Skip to content

Commit 4313d83

Browse files
committed
test:Add test to confirm Context expected behavior
1 parent 367e484 commit 4313d83

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed

opentelemetry-sdk/src/trace/mod.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,49 @@ mod tests {
7676
Context, KeyValue,
7777
};
7878

79+
#[test]
80+
fn span_context_immutable() {
81+
let exporter = InMemorySpanExporterBuilder::new().build();
82+
let provider = SdkTracerProvider::builder()
83+
.with_span_processor(SimpleSpanProcessor::new(exporter.clone()))
84+
.build();
85+
let tracer = provider.tracer("test_tracer");
86+
87+
#[derive(Debug, PartialEq)]
88+
struct ValueA(u64);
89+
90+
let span = tracer.start("span-name");
91+
92+
// start with Current, which should have no span
93+
let cx = Context::current();
94+
assert!(cx.has_active_span() == false);
95+
96+
// add span to context
97+
let cx_with_span = cx.with_span(span);
98+
assert!(cx_with_span.has_active_span() == true);
99+
assert!(cx.has_active_span() == false);
100+
101+
// modify the span in the context
102+
let span_ref = cx_with_span.span();
103+
span_ref.set_attribute(KeyValue::new("attribute1", "value1"));
104+
105+
// create a new context, which should not affect the original
106+
let cx_with_span_and_more = cx_with_span.with_value(ValueA(1));
107+
108+
// modify the span in the new context, which should not affect the original
109+
let span_ref_new = cx_with_span_and_more.span();
110+
span_ref_new.set_attribute(KeyValue::new("attribute2", "value2"));
111+
112+
span_ref.end();
113+
span_ref_new.end();
114+
115+
let exported_spans = exporter
116+
.get_finished_spans()
117+
.expect("Spans are expected to be exported.");
118+
// There should be 2 independent spans.
119+
assert_eq!(exported_spans.len(), 2);
120+
}
121+
79122
#[test]
80123
fn tracer_in_span() {
81124
// Arrange

opentelemetry/src/context.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,43 @@ impl Hasher for IdHasher {
385385
mod tests {
386386
use super::*;
387387

388+
#[test]
389+
fn context_immutable() {
390+
#[derive(Debug, PartialEq)]
391+
struct ValueA(u64);
392+
#[derive(Debug, PartialEq)]
393+
struct ValueB(u64);
394+
395+
// start with Current, which should be an empty context
396+
let cx = Context::current();
397+
assert_eq!(cx.get::<ValueA>(), None);
398+
assert_eq!(cx.get::<ValueB>(), None);
399+
400+
// with_value should return a new context,
401+
// leaving the original context unchanged
402+
let cx_new = cx.with_value(ValueA(1));
403+
404+
// cx should be unchanged
405+
assert_eq!(cx.get::<ValueA>(), None);
406+
assert_eq!(cx.get::<ValueB>(), None);
407+
408+
// cx_new should contain the new value
409+
assert_eq!(cx_new.get::<ValueA>(), Some(&ValueA(1)));
410+
411+
// cx_new should be unchanged
412+
let cx_newer = cx_new.with_value(ValueB(1));
413+
414+
// Cx and cx_new are unchanged
415+
assert_eq!(cx.get::<ValueA>(), None);
416+
assert_eq!(cx.get::<ValueB>(), None);
417+
assert_eq!(cx_new.get::<ValueA>(), Some(&ValueA(1)));
418+
assert_eq!(cx_new.get::<ValueB>(), None);
419+
420+
// cx_newer should contain both values
421+
assert_eq!(cx_newer.get::<ValueA>(), Some(&ValueA(1)));
422+
assert_eq!(cx_newer.get::<ValueB>(), Some(&ValueB(1)));
423+
}
424+
388425
#[test]
389426
fn nested_contexts() {
390427
#[derive(Debug, PartialEq)]

0 commit comments

Comments
 (0)