tokio-rs / tracing

Application level tracing for Rust.
https://tracing.rs
MIT License
5.39k stars 707 forks source link

mock: add `ExpectedId` to link span expectations #3007

Closed hds closed 3 months ago

hds commented 3 months ago

Motivation

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.