Skip to content

Commit 5b77291

Browse files
committed
fix(test): update test_compat template and goldens for complete branch coverage without pragmas
1 parent dbd4f5f commit 5b77291

9 files changed

Lines changed: 2088 additions & 837 deletions

File tree

Lines changed: 232 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,102 +1,241 @@
11
# {% include '_license.j2' %}
22

3+
import builtins
4+
import importlib
5+
import sys
6+
from unittest import mock
37
import pytest
4-
import os
58
from google.auth.exceptions import MutualTLSChannelError
9+
from google.protobuf import descriptor_pb2
610

711
{% set package_path = api.naming.module_namespace|join('.') + "." + api.naming.versioned_module_name %}
812
from {{package_path}} import _compat
913

1014

11-
def test_get_default_mtls_endpoint():
12-
assert _compat.get_default_mtls_endpoint(None) is None
13-
assert _compat.get_default_mtls_endpoint("foo.googleapis.com") == "foo.mtls.googleapis.com"
14-
assert _compat.get_default_mtls_endpoint("foo.sandbox.googleapis.com") == "foo.mtls.sandbox.googleapis.com"
15-
assert _compat.get_default_mtls_endpoint("foo.mtls.googleapis.com") == "foo.mtls.googleapis.com"
16-
assert _compat.get_default_mtls_endpoint("invalid") == "invalid"
17-
18-
19-
def test_get_api_endpoint():
20-
assert _compat.get_api_endpoint("https://override.com", None, "googleapis.com", "auto", "googleapis.com", "mtls.com", "https://{UNIVERSE_DOMAIN}") == "https://override.com"
21-
assert _compat.get_api_endpoint(None, lambda: (b"", b""), "googleapis.com", "always", "googleapis.com", "mtls.com", "https://{UNIVERSE_DOMAIN}") == "mtls.com"
22-
with pytest.raises(MutualTLSChannelError):
23-
_compat.get_api_endpoint(None, None, "otheruniverse.com", "always", "googleapis.com", "mtls.com", "https://{UNIVERSE_DOMAIN}")
24-
assert _compat.get_api_endpoint(None, None, "googleapis.com", "never", "googleapis.com", "mtls.com", "https://{UNIVERSE_DOMAIN}") == "https://googleapis.com"
25-
26-
27-
def test_get_universe_domain():
28-
assert _compat.get_universe_domain("custom.com", None, "googleapis.com") == "custom.com"
29-
assert _compat.get_universe_domain(None, "env.com", "googleapis.com") == "env.com"
30-
assert _compat.get_universe_domain(None, None, "googleapis.com") == "googleapis.com"
31-
with pytest.raises(ValueError):
32-
_compat.get_universe_domain(" ", None, "googleapis.com")
33-
34-
35-
def test_use_client_cert_effective(monkeypatch):
36-
monkeypatch.setenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "true")
37-
assert _compat.use_client_cert_effective() is True
38-
monkeypatch.setenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")
39-
assert _compat.use_client_cert_effective() is False
40-
monkeypatch.setenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "invalid")
41-
with pytest.raises(ValueError):
42-
_compat.use_client_cert_effective()
43-
44-
45-
def test_get_client_cert_source():
46-
cert_fn = lambda: (b"cert", b"key")
47-
assert _compat.get_client_cert_source(cert_fn, True) == cert_fn
48-
assert _compat.get_client_cert_source(None, False) is None
49-
with pytest.raises(ValueError):
50-
_compat.get_client_cert_source(None, True)
51-
52-
53-
def test_read_environment_variables(monkeypatch):
54-
monkeypatch.setenv("GOOGLE_API_USE_MTLS_ENDPOINT", "always")
55-
monkeypatch.setenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN", "myuniverse.com")
56-
use_cert, use_mtls, universe = _compat.read_environment_variables()
57-
assert use_mtls == "always"
58-
assert universe == "myuniverse.com"
59-
60-
monkeypatch.setenv("GOOGLE_API_USE_MTLS_ENDPOINT", "invalid")
61-
with pytest.raises(MutualTLSChannelError):
62-
_compat.read_environment_variables()
63-
64-
65-
def test_setup_request_id():
66-
# Test with None request
67-
_compat.setup_request_id(None, "request_id", False)
68-
69-
# Test with dict request (proto3 optional and non-optional)
70-
d1 = {}
71-
_compat.setup_request_id(d1, "request_id", is_proto3_optional=True)
72-
assert "request_id" in d1
73-
74-
d2 = {}
75-
_compat.setup_request_id(d2, "request_id", is_proto3_optional=False)
76-
assert "request_id" in d2
77-
78-
# Test when field already present
79-
d3 = {"request_id": "existing"}
80-
_compat.setup_request_id(d3, "request_id", is_proto3_optional=False)
81-
assert d3["request_id"] == "existing"
82-
83-
# Test with object
84-
class Dummy:
85-
request_id = None
86-
obj = Dummy()
87-
_compat.setup_request_id(obj, "request_id", is_proto3_optional=False)
88-
assert obj.request_id is not None
89-
90-
91-
def test_flatten_query_params():
92-
assert _compat.flatten_query_params(None) == []
93-
res = _compat.flatten_query_params({"a": "val1", "b": [1, 2]})
94-
assert ("a", "val1") in res
95-
assert ("b", 1) in res
96-
assert ("b", 2) in res
97-
98-
with pytest.raises(TypeError):
99-
_compat.flatten_query_params("invalid")
100-
101-
with pytest.raises(ValueError):
102-
_compat.flatten_query_params({"a": [{"nested": "dict"}]})
15+
def test_compat_normal_import():
16+
assert _compat.setup_request_id is not None
17+
18+
19+
def test_compat_fallback_implementations():
20+
orig_import = builtins.__import__
21+
22+
def custom_import(name, globals=None, locals=None, fromlist=(), level=0):
23+
if name in (
24+
"google.api_core.universe",
25+
"google.api_core.gapic_v1.config",
26+
"google.api_core.gapic_v1.request",
27+
"google.api_core.rest_helpers",
28+
):
29+
raise ImportError(f"Mocked ImportError for {name}")
30+
return orig_import(name, globals, locals, fromlist, level)
31+
32+
with mock.patch("builtins.__import__", side_effect=custom_import):
33+
fallback = importlib.reload(_compat)
34+
35+
# get_default_mtls_endpoint tests
36+
assert fallback.get_default_mtls_endpoint(None) is None
37+
assert fallback.get_default_mtls_endpoint("") == ""
38+
assert fallback.get_default_mtls_endpoint("foo.googleapis.com") == "foo.mtls.googleapis.com"
39+
assert fallback.get_default_mtls_endpoint("foo.sandbox.googleapis.com") == "foo.mtls.sandbox.googleapis.com"
40+
assert fallback.get_default_mtls_endpoint("foo.mtls.googleapis.com") == "foo.mtls.googleapis.com"
41+
assert fallback.get_default_mtls_endpoint("custom.domain.com") == "custom.domain.com"
42+
assert fallback.get_default_mtls_endpoint(":::invalid-url:::") == ":::invalid-url:::"
43+
44+
# get_api_endpoint tests
45+
assert fallback.get_api_endpoint("https://override.com", None, "googleapis.com", "auto", "googleapis.com", "mtls.com", "https://{UNIVERSE_DOMAIN}") == "https://override.com"
46+
assert fallback.get_api_endpoint(None, lambda: (b"", b""), "googleapis.com", "always", "googleapis.com", "mtls.com", "https://{UNIVERSE_DOMAIN}") == "mtls.com"
47+
assert fallback.get_api_endpoint(None, lambda: (b"", b""), "googleapis.com", "auto", "googleapis.com", "mtls.com", "https://{UNIVERSE_DOMAIN}") == "mtls.com"
48+
with pytest.raises(MutualTLSChannelError):
49+
fallback.get_api_endpoint(None, lambda: (b"", b""), "otheruniverse.com", "always", "googleapis.com", "mtls.com", "https://{UNIVERSE_DOMAIN}")
50+
assert fallback.get_api_endpoint(None, None, "googleapis.com", "never", "googleapis.com", "mtls.com", "https://{UNIVERSE_DOMAIN}") == "https://googleapis.com"
51+
52+
# get_universe_domain tests
53+
assert fallback.get_universe_domain("custom.com", None, "googleapis.com") == "custom.com"
54+
assert fallback.get_universe_domain(None, "env.com", "googleapis.com") == "env.com"
55+
assert fallback.get_universe_domain(None, None, "googleapis.com") == "googleapis.com"
56+
with pytest.raises(ValueError):
57+
fallback.get_universe_domain(" ", None, "googleapis.com")
58+
59+
# use_client_cert_effective tests
60+
with mock.patch("google.auth.transport.mtls.should_use_client_cert", return_value=True, create=True):
61+
assert fallback.use_client_cert_effective() is True
62+
63+
with mock.patch.object(fallback, "mtls", spec=object()):
64+
with mock.patch.dict("os.environ", {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}):
65+
assert fallback.use_client_cert_effective() is True
66+
with mock.patch.dict("os.environ", {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}):
67+
assert fallback.use_client_cert_effective() is False
68+
with mock.patch.dict("os.environ", {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "invalid"}):
69+
with pytest.raises(ValueError):
70+
fallback.use_client_cert_effective()
71+
72+
# get_client_cert_source tests
73+
cert_fn = lambda: (b"cert", b"key")
74+
assert fallback.get_client_cert_source(cert_fn, True) == cert_fn
75+
assert fallback.get_client_cert_source(None, False) is None
76+
77+
with mock.patch("google.auth.transport.mtls.has_default_client_cert_source", return_value=True, create=True):
78+
with mock.patch("google.auth.transport.mtls.default_client_cert_source", return_value=cert_fn, create=True):
79+
assert fallback.get_client_cert_source(None, True) == cert_fn
80+
81+
with mock.patch.object(fallback, "mtls", spec=object()):
82+
with pytest.raises(ValueError):
83+
fallback.get_client_cert_source(None, True)
84+
85+
# read_environment_variables tests
86+
with mock.patch.dict("os.environ", {"GOOGLE_API_USE_MTLS_ENDPOINT": "always", "GOOGLE_CLOUD_UNIVERSE_DOMAIN": "myuniverse.com"}):
87+
use_cert, use_mtls, universe = fallback.read_environment_variables()
88+
assert use_mtls == "always"
89+
assert universe == "myuniverse.com"
90+
91+
with mock.patch.dict("os.environ", {"GOOGLE_API_USE_MTLS_ENDPOINT": "invalid"}):
92+
with pytest.raises(MutualTLSChannelError):
93+
fallback.read_environment_variables()
94+
95+
# setup_request_id tests
96+
fallback.setup_request_id(None, "request_id", False)
97+
98+
d1 = {}
99+
fallback.setup_request_id(d1, "request_id", is_proto3_optional=True)
100+
assert "request_id" in d1
101+
102+
d1_existing = {"request_id": None}
103+
fallback.setup_request_id(d1_existing, "request_id", is_proto3_optional=True)
104+
assert d1_existing["request_id"] is not None
105+
106+
d2 = {}
107+
fallback.setup_request_id(d2, "request_id", is_proto3_optional=False)
108+
assert "request_id" in d2
109+
110+
d3 = {"request_id": "existing"}
111+
fallback.setup_request_id(d3, "request_id", is_proto3_optional=False)
112+
assert d3["request_id"] == "existing"
113+
114+
d4 = {"request_id": "val"}
115+
fallback.setup_request_id(d4, "request_id", is_proto3_optional=True)
116+
assert d4["request_id"] == "val"
117+
118+
class DummyPopulated:
119+
def __init__(self):
120+
self.request_id = "val"
121+
p_existing = DummyPopulated()
122+
fallback.setup_request_id(p_existing, "request_id", is_proto3_optional=False)
123+
assert p_existing.request_id == "val"
124+
125+
class NonOptPlain:
126+
def __init__(self):
127+
self.request_id = ""
128+
nop = NonOptPlain()
129+
fallback.setup_request_id(nop, "request_id", is_proto3_optional=False)
130+
assert nop.request_id != ""
131+
132+
class DummyProto:
133+
def __init__(self):
134+
self.request_id = ""
135+
self._has = False
136+
def HasField(self, name):
137+
if not self._has:
138+
return False
139+
return True
140+
141+
p1 = DummyProto()
142+
fallback.setup_request_id(p1, "request_id", is_proto3_optional=True)
143+
assert p1.request_id != ""
144+
145+
class DummyWrapper:
146+
def __init__(self):
147+
self._pb = DummyProto()
148+
149+
w1 = DummyWrapper()
150+
fallback.setup_request_id(w1, "request_id", is_proto3_optional=True)
151+
assert getattr(w1, "request_id", None) is not None or getattr(w1._pb, "request_id", None) != ""
152+
153+
class BadProto:
154+
def HasField(self, name):
155+
raise AttributeError()
156+
class BadWrapper:
157+
def __init__(self):
158+
self._pb = BadProto()
159+
self.request_id = None
160+
bw = BadWrapper()
161+
fallback.setup_request_id(bw, "request_id", is_proto3_optional=True)
162+
assert bw.request_id is not None
163+
164+
class SetProto:
165+
def __init__(self):
166+
self.request_id = "already_set"
167+
def HasField(self, name):
168+
return True
169+
sp = SetProto()
170+
fallback.setup_request_id(sp, "request_id", is_proto3_optional=True)
171+
assert sp.request_id == "already_set"
172+
173+
class SetProtoNonOpt:
174+
def __init__(self):
175+
self.request_id = "already_set"
176+
sp_non_opt = SetProtoNonOpt()
177+
fallback.setup_request_id(sp_non_opt, "request_id", is_proto3_optional=False)
178+
assert sp_non_opt.request_id == "already_set"
179+
180+
class DummyPlain:
181+
def __init__(self):
182+
self.request_id = None
183+
184+
pl1 = DummyPlain()
185+
fallback.setup_request_id(pl1, "request_id", is_proto3_optional=True)
186+
assert pl1.request_id is not None
187+
188+
pl2 = DummyPlain()
189+
fallback.setup_request_id(pl2, "request_id", is_proto3_optional=False)
190+
assert pl2.request_id is not None
191+
192+
# flatten_query_params tests
193+
assert fallback.flatten_query_params(None) == []
194+
res = fallback.flatten_query_params({"a": "val1", "b": [1, 2], "c": True})
195+
assert ("a", "val1") in res
196+
assert ("b", 1) in res
197+
assert ("b", 2) in res
198+
assert ("c", True) in res
199+
200+
res_strict = fallback.flatten_query_params({"c": True}, strict=True)
201+
assert ("c", "true") in res_strict
202+
203+
assert fallback._canonicalize(True, strict=True) == "true"
204+
assert fallback._canonicalize(True, strict=False) is True
205+
assert fallback._canonicalize(123, strict=True) == "123"
206+
assert fallback._canonicalize("str", strict=True) == "str"
207+
assert fallback._canonicalize("str", strict=False) == "str"
208+
assert fallback._is_primitive_value(None) is False
209+
210+
with pytest.raises(TypeError):
211+
fallback.flatten_query_params("invalid")
212+
213+
with pytest.raises(ValueError):
214+
fallback.flatten_query_params({"a": [{"nested": "dict"}]})
215+
216+
with pytest.raises(ValueError):
217+
fallback._is_primitive_value([1, 2])
218+
219+
# transcode_request tests
220+
dummy_req = descriptor_pb2.DescriptorProto()
221+
http_opts = [{"method": "get", "uri": "/v1/test"}]
222+
transcoded, body, query = fallback.transcode_request(
223+
http_opts,
224+
dummy_req,
225+
required_fields_default_values={"non_existent_key": "val"},
226+
rest_numeric_enums=True,
227+
)
228+
assert transcoded is not None
229+
assert query.get("non_existent_key") == "val"
230+
assert query.get("$alt") == "json;enum-encoding=int"
231+
232+
transcoded2, body2, query2 = fallback.transcode_request(
233+
http_opts,
234+
dummy_req,
235+
required_fields_default_values={"name": "override_name"},
236+
rest_numeric_enums=False,
237+
)
238+
assert body2 is None
239+
assert "$alt" not in query2
240+
241+
importlib.reload(_compat)

0 commit comments

Comments
 (0)