Skip to content

Commit f3efe3c

Browse files
tests(stats): add tests
1 parent 40ab604 commit f3efe3c

2 files changed

Lines changed: 191 additions & 0 deletions

File tree

libdd-data-pipeline/src/stats_exporter.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,4 +391,28 @@ mod tests {
391391
"Expected max retry attempts"
392392
);
393393
}
394+
395+
#[test]
396+
fn test_encode_stats_payload_defaults_empty_env() {
397+
// Test that empty env defaults to "unknown-env"
398+
let mut meta_with_empty_env = get_test_metadata();
399+
meta_with_empty_env.env = "".to_string();
400+
401+
let buckets = vec![];
402+
let payload = encode_stats_payload(&meta_with_empty_env, 1, buckets.clone());
403+
404+
assert_eq!(
405+
payload.env, "unknown-env",
406+
"Empty env should default to 'unknown-env'"
407+
);
408+
409+
// Test that non-empty env is preserved
410+
let meta_with_env = get_test_metadata();
411+
let payload_with_env = encode_stats_payload(&meta_with_env, 2, buckets);
412+
413+
assert_eq!(
414+
payload_with_env.env, "test",
415+
"Non-empty env should be preserved"
416+
);
417+
}
394418
}

libdd-trace-stats/src/span_concentrator/tests.rs

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -877,6 +877,173 @@ fn test_peer_tags_aggregation() {
877877
);
878878
}
879879

880+
/// Test that internal spans with _dd.base_service use it as their sole peer tag
881+
#[test]
882+
fn test_base_service_peer_tag() {
883+
let now = SystemTime::now();
884+
let mut spans = vec![
885+
// Regular internal span without base_service (no peer tags)
886+
get_test_span_with_meta(
887+
now,
888+
1,
889+
0,
890+
100,
891+
5,
892+
"A1",
893+
"internal.operation",
894+
0,
895+
&[],
896+
&[("_dd.measured", 1.0)],
897+
),
898+
// Internal span with _dd.base_service (should have base_service as peer tag)
899+
get_test_span_with_meta(
900+
now,
901+
2,
902+
0,
903+
75,
904+
5,
905+
"A1",
906+
"internal.with.base.service",
907+
0,
908+
&[("_dd.base_service", "original-service")],
909+
&[("_dd.measured", 1.0)],
910+
),
911+
// Another internal span with same _dd.base_service (should aggregate together)
912+
get_test_span_with_meta(
913+
now,
914+
3,
915+
0,
916+
50,
917+
5,
918+
"A1",
919+
"internal.with.base.service",
920+
0,
921+
&[("_dd.base_service", "original-service")],
922+
&[("_dd.measured", 1.0)],
923+
),
924+
// Internal span with different _dd.base_service (should be separate group)
925+
get_test_span_with_meta(
926+
now,
927+
4,
928+
0,
929+
60,
930+
5,
931+
"A1",
932+
"internal.with.base.service",
933+
0,
934+
&[("_dd.base_service", "other-service")],
935+
&[("_dd.measured", 1.0)],
936+
),
937+
// Client span with _dd.base_service and other peer tags enabled
938+
// (should use configured peer tags, not base_service)
939+
get_test_span_with_meta(
940+
now,
941+
5,
942+
0,
943+
80,
944+
5,
945+
"A1",
946+
"SELECT * FROM users",
947+
0,
948+
&[
949+
("span.kind", "client"),
950+
("_dd.base_service", "ignored-for-client"),
951+
("db.instance", "i-1234"),
952+
("db.system", "postgres"),
953+
],
954+
&[("_dd.measured", 1.0)],
955+
),
956+
];
957+
compute_top_level_span(spans.as_mut_slice());
958+
959+
let mut concentrator = SpanConcentrator::new(
960+
Duration::from_nanos(BUCKET_SIZE),
961+
now,
962+
get_span_kinds(),
963+
vec!["db.instance".to_string(), "db.system".to_string()],
964+
);
965+
966+
for span in &spans {
967+
concentrator.add_span(span);
968+
}
969+
970+
let flushtime =
971+
now + Duration::from_nanos(concentrator.bucket_size * concentrator.buffer_len as u64);
972+
973+
let expected = vec![
974+
// Internal span without base_service - no peer tags
975+
pb::ClientGroupedStats {
976+
service: "A1".to_string(),
977+
resource: "internal.operation".to_string(),
978+
r#type: "db".to_string(),
979+
name: "query".to_string(),
980+
duration: 100,
981+
hits: 1,
982+
top_level_hits: 1,
983+
errors: 0,
984+
is_trace_root: pb::Trilean::True.into(),
985+
..Default::default()
986+
},
987+
// Internal spans with _dd.base_service="original-service" - aggregated with base_service
988+
// peer tag
989+
pb::ClientGroupedStats {
990+
service: "A1".to_string(),
991+
resource: "internal.with.base.service".to_string(),
992+
r#type: "db".to_string(),
993+
name: "query".to_string(),
994+
peer_tags: vec!["_dd.base_service:original-service".to_string()],
995+
duration: 125,
996+
hits: 2,
997+
top_level_hits: 2,
998+
errors: 0,
999+
is_trace_root: pb::Trilean::True.into(),
1000+
..Default::default()
1001+
},
1002+
// Internal span with _dd.base_service="other-service" - separate group
1003+
pb::ClientGroupedStats {
1004+
service: "A1".to_string(),
1005+
resource: "internal.with.base.service".to_string(),
1006+
r#type: "db".to_string(),
1007+
name: "query".to_string(),
1008+
peer_tags: vec!["_dd.base_service:other-service".to_string()],
1009+
duration: 60,
1010+
hits: 1,
1011+
top_level_hits: 1,
1012+
errors: 0,
1013+
is_trace_root: pb::Trilean::True.into(),
1014+
..Default::default()
1015+
},
1016+
// Client span - uses configured peer tags, not base_service
1017+
pb::ClientGroupedStats {
1018+
service: "A1".to_string(),
1019+
resource: "SELECT * FROM users".to_string(),
1020+
r#type: "db".to_string(),
1021+
name: "query".to_string(),
1022+
span_kind: "client".to_string(),
1023+
peer_tags: vec![
1024+
"db.instance:i-1234".to_string(),
1025+
"db.system:postgres".to_string(),
1026+
],
1027+
duration: 80,
1028+
hits: 1,
1029+
top_level_hits: 1,
1030+
errors: 0,
1031+
is_trace_root: pb::Trilean::True.into(),
1032+
..Default::default()
1033+
},
1034+
];
1035+
1036+
let stats = concentrator.flush(flushtime, false);
1037+
assert_counts_equal(
1038+
expected,
1039+
stats
1040+
.first()
1041+
.expect("There should be at least one time bucket")
1042+
.stats
1043+
.clone(),
1044+
);
1045+
}
1046+
8801047
#[test]
8811048
fn test_compute_stats_for_span_kind() {
8821049
let test_cases: Vec<(SpanSlice, bool)> = vec![

0 commit comments

Comments
 (0)