Skip to content

Commit 22bc92c

Browse files
vjfridgeCodex GPT-6
andcommitted
fix: preserve flag flush fallback and wait for smoke readiness
Keep invalid timeout defaults numeric, initialize the smoke provider before invocation, and assert older tracer compatibility. Environment: Datadog workspace Co-Authored-By: Codex GPT-6 <noreply@localhost>
1 parent 5c81661 commit 22bc92c

4 files changed

Lines changed: 39 additions & 6 deletions

File tree

‎datadog_lambda/config.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ def _resolve_env(self, key, default=None, cast=None, depends_on_tracing=False):
8686

8787
flush_in_thread = _get_env("DD_FLUSH_IN_THREAD", "false", as_bool)
8888
feature_flag_flush_timeout_ms = _get_env(
89-
"DD_FEATURE_FLAG_FLUSH_TIMEOUT_MS", "500", float
89+
"DD_FEATURE_FLAG_FLUSH_TIMEOUT_MS", 500.0, float
9090
)
9191
flush_to_log = _get_env("DD_FLUSH_TO_LOG", "false", as_bool)
9292
logs_injection = _get_env("DD_LOGS_INJECTION", "true", as_bool)

‎tests/integration/FEATURE_FLAG_FLUSH.md‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ layer until the release record below is populated.
77
## Existing examples and access
88

99
The smoke handler initializes its provider and client once at module scope and
10-
reuses them across invocations.
10+
reuses them across invocations. Registration waits for provider initialization
11+
before the first invocation, bounded by the provider's default 10-second timeout.
1112

1213
This repository's `scripts/run_integration_tests.sh` documents
1314
`sso-serverless-sandbox-account-admin`. `tests/integration/serverless.yml` uses
@@ -22,7 +23,8 @@ Verify that the selected profile can access the approved account before deployin
2223
internal flush contract version 1 and this Lambda library. The ordinary layer
2324
build installs the declared tracer dependency, so verify the zip actually
2425
contains the candidate tracer instead of a published version without the fix.
25-
2. Package `feature_flags.py` and `openfeature-sdk`. Configure its handler as
26+
2. Package `feature_flags.py` and `openfeature-sdk==0.10.0` (which provides
27+
`set_provider_and_wait`). Configure its handler as
2628
`feature_flags.handle`. It uses the ordinary Datadog wrapper and has no flush
2729
or shutdown calls. Reuse the approved sandbox's IAM and deployment settings
2830
from `serverless.yml`, with a unique `integration-tests-*` function name.

‎tests/integration/feature_flags.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from openfeature.evaluation_context import EvaluationContext
1212

1313
provider = DataDogProvider()
14-
api.set_provider(provider)
14+
api.set_provider_and_wait(provider)
1515
client = api.get_client("lambda-flush-smoke")
1616
sandbox_id = uuid.uuid4().hex
1717
invocations = 0

‎tests/test_feature_flags.py‎

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import importlib.util
2+
import os
23
import unittest
34
from unittest.mock import Mock, patch
45

56
from datadog_lambda import feature_flags
67
from datadog_lambda import wrapper
8+
from datadog_lambda.config import Config
79

810

911
class FeatureFlagFlushTest(unittest.TestCase):
@@ -48,8 +50,37 @@ def test_no_budget(self):
4850

4951
def test_old_tracer(self):
5052
for telemetry in [None, Mock(FLUSH_API_VERSION=2)]:
51-
with patch.object(feature_flags, "_telemetry", telemetry):
52-
feature_flags.flush_feature_flag_telemetry(None)
53+
with self.subTest(telemetry=telemetry), patch.object(
54+
feature_flags, "_telemetry", telemetry
55+
):
56+
context = Mock()
57+
context.get_remaining_time_in_millis.return_value = 1000
58+
feature_flags.flush_feature_flag_telemetry(context)
59+
context.get_remaining_time_in_millis.assert_not_called()
60+
if telemetry is not None:
61+
telemetry.flush.assert_not_called()
62+
63+
def test_timeout_environment_parsing_preserves_flush(self):
64+
for value, expected in [
65+
(None, 0.5),
66+
("250.5", 0.2505),
67+
("", 0.5),
68+
("garbage", 0.5),
69+
("500ms", 0.5),
70+
]:
71+
with self.subTest(value=value), patch.dict(os.environ), patch.object(
72+
feature_flags, "config", Config()
73+
), patch.object(feature_flags, "_telemetry") as telemetry:
74+
if value is None:
75+
os.environ.pop("DD_FEATURE_FLAG_FLUSH_TIMEOUT_MS", None)
76+
else:
77+
os.environ["DD_FEATURE_FLAG_FLUSH_TIMEOUT_MS"] = value
78+
telemetry.FLUSH_API_VERSION = 1
79+
telemetry.flush.return_value = "completed"
80+
feature_flags.flush_feature_flag_telemetry(
81+
Mock(get_remaining_time_in_millis=lambda: 1000)
82+
)
83+
telemetry.flush.assert_called_once_with(expected)
5384

5485
def test_missing_context_and_telemetry_errors_are_safe(self):
5586
with patch.object(feature_flags, "_telemetry") as telemetry:

0 commit comments

Comments
 (0)