Skip to content

Commit dbfb781

Browse files
committed
chore(antithesis): Intro Intake V3
This commit introduces a v3 intake into antithesis harness to support symmetric difference with ADP-on -- v2 by default -- and ADP-off -- v3 by default.
1 parent 20f18cf commit dbfb781

27 files changed

Lines changed: 3221 additions & 407 deletions

Cargo.lock

Lines changed: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/antithesis/harness/src/config.rs

Lines changed: 110 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,54 @@ impl DogStatsdConfig {
117117
/// unset. The current value caps the preallocation at 512 MiB.
118118
const MAX_STRING_INTERNER_ENTRIES: u64 = 1_048_576;
119119

120+
/// Compressor both targets serialize metric payloads with.
121+
#[derive(Debug, Clone, Copy, Serialize)]
122+
#[serde(rename_all = "lowercase")]
123+
pub(crate) enum CompressorKind {
124+
/// Deflate. Disables the v3 series intake on both targets.
125+
Zlib,
126+
/// Zstandard.
127+
Zstd,
128+
/// Gzip.
129+
Gzip,
130+
/// No compression, the Agent's `NoneKind`.
131+
None,
132+
/// A codec neither target implements, so each falls back its own way and the two lanes disagree
133+
/// on the wire from one config value.
134+
Snappy,
135+
}
136+
137+
impl Distribution<CompressorKind> for StandardUniform {
138+
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> CompressorKind {
139+
match rng.random_range(0..5u8) {
140+
0 => CompressorKind::Zlib,
141+
1 => CompressorKind::Zstd,
142+
2 => CompressorKind::Gzip,
143+
3 => CompressorKind::None,
144+
_ => CompressorKind::Snappy,
145+
}
146+
}
147+
}
148+
149+
/// The Agent's nested `use_v3_api.series` switch between the v2 and v3 series
150+
/// intake.
151+
#[derive(Debug, Serialize)]
152+
pub(crate) struct UseV3ApiConfig {
153+
/// The series sub-tree.
154+
series: V3SeriesConfig,
155+
}
156+
157+
/// The `enabled` leaf under a v3 series key.
158+
#[derive(Debug, Serialize)]
159+
pub(crate) struct V3SeriesConfig {
160+
/// Whether the series intake is v3 rather than v2.
161+
enabled: bool,
162+
}
163+
120164
/// Agent-facing config. `hostname`, `api_key`, `dd_url`, and the socket are
121-
/// supplied by the environment; `log_level` and the `DogStatsD` options are
122-
/// sampled per branch. The static flags are appended by [`Self::to_yaml`], not
123-
/// fields here.
165+
/// supplied by the environment; `log_level`, the series intake API, and the
166+
/// `DogStatsD` options are sampled per branch. The static flags are appended by
167+
/// [`Self::to_yaml`], not fields here.
124168
#[derive(Debug, Serialize)]
125169
pub struct DatadogConfig {
126170
/// Agent hostname. Supplied by the environment. ADP requires it
@@ -132,6 +176,13 @@ pub struct DatadogConfig {
132176
dd_url: String,
133177
/// Agent log verbosity. Pinned to `error` (see [`LogLevel`]).
134178
log_level: LogLevel,
179+
/// Series intake API for this timeline.
180+
use_v3_api: UseV3ApiConfig,
181+
/// Compressor for metric payloads. Sampled independently of the series API.
182+
serializer_compressor_kind: CompressorKind,
183+
/// ADP's safety gate for authoritative v3 series, which the Agent has no counterpart for.
184+
/// Sampled with [`Self::use_v3_api`] so ADP and the Agent never split encodings in a timeline.
185+
data_plane_metrics_v3_series_enabled: bool,
135186
/// `DogStatsD` options, flattened to top-level `dogstatsd_*` keys.
136187
#[serde(flatten)]
137188
dogstatsd: DogStatsdConfig,
@@ -145,11 +196,17 @@ impl DatadogConfig {
145196
pub fn sample<R: Rng + ?Sized>(
146197
rng: &mut R, hostname: &str, api_key: &str, dd_url: &str, dogstatsd_socket: &Path,
147198
) -> Self {
199+
let series_v3 = rng.random();
148200
Self {
149201
hostname: hostname.to_owned(),
150202
api_key: api_key.to_owned(),
151203
dd_url: dd_url.to_owned(),
152204
log_level: LogLevel::Error,
205+
use_v3_api: UseV3ApiConfig {
206+
series: V3SeriesConfig { enabled: series_v3 },
207+
},
208+
serializer_compressor_kind: rng.random(),
209+
data_plane_metrics_v3_series_enabled: series_v3,
153210
dogstatsd: DogStatsdConfig::sample(rng, dogstatsd_socket),
154211
}
155212
}
@@ -177,7 +234,6 @@ impl DatadogConfig {
177234

178235
/// Yaml flags the Agent reads at boot that never vary.
179236
const STATIC_YAML_TAIL: &str = "use_dogstatsd: true
180-
use_v2_api_series: true
181237
inventories_enabled: false
182238
enable_metadata_collection: false
183239
cloud_provider_metadata: []
@@ -239,6 +295,7 @@ impl DriverConfig {
239295

240296
#[cfg(test)]
241297
mod tests {
298+
use std::collections::BTreeSet;
242299
use std::convert::Infallible;
243300

244301
use rand::rand_core::TryRng;
@@ -303,4 +360,53 @@ mod tests {
303360
assert!(has_key(&render(0), "log_level"));
304361
assert!(render(0).contains("log_level: error"));
305362
}
363+
364+
/// The Agent's nested switch and ADP's safety gate, as a timeline renders them.
365+
fn series_api(seed: u64) -> (bool, bool) {
366+
let yaml = render(seed);
367+
let parsed: serde_yaml::Value = serde_yaml::from_str(&yaml).expect("parse rendered yaml");
368+
let agent = parsed["use_v3_api"]["series"]["enabled"]
369+
.as_bool()
370+
.expect("use_v3_api.series.enabled");
371+
let adp = parsed["data_plane_metrics_v3_series_enabled"]
372+
.as_bool()
373+
.expect("data_plane_metrics_v3_series_enabled");
374+
(agent, adp)
375+
}
376+
377+
#[test]
378+
fn both_lanes_share_one_series_api() {
379+
for seed in 0..16 {
380+
let (agent, adp) = series_api(seed);
381+
assert_eq!(agent, adp, "seed {seed}");
382+
}
383+
}
384+
385+
#[test]
386+
fn series_api_samples_both_intakes() {
387+
let mut seen = [false, false];
388+
for seed in 0..16 {
389+
seen[usize::from(series_api(seed).0)] = true;
390+
}
391+
assert_eq!(seen, [true, true]);
392+
}
393+
394+
#[test]
395+
fn compressor_samples_every_kind() {
396+
let mut seen = BTreeSet::new();
397+
for seed in 0..64 {
398+
let yaml = render(seed);
399+
let kind = yaml
400+
.lines()
401+
.find_map(|line| line.strip_prefix("serializer_compressor_kind: "))
402+
.expect("serializer_compressor_kind")
403+
.to_owned();
404+
seen.insert(kind);
405+
}
406+
let want = ["gzip", "none", "snappy", "zlib", "zstd"]
407+
.into_iter()
408+
.map(str::to_owned)
409+
.collect::<BTreeSet<_>>();
410+
assert_eq!(seen, want);
411+
}
306412
}

test/antithesis/intake/Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,16 @@ anyhow = { workspace = true, features = ["std"] }
1919
axum = { workspace = true, features = ["http1", "json", "tokio", "tracing"] }
2020
clap = { workspace = true, features = ["derive", "env", "error-context", "help", "std", "usage"] }
2121
datadog-protos = { workspace = true }
22+
harness = { path = "../harness" }
2223
headers = { workspace = true }
24+
http-body-util = { workspace = true }
2325
mime = { workspace = true }
2426
protobuf = { workspace = true }
2527
serde = { workspace = true, features = ["derive"] }
2628
serde_json = { workspace = true }
27-
stele = { workspace = true }
29+
serde_yaml = { workspace = true }
2830
tokio = { workspace = true, features = [
31+
"io-util",
2932
"macros",
3033
"net",
3134
"rt",

0 commit comments

Comments
 (0)