Skip to content

Commit d59b379

Browse files
committed
chore: add resolver test for origin uniqueness + small cleanup
1 parent 30c0540 commit d59b379

File tree

3 files changed

+59
-22
lines changed
  • bin/agent-data-plane/src/components/remapper
  • lib

3 files changed

+59
-22
lines changed

bin/agent-data-plane/src/components/remapper/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ mod tests {
280280
#[test]
281281
fn test_remap_object_pool_metrics() {
282282
let mut remapper = AgentTelemetryRemapper {
283-
context_resolver: ContextResolverBuilder::for_tests(),
283+
context_resolver: ContextResolverBuilder::for_tests().build(),
284284
rules: get_datadog_agent_remappings(),
285285
};
286286

lib/saluki-components/src/sources/dogstatsd/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -953,7 +953,7 @@ mod tests {
953953
// We set our metric name to be longer than 31 bytes (the inlining limit) to ensure this.
954954

955955
let codec = DogstatsdCodec::from_configuration(DogstatsdCodecConfiguration::default());
956-
let mut context_resolver = ContextResolverBuilder::for_tests().with_heap_allocations(false);
956+
let mut context_resolver = ContextResolverBuilder::for_tests().with_heap_allocations(false).build();
957957
let peer_addr = ConnectionAddress::from("1.1.1.1:1234".parse::<SocketAddr>().unwrap());
958958

959959
let input = "big_metric_name_that_cant_possibly_be_inlined:1|c|#tag1:value1,tag2:value2,tag3:value3";

lib/saluki-context/src/resolver.rs

+57-20
Original file line numberDiff line numberDiff line change
@@ -180,9 +180,9 @@ impl ContextResolverBuilder {
180180
self
181181
}
182182

183-
/// Builds a [`ContextResolver`] with a no-op configuration, suitable for tests.
183+
/// Configures a [`ContextResolverBuilder`] that is suitable for tests.
184184
///
185-
/// This ignores all configuration on the builder and uses a default configuration of:
185+
/// This configures the builder with the following defaults:
186186
///
187187
/// - resolver name of "noop"
188188
/// - unlimited context cache size
@@ -191,13 +191,12 @@ impl ContextResolverBuilder {
191191
///
192192
/// This is generally only useful for testing purposes, and is exposed publicly in order to be used in cross-crate
193193
/// testing scenarios.
194-
pub fn for_tests() -> ContextResolver {
194+
pub fn for_tests() -> ContextResolverBuilder {
195195
ContextResolverBuilder::from_name("noop")
196196
.expect("resolver name not empty")
197197
.with_cached_contexts_limit(usize::MAX)
198198
.with_interner_capacity_bytes(NonZeroUsize::new(1).expect("not zero"))
199199
.with_heap_allocations(true)
200-
.build()
201200
}
202201

203202
/// Builds a [`ContextResolver`] from the current configuration.
@@ -297,18 +296,6 @@ pub struct ContextResolver {
297296
}
298297

299298
impl ContextResolver {
300-
/// Sets whether or not to allow heap allocations when interning strings.
301-
///
302-
/// In cases where the interner is full, this setting determines whether or not we refuse to resolve a context, or
303-
/// if we instead allocate strings normally (which will not be interned and will not be shared with other contexts)
304-
/// to satisfy the request.
305-
///
306-
/// Defaults to `true`.
307-
pub fn with_heap_allocations(mut self, allow: bool) -> Self {
308-
self.allow_heap_allocations = allow;
309-
self
310-
}
311-
312299
fn intern(&self, s: &str) -> Option<MetaString> {
313300
// First we'll see if we can inline the string, and if we can't, then we try to actually intern it. If interning
314301
// fails, then we just fall back to allocating a new `MetaString` instance.
@@ -474,6 +461,7 @@ mod tests {
474461
};
475462

476463
use super::*;
464+
use crate::origin::{OriginKey, OriginTagVisitor};
477465

478466
fn get_gauge_value(metrics: &[(CompositeKey, Option<Unit>, Option<SharedString>, DebugValue)], key: &str) -> f64 {
479467
metrics
@@ -486,9 +474,19 @@ mod tests {
486474
.unwrap_or_else(|| panic!("no metric found with key: {}", key))
487475
}
488476

477+
struct DummyOriginTagsResolver;
478+
479+
impl OriginTagsResolver for DummyOriginTagsResolver {
480+
fn resolve_origin_key(&self, info: OriginInfo<'_>) -> Option<OriginKey> {
481+
Some(OriginKey::from_opaque(info))
482+
}
483+
484+
fn visit_origin_tags(&self, _: OriginKey, _: &mut dyn OriginTagVisitor) {}
485+
}
486+
489487
#[test]
490488
fn basic() {
491-
let mut resolver: ContextResolver = ContextResolverBuilder::for_tests();
489+
let mut resolver = ContextResolverBuilder::for_tests().build();
492490

493491
// Create two distinct contexts with the same name but different tags:
494492
let name = "metric_name";
@@ -526,7 +524,7 @@ mod tests {
526524

527525
#[test]
528526
fn tag_order() {
529-
let mut resolver: ContextResolver = ContextResolverBuilder::for_tests();
527+
let mut resolver = ContextResolverBuilder::for_tests().build();
530528

531529
// Create two distinct contexts with the same name and tags, but with the tags in a different order:
532530
let name = "metric_name";
@@ -555,7 +553,7 @@ mod tests {
555553

556554
// Create our resolver and then create a context, which will have its metrics attached to our local recorder:
557555
let context = metrics::with_local_recorder(&recorder, || {
558-
let mut resolver: ContextResolver = ContextResolverBuilder::for_tests();
556+
let mut resolver = ContextResolverBuilder::for_tests().build();
559557
resolver
560558
.resolve("name", &["tag"][..], None)
561559
.expect("should not fail to resolve")
@@ -575,7 +573,7 @@ mod tests {
575573

576574
#[test]
577575
fn duplicate_tags() {
578-
let mut resolver: ContextResolver = ContextResolverBuilder::for_tests();
576+
let mut resolver = ContextResolverBuilder::for_tests().build();
579577

580578
// Two contexts with the same name, but each with a different set of duplicate tags:
581579
let name = "metric_name";
@@ -614,4 +612,43 @@ mod tests {
614612
assert_ne!(context1, context2_duplicated);
615613
assert_ne!(context2, context1_duplicated);
616614
}
615+
616+
#[test]
617+
fn differing_origins_with_without_resolver() {
618+
// Create a regular context resolver, without any origin tags resolver, which should result in contexts being
619+
// the same so long as the name and tags are the same, disregarding any difference in origin information:
620+
let mut resolver = ContextResolverBuilder::for_tests().build();
621+
622+
let name = "metric_name";
623+
let tags = ["tag1"];
624+
let mut origin1 = OriginInfo::default();
625+
origin1.set_container_id("container1");
626+
let mut origin2 = OriginInfo::default();
627+
origin2.set_container_id("container2");
628+
629+
let context1 = resolver
630+
.resolve(name, &tags[..], Some(origin1.clone()))
631+
.expect("should not fail to resolve");
632+
let context2 = resolver
633+
.resolve(name, &tags[..], Some(origin2.clone()))
634+
.expect("should not fail to resolve");
635+
636+
assert_eq!(context1, context2);
637+
638+
// Now build a context resolver with an origin tags resolver that trivially returns the origin key based on the
639+
// hash of the origin info, which should result in the contexts incorporating the origin information into their
640+
// equality/hashing, thus no longer comparing as equal:
641+
let mut resolver = ContextResolverBuilder::for_tests()
642+
.with_origin_tags_resolver(DummyOriginTagsResolver)
643+
.build();
644+
645+
let context1 = resolver
646+
.resolve(name, &tags[..], Some(origin1))
647+
.expect("should not fail to resolve");
648+
let context2 = resolver
649+
.resolve(name, &tags[..], Some(origin2))
650+
.expect("should not fail to resolve");
651+
652+
assert_ne!(context1, context2);
653+
}
617654
}

0 commit comments

Comments
 (0)