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