oxedyne/fe2o3/fe2o3_sys/tests/parse.rs
5.4 KiB, 2 runs
created by r1870400018:10598, which is this file's identity for as long as the history lasts, whatever it is later renamed to
download · who wrote it · its history
| 1 | //! Integration tests for the `/proc` parsers. Each test uses a |
| 2 | //! fixed sample body copied from a real machine so the parsers |
| 3 | //! are exercised deterministically, regardless of the host the |
| 4 | //! test happens to run on. |
| 5 | |
| 6 | use oxedyne_fe2o3_core::prelude::*; |
| 7 | use oxedyne_fe2o3_sys::{ |
| 8 | cpu::CpuTimes, |
| 9 | disk::DiskStats, |
| 10 | load::LoadAvg, |
| 11 | mem::MemInfo, |
| 12 | net::NetStats, |
| 13 | proc_self::ProcSelf, |
| 14 | uptime::Uptime, |
| 15 | }; |
| 16 | |
| 17 | #[test] |
| 18 | fn cpu_aggregate_line() -> Outcome<()> { |
| 19 | let sample = |
| 20 | "cpu 100 20 40 500 10 0 5 0 0 0\n\ |
| 21 | cpu0 50 10 20 250 5 0 2 0 0 0\n\ |
| 22 | cpu1 50 10 20 250 5 0 3 0 0 0\n\ |
| 23 | intr 123\n"; |
| 24 | let c = res!(CpuTimes::from_stat(sample)); |
| 25 | assert_eq!(c.user, 100); |
| 26 | assert_eq!(c.nice, 20); |
| 27 | assert_eq!(c.system, 40); |
| 28 | assert_eq!(c.idle, 500); |
| 29 | assert_eq!(c.iowait, 10); |
| 30 | assert_eq!(c.irq, 0); |
| 31 | assert_eq!(c.softirq, 5); |
| 32 | assert_eq!(c.total(), 675); |
| 33 | assert_eq!(c.idle_total(), 510); |
| 34 | Ok(()) |
| 35 | } |
| 36 | |
| 37 | #[test] |
| 38 | fn cpu_busy_fraction() -> Outcome<()> { |
| 39 | let prev = res!(CpuTimes::from_line("cpu 100 0 50 850 0 0 0 0 0 0")); |
| 40 | let now = res!(CpuTimes::from_line("cpu 150 0 100 900 0 0 0 0 0 0")); |
| 41 | // total prev = 1000, now = 1150 → delta 150 |
| 42 | // idle prev = 850, now = 900 → delta 50 |
| 43 | // busy / total = 100 / 150 ≈ 0.6667 |
| 44 | let frac = now.busy_fraction(&prev); |
| 45 | assert!((frac - (100.0 / 150.0)).abs() < 1e-9); |
| 46 | Ok(()) |
| 47 | } |
| 48 | |
| 49 | #[test] |
| 50 | fn meminfo_parses_total_and_available() -> Outcome<()> { |
| 51 | let sample = |
| 52 | "MemTotal: 8000000 kB\n\ |
| 53 | MemFree: 500000 kB\n\ |
| 54 | MemAvailable: 2000000 kB\n\ |
| 55 | Buffers: 100000 kB\n\ |
| 56 | Cached: 1500000 kB\n\ |
| 57 | SwapTotal: 1000000 kB\n\ |
| 58 | SwapFree: 900000 kB\n"; |
| 59 | let m = res!(MemInfo::from_meminfo(sample)); |
| 60 | assert_eq!(m.total, 8_000_000 * 1024); |
| 61 | assert_eq!(m.available, 2_000_000 * 1024); |
| 62 | assert_eq!(m.swap_total,1_000_000 * 1024); |
| 63 | assert_eq!(m.swap_free, 900_000 * 1024); |
| 64 | assert_eq!(m.swap_used(), 100_000 * 1024); |
| 65 | // used = total - available = 6M kB. |
| 66 | assert_eq!(m.used(), 6_000_000 * 1024); |
| 67 | Ok(()) |
| 68 | } |
| 69 | |
| 70 | #[test] |
| 71 | fn loadavg_parses() -> Outcome<()> { |
| 72 | let l = res!(LoadAvg::from_line("0.42 0.51 0.63 3/612 12345")); |
| 73 | assert!((l.one - 0.42).abs() < 1e-9); |
| 74 | assert!((l.five - 0.51).abs() < 1e-9); |
| 75 | assert!((l.fifteen - 0.63).abs() < 1e-9); |
| 76 | assert_eq!(l.runnable, 3); |
| 77 | assert_eq!(l.total, 612); |
| 78 | Ok(()) |
| 79 | } |
| 80 | |
| 81 | #[test] |
| 82 | fn uptime_parses() -> Outcome<()> { |
| 83 | let u = res!(Uptime::from_line("12345.67 98765.43")); |
| 84 | assert!((u.seconds - 12345.67).abs() < 1e-3); |
| 85 | assert!((u.idle_total - 98765.43).abs() < 1e-3); |
| 86 | Ok(()) |
| 87 | } |
| 88 | |
| 89 | #[test] |
| 90 | fn diskstats_parses_minimum_column_count() -> Outcome<()> { |
| 91 | // 14-column diskstats line (kernel 4.18+). |
| 92 | let sample = |
| 93 | " 8 0 sda 100 0 2000 50 200 0 4000 80 0 120 130\n\ |
| 94 | 254 0 dm-0 10 0 200 5 20 0 400 8 0 12 13\n"; |
| 95 | let d = res!(DiskStats::from_diskstats(sample)); |
| 96 | assert_eq!(d.devices.len(), 2); |
| 97 | assert_eq!(d.devices[0].name, "sda"); |
| 98 | assert_eq!(d.devices[0].reads, 100); |
| 99 | assert_eq!(d.devices[0].read_sectors, 2000); |
| 100 | assert_eq!(d.devices[0].writes, 200); |
| 101 | assert_eq!(d.devices[0].write_sectors, 4000); |
| 102 | assert_eq!(d.devices[1].name, "dm-0"); |
| 103 | Ok(()) |
| 104 | } |
| 105 | |
| 106 | #[test] |
| 107 | fn net_dev_parses() -> Outcome<()> { |
| 108 | let sample = |
| 109 | "Inter-| Receive | Transmit\n\ |
| 110 | face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed\n\ |
| 111 | lo: 1000 10 0 0 0 0 0 0 1000 10 0 0 0 0 0 0\n\ |
| 112 | eth0: 5000 50 1 2 0 0 0 0 6000 60 0 0 0 0 0 0\n"; |
| 113 | let n = res!(NetStats::from_net_dev(sample)); |
| 114 | assert_eq!(n.interfaces.len(), 2); |
| 115 | assert_eq!(n.interfaces[0].name, "lo"); |
| 116 | assert_eq!(n.interfaces[0].rx_bytes, 1000); |
| 117 | assert_eq!(n.interfaces[0].tx_bytes, 1000); |
| 118 | assert_eq!(n.interfaces[1].name, "eth0"); |
| 119 | assert_eq!(n.interfaces[1].rx_errors, 1); |
| 120 | assert_eq!(n.interfaces[1].rx_drops, 2); |
| 121 | assert_eq!(n.interfaces[1].tx_bytes, 6000); |
| 122 | Ok(()) |
| 123 | } |
| 124 | |
| 125 | #[test] |
| 126 | fn proc_self_status_parses() -> Outcome<()> { |
| 127 | let sample = |
| 128 | "Name:\tsteel\n\ |
| 129 | State:\tR (running)\n\ |
| 130 | VmPeak:\t 12345 kB\n\ |
| 131 | VmSize:\t 10000 kB\n\ |
| 132 | VmRSS:\t 4000 kB\n\ |
| 133 | Threads:\t8\n\ |
| 134 | voluntary_ctxt_switches:\t1234\n\ |
| 135 | nonvoluntary_ctxt_switches:\t56\n"; |
| 136 | let p = res!(ProcSelf::from_status(sample)); |
| 137 | assert_eq!(p.rss_bytes, 4_000 * 1024); |
| 138 | assert_eq!(p.vsize_bytes, 10_000 * 1024); |
| 139 | assert_eq!(p.peak_rss, 12_345 * 1024); |
| 140 | assert_eq!(p.threads, 8); |
| 141 | assert_eq!(p.voluntary_ctxt, 1234); |
| 142 | assert_eq!(p.involuntary_ctxt, 56); |
| 143 | Ok(()) |
| 144 | } |
| 145 | |
| 146 | #[test] |
| 147 | fn proc_self_stat_cpu_ticks_parses() -> Outcome<()> { |
| 148 | // A synthetic /proc/self/stat line whose comm field deliberately |
| 149 | // contains spaces and brackets to exercise the "parse after the |
| 150 | // final ')'" logic. utime is field 14 (value 30) and stime is |
| 151 | // field 15 (value 12), so the sum is 42. |
| 152 | let sample = "1234 (odd )name) ) R 1 1234 1234 0 -1 4194560 100 0 0 0 30 12 0 0 20 0 8 0 999"; |
| 153 | let ticks = res!(ProcSelf::cpu_ticks_from_stat(sample)); |
| 154 | assert_eq!(ticks, 42); |
| 155 | Ok(()) |
| 156 | } |