build_helper/
metrics.rs

1use serde_derive::{Deserialize, Serialize};
2
3#[derive(Serialize, Deserialize)]
4#[serde(rename_all = "snake_case")]
5pub struct JsonRoot {
6    #[serde(default)] // For version 0 the field was not present.
7    pub format_version: usize,
8    pub system_stats: JsonInvocationSystemStats,
9    pub invocations: Vec<JsonInvocation>,
10}
11
12#[derive(Serialize, Deserialize)]
13#[serde(rename_all = "snake_case")]
14pub struct JsonInvocation {
15    // Unix timestamp in seconds
16    //
17    // This is necessary to easily correlate this invocation with logs or other data.
18    pub start_time: u64,
19    #[serde(deserialize_with = "null_as_f64_nan")]
20    pub duration_including_children_sec: f64,
21    pub children: Vec<JsonNode>,
22}
23
24#[derive(Serialize, Deserialize)]
25#[serde(tag = "kind", rename_all = "snake_case")]
26pub enum JsonNode {
27    RustbuildStep {
28        #[serde(rename = "type")]
29        type_: String,
30        debug_repr: String,
31
32        #[serde(deserialize_with = "null_as_f64_nan")]
33        duration_excluding_children_sec: f64,
34        system_stats: JsonStepSystemStats,
35
36        children: Vec<JsonNode>,
37    },
38    TestSuite(TestSuite),
39}
40
41#[derive(Serialize, Deserialize)]
42pub struct TestSuite {
43    pub metadata: TestSuiteMetadata,
44    pub tests: Vec<Test>,
45}
46
47#[derive(Serialize, Deserialize)]
48#[serde(tag = "kind", rename_all = "snake_case")]
49pub enum TestSuiteMetadata {
50    CargoPackage {
51        crates: Vec<String>,
52        target: String,
53        host: String,
54        stage: u32,
55    },
56    Compiletest {
57        suite: String,
58        mode: String,
59        compare_mode: Option<String>,
60        target: String,
61        host: String,
62        stage: u32,
63    },
64}
65
66#[derive(Serialize, Deserialize)]
67pub struct Test {
68    pub name: String,
69    #[serde(flatten)]
70    pub outcome: TestOutcome,
71}
72
73#[derive(Serialize, Deserialize)]
74#[serde(tag = "outcome", rename_all = "snake_case")]
75pub enum TestOutcome {
76    Passed,
77    Failed,
78    Ignored { ignore_reason: Option<String> },
79}
80
81#[derive(Serialize, Deserialize)]
82#[serde(rename_all = "snake_case")]
83pub struct JsonInvocationSystemStats {
84    pub cpu_threads_count: usize,
85    pub cpu_model: String,
86
87    pub memory_total_bytes: u64,
88}
89
90#[derive(Serialize, Deserialize)]
91#[serde(rename_all = "snake_case")]
92pub struct JsonStepSystemStats {
93    #[serde(deserialize_with = "null_as_f64_nan")]
94    pub cpu_utilization_percent: f64,
95}
96
97fn null_as_f64_nan<'de, D: serde::Deserializer<'de>>(d: D) -> Result<f64, D::Error> {
98    use serde::Deserialize as _;
99    Option::<f64>::deserialize(d).map(|f| f.unwrap_or(f64::NAN))
100}