|
1 | 1 | //! Define the ancestry of an event or span.
|
2 | 2 | //!
|
3 |
| -//! See the documentation on the [`Ancestry`] enum for further details. |
| 3 | +//! See the documentation on the [`ExpectedAncestry`] enum for further details. |
4 | 4 |
|
5 | 5 | use tracing_core::{
|
6 | 6 | span::{self, Attributes},
|
7 | 7 | Event,
|
8 | 8 | };
|
9 | 9 |
|
| 10 | +use crate::span::{ActualSpan, ExpectedSpan}; |
| 11 | + |
10 | 12 | /// The ancestry of an event or span.
|
11 | 13 | ///
|
12 | 14 | /// An event or span can have an explicitly assigned parent, or be an explicit root. Otherwise,
|
13 | 15 | /// an event or span may have a contextually assigned parent or in the final case will be a
|
14 | 16 | /// contextual root.
|
15 | 17 | #[derive(Debug, Eq, PartialEq)]
|
16 |
| -pub enum Ancestry { |
17 |
| - /// The event or span has an explicitly assigned parent (created with `parent: span_id`) with |
18 |
| - /// the specified name. |
19 |
| - HasExplicitParent(String), |
| 18 | +pub enum ExpectedAncestry { |
| 19 | + /// The event or span has an explicitly assigned parent (created with `parent: span_id`) span. |
| 20 | + HasExplicitParent(ExpectedSpan), |
20 | 21 | /// The event or span is an explicitly defined root. It was created with `parent: None` and
|
21 | 22 | /// has no parent.
|
22 | 23 | IsExplicitRoot,
|
23 |
| - /// The event or span has a contextually assigned parent with the specified name. It has no |
24 |
| - /// explicitly assigned parent, nor has it been explicitly defined as a root (it was created |
25 |
| - /// without the `parent:` directive). There was a span in context when this event or span was |
26 |
| - /// created. |
27 |
| - HasContextualParent(String), |
| 24 | + /// The event or span has a contextually assigned parent span. It has no explicitly assigned |
| 25 | + /// parent span, nor has it been explicitly defined as a root (it was created without the |
| 26 | + /// `parent:` directive). There was a span in context when this event or span was created. |
| 27 | + HasContextualParent(ExpectedSpan), |
28 | 28 | /// The event or span is a contextual root. It has no explicitly assigned parent, nor has it
|
29 | 29 | /// been explicitly defined as a root (it was created without the `parent:` directive).
|
30 | 30 | /// Additionally, no span was in context when this event or span was created.
|
31 | 31 | IsContextualRoot,
|
32 | 32 | }
|
33 | 33 |
|
34 |
| -impl Ancestry { |
| 34 | +pub(crate) enum ActualAncestry { |
| 35 | + HasExplicitParent(ActualSpan), |
| 36 | + IsExplicitRoot, |
| 37 | + HasContextualParent(ActualSpan), |
| 38 | + IsContextualRoot, |
| 39 | +} |
| 40 | + |
| 41 | +impl ExpectedAncestry { |
35 | 42 | #[track_caller]
|
36 | 43 | pub(crate) fn check(
|
37 | 44 | &self,
|
38 |
| - actual_ancestry: &Ancestry, |
| 45 | + actual_ancestry: &ActualAncestry, |
39 | 46 | ctx: impl std::fmt::Display,
|
40 | 47 | collector_name: &str,
|
41 | 48 | ) {
|
42 |
| - let expected_description = |ancestry: &Ancestry| match ancestry { |
43 |
| - Self::IsExplicitRoot => "be an explicit root".to_string(), |
44 |
| - Self::HasExplicitParent(name) => format!("have an explicit parent with name='{name}'"), |
45 |
| - Self::IsContextualRoot => "be a contextual root".to_string(), |
46 |
| - Self::HasContextualParent(name) => { |
47 |
| - format!("have a contextual parent with name='{name}'") |
| 49 | + match (self, actual_ancestry) { |
| 50 | + (Self::IsExplicitRoot, ActualAncestry::IsExplicitRoot) => {} |
| 51 | + (Self::IsContextualRoot, ActualAncestry::IsContextualRoot) => {} |
| 52 | + ( |
| 53 | + Self::HasExplicitParent(expected_parent), |
| 54 | + ActualAncestry::HasExplicitParent(actual_parent), |
| 55 | + ) => { |
| 56 | + expected_parent.check( |
| 57 | + actual_parent, |
| 58 | + format_args!("{ctx} to have an explicit parent span"), |
| 59 | + collector_name, |
| 60 | + ); |
48 | 61 | }
|
49 |
| - }; |
50 |
| - |
51 |
| - let actual_description = |ancestry: &Ancestry| match ancestry { |
52 |
| - Self::IsExplicitRoot => "was actually an explicit root".to_string(), |
53 |
| - Self::HasExplicitParent(name) => { |
54 |
| - format!("actually has an explicit parent with name='{name}'") |
| 62 | + ( |
| 63 | + Self::HasContextualParent(expected_parent), |
| 64 | + ActualAncestry::HasContextualParent(actual_parent), |
| 65 | + ) => { |
| 66 | + println!("----> [{collector_name}] check {expected_parent:?} against actual parent with Id={id:?}", id = actual_parent.id()); |
| 67 | + expected_parent.check( |
| 68 | + actual_parent, |
| 69 | + format_args!("{ctx} to have a contextual parent span"), |
| 70 | + collector_name, |
| 71 | + ); |
55 | 72 | }
|
56 |
| - Self::IsContextualRoot => "was actually a contextual root".to_string(), |
57 |
| - Self::HasContextualParent(name) => { |
58 |
| - format!("actually has a contextual parent with name='{name}'") |
| 73 | + _ => { |
| 74 | + // Ancestry types don't match at all. |
| 75 | + let expected_description = match self { |
| 76 | + Self::IsExplicitRoot => "be an explicit root", |
| 77 | + Self::HasExplicitParent(_) => "have an explicit parent span", |
| 78 | + Self::IsContextualRoot => "be a contextual root", |
| 79 | + Self::HasContextualParent(_) => "have a contextual parent span", |
| 80 | + }; |
| 81 | + |
| 82 | + let actual_description = match actual_ancestry { |
| 83 | + ActualAncestry::IsExplicitRoot => "is actually an explicit root", |
| 84 | + ActualAncestry::HasExplicitParent(_) => "actually has an explicit parent span", |
| 85 | + ActualAncestry::IsContextualRoot => "is actually a contextual root", |
| 86 | + ActualAncestry::HasContextualParent(_) => { |
| 87 | + "actually has a contextual parent span" |
| 88 | + } |
| 89 | + }; |
| 90 | + |
| 91 | + panic!( |
| 92 | + "{}", |
| 93 | + format!( |
| 94 | + "[{collector_name}] expected {ctx} to {expected_description}, \ |
| 95 | + but it {actual_description}" |
| 96 | + ) |
| 97 | + ); |
59 | 98 | }
|
60 |
| - }; |
61 |
| - |
62 |
| - assert_eq!( |
63 |
| - self, |
64 |
| - actual_ancestry, |
65 |
| - "[{collector_name}] expected {ctx} to {expected_description}, but {actual_description}", |
66 |
| - expected_description = expected_description(self), |
67 |
| - actual_description = actual_description(actual_ancestry) |
68 |
| - ); |
| 99 | + } |
69 | 100 | }
|
70 | 101 | }
|
71 | 102 |
|
@@ -120,29 +151,29 @@ impl HasAncestry for &Attributes<'_> {
|
120 | 151 | pub(crate) fn get_ancestry(
|
121 | 152 | item: impl HasAncestry,
|
122 | 153 | lookup_current: impl FnOnce() -> Option<span::Id>,
|
123 |
| - span_name: impl FnOnce(&span::Id) -> Option<&str>, |
124 |
| -) -> Ancestry { |
| 154 | + actual_span: impl FnOnce(&span::Id) -> Option<ActualSpan>, |
| 155 | +) -> ActualAncestry { |
125 | 156 | if item.is_contextual() {
|
126 | 157 | if let Some(parent_id) = lookup_current() {
|
127 |
| - let contextual_parent_name = span_name(&parent_id).expect( |
| 158 | + let contextual_parent_span = actual_span(&parent_id).expect( |
128 | 159 | "tracing-mock: contextual parent cannot \
|
129 | 160 | be looked up by ID. Was it recorded correctly?",
|
130 | 161 | );
|
131 |
| - Ancestry::HasContextualParent(contextual_parent_name.to_string()) |
| 162 | + ActualAncestry::HasContextualParent(contextual_parent_span) |
132 | 163 | } else {
|
133 |
| - Ancestry::IsContextualRoot |
| 164 | + ActualAncestry::IsContextualRoot |
134 | 165 | }
|
135 | 166 | } else if item.is_root() {
|
136 |
| - Ancestry::IsExplicitRoot |
| 167 | + ActualAncestry::IsExplicitRoot |
137 | 168 | } else {
|
138 | 169 | let parent_id = item.parent().expect(
|
139 | 170 | "tracing-mock: is_contextual=false is_root=false \
|
140 | 171 | but no explicit parent found. This is a bug!",
|
141 | 172 | );
|
142 |
| - let explicit_parent_name = span_name(parent_id).expect( |
| 173 | + let explicit_parent_span = actual_span(parent_id).expect( |
143 | 174 | "tracing-mock: explicit parent cannot be looked \
|
144 | 175 | up by ID. Is the provided Span ID valid: {parent_id}",
|
145 | 176 | );
|
146 |
| - Ancestry::HasExplicitParent(explicit_parent_name.to_string()) |
| 177 | + ActualAncestry::HasExplicitParent(explicit_parent_span) |
147 | 178 | }
|
148 | 179 | }
|
0 commit comments