Skip to content

Enable PHP FFE evaluation system tests#7003

Merged
leoromanovsky merged 9 commits into
mainfrom
leo.romanovsky/pr-g-php-ffe-scaffold
May 29, 2026
Merged

Enable PHP FFE evaluation system tests#7003
leoromanovsky merged 9 commits into
mainfrom
leo.romanovsky/pr-g-php-ffe-scaffold

Conversation

@leoromanovsky
Copy link
Copy Markdown
Contributor

@leoromanovsky leoromanovsky commented May 21, 2026

Motivation

The PHP Feature Flags and Experimentation evaluation runtime has landed in dd-trace-php and is published through the v1.21.0-dev artifact. PHP should run the shared FFE system tests so the runtime path is covered by live FFE_FLAGS Remote Config delivery and by the canonical JSON evaluation fixtures used across libraries.

Reference design doc: https://docs.google.com/document/d/1NvMfTpZWLBlFmEFNjdnlMyeVpy5l7KD8qujGFco6w2w/edit?tab=t.0

Changes

This PR enables the existing end-to-end tests/ffe/test_dynamic_evaluation.py suite for PHP starting at v1.21.0-dev and adds the minimal PHP weblog /ffe endpoint needed by that shared suite. The endpoint calls the DDTrace\FeatureFlags\Client details API, normalizes the request shape used by system-tests, and returns provider-not-ready defaults when the runtime is unavailable.

This PR also enables the parametric canonical JSON fixture evaluation suite for PHP. The PHP parametric server implements /ffe/start and /ffe/evaluate using the same Datadog client API, and OF.7 is covered through test-case-of-7-empty-targeting-key.json in the shared parametrized test.

Decisions

The parametric evaluation test still sets FFE_FLAGS through Remote Config and waits for the test-agent to observe an acknowledged apply state. For the PHP parametric CLI process, that ACK is not enough to make the native evaluator report loaded config: CI on 1d6ac67 showed every dynamic evaluation case still returning PROVIDER_NOT_READY with providerState.hasConfig == false after the retry loop.

To keep the parametric suite deterministic, /ffe/start accepts the canonical UFC fixture payload uniformly. Existing non-PHP parametric servers ignore that optional payload; PHP uses it to seed the native evaluator through DDTrace\Testing\ffe_load_config before constructing the client. The shared test still has no PHP branch, and the explicit readiness check remains so failures show whether the provider is still waiting for config.

The scope is deliberately evaluation-only. Exposure forwarding and feature_flag.evaluations metrics remain disabled here so they can be enabled in separate stacked PRs after their runtime implementations are ready.

Verification

Current branch checks:

$ ./format.sh
All good, the system-tests CI will be happy!
$ TEST_LIBRARY=php ./run.sh PARAMETRIC --skip-parametric-build tests/parametric/test_ffe/test_dynamic_evaluation.py::Test_Feature_Flag_Dynamic_Evaluation --collect-only -q
24 tests collected

The collected set includes test-case-of-7-empty-targeting-key.json, so OF.7 is covered by the generic JSON parametrization.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 21, 2026

CODEOWNERS have been resolved as:

utils/build/docker/php/common/ffe.php                                   @DataDog/apm-php @DataDog/system-tests-core
docs/understand/weblogs/end-to-end_weblog.md                            @DataDog/system-tests-core
manifests/dotnet.yml                                                    @DataDog/apm-dotnet @DataDog/asm-dotnet
manifests/java.yml                                                      @DataDog/asm-java @DataDog/apm-java
manifests/nodejs.yml                                                    @DataDog/dd-trace-js
manifests/php.yml                                                       @DataDog/apm-php @DataDog/asm-php
tests/parametric/test_ffe/test_dynamic_evaluation.py                    @DataDog/feature-flagging-and-experimentation-sdk @DataDog/system-tests-core
utils/build/docker/php/common/rewrite-rules.conf                        @DataDog/apm-php @DataDog/system-tests-core
utils/build/docker/php/parametric/server.php                            @DataDog/apm-php @DataDog/system-tests-core
utils/docker_fixtures/_test_clients/_test_client_parametric.py          @DataDog/system-tests-core

@leoromanovsky leoromanovsky changed the title Add PHP FFE system-test scaffold Enable PHP FFE parametric system tests May 22, 2026
@datadog-prod-us1-4
Copy link
Copy Markdown

datadog-prod-us1-4 Bot commented May 22, 2026

Tests

🎉 All green!

🧪 All tests passed
❄️ No new flaky tests detected

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

@leoromanovsky leoromanovsky force-pushed the leo.romanovsky/pr-g-php-ffe-scaffold branch from 4ca7546 to 984548d Compare May 28, 2026 02:54
@leoromanovsky leoromanovsky changed the title Enable PHP FFE parametric system tests Enable PHP FFE evaluation system tests May 28, 2026
@leoromanovsky leoromanovsky marked this pull request as ready for review May 28, 2026 21:09
@leoromanovsky leoromanovsky requested review from a team as code owners May 28, 2026 21:09
@leoromanovsky leoromanovsky requested review from sameerank and typotter and removed request for a team May 28, 2026 21:10
Comment thread manifests/php.yml
Comment thread tests/parametric/test_ffe/test_dynamic_evaluation.py Outdated
Comment thread tests/parametric/test_ffe/test_dynamic_evaluation.py Outdated
@leoromanovsky leoromanovsky requested review from a team as code owners May 28, 2026 23:30
def ffe_start(self, configuration: dict | None = None) -> bool:
"""Initialize the FFE (Feature Flagging & Experimentation) provider."""
return self._client.ffe_start()
return self._client.ffe_start(configuration)
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.

You don't have to do this, you can also rely on RC polling and do a small loop with a few sleeps until RC data is available?

Comment thread manifests/dotnet.yml
tests/parametric/test_dynamic_configuration.py::TestDynamicConfigV2: v2.44.0
tests/parametric/test_ffe/test_dynamic_evaluation.py::Test_Feature_Flag_Dynamic_Evaluation: '>=3.36.0' # Modified by easy win activation script
tests/parametric/test_ffe/test_dynamic_evaluation.py::Test_Feature_Flag_Dynamic_Evaluation::test_ffe_flag_evaluation: missing_feature # Created by easy win activation script
tests/parametric/test_ffe/test_dynamic_evaluation.py::Test_Feature_Flag_Dynamic_Evaluation::test_ffe_of7_empty_targeting_key: missing_feature # Created by easy win activation script
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This was fixed; removing

Comment thread manifests/java.yml
tests/parametric/test_dynamic_configuration.py::TestDynamicConfigV1_ServiceTargets::test_not_match_service_target: irrelevant (APMAPI-1003)
tests/parametric/test_dynamic_configuration.py::TestDynamicConfigV2: v1.31.0
tests/parametric/test_ffe/test_dynamic_evaluation.py::Test_Feature_Flag_Dynamic_Evaluation: v1.56.0
tests/parametric/test_ffe/test_dynamic_evaluation.py::Test_Feature_Flag_Dynamic_Evaluation::test_ffe_of7_empty_targeting_key: bug (FFL-1729)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This was fixed; removing

Comment thread manifests/nodejs.yml
tests/parametric/test_dynamic_configuration.py::TestDynamicConfigV1_ServiceTargets::test_not_match_service_target: bug (APMAPI-865)
tests/parametric/test_dynamic_configuration.py::TestDynamicConfigV2: *ref_4_23_0
tests/parametric/test_ffe/test_dynamic_evaluation.py::Test_Feature_Flag_Dynamic_Evaluation: *ref_5_75_0
tests/parametric/test_ffe/test_dynamic_evaluation.py::Test_Feature_Flag_Dynamic_Evaluation::test_ffe_of7_empty_targeting_key: bug (FFL-1730)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This was fixed; removing

Comment on lines -114 to -119
# Skip OF.7 (empty targeting key) test for libraries with known bugs
# Java: FFL-1729 - OpenFeature Java SDK rejects empty targeting keys
# Node.js: FFL-1730 - OpenFeature JS SDK rejects empty targeting keys
if test_case_file == "test-case-of-7-empty-targeting-key.json":
if context.library.name in ("java", "nodejs"):
pytest.skip("OF.7 empty targeting key bug: FFL-1729 (java), FFL-1730 (nodejs)")
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This was fixed; removing - works for php as well

Comment on lines -162 to -164
@parametrize("library_env", [{**DEFAULT_ENVVARS}])
def test_ffe_of7_empty_targeting_key(self, test_agent: TestAgentAPI, test_library: APMLibrary) -> None:
"""OF.7: Empty string is a valid targeting key.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

special test not needed; using the centralized fixtures again for all languages

@leoromanovsky leoromanovsky requested a review from sameerank May 29, 2026 13:57
Copy link
Copy Markdown
Contributor Author

leoromanovsky commented May 29, 2026

Merge activity

  • May 29, 3:48 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • May 29, 3:48 PM UTC: @leoromanovsky merged this pull request with Graphite.

@leoromanovsky leoromanovsky merged commit 56306b6 into main May 29, 2026
1392 of 1395 checks passed
@leoromanovsky leoromanovsky deleted the leo.romanovsky/pr-g-php-ffe-scaffold branch May 29, 2026 15:48
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.

3 participants