Skip to content

Commit 9668b88

Browse files
test(spanner): clear context-aware mTLS env var in unit tests
Unset CLOUDSDK_CONTEXT_AWARE_USE_CLIENT_CERTIFICATE in mTLS unit tests to prevent failures in Google and Kokoro CI environments.
1 parent 270c7fe commit 9668b88

9 files changed

Lines changed: 165 additions & 31 deletions

File tree

packages/gapic-generator/gapic/templates/tests/unit/gapic/%name_%version/%sub/test_%service.py.j2

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -896,6 +896,7 @@ def test_{{ service.client_name|snake_case }}_get_mtls_endpoint_and_cert_source(
896896
for config_data, expected_cert_source in test_cases:
897897
env = os.environ.copy()
898898
env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", None)
899+
env.pop("CLOUDSDK_CONTEXT_AWARE_USE_CLIENT_CERTIFICATE", None)
899900
with mock.patch.dict(os.environ, env, clear=True):
900901
config_filename = "mock_certificate_config.json"
901902
config_file_content = json.dumps(config_data)
@@ -943,6 +944,7 @@ def test_{{ service.client_name|snake_case }}_get_mtls_endpoint_and_cert_source(
943944
for config_data, expected_cert_source in test_cases:
944945
env = os.environ.copy()
945946
env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", "")
947+
env.pop("CLOUDSDK_CONTEXT_AWARE_USE_CLIENT_CERTIFICATE", "")
946948
with mock.patch.dict(os.environ, env, clear=True):
947949
config_filename = "mock_certificate_config.json"
948950
config_file_content = json.dumps(config_data)
@@ -963,13 +965,25 @@ def test_{{ service.client_name|snake_case }}_get_mtls_endpoint_and_cert_source(
963965
assert cert_source is expected_cert_source
964966

965967
# Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never".
966-
with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}):
968+
with mock.patch.dict(
969+
os.environ,
970+
{
971+
"GOOGLE_API_USE_MTLS_ENDPOINT": "never",
972+
"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false",
973+
},
974+
):
967975
api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source()
968976
assert api_endpoint == client_class.DEFAULT_ENDPOINT
969977
assert cert_source is None
970978

971979
# Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always".
972-
with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}):
980+
with mock.patch.dict(
981+
os.environ,
982+
{
983+
"GOOGLE_API_USE_MTLS_ENDPOINT": "always",
984+
"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false",
985+
},
986+
):
973987
api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source()
974988
assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT
975989
assert cert_source is None

packages/google-cloud-spanner/google/cloud/spanner_v1/_helpers.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,20 +48,24 @@
4848
try:
4949
from opentelemetry.propagate import inject
5050
from opentelemetry.propagators.textmap import Setter
51+
from opentelemetry.semconv.resource import ResourceAttributes
52+
53+
HAS_OPENTELEMETRY_INSTALLED = True
54+
except ImportError:
55+
HAS_OPENTELEMETRY_INSTALLED = False
56+
57+
try:
5158
from opentelemetry.resourcedetector import gcp_resource_detector
5259
from opentelemetry.resourcedetector.gcp_resource_detector import (
5360
GoogleCloudResourceDetector,
5461
)
55-
from opentelemetry.semconv.resource import ResourceAttributes
5662

5763
# Overwrite the requests timeout for the detector.
5864
# This is necessary as the client will wait the full timeout if the
5965
# code is not run in a GCP environment, with the location endpoints available.
6066
gcp_resource_detector._TIMEOUT_SEC = 0.2
61-
62-
HAS_OPENTELEMETRY_INSTALLED = True
6367
except ImportError:
64-
HAS_OPENTELEMETRY_INSTALLED = False
68+
GoogleCloudResourceDetector = None
6569
import random
6670
from typing import List, Tuple
6771

packages/google-cloud-spanner/tests/unit/_async/test_database.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4211,14 +4211,16 @@ def __init__(self, name, instance=None):
42114211
self._sessions_manager = mock.Mock()
42124212
# Configure get_session to return sessions from the pool
42134213
self._sessions_manager.get_session = mock.AsyncMock(
4214-
side_effect=lambda tx_type: self._pool.get()
4215-
if hasattr(self, "_pool") and self._pool
4216-
else None
4214+
side_effect=lambda tx_type: (
4215+
self._pool.get() if hasattr(self, "_pool") and self._pool else None
4216+
)
42174217
)
42184218
self._sessions_manager.put_session = mock.AsyncMock(
4219-
side_effect=lambda session: self._pool.put(session)
4220-
if hasattr(self, "_pool") and self._pool
4221-
else None
4219+
side_effect=lambda session: (
4220+
self._pool.put(session)
4221+
if hasattr(self, "_pool") and self._pool
4222+
else None
4223+
)
42224224
)
42234225

42244226
@property

packages/google-cloud-spanner/tests/unit/gapic/spanner_admin_database_v1/test_database_admin.py

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -974,11 +974,20 @@ def test_database_admin_client_get_mtls_endpoint_and_cert_source(client_class):
974974
for config_data, expected_cert_source in test_cases:
975975
env = os.environ.copy()
976976
env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", None)
977+
env.pop("CLOUDSDK_CONTEXT_AWARE_USE_CLIENT_CERTIFICATE", None)
977978
with mock.patch.dict(os.environ, env, clear=True):
978979
config_filename = "mock_certificate_config.json"
979980
config_file_content = json.dumps(config_data)
980981
m = mock.mock_open(read_data=config_file_content)
981-
with mock.patch("builtins.open", m):
982+
with (
983+
mock.patch("builtins.open", m),
984+
mock.patch(
985+
"os.path.exists",
986+
side_effect=lambda path: (
987+
os.path.basename(path) == config_filename
988+
),
989+
),
990+
):
982991
with mock.patch.dict(
983992
os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename}
984993
):
@@ -1021,11 +1030,20 @@ def test_database_admin_client_get_mtls_endpoint_and_cert_source(client_class):
10211030
for config_data, expected_cert_source in test_cases:
10221031
env = os.environ.copy()
10231032
env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", "")
1033+
env.pop("CLOUDSDK_CONTEXT_AWARE_USE_CLIENT_CERTIFICATE", "")
10241034
with mock.patch.dict(os.environ, env, clear=True):
10251035
config_filename = "mock_certificate_config.json"
10261036
config_file_content = json.dumps(config_data)
10271037
m = mock.mock_open(read_data=config_file_content)
1028-
with mock.patch("builtins.open", m):
1038+
with (
1039+
mock.patch("builtins.open", m),
1040+
mock.patch(
1041+
"os.path.exists",
1042+
side_effect=lambda path: (
1043+
os.path.basename(path) == config_filename
1044+
),
1045+
),
1046+
):
10291047
with mock.patch.dict(
10301048
os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename}
10311049
):
@@ -1041,13 +1059,25 @@ def test_database_admin_client_get_mtls_endpoint_and_cert_source(client_class):
10411059
assert cert_source is expected_cert_source
10421060

10431061
# Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never".
1044-
with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}):
1062+
with mock.patch.dict(
1063+
os.environ,
1064+
{
1065+
"GOOGLE_API_USE_MTLS_ENDPOINT": "never",
1066+
"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false",
1067+
},
1068+
):
10451069
api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source()
10461070
assert api_endpoint == client_class.DEFAULT_ENDPOINT
10471071
assert cert_source is None
10481072

10491073
# Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always".
1050-
with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}):
1074+
with mock.patch.dict(
1075+
os.environ,
1076+
{
1077+
"GOOGLE_API_USE_MTLS_ENDPOINT": "always",
1078+
"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false",
1079+
},
1080+
):
10511081
api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source()
10521082
assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT
10531083
assert cert_source is None

packages/google-cloud-spanner/tests/unit/gapic/spanner_admin_instance_v1/test_instance_admin.py

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -960,11 +960,20 @@ def test_instance_admin_client_get_mtls_endpoint_and_cert_source(client_class):
960960
for config_data, expected_cert_source in test_cases:
961961
env = os.environ.copy()
962962
env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", None)
963+
env.pop("CLOUDSDK_CONTEXT_AWARE_USE_CLIENT_CERTIFICATE", None)
963964
with mock.patch.dict(os.environ, env, clear=True):
964965
config_filename = "mock_certificate_config.json"
965966
config_file_content = json.dumps(config_data)
966967
m = mock.mock_open(read_data=config_file_content)
967-
with mock.patch("builtins.open", m):
968+
with (
969+
mock.patch("builtins.open", m),
970+
mock.patch(
971+
"os.path.exists",
972+
side_effect=lambda path: (
973+
os.path.basename(path) == config_filename
974+
),
975+
),
976+
):
968977
with mock.patch.dict(
969978
os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename}
970979
):
@@ -1007,11 +1016,20 @@ def test_instance_admin_client_get_mtls_endpoint_and_cert_source(client_class):
10071016
for config_data, expected_cert_source in test_cases:
10081017
env = os.environ.copy()
10091018
env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", "")
1019+
env.pop("CLOUDSDK_CONTEXT_AWARE_USE_CLIENT_CERTIFICATE", "")
10101020
with mock.patch.dict(os.environ, env, clear=True):
10111021
config_filename = "mock_certificate_config.json"
10121022
config_file_content = json.dumps(config_data)
10131023
m = mock.mock_open(read_data=config_file_content)
1014-
with mock.patch("builtins.open", m):
1024+
with (
1025+
mock.patch("builtins.open", m),
1026+
mock.patch(
1027+
"os.path.exists",
1028+
side_effect=lambda path: (
1029+
os.path.basename(path) == config_filename
1030+
),
1031+
),
1032+
):
10151033
with mock.patch.dict(
10161034
os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename}
10171035
):
@@ -1027,13 +1045,25 @@ def test_instance_admin_client_get_mtls_endpoint_and_cert_source(client_class):
10271045
assert cert_source is expected_cert_source
10281046

10291047
# Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never".
1030-
with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}):
1048+
with mock.patch.dict(
1049+
os.environ,
1050+
{
1051+
"GOOGLE_API_USE_MTLS_ENDPOINT": "never",
1052+
"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false",
1053+
},
1054+
):
10311055
api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source()
10321056
assert api_endpoint == client_class.DEFAULT_ENDPOINT
10331057
assert cert_source is None
10341058

10351059
# Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always".
1036-
with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}):
1060+
with mock.patch.dict(
1061+
os.environ,
1062+
{
1063+
"GOOGLE_API_USE_MTLS_ENDPOINT": "always",
1064+
"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false",
1065+
},
1066+
):
10371067
api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source()
10381068
assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT
10391069
assert cert_source is None

packages/google-cloud-spanner/tests/unit/gapic/spanner_v1/test_spanner.py

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -921,11 +921,20 @@ def test_spanner_client_get_mtls_endpoint_and_cert_source(client_class):
921921
for config_data, expected_cert_source in test_cases:
922922
env = os.environ.copy()
923923
env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", None)
924+
env.pop("CLOUDSDK_CONTEXT_AWARE_USE_CLIENT_CERTIFICATE", None)
924925
with mock.patch.dict(os.environ, env, clear=True):
925926
config_filename = "mock_certificate_config.json"
926927
config_file_content = json.dumps(config_data)
927928
m = mock.mock_open(read_data=config_file_content)
928-
with mock.patch("builtins.open", m):
929+
with (
930+
mock.patch("builtins.open", m),
931+
mock.patch(
932+
"os.path.exists",
933+
side_effect=lambda path: (
934+
os.path.basename(path) == config_filename
935+
),
936+
),
937+
):
929938
with mock.patch.dict(
930939
os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename}
931940
):
@@ -968,11 +977,20 @@ def test_spanner_client_get_mtls_endpoint_and_cert_source(client_class):
968977
for config_data, expected_cert_source in test_cases:
969978
env = os.environ.copy()
970979
env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", "")
980+
env.pop("CLOUDSDK_CONTEXT_AWARE_USE_CLIENT_CERTIFICATE", "")
971981
with mock.patch.dict(os.environ, env, clear=True):
972982
config_filename = "mock_certificate_config.json"
973983
config_file_content = json.dumps(config_data)
974984
m = mock.mock_open(read_data=config_file_content)
975-
with mock.patch("builtins.open", m):
985+
with (
986+
mock.patch("builtins.open", m),
987+
mock.patch(
988+
"os.path.exists",
989+
side_effect=lambda path: (
990+
os.path.basename(path) == config_filename
991+
),
992+
),
993+
):
976994
with mock.patch.dict(
977995
os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename}
978996
):
@@ -988,13 +1006,25 @@ def test_spanner_client_get_mtls_endpoint_and_cert_source(client_class):
9881006
assert cert_source is expected_cert_source
9891007

9901008
# Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never".
991-
with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}):
1009+
with mock.patch.dict(
1010+
os.environ,
1011+
{
1012+
"GOOGLE_API_USE_MTLS_ENDPOINT": "never",
1013+
"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false",
1014+
},
1015+
):
9921016
api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source()
9931017
assert api_endpoint == client_class.DEFAULT_ENDPOINT
9941018
assert cert_source is None
9951019

9961020
# Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always".
997-
with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}):
1021+
with mock.patch.dict(
1022+
os.environ,
1023+
{
1024+
"GOOGLE_API_USE_MTLS_ENDPOINT": "always",
1025+
"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false",
1026+
},
1027+
):
9981028
api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source()
9991029
assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT
10001030
assert cert_source is None

packages/google-cloud-spanner/tests/unit/test__helpers.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ def _callFUT(self, *args, **kw):
104104

105105
return _get_cloud_region(*args, **kw)
106106

107+
@unittest.skipUnless(
108+
hasattr(_helpers, "GoogleCloudResourceDetector")
109+
and _helpers.GoogleCloudResourceDetector is not None,
110+
"opentelemetry-resourcedetector-gcp not installed",
111+
)
107112
@mock.patch("google.cloud.spanner_v1._helpers.GoogleCloudResourceDetector.detect")
108113
def test_get_location_with_region(self, mock_detect):
109114
"""Test that _get_cloud_region returns the region when detected."""
@@ -115,6 +120,11 @@ def test_get_location_with_region(self, mock_detect):
115120
location = self._callFUT()
116121
self.assertEqual(location, "us-central1")
117122

123+
@unittest.skipUnless(
124+
hasattr(_helpers, "GoogleCloudResourceDetector")
125+
and _helpers.GoogleCloudResourceDetector is not None,
126+
"opentelemetry-resourcedetector-gcp not installed",
127+
)
118128
@mock.patch("google.cloud.spanner_v1._helpers.GoogleCloudResourceDetector.detect")
119129
def test_get_location_without_region(self, mock_detect):
120130
"""Test that _get_cloud_region returns 'global' when no region is detected."""
@@ -124,6 +134,11 @@ def test_get_location_without_region(self, mock_detect):
124134
location = self._callFUT()
125135
self.assertEqual(location, "global")
126136

137+
@unittest.skipUnless(
138+
hasattr(_helpers, "GoogleCloudResourceDetector")
139+
and _helpers.GoogleCloudResourceDetector is not None,
140+
"opentelemetry-resourcedetector-gcp not installed",
141+
)
127142
@mock.patch("google.cloud.spanner_v1._helpers.GoogleCloudResourceDetector.detect")
128143
def test_get_location_with_exception(self, mock_detect):
129144
"""Test that _get_cloud_region returns 'global' and logs a warning on exception."""

packages/google-cloud-spanner/tests/unit/test_batch.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -759,7 +759,14 @@ def test_batch_write_no_request_options(self, mock_region):
759759
return_value="global",
760760
)
761761
def test_batch_write_end_to_end_tracing_enabled(self, mock_region):
762-
self._test_batch_write_with_request_options(enable_end_to_end_tracing=True)
762+
if ot_helpers.HAS_OPENTELEMETRY_INSTALLED:
763+
tracer = _opentelemetry_tracing.get_tracer()
764+
with tracer.start_as_current_span("test"):
765+
self._test_batch_write_with_request_options(
766+
enable_end_to_end_tracing=True
767+
)
768+
else:
769+
self._test_batch_write_with_request_options(enable_end_to_end_tracing=True)
763770

764771
@mock.patch(
765772
"google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region",

packages/google-cloud-spanner/tests/unit/test_database.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3658,14 +3658,16 @@ def _resource_info(self):
36583658
self._sessions_manager = mock.Mock()
36593659
# Configure get_session to return sessions from the pool
36603660
self._sessions_manager.get_session = mock.Mock(
3661-
side_effect=lambda tx_type: self._pool.get()
3662-
if hasattr(self, "_pool") and self._pool
3663-
else None
3661+
side_effect=lambda tx_type: (
3662+
self._pool.get() if hasattr(self, "_pool") and self._pool else None
3663+
)
36643664
)
36653665
self._sessions_manager.put_session = mock.Mock(
3666-
side_effect=lambda session: self._pool.put(session)
3667-
if hasattr(self, "_pool") and self._pool
3668-
else None
3666+
side_effect=lambda session: (
3667+
self._pool.put(session)
3668+
if hasattr(self, "_pool") and self._pool
3669+
else None
3670+
)
36693671
)
36703672

36713673
@property

0 commit comments

Comments
 (0)