Skip to content

Commit 88915d4

Browse files
committed
test(observability): add test-only environment variable overrides and refactor tests
1 parent 09e8420 commit 88915d4

3 files changed

Lines changed: 118 additions & 18 deletions

File tree

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,22 @@
1-
from .options import is_signal_enabled
1+
from .options import (
2+
clear_test_env_overrides,
3+
is_signal_enabled,
4+
set_test_env_override,
5+
)
26

37
try:
48
# Tell flake8 that it's okay this is unused, it's just being exposed to the package namespace.
59
from .tracing import OtelSpanEnricher # noqa: F401
610

7-
__all__ = ["is_signal_enabled", "OtelSpanEnricher"]
11+
__all__ = [
12+
"is_signal_enabled",
13+
"set_test_env_override",
14+
"clear_test_env_overrides",
15+
"OtelSpanEnricher",
16+
]
817
except ImportError:
9-
__all__ = ["is_signal_enabled"]
18+
__all__ = [
19+
"is_signal_enabled",
20+
"set_test_env_override",
21+
"clear_test_env_overrides",
22+
]

packages/google-api-core/google/api_core/observability/options.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,31 @@ def _strtobool(val: str) -> Optional[bool]:
2121
raise ValueError(f"Invalid truth value: {val!r}")
2222

2323

24+
_TEST_ENV_OVERRIDES: Dict[str, bool] = {}
25+
26+
27+
def set_test_env_override(name: str, value: Optional[bool]) -> None:
28+
"""Sets a test-only override for a specific environment variable.
29+
30+
This is intended ONLY for unit/integration testing to prevent mutating
31+
os.environ.
32+
"""
33+
if value is None:
34+
_TEST_ENV_OVERRIDES.pop(name, None)
35+
else:
36+
_TEST_ENV_OVERRIDES[name] = value
37+
38+
39+
def clear_test_env_overrides() -> None:
40+
"""Clears all test-only overrides."""
41+
_TEST_ENV_OVERRIDES.clear()
42+
43+
2444
def _get_env_bool(name: str) -> Optional[bool]:
2545
"""Retrieve the boolean value of an environment variable."""
46+
if name in _TEST_ENV_OVERRIDES:
47+
return _TEST_ENV_OVERRIDES[name]
48+
2649
val = os.getenv(name)
2750
if val is None:
2851
return None

packages/google-api-core/tests/unit/observability/test_options.py

Lines changed: 79 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,72 @@
1+
# Copyright 2026 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
115
import pytest
216

317
from google.api_core.observability import options
18+
from google.api_core.observability.options import (
19+
_get_env_bool,
20+
_strtobool,
21+
clear_test_env_overrides,
22+
set_test_env_override,
23+
)
24+
25+
26+
@pytest.fixture(autouse=True)
27+
def clean_overrides():
28+
yield
29+
clear_test_env_overrides()
30+
31+
32+
@pytest.mark.parametrize(
33+
"value,expected",
34+
[
35+
("y", True),
36+
("yes", True),
37+
("t", True),
38+
("true", True),
39+
("on", True),
40+
("1", True),
41+
("n", False),
42+
("no", False),
43+
("f", False),
44+
("false", False),
45+
("off", False),
46+
("0", False),
47+
(" True ", True),
48+
(" FALSE ", False),
49+
("", None),
50+
],
51+
)
52+
def test_strtobool(value, expected):
53+
assert _strtobool(value) is expected
54+
55+
56+
def test_strtobool_invalid():
57+
with pytest.raises(ValueError):
58+
_strtobool("invalid")
59+
60+
61+
def test_get_env_bool(monkeypatch):
62+
monkeypatch.setenv("TEST_VAR", "true")
63+
assert _get_env_bool("TEST_VAR") is True
64+
65+
monkeypatch.setenv("TEST_VAR", "invalid")
66+
assert _get_env_bool("TEST_VAR") is None
67+
68+
monkeypatch.delenv("TEST_VAR", raising=False)
69+
assert _get_env_bool("TEST_VAR") is None
470

571

672
@pytest.mark.parametrize(
@@ -10,58 +76,56 @@
1076
({}, None, False, False),
1177
({}, None, True, True),
1278
# Service-specific env var
13-
({"GOOGLE_CLOUD_PYTHON_TRANSLATE_TRACES_ENABLED": "true"}, None, False, True),
14-
({"GOOGLE_CLOUD_PYTHON_TRANSLATE_TRACES_ENABLED": "false"}, None, True, False),
79+
({"GOOGLE_CLOUD_PYTHON_TRANSLATE_TRACES_ENABLED": True}, None, False, True),
80+
({"GOOGLE_CLOUD_PYTHON_TRANSLATE_TRACES_ENABLED": False}, None, True, False),
1581
# Experimental fallback
1682
(
17-
{"GOOGLE_CLOUD_EXPERIMENTAL_PYTHON_TRANSLATE_TRACES_ENABLED": "true"},
83+
{"GOOGLE_CLOUD_EXPERIMENTAL_PYTHON_TRANSLATE_TRACES_ENABLED": True},
1884
None,
1985
False,
2086
True,
2187
),
2288
# Precedence: Service specific overrides global
2389
(
2490
{
25-
"GOOGLE_CLOUD_PYTHON_TRACES_ENABLED": "true",
26-
"GOOGLE_CLOUD_PYTHON_TRANSLATE_TRACES_ENABLED": "false",
91+
"GOOGLE_CLOUD_PYTHON_TRACES_ENABLED": True,
92+
"GOOGLE_CLOUD_PYTHON_TRANSLATE_TRACES_ENABLED": False,
2793
},
2894
None,
2995
False,
3096
False,
3197
),
3298
(
3399
{
34-
"GOOGLE_CLOUD_PYTHON_TRACES_ENABLED": "false",
35-
"GOOGLE_CLOUD_PYTHON_TRANSLATE_TRACES_ENABLED": "true",
100+
"GOOGLE_CLOUD_PYTHON_TRACES_ENABLED": False,
101+
"GOOGLE_CLOUD_PYTHON_TRANSLATE_TRACES_ENABLED": True,
36102
},
37103
None,
38104
False,
39105
True,
40106
),
41107
# Precedence: Client options override env vars
42108
(
43-
{"GOOGLE_CLOUD_PYTHON_TRANSLATE_TRACES_ENABLED": "false"},
109+
{"GOOGLE_CLOUD_PYTHON_TRANSLATE_TRACES_ENABLED": False},
44110
{"enable_traces": True},
45111
False,
46112
True,
47113
),
48114
],
49115
)
50-
def test_is_signal_enabled(
51-
monkeypatch, env_vars, client_options, default_val, expected
52-
):
53-
# Setup environment variables using pytest's monkeypatch fixture
116+
def test_is_signal_enabled(env_vars, client_options, default_val, expected):
117+
# Setup environment variables using our test overrides
54118
for k, v in env_vars.items():
55-
monkeypatch.setenv(k, v)
119+
set_test_env_override(k, v)
56120

57121
result = options.is_signal_enabled(
58122
"translate", "traces", client_options=client_options, default=default_val
59123
)
60124
assert result is expected
61125

62126

63-
def test_legacy_var_with_warning(monkeypatch):
64-
monkeypatch.setenv("LEGACY_TRACE_VAR", "true")
127+
def test_legacy_var_with_warning():
128+
set_test_env_override("LEGACY_TRACE_VAR", True)
65129

66130
with pytest.warns(DeprecationWarning, match="LEGACY_TRACE_VAR"):
67131
result = options.is_signal_enabled(

0 commit comments

Comments
 (0)