Skip to content

Commit c71d579

Browse files
committed
empty payloads are allowed
Signed-off-by: Brian L. Troutwine <brian.troutwine@datadoghq.com>
1 parent 893290c commit c71d579

File tree

3 files changed

+24
-47
lines changed

3 files changed

+24
-47
lines changed

lading_payload/proptest-regressions/opentelemetry_metric.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ cc 297490dc1350251d3ef3efa2d11d9c73aedf5de8b3bc09e8d09ded7278c2999c # shrinks to
99
cc 8c98a58aa732d909f04b084be456b2eb30dd41f640ff4d423d4a771a62146543 # shrinks to seed = 0, total_contexts = 1, attributes_per_resource = 0, scopes_per_resource = 1, attributes_per_scope = 0, metrics_per_scope = 0, attributes_per_metric = 0, steps = 1
1010
cc 7702b34625bb90e2024e073e96098b05ca87811d053533b030172b6a5d94e436 # shrinks to seed = 13678916928949602505, total_contexts_min = 2, total_contexts_max = 5, attributes_per_resource = 0, scopes_per_resource = 0, attributes_per_scope = 0, metrics_per_scope = 1, attributes_per_metric = 0
1111
cc 6fc7e550d9e2a9bc3345d505dde242b92b199c844deec70498376606e500a986 # shrinks to seed = 1778269825629053722, total_contexts_min = 3, total_contexts_max = 5, attributes_per_resource = 0, scopes_per_resource = 20, attributes_per_scope = 1, metrics_per_scope = 31, attributes_per_metric = 0
12+
cc 1f22261db4376eba4a685485d5adead24d523c1889df3a2671a02645a7dee6d4 # shrinks to seed = 8924114292563559279, total_contexts_min = 3, total_contexts_max = 5, attributes_per_resource = 0, scopes_per_resource = 2, attributes_per_scope = 1, metrics_per_scope = 2, attributes_per_metric = 0

lading_payload/src/opentelemetry_metric.rs

Lines changed: 22 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ impl Default for Contexts {
8282
attributes_per_resource: ConfRange::Inclusive { min: 1, max: 20 },
8383
scopes_per_resource: ConfRange::Inclusive { min: 1, max: 20 },
8484
attributes_per_scope: ConfRange::Constant(0),
85-
metrics_per_scope: ConfRange::Inclusive { min: 0, max: 20 },
85+
metrics_per_scope: ConfRange::Inclusive { min: 1, max: 20 },
8686
attributes_per_metric: ConfRange::Inclusive { min: 0, max: 10 },
8787
}
8888
}
@@ -288,12 +288,13 @@ impl crate::Serialize for OpentelemetryMetrics {
288288
// those in until max_bytes -- but they do set the scopes per request
289289
// etc. All of that is transparent here, handled by the generators
290290
// above.
291-
let bytes_remaining = max_bytes.checked_sub(5 + max_bytes.div_ceil(0b0111_1111));
292-
let Some(mut bytes_remaining) = bytes_remaining else {
293-
return Ok(());
294-
};
295-
291+
let mut bytes_remaining = max_bytes
292+
.checked_sub(5 + max_bytes.div_ceil(0b0111_1111))
293+
.ok_or(Error::Serialize)?;
296294
let mut acc = Vec::with_capacity(128); // arbitrary constant
295+
296+
// Generate resources as space allows. We will always generate at least
297+
// one, whether it fits or not.
297298
loop {
298299
let resource: v1::ResourceMetrics = self.generate(&mut rng)?;
299300
let len = resource.encoded_len() + 2;
@@ -378,10 +379,22 @@ mod test {
378379
// exceed `max_bytes`.
379380
proptest! {
380381
#[test]
381-
fn payload_not_exceed_max_bytes(seed: u64, max_bytes: u16) {
382+
fn payload_not_exceed_max_bytes(seed: u64, max_bytes in 128u16..u16::MAX) {
383+
let config = Config {
384+
contexts: Contexts {
385+
total_contexts: ConfRange::Constant(1),
386+
attributes_per_resource: ConfRange::Constant(0),
387+
scopes_per_resource: ConfRange::Constant(1),
388+
attributes_per_scope: ConfRange::Constant(0),
389+
metrics_per_scope: ConfRange::Constant(1),
390+
attributes_per_metric: ConfRange::Constant(0),
391+
},
392+
..Default::default()
393+
};
394+
382395
let max_bytes = max_bytes as usize;
383396
let mut rng = SmallRng::seed_from_u64(seed);
384-
let mut metrics = OpentelemetryMetrics::new(Config::default(), &mut rng).expect("failed to create metrics generator");
397+
let mut metrics = OpentelemetryMetrics::new(config, &mut rng).expect("failed to create metrics generator");
385398

386399
let mut bytes = Vec::with_capacity(max_bytes);
387400
metrics.to_bytes(rng, max_bytes, &mut bytes).expect("failed to convert to bytes");
@@ -437,42 +450,6 @@ mod test {
437450
}
438451
}
439452

440-
// We want to be sure that the payloads are not being left empty.
441-
proptest! {
442-
#[test]
443-
fn payload_is_at_least_half_of_max_bytes(
444-
seed: u64,
445-
total_contexts in 1..1_000_u32,
446-
attributes_per_resource in 0..20_u8,
447-
scopes_per_resource in 0..20_u8,
448-
attributes_per_scope in 0..20_u8,
449-
metrics_per_scope in 0..20_u8,
450-
attributes_per_metric in 0..10_u8,
451-
max_bytes in 16u16..u16::MAX
452-
) {
453-
let config = Config {
454-
contexts: Contexts {
455-
total_contexts: ConfRange::Constant(total_contexts),
456-
attributes_per_resource: ConfRange::Constant(attributes_per_resource),
457-
scopes_per_resource: ConfRange::Constant(scopes_per_resource),
458-
attributes_per_scope: ConfRange::Constant(attributes_per_scope),
459-
metrics_per_scope: ConfRange::Constant(metrics_per_scope),
460-
attributes_per_metric: ConfRange::Constant(attributes_per_metric),
461-
},
462-
..Default::default()
463-
};
464-
465-
let max_bytes = max_bytes as usize;
466-
let mut rng = SmallRng::seed_from_u64(seed);
467-
let metrics = OpentelemetryMetrics::new(config, &mut rng).expect("failed to create metrics generator");
468-
469-
let mut bytes = Vec::with_capacity(max_bytes);
470-
metrics.to_bytes(rng, max_bytes, &mut bytes).expect("failed to convert to bytes");
471-
472-
assert!(!bytes.is_empty());
473-
}
474-
}
475-
476453
// We want to know that every payload produced by this type actually
477454
// deserializes as a collection of OTEL metrics.
478455
proptest! {
@@ -485,7 +462,7 @@ mod test {
485462
attributes_per_scope in 0..20_u8,
486463
metrics_per_scope in 0..20_u8,
487464
attributes_per_metric in 0..10_u8,
488-
max_bytes: u16
465+
max_bytes in 8u16..u16::MAX
489466
) {
490467
let config = Config {
491468
contexts: Contexts {

lading_payload/src/opentelemetry_metric/templates.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ use super::{Config, UnitGenerator, tags::TagGenerator};
1818
use crate::{Error, common::config::ConfRange, common::strings};
1919

2020
const UNIQUE_TAG_RATIO: f32 = 0.75;
21-
2221
struct Ndp(NumberDataPoint);
2322
impl Distribution<Ndp> for StandardUniform {
2423
fn sample<R>(&self, rng: &mut R) -> Ndp
@@ -157,7 +156,7 @@ pub(crate) enum Kind {
157156
impl MetricTemplate {
158157
/// Instantiate the template into a concrete `v1::Metric`
159158
pub(crate) fn instantiate<R: Rng + ?Sized>(&self, rng: &mut R) -> Metric {
160-
let total_data_points = rng.random_range(0..60);
159+
let total_data_points = rng.random_range(1..60);
161160
let data_points = (0..total_data_points)
162161
.map(|_| rng.random::<Ndp>().0)
163162
.collect();

0 commit comments

Comments
 (0)