Skip to main content

muxtop_proto/
lib.rs

1pub mod error;
2pub mod frame;
3pub mod remote;
4pub mod tls;
5pub mod wire;
6
7pub use error::ProtoError;
8pub use frame::{
9    Frame, FrameReader, FrameWriter, MAX_FRAME_SIZE, MSG_ERROR, MSG_HEARTBEAT, MSG_HELLO,
10    MSG_SNAPSHOT, MSG_WELCOME, decode_frame, encode_frame,
11};
12pub use remote::{ConnectionEvent, RemoteCollector};
13pub use tls::{RemoteTargetError, parse_remote_target};
14pub use wire::WireMessage;
15
16#[cfg(test)]
17mod tests {
18    use bincode::{config, decode_from_slice, encode_to_vec};
19    use muxtop_core::network::{NetworkInterfaceSnapshot, NetworkSnapshot};
20    use muxtop_core::process::ProcessInfo;
21    use muxtop_core::system::{
22        CoreSnapshot, CpuSnapshot, LoadSnapshot, MemorySnapshot, SystemSnapshot,
23    };
24
25    fn bincode_config() -> impl bincode::config::Config {
26        config::standard()
27    }
28
29    fn make_test_process() -> ProcessInfo {
30        ProcessInfo {
31            pid: 42,
32            parent_pid: Some(1),
33            name: "test_proc".into(),
34            command: "/usr/bin/test --flag".into(),
35            user: "root".into(),
36            cpu_percent: 12.5,
37            memory_bytes: 1_048_576,
38            memory_percent: 2.3,
39            status: "Running".into(),
40        }
41    }
42
43    fn make_test_network_iface() -> NetworkInterfaceSnapshot {
44        NetworkInterfaceSnapshot {
45            name: "eth0".into(),
46            bytes_rx: 123_456,
47            bytes_tx: 78_901,
48            packets_rx: 100,
49            packets_tx: 50,
50            errors_rx: 0,
51            errors_tx: 0,
52            mac_address: "00:11:22:33:44:55".into(),
53            is_up: true,
54        }
55    }
56
57    fn make_test_snapshot() -> SystemSnapshot {
58        SystemSnapshot {
59            cpu: CpuSnapshot {
60                global_usage: 45.2,
61                cores: vec![
62                    CoreSnapshot {
63                        name: "cpu0".into(),
64                        usage: 50.0,
65                        frequency: 3600,
66                    },
67                    CoreSnapshot {
68                        name: "cpu1".into(),
69                        usage: 40.4,
70                        frequency: 3600,
71                    },
72                ],
73            },
74            memory: MemorySnapshot {
75                total: 16_000_000_000,
76                used: 8_000_000_000,
77                available: 8_000_000_000,
78                swap_total: 4_000_000_000,
79                swap_used: 1_000_000_000,
80            },
81            load: LoadSnapshot {
82                one: 1.5,
83                five: 1.2,
84                fifteen: 0.8,
85                uptime_secs: 3600,
86            },
87            processes: vec![make_test_process()],
88            networks: NetworkSnapshot {
89                interfaces: vec![make_test_network_iface()],
90                total_rx: 123_456,
91                total_tx: 78_901,
92            },
93            containers: None,
94            timestamp_ms: 1_713_200_000_000,
95        }
96    }
97
98    #[test]
99    fn test_process_info_roundtrip() {
100        let original = make_test_process();
101        let bytes = encode_to_vec(&original, bincode_config()).unwrap();
102        let (decoded, _): (ProcessInfo, _) = decode_from_slice(&bytes, bincode_config()).unwrap();
103        assert_eq!(original, decoded);
104    }
105
106    #[test]
107    fn test_network_interface_roundtrip() {
108        let original = make_test_network_iface();
109        let bytes = encode_to_vec(&original, bincode_config()).unwrap();
110        let (decoded, _): (NetworkInterfaceSnapshot, _) =
111            decode_from_slice(&bytes, bincode_config()).unwrap();
112        assert_eq!(original, decoded);
113    }
114
115    #[test]
116    fn test_network_snapshot_roundtrip() {
117        let original = NetworkSnapshot {
118            interfaces: vec![make_test_network_iface()],
119            total_rx: 123_456,
120            total_tx: 78_901,
121        };
122        let bytes = encode_to_vec(&original, bincode_config()).unwrap();
123        let (decoded, _): (NetworkSnapshot, _) =
124            decode_from_slice(&bytes, bincode_config()).unwrap();
125        assert_eq!(original, decoded);
126    }
127
128    #[test]
129    fn test_system_snapshot_roundtrip() {
130        let original = make_test_snapshot();
131        let bytes = encode_to_vec(&original, bincode_config()).unwrap();
132        let (decoded, _): (SystemSnapshot, _) =
133            decode_from_slice(&bytes, bincode_config()).unwrap();
134        assert_eq!(original, decoded);
135    }
136
137    #[test]
138    fn test_cpu_snapshot_roundtrip() {
139        let original = CpuSnapshot {
140            global_usage: 75.3,
141            cores: vec![CoreSnapshot {
142                name: "cpu0".into(),
143                usage: 75.3,
144                frequency: 2400,
145            }],
146        };
147        let bytes = encode_to_vec(&original, bincode_config()).unwrap();
148        let (decoded, _): (CpuSnapshot, _) = decode_from_slice(&bytes, bincode_config()).unwrap();
149        assert_eq!(original, decoded);
150    }
151
152    #[test]
153    fn test_memory_snapshot_roundtrip() {
154        let original = MemorySnapshot {
155            total: 32_000_000_000,
156            used: 16_000_000_000,
157            available: 16_000_000_000,
158            swap_total: 8_000_000_000,
159            swap_used: 2_000_000_000,
160        };
161        let bytes = encode_to_vec(&original, bincode_config()).unwrap();
162        let (decoded, _): (MemorySnapshot, _) =
163            decode_from_slice(&bytes, bincode_config()).unwrap();
164        assert_eq!(original, decoded);
165    }
166
167    #[test]
168    fn test_load_snapshot_roundtrip() {
169        let original = LoadSnapshot {
170            one: 2.5,
171            five: 1.8,
172            fifteen: 1.2,
173            uptime_secs: 86400,
174        };
175        let bytes = encode_to_vec(&original, bincode_config()).unwrap();
176        let (decoded, _): (LoadSnapshot, _) = decode_from_slice(&bytes, bincode_config()).unwrap();
177        assert_eq!(original, decoded);
178    }
179
180    #[test]
181    fn test_timestamp_is_unix_ms() {
182        let snap = make_test_snapshot();
183        assert!(snap.timestamp_ms > 0, "timestamp should be positive");
184        assert!(
185            snap.timestamp_ms > 1_700_000_000_000,
186            "timestamp should be in milliseconds since epoch"
187        );
188    }
189}