Skip to content

Enable PHP FFE span-enrichment parametric tests#7153

Draft
leoromanovsky wants to merge 1 commit into
mainfrom
leo.romanovsky/ffe-enrichment-enable-php
Draft

Enable PHP FFE span-enrichment parametric tests#7153
leoromanovsky wants to merge 1 commit into
mainfrom
leo.romanovsky/ffe-enrichment-enable-php

Conversation

@leoromanovsky

Copy link
Copy Markdown
Contributor

Motivation

The FFE APM feature-flag span-enrichment contract (frozen against dd-trace-js#8343) is being
fanned out to the remaining server SDKs. The parametric suite
tests/parametric/test_ffe/test_span_enrichment.py already exists and is frozen; this PR enables
it for PHP (the last of the 5 server SDKs), against the tracer changes in
DataDog/dd-trace-php#3996.

Changes

  • manifest: activate tests/parametric/test_ffe/test_span_enrichment.py for PHP at
    v1.21.0-dev.
  • PHP parametric server (utils/build/docker/php/parametric/server.php) — adapt the
    long-running CLI app so the frozen suite passes:
    • /ffe/evaluate: re-activate the caller-supplied span (span_id) around the evaluation via
      switch_stack, so the ffe_* enrichment tags land on the test's span. This makes multi-eval
      aggregation onto a single root work and lets a child-span evaluation propagate to the root.
    • /ffe/start: when the test pushes a UFC config via Remote Config (no inline configuration),
      call dd_trace_internal_fn('await_ffe_config') to actively pump Remote Config. In the
      long-running CLI server the SIGVTALRM-driven RC refresh is starved (the amphp event loop is
      mostly blocked in IO, not burning CPU time), so without this the worker never applies the
      pushed UFC and evaluation returns default values.
    • /trace/span/finish: synchronously flush on root-span close so the finished trace
      (carrying the enrichment tags written on root finish) deterministically reaches the agent
      before wait_for_num_traces reads it, instead of racing the async send-queue drain.

The diff is language-scoped: only the PHP parametric server and the PHP manifest line are touched.
No unrelated cross-language drift, _test_agent.py, or local-only Docker/platform changes are
included.

Decisions

  • The enrichment write path itself is implemented in the tracer (dd-trace-php#3996); this PR is
    purely the system-tests enablement + parametric-app adaptation. await_ffe_config is a tracer
    testing internal fn added in that PR.
  • Root-finish synchronous flush is scoped to root spans only, mirroring the existing
    /trace/span/flush endpoint's dd_trace_synchronous_flush usage, to keep child-span semantics
    unchanged.

Validation

Run locally against the dd-trace-php#3996 build (dd-library-php-1.21.0, C extension built from
source for aarch64-linux-gnu, PHP 8.2 NTS):

TEST_LIBRARY=php ./run.sh PARAMETRIC -k span_enrichment
...
Library: php@1.21.0
============================= 18 passed in 49.99s ==============================

All 18 cases pass — serial-ID aggregation/child-span propagation (e.g. ZAgUAg==
[100,108,128,130]), SHA256-hashed subjects gated on doLog, runtime-defaults with 64-char
truncation, and all frozen limits (200/10/20/5).

Activate tests/parametric/test_ffe/test_span_enrichment.py for PHP (v1.21.0-dev)
and adapt the PHP parametric server so the FROZEN suite passes in the
long-running CLI app:

- /ffe/evaluate: re-activate the caller-supplied span (span_id) around the
  evaluation via switch_stack, so the ffe_* enrichment tags land on the test's
  span (multi-eval aggregation onto one root; child-span propagation to root).
- /ffe/start: when the test pushes a UFC via Remote Config (no inline config),
  call dd_trace_internal_fn('await_ffe_config') to actively pump Remote Config.
  The CLI server's SIGVTALRM-driven RC refresh is starved by IO-blocking, so
  without this the worker never applies the pushed UFC and evaluation returns
  defaults.
- /trace/span/finish: synchronously flush on ROOT-span close so the finished
  trace (carrying the enrichment tags written on root finish) deterministically
  reaches the agent before wait_for_num_traces reads it, instead of racing the
  async send-queue drain.

Validated locally: TEST_LIBRARY=php ./run.sh PARAMETRIC -k span_enrichment
=> 18 passed.
@github-actions

Copy link
Copy Markdown
Contributor

CODEOWNERS have been resolved as:

manifests/php.yml                                                       @DataDog/apm-php @DataDog/asm-php
utils/build/docker/php/parametric/server.php                            @DataDog/apm-php @DataDog/system-tests-core

@datadog-official

datadog-official Bot commented Jun 17, 2026

Copy link
Copy Markdown

Pipelines  Tests

Fix all issues with BitsAI

⚠️ Warnings

🚦 4 Pipeline jobs failed

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

🧪 10 Tests failed

tests.parametric.test_ffe.test_span_enrichment.Test_Span_Enrichment_Child_Span_Propagation.test_child_span_flag_evaluation_propagates_to_root[library_env0, parametric-php] from system_tests_suite   View in Datadog
AssertionError: ffe_flags_enc not found in root span meta: ['_dd.p.dm', '_dd.tags.process', 'runtime-id', '_dd.svc_src', '_dd.p.tid']
assert 'ffe_flags_enc' in {'_dd.p.dm': '-0', '_dd.p.tid': '6a31e9d400000000', '_dd.svc_src': 'm', '_dd.tags.process': 'entrypoint.basedir:binaries,entrypoint.name:server,entrypoint.type:script,entrypoint.workdir:binaries,runtime.sapi:cli', ...}

self = <tests.parametric.test_ffe.test_span_enrichment.Test_Span_Enrichment_Child_Span_Propagation object at 0x7f211aeb19a0>
test_agent = <utils.docker_fixtures._test_agent.TestAgentAPI object at 0x7f20e5d0a330>
test_library = <utils.docker_fixtures._test_clients._test_client_parametric.ParametricTestClientApi object at 0x7f20e5d0a930>

    @parametrize("library_env", [{**DEFAULT_ENVVARS}])
    def test_child_span_flag_evaluation_propagates_to_root(
        self, test_agent: TestAgentAPI, test_library: APMLibrary
...
tests.parametric.test_ffe.test_span_enrichment.Test_Span_Enrichment_Default_Fallback.test_ffe_runtime_defaults_value_truncated_at_64_chars[library_env0, parametric-php] from system_tests_suite   View in Datadog
AssertionError: ffe_runtime_defaults not found in span meta: ['_dd.tags.process', 'runtime-id', '_dd.svc_src', '_dd.p.dm', '_dd.p.tid']
assert 'ffe_runtime_defaults' in {'_dd.p.dm': '-0', '_dd.p.tid': '6a31e9d300000000', '_dd.svc_src': 'm', '_dd.tags.process': 'entrypoint.basedir:binaries,entrypoint.name:server,entrypoint.type:script,entrypoint.workdir:binaries,runtime.sapi:cli', ...}

self = <tests.parametric.test_ffe.test_span_enrichment.Test_Span_Enrichment_Default_Fallback object at 0x7f4a2ca28320>
test_agent = <utils.docker_fixtures._test_agent.TestAgentAPI object at 0x7f4a2c52be90>
test_library = <utils.docker_fixtures._test_clients._test_client_parametric.ParametricTestClientApi object at 0x7f4a2bf36f00>

    @parametrize("library_env", [{**DEFAULT_ENVVARS}])
    def test_ffe_runtime_defaults_value_truncated_at_64_chars(
        self, test_agent: TestAgentAPI, test_library: APMLibrary
...
View all 10 test failures

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

🧪 10 Tests failed

tests.parametric.test_ffe.test_span_enrichment.Test_Span_Enrichment_Child_Span_Propagation.test_child_span_flag_evaluation_propagates_to_root[library_env0, parametric-php] from system_tests_suite   View in Datadog
AssertionError: ffe_flags_enc not found in root span meta: ['_dd.p.tid', '_dd.p.dm', '_dd.tags.process', 'runtime-id']
assert 'ffe_flags_enc' in {'_dd.p.dm': '-0', '_dd.p.tid': '6a31e9e200000000', '_dd.tags.process': 'entrypoint.basedir:binaries,entrypoint.name:s...ypoint.type:script,entrypoint.workdir:binaries,runtime.sapi:cli', 'runtime-id': '4c0823fe-aebc-471c-980c-9f3726a93ee0'}

self = <tests.parametric.test_ffe.test_span_enrichment.Test_Span_Enrichment_Child_Span_Propagation object at 0x7f61d46c46e0>
test_agent = <utils.docker_fixtures._test_agent.TestAgentAPI object at 0x7f619f7d1400>
test_library = <utils.docker_fixtures._test_clients._test_client_parametric.ParametricTestClientApi object at 0x7f619f3028d0>

    @parametrize("library_env", [{**DEFAULT_ENVVARS}])
    def test_child_span_flag_evaluation_propagates_to_root(
        self, test_agent: TestAgentAPI, test_library: APMLibrary
...
tests.parametric.test_ffe.test_span_enrichment.Test_Span_Enrichment_Default_Fallback.test_ffe_runtime_defaults_value_truncated_at_64_chars[library_env0, parametric-php] from system_tests_suite   View in Datadog
AssertionError: ffe_runtime_defaults not found in span meta: ['runtime-id', '_dd.tags.process', '_dd.p.dm', '_dd.p.tid']
assert 'ffe_runtime_defaults' in {'_dd.p.dm': '-0', '_dd.p.tid': '6a31e9e600000000', '_dd.tags.process': 'entrypoint.basedir:binaries,entrypoint.name:s...ypoint.type:script,entrypoint.workdir:binaries,runtime.sapi:cli', 'runtime-id': '9ebf5d26-cc3b-4738-88ae-e6b837c22f9d'}

self = <tests.parametric.test_ffe.test_span_enrichment.Test_Span_Enrichment_Default_Fallback object at 0x7ff726502090>
test_agent = <utils.docker_fixtures._test_agent.TestAgentAPI object at 0x7ff726128890>
test_library = <utils.docker_fixtures._test_clients._test_client_parametric.ParametricTestClientApi object at 0x7ff725b2e9c0>

    @parametrize("library_env", [{**DEFAULT_ENVVARS}])
    def test_ffe_runtime_defaults_value_truncated_at_64_chars(
        self, test_agent: TestAgentAPI, test_library: APMLibrary
...
View all 10 test failures

Testing the test | System Tests (golang, prod) / parametric / parametric (1)   View in Datadog   GitHub Actions

View all 4 failed jobs.

ℹ️ Info

No other issues found (see more)

❄️ No new flaky tests detected

Useful? React with 👍 / 👎

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

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