Skip to main content

lobe_core/engine/
timing.rs

1use crate::models::TimingReport;
2
3#[derive(Debug, Clone, Copy, Default)]
4pub struct TimingPhases {
5    pub dns_ms: u64,
6    pub tcp_ms: u64,
7    pub tls_ms: u64,
8    pub ttfb_ms: u64,
9    pub download_ms: u64,
10}
11
12pub fn build_report(
13    dns_ms: u64,
14    tcp_ms: u64,
15    tls_ms: u64,
16    ttfb_ms: u64,
17    download_ms: u64,
18) -> TimingReport {
19    let total_ms = calculate_total_ms(dns_ms, tcp_ms, tls_ms, ttfb_ms, download_ms);
20
21    TimingReport {
22        dns_ms,
23        tcp_ms,
24        tls_ms,
25        ttfb_ms,
26        download_ms,
27        total_ms,
28        // Filled in by the capture proxy once the response is written back to
29        // the client (see engine::capture); the probe path leaves it at 0.
30        proxy_overhead_us: 0,
31    }
32}
33
34pub fn build_report_from_phases(phases: TimingPhases) -> TimingReport {
35    build_report(
36        phases.dns_ms,
37        phases.tcp_ms,
38        phases.tls_ms,
39        phases.ttfb_ms,
40        phases.download_ms,
41    )
42}
43
44pub fn calculate_total_ms(
45    dns_ms: u64,
46    tcp_ms: u64,
47    tls_ms: u64,
48    ttfb_ms: u64,
49    download_ms: u64,
50) -> u64 {
51    dns_ms + tcp_ms + tls_ms + ttfb_ms + download_ms
52}
53
54#[cfg(test)]
55mod tests {
56    use super::{build_report, build_report_from_phases, calculate_total_ms, TimingPhases};
57
58    #[test]
59    fn calculate_total_ms_sums_all_phases() {
60        let total_ms = calculate_total_ms(10, 20, 30, 40, 50);
61
62        assert_eq!(total_ms, 150);
63    }
64
65    #[test]
66    fn calculate_total_ms_handles_zero_values() {
67        let total_ms = calculate_total_ms(0, 0, 0, 0, 0);
68
69        assert_eq!(total_ms, 0);
70    }
71
72    #[test]
73    fn build_report_populates_each_field() {
74        let report = build_report(15, 25, 35, 45, 55);
75
76        assert_eq!(report.dns_ms, 15);
77        assert_eq!(report.tcp_ms, 25);
78        assert_eq!(report.tls_ms, 35);
79        assert_eq!(report.ttfb_ms, 45);
80        assert_eq!(report.download_ms, 55);
81        assert_eq!(report.total_ms, 175);
82    }
83
84    #[test]
85    fn build_report_from_phases_uses_phase_values() {
86        let phases = TimingPhases {
87            dns_ms: 5,
88            tcp_ms: 10,
89            tls_ms: 15,
90            ttfb_ms: 20,
91            download_ms: 25,
92        };
93
94        let report = build_report_from_phases(phases);
95
96        assert_eq!(report.dns_ms, 5);
97        assert_eq!(report.tcp_ms, 10);
98        assert_eq!(report.tls_ms, 15);
99        assert_eq!(report.ttfb_ms, 20);
100        assert_eq!(report.download_ms, 25);
101        assert_eq!(report.total_ms, 75);
102    }
103}