It currently isn't possible to differentiate spans with the same name,
target, and level when setting expectations on enter, exit, and
drop_span. This is not an issue for tracing-mock's original (and
still primary) use case, which is to test tracing itself. However,
when testing the tracing instrumentation in library or application code,
this can be a limitation.
For example, when testing the instrumentation in tokio
(tokio-rs/tokio#6112), it isn't possible to set an expectation on which
task span is entered first, because the name, target, and level of those
spans are always identical - in fact, the spans have the same metadata
and only the field values are different.
Solution
To make differentiating different spans possible, ExpectId has been
introduced. It is an opaque struct which represents a span::Id and can
be used to match spans from a new_span expectation (where a NewSpan
is accepted and all fields and values can be expected) through to
subsequent enter, exit, and drop_span expectations.
An ExpectedId is passed to an ExpectedSpan which then needs to be
expected with MockCollector::new_span. A clone of the ExpectedId (or
a clone of the ExpectedSpan with the ExpectedId already on it) will
then match the ID assigned to the span to the other span lifecycle
expectations.
The ExpectedId uses an Arc<AtomicU64> which has the ID for the new
span assigned to it, and then its clones will be matched against that
same ID.
In future changes it will also be possible to use this ExpectedId to
match parent spans, currently a parent is only matched by name.
Motivation
It currently isn't possible to differentiate spans with the same name, target, and level when setting expectations on
enter
,exit
, anddrop_span
. This is not an issue fortracing-mock
's original (and still primary) use case, which is to testtracing
itself. However, when testing the tracing instrumentation in library or application code, this can be a limitation.For example, when testing the instrumentation in tokio (tokio-rs/tokio#6112), it isn't possible to set an expectation on which task span is entered first, because the name, target, and level of those spans are always identical - in fact, the spans have the same metadata and only the field values are different.
Solution
To make differentiating different spans possible,
ExpectId
has been introduced. It is an opaque struct which represents aspan::Id
and can be used to match spans from anew_span
expectation (where aNewSpan
is accepted and all fields and values can be expected) through to subsequententer
,exit
, anddrop_span
expectations.An
ExpectedId
is passed to anExpectedSpan
which then needs to be expected withMockCollector::new_span
. A clone of theExpectedId
(or a clone of theExpectedSpan
with theExpectedId
already on it) will then match the ID assigned to the span to the other span lifecycle expectations.The
ExpectedId
uses anArc<AtomicU64>
which has the ID for the new span assigned to it, and then its clones will be matched against that same ID.In future changes it will also be possible to use this
ExpectedId
to match parent spans, currently a parent is only matched by name.