Skip to content

Commit 3e9393a

Browse files
committed
test: split test_client_helpers.py into domain-specific test files
1 parent 17acb05 commit 3e9393a

4 files changed

Lines changed: 197 additions & 124 deletions

File tree

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# -*- coding: utf-8 -*-
2+
# Copyright 2026 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
import os
17+
from unittest import mock
18+
19+
import pytest
20+
21+
try:
22+
import grpc # noqa: F401
23+
except ImportError:
24+
pytest.skip("No GRPC", allow_module_level=True)
25+
26+
from google.api_core.gapic_v1._client_cert import (
27+
get_client_cert_source,
28+
use_client_cert_effective,
29+
)
30+
31+
32+
@mock.patch("google.auth.transport.mtls.should_use_client_cert", create=True)
33+
def test_use_client_cert_effective_with_google_auth(mock_method):
34+
# Test when google-auth supports the method
35+
mock_method.return_value = True
36+
assert use_client_cert_effective() is True
37+
38+
mock_method.return_value = False
39+
assert use_client_cert_effective() is False
40+
41+
42+
@mock.patch.dict(os.environ, {}, clear=True)
43+
def test_use_client_cert_effective_fallback():
44+
# We must patch hasattr to simulate google-auth lacking the method
45+
with mock.patch(
46+
"google.api_core.gapic_v1._client_cert.hasattr", return_value=False
47+
):
48+
# Default is false
49+
assert use_client_cert_effective() is False
50+
51+
env_true = {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}
52+
with mock.patch.dict(os.environ, env_true):
53+
assert use_client_cert_effective() is True
54+
55+
with mock.patch.dict(
56+
os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}
57+
):
58+
assert use_client_cert_effective() is False
59+
60+
with mock.patch.dict(
61+
os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "invalid"}
62+
):
63+
match_str = "must be either `true` or `false`"
64+
with pytest.raises(ValueError, match=match_str):
65+
use_client_cert_effective()
66+
67+
68+
@mock.patch(
69+
"google.auth.transport.mtls.has_default_client_cert_source", create=True
70+
) # noqa: E501
71+
@mock.patch(
72+
"google.auth.transport.mtls.default_client_cert_source", create=True
73+
) # noqa: E501
74+
def test_get_client_cert_source(mock_default, mock_has_default):
75+
mock_default.return_value = b"default_cert"
76+
mock_has_default.return_value = True
77+
78+
# When use_cert_flag is False, return None
79+
assert get_client_cert_source(b"provided", False) is None
80+
81+
# When provided_cert_source is given, return provided
82+
assert get_client_cert_source(b"provided", True) == b"provided" # noqa: E501
83+
84+
# When no provided cert but default is available
85+
assert get_client_cert_source(None, True) == b"default_cert"
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# -*- coding: utf-8 -*-
2+
# Copyright 2026 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
import os
17+
from unittest import mock
18+
19+
import pytest
20+
21+
try:
22+
import grpc # noqa: F401
23+
except ImportError:
24+
pytest.skip("No GRPC", allow_module_level=True)
25+
26+
from google.auth.exceptions import MutualTLSChannelError
27+
28+
from google.api_core.gapic_v1._config_helpers import read_environment_variables
29+
30+
31+
@mock.patch(
32+
"google.api_core.gapic_v1._config_helpers.use_client_cert_effective"
33+
) # noqa: E501
34+
@mock.patch.dict(os.environ, clear=True)
35+
def test_read_environment_variables(mock_effective):
36+
mock_effective.return_value = True
37+
os.environ["GOOGLE_API_USE_MTLS_ENDPOINT"] = "always"
38+
os.environ["GOOGLE_CLOUD_UNIVERSE_DOMAIN"] = "custom.com"
39+
40+
cert, mtls, domain = read_environment_variables()
41+
assert cert is True
42+
assert mtls == "always"
43+
assert domain == "custom.com"
44+
45+
46+
@mock.patch.dict(os.environ, clear=True)
47+
def test_read_environment_variables_invalid_mtls():
48+
os.environ["GOOGLE_API_USE_MTLS_ENDPOINT"] = "invalid"
49+
with pytest.raises(
50+
MutualTLSChannelError, match="must be `never`, `auto` or `always`"
51+
):
52+
read_environment_variables()
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# -*- coding: utf-8 -*-
2+
# Copyright 2026 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
import pytest
17+
18+
try:
19+
import grpc # noqa: F401
20+
except ImportError:
21+
pytest.skip("No GRPC", allow_module_level=True)
22+
23+
from google.api_core.gapic_v1._method_helpers import setup_request_id
24+
25+
26+
def test_setup_request_id():
27+
import uuid
28+
29+
# test dict request
30+
req = {}
31+
setup_request_id(req, "request_id", True)
32+
assert "request_id" in req
33+
uuid_str = req["request_id"]
34+
uuid.UUID(uuid_str) # verify it is a valid UUID
35+
36+
# test dict request when already set
37+
req = {"request_id": "existing"}
38+
setup_request_id(req, "request_id", True)
39+
assert req["request_id"] == "existing"
40+
41+
class DummyRequest:
42+
def __init__(self):
43+
self.request_id = ""
44+
45+
def HasField(self, field_name):
46+
if not hasattr(self, field_name):
47+
raise ValueError()
48+
return bool(getattr(self, field_name))
49+
50+
# test object request proto3 optional true
51+
req_obj = DummyRequest()
52+
setup_request_id(req_obj, "request_id", True)
53+
assert req_obj.request_id != ""
54+
uuid.UUID(req_obj.request_id)
55+
56+
# test object request proto3 optional false
57+
req_obj2 = DummyRequest()
58+
setup_request_id(req_obj2, "request_id", False)
59+
assert req_obj2.request_id != ""
60+
uuid.UUID(req_obj2.request_id)

packages/google-api-core/tests/unit/gapic/test_client_helpers.py renamed to packages/google-api-core/tests/unit/gapic/test_routing.py

Lines changed: 0 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515

16-
import os
1716
from unittest import mock
1817

1918
import pytest
@@ -25,12 +24,6 @@
2524

2625
from google.auth.exceptions import MutualTLSChannelError
2726

28-
from google.api_core.gapic_v1._client_cert import (
29-
get_client_cert_source,
30-
use_client_cert_effective,
31-
)
32-
from google.api_core.gapic_v1._config_helpers import read_environment_variables
33-
from google.api_core.gapic_v1._method_helpers import setup_request_id
3427
from google.api_core.gapic_v1._routing import (
3528
get_api_endpoint,
3629
get_default_mtls_endpoint,
@@ -58,42 +51,6 @@ def test_get_default_mtls_endpoint():
5851
assert get_default_mtls_endpoint(None) is None
5952

6053

61-
@mock.patch("google.auth.transport.mtls.should_use_client_cert", create=True)
62-
def test_use_client_cert_effective_with_google_auth(mock_method):
63-
# Test when google-auth supports the method
64-
mock_method.return_value = True
65-
assert use_client_cert_effective() is True
66-
67-
mock_method.return_value = False
68-
assert use_client_cert_effective() is False
69-
70-
71-
@mock.patch.dict(os.environ, {}, clear=True)
72-
def test_use_client_cert_effective_fallback():
73-
# We must patch hasattr to simulate google-auth lacking the method
74-
with mock.patch(
75-
"google.api_core.gapic_v1._client_cert.hasattr", return_value=False
76-
):
77-
# Default is false
78-
assert use_client_cert_effective() is False
79-
80-
env_true = {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}
81-
with mock.patch.dict(os.environ, env_true):
82-
assert use_client_cert_effective() is True
83-
84-
with mock.patch.dict(
85-
os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}
86-
):
87-
assert use_client_cert_effective() is False
88-
89-
with mock.patch.dict(
90-
os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "invalid"}
91-
):
92-
match_str = "must be either `true` or `false`"
93-
with pytest.raises(ValueError, match=match_str):
94-
use_client_cert_effective()
95-
96-
9754
def test_get_api_endpoint_override():
9855
# If api_override is provided, it should be returned
9956
# regardless of other args
@@ -165,50 +122,6 @@ def test_get_api_endpoint_mtls_universe_mismatch():
165122
)
166123

167124

168-
@mock.patch(
169-
"google.api_core.gapic_v1._config_helpers.use_client_cert_effective"
170-
) # noqa: E501
171-
@mock.patch.dict(os.environ, clear=True)
172-
def test_read_environment_variables(mock_effective):
173-
mock_effective.return_value = True
174-
os.environ["GOOGLE_API_USE_MTLS_ENDPOINT"] = "always"
175-
os.environ["GOOGLE_CLOUD_UNIVERSE_DOMAIN"] = "custom.com"
176-
177-
cert, mtls, domain = read_environment_variables()
178-
assert cert is True
179-
assert mtls == "always"
180-
assert domain == "custom.com"
181-
182-
183-
@mock.patch.dict(os.environ, clear=True)
184-
def test_read_environment_variables_invalid_mtls():
185-
os.environ["GOOGLE_API_USE_MTLS_ENDPOINT"] = "invalid"
186-
with pytest.raises(
187-
MutualTLSChannelError, match="must be `never`, `auto` or `always`"
188-
):
189-
read_environment_variables()
190-
191-
192-
@mock.patch(
193-
"google.auth.transport.mtls.has_default_client_cert_source", create=True
194-
) # noqa: E501
195-
@mock.patch(
196-
"google.auth.transport.mtls.default_client_cert_source", create=True
197-
) # noqa: E501
198-
def test_get_client_cert_source(mock_default, mock_has_default):
199-
mock_default.return_value = b"default_cert"
200-
mock_has_default.return_value = True
201-
202-
# When use_cert_flag is False, return None
203-
assert get_client_cert_source(b"provided", False) is None
204-
205-
# When provided_cert_source is given, return provided
206-
assert get_client_cert_source(b"provided", True) == b"provided" # noqa: E501
207-
208-
# When no provided cert but default is available
209-
assert get_client_cert_source(None, True) == b"default_cert"
210-
211-
212125
def test_get_universe_domain():
213126
# client_universe_domain takes precedence
214127
assert (
@@ -228,40 +141,3 @@ def test_get_universe_domain():
228141
def test_get_universe_domain_empty():
229142
with pytest.raises(ValueError, match="cannot be an empty string"):
230143
get_universe_domain("", None, "default.com")
231-
232-
233-
def test_setup_request_id():
234-
import uuid
235-
236-
# test dict request
237-
req = {}
238-
setup_request_id(req, "request_id", True)
239-
assert "request_id" in req
240-
uuid_str = req["request_id"]
241-
uuid.UUID(uuid_str) # verify it is a valid UUID
242-
243-
# test dict request when already set
244-
req = {"request_id": "existing"}
245-
setup_request_id(req, "request_id", True)
246-
assert req["request_id"] == "existing"
247-
248-
class DummyRequest:
249-
def __init__(self):
250-
self.request_id = ""
251-
252-
def HasField(self, field_name):
253-
if not hasattr(self, field_name):
254-
raise ValueError()
255-
return bool(getattr(self, field_name))
256-
257-
# test object request proto3 optional true
258-
req_obj = DummyRequest()
259-
setup_request_id(req_obj, "request_id", True)
260-
assert req_obj.request_id != ""
261-
uuid.UUID(req_obj.request_id)
262-
263-
# test object request proto3 optional false
264-
req_obj2 = DummyRequest()
265-
setup_request_id(req_obj2, "request_id", False)
266-
assert req_obj2.request_id != ""
267-
uuid.UUID(req_obj2.request_id)

0 commit comments

Comments
 (0)