use libdd_profiling::api;
use libdd_profiling_protobuf::prost_impls;
use lz4_flex::frame::FrameDecoder;
use prost::Message;
use std::fs::File;
use std::io::{copy, Cursor};
use std::time::Duration;
fn php_location<'a>(name: &'a str, filename: &'a str, line: i64) -> api::Location<'a> {
api::Location {
mapping: api::Mapping::default(),
address: 0,
function: api::Function {
name,
system_name: "",
filename,
},
line,
}
}
#[test]
#[cfg_attr(miri, ignore)]
fn wordpress() {
let compressed_size = 101824_u64;
let uncompressed_size = 200692_u64;
let path = concat!(env!("CARGO_MANIFEST_DIR"), "/tests/wordpress.pprof.lz4");
let mut decoder = FrameDecoder::new(File::open(path).unwrap());
let mut bytes = Vec::with_capacity(compressed_size as usize);
let bytes_copied = copy(&mut decoder, &mut bytes).unwrap();
assert_eq!(uncompressed_size, bytes_copied);
let pprof = prost_impls::Profile::decode(&mut Cursor::new(&bytes)).unwrap();
let api = api::Profile::try_from(&pprof).unwrap();
assert_eq!(Duration::from_nanos(67000138417_u64), api.duration);
let expected_sample_types = vec![
api::ValueType {
r#type: "sample",
unit: "count",
},
api::ValueType {
r#type: "wall-time",
unit: "nanoseconds",
},
api::ValueType {
r#type: "cpu-time",
unit: "nanoseconds",
},
];
assert_eq!(expected_sample_types, api.sample_types);
let expected_period = Some((
10000000_i64,
api::ValueType {
r#type: "wall-time",
unit: "nanoseconds",
},
));
assert_eq!(expected_period, api.period);
let sample0 = api::Sample {
locations: vec![
php_location(
"WP_Hook::add_filter",
"/var/www/html/public/wp-includes/class-wp-hook.php",
88,
),
php_location(
"add_filter",
"/var/www/html/public/wp-includes/plugin.php",
113,
),
php_location(
"add_action",
"/var/www/html/public/wp-includes/plugin.php",
404,
),
php_location(
"<?php",
"/var/www/html/public/wp-includes/default-filters.php",
435,
),
php_location("<?php", "/var/www/html/public/wp-settings.php", 136),
php_location("<?php", "/var/www/html/public/wp-config.php", 93),
php_location("<?php", "/var/www/html/public/wp-load.php", 37),
php_location("<?php", "/var/www/html/public/wp-blog-header.php", 13),
php_location("<?php", "/var/www/html/public/index.php", 17),
],
values: &[1, 6925169, 5340670],
labels: vec![],
};
let actual_sample0 = api.samples.first().unwrap();
compare_sample(sample0, actual_sample0);
let sample1 = api::Sample {
locations: vec![
php_location(
"apply_filters",
"/var/www/html/public/wp-includes/plugin.php",
211,
),
php_location(
"get_option",
"/var/www/html/public/wp-includes/option.php",
152,
),
php_location(
"WP_Widget::get_settings",
"/var/www/html/public/wp-includes/class-wp-widget.php",
577,
),
php_location(
"WP_Widget::_register",
"/var/www/html/public/wp-includes/class-wp-widget.php",
240,
),
php_location(
"WP_Widget_Factory::_register_widgets",
"/var/www/html/public/wp-includes/class-wp-widget-factory.php",
102,
),
php_location(
"WP_Hook::apply_filters",
"/var/www/html/public/wp-includes/class-wp-hook.php",
287,
),
php_location(
"WP_Hook::do_action",
"/var/www/html/public/wp-includes/class-wp-hook.php",
311,
),
php_location(
"do_action",
"/var/www/html/public/wp-includes/plugin.php",
478,
),
php_location(
"wp_widgets_init",
"/var/www/html/public/wp-includes/widgets.php",
1765,
),
php_location(
"WP_Hook::apply_filters",
"/var/www/html/public/wp-includes/class-wp-hook.php",
287,
),
php_location(
"WP_Hook::do_action",
"/var/www/html/public/wp-includes/class-wp-hook.php",
311,
),
php_location(
"do_action",
"/var/www/html/public/wp-includes/plugin.php",
478,
),
php_location("<?php", "/var/www/html/public/wp-settings.php", 540),
php_location("<?php", "/var/www/html/public/wp-config.php", 93),
php_location("<?php", "/var/www/html/public/wp-load.php", 37),
php_location("<?php", "/var/www/html/public/wp-blog-header.php", 13),
php_location("<?php", "/var/www/html/public/index.php", 17),
],
values: &[1, 10097441, 8518865],
labels: vec![],
};
let actual_sample1 = api.samples.get(1).unwrap();
compare_sample(sample1, actual_sample1);
}
fn compare_sample(a: api::Sample, b: &api::Sample) {
assert_eq!(a.labels, b.labels);
assert_eq!(a.values, b.values);
assert_eq!(a.locations.len(), b.locations.len());
for (offset, (a, b)) in a.locations.iter().zip(b.locations.iter()).enumerate() {
assert_eq!(
a, b,
"Sample location offsets {offset} differ:\n{a:#?}\n{b:#?}"
);
}
}