blob: 6b58491ad5925fef25116b8513e05581699419a8 [file] [log] [blame]
// Copyright 2019 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use std::thread::sleep;
use std::time::Duration;
use trace_events::{
counter, disable_all, duration, enable_category, instant, set_tracer,
trivial_tracer::{OwnedLabel, OwnedTraceRecord, TrivialTracer},
Scope,
};
#[instant(category = "display", global)]
fn vblank_happened() {}
#[instant(category = "signals", process)]
fn handle_sigterm() {}
#[instant(category = "gpu", end)]
fn submit_buffer() -> bool {
true
}
#[duration(category = "suite", name = "task_long")]
fn long_running_task(a: u32, b: u32) -> u32 {
sleep(Duration::from_millis(50));
a + b
}
#[counter]
fn process_a_widget() {}
fn test_instant(t: &TrivialTracer) {
enable_category("display".to_owned());
enable_category("signals".to_owned());
enable_category("gpu".to_owned());
vblank_happened();
handle_sigterm();
assert!(submit_buffer());
disable_all();
let mut records = t.take_records();
assert_eq!(records.len(), 3);
match records.remove(0) {
(OwnedLabel { category, name }, OwnedTraceRecord::Instant(_, scope, _)) => {
assert_eq!(category, "display");
assert_eq!(name, "vblank_happened");
assert_eq!(scope, Scope::Global);
}
_ => panic!("expected instant record"),
};
match records.remove(0) {
(OwnedLabel { category, name }, OwnedTraceRecord::Instant(_, scope, _)) => {
assert_eq!(category, "signals");
assert_eq!(name, "handle_sigterm");
assert_eq!(scope, Scope::Process);
}
_ => panic!("expected instant record"),
};
match records.remove(0) {
(OwnedLabel { category, name }, OwnedTraceRecord::Instant(_, scope, _)) => {
assert_eq!(category, "gpu");
assert_eq!(name, "submit_buffer");
assert_eq!(scope, Default::default());
}
_ => panic!("expected instant record"),
};
}
fn test_duration(t: &TrivialTracer) {
enable_category("suite".to_owned());
let x = long_running_task(4, 8);
assert_eq!(x, 12);
disable_all();
let mut records = t.take_records();
assert_eq!(records.len(), 2);
let begin_point;
match records.remove(0) {
(OwnedLabel { category, name }, OwnedTraceRecord::Begin(point, _)) => {
assert_eq!(category, "suite");
assert_eq!(name, "task_long");
begin_point = point;
}
_ => panic!("expected begin record"),
};
match records.remove(0) {
(OwnedLabel { category, name }, OwnedTraceRecord::End(end_point, _)) => {
assert_eq!(category, "suite");
assert_eq!(name, "task_long");
assert!(begin_point.ts < end_point.ts);
assert_eq!(begin_point.pid, end_point.pid);
assert_eq!(begin_point.tid, end_point.tid);
}
_ => panic!("expected end record"),
};
}
fn test_counter(t: &TrivialTracer) {
enable_category("fn_attrs".to_owned());
process_a_widget();
process_a_widget();
disable_all();
let records = t.take_records();
assert_eq!(records.len(), 2);
for (i, record) in records.iter().enumerate() {
match record {
(OwnedLabel { category, name }, OwnedTraceRecord::Counter(_, counters)) => {
assert_eq!(category, module_path!());
assert_eq!(name, "process_a_widget");
assert_eq!(counters, &[("calls".to_owned(), (i + 1) as u64)]);
}
_ => panic!("expected counter record"),
}
}
}
#[test]
fn test_all() {
let t = Box::leak(Box::new(TrivialTracer::default()));
set_tracer(t);
test_instant(t);
test_duration(t);
test_counter(t);
}