@@ -392,4 +392,119 @@ mod tests {
392392 | Environment :: BareMetal
393393 ) ) ;
394394 }
395+
396+ // --- RuntimeContext tests ---
397+
398+ #[ test]
399+ fn test_runtime_context_detect_does_not_panic ( ) {
400+ let ctx = RuntimeContext :: detect ( ) ;
401+ // Environment is always set
402+ assert ! ( matches!(
403+ ctx. environment,
404+ Environment :: Kubernetes
405+ | Environment :: Docker
406+ | Environment :: Container
407+ | Environment :: BareMetal
408+ ) ) ;
409+ }
410+
411+ #[ test]
412+ fn test_runtime_context_bare_metal_has_no_k8s_fields ( ) {
413+ // On a dev machine (bare metal), K8s fields should be None
414+ // unless POD_NAME etc. env vars happen to be set
415+ let ctx = RuntimeContext :: detect ( ) ;
416+ if ctx. environment . is_bare_metal ( ) {
417+ assert ! (
418+ ctx. node_name. is_none( ) ,
419+ "node_name should be None on bare metal"
420+ ) ;
421+ // pod_name might come from HOSTNAME, so we don't assert it's None
422+ }
423+ }
424+
425+ #[ test]
426+ fn test_runtime_context_reads_pod_name_env ( ) {
427+ temp_env:: with_vars (
428+ [
429+ ( "POD_NAME" , Some ( "test-pod-123" ) ) ,
430+ ( "KUBERNETES_SERVICE_HOST" , Some ( "10.0.0.1" ) ) ,
431+ ] ,
432+ || {
433+ let ctx = RuntimeContext :: detect ( ) ;
434+ assert_eq ! ( ctx. pod_name. as_deref( ) , Some ( "test-pod-123" ) ) ;
435+ } ,
436+ ) ;
437+ }
438+
439+ #[ test]
440+ fn test_runtime_context_reads_namespace_env ( ) {
441+ temp_env:: with_var ( "POD_NAMESPACE" , Some ( "production" ) , || {
442+ let ctx = RuntimeContext :: detect ( ) ;
443+ assert_eq ! ( ctx. namespace. as_deref( ) , Some ( "production" ) ) ;
444+ } ) ;
445+ }
446+
447+ #[ test]
448+ fn test_runtime_context_reads_node_name_env ( ) {
449+ temp_env:: with_var ( "NODE_NAME" , Some ( "node-1" ) , || {
450+ let ctx = RuntimeContext :: detect ( ) ;
451+ assert_eq ! ( ctx. node_name. as_deref( ) , Some ( "node-1" ) ) ;
452+ } ) ;
453+ }
454+
455+ #[ test]
456+ fn test_runtime_context_global_singleton ( ) {
457+ // runtime_context() should return the same instance every time
458+ let ctx1 = runtime_context ( ) ;
459+ let ctx2 = runtime_context ( ) ;
460+ assert_eq ! ( ctx1. environment, ctx2. environment) ;
461+ assert_eq ! ( ctx1. pod_name, ctx2. pod_name) ;
462+ }
463+
464+ #[ test]
465+ fn test_runtime_context_is_kubernetes_convenience ( ) {
466+ let mut ctx = RuntimeContext :: detect ( ) ;
467+ ctx. environment = Environment :: Kubernetes ;
468+ assert ! ( ctx. is_kubernetes( ) ) ;
469+ assert ! ( ctx. is_container( ) ) ;
470+ assert ! ( !ctx. is_bare_metal( ) ) ;
471+ }
472+
473+ #[ test]
474+ fn test_runtime_context_is_bare_metal_convenience ( ) {
475+ let mut ctx = RuntimeContext :: detect ( ) ;
476+ ctx. environment = Environment :: BareMetal ;
477+ assert ! ( !ctx. is_kubernetes( ) ) ;
478+ assert ! ( !ctx. is_container( ) ) ;
479+ assert ! ( ctx. is_bare_metal( ) ) ;
480+ }
481+
482+ // --- cgroup helper tests ---
483+
484+ #[ test]
485+ fn test_read_cgroup_memory_limit_returns_option ( ) {
486+ // On bare metal, returns None (no cgroup). On container, returns Some.
487+ let limit = read_cgroup_memory_limit ( ) ;
488+ // Just verify it doesn't panic — result depends on environment
489+ let _ = limit;
490+ }
491+
492+ #[ test]
493+ fn test_read_cgroup_cpu_quota_returns_option ( ) {
494+ let quota = read_cgroup_cpu_quota ( ) ;
495+ let _ = quota;
496+ }
497+
498+ #[ test]
499+ fn test_prestop_delay_default_bare_metal ( ) {
500+ // On bare metal, default pre-stop delay should be 0
501+ temp_env:: with_var ( "PRESTOP_DELAY_SECS" , None :: < & str > , || {
502+ let ctx = RuntimeContext :: detect ( ) ;
503+ if ctx. environment . is_bare_metal ( ) {
504+ // The prestop_delay_secs function is in shutdown.rs,
505+ // but we can verify the RuntimeContext is bare metal
506+ assert ! ( !ctx. is_kubernetes( ) ) ;
507+ }
508+ } ) ;
509+ }
395510}
0 commit comments