Skip to content

Add parametric test: thread UFC serialId through flagMetadata - #7820

Merged
gh-worker-dd-mergequeue-cf854d[bot] merged 8 commits into
mainfrom
ffe-serial-id-metadata-system-test
Oct 16, 2026
Merged

gh-worker-dd-mergequeue-cf854d[bot] merged 8 commits into
mainfrom
ffe-serial-id-metadata-system-test

Conversation

@hhan2024

@hhan2024 hhan2024 commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Add shared parametric system tests for the contract that SDKs expose the selected UFC split's serialId in flag-evaluation metadata when span enrichment is enabled. The tests inspect the SDK's evaluation details through the parametric adapter; adapters must forward actual SDK metadata rather than reconstruct serial IDs from the configuration.

This PR introduces the tests and intentionally marks all eight language manifests (cpp, dotnet, golang, java, nodejs, php, python, ruby) as missing_feature. The SDK-specific PRs below expose metadata through the adapters, identify any SDK implementation gaps, and enable the tests at verified versions.

Contract

  1. Flag-evaluation details always expose flagMetadata. When there is no metadata, the field may be an empty map or null; the field itself must not be omitted.
  2. When span enrichment is enabled and the selected UFC split has a serial ID, that ID must appear in flag metadata. Positive IDs and zero are valid; zero must not be dropped by a truthiness check. A null or empty metadata map does not satisfy this case.
  3. When the selected split has no serial ID, the serial-ID key must be absent. A key with a null value does not count as omission. With span enrichment enabled, a missing UFC serial ID is the only case where the serial-ID key is expected to be absent. Other metadata may still be present.
  4. The ID must match the split actually selected by targeting and remain consistent across repeated evaluations of the same configuration and context.
  5. .NET is the only representation exception: it returns the serial ID as an exact decimal string (for example, "42" or "0"); all other SDKs return a numeric value. .NET uses strings to preserve Int64 serial IDs through an OpenFeature metadata API whose integer getter only supports Int32. No response coercion is used to make the test pass.

The contract does not require serial-ID metadata when span enrichment is disabled.

The tests use each SDK's metadata key: Go uses dd.serialId; the other server SDKs use __dd_split_serial_id. The Go key handling and .NET string exception are implemented in their respective stacked PRs below, not in this parent branch alone.

Implementation

  • Add tests/parametric/test_ffe/test_serial_id_metadata.py with five cases: positive ID, zero ID, missing-ID key omission, targeting-selected IDs, and repeated evaluations.
  • Add serial-id-metadata-flags.json with fixtures for those cases, including separate targeted allocations with distinct serial IDs.
  • Explicitly enable flagging and span enrichment via DD_EXPERIMENTAL_FLAGGING_PROVIDER_ENABLED=true and DD_EXPERIMENTAL_FLAGGING_PROVIDER_SPAN_ENRICHMENT_ENABLED=true.
  • Deliver the UFC fixture through Remote Config, wait for acknowledgement, and retry evaluations while the provider is not ready.
  • Add the feature_flags_serial_id_metadata feature marker (NOT_REPORTED_ID pending an assigned feature-parity ID).
  • Use the approved utils.pytest facade, including the upstream facade on this branch so both PR-head and merged-tree imports work.

Server SDK test-enablement PRs

All seven system-tests PRs are stacked directly on this PR's branch, ffe-serial-id-metadata-system-test, rather than on one another. Version floors below are locally verified floors, not claims that every earlier release fails.

Server SDK System-tests PR Enablement / dependency
Go #7844 Enables from v2.10.1; forwards SDK metadata and checks the native dd.serialId key. No SDK change required.
Node.js #7852 Enables from v6.18.0; uses evaluation-detail APIs and forwards metadata. No SDK change required.
Python #7853 Enables from v4.15.2; forwards SDK metadata. No SDK change required.
Java #7854 Enables from v1.66.0; uses evaluation-detail APIs and forwards metadata. No SDK change required.
.NET #7858 Enables from v3.54.0; adds FFE endpoints and the .NET-only string expectation. No SDK change required.
Ruby #7856 Draft; forwards metadata and depends on dd-trace-rb #6400. Retains missing_feature until the SDK fix is merged and its release version is known.
PHP #7857 Draft; preserves metadata as a JSON map and depends on dd-trace-php #4247. Retains missing_feature until the SDK fix is merged and its release version is known.

C++ remains missing_feature; there is no C++ activation PR in this set.

Validation

  • Parent test-module import and repository formatting/lint checks passed, including the merged-main import policy.
  • All five serial-ID tests passed without force overrides in the Go, Node.js, Python, Java, and .NET activation branches at the versions above.
  • Ruby and PHP candidate SDK fixes passed all five serial-ID cases locally; those tests are not yet enabled for released SDKs. Their SDK unit-test and lint evidence is recorded in the linked PRs.
  • Node.js, Python, and Java also passed all 24 dynamic-evaluation regression cases. The .NET draft documents two separate JSON-default/no-allocation failures from that regression suite; these are not serial-ID failures and are not hidden by this contract exception.

Follow-up

  • Assign a real feature-parity ID to replace NOT_REPORTED_ID.
  • Merge the SDK-specific adapter/activation PRs alongside this shared test foundation.
  • For Ruby and PHP, merge the SDK fixes and select their release floors before replacing missing_feature.

@hhan2024
hhan2024 requested review from a team as code owners September 24, 2026 22:32
@hhan2024
hhan2024 requested review from danyal002 and leoromanovsky and removed request for a team September 24, 2026 22:32
@github-actions

github-actions Bot commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

CODEOWNERS have been resolved as:

tests/parametric/test_ffe/serial-id-metadata-flags.json                 @DataDog/feature-flagging-and-experimentation-sdk
tests/parametric/test_ffe/test_serial_id_metadata.py                    @DataDog/feature-flagging-and-experimentation-sdk
manifests/cpp.yml                                                       @DataDog/system-tests-reviewers
manifests/dotnet.yml                                                    @DataDog/system-tests-reviewers
manifests/golang.yml                                                    @DataDog/system-tests-reviewers
manifests/java.yml                                                      @DataDog/system-tests-reviewers
manifests/nodejs.yml                                                    @DataDog/system-tests-reviewers
manifests/php.yml                                                       @DataDog/system-tests-reviewers
manifests/python.yml                                                    @DataDog/system-tests-reviewers
manifests/ruby.yml                                                      @DataDog/system-tests-reviewers
manifests/rust.yml                                                      @DataDog/system-tests-reviewers
tests/parametric/test_ffe/test_dynamic_evaluation.py                    @DataDog/feature-flagging-and-experimentation-sdk
utils/_features.py                                                      @DataDog/system-tests-core

@hhan2024
hhan2024 marked this pull request as draft September 24, 2026 22:33

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 194539dc51

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9547cefa87

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread tests/parametric/test_ffe/test_serial_id_metadata.py Outdated
@hhan2024
hhan2024 force-pushed the ffe-serial-id-metadata-system-test branch from 9547cef to ea6ec3f Compare September 30, 2026 16:24

@leoromanovsky leoromanovsky left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

Comment thread utils/_features.py Outdated
hhan2024 and others added 2 commits October 15, 2026 17:09
Every UFC split has a stable per-org serialId used by downstream consumers
(APM span enrichment, exposure caching, evaluation-metrics correlation) to
identify the exact (allocation, variant) pair that was assigned. Today only
the Node server SDK (openfeature-js-client#269) exposes this via
flagMetadata["__dd_split_serial_id"]; this test generalizes the contract
so every SDK can be validated the same way.

Adds a dedicated fixture covering: a plain serialId, serialId=0 (a valid ID
that must not be dropped by a truthiness check), a split with no serialId
(must not fabricate one), and two allocations with different serialIds
selected via targeting.

All languages are marked missing_feature: verified directly against the
Node.js and Go parametric weblog handlers that neither returns flagMetadata
from POST /ffe/evaluate today.

The new feature_flags_serial_id_metadata marker uses NOT_REPORTED_ID
pending a real feature-parity page.

Co-authored-by: helen.han <helen.han@datadoghq.com>
Exclude the UFC configuration from evaluation-case discovery, disable the
new suite for Rust, and require successful evaluation before accepting an
absent serial ID. Apply the repository formatter to the new test module.

Environment: Datadog workspace

Co-authored-by: Leo Romanovsky <leo.romanovsky@datadoghq.com>
hhan2024 and others added 5 commits October 15, 2026 17:10
Fail evaluations that omit flagMetadata while allowing null or empty metadata when a split has no serial ID.

Environment: Datadog workspace

Co-Authored-By: Codex GPT-5 <noreply@localhost>

Co-authored-by: hhan2024 <helen.han@datadoghq.com>
Tighten the missing-serial-ID test so an SDK cannot serialize an absent UFC serial ID as a null metadata entry.

Environment: Datadog workspace

Co-Authored-By: Codex GPT-5 <noreply@localhost>

Co-authored-by: hhan2024 <helen.han@datadoghq.com>
Exercise serial-ID flag metadata under the required span-enrichment configuration for positive, zero, and missing UFC serial IDs.

Environment: Datadog workspace

Co-Authored-By: Codex GPT-5 <noreply@localhost>

Co-authored-by: hhan2024 <helen.han@datadoghq.com>
Fix the import-policy failure when the PR is tested against current main.

Environment: Datadog workspace

Co-Authored-By: Codex GPT-6 <noreply@localhost>

Co-authored-by: hhan2024 <helen.han@datadoghq.com>
Use the registered Feature Parity entry for FFE serial ID metadata.

Environment: Datadog workspace

Co-Authored-By: Codex GPT-5 <noreply@localhost>
@hhan2024
hhan2024 force-pushed the ffe-serial-id-metadata-system-test branch from b59cca6 to 4352704 Compare October 15, 2026 17:12
@hhan2024
hhan2024 requested a review from cbeauchesne October 15, 2026 17:26
Start the provider without injecting the UFC fixture after Remote Config acknowledgement.

Environment: Datadog workspace

Co-Authored-By: Codex GPT-6 <noreply@localhost>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants