Skip to content

Commit 55d1ba5

Browse files
committed
tests(auth): avoid running aio-only tests in gcloud-rest
1 parent 361cec6 commit 55d1ba5

1 file changed

Lines changed: 127 additions & 126 deletions

File tree

auth/tests/unit/token_test.py

Lines changed: 127 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -85,137 +85,138 @@ async def test_acquiring_cancellation():
8585
t.acquire_access_token.return_value = None
8686
await t.get()
8787

88+
@pytest.mark.asyncio
89+
async def test_external_account_as_io():
90+
service_data = {
91+
'type': 'external_account',
92+
'audience': (
93+
'//iam.googleapis.com/projects/123456/locations/global'
94+
'/workloadIdentityPools/pool/subject'
95+
),
96+
'subject_token_type': 'urn:ietf:params:oauth:token-type:jwt',
97+
'token_url': 'https://sts.googleapis.com/v1/token',
98+
'credential_source': {
99+
'type': 'url',
100+
'url': 'http://169.254.169.254/metadata/identity/oauth2/token',
101+
'headers': {'Metadata': 'true'},
102+
},
103+
}
104+
105+
service_file = io.StringIO(json.dumps(service_data))
106+
t = token.BaseToken(service_file=service_file)
107+
108+
assert t.token_type == token.Type.EXTERNAL_ACCOUNT
109+
assert t.token_uri == 'https://oauth2.googleapis.com/token'
88110

89-
@pytest.mark.asyncio
90-
async def test_external_account_as_io():
91-
service_data = {
92-
'type': 'external_account',
93-
'audience': (
94-
'//iam.googleapis.com/projects/123456/locations/global'
95-
'/workloadIdentityPools/pool/subject'
96-
),
97-
'subject_token_type': 'urn:ietf:params:oauth:token-type:jwt',
98-
'token_url': 'https://sts.googleapis.com/v1/token',
99-
'credential_source': {
100-
'type': 'url',
101-
'url': 'http://169.254.169.254/metadata/identity/oauth2/token',
102-
'headers': {'Metadata': 'true'},
103-
},
104-
}
111+
@pytest.mark.asyncio
112+
async def test_external_account_missing_required_fields():
113+
# Missing token_url and credential_source
114+
service_data = {
115+
'type': 'external_account',
116+
'audience': (
117+
'//iam.googleapis.com/projects/123456/locations/global'
118+
'/workloadIdentityPools/pool/subject'
119+
),
120+
'subject_token_type': 'urn:ietf:params:oauth:token-type:jwt',
121+
}
122+
123+
service_file = io.StringIO(json.dumps(service_data))
124+
with mock.patch(
125+
'gcloud.aio.auth.token.get_service_data', return_value=service_data
126+
):
127+
with pytest.raises(
128+
ValueError,
129+
match='external_account credentials missing required fields',
130+
):
131+
await token.Token(service_file=service_file).get()
105132

106-
service_file = io.StringIO(json.dumps(service_data))
107-
t = token.BaseToken(service_file=service_file)
133+
@pytest.mark.asyncio
134+
async def test_external_account_token_refresh():
135+
service_data = {
136+
'type': 'external_account',
137+
'audience': (
138+
'//iam.googleapis.com/projects/123456/locations/global'
139+
'/workloadIdentityPools/pool/subject'
140+
),
141+
'subject_token_type': 'urn:ietf:params:oauth:token-type:jwt',
142+
'token_url': 'https://sts.googleapis.com/v1/token',
143+
'credential_source': {
144+
'type': 'url',
145+
'url': 'http://169.254.169.254/metadata/identity/oauth2/token',
146+
'headers': {'Metadata': 'true'},
147+
},
148+
}
149+
150+
service_file = io.StringIO(f'{json.dumps(service_data)}')
151+
t = token.Token(service_file=service_file)
152+
153+
# Mock the session to return a subject token
154+
mock_response = mock.AsyncMock()
155+
mock_response.status = 200
156+
mock_response.text = 'subject_token_123'
157+
t.session.get = mock.AsyncMock(return_value=mock_response)
158+
159+
# Mock the token exchange response
160+
mock_token_response = mock.AsyncMock()
161+
mock_token_response.status = 200
162+
mock_token_response.json = mock.AsyncMock(
163+
return_value={
164+
'access_token': 'access_token_123',
165+
'expires_in': 3600,
166+
},
167+
)
168+
t.session.post = mock.AsyncMock(return_value=mock_token_response)
169+
170+
# Test token refresh
171+
token_response = await t._refresh_external_account(timeout=10)
172+
assert token_response.value == 'access_token_123'
173+
assert token_response.expires_in == 3600
174+
175+
# Verify the correct requests were made
176+
t.session.get.assert_called_once_with(
177+
'http://169.254.169.254/metadata/identity/oauth2/token',
178+
headers={'Metadata': 'true'},
179+
timeout=10,
180+
)
108181

109-
assert t.token_type == token.Type.EXTERNAL_ACCOUNT
110-
assert t.token_uri == 'https://oauth2.googleapis.com/token'
182+
t.session.post.assert_called_once()
183+
call_args = t.session.post.call_args
184+
assert call_args[0][0] == 'https://sts.googleapis.com/v1/token'
111185

186+
@pytest.mark.asyncio
187+
async def test_external_account_credential_source_types():
188+
# Test URL credential source
189+
url_source = {
190+
'type': 'url',
191+
'url': 'http://example.com/token',
192+
'headers': {'Authorization': 'Bearer secret'},
193+
}
194+
t = token.Token()
195+
mock_response = mock.AsyncMock()
196+
mock_response.status = 200
197+
mock_response.text = 'token_from_url'
198+
t.session.get = mock.AsyncMock(return_value=mock_response)
199+
token_value = await t._get_subject_token(url_source, timeout=10)
200+
assert token_value == 'token_from_url'
201+
202+
# Test file credential source
203+
file_source = {'type': 'file', 'file': 'test_token.txt'}
204+
with mock.patch(
205+
'builtins.open',
206+
mock.mock_open(read_data='token_from_file'),
207+
):
208+
token_value = await t._get_subject_token(file_source, timeout=10)
209+
assert token_value == 'token_from_file'
112210

113-
@pytest.mark.asyncio
114-
async def test_external_account_missing_required_fields():
115-
# Missing token_url and credential_source
116-
service_data = {
117-
'type': 'external_account',
118-
'audience': (
119-
'//iam.googleapis.com/projects/123456/locations/global'
120-
'/workloadIdentityPools/pool/subject'
121-
),
122-
'subject_token_type': 'urn:ietf:params:oauth:token-type:jwt',
123-
}
211+
# Test environment credential source
212+
env_source = {'type': 'environment', 'environment_id': 'TEST_TOKEN'}
213+
with mock.patch.dict('os.environ', {'TEST_TOKEN': 'token_from_env'}):
214+
token_value = await t._get_subject_token(env_source, timeout=10)
215+
assert token_value == 'token_from_env'
124216

125-
service_file = io.StringIO(json.dumps(service_data))
126-
with mock.patch(
127-
'gcloud.aio.auth.token.get_service_data', return_value=service_data
128-
):
217+
# Test invalid credential source type
218+
invalid_source = {'type': 'invalid'}
129219
with pytest.raises(
130-
ValueError,
131-
match='external_account credentials missing required fields',
220+
ValueError, match='unsupported credential_source type',
132221
):
133-
await token.Token(service_file=service_file).get()
134-
135-
136-
@pytest.mark.asyncio
137-
async def test_external_account_token_refresh():
138-
service_data = {
139-
'type': 'external_account',
140-
'audience': (
141-
'//iam.googleapis.com/projects/123456/locations/global'
142-
'/workloadIdentityPools/pool/subject'
143-
),
144-
'subject_token_type': 'urn:ietf:params:oauth:token-type:jwt',
145-
'token_url': 'https://sts.googleapis.com/v1/token',
146-
'credential_source': {
147-
'type': 'url',
148-
'url': 'http://169.254.169.254/metadata/identity/oauth2/token',
149-
'headers': {'Metadata': 'true'},
150-
},
151-
}
152-
153-
service_file = io.StringIO(f'{json.dumps(service_data)}')
154-
t = token.Token(service_file=service_file)
155-
156-
# Mock the session to return a subject token
157-
mock_response = mock.AsyncMock()
158-
mock_response.status = 200
159-
mock_response.text = 'subject_token_123'
160-
t.session.get = mock.AsyncMock(return_value=mock_response)
161-
162-
# Mock the token exchange response
163-
mock_token_response = mock.AsyncMock()
164-
mock_token_response.status = 200
165-
mock_token_response.json = mock.AsyncMock(
166-
return_value={'access_token': 'access_token_123', 'expires_in': 3600}
167-
)
168-
t.session.post = mock.AsyncMock(return_value=mock_token_response)
169-
170-
# Test token refresh
171-
token_response = await t._refresh_external_account(timeout=10)
172-
assert token_response.value == 'access_token_123'
173-
assert token_response.expires_in == 3600
174-
175-
# Verify the correct requests were made
176-
t.session.get.assert_called_once_with(
177-
'http://169.254.169.254/metadata/identity/oauth2/token',
178-
headers={'Metadata': 'true'},
179-
timeout=10,
180-
)
181-
182-
t.session.post.assert_called_once()
183-
call_args = t.session.post.call_args
184-
assert call_args[0][0] == 'https://sts.googleapis.com/v1/token'
185-
186-
187-
@pytest.mark.asyncio
188-
async def test_external_account_credential_source_types():
189-
# Test URL credential source
190-
url_source = {
191-
'type': 'url',
192-
'url': 'http://example.com/token',
193-
'headers': {'Authorization': 'Bearer secret'},
194-
}
195-
t = token.Token()
196-
mock_response = mock.AsyncMock()
197-
mock_response.status = 200
198-
mock_response.text = 'token_from_url'
199-
t.session.get = mock.AsyncMock(return_value=mock_response)
200-
token_value = await t._get_subject_token(url_source, timeout=10)
201-
assert token_value == 'token_from_url'
202-
203-
# Test file credential source
204-
file_source = {'type': 'file', 'file': 'test_token.txt'}
205-
with mock.patch(
206-
'builtins.open',
207-
mock.mock_open(read_data='token_from_file'),
208-
):
209-
token_value = await t._get_subject_token(file_source, timeout=10)
210-
assert token_value == 'token_from_file'
211-
212-
# Test environment credential source
213-
env_source = {'type': 'environment', 'environment_id': 'TEST_TOKEN'}
214-
with mock.patch.dict('os.environ', {'TEST_TOKEN': 'token_from_env'}):
215-
token_value = await t._get_subject_token(env_source, timeout=10)
216-
assert token_value == 'token_from_env'
217-
218-
# Test invalid credential source type
219-
invalid_source = {'type': 'invalid'}
220-
with pytest.raises(ValueError, match='unsupported credential_source type'):
221-
await t._get_subject_token(invalid_source, timeout=10)
222+
await t._get_subject_token(invalid_source, timeout=10)

0 commit comments

Comments
 (0)