Repository navigation
test: shared fixture corpus for tests and benches - #1472
duncanista wants to merge 3 commits into
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fa7a94d02a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
lym953
left a comment
There was a problem hiding this comment.
Could you explain more context? It's hard for me to understand what this PR does without reading your other PRs.
- dogstatsd: advance the metric name every 100 lines so n lines give min(n, 5000) contexts - traces: set BASE_NS to 2026-10-27T12:00:00Z and encode meta/metrics in key order - events: pad the SQS body to the exact size and put the LWA deadline 60 s from now - telemetry: emit extension logs in the logger::Formatter JSON shape
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3e499bbbed
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| ("Datadog-Meta-Lang", "python"), | ||
| ("Datadog-Meta-Lang-Version", "3.12"), | ||
| ("Datadog-Meta-Tracer-Version", "2.10.0"), | ||
| ("X-Datadog-Trace-Count", "100"), |
There was a problem hiding this comment.
Match the trace-count header to each generated payload
When TRACE_HEADERS is reused with traces/v04_100_spans.msgpack, the request advertises 100 traces even though write_corpus constructs that payload with make_traces(5, 20, true). This makes the shared headers inconsistent with one of the generated payloads and can skew consumers that validate or account for the declared trace count; derive this header from the trace collection or provide separate headers for each corpus payload.
Useful? React with 👍 / 👎.
| "dataType": "String" | ||
| } | ||
| }, | ||
| "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3", |
There was a problem hiding this comment.
Compute the checksum for the generated SQS body
When sqs_event is used as a realistic SQS invocation, every record carries this fixed checksum even though the body varies with body_bytes; for example, the 22,000-byte body generated by sqs_220kb() has MD5 7610aadcb8bbb0434939e3680b0db7ca, not the value here. Consumers that verify SQS message integrity will therefore reject the fixture as corrupted, so md5OfBody should be computed from the generated body.
Useful? React with 👍 / 👎.
| put( | ||
| &format!("telemetry/{name}"), | ||
| &telemetry::log_batch(kind, 1000), | ||
| ); |
There was a problem hiding this comment.
Keep generated telemetry POSTs within the subscribed byte limit
When the corpus is written, the JSON-object and JSON-string variants each put 1,000 generated records into one POST, but each underlying JSON record is already about 1.2 KB before its telemetry envelope and string escaping, so these bodies exceed the extension's configured 1 MiB maxBytes. Lambda would flush these small records before reaching 1,000 items, meaning the generated files exercise a batch shape the configured subscription will not produce; split these variants by serialized byte size or lower their event count.
Useful? React with 👍 / 👎.
This comment has been minimized.
This comment has been minimized.
- write_corpus: 600 events for the JSON shapes so each POST fits the 1 MiB maxBytes - traces: TRACE_HEADERS matches the reference payload's 100 traces
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e895b770b2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| .map(|(k, v)| (k.as_str(), v.as_str())) | ||
| .collect(), | ||
| metrics: s.metrics.iter().map(|(k, v)| (k.as_str(), *v)).collect(), | ||
| r#type: &s.r#type, |
There was a problem hiding this comment.
Preserve optional span fields during encoding
When v04_msgpack receives a pb::Span with meta_struct, span_links, or span_events, this conversion silently omits those fields from the encoded payload. Because the helper is exposed as an encoder for caller-supplied traces, benchmarks or fault-injection cases targeting structured metadata, links, or events will not actually send the requested data; preserve these fields deterministically or explicitly restrict the helper to the generated spans.
Useful? React with 👍 / 👎.
| "serverless", | ||
| vec![ | ||
| ("span.kind", "server"), | ||
| ("request_id", "8f5a7e2c-1b2c-4d5e-9f00-0123456789ab"), |
There was a problem hiding this comment.
Reuse the corpus request ID in trace roots
When a simulator combines these traces with the telemetry and log fixtures, every trace root carries a different request ID from telemetry::REQUEST_ID, which the other corpus generators consistently use. Request-ID-keyed paths such as invocation-context enrichment therefore cannot associate the tracer span with the simulated invocation; use the shared constant or accept a request ID as an argument.
Useful? React with 👍 / 👎.
| //! DogStatsD datagrams as a client library sends them to UDP 8125. | ||
|
|
||
| /// The tags bottlecap adds to every metric (`SortedTags::parse(ENRICH_TAGS)`). | ||
| pub const ENRICH_TAGS: &str = "function_arn:arn:aws:lambda:us-east-1:123456789012:function:my-checkout-fn,region:us-east-1,account_id:123456789012,aws_account:123456789012,functionname:my-checkout-fn,resource:my-checkout-fn,executedversion:$LATEST,memorysize:128,architecture:arm64,runtime:nodejs22.x,_dd.runtime_family:nodejs,env:prod,service:checkout,version:1.2.3,dd_extension_version:90,_dd.compute_stats:1"; |
There was a problem hiding this comment.
Remove the span-only directive from metric enrichment tags
When ENRICH_TAGS is used to construct the DogStatsD aggregator, it adds _dd.compute_stats:1 to every generated metric even though tags/lambda/tags.rs::tags_from_env explicitly keeps this directive out of function tags and stamps it only on trace spans. The benchmark corpus consequently measures and asserts a custom-metric tag shape that production never emits; remove this directive from the enrichment fixture.
Useful? React with 👍 / 👎.
| "Keys": {"Id": {"N": "101"}}, | ||
| "NewImage": Value::Object(img), | ||
| "SequenceNumber": format!("{i}00000000000000000"), | ||
| "SizeBytes": 26, |
There was a problem hiding this comment.
Update SizeBytes for generated DynamoDB images
When attrs changes the generated NewImage size—most notably in the 30-attribute reference event—SizeBytes remains the 26-byte value copied from the small sample event. DynamoDbRecord::enrich_span propagates this value into the inferred span's size_bytes tag, so simulator and processing experiments record incorrect payload metadata; derive a matching size for the generated image.
Useful? React with 👍 / 👎.
| "body": body, | ||
| "attributes": { | ||
| "ApproximateReceiveCount": "1", | ||
| "SentTimestamp": "1545082649183", |
There was a problem hiding this comment.
Align generated trigger timestamps with the corpus epoch
When the generated SQS event is processed alongside the 2026 telemetry and trace fixtures, every record still has a 2018 SentTimestamp (and the generated DynamoDB records similarly use a 2015 creation time). The trigger processors use these fields as inferred-span start times, so simulator runs produce spans years outside the invocation and stats window; generate trigger timestamps from the shared fixture epoch.
Useful? React with 👍 / 👎.
TL;DR: One shared set of generated test inputs: Telemetry API batches, Lambda log lines, traces, DogStatsD packets and trigger events.
Why: The fault-injection harness (#1473) and the benchmarks (#1474) need the same realistic inputs. Today each test builds its own by hand. The extension does not change.
Overview
Jira: SVLS-9977
Stacked on #1471 (
jordan.gonzalez/cargo-machete/feature). This PR does not need the CI PRs below it. It sits on this stack so that the bench PR can build on both.Why this PR
We are adding test tools for the extension:
bottlecapbinary against a fake Lambda API and an intake that fails on demand (test: process-level fault-injection harness and the contract tests that pass today #1473)All of them need the same realistic inputs: Telemetry API batches, Lambda log lines, trace payloads, DogStatsD packets and trigger events. Today each test builds its own inputs by hand. This PR adds one small set of generators for those inputs, so every tool tests and measures the same shapes. Large inputs, such as a 220 KB SQS batch, are generated at test time instead of being checked into git.
On its own, this PR only adds test code. The extension does not change. The only non-test change is 9 lines that make the existing
stitchmodule#[doc(hidden)] pub, so integration tests and benches can call it.What to check here: that the generated shapes match what Lambda sends (for example the split-record format that the stitcher reassembles since #1415), and the self-test in
tests/fixtures_corpus.rs.What is in it
bottlecap/tests/fixtures/generates the inputs that the benches, the fault-injectionharness and the Lambda simulator share, so no large blob is in git:
telemetry: Telemetry API batches (platform events, function logs in 3 formats, splitrecords for the stitcher,
runtimeDonewith or without metrics,logsDropped, unknownevents);
logs: Lambda text and JSON lines, one OOM line per runtime;traces: synthetic traces and the 2000-span v0.4 msgpack payload, at a fixed base time;dogstatsd: datagrams for 50 metric names x 100 endpoints;events: the checked-in trigger payloads plus a 220 KB SQS and a 100-record DynamoDB event.tests/fixtures_corpus.rschecks the generators (for example, a split record stitches back).It needs
extension::telemetry::stitchfrom the integration tests, so the module andFragmentBufferbecome#[doc(hidden)] pub. No behavior change.Size: 13 core lines, 1058 lines in total.
Testing
cargo fmt --all -- --check: passcargo clippy --workspace --all-targets --features default -- -D warnings: passcargo clippy --workspace --all-targets --features default,test-mode -- -D warnings: passcargo nextest run --workspace: pass