xref: /aosp_15_r20/system/extras/libatrace_rust/src/tracing_subscriber.rs (revision 288bf5226967eb3dac5cce6c939ccc2a7f2b4fe5)
1*288bf522SAndroid Build Coastguard Worker // Copyright (C) 2023 The Android Open Source Project
2*288bf522SAndroid Build Coastguard Worker //
3*288bf522SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*288bf522SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*288bf522SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*288bf522SAndroid Build Coastguard Worker //
7*288bf522SAndroid Build Coastguard Worker //     http://www.apache.org/licenses/LICENSE-2.0
8*288bf522SAndroid Build Coastguard Worker //
9*288bf522SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*288bf522SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*288bf522SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*288bf522SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*288bf522SAndroid Build Coastguard Worker // limitations under the License.
14*288bf522SAndroid Build Coastguard Worker 
15*288bf522SAndroid Build Coastguard Worker //! Tracing-subscriber layer for libatrace_rust.
16*288bf522SAndroid Build Coastguard Worker 
17*288bf522SAndroid Build Coastguard Worker use ::atrace::AtraceTag;
18*288bf522SAndroid Build Coastguard Worker use std::fmt::Write;
19*288bf522SAndroid Build Coastguard Worker use tracing::span::Attributes;
20*288bf522SAndroid Build Coastguard Worker use tracing::span::Record;
21*288bf522SAndroid Build Coastguard Worker use tracing::{Event, Id, Subscriber};
22*288bf522SAndroid Build Coastguard Worker use tracing_subscriber::field::Visit;
23*288bf522SAndroid Build Coastguard Worker use tracing_subscriber::layer::{Context, Layer};
24*288bf522SAndroid Build Coastguard Worker use tracing_subscriber::registry::LookupSpan;
25*288bf522SAndroid Build Coastguard Worker 
26*288bf522SAndroid Build Coastguard Worker /// Subscriber layer that forwards events to ATrace.
27*288bf522SAndroid Build Coastguard Worker pub struct AtraceSubscriber {
28*288bf522SAndroid Build Coastguard Worker     tag: AtraceTag,
29*288bf522SAndroid Build Coastguard Worker     should_record_fields: bool,
30*288bf522SAndroid Build Coastguard Worker     should_filter: bool,
31*288bf522SAndroid Build Coastguard Worker }
32*288bf522SAndroid Build Coastguard Worker 
33*288bf522SAndroid Build Coastguard Worker impl Default for AtraceSubscriber {
default() -> Self34*288bf522SAndroid Build Coastguard Worker     fn default() -> Self {
35*288bf522SAndroid Build Coastguard Worker         Self::new(AtraceTag::App)
36*288bf522SAndroid Build Coastguard Worker     }
37*288bf522SAndroid Build Coastguard Worker }
38*288bf522SAndroid Build Coastguard Worker 
39*288bf522SAndroid Build Coastguard Worker impl AtraceSubscriber {
40*288bf522SAndroid Build Coastguard Worker     /// Makes a new subscriber with tag.
new(tag: AtraceTag) -> AtraceSubscriber41*288bf522SAndroid Build Coastguard Worker     pub fn new(tag: AtraceTag) -> AtraceSubscriber {
42*288bf522SAndroid Build Coastguard Worker         AtraceSubscriber { tag, should_filter: false, should_record_fields: true }
43*288bf522SAndroid Build Coastguard Worker     }
44*288bf522SAndroid Build Coastguard Worker 
45*288bf522SAndroid Build Coastguard Worker     /// Enables event and span filtering. With filtering enabled, this layer would filter events for
46*288bf522SAndroid Build Coastguard Worker     /// all the layers of the subscriber.
47*288bf522SAndroid Build Coastguard Worker     /// Use this to speed up the subscriber if it's the only layer. Do not enable if you need other
48*288bf522SAndroid Build Coastguard Worker     /// layers to receive events when ATrace is disabled.
with_filter(self) -> AtraceSubscriber49*288bf522SAndroid Build Coastguard Worker     pub fn with_filter(self) -> AtraceSubscriber {
50*288bf522SAndroid Build Coastguard Worker         AtraceSubscriber { should_filter: true, ..self }
51*288bf522SAndroid Build Coastguard Worker     }
52*288bf522SAndroid Build Coastguard Worker 
53*288bf522SAndroid Build Coastguard Worker     /// Disables recording of field values.
without_fields(self) -> AtraceSubscriber54*288bf522SAndroid Build Coastguard Worker     pub fn without_fields(self) -> AtraceSubscriber {
55*288bf522SAndroid Build Coastguard Worker         AtraceSubscriber { should_record_fields: false, ..self }
56*288bf522SAndroid Build Coastguard Worker     }
57*288bf522SAndroid Build Coastguard Worker }
58*288bf522SAndroid Build Coastguard Worker 
59*288bf522SAndroid Build Coastguard Worker // Internal methods.
60*288bf522SAndroid Build Coastguard Worker impl AtraceSubscriber {
61*288bf522SAndroid Build Coastguard Worker     /// Checks that events and spans should be recorded in the span/event notification.
should_process_event(&self) -> bool62*288bf522SAndroid Build Coastguard Worker     fn should_process_event(&self) -> bool {
63*288bf522SAndroid Build Coastguard Worker         // If `should_filter == true` we don't need to check the tag - it was already checked by
64*288bf522SAndroid Build Coastguard Worker         // the layer filter in the `Layer::enabled()` method.
65*288bf522SAndroid Build Coastguard Worker         // The checks are done in this order:
66*288bf522SAndroid Build Coastguard Worker         //  * `Layer::register_callsite()` - once per callsite, the result is cached.
67*288bf522SAndroid Build Coastguard Worker         //  * `Layer::enabled()` - once per span or event construction if the callsite is enabled.
68*288bf522SAndroid Build Coastguard Worker         //  * `should_process_event()` - on every notification like new span, span enter/exit/record, event.
69*288bf522SAndroid Build Coastguard Worker         // The first two checks are global, i.e. affect other layers, and only enabled with `should_filter`.
70*288bf522SAndroid Build Coastguard Worker         // Read more:
71*288bf522SAndroid Build Coastguard Worker         // https://docs.rs/tracing-subscriber/latest/tracing_subscriber/layer/index.html#filtering-with-layers
72*288bf522SAndroid Build Coastguard Worker         self.should_filter || atrace::atrace_is_tag_enabled(self.tag)
73*288bf522SAndroid Build Coastguard Worker     }
74*288bf522SAndroid Build Coastguard Worker }
75*288bf522SAndroid Build Coastguard Worker 
76*288bf522SAndroid Build Coastguard Worker impl<S: Subscriber + for<'lookup> LookupSpan<'lookup>> Layer<S> for AtraceSubscriber {
register_callsite( &self, _metadata: &'static tracing::Metadata<'static>, ) -> tracing::subscriber::Interest77*288bf522SAndroid Build Coastguard Worker     fn register_callsite(
78*288bf522SAndroid Build Coastguard Worker         &self,
79*288bf522SAndroid Build Coastguard Worker         _metadata: &'static tracing::Metadata<'static>,
80*288bf522SAndroid Build Coastguard Worker     ) -> tracing::subscriber::Interest {
81*288bf522SAndroid Build Coastguard Worker         if self.should_filter {
82*288bf522SAndroid Build Coastguard Worker             // When we return `Interest::sometimes()`, the `enabled()` method would get checked
83*288bf522SAndroid Build Coastguard Worker             // every time.
84*288bf522SAndroid Build Coastguard Worker             // We can't use callsite caching (`Interest::never()`) because there's no callback
85*288bf522SAndroid Build Coastguard Worker             // for when tracing gets enabled - we need to check it every time.
86*288bf522SAndroid Build Coastguard Worker             tracing::subscriber::Interest::sometimes()
87*288bf522SAndroid Build Coastguard Worker         } else {
88*288bf522SAndroid Build Coastguard Worker             // If we do not disable events in the layer, we always receive the notifications.
89*288bf522SAndroid Build Coastguard Worker             tracing::subscriber::Interest::always()
90*288bf522SAndroid Build Coastguard Worker         }
91*288bf522SAndroid Build Coastguard Worker     }
92*288bf522SAndroid Build Coastguard Worker 
93*288bf522SAndroid Build Coastguard Worker     // When filtering in this layer is enabled, this method would get called on every event and span.
94*288bf522SAndroid Build Coastguard Worker     // This filter affects all layers, so if this method returns false, it would disable the event
95*288bf522SAndroid Build Coastguard Worker     // for others as well.
enabled(&self, _metadata: &tracing::Metadata<'_>, _ctx: Context<'_, S>) -> bool96*288bf522SAndroid Build Coastguard Worker     fn enabled(&self, _metadata: &tracing::Metadata<'_>, _ctx: Context<'_, S>) -> bool {
97*288bf522SAndroid Build Coastguard Worker         !self.should_filter || atrace::atrace_is_tag_enabled(self.tag)
98*288bf522SAndroid Build Coastguard Worker     }
99*288bf522SAndroid Build Coastguard Worker 
on_new_span(&self, attrs: &Attributes, id: &Id, ctx: Context<S>)100*288bf522SAndroid Build Coastguard Worker     fn on_new_span(&self, attrs: &Attributes, id: &Id, ctx: Context<S>) {
101*288bf522SAndroid Build Coastguard Worker         if !self.should_record_fields || attrs.fields().is_empty() || !self.should_process_event() {
102*288bf522SAndroid Build Coastguard Worker             return;
103*288bf522SAndroid Build Coastguard Worker         }
104*288bf522SAndroid Build Coastguard Worker 
105*288bf522SAndroid Build Coastguard Worker         let span = ctx.span(id).unwrap();
106*288bf522SAndroid Build Coastguard Worker         let mut formatter = FieldFormatter::for_span(span.metadata().name());
107*288bf522SAndroid Build Coastguard Worker         attrs.record(&mut formatter);
108*288bf522SAndroid Build Coastguard Worker         span.extensions_mut().insert(formatter);
109*288bf522SAndroid Build Coastguard Worker     }
110*288bf522SAndroid Build Coastguard Worker 
on_record(&self, span: &Id, values: &Record, ctx: Context<S>)111*288bf522SAndroid Build Coastguard Worker     fn on_record(&self, span: &Id, values: &Record, ctx: Context<S>) {
112*288bf522SAndroid Build Coastguard Worker         if !self.should_record_fields || !self.should_process_event() {
113*288bf522SAndroid Build Coastguard Worker             return;
114*288bf522SAndroid Build Coastguard Worker         }
115*288bf522SAndroid Build Coastguard Worker 
116*288bf522SAndroid Build Coastguard Worker         values
117*288bf522SAndroid Build Coastguard Worker             .record(ctx.span(span).unwrap().extensions_mut().get_mut::<FieldFormatter>().unwrap());
118*288bf522SAndroid Build Coastguard Worker     }
119*288bf522SAndroid Build Coastguard Worker 
on_enter(&self, id: &Id, ctx: Context<S>)120*288bf522SAndroid Build Coastguard Worker     fn on_enter(&self, id: &Id, ctx: Context<S>) {
121*288bf522SAndroid Build Coastguard Worker         if !self.should_process_event() {
122*288bf522SAndroid Build Coastguard Worker             return;
123*288bf522SAndroid Build Coastguard Worker         }
124*288bf522SAndroid Build Coastguard Worker 
125*288bf522SAndroid Build Coastguard Worker         let span = ctx.span(id).unwrap();
126*288bf522SAndroid Build Coastguard Worker         if span.fields().is_empty() || !self.should_record_fields {
127*288bf522SAndroid Build Coastguard Worker             atrace::atrace_begin(self.tag, span.metadata().name());
128*288bf522SAndroid Build Coastguard Worker         } else {
129*288bf522SAndroid Build Coastguard Worker             let span_extensions = span.extensions();
130*288bf522SAndroid Build Coastguard Worker             let formatter = span_extensions.get::<FieldFormatter>().unwrap();
131*288bf522SAndroid Build Coastguard Worker             atrace::atrace_begin(self.tag, formatter.as_str());
132*288bf522SAndroid Build Coastguard Worker         }
133*288bf522SAndroid Build Coastguard Worker     }
134*288bf522SAndroid Build Coastguard Worker 
on_exit(&self, _id: &Id, _ctx: Context<S>)135*288bf522SAndroid Build Coastguard Worker     fn on_exit(&self, _id: &Id, _ctx: Context<S>) {
136*288bf522SAndroid Build Coastguard Worker         if !self.should_process_event() {
137*288bf522SAndroid Build Coastguard Worker             return;
138*288bf522SAndroid Build Coastguard Worker         }
139*288bf522SAndroid Build Coastguard Worker 
140*288bf522SAndroid Build Coastguard Worker         atrace::atrace_end(self.tag);
141*288bf522SAndroid Build Coastguard Worker     }
142*288bf522SAndroid Build Coastguard Worker 
on_event(&self, event: &Event, _ctx: Context<S>)143*288bf522SAndroid Build Coastguard Worker     fn on_event(&self, event: &Event, _ctx: Context<S>) {
144*288bf522SAndroid Build Coastguard Worker         if !self.should_process_event() {
145*288bf522SAndroid Build Coastguard Worker             return;
146*288bf522SAndroid Build Coastguard Worker         }
147*288bf522SAndroid Build Coastguard Worker 
148*288bf522SAndroid Build Coastguard Worker         if self.should_record_fields {
149*288bf522SAndroid Build Coastguard Worker             let mut formatter = FieldFormatter::for_event();
150*288bf522SAndroid Build Coastguard Worker             event.record(&mut formatter);
151*288bf522SAndroid Build Coastguard Worker             atrace::atrace_instant(self.tag, formatter.as_str());
152*288bf522SAndroid Build Coastguard Worker         } else if let Some(field) = event.metadata().fields().field("message") {
153*288bf522SAndroid Build Coastguard Worker             struct MessageVisitor<'a> {
154*288bf522SAndroid Build Coastguard Worker                 tag: AtraceTag,
155*288bf522SAndroid Build Coastguard Worker                 field: &'a tracing::field::Field,
156*288bf522SAndroid Build Coastguard Worker             }
157*288bf522SAndroid Build Coastguard Worker             impl Visit for MessageVisitor<'_> {
158*288bf522SAndroid Build Coastguard Worker                 fn record_str(&mut self, field: &tracing::field::Field, value: &str) {
159*288bf522SAndroid Build Coastguard Worker                     if field == self.field {
160*288bf522SAndroid Build Coastguard Worker                         atrace::atrace_instant(self.tag, value);
161*288bf522SAndroid Build Coastguard Worker                     }
162*288bf522SAndroid Build Coastguard Worker                 }
163*288bf522SAndroid Build Coastguard Worker                 fn record_debug(
164*288bf522SAndroid Build Coastguard Worker                     &mut self,
165*288bf522SAndroid Build Coastguard Worker                     field: &tracing::field::Field,
166*288bf522SAndroid Build Coastguard Worker                     value: &dyn std::fmt::Debug,
167*288bf522SAndroid Build Coastguard Worker                 ) {
168*288bf522SAndroid Build Coastguard Worker                     if field == self.field {
169*288bf522SAndroid Build Coastguard Worker                         atrace::atrace_instant(self.tag, &format!("{:?}", value));
170*288bf522SAndroid Build Coastguard Worker                     }
171*288bf522SAndroid Build Coastguard Worker                 }
172*288bf522SAndroid Build Coastguard Worker             }
173*288bf522SAndroid Build Coastguard Worker             event.record(&mut MessageVisitor { tag: self.tag, field: &field });
174*288bf522SAndroid Build Coastguard Worker         } else {
175*288bf522SAndroid Build Coastguard Worker             atrace::atrace_instant(
176*288bf522SAndroid Build Coastguard Worker                 self.tag,
177*288bf522SAndroid Build Coastguard Worker                 &format!("{} event", event.metadata().level().as_str()),
178*288bf522SAndroid Build Coastguard Worker             );
179*288bf522SAndroid Build Coastguard Worker         }
180*288bf522SAndroid Build Coastguard Worker     }
181*288bf522SAndroid Build Coastguard Worker }
182*288bf522SAndroid Build Coastguard Worker 
183*288bf522SAndroid Build Coastguard Worker struct FieldFormatter {
184*288bf522SAndroid Build Coastguard Worker     is_event: bool,
185*288bf522SAndroid Build Coastguard Worker     s: String,
186*288bf522SAndroid Build Coastguard Worker }
187*288bf522SAndroid Build Coastguard Worker 
188*288bf522SAndroid Build Coastguard Worker impl FieldFormatter {
new() -> FieldFormatter189*288bf522SAndroid Build Coastguard Worker     fn new() -> FieldFormatter {
190*288bf522SAndroid Build Coastguard Worker         const DEFAULT_STR_CAPACITY: usize = 128; // Should fit most events without realloc.
191*288bf522SAndroid Build Coastguard Worker         FieldFormatter { is_event: true, s: String::with_capacity(DEFAULT_STR_CAPACITY) }
192*288bf522SAndroid Build Coastguard Worker     }
193*288bf522SAndroid Build Coastguard Worker 
for_event() -> FieldFormatter194*288bf522SAndroid Build Coastguard Worker     fn for_event() -> FieldFormatter {
195*288bf522SAndroid Build Coastguard Worker         FieldFormatter { is_event: true, ..FieldFormatter::new() }
196*288bf522SAndroid Build Coastguard Worker     }
for_span(span_name: &str) -> FieldFormatter197*288bf522SAndroid Build Coastguard Worker     fn for_span(span_name: &str) -> FieldFormatter {
198*288bf522SAndroid Build Coastguard Worker         let mut formatter = FieldFormatter { is_event: false, ..FieldFormatter::new() };
199*288bf522SAndroid Build Coastguard Worker         formatter.s.push_str(span_name);
200*288bf522SAndroid Build Coastguard Worker         formatter
201*288bf522SAndroid Build Coastguard Worker     }
202*288bf522SAndroid Build Coastguard Worker 
as_str(&self) -> &str203*288bf522SAndroid Build Coastguard Worker     fn as_str(&self) -> &str {
204*288bf522SAndroid Build Coastguard Worker         &self.s
205*288bf522SAndroid Build Coastguard Worker     }
add_delimeter_if_needed(&mut self)206*288bf522SAndroid Build Coastguard Worker     fn add_delimeter_if_needed(&mut self) {
207*288bf522SAndroid Build Coastguard Worker         if !self.s.is_empty() {
208*288bf522SAndroid Build Coastguard Worker             self.s.push_str(", ");
209*288bf522SAndroid Build Coastguard Worker         }
210*288bf522SAndroid Build Coastguard Worker     }
211*288bf522SAndroid Build Coastguard Worker }
212*288bf522SAndroid Build Coastguard Worker 
213*288bf522SAndroid Build Coastguard Worker impl Visit for FieldFormatter {
record_str(&mut self, field: &tracing::field::Field, value: &str)214*288bf522SAndroid Build Coastguard Worker     fn record_str(&mut self, field: &tracing::field::Field, value: &str) {
215*288bf522SAndroid Build Coastguard Worker         self.add_delimeter_if_needed();
216*288bf522SAndroid Build Coastguard Worker         if self.is_event && field.name() == "message" {
217*288bf522SAndroid Build Coastguard Worker             self.s.push_str(value);
218*288bf522SAndroid Build Coastguard Worker         } else {
219*288bf522SAndroid Build Coastguard Worker             write!(&mut self.s, "{} = \"{}\"", field.name(), value).unwrap();
220*288bf522SAndroid Build Coastguard Worker         }
221*288bf522SAndroid Build Coastguard Worker     }
record_debug(&mut self, field: &tracing::field::Field, value: &dyn std::fmt::Debug)222*288bf522SAndroid Build Coastguard Worker     fn record_debug(&mut self, field: &tracing::field::Field, value: &dyn std::fmt::Debug) {
223*288bf522SAndroid Build Coastguard Worker         self.add_delimeter_if_needed();
224*288bf522SAndroid Build Coastguard Worker         if self.is_event && field.name() == "message" {
225*288bf522SAndroid Build Coastguard Worker             write!(&mut self.s, "{:?}", value).unwrap();
226*288bf522SAndroid Build Coastguard Worker         } else {
227*288bf522SAndroid Build Coastguard Worker             write!(&mut self.s, "{} = {:?}", field.name(), value).unwrap();
228*288bf522SAndroid Build Coastguard Worker         }
229*288bf522SAndroid Build Coastguard Worker     }
230*288bf522SAndroid Build Coastguard Worker }
231*288bf522SAndroid Build Coastguard Worker 
232*288bf522SAndroid Build Coastguard Worker #[cfg(test)]
233*288bf522SAndroid Build Coastguard Worker use self::tests::mock_atrace as atrace;
234*288bf522SAndroid Build Coastguard Worker 
235*288bf522SAndroid Build Coastguard Worker #[cfg(test)]
236*288bf522SAndroid Build Coastguard Worker mod tests {
237*288bf522SAndroid Build Coastguard Worker     use super::*;
238*288bf522SAndroid Build Coastguard Worker     use tracing::Level;
239*288bf522SAndroid Build Coastguard Worker     use tracing_subscriber::prelude::__tracing_subscriber_SubscriberExt;
240*288bf522SAndroid Build Coastguard Worker 
241*288bf522SAndroid Build Coastguard Worker     pub mod mock_atrace {
242*288bf522SAndroid Build Coastguard Worker         use atrace::AtraceTag;
243*288bf522SAndroid Build Coastguard Worker         use std::cell::RefCell;
244*288bf522SAndroid Build Coastguard Worker 
245*288bf522SAndroid Build Coastguard Worker         /// Contains logic to check binding calls.
246*288bf522SAndroid Build Coastguard Worker         /// Implement this trait in the test with mocking logic and checks in implemented functions.
247*288bf522SAndroid Build Coastguard Worker         /// Default implementations panic.
248*288bf522SAndroid Build Coastguard Worker         pub trait ATraceMocker {
atrace_is_tag_enabled(&mut self, _tag: AtraceTag) -> bool249*288bf522SAndroid Build Coastguard Worker             fn atrace_is_tag_enabled(&mut self, _tag: AtraceTag) -> bool {
250*288bf522SAndroid Build Coastguard Worker                 panic!("Unexpected call");
251*288bf522SAndroid Build Coastguard Worker             }
252*288bf522SAndroid Build Coastguard Worker 
atrace_begin(&mut self, _tag: AtraceTag, _name: &str)253*288bf522SAndroid Build Coastguard Worker             fn atrace_begin(&mut self, _tag: AtraceTag, _name: &str) {
254*288bf522SAndroid Build Coastguard Worker                 panic!("Unexpected call");
255*288bf522SAndroid Build Coastguard Worker             }
256*288bf522SAndroid Build Coastguard Worker 
atrace_end(&mut self, _tag: AtraceTag)257*288bf522SAndroid Build Coastguard Worker             fn atrace_end(&mut self, _tag: AtraceTag) {
258*288bf522SAndroid Build Coastguard Worker                 panic!("Unexpected call");
259*288bf522SAndroid Build Coastguard Worker             }
260*288bf522SAndroid Build Coastguard Worker 
atrace_instant(&mut self, _tag: AtraceTag, _name: &str)261*288bf522SAndroid Build Coastguard Worker             fn atrace_instant(&mut self, _tag: AtraceTag, _name: &str) {
262*288bf522SAndroid Build Coastguard Worker                 panic!("Unexpected call");
263*288bf522SAndroid Build Coastguard Worker             }
264*288bf522SAndroid Build Coastguard Worker 
265*288bf522SAndroid Build Coastguard Worker             /// This method should contain checks to be performed at the end of the test.
finish(&self)266*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {}
267*288bf522SAndroid Build Coastguard Worker         }
268*288bf522SAndroid Build Coastguard Worker 
269*288bf522SAndroid Build Coastguard Worker         struct DefaultMocker;
270*288bf522SAndroid Build Coastguard Worker         impl ATraceMocker for DefaultMocker {}
271*288bf522SAndroid Build Coastguard Worker 
272*288bf522SAndroid Build Coastguard Worker         // Global mock object is thread-local, so that the tests can run safely in parallel.
273*288bf522SAndroid Build Coastguard Worker         thread_local!(static MOCKER: RefCell<Box<dyn ATraceMocker>> = RefCell::new(Box::new(DefaultMocker{})));
274*288bf522SAndroid Build Coastguard Worker 
275*288bf522SAndroid Build Coastguard Worker         /// Sets the global mock object.
set_mocker(mocker: Box<dyn ATraceMocker>)276*288bf522SAndroid Build Coastguard Worker         fn set_mocker(mocker: Box<dyn ATraceMocker>) {
277*288bf522SAndroid Build Coastguard Worker             MOCKER.with(|m| *m.borrow_mut() = mocker)
278*288bf522SAndroid Build Coastguard Worker         }
279*288bf522SAndroid Build Coastguard Worker 
280*288bf522SAndroid Build Coastguard Worker         /// Calls the passed method `f` with a mutable reference to the global mock object.
281*288bf522SAndroid Build Coastguard Worker         /// Example:
282*288bf522SAndroid Build Coastguard Worker         /// ```
283*288bf522SAndroid Build Coastguard Worker         /// with_mocker(|mocker| mocker.atrace_begin(tag, name))
284*288bf522SAndroid Build Coastguard Worker         /// ```
with_mocker<F, R>(f: F) -> R where F: FnOnce(&mut dyn ATraceMocker) -> R,285*288bf522SAndroid Build Coastguard Worker         fn with_mocker<F, R>(f: F) -> R
286*288bf522SAndroid Build Coastguard Worker         where
287*288bf522SAndroid Build Coastguard Worker             F: FnOnce(&mut dyn ATraceMocker) -> R,
288*288bf522SAndroid Build Coastguard Worker         {
289*288bf522SAndroid Build Coastguard Worker             MOCKER.with(|m| f(m.borrow_mut().as_mut()))
290*288bf522SAndroid Build Coastguard Worker         }
291*288bf522SAndroid Build Coastguard Worker 
292*288bf522SAndroid Build Coastguard Worker         /// Finish the test and perform final checks in the mocker.
293*288bf522SAndroid Build Coastguard Worker         /// Calls `finish()` on the global mocker.
294*288bf522SAndroid Build Coastguard Worker         ///
295*288bf522SAndroid Build Coastguard Worker         /// Needs to be called manually at the end of each test that uses mocks.
296*288bf522SAndroid Build Coastguard Worker         ///
297*288bf522SAndroid Build Coastguard Worker         /// May panic, so it can not be called in `drop()` methods,
298*288bf522SAndroid Build Coastguard Worker         /// since it may result in double panic.
mocker_finish()299*288bf522SAndroid Build Coastguard Worker         pub fn mocker_finish() {
300*288bf522SAndroid Build Coastguard Worker             with_mocker(|m| m.finish())
301*288bf522SAndroid Build Coastguard Worker         }
302*288bf522SAndroid Build Coastguard Worker 
303*288bf522SAndroid Build Coastguard Worker         /// RAII guard that resets the mock to the default implementation.
304*288bf522SAndroid Build Coastguard Worker         pub struct MockerGuard;
305*288bf522SAndroid Build Coastguard Worker         impl Drop for MockerGuard {
drop(&mut self)306*288bf522SAndroid Build Coastguard Worker             fn drop(&mut self) {
307*288bf522SAndroid Build Coastguard Worker                 set_mocker(Box::new(DefaultMocker {}));
308*288bf522SAndroid Build Coastguard Worker             }
309*288bf522SAndroid Build Coastguard Worker         }
310*288bf522SAndroid Build Coastguard Worker 
311*288bf522SAndroid Build Coastguard Worker         /// Sets the mock object for the duration of the scope.
312*288bf522SAndroid Build Coastguard Worker         ///
313*288bf522SAndroid Build Coastguard Worker         /// Returns a RAII guard that resets the mock back to default on destruction.
set_scoped_mocker<T: ATraceMocker + 'static>(m: T) -> MockerGuard314*288bf522SAndroid Build Coastguard Worker         pub fn set_scoped_mocker<T: ATraceMocker + 'static>(m: T) -> MockerGuard {
315*288bf522SAndroid Build Coastguard Worker             set_mocker(Box::new(m));
316*288bf522SAndroid Build Coastguard Worker             MockerGuard {}
317*288bf522SAndroid Build Coastguard Worker         }
318*288bf522SAndroid Build Coastguard Worker 
319*288bf522SAndroid Build Coastguard Worker         // Wrapped functions that forward calls into mocker.
320*288bf522SAndroid Build Coastguard Worker 
atrace_is_tag_enabled(tag: AtraceTag) -> bool321*288bf522SAndroid Build Coastguard Worker         pub fn atrace_is_tag_enabled(tag: AtraceTag) -> bool {
322*288bf522SAndroid Build Coastguard Worker             with_mocker(|m| m.atrace_is_tag_enabled(tag))
323*288bf522SAndroid Build Coastguard Worker         }
atrace_begin(tag: AtraceTag, name: &str)324*288bf522SAndroid Build Coastguard Worker         pub fn atrace_begin(tag: AtraceTag, name: &str) {
325*288bf522SAndroid Build Coastguard Worker             with_mocker(|m| m.atrace_begin(tag, name))
326*288bf522SAndroid Build Coastguard Worker         }
327*288bf522SAndroid Build Coastguard Worker 
atrace_end(tag: AtraceTag)328*288bf522SAndroid Build Coastguard Worker         pub fn atrace_end(tag: AtraceTag) {
329*288bf522SAndroid Build Coastguard Worker             with_mocker(|m| m.atrace_end(tag))
330*288bf522SAndroid Build Coastguard Worker         }
331*288bf522SAndroid Build Coastguard Worker 
atrace_instant(tag: AtraceTag, name: &str)332*288bf522SAndroid Build Coastguard Worker         pub fn atrace_instant(tag: AtraceTag, name: &str) {
333*288bf522SAndroid Build Coastguard Worker             with_mocker(|m| m.atrace_instant(tag, name))
334*288bf522SAndroid Build Coastguard Worker         }
335*288bf522SAndroid Build Coastguard Worker     }
336*288bf522SAndroid Build Coastguard Worker 
337*288bf522SAndroid Build Coastguard Worker     #[test]
emits_span_begin()338*288bf522SAndroid Build Coastguard Worker     fn emits_span_begin() {
339*288bf522SAndroid Build Coastguard Worker         #[derive(Default)]
340*288bf522SAndroid Build Coastguard Worker         struct CallCheck {
341*288bf522SAndroid Build Coastguard Worker             begin_count: u32,
342*288bf522SAndroid Build Coastguard Worker         }
343*288bf522SAndroid Build Coastguard Worker         impl mock_atrace::ATraceMocker for CallCheck {
344*288bf522SAndroid Build Coastguard Worker             fn atrace_is_tag_enabled(&mut self, _tag: AtraceTag) -> bool {
345*288bf522SAndroid Build Coastguard Worker                 true
346*288bf522SAndroid Build Coastguard Worker             }
347*288bf522SAndroid Build Coastguard Worker             fn atrace_begin(&mut self, tag: AtraceTag, name: &str) {
348*288bf522SAndroid Build Coastguard Worker                 self.begin_count += 1;
349*288bf522SAndroid Build Coastguard Worker                 assert!(self.begin_count < 2);
350*288bf522SAndroid Build Coastguard Worker                 assert_eq!(tag, AtraceTag::App);
351*288bf522SAndroid Build Coastguard Worker                 assert_eq!(name, "test span");
352*288bf522SAndroid Build Coastguard Worker             }
353*288bf522SAndroid Build Coastguard Worker             fn atrace_end(&mut self, _tag: AtraceTag) {}
354*288bf522SAndroid Build Coastguard Worker 
355*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {
356*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.begin_count, 1);
357*288bf522SAndroid Build Coastguard Worker             }
358*288bf522SAndroid Build Coastguard Worker         }
359*288bf522SAndroid Build Coastguard Worker         let _mock_guard = mock_atrace::set_scoped_mocker(CallCheck::default());
360*288bf522SAndroid Build Coastguard Worker 
361*288bf522SAndroid Build Coastguard Worker         let _subscriber_guard = tracing::subscriber::set_default(
362*288bf522SAndroid Build Coastguard Worker             tracing_subscriber::registry().with(AtraceSubscriber::default()),
363*288bf522SAndroid Build Coastguard Worker         );
364*288bf522SAndroid Build Coastguard Worker 
365*288bf522SAndroid Build Coastguard Worker         let _span = tracing::info_span!("test span").entered();
366*288bf522SAndroid Build Coastguard Worker 
367*288bf522SAndroid Build Coastguard Worker         mock_atrace::mocker_finish();
368*288bf522SAndroid Build Coastguard Worker     }
369*288bf522SAndroid Build Coastguard Worker 
370*288bf522SAndroid Build Coastguard Worker     #[test]
emits_span_end()371*288bf522SAndroid Build Coastguard Worker     fn emits_span_end() {
372*288bf522SAndroid Build Coastguard Worker         #[derive(Default)]
373*288bf522SAndroid Build Coastguard Worker         struct CallCheck {
374*288bf522SAndroid Build Coastguard Worker             end_count: u32,
375*288bf522SAndroid Build Coastguard Worker         }
376*288bf522SAndroid Build Coastguard Worker         impl mock_atrace::ATraceMocker for CallCheck {
377*288bf522SAndroid Build Coastguard Worker             fn atrace_is_tag_enabled(&mut self, _tag: AtraceTag) -> bool {
378*288bf522SAndroid Build Coastguard Worker                 true
379*288bf522SAndroid Build Coastguard Worker             }
380*288bf522SAndroid Build Coastguard Worker             fn atrace_begin(&mut self, _tag: AtraceTag, _name: &str) {}
381*288bf522SAndroid Build Coastguard Worker             fn atrace_end(&mut self, tag: AtraceTag) {
382*288bf522SAndroid Build Coastguard Worker                 self.end_count += 1;
383*288bf522SAndroid Build Coastguard Worker                 assert!(self.end_count < 2);
384*288bf522SAndroid Build Coastguard Worker                 assert_eq!(tag, AtraceTag::App);
385*288bf522SAndroid Build Coastguard Worker             }
386*288bf522SAndroid Build Coastguard Worker 
387*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {
388*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.end_count, 1);
389*288bf522SAndroid Build Coastguard Worker             }
390*288bf522SAndroid Build Coastguard Worker         }
391*288bf522SAndroid Build Coastguard Worker         let _mock_guard = mock_atrace::set_scoped_mocker(CallCheck::default());
392*288bf522SAndroid Build Coastguard Worker 
393*288bf522SAndroid Build Coastguard Worker         let _subscriber_guard = tracing::subscriber::set_default(
394*288bf522SAndroid Build Coastguard Worker             tracing_subscriber::registry().with(AtraceSubscriber::default()),
395*288bf522SAndroid Build Coastguard Worker         );
396*288bf522SAndroid Build Coastguard Worker 
397*288bf522SAndroid Build Coastguard Worker         {
398*288bf522SAndroid Build Coastguard Worker             let _span = tracing::info_span!("test span").entered();
399*288bf522SAndroid Build Coastguard Worker         }
400*288bf522SAndroid Build Coastguard Worker 
401*288bf522SAndroid Build Coastguard Worker         mock_atrace::mocker_finish();
402*288bf522SAndroid Build Coastguard Worker     }
403*288bf522SAndroid Build Coastguard Worker 
404*288bf522SAndroid Build Coastguard Worker     #[test]
span_begin_end_is_ordered()405*288bf522SAndroid Build Coastguard Worker     fn span_begin_end_is_ordered() {
406*288bf522SAndroid Build Coastguard Worker         #[derive(Default)]
407*288bf522SAndroid Build Coastguard Worker         struct CallCheck {
408*288bf522SAndroid Build Coastguard Worker             begin_count: u32,
409*288bf522SAndroid Build Coastguard Worker             instant_count: u32,
410*288bf522SAndroid Build Coastguard Worker             end_count: u32,
411*288bf522SAndroid Build Coastguard Worker         }
412*288bf522SAndroid Build Coastguard Worker         impl mock_atrace::ATraceMocker for CallCheck {
413*288bf522SAndroid Build Coastguard Worker             fn atrace_is_tag_enabled(&mut self, _tag: AtraceTag) -> bool {
414*288bf522SAndroid Build Coastguard Worker                 true
415*288bf522SAndroid Build Coastguard Worker             }
416*288bf522SAndroid Build Coastguard Worker             fn atrace_begin(&mut self, _tag: AtraceTag, _name: &str) {
417*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.end_count, 0);
418*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.instant_count, 0);
419*288bf522SAndroid Build Coastguard Worker 
420*288bf522SAndroid Build Coastguard Worker                 self.begin_count += 1;
421*288bf522SAndroid Build Coastguard Worker                 assert!(self.begin_count < 2);
422*288bf522SAndroid Build Coastguard Worker             }
423*288bf522SAndroid Build Coastguard Worker             fn atrace_instant(&mut self, _tag: AtraceTag, _name: &str) {
424*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.begin_count, 1);
425*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.end_count, 0);
426*288bf522SAndroid Build Coastguard Worker 
427*288bf522SAndroid Build Coastguard Worker                 self.instant_count += 1;
428*288bf522SAndroid Build Coastguard Worker                 assert!(self.instant_count < 2);
429*288bf522SAndroid Build Coastguard Worker             }
430*288bf522SAndroid Build Coastguard Worker             fn atrace_end(&mut self, _tag: AtraceTag) {
431*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.begin_count, 1);
432*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.instant_count, 1);
433*288bf522SAndroid Build Coastguard Worker 
434*288bf522SAndroid Build Coastguard Worker                 self.end_count += 1;
435*288bf522SAndroid Build Coastguard Worker                 assert!(self.end_count < 2);
436*288bf522SAndroid Build Coastguard Worker             }
437*288bf522SAndroid Build Coastguard Worker 
438*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {
439*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.begin_count, 1);
440*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.end_count, 1);
441*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.instant_count, 1);
442*288bf522SAndroid Build Coastguard Worker             }
443*288bf522SAndroid Build Coastguard Worker         }
444*288bf522SAndroid Build Coastguard Worker         let _mock_guard = mock_atrace::set_scoped_mocker(CallCheck::default());
445*288bf522SAndroid Build Coastguard Worker 
446*288bf522SAndroid Build Coastguard Worker         let _subscriber_guard = tracing::subscriber::set_default(
447*288bf522SAndroid Build Coastguard Worker             tracing_subscriber::registry().with(AtraceSubscriber::default()),
448*288bf522SAndroid Build Coastguard Worker         );
449*288bf522SAndroid Build Coastguard Worker 
450*288bf522SAndroid Build Coastguard Worker         {
451*288bf522SAndroid Build Coastguard Worker             let _span = tracing::info_span!("span").entered();
452*288bf522SAndroid Build Coastguard Worker             tracing::info!("test info");
453*288bf522SAndroid Build Coastguard Worker         }
454*288bf522SAndroid Build Coastguard Worker 
455*288bf522SAndroid Build Coastguard Worker         mock_atrace::mocker_finish();
456*288bf522SAndroid Build Coastguard Worker     }
457*288bf522SAndroid Build Coastguard Worker 
458*288bf522SAndroid Build Coastguard Worker     #[test]
emits_instant_event()459*288bf522SAndroid Build Coastguard Worker     fn emits_instant_event() {
460*288bf522SAndroid Build Coastguard Worker         #[derive(Default)]
461*288bf522SAndroid Build Coastguard Worker         struct CallCheck {
462*288bf522SAndroid Build Coastguard Worker             instant_count: u32,
463*288bf522SAndroid Build Coastguard Worker         }
464*288bf522SAndroid Build Coastguard Worker         impl mock_atrace::ATraceMocker for CallCheck {
465*288bf522SAndroid Build Coastguard Worker             fn atrace_is_tag_enabled(&mut self, _tag: AtraceTag) -> bool {
466*288bf522SAndroid Build Coastguard Worker                 true
467*288bf522SAndroid Build Coastguard Worker             }
468*288bf522SAndroid Build Coastguard Worker             fn atrace_instant(&mut self, tag: AtraceTag, name: &str) {
469*288bf522SAndroid Build Coastguard Worker                 self.instant_count += 1;
470*288bf522SAndroid Build Coastguard Worker                 assert!(self.instant_count < 2);
471*288bf522SAndroid Build Coastguard Worker                 assert_eq!(tag, AtraceTag::App);
472*288bf522SAndroid Build Coastguard Worker                 assert_eq!(name, "test info");
473*288bf522SAndroid Build Coastguard Worker             }
474*288bf522SAndroid Build Coastguard Worker 
475*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {
476*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.instant_count, 1);
477*288bf522SAndroid Build Coastguard Worker             }
478*288bf522SAndroid Build Coastguard Worker         }
479*288bf522SAndroid Build Coastguard Worker         let _mock_guard = mock_atrace::set_scoped_mocker(CallCheck::default());
480*288bf522SAndroid Build Coastguard Worker 
481*288bf522SAndroid Build Coastguard Worker         let _subscriber_guard = tracing::subscriber::set_default(
482*288bf522SAndroid Build Coastguard Worker             tracing_subscriber::registry().with(AtraceSubscriber::default()),
483*288bf522SAndroid Build Coastguard Worker         );
484*288bf522SAndroid Build Coastguard Worker 
485*288bf522SAndroid Build Coastguard Worker         tracing::info!("test info");
486*288bf522SAndroid Build Coastguard Worker 
487*288bf522SAndroid Build Coastguard Worker         mock_atrace::mocker_finish();
488*288bf522SAndroid Build Coastguard Worker     }
489*288bf522SAndroid Build Coastguard Worker 
490*288bf522SAndroid Build Coastguard Worker     #[test]
formats_event_without_message_with_fields_disabled()491*288bf522SAndroid Build Coastguard Worker     fn formats_event_without_message_with_fields_disabled() {
492*288bf522SAndroid Build Coastguard Worker         #[derive(Default)]
493*288bf522SAndroid Build Coastguard Worker         struct CallCheck {
494*288bf522SAndroid Build Coastguard Worker             instant_count: u32,
495*288bf522SAndroid Build Coastguard Worker         }
496*288bf522SAndroid Build Coastguard Worker         impl mock_atrace::ATraceMocker for CallCheck {
497*288bf522SAndroid Build Coastguard Worker             fn atrace_is_tag_enabled(&mut self, _tag: AtraceTag) -> bool {
498*288bf522SAndroid Build Coastguard Worker                 true
499*288bf522SAndroid Build Coastguard Worker             }
500*288bf522SAndroid Build Coastguard Worker             fn atrace_instant(&mut self, _tag: AtraceTag, name: &str) {
501*288bf522SAndroid Build Coastguard Worker                 self.instant_count += 1;
502*288bf522SAndroid Build Coastguard Worker                 assert!(self.instant_count < 2);
503*288bf522SAndroid Build Coastguard Worker                 assert_eq!(name, "DEBUG event");
504*288bf522SAndroid Build Coastguard Worker             }
505*288bf522SAndroid Build Coastguard Worker 
506*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {
507*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.instant_count, 1);
508*288bf522SAndroid Build Coastguard Worker             }
509*288bf522SAndroid Build Coastguard Worker         }
510*288bf522SAndroid Build Coastguard Worker         let _mock_guard = mock_atrace::set_scoped_mocker(CallCheck::default());
511*288bf522SAndroid Build Coastguard Worker 
512*288bf522SAndroid Build Coastguard Worker         let _subscriber_guard = tracing::subscriber::set_default(
513*288bf522SAndroid Build Coastguard Worker             tracing_subscriber::registry().with(AtraceSubscriber::default().without_fields()),
514*288bf522SAndroid Build Coastguard Worker         );
515*288bf522SAndroid Build Coastguard Worker 
516*288bf522SAndroid Build Coastguard Worker         tracing::debug!(foo = 1);
517*288bf522SAndroid Build Coastguard Worker 
518*288bf522SAndroid Build Coastguard Worker         mock_atrace::mocker_finish();
519*288bf522SAndroid Build Coastguard Worker     }
520*288bf522SAndroid Build Coastguard Worker 
521*288bf522SAndroid Build Coastguard Worker     #[test]
formats_event_without_message_with_fields_enabled()522*288bf522SAndroid Build Coastguard Worker     fn formats_event_without_message_with_fields_enabled() {
523*288bf522SAndroid Build Coastguard Worker         #[derive(Default)]
524*288bf522SAndroid Build Coastguard Worker         struct CallCheck {
525*288bf522SAndroid Build Coastguard Worker             instant_count: u32,
526*288bf522SAndroid Build Coastguard Worker         }
527*288bf522SAndroid Build Coastguard Worker         impl mock_atrace::ATraceMocker for CallCheck {
528*288bf522SAndroid Build Coastguard Worker             fn atrace_is_tag_enabled(&mut self, _tag: AtraceTag) -> bool {
529*288bf522SAndroid Build Coastguard Worker                 true
530*288bf522SAndroid Build Coastguard Worker             }
531*288bf522SAndroid Build Coastguard Worker             fn atrace_instant(&mut self, _tag: AtraceTag, name: &str) {
532*288bf522SAndroid Build Coastguard Worker                 self.instant_count += 1;
533*288bf522SAndroid Build Coastguard Worker                 assert!(self.instant_count < 2);
534*288bf522SAndroid Build Coastguard Worker                 assert_eq!(name, "foo = 1");
535*288bf522SAndroid Build Coastguard Worker             }
536*288bf522SAndroid Build Coastguard Worker 
537*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {
538*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.instant_count, 1);
539*288bf522SAndroid Build Coastguard Worker             }
540*288bf522SAndroid Build Coastguard Worker         }
541*288bf522SAndroid Build Coastguard Worker         let _mock_guard = mock_atrace::set_scoped_mocker(CallCheck::default());
542*288bf522SAndroid Build Coastguard Worker 
543*288bf522SAndroid Build Coastguard Worker         let _subscriber_guard = tracing::subscriber::set_default(
544*288bf522SAndroid Build Coastguard Worker             tracing_subscriber::registry().with(AtraceSubscriber::default()),
545*288bf522SAndroid Build Coastguard Worker         );
546*288bf522SAndroid Build Coastguard Worker 
547*288bf522SAndroid Build Coastguard Worker         tracing::debug!(foo = 1);
548*288bf522SAndroid Build Coastguard Worker 
549*288bf522SAndroid Build Coastguard Worker         mock_atrace::mocker_finish();
550*288bf522SAndroid Build Coastguard Worker     }
551*288bf522SAndroid Build Coastguard Worker 
552*288bf522SAndroid Build Coastguard Worker     #[test]
can_set_tag()553*288bf522SAndroid Build Coastguard Worker     fn can_set_tag() {
554*288bf522SAndroid Build Coastguard Worker         #[derive(Default)]
555*288bf522SAndroid Build Coastguard Worker         struct CallCheck {
556*288bf522SAndroid Build Coastguard Worker             begin_count: u32,
557*288bf522SAndroid Build Coastguard Worker             instant_count: u32,
558*288bf522SAndroid Build Coastguard Worker             end_count: u32,
559*288bf522SAndroid Build Coastguard Worker         }
560*288bf522SAndroid Build Coastguard Worker         impl mock_atrace::ATraceMocker for CallCheck {
561*288bf522SAndroid Build Coastguard Worker             fn atrace_is_tag_enabled(&mut self, _tag: AtraceTag) -> bool {
562*288bf522SAndroid Build Coastguard Worker                 true
563*288bf522SAndroid Build Coastguard Worker             }
564*288bf522SAndroid Build Coastguard Worker             fn atrace_begin(&mut self, tag: AtraceTag, _name: &str) {
565*288bf522SAndroid Build Coastguard Worker                 self.begin_count += 1;
566*288bf522SAndroid Build Coastguard Worker                 assert!(self.begin_count < 2);
567*288bf522SAndroid Build Coastguard Worker                 assert_eq!(tag, AtraceTag::WindowManager);
568*288bf522SAndroid Build Coastguard Worker             }
569*288bf522SAndroid Build Coastguard Worker             fn atrace_instant(&mut self, tag: AtraceTag, _name: &str) {
570*288bf522SAndroid Build Coastguard Worker                 self.instant_count += 1;
571*288bf522SAndroid Build Coastguard Worker                 assert!(self.instant_count < 2);
572*288bf522SAndroid Build Coastguard Worker                 assert_eq!(tag, AtraceTag::WindowManager);
573*288bf522SAndroid Build Coastguard Worker             }
574*288bf522SAndroid Build Coastguard Worker             fn atrace_end(&mut self, tag: AtraceTag) {
575*288bf522SAndroid Build Coastguard Worker                 self.end_count += 1;
576*288bf522SAndroid Build Coastguard Worker                 assert!(self.end_count < 2);
577*288bf522SAndroid Build Coastguard Worker                 assert_eq!(tag, AtraceTag::WindowManager);
578*288bf522SAndroid Build Coastguard Worker             }
579*288bf522SAndroid Build Coastguard Worker 
580*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {
581*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.begin_count, 1);
582*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.end_count, 1);
583*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.instant_count, 1);
584*288bf522SAndroid Build Coastguard Worker             }
585*288bf522SAndroid Build Coastguard Worker         }
586*288bf522SAndroid Build Coastguard Worker         let _mock_guard = mock_atrace::set_scoped_mocker(CallCheck::default());
587*288bf522SAndroid Build Coastguard Worker 
588*288bf522SAndroid Build Coastguard Worker         let _subscriber_guard = tracing::subscriber::set_default(
589*288bf522SAndroid Build Coastguard Worker             tracing_subscriber::registry().with(AtraceSubscriber::new(AtraceTag::WindowManager)),
590*288bf522SAndroid Build Coastguard Worker         );
591*288bf522SAndroid Build Coastguard Worker 
592*288bf522SAndroid Build Coastguard Worker         {
593*288bf522SAndroid Build Coastguard Worker             let _span = tracing::info_span!("span").entered();
594*288bf522SAndroid Build Coastguard Worker             tracing::info!("test info");
595*288bf522SAndroid Build Coastguard Worker         }
596*288bf522SAndroid Build Coastguard Worker 
597*288bf522SAndroid Build Coastguard Worker         mock_atrace::mocker_finish();
598*288bf522SAndroid Build Coastguard Worker     }
599*288bf522SAndroid Build Coastguard Worker 
600*288bf522SAndroid Build Coastguard Worker     #[test]
fields_ignored_when_disabled()601*288bf522SAndroid Build Coastguard Worker     fn fields_ignored_when_disabled() {
602*288bf522SAndroid Build Coastguard Worker         #[derive(Default)]
603*288bf522SAndroid Build Coastguard Worker         struct CallCheck {
604*288bf522SAndroid Build Coastguard Worker             begin_count: u32,
605*288bf522SAndroid Build Coastguard Worker             instant_count: u32,
606*288bf522SAndroid Build Coastguard Worker         }
607*288bf522SAndroid Build Coastguard Worker         impl mock_atrace::ATraceMocker for CallCheck {
608*288bf522SAndroid Build Coastguard Worker             fn atrace_is_tag_enabled(&mut self, _tag: AtraceTag) -> bool {
609*288bf522SAndroid Build Coastguard Worker                 true
610*288bf522SAndroid Build Coastguard Worker             }
611*288bf522SAndroid Build Coastguard Worker             fn atrace_begin(&mut self, _tag: AtraceTag, name: &str) {
612*288bf522SAndroid Build Coastguard Worker                 self.begin_count += 1;
613*288bf522SAndroid Build Coastguard Worker                 assert!(self.begin_count < 2);
614*288bf522SAndroid Build Coastguard Worker                 assert_eq!(name, "test span");
615*288bf522SAndroid Build Coastguard Worker             }
616*288bf522SAndroid Build Coastguard Worker             fn atrace_instant(&mut self, _tag: AtraceTag, name: &str) {
617*288bf522SAndroid Build Coastguard Worker                 self.instant_count += 1;
618*288bf522SAndroid Build Coastguard Worker                 assert!(self.instant_count < 2);
619*288bf522SAndroid Build Coastguard Worker                 assert_eq!(name, "test info");
620*288bf522SAndroid Build Coastguard Worker             }
621*288bf522SAndroid Build Coastguard Worker             fn atrace_end(&mut self, _tag: AtraceTag) {}
622*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {
623*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.begin_count, 1);
624*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.instant_count, 1);
625*288bf522SAndroid Build Coastguard Worker             }
626*288bf522SAndroid Build Coastguard Worker         }
627*288bf522SAndroid Build Coastguard Worker         let _mock_guard = mock_atrace::set_scoped_mocker(CallCheck::default());
628*288bf522SAndroid Build Coastguard Worker 
629*288bf522SAndroid Build Coastguard Worker         let _subscriber_guard = tracing::subscriber::set_default(
630*288bf522SAndroid Build Coastguard Worker             tracing_subscriber::registry().with(AtraceSubscriber::default().without_fields()),
631*288bf522SAndroid Build Coastguard Worker         );
632*288bf522SAndroid Build Coastguard Worker 
633*288bf522SAndroid Build Coastguard Worker         let _span = tracing::info_span!("test span", bar = "foo").entered();
634*288bf522SAndroid Build Coastguard Worker         tracing::event!(Level::INFO, foo = "bar", "test info");
635*288bf522SAndroid Build Coastguard Worker 
636*288bf522SAndroid Build Coastguard Worker         mock_atrace::mocker_finish();
637*288bf522SAndroid Build Coastguard Worker     }
638*288bf522SAndroid Build Coastguard Worker 
639*288bf522SAndroid Build Coastguard Worker     #[test]
formats_instant_event_fields()640*288bf522SAndroid Build Coastguard Worker     fn formats_instant_event_fields() {
641*288bf522SAndroid Build Coastguard Worker         #[derive(Default)]
642*288bf522SAndroid Build Coastguard Worker         struct CallCheck {
643*288bf522SAndroid Build Coastguard Worker             instant_count: u32,
644*288bf522SAndroid Build Coastguard Worker         }
645*288bf522SAndroid Build Coastguard Worker         impl mock_atrace::ATraceMocker for CallCheck {
646*288bf522SAndroid Build Coastguard Worker             fn atrace_is_tag_enabled(&mut self, _tag: AtraceTag) -> bool {
647*288bf522SAndroid Build Coastguard Worker                 true
648*288bf522SAndroid Build Coastguard Worker             }
649*288bf522SAndroid Build Coastguard Worker             fn atrace_instant(&mut self, _tag: AtraceTag, name: &str) {
650*288bf522SAndroid Build Coastguard Worker                 self.instant_count += 1;
651*288bf522SAndroid Build Coastguard Worker                 assert!(self.instant_count < 2);
652*288bf522SAndroid Build Coastguard Worker                 assert_eq!(name, "test info, foo = \"bar\", baz = 5");
653*288bf522SAndroid Build Coastguard Worker             }
654*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {
655*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.instant_count, 1);
656*288bf522SAndroid Build Coastguard Worker             }
657*288bf522SAndroid Build Coastguard Worker         }
658*288bf522SAndroid Build Coastguard Worker         let _mock_guard = mock_atrace::set_scoped_mocker(CallCheck::default());
659*288bf522SAndroid Build Coastguard Worker 
660*288bf522SAndroid Build Coastguard Worker         let _subscriber_guard = tracing::subscriber::set_default(
661*288bf522SAndroid Build Coastguard Worker             tracing_subscriber::registry().with(AtraceSubscriber::default()),
662*288bf522SAndroid Build Coastguard Worker         );
663*288bf522SAndroid Build Coastguard Worker 
664*288bf522SAndroid Build Coastguard Worker         tracing::event!(Level::INFO, foo = "bar", baz = 5, "test info");
665*288bf522SAndroid Build Coastguard Worker 
666*288bf522SAndroid Build Coastguard Worker         mock_atrace::mocker_finish();
667*288bf522SAndroid Build Coastguard Worker     }
668*288bf522SAndroid Build Coastguard Worker 
669*288bf522SAndroid Build Coastguard Worker     #[test]
formats_span_fields()670*288bf522SAndroid Build Coastguard Worker     fn formats_span_fields() {
671*288bf522SAndroid Build Coastguard Worker         #[derive(Default)]
672*288bf522SAndroid Build Coastguard Worker         struct CallCheck {
673*288bf522SAndroid Build Coastguard Worker             begin_count: u32,
674*288bf522SAndroid Build Coastguard Worker         }
675*288bf522SAndroid Build Coastguard Worker         impl mock_atrace::ATraceMocker for CallCheck {
676*288bf522SAndroid Build Coastguard Worker             fn atrace_is_tag_enabled(&mut self, _tag: AtraceTag) -> bool {
677*288bf522SAndroid Build Coastguard Worker                 true
678*288bf522SAndroid Build Coastguard Worker             }
679*288bf522SAndroid Build Coastguard Worker             fn atrace_begin(&mut self, _tag: AtraceTag, name: &str) {
680*288bf522SAndroid Build Coastguard Worker                 self.begin_count += 1;
681*288bf522SAndroid Build Coastguard Worker                 assert!(self.begin_count < 2);
682*288bf522SAndroid Build Coastguard Worker                 assert_eq!(name, "test span, foo = \"bar\", baz = 5");
683*288bf522SAndroid Build Coastguard Worker             }
684*288bf522SAndroid Build Coastguard Worker             fn atrace_end(&mut self, _tag: AtraceTag) {}
685*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {
686*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.begin_count, 1);
687*288bf522SAndroid Build Coastguard Worker             }
688*288bf522SAndroid Build Coastguard Worker         }
689*288bf522SAndroid Build Coastguard Worker         let _mock_guard = mock_atrace::set_scoped_mocker(CallCheck::default());
690*288bf522SAndroid Build Coastguard Worker 
691*288bf522SAndroid Build Coastguard Worker         let _subscriber_guard = tracing::subscriber::set_default(
692*288bf522SAndroid Build Coastguard Worker             tracing_subscriber::registry().with(AtraceSubscriber::default()),
693*288bf522SAndroid Build Coastguard Worker         );
694*288bf522SAndroid Build Coastguard Worker 
695*288bf522SAndroid Build Coastguard Worker         let _span = tracing::info_span!("test span", foo = "bar", baz = 5).entered();
696*288bf522SAndroid Build Coastguard Worker 
697*288bf522SAndroid Build Coastguard Worker         mock_atrace::mocker_finish();
698*288bf522SAndroid Build Coastguard Worker     }
699*288bf522SAndroid Build Coastguard Worker }
700