Skip to content

Commit d426414

Browse files
committed
chore(tracing): Add tracing export tests
This adds tests for the tracing exporter. This will help a future PR that modifies this to use the upstream tracing exporter. Signed-off-by: Scott Fleener <[email protected]>
1 parent 9329994 commit d426414

File tree

4 files changed

+156
-9
lines changed

4 files changed

+156
-9
lines changed

Cargo.lock

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
600600
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
601601
dependencies = [
602602
"libc",
603-
"windows-sys 0.52.0",
603+
"windows-sys 0.61.1",
604604
]
605605

606606
[[package]]
@@ -635,9 +635,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
635635

636636
[[package]]
637637
name = "flate2"
638-
version = "1.1.4"
638+
version = "1.1.5"
639639
source = "registry+https://github.com/rust-lang/crates.io-index"
640-
checksum = "dc5a4e564e38c699f2880d3fda590bedc2e69f3f84cd48b457bd892ce61d0aa9"
640+
checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb"
641641
dependencies = [
642642
"crc32fast",
643643
"miniz_oxide",
@@ -1224,7 +1224,7 @@ dependencies = [
12241224
"portable-atomic",
12251225
"portable-atomic-util",
12261226
"serde",
1227-
"windows-sys 0.52.0",
1227+
"windows-sys 0.59.0",
12281228
]
12291229

12301230
[[package]]
@@ -2056,15 +2056,21 @@ name = "linkerd-opentelemetry"
20562056
version = "0.1.0"
20572057
dependencies = [
20582058
"futures",
2059+
"hex",
2060+
"http",
20592061
"http-body",
2062+
"http-body-util",
20602063
"linkerd-error",
20612064
"linkerd-metrics",
20622065
"linkerd-trace-context",
2066+
"linkerd-tracing",
20632067
"opentelemetry",
20642068
"opentelemetry-proto",
20652069
"opentelemetry_sdk",
20662070
"tokio",
20672071
"tonic",
2072+
"tonic-prost",
2073+
"tower-test",
20682074
"tracing",
20692075
]
20702076

@@ -2830,7 +2836,7 @@ version = "0.50.3"
28302836
source = "registry+https://github.com/rust-lang/crates.io-index"
28312837
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
28322838
dependencies = [
2833-
"windows-sys 0.59.0",
2839+
"windows-sys 0.61.1",
28342840
]
28352841

28362842
[[package]]
@@ -3472,7 +3478,7 @@ dependencies = [
34723478
"errno",
34733479
"libc",
34743480
"linux-raw-sys 0.4.15",
3475-
"windows-sys 0.52.0",
3481+
"windows-sys 0.59.0",
34763482
]
34773483

34783484
[[package]]
@@ -3485,7 +3491,7 @@ dependencies = [
34853491
"errno",
34863492
"libc",
34873493
"linux-raw-sys 0.9.2",
3488-
"windows-sys 0.52.0",
3494+
"windows-sys 0.59.0",
34893495
]
34903496

34913497
[[package]]
@@ -3786,7 +3792,7 @@ dependencies = [
37863792
"getrandom 0.3.1",
37873793
"once_cell",
37883794
"rustix 1.0.2",
3789-
"windows-sys 0.52.0",
3795+
"windows-sys 0.61.1",
37903796
]
37913797

37923798
[[package]]

linkerd/opentelemetry/Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,12 @@ tonic = { workspace = true, default-features = false, features = [
2020
] }
2121
tokio = { version = "1", features = ["macros", "sync", "time"] }
2222
tracing = { workspace = true }
23+
hex = "0.4.3"
24+
http-body-util = "0.1.3"
25+
26+
[dev-dependencies]
27+
http = "1"
28+
linkerd-tracing = { path = "../tracing" }
29+
tonic-prost = { workspace = true, default-features = false }
30+
tokio = { version = "1", features = ["test-util"] }
31+
tower-test = { workspace = true }

linkerd/opentelemetry/src/lib.rs

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,3 +276,135 @@ fn convert_span(span: ExportSpan) -> Result<SpanData, Error> {
276276
instrumentation_scope: Default::default(),
277277
})
278278
}
279+
280+
#[cfg(test)]
281+
mod tests {
282+
use super::*;
283+
use linkerd_trace_context::{export::SpanKind, Id, Span};
284+
use opentelemetry_proto::tonic::{common::v1::InstrumentationScope, resource::v1::Resource};
285+
use std::{collections::HashMap, sync::Arc, time::SystemTime};
286+
use tokio::sync::mpsc;
287+
use tonic::codegen::{tokio_stream::wrappers::ReceiverStream, tokio_stream::StreamExt, Bytes};
288+
use tonic_prost::ProstDecoder;
289+
290+
#[tokio::test(flavor = "current_thread")]
291+
async fn send_span() {
292+
let trace_id = Id::from(Bytes::from(
293+
hex::decode("0123456789abcedffedcba9876543210").expect("decode"),
294+
));
295+
let span_id = Id::from(Bytes::from(
296+
hex::decode("fedcba9876543210").expect("decode"),
297+
));
298+
let parent_id = Id::from(Bytes::from(
299+
hex::decode("0123456789abcedf").expect("decode"),
300+
));
301+
let span_name = "test".to_string();
302+
303+
let start = SystemTime::now();
304+
let end = SystemTime::now();
305+
306+
let span = ExportSpan {
307+
span: Span {
308+
trace_id: trace_id.clone(),
309+
span_id: span_id.clone(),
310+
parent_id: parent_id.clone(),
311+
span_name: span_name.clone(),
312+
start,
313+
end,
314+
labels: HashMap::new(),
315+
},
316+
kind: SpanKind::Server,
317+
labels: Arc::new(Default::default()),
318+
};
319+
320+
let mut req = send_mock_request(span).await;
321+
322+
assert_eq!(req.resource_spans.len(), 1);
323+
let mut resource_span = req.resource_spans.remove(0);
324+
assert_eq!(
325+
resource_span.resource,
326+
Some(Resource {
327+
attributes: vec![],
328+
dropped_attributes_count: 0,
329+
entity_refs: vec![],
330+
})
331+
);
332+
assert_eq!(resource_span.schema_url, "");
333+
assert_eq!(resource_span.scope_spans.len(), 1);
334+
335+
let mut scope_span = resource_span.scope_spans.remove(0);
336+
assert_eq!(scope_span.schema_url, "");
337+
assert_eq!(
338+
scope_span.scope,
339+
Some(InstrumentationScope {
340+
name: "".to_string(),
341+
version: "".to_string(),
342+
attributes: vec![],
343+
dropped_attributes_count: 0,
344+
})
345+
);
346+
assert_eq!(scope_span.spans.len(), 1);
347+
348+
let span = scope_span.spans.remove(0);
349+
assert_eq!(
350+
span.span_id,
351+
span_id.into_bytes::<8>().expect("into_bytes").to_vec()
352+
);
353+
assert_eq!(
354+
span.parent_span_id,
355+
parent_id.into_bytes::<8>().expect("into_bytes").to_vec()
356+
);
357+
assert_eq!(
358+
span.trace_id,
359+
trace_id.into_bytes::<16>().expect("into_bytes").to_vec()
360+
);
361+
assert_eq!(span.name, span_name);
362+
assert_eq!(
363+
span.start_time_unix_nano,
364+
start
365+
.duration_since(SystemTime::UNIX_EPOCH)
366+
.expect("duration")
367+
.as_nanos() as u64
368+
);
369+
assert_eq!(
370+
span.end_time_unix_nano,
371+
end.duration_since(SystemTime::UNIX_EPOCH)
372+
.expect("duration")
373+
.as_nanos() as u64
374+
);
375+
assert_eq!(span.flags, 0b11_0000_0000);
376+
}
377+
378+
async fn send_mock_request(span: ExportSpan) -> ExportTraceServiceRequest {
379+
let _trace = linkerd_tracing::test::trace_init();
380+
let (span_tx, span_rx) = mpsc::channel(1);
381+
382+
let (inner, mut handle) = tower_test::mock::pair::<
383+
http::Request<tonic::body::Body>,
384+
http::Response<tonic::body::Body>,
385+
>();
386+
handle.allow(1);
387+
388+
span_tx.try_send(span).expect("Must have space");
389+
390+
let (metrics, _) = metrics::new();
391+
tokio::spawn(export_spans(
392+
inner,
393+
ReceiverStream::new(span_rx),
394+
ResourceAttributesWithSchema::default(),
395+
metrics,
396+
));
397+
398+
let (req, _tx) = handle.next_request().await.expect("next request");
399+
let req = tonic::Request::from_http(req);
400+
let mut req = tonic::codec::Streaming::<ExportTraceServiceRequest>::new_request(
401+
ProstDecoder::default(),
402+
req.into_inner(),
403+
None,
404+
None,
405+
);
406+
let req = req.next().await.expect("next").expect("must succeed");
407+
408+
req
409+
}
410+
}

linkerd/trace-context/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use thiserror::Error;
1616

1717
const SPAN_ID_LEN: usize = 8;
1818

19-
#[derive(Debug, Default)]
19+
#[derive(Debug, Default, Clone)]
2020
pub struct Id(Vec<u8>);
2121

2222
#[derive(Debug, Error)]

0 commit comments

Comments
 (0)