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}