Skip to content

test(trace stats): assert trace stats aggregation values via fake-intake#1256

Merged
lucaspimentel merged 3 commits into
mainfrom
lpimentel/stats-aggregation-tests
Jun 15, 2026
Merged

test(trace stats): assert trace stats aggregation values via fake-intake#1256
lucaspimentel merged 3 commits into
mainfrom
lpimentel/stats-aggregation-tests

Conversation

@lucaspimentel

@lucaspimentel lucaspimentel commented Jun 12, 2026

Copy link
Copy Markdown
Member

Overview

Extends the in-process fake-intake APM tests (added in #1194) with value-level coverage of trace stats aggregation. The existing stats tests assert serialization fidelity (a hand-built ClientStatsPayload survives the roundtrip) and stats presence/suppression (_dd.compute_stats truth table). None assert that the computed aggregates reaching the intake are correct.

This PR routes concrete spans through the real pipeline (SendingTraceProcessorStatsConcentratorServiceStatsFlusher → fake-intake) and asserts on the decoded ClientGroupedStats:

  • e2e_stats_count_aggregates_identical_spans — 3 identical top-level spans collapse into one group with hits == 3, top_level_hits == 3.
  • e2e_stats_counts_errors_separately_from_hitserrors counts only error != 0; hits counts all.
  • e2e_stats_sums_span_durationsduration is the nanosecond sum of aggregated spans.
  • e2e_stats_groups_by_resource — distinct resources stay in separate groups.
  • e2e_stats_groups_by_span_kind — distinct span.kind stay in separate groups.
  • e2e_stats_groups_by_http_status_code — distinct http.status_code stay in separate groups.

These verify bottlecap's wiring and serialization end-to-end (a span entering the trace path comes out the intake correctly aggregated), which libdatadog's concentrator unit tests cannot see. The aggregation math itself is owned and exhaustively tested upstream in libdd-trace-stats.

To support multiple spans, run_processor_pipeline was generalized into run_processor_pipeline_with_traces(.., traces), with a thin single-span wrapper preserving the existing _dd.compute_stats tests unchanged.

Out of scope: time-bucketing

Deliberately not added. Bucket assignment lives entirely inside SpanConcentrator and is thoroughly tested in libdd-trace-stats (test_concentrator_stats_counts over multiple buckets, test_concentrator_oldest_timestamp_cold/hot, test_force_flush). bottlecap's wiring does not touch bucketing, so a test here would duplicate upstream coverage and require a production clock seam (the concentrator seeds oldest_timestamp from wall-clock) for no unique coverage.

Testing

This PR is only adding more tests. If they pass, we're good.

Ran locally:

  • cargo test --test apm_integration_test
  • cargo fmt --all -- --check
  • cargo clippy --workspace --all-targets --features default

"Six tests walk into a bucket. They all collapse into one group — turns out they were identical the whole time." — Claude 🤖

@datadog-prod-us1-3

datadog-prod-us1-3 Bot commented Jun 12, 2026

Copy link
Copy Markdown

Pipelines

Fix all issues with BitsAI

⚠️ Warnings

🚦 2 Pipeline jobs failed

DataDog/datadog-lambda-extension | e2e-test-status (amd64, fips)   View in Datadog   GitLab

DataDog/datadog-lambda-extension | e2e-test-status (amd64)   View in Datadog   GitLab

Useful? React with 👍 / 👎

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

@lucaspimentel lucaspimentel changed the title [APMSVLS-494] test(traces): assert trace stats aggregation values via fake-intake test(trace stats): assert trace stats aggregation values via fake-intake Jun 12, 2026
@lucaspimentel
lucaspimentel force-pushed the lpimentel/stats-aggregation-tests branch from a17f441 to f706f60 Compare June 12, 2026 23:20
@lucaspimentel
lucaspimentel changed the base branch from main to lpimentel/fix-cold-start-test-runtime June 12, 2026 23:21
@lucaspimentel
lucaspimentel marked this pull request as ready for review June 12, 2026 23:22
@lucaspimentel
lucaspimentel requested a review from a team as a code owner June 12, 2026 23:22

Copilot AI 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.

Pull request overview

Adds end-to-end, value-level assertions for trace stats aggregation by routing real spans through bottlecap’s trace/stats pipeline and validating the decoded ClientGroupedStats captured by the in-process fake-intake. This strengthens integration coverage beyond “payload exists/roundtrips” by checking that the computed aggregates (hits/errors/duration) and grouping keys match expectations.

Changes:

  • Generalizes the existing test helper into run_processor_pipeline_with_traces(.., traces) and keeps a single-span wrapper for existing _dd.compute_stats tests.
  • Introduces deterministic, aggregate-value tests (hits/errors/duration and grouping by resource, span.kind, and http.status_code) using concrete spans sent through SendingTraceProcessor → StatsConcentratorService → StatsFlusher → fake-intake.
  • Centralizes a fixed span start timestamp (STATS_SPAN_START_NS) for deterministic bucketing behavior in tests.

Comment on lines +403 to +406
/// Fixed span start well in the past relative to the concentrator's clock, so all spans
/// fold into the single oldest bucket and a `force_flush` returns exactly one bucket.
/// That keeps the aggregation assertions deterministic without controlling time.
const STATS_SPAN_START_NS: i64 = 1_700_000_000_000_000_000;
Base automatically changed from lpimentel/fix-cold-start-test-runtime to main June 15, 2026 14:04
Add E2E tests that route concrete spans through the real SpanConcentrator
and assert on the computed aggregate values (hits, errors, duration sum,
resource grouping) that reach the intake, rather than only on stats
presence/suppression.

Generalize run_processor_pipeline to accept arbitrary traces; keep a
single-span wrapper for the existing _dd.compute_stats tests.

🤖 Co-Authored-By: Claude Code <[email protected]>
Add two more aggregation tests: spans differing only in span.kind or
http.status_code must land in separate ClientGroupedStats, each counted
independently.

🤖 Co-Authored-By: Claude Code <[email protected]>
…estamp

Name the fixed past timestamp used to fold stats spans into one bucket,
so its intent is self-documenting at each use site.

🤖 Co-Authored-By: Claude Code <[email protected]>
@lucaspimentel
lucaspimentel force-pushed the lpimentel/stats-aggregation-tests branch from f706f60 to 6b29ef1 Compare June 15, 2026 17:47
@lucaspimentel
lucaspimentel merged commit c4a1a81 into main Jun 15, 2026
57 of 59 checks passed
@lucaspimentel
lucaspimentel deleted the lpimentel/stats-aggregation-tests branch June 15, 2026 20: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