@@ -222,3 +222,143 @@ pub fn spawn_heartbeat(
222222 }
223223 } )
224224}
225+
226+ #[ cfg( test) ]
227+ mod tests {
228+ use super :: * ;
229+
230+ #[ test]
231+ fn metrics_snapshot_default ( ) {
232+ let snapshot = MetricsSnapshot :: default ( ) ;
233+ assert_eq ! ( snapshot. timestamp_ms, 0 ) ;
234+ assert_eq ! ( snapshot. cpu_usage_pct, 0.0 ) ;
235+ assert_eq ! ( snapshot. memory_total_bytes, 0 ) ;
236+ assert_eq ! ( snapshot. memory_used_bytes, 0 ) ;
237+ assert_eq ! ( snapshot. memory_used_pct, 0.0 ) ;
238+ assert_eq ! ( snapshot. disk_total_bytes, 0 ) ;
239+ assert_eq ! ( snapshot. disk_used_bytes, 0 ) ;
240+ assert_eq ! ( snapshot. disk_used_pct, 0.0 ) ;
241+ }
242+
243+ #[ test]
244+ fn metrics_snapshot_serialization ( ) {
245+ let snapshot = MetricsSnapshot {
246+ timestamp_ms : 1700000000000 ,
247+ cpu_usage_pct : 45.5 ,
248+ memory_total_bytes : 16_000_000_000 ,
249+ memory_used_bytes : 8_000_000_000 ,
250+ memory_used_pct : 50.0 ,
251+ disk_total_bytes : 500_000_000_000 ,
252+ disk_used_bytes : 250_000_000_000 ,
253+ disk_used_pct : 50.0 ,
254+ } ;
255+ let json = serde_json:: to_string ( & snapshot) . unwrap ( ) ;
256+ assert ! ( json. contains( "\" cpu_usage_pct\" :45.5" ) ) ;
257+ assert ! ( json. contains( "\" memory_total_bytes\" :16000000000" ) ) ;
258+ }
259+
260+ #[ test]
261+ fn control_plane_display ( ) {
262+ assert_eq ! ( ControlPlane :: StatusPanel . to_string( ) , "status_panel" ) ;
263+ assert_eq ! ( ControlPlane :: ComposeAgent . to_string( ) , "compose_agent" ) ;
264+ }
265+
266+ #[ test]
267+ fn control_plane_serialization ( ) {
268+ let json = serde_json:: to_string ( & ControlPlane :: StatusPanel ) . unwrap ( ) ;
269+ assert_eq ! ( json, "\" status_panel\" " ) ;
270+ let json = serde_json:: to_string ( & ControlPlane :: ComposeAgent ) . unwrap ( ) ;
271+ assert_eq ! ( json, "\" compose_agent\" " ) ;
272+ }
273+
274+ #[ test]
275+ fn control_plane_equality ( ) {
276+ assert_eq ! ( ControlPlane :: StatusPanel , ControlPlane :: StatusPanel ) ;
277+ assert_ne ! ( ControlPlane :: StatusPanel , ControlPlane :: ComposeAgent ) ;
278+ }
279+
280+ #[ test]
281+ fn command_execution_metrics_default ( ) {
282+ let metrics = CommandExecutionMetrics :: default ( ) ;
283+ assert_eq ! ( metrics. status_panel_count, 0 ) ;
284+ assert_eq ! ( metrics. compose_agent_count, 0 ) ;
285+ assert_eq ! ( metrics. total_count, 0 ) ;
286+ assert ! ( metrics. last_control_plane. is_none( ) ) ;
287+ assert_eq ! ( metrics. last_command_timestamp_ms, 0 ) ;
288+ }
289+
290+ #[ test]
291+ fn record_status_panel_execution ( ) {
292+ let mut metrics = CommandExecutionMetrics :: default ( ) ;
293+ metrics. record_execution ( ControlPlane :: StatusPanel ) ;
294+
295+ assert_eq ! ( metrics. status_panel_count, 1 ) ;
296+ assert_eq ! ( metrics. compose_agent_count, 0 ) ;
297+ assert_eq ! ( metrics. total_count, 1 ) ;
298+ assert_eq ! ( metrics. last_control_plane, Some ( "status_panel" . to_string( ) ) ) ;
299+ assert ! ( metrics. last_command_timestamp_ms > 0 ) ;
300+ }
301+
302+ #[ test]
303+ fn record_compose_agent_execution ( ) {
304+ let mut metrics = CommandExecutionMetrics :: default ( ) ;
305+ metrics. record_execution ( ControlPlane :: ComposeAgent ) ;
306+
307+ assert_eq ! ( metrics. status_panel_count, 0 ) ;
308+ assert_eq ! ( metrics. compose_agent_count, 1 ) ;
309+ assert_eq ! ( metrics. total_count, 1 ) ;
310+ assert_eq ! (
311+ metrics. last_control_plane,
312+ Some ( "compose_agent" . to_string( ) )
313+ ) ;
314+ }
315+
316+ #[ test]
317+ fn record_multiple_executions ( ) {
318+ let mut metrics = CommandExecutionMetrics :: default ( ) ;
319+ metrics. record_execution ( ControlPlane :: StatusPanel ) ;
320+ metrics. record_execution ( ControlPlane :: StatusPanel ) ;
321+ metrics. record_execution ( ControlPlane :: ComposeAgent ) ;
322+
323+ assert_eq ! ( metrics. status_panel_count, 2 ) ;
324+ assert_eq ! ( metrics. compose_agent_count, 1 ) ;
325+ assert_eq ! ( metrics. total_count, 3 ) ;
326+ assert_eq ! (
327+ metrics. last_control_plane,
328+ Some ( "compose_agent" . to_string( ) )
329+ ) ;
330+ }
331+
332+ #[ tokio:: test]
333+ async fn metrics_collector_snapshot_returns_valid_data ( ) {
334+ let collector = MetricsCollector :: new ( ) ;
335+ let snapshot = collector. snapshot ( ) . await ;
336+
337+ assert ! ( snapshot. timestamp_ms > 0 ) ;
338+ // On any machine, total memory should be > 0
339+ assert ! ( snapshot. memory_total_bytes > 0 ) ;
340+ // Used memory should not exceed total
341+ assert ! ( snapshot. memory_used_bytes <= snapshot. memory_total_bytes) ;
342+ // Percentages should be 0-100 range
343+ assert ! ( snapshot. memory_used_pct >= 0.0 && snapshot. memory_used_pct <= 100.0 ) ;
344+ assert ! ( snapshot. disk_used_pct >= 0.0 && snapshot. disk_used_pct <= 100.0 ) ;
345+ }
346+
347+ #[ test]
348+ fn command_execution_metrics_serialization ( ) {
349+ let mut metrics = CommandExecutionMetrics :: default ( ) ;
350+ metrics. record_execution ( ControlPlane :: StatusPanel ) ;
351+
352+ let json = serde_json:: to_string ( & metrics) . unwrap ( ) ;
353+ assert ! ( json. contains( "\" status_panel_count\" :1" ) ) ;
354+ assert ! ( json. contains( "\" compose_agent_count\" :0" ) ) ;
355+ assert ! ( json. contains( "\" total_count\" :1" ) ) ;
356+ }
357+
358+ #[ test]
359+ fn metrics_collector_default ( ) {
360+ // Verify Default trait works
361+ let collector = MetricsCollector :: default ( ) ;
362+ let _ = format ! ( "{:?}" , collector) ;
363+ }
364+ }
0 commit comments