fix(test): remove non-deterministic tiebreaks in otel snapshot ordering#9793
Open
aaronArinder wants to merge 1 commit into
Open
fix(test): remove non-deterministic tiebreaks in otel snapshot ordering#9793aaronArinder wants to merge 1 commit into
aaronArinder wants to merge 1 commit into
Conversation
sort_spans_for_snapshot had two independent sources of run-to-run nondeterminism: root ordering came from spans_by_root.keys() straight out of a HashMap (random hasher seed per process), and the sibling tiebreak was raw batch-arrival position — exactly the tokio scheduling noise this function exists to cancel out. Both only mattered when spans tied on (start_time, end_time, name), which test_batch_trace_id hits routinely since its two batched operations produce structurally identical supergraph root spans. Keep (start_time, end_time) as the primary sort key so non-tied siblings retain today's order, and replace the tiebreak with a bottom-up content signature (name + own attributes minus volatile keys + children's signatures) instead of anything positional. The volatile-attribute list is now a single VOLATILE_ATTRIBUTE_KEYS const shared with assert_report!'s redaction list, so the two can't drift apart. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Contributor
✅ Docs preview has no changesThe preview was not built because there were no changes. Build ID: 5addf779add524081cb1dd4c ✅ AI Style Review — No Changes DetectedNo MDX files were changed in this pull request. Review Log: View detailed log
|
Contributor
|
@aaronArinder, please consider creating a changeset entry in |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
test_batch_trace_idfailed intermittently in CI (insta snapshot mismatch, confirmed onamd_linux_test2026-07-09) due tosort_spans_for_snapshotnot fully canonicalizing span order.HashMapiteration order. Roots were collected viaspans_by_root.keys().cloned().collect(). Rust's default hasher is randomly seeded per process, so whenever two roots tied on(start_time, end_time, name)— whichtest_batch_trace_idhits routinely, since its two batched operations produce two structurally-identicalsupergraphroot spans that can start/end within the same nanosecond — the pre-sort order (and therefore the stable-sort tiebreak outcome) depended on hash-iteration order, not content.original_position_within_parent— exactly the tokio-scheduling arrival sequence the function exists to cancel out.get_tracesalready polls up to 10s for a report matching a shape filter, notreports[0], so that part was already handled correctly.Fix
(start_time_unix_nano, end_time_unix_nano)as the primary sort key, so non-tied siblings (the overwhelming common case) retain today's order and existing snapshots don't need to be regenerated.HashMapiteration influencing order.VOLATILE_ATTRIBUTE_KEYSconst shared withassert_report!'s redaction list, closing a drift risk between "redacted for display" and "excluded from sort key."An earlier draft made the entire key content-based (no timestamps). That's a valid total order but reorders every non-tied sibling too, churning nearly every snapshot in the file — rejected in favor of the hybrid above.
Test plan
test_batch_trace_idalone: 40/40 passesapollo_otel_tracessuite (12 tests): 12/12 full-suite runs (144 individual executions), viacargo nextestper this file's serialization requirementcargo clippy --test apollo_otel_tracesandcargo fmt --checkclean.snapfiles needed regeneration — the hybrid design preserves existing checked-in snapshots exactlyTest-only change; no production code touched.
🤖 Generated with Claude Code