Skip to content

Use canonical FFE fixtures - #6901

Draft
leoromanovsky wants to merge 8 commits into
mainfrom
leo.romanovsky/ffe-canonical-fixtures-20260512
Draft

Use canonical FFE fixtures#6901
leoromanovsky wants to merge 8 commits into
mainfrom
leo.romanovsky/ffe-canonical-fixtures-20260512

Conversation

@leoromanovsky

@leoromanovsky leoromanovsky commented May 12, 2026

Copy link
Copy Markdown
Contributor

Motivation

Use the shared FFE fixture corpus in System Tests. This prevents copied fixtures from drifting and exercises one contract across supported SDKs.

The same migration is merged in Java and libdatadog. The Go migration is approved. Related migrations are open for Python, JavaScript, Ruby, and .NET.

Changes and Decisions

  • Add DataDog/ffe-system-test-data as a submodule under the parametric FFE tests.
  • Remove copied evaluator fixtures and load the canonical configuration and evaluation cases.
  • Assert canonical values and reasons for all 236 evaluation cases.
  • Fail selected FFE tests with an initialization instruction when the submodule is missing.
  • Initialize submodules in GitHub and GitLab test workflows.
  • Configure weekly Dependabot updates for the submodule.
  • Keep known SDK gaps in narrowly scoped manifest entries.

@github-actions

github-actions Bot commented May 12, 2026

Copy link
Copy Markdown
Contributor

CODEOWNERS have been resolved as:

.github/dependabot.yml                                                  @DataDog/system-tests-core
.gitmodules                                                             @DataDog/system-tests-core
.github/workflows/ci.yml                                                @DataDog/system-tests-core
.github/workflows/compute_libraries_and_scenarios.yml                   @DataDog/system-tests-core
.github/workflows/lint.yml                                              @DataDog/system-tests-core
.github/workflows/run-exotics.yml                                       @DataDog/system-tests-core
.github/workflows/run-parametric.yml                                    @DataDog/system-tests-core
.github/workflows/system-tests.yml                                      @DataDog/system-tests-core
.gitlab-ci.yml                                                          @DataDog/system-tests-core
manifests/dotnet.yml                                                    @DataDog/apm-dotnet @DataDog/asm-dotnet
manifests/ruby.yml                                                      @DataDog/ruby-guild @DataDog/asm-ruby
tests/ffe/README.md                                                     @DataDog/feature-flagging-and-experimentation-sdk @DataDog/system-tests-core
tests/parametric/test_ffe/test_configuration_sources.py                 @DataDog/feature-flagging-and-experimentation-sdk @DataDog/system-tests-core
tests/parametric/test_ffe/test_dynamic_evaluation.py                    @DataDog/feature-flagging-and-experimentation-sdk @DataDog/system-tests-core
utils/ci/gitlab/templates.yml                                           @DataDog/system-tests-core
utils/mocked_backend/ffe.py                                             @DataDog/system-tests-core
tests/parametric/test_ffe/flags-v1.json                                 @DataDog/feature-flagging-and-experimentation-sdk @DataDog/system-tests-core
tests/parametric/test_ffe/test-case-boolean-false-assignment.json       @DataDog/feature-flagging-and-experimentation-sdk @DataDog/system-tests-core
tests/parametric/test_ffe/test-case-boolean-one-of-matches.json         @DataDog/feature-flagging-and-experimentation-sdk @DataDog/system-tests-core
tests/parametric/test_ffe/test-case-comparator-operator-flag.json       @DataDog/feature-flagging-and-experimentation-sdk @DataDog/system-tests-core
tests/parametric/test_ffe/test-case-disabled-flag.json                  @DataDog/feature-flagging-and-experimentation-sdk @DataDog/system-tests-core
tests/parametric/test_ffe/test-case-empty-flag.json                     @DataDog/feature-flagging-and-experimentation-sdk @DataDog/system-tests-core
tests/parametric/test_ffe/test-case-empty-string-variation.json         @DataDog/feature-flagging-and-experimentation-sdk @DataDog/system-tests-core
tests/parametric/test_ffe/test-case-falsy-value-assignments.json        @DataDog/feature-flagging-and-experimentation-sdk @DataDog/system-tests-core
tests/parametric/test_ffe/test-case-flag-with-empty-string.json         @DataDog/feature-flagging-and-experimentation-sdk @DataDog/system-tests-core
tests/parametric/test_ffe/test-case-integer-flag.json                   @DataDog/feature-flagging-and-experimentation-sdk @DataDog/system-tests-core
tests/parametric/test_ffe/test-case-kill-switch-flag.json               @DataDog/feature-flagging-and-experimentation-sdk @DataDog/system-tests-core
tests/parametric/test_ffe/test-case-new-user-onboarding-flag.json       @DataDog/feature-flagging-and-experimentation-sdk @DataDog/system-tests-core
tests/parametric/test_ffe/test-case-no-allocations-flag.json            @DataDog/feature-flagging-and-experimentation-sdk @DataDog/system-tests-core
tests/parametric/test_ffe/test-case-null-operator-flag.json             @DataDog/feature-flagging-and-experimentation-sdk @DataDog/system-tests-core
tests/parametric/test_ffe/test-case-numeric-flag.json                   @DataDog/feature-flagging-and-experimentation-sdk @DataDog/system-tests-core
tests/parametric/test_ffe/test-case-numeric-one-of.json                 @DataDog/feature-flagging-and-experimentation-sdk @DataDog/system-tests-core
tests/parametric/test_ffe/test-case-of-7-empty-targeting-key.json       @DataDog/feature-flagging-and-experimentation-sdk @DataDog/system-tests-core
tests/parametric/test_ffe/test-case-regex-flag.json                     @DataDog/feature-flagging-and-experimentation-sdk @DataDog/system-tests-core
tests/parametric/test_ffe/test-case-start-and-end-date-flag.json        @DataDog/feature-flagging-and-experimentation-sdk @DataDog/system-tests-core
tests/parametric/test_ffe/test-flag-that-does-not-exist.json            @DataDog/feature-flagging-and-experimentation-sdk @DataDog/system-tests-core
tests/parametric/test_ffe/test-json-config-flag.json                    @DataDog/feature-flagging-and-experimentation-sdk @DataDog/system-tests-core
tests/parametric/test_ffe/test-no-allocations-flag.json                 @DataDog/feature-flagging-and-experimentation-sdk @DataDog/system-tests-core
tests/parametric/test_ffe/test-special-characters.json                  @DataDog/feature-flagging-and-experimentation-sdk @DataDog/system-tests-core
tests/parametric/test_ffe/test-string-with-special-characters.json      @DataDog/feature-flagging-and-experimentation-sdk @DataDog/system-tests-core

@datadog-datadog-prod-us1

datadog-datadog-prod-us1 Bot commented May 13, 2026

Copy link
Copy Markdown

Pipelines  Tests

Unblock PR with BitsAI

⚠️ Warnings

🚦 27 Pipeline jobs failed

Testing the test | System Tests (dotnet, dev) / parametric / parametric (2)   View in Datadog   GitHub Actions

🔧 Fix in code. This looks caused by changes in this PR. 1 failed test. AssertionError: No RemoteConfig apply status found, got requests [] at tests/parametric/test_ffe/test_dynamic_evaluation.py:224.

🧪 1 Test failed · 🎯 related to the job error above

🎯 tests.parametric.test_ffe.test_dynamic_evaluation.Test_Feature_Flag_Dynamic_Evaluation.test_ffe_remote_config[library_env0, parametric-dotnet] from system_tests_suite   View in Datadog
AssertionError: No RemoteConfig apply status found, got requests [{'headers': {'Host': 'ddapm-test-agent-worker-gw7-5740354900026072187:8126', 'Datadog-Entity-ID': 'in-40901', 'Datadog-Meta-Lang': '.NET', 'Datadog-Meta-Tracer-Version': '3.51.0.0', 'x-datadog-tracing-enabled': 'false', 'Connection': 'close', 'Transfer-Encoding': 'chunked', 'Content-Type': 'application/json'}, 'body': {'client': {'state': {'root_version': 1, 'targets_version': 0, 'config_states': [], 'has_error': False, 'error': None, 'backend_client_state': None}, 'id': '885eec58-5c98-482e-91f9-9228cbacaa66', 'products': ['ASM_FEATURES', 'ASM_DD', 'FFE_FLAGS', 'APM_TRACING', 'AGENT_CONFIG', 'AGENT_TASK'], 'is_tracer': True, 'client_tracer': {'runtime_id': 'f3101a50-62e8-4674-8ec3-07075a851c5d', 'language': 'dotnet', 'tracer_version': '3.51.0', 'service': 'apmtestapi', 'process_tags': ['entrypoint.basedir:app', 'entrypoint.name:program', 'entrypoint.workdir:app', 'svc.auto:apmtestapi'], 'extra_services': None, 'env': None, 'app_version': None, 'tags': ['tracer_version:3.51.0', 'host_name:e3852b56b5d3', 'git.commit.sha:', 'git.repository_url:']}, 'capabilities': 'Y8CgCPf+'}, 'cached_target_files': []}, 'url': 'http://ddapm-test-agent-worker-gw7-5740354900026072187:8126/v0.7/config', 'method': 'POST'}, {'headers': {'Host': 'ddapm-test-agent-worker-gw7-5740354900026072187:8126', 'Datadog-Entity-ID': 'in-40901', 'Datadog-Meta-Lang': '.NET', 'Datadog-Meta-Tracer-Version': '3.51.0.0', 'x-datadog-tracing-enabled': 'false', 'Connection': 'close', 'Transfer-Encoding': 'chunked', 'traceparent': '00-0cebd5cc4e38641a17dd1d9fde81bf3a-289867dbf1d487de-00', 'Content-Type': 'application/json'}, 'body': {'client': {'state': {'root_version': 1, 'targets_version': 0, 'config_states': [], 'has_error': False, 'error': None, 'backend_client_state': None}, 'id': '885eec58-5c98-482e-91f9-9228cbacaa66', 'products': ['ASM_FEATURES', 'ASM_DD', 'FFE_FLAGS', 'APM_TRACING', 'AGENT_CONFIG', 'AGENT_TASK', 'LIVE_DEBUGGING_SYMBOL_DB'], 'is_tracer': True, 'client_tracer': {'runtime_id': 'f3101a50-62e8-4674-8ec3-07075a851c5d', 'language': 'dotnet', 'tracer_version': '3.51.0', 'service': 'apmtestapi', 'process_tags': ['entrypoint.basedir:app', 'entrypoint.name:program', 'entrypoint.workdir:app', 'svc.auto:apmtestapi'], 'extra_services': None, 'env': None, 'app_version': None, 'tags': ['tracer_version:3.51.0', 'host_name:e3852b56b5d3', 'git.commit.sha:', 'git.repository_url:']}, 'capabilities': 'Y8CgCPf+'}, 'cached_target_files': []}, 'url': 'http://ddapm-test-agent-worker-gw7-5740354900026072187:8126/v0.7/config', 'method': 'POST'}, {'headers': {'Host': 'ddapm-test-agent-worker-gw7-5740354900026072187:8126', 'Datadog-Entity-ID': 'in-40901', 'Datadog-Meta-Lang': '.NET', 'Datadog-Meta-Tracer-Version': '3.51.0.0', 'x-datadog-tracing-enabled': 'false', 'Connection': 'close', 'Transfer-Encoding': 'chunked', 'traceparent': '00-f8cf3da9dad7e1e5bde65f058607a40e-b0b7cedafb3899bb-00', 'Content-Type': 'application/json'}, 'body': {'client': {'state': {'root_version': 1, 'targets_version': 0, 'config_states': [], 'has_error': False, 'error': None, 'backend_client_state': None}, 'id': '885eec58-5c98-482e-91f9-9228cbacaa66', 'products': ['ASM_FEATURES', 'ASM_DD', 'FFE_FLAGS', 'APM_TRACING', 'AGENT_CONFIG', 'AGENT_TASK', 'LIVE_DEBUGGING_SYMBOL_DB'], 'is_tracer': True, 'client_tracer': {'runtime_id': 'f3101a50-62e8-4674-8ec3-07075a851c5d', 'language': 'dotnet', 'tracer_version': '3.51.0', 'service': 'apmtestapi', 'process_tags': ['entrypoint.basedir:app', 'entrypoint.name:program', 'entrypoint.workdir:app', 'svc.auto:apmtestapi'], 'extra_services': None, 'env': None, 'app_version': None, 'tags': ['tracer_version:3.51.0', 'host_name:e3852b56b5d3', 'git.commit.sha:', 'git.repository_url:']}, 'capabilities': 'Y8CgCPf+'}, 'cached_target_files': []}, 'url': 'http://ddapm-test-agent-worker-gw7-5740354900026072187:8126/v0.7/config', 'method': 'POST'}, {'headers': {'Host': 'ddapm-test-agent-worker-gw7-5740354900026072187:8126', 'Datadog-Entity-ID': 'in-40901', 'Datadog-Meta-Lang': '.NET', 'Datadog-Meta-Tracer-Version': '3.51.0.0', 'x-datadog-tracing-enabled': 'false', 'Connection': 'close', 'Transfer-Encoding': 'chunked', 'traceparent': '00-99d122a3af7890ac7d55044fa2b99c23-40072de5f1c9cbb9-00', 'Content-Type': 'application/json'}, 'body': {'client': {'state': {'root_version': 1, 'targets_version': 0, 'config_states': [], 'has_error': False, 'error': None, 'backend_client_state': None}, 'id': '885eec58-5c98-482e-91f9-9228cbacaa66', 'products': ['ASM_FEATURES', 'ASM_DD', 'FFE_FLAGS', 'APM_TRACING', 'AGENT_CONFIG', 'AGENT_TASK', 'LIVE_DEBUGGING_SYMBOL_DB'], 'is_tracer': True, 'client_tracer': {'runtime_id': 'f3101a50-62e8-4674-8ec3-07075a851c5d', 'language': 'dotnet', 'tracer_version': '3.51.0', 'service': 'apmtestapi', 'process_tags': ['entrypoint.basedir:app', 'entrypoint.name:program', 'entrypoint.workdir:app', 'svc.auto:apmtestapi'], 'extra_services': None, 'env': None, 'app_version': None, 'tags': ['

Testing the test | System Tests (nodejs, dev) / parametric / parametric (2)   View in Datadog   GitHub Actions

🔧 Fix in code. This looks caused by changes in this PR. Test run failed. Assertion Error: Test case 0 in test-case-of-7-empty-targeting-key.json failed: flag='empty-targeting-key-flag', targetingKey='', expected reason=STATIC, actual reason=DEFAULT

🧪 25 Tests failed · 🎯 related to the job error above

🎯 tests.parametric.test_ffe.test_dynamic_evaluation.Test_Feature_Flag_Dynamic_Evaluation.test_ffe_flag_evaluation[test-case-of-7-empty-targeting-key.json-library_env0, parametric-nodejs] from system_tests_suite   View in Datadog
AssertionError: Test case 0 in test-case-of-7-empty-targeting-key.json failed: flag='empty-targeting-key-flag', targetingKey='', expected reason=STATIC, actual reason=DEFAULT
assert 'DEFAULT' == 'STATIC'
  - STATIC
  + DEFAULT

self = <tests.parametric.test_ffe.test_dynamic_evaluation.Test_Feature_Flag_Dynamic_Evaluation object at 0x7f6d637b7e30>
test_case_file = 'test-case-of-7-empty-targeting-key.json'
ufc_fixture_data = {'createdAt': '2024-04-17T19:40:53.716Z', 'environment': {'name': 'Test', 'unknownEnvironmentField': 'ignored'}, 'flag...ations': [], 'enabled': False, 'key': 'disabled_flag', 'variationType': 'INTEGER', ...}, ...}, 'format': 'SERVER', ...}
test_agent = <utils.docker_fixtures._test_agent.TestAgentAPI object at 0x7f6d623ebad0>
test_library = <utils.docker_fixtures._test_clients._test_client_parametric.ParametricTestClientApi object at 0x7f6d6234b770>
...
View all failed tests

Testing the test | System Tests (php, dev) / parametric / parametric (2)   View in Datadog   GitHub Actions

🔧 Fix in code. This looks caused by changes in this PR. 6 failed tests. Assertion Error: failed evaluations for 'test-case-empty-flag.json', 'test-case-invalid-shard-bounds-isolation.json', 'test-case-disabled-flag.json', 'test-case-malformed-flag-isolation.json', 'test-case-missing-split-shards-isolation.json', and 'test-case-unknown-operator-isolation.json'.

🧪 6 Tests failed · 🎯 related to the job error above

🎯 tests.parametric.test_ffe.test_dynamic_evaluation.Test_Feature_Flag_Dynamic_Evaluation.test_ffe_flag_evaluation[test-case-disabled-flag.json-library_env0, parametric-php] from system_tests_suite   View in Datadog
AssertionError: Test case 0 in test-case-disabled-flag.json failed: flag='disabled_flag', targetingKey='alice', expected reason=DISABLED, actual reason=ERROR
assert 'ERROR' == 'DISABLED'
  - DISABLED
  + ERROR

self = <tests.parametric.test_ffe.test_dynamic_evaluation.Test_Feature_Flag_Dynamic_Evaluation object at 0x7fed0d1e3f20>
test_case_file = 'test-case-disabled-flag.json'
ufc_fixture_data = {'createdAt': '2024-04-17T19:40:53.716Z', 'environment': {'name': 'Test', 'unknownEnvironmentField': 'ignored'}, 'flag...ations': [], 'enabled': False, 'key': 'disabled_flag', 'variationType': 'INTEGER', ...}, ...}, 'format': 'SERVER', ...}
test_agent = <utils.docker_fixtures._test_agent.TestAgentAPI object at 0x7fecd9aaa330>
test_library = <utils.docker_fixtures._test_clients._test_client_parametric.ParametricTestClientApi object at 0x7fecda1a03b0>
...
🎯 tests.parametric.test_ffe.test_dynamic_evaluation.Test_Feature_Flag_Dynamic_Evaluation.test_ffe_flag_evaluation[test-case-empty-flag.json-library_env0, parametric-php] from system_tests_suite   View in Datadog
AssertionError: Test case 0 in test-case-empty-flag.json failed: flag='empty_flag', targetingKey='alice', expected reason=DEFAULT, actual reason=ERROR
assert 'ERROR' == 'DEFAULT'
  - DEFAULT
  + ERROR

self = <tests.parametric.test_ffe.test_dynamic_evaluation.Test_Feature_Flag_Dynamic_Evaluation object at 0x7f2b377dc080>
test_case_file = 'test-case-empty-flag.json'
ufc_fixture_data = {'createdAt': '2024-04-17T19:40:53.716Z', 'environment': {'name': 'Test', 'unknownEnvironmentField': 'ignored'}, 'flag...ations': [], 'enabled': False, 'key': 'disabled_flag', 'variationType': 'INTEGER', ...}, ...}, 'format': 'SERVER', ...}
test_agent = <utils.docker_fixtures._test_agent.TestAgentAPI object at 0x7f2b07556780>
test_library = <utils.docker_fixtures._test_clients._test_client_parametric.ParametricTestClientApi object at 0x7f2b07555b50>
...
🎯 tests.parametric.test_ffe.test_dynamic_evaluation.Test_Feature_Flag_Dynamic_Evaluation.test_ffe_flag_evaluation[test-case-invalid-shard-bounds-isolation.json-library_env0, parametric-php] from system_tests_suite   View in Datadog
AssertionError: Test case 0 in test-case-invalid-shard-bounds-isolation.json failed: flag='overflow-total-shards-flag', targetingKey='alice', expected reason=DEFAULT, actual reason=ERROR
assert 'ERROR' == 'DEFAULT'
  - DEFAULT
  + ERROR

self = <tests.parametric.test_ffe.test_dynamic_evaluation.Test_Feature_Flag_Dynamic_Evaluation object at 0x7f73bd963d10>
test_case_file = 'test-case-invalid-shard-bounds-isolation.json'
ufc_fixture_data = {'createdAt': '2024-04-17T19:40:53.716Z', 'environment': {'name': 'Test', 'unknownEnvironmentField': 'ignored'}, 'flag...ations': [], 'enabled': False, 'key': 'disabled_flag', 'variationType': 'INTEGER', ...}, ...}, 'format': 'SERVER', ...}
test_agent = <utils.docker_fixtures._test_agent.TestAgentAPI object at 0x7f73bcacbad0>
test_library = <utils.docker_fixtures._test_clients._test_client_parametric.ParametricTestClientApi object at 0x7f73bcd7a7b0>
...
View all failed tests

View all 27 failed jobs.

📋 Copy prompt for your agent
CI on my pull request is failing. Help me find and fix the root cause of each failing job below — they were flagged as caused by changes in this PR, so focus on the diff. For each job, explain the failure and propose a fix.

Branch: leo.romanovsky/ffe-canonical-fixtures-20260512

Testing the test | System Tests (dotnet, dev) / parametric / parametric (2)
Commit: 946258aa92c9cadecbbdba943ca9b0c81f309327
Error (code / test):
1 failed test. AssertionError: No RemoteConfig apply status found, got requests [] at tests/parametric/test_ffe/test_dynamic_evaluation.py:224.
CI job: https://github.com/DataDog/system-tests/actions/runs/30771273562/job/91567499463

Testing the test | System Tests (nodejs, dev) / parametric / parametric (2)
Commit: 946258aa92c9cadecbbdba943ca9b0c81f309327
Error (code / test):
4 failed tests. Assertion Error: Test case 0 in test-case-of-7-empty-targeting-key.json failed: flag='empty-targeting-key-flag', targetingKey='', expected reason=STATIC, actual reason=DEFAULT
CI job: https://github.com/DataDog/system-tests/actions/runs/30771273562/job/91567499292

Testing the test | System Tests (php, dev) / parametric / parametric (2)
Commit: 946258aa92c9cadecbbdba943ca9b0c81f309327
Error (code / test):
6 failed tests. Assertion Error: failed evaluations for 'test-case-empty-flag.json', 'test-case-invalid-shard-bounds-isolation.json', 'test-case-disabled-flag.json', 'test-case-malformed-flag-isolation.json', 'test-case-missing-split-shards-isolation.json', and 'test-case-unknown-operator-isolation.json'.
CI job: https://github.com/DataDog/system-tests/actions/runs/30771273562/job/91567499588

Plus 6 more failing jobs not shown here.

ℹ️ Info

No other issues found (see more)

❄️ No new flaky tests detected

🔄 Datadog auto-retried 4 jobs - 0 passed on retry View in Datadog

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 1b018b5 | Docs | Datadog PR Page | Give us feedback!

@leoromanovsky
leoromanovsky force-pushed the leo.romanovsky/ffe-canonical-fixtures-20260512 branch from cf3498a to 9be6f96 Compare July 13, 2026 17:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant