mod cli_binary_test_helpers;
use cli_binary_test_helpers::stdout_str;
#[ cfg( unix ) ]
#[ test ]
fn it30_flags_column_absent_when_no_flags()
{
use cli_binary_test_helpers::fake_claude_binary_dir;
let ( _bin_dir, path_val ) = fake_claude_binary_dir();
let temp_home = tempfile::TempDir::new().expect( "tmp home" );
let work_dir = temp_home.path().join( "work" );
std::fs::create_dir_all( &work_dir ).expect( "create work dir" );
let mut bg = std::process::Command::new( "claude" )
.env( "PATH", &path_val )
.arg( "30" )
.current_dir( &work_dir )
.stdout( std::process::Stdio::null() )
.stderr( std::process::Stdio::null() )
.spawn()
.expect( "spawn fake claude" );
std::thread::sleep( core::time::Duration::from_millis( 200 ) );
let bin = env!( "CARGO_BIN_EXE_clr" );
let out = std::process::Command::new( bin )
.args( [ "ps" ] )
.env( "PATH", &path_val )
.env( "HOME", temp_home.path() )
.env( "CLR_PS_ANCIENT_SECS", "999999" )
.env( "CLR_PS_HIGH_RAM_MB", "999999" )
.output()
.expect( "run clr ps" );
let _ = bg.kill();
let _ = bg.wait();
let stdout = stdout_str( &out );
assert!( out.status.success(), "IT-30: exit 0 expected, got {:?}", out.status.code() );
assert!(
!stdout.contains( "Flags" ),
"IT-30: 'Flags' column must NOT appear when no flags fire. Got:\n{stdout}"
);
}
#[ cfg( target_os = "linux" ) ]
#[ test ]
fn it31_container_flag_for_session_outside_home()
{
use cli_binary_test_helpers::fake_claude_binary_dir;
let ( _bin_dir, path_val ) = fake_claude_binary_dir();
let temp_home = tempfile::TempDir::new().expect( "tmp home" );
let outside_home = tempfile::TempDir::new().expect( "tmp outside home" );
let home_str = temp_home.path().to_string_lossy().to_string();
let outside_str = outside_home.path().to_string_lossy().to_string();
assert!(
!outside_str.starts_with( &home_str ),
"IT-31: outside_home must not be inside temp_home for this test to be valid"
);
let mut bg = std::process::Command::new( "claude" )
.env( "PATH", &path_val )
.arg( "30" )
.current_dir( outside_home.path() )
.stdout( std::process::Stdio::null() )
.stderr( std::process::Stdio::null() )
.spawn()
.expect( "spawn fake claude" );
std::thread::sleep( core::time::Duration::from_millis( 200 ) );
let bin = env!( "CARGO_BIN_EXE_clr" );
let out = std::process::Command::new( bin )
.args( [ "ps" ] )
.env( "PATH", &path_val )
.env( "HOME", temp_home.path() )
.env( "CLR_PS_ANCIENT_SECS", "999999" )
.env( "CLR_PS_HIGH_RAM_MB", "999999" )
.output()
.expect( "run clr ps" );
let _ = bg.kill();
let _ = bg.wait();
let stdout = stdout_str( &out );
assert!( out.status.success(), "IT-31: exit 0 expected, got {:?}", out.status.code() );
assert!(
stdout.contains( "🐳" ),
"IT-31: 🐳 flag must appear for session outside HOME. Got:\n{stdout}"
);
assert!(
stdout.contains( "Flags" ),
"IT-31: 'Flags' column header must appear when 🐳 fires. Got:\n{stdout}"
);
}
#[ cfg( target_os = "linux" ) ]
#[ test ]
fn it32_ancient_flag_fires_with_zero_threshold()
{
use cli_binary_test_helpers::fake_claude_binary_dir;
let ( _bin_dir, path_val ) = fake_claude_binary_dir();
let mut bg = std::process::Command::new( "claude" )
.env( "PATH", &path_val )
.arg( "30" )
.stdout( std::process::Stdio::null() )
.stderr( std::process::Stdio::null() )
.spawn()
.expect( "spawn fake claude" );
std::thread::sleep( core::time::Duration::from_millis( 1_100 ) );
let bin = env!( "CARGO_BIN_EXE_clr" );
let out = std::process::Command::new( bin )
.args( [ "ps" ] )
.env( "PATH", &path_val )
.env( "CLR_PS_ANCIENT_SECS", "0" )
.env( "CLR_PS_HIGH_RAM_MB", "999999" )
.output()
.expect( "run clr ps" );
let _ = bg.kill();
let _ = bg.wait();
let stdout = stdout_str( &out );
assert!( out.status.success(), "IT-32: exit 0 expected, got {:?}", out.status.code() );
assert!(
stdout.contains( "🕰" ),
"IT-32: 🕰 flag must appear when elapsed > 0 and CLR_PS_ANCIENT_SECS=0. Got:\n{stdout}"
);
}
#[ cfg( target_os = "linux" ) ]
#[ test ]
fn it33_high_ram_flag_fires_with_zero_threshold()
{
use cli_binary_test_helpers::fake_claude_binary_dir;
let ( _bin_dir, path_val ) = fake_claude_binary_dir();
let mut bg = std::process::Command::new( "claude" )
.env( "PATH", &path_val )
.arg( "30" )
.stdout( std::process::Stdio::null() )
.stderr( std::process::Stdio::null() )
.spawn()
.expect( "spawn fake claude" );
std::thread::sleep( core::time::Duration::from_millis( 200 ) );
let bin = env!( "CARGO_BIN_EXE_clr" );
let out = std::process::Command::new( bin )
.args( [ "ps" ] )
.env( "PATH", &path_val )
.env( "CLR_PS_ANCIENT_SECS", "999999" )
.env( "CLR_PS_HIGH_RAM_MB", "0" )
.output()
.expect( "run clr ps" );
let _ = bg.kill();
let _ = bg.wait();
let stdout = stdout_str( &out );
assert!( out.status.success(), "IT-33: exit 0 expected, got {:?}", out.status.code() );
assert!(
stdout.contains( "🐘" ),
"IT-33: 🐘 flag must appear when ram_kb > 0 and CLR_PS_HIGH_RAM_MB=0. Got:\n{stdout}"
);
}
#[ cfg( target_os = "linux" ) ]
#[ test ]
fn it34_dead_metrics_flag_for_missing_stat()
{
let fake_proc = tempfile::TempDir::new().expect( "fake proc dir" );
let pid_dir = fake_proc.path().join( "99999998" );
std::fs::create_dir_all( &pid_dir ).expect( "create fake pid dir" );
std::fs::write( pid_dir.join( "cmdline" ), b"claude\x0030\x00" )
.expect( "write fake cmdline" );
let bin = env!( "CARGO_BIN_EXE_clr" );
let out = std::process::Command::new( bin )
.args( [ "ps" ] )
.env( "CLR_PROC_DIR", fake_proc.path() )
.output()
.expect( "run clr ps" );
let stdout = stdout_str( &out );
assert!( out.status.success(), "IT-34: exit 0 expected, got {:?}", out.status.code() );
assert!(
stdout.contains( "⚠" ),
"IT-34: ⚠ flag must appear when /proc/{{pid}}/stat is absent. Got:\n{stdout}"
);
}
#[ cfg( target_os = "linux" ) ]
#[ test ]
fn it35_print_mode_flag_for_print_session()
{
use std::os::unix::process::CommandExt as _;
use cli_binary_test_helpers::fake_claude_binary_dir;
let ( _bin_dir, path_val ) = fake_claude_binary_dir();
let mut bg = std::process::Command::new( "/bin/sh" )
.arg0( "claude" )
.arg( "-c" )
.arg( "sleep 30; :" )
.arg( "--print" )
.env( "PATH", &path_val )
.stdout( std::process::Stdio::null() )
.stderr( std::process::Stdio::null() )
.spawn()
.expect( "spawn print-mode claude" );
std::thread::sleep( core::time::Duration::from_millis( 200 ) );
let bin = env!( "CARGO_BIN_EXE_clr" );
let out = std::process::Command::new( bin )
.args( [ "ps" ] )
.env( "PATH", &path_val )
.env( "CLR_PS_ANCIENT_SECS", "999999" )
.env( "CLR_PS_HIGH_RAM_MB", "999999" )
.output()
.expect( "run clr ps" );
let _ = bg.kill();
let _ = bg.wait();
let stdout = stdout_str( &out );
assert!( out.status.success(), "IT-35: exit 0 expected, got {:?}", out.status.code() );
assert!(
stdout.contains( "🖨" ),
"IT-35: 🖨 flag must appear for print-mode session. Got:\n{stdout}"
);
}
#[ cfg( target_os = "linux" ) ]
#[ test ]
fn it36_legend_present_when_flags_fire()
{
use cli_binary_test_helpers::fake_claude_binary_dir;
let ( _bin_dir, path_val ) = fake_claude_binary_dir();
let temp_home = tempfile::TempDir::new().expect( "tmp home" );
let outside_home = tempfile::TempDir::new().expect( "tmp outside home" );
let mut bg = std::process::Command::new( "claude" )
.env( "PATH", &path_val )
.arg( "30" )
.current_dir( outside_home.path() )
.stdout( std::process::Stdio::null() )
.stderr( std::process::Stdio::null() )
.spawn()
.expect( "spawn fake claude" );
std::thread::sleep( core::time::Duration::from_millis( 200 ) );
let bin = env!( "CARGO_BIN_EXE_clr" );
let out = std::process::Command::new( bin )
.args( [ "ps" ] )
.env( "PATH", &path_val )
.env( "HOME", temp_home.path() )
.env( "CLR_PS_ANCIENT_SECS", "999999" )
.env( "CLR_PS_HIGH_RAM_MB", "999999" )
.output()
.expect( "run clr ps" );
let _ = bg.kill();
let _ = bg.wait();
let stdout = stdout_str( &out );
assert!( out.status.success(), "IT-36: exit 0 expected, got {:?}", out.status.code() );
assert!(
stdout.contains( "Active Sessions" ),
"IT-36: active table must appear. Got:\n{stdout}"
);
assert!(
stdout.contains( "🐳" ) && stdout.contains( "Container" ),
"IT-36: legend must contain '🐳 Container'. Got:\n{stdout}"
);
}
#[ cfg( unix ) ]
#[ test ]
fn it37_legend_absent_when_no_flags()
{
use cli_binary_test_helpers::fake_claude_binary_dir;
let ( _bin_dir, path_val ) = fake_claude_binary_dir();
let temp_home = tempfile::TempDir::new().expect( "tmp home" );
let work_dir = temp_home.path().join( "work" );
std::fs::create_dir_all( &work_dir ).expect( "create work dir" );
let mut bg = std::process::Command::new( "claude" )
.env( "PATH", &path_val )
.arg( "30" )
.current_dir( &work_dir )
.stdout( std::process::Stdio::null() )
.stderr( std::process::Stdio::null() )
.spawn()
.expect( "spawn fake claude" );
std::thread::sleep( core::time::Duration::from_millis( 200 ) );
let bin = env!( "CARGO_BIN_EXE_clr" );
let out = std::process::Command::new( bin )
.args( [ "ps" ] )
.env( "PATH", &path_val )
.env( "HOME", temp_home.path() )
.env( "CLR_PS_ANCIENT_SECS", "999999" )
.env( "CLR_PS_HIGH_RAM_MB", "999999" )
.output()
.expect( "run clr ps" );
let _ = bg.kill();
let _ = bg.wait();
let stdout = stdout_str( &out );
assert!( out.status.success(), "IT-37: exit 0 expected, got {:?}", out.status.code() );
for emoji in [ "👈", "🖨", "⚡", "🕰", "🐘", "⚠", "🐳" ]
{
assert!(
!stdout.contains( emoji ),
"IT-37: flag emoji '{emoji}' must NOT appear when no flags fire. Got:\n{stdout}"
);
}
}
#[ cfg( unix ) ]
#[ test ]
fn it38_high_thresholds_suppress_time_and_ram_flags()
{
use cli_binary_test_helpers::fake_claude_binary_dir;
let ( _bin_dir, path_val ) = fake_claude_binary_dir();
let temp_home = tempfile::TempDir::new().expect( "tmp home" );
let work_dir = temp_home.path().join( "work" );
std::fs::create_dir_all( &work_dir ).expect( "create work dir" );
let mut bg = std::process::Command::new( "claude" )
.env( "PATH", &path_val )
.arg( "30" )
.current_dir( &work_dir )
.stdout( std::process::Stdio::null() )
.stderr( std::process::Stdio::null() )
.spawn()
.expect( "spawn fake claude" );
std::thread::sleep( core::time::Duration::from_millis( 200 ) );
let bin = env!( "CARGO_BIN_EXE_clr" );
let out = std::process::Command::new( bin )
.args( [ "ps" ] )
.env( "PATH", &path_val )
.env( "HOME", temp_home.path() )
.env( "CLR_PS_ANCIENT_SECS", "999999" )
.env( "CLR_PS_HIGH_RAM_MB", "999999" )
.output()
.expect( "run clr ps" );
let _ = bg.kill();
let _ = bg.wait();
let stdout = stdout_str( &out );
assert!( out.status.success(), "IT-38: exit 0 expected, got {:?}", out.status.code() );
assert!( !stdout.contains( "🕰" ), "IT-38: 🕰 must NOT fire with threshold 999999. Got:\n{stdout}" );
assert!( !stdout.contains( "🐘" ), "IT-38: 🐘 must NOT fire with threshold 999999. Got:\n{stdout}" );
}
#[ cfg( unix ) ]
#[ test ]
fn us18_flags_column_absent_when_no_flags_apply()
{
use cli_binary_test_helpers::fake_claude_binary_dir;
let ( _bin_dir, path_val ) = fake_claude_binary_dir();
let temp_home = tempfile::TempDir::new().expect( "tmp home" );
let work_dir = temp_home.path().join( "src" );
std::fs::create_dir_all( &work_dir ).expect( "create work dir" );
let mut bg = std::process::Command::new( "claude" )
.env( "PATH", &path_val )
.arg( "30" )
.current_dir( &work_dir )
.stdout( std::process::Stdio::null() )
.stderr( std::process::Stdio::null() )
.spawn()
.expect( "spawn fake claude" );
std::thread::sleep( core::time::Duration::from_millis( 200 ) );
let bin = env!( "CARGO_BIN_EXE_clr" );
let out = std::process::Command::new( bin )
.args( [ "ps" ] )
.env( "PATH", &path_val )
.env( "HOME", temp_home.path() )
.env( "CLR_PS_ANCIENT_SECS", "999999" )
.env( "CLR_PS_HIGH_RAM_MB", "999999" )
.output()
.expect( "run clr ps" );
let _ = bg.kill();
let _ = bg.wait();
let stdout = stdout_str( &out );
assert!( out.status.success(), "US-18: exit 0 expected, got {:?}", out.status.code() );
assert!(
!stdout.contains( "Flags" ),
"US-18: 'Flags' column must NOT appear when no flags apply. Got:\n{stdout}"
);
}
#[ cfg( target_os = "linux" ) ]
#[ test ]
fn us19_container_flag_for_cwd_outside_home()
{
use cli_binary_test_helpers::fake_claude_binary_dir;
let ( _bin_dir, path_val ) = fake_claude_binary_dir();
let temp_home = tempfile::TempDir::new().expect( "tmp home" );
let container = tempfile::TempDir::new().expect( "container dir" );
let home_str = temp_home.path().to_string_lossy().to_string();
let container_str = container.path().to_string_lossy().to_string();
assert!( !container_str.starts_with( &home_str ), "dirs must not overlap" );
let mut bg = std::process::Command::new( "claude" )
.env( "PATH", &path_val )
.arg( "30" )
.current_dir( container.path() )
.stdout( std::process::Stdio::null() )
.stderr( std::process::Stdio::null() )
.spawn()
.expect( "spawn fake claude" );
std::thread::sleep( core::time::Duration::from_millis( 200 ) );
let bin = env!( "CARGO_BIN_EXE_clr" );
let out = std::process::Command::new( bin )
.args( [ "ps" ] )
.env( "PATH", &path_val )
.env( "HOME", temp_home.path() )
.output()
.expect( "run clr ps" );
let _ = bg.kill();
let _ = bg.wait();
let stdout = stdout_str( &out );
assert!( out.status.success(), "US-19: exit 0 expected, got {:?}", out.status.code() );
assert!(
stdout.contains( "🐳" ),
"US-19: 🐳 flag must appear for cwd outside HOME. Got:\n{stdout}"
);
assert!(
stdout.contains( "Container" ),
"US-19: legend must contain 'Container'. Got:\n{stdout}"
);
}
#[ cfg( target_os = "linux" ) ]
#[ test ]
fn us20_ancient_flag_with_zero_threshold()
{
use cli_binary_test_helpers::fake_claude_binary_dir;
let ( _bin_dir, path_val ) = fake_claude_binary_dir();
let mut bg = std::process::Command::new( "claude" )
.env( "PATH", &path_val )
.arg( "30" )
.stdout( std::process::Stdio::null() )
.stderr( std::process::Stdio::null() )
.spawn()
.expect( "spawn fake claude" );
std::thread::sleep( core::time::Duration::from_millis( 1_100 ) );
let bin = env!( "CARGO_BIN_EXE_clr" );
let out = std::process::Command::new( bin )
.args( [ "ps" ] )
.env( "PATH", &path_val )
.env( "CLR_PS_ANCIENT_SECS", "0" )
.env( "CLR_PS_HIGH_RAM_MB", "999999" )
.output()
.expect( "run clr ps" );
let _ = bg.kill();
let _ = bg.wait();
let stdout = stdout_str( &out );
assert!( out.status.success(), "US-20: exit 0 expected, got {:?}", out.status.code() );
assert!(
stdout.contains( "🕰" ),
"US-20: 🕰 flag must appear with CLR_PS_ANCIENT_SECS=0. Got:\n{stdout}"
);
assert!(
stdout.contains( "Ancient" ),
"US-20: legend must contain 'Ancient'. Got:\n{stdout}"
);
}
#[ cfg( target_os = "linux" ) ]
#[ test ]
fn us21_high_ram_flag_with_zero_threshold()
{
use cli_binary_test_helpers::fake_claude_binary_dir;
let ( _bin_dir, path_val ) = fake_claude_binary_dir();
let mut bg = std::process::Command::new( "claude" )
.env( "PATH", &path_val )
.arg( "30" )
.stdout( std::process::Stdio::null() )
.stderr( std::process::Stdio::null() )
.spawn()
.expect( "spawn fake claude" );
std::thread::sleep( core::time::Duration::from_millis( 200 ) );
let bin = env!( "CARGO_BIN_EXE_clr" );
let out = std::process::Command::new( bin )
.args( [ "ps" ] )
.env( "PATH", &path_val )
.env( "CLR_PS_ANCIENT_SECS", "999999" )
.env( "CLR_PS_HIGH_RAM_MB", "0" )
.output()
.expect( "run clr ps" );
let _ = bg.kill();
let _ = bg.wait();
let stdout = stdout_str( &out );
assert!( out.status.success(), "US-21: exit 0 expected, got {:?}", out.status.code() );
assert!(
stdout.contains( "🐘" ),
"US-21: 🐘 flag must appear with CLR_PS_HIGH_RAM_MB=0. Got:\n{stdout}"
);
assert!(
stdout.contains( "High RAM" ),
"US-21: legend must contain 'High RAM'. Got:\n{stdout}"
);
}
#[ cfg( target_os = "linux" ) ]
#[ test ]
fn us22_dead_metrics_flag_for_missing_stat()
{
let fake_proc = tempfile::TempDir::new().expect( "fake proc dir" );
let pid_dir = fake_proc.path().join( "99999997" );
std::fs::create_dir_all( &pid_dir ).expect( "create fake pid dir" );
std::fs::write( pid_dir.join( "cmdline" ), b"claude\x0030\x00" )
.expect( "write fake cmdline" );
let bin = env!( "CARGO_BIN_EXE_clr" );
let out = std::process::Command::new( bin )
.args( [ "ps" ] )
.env( "CLR_PROC_DIR", fake_proc.path() )
.output()
.expect( "run clr ps" );
let stdout = stdout_str( &out );
assert!( out.status.success(), "US-22: exit 0 expected, got {:?}", out.status.code() );
assert!(
stdout.contains( "⚠" ),
"US-22: ⚠ flag must appear for TOCTOU-dead session. Got:\n{stdout}"
);
assert!(
stdout.contains( "Dead metrics" ),
"US-22: legend must contain 'Dead metrics'. Got:\n{stdout}"
);
}
#[ cfg( target_os = "linux" ) ]
#[ test ]
fn us23_active_flag_for_cpu_intensive_session()
{
use std::os::unix::process::CommandExt as _;
use cli_binary_test_helpers::fake_claude_binary_dir;
let ( _bin_dir, path_val ) = fake_claude_binary_dir();
let mut bg = std::process::Command::new( "/bin/sh" )
.arg0( "claude" )
.arg( "-c" )
.arg( "while :; do :; done" )
.env( "PATH", &path_val )
.stdout( std::process::Stdio::null() )
.stderr( std::process::Stdio::null() )
.spawn()
.expect( "spawn busy-loop claude" );
std::thread::sleep( core::time::Duration::from_millis( 200 ) );
let bin = env!( "CARGO_BIN_EXE_clr" );
let out = std::process::Command::new( bin )
.args( [ "ps" ] )
.env( "PATH", &path_val )
.env( "CLR_PS_ANCIENT_SECS", "999999" )
.env( "CLR_PS_HIGH_RAM_MB", "999999" )
.output()
.expect( "run clr ps" );
let _ = bg.kill();
let _ = bg.wait();
let stdout = stdout_str( &out );
assert!( out.status.success(), "US-23: exit 0 expected, got {:?}", out.status.code() );
assert!(
stdout.contains( "⚡" ),
"US-23: ⚡ flag must appear for busy-loop session (CPU delta >> 3). Got:\n{stdout}"
);
assert!(
stdout.contains( "Active" ),
"US-23: legend must contain 'Active'. Got:\n{stdout}"
);
}
#[ cfg( target_os = "linux" ) ]
#[ test ]
fn us24_print_mode_flag_for_print_session()
{
use std::os::unix::process::CommandExt as _;
use cli_binary_test_helpers::fake_claude_binary_dir;
let ( _bin_dir, path_val ) = fake_claude_binary_dir();
let mut bg = std::process::Command::new( "/bin/sh" )
.arg0( "claude" )
.arg( "-c" )
.arg( "sleep 30; :" )
.arg( "--print" )
.env( "PATH", &path_val )
.stdout( std::process::Stdio::null() )
.stderr( std::process::Stdio::null() )
.spawn()
.expect( "spawn print-mode claude" );
std::thread::sleep( core::time::Duration::from_millis( 200 ) );
let bin = env!( "CARGO_BIN_EXE_clr" );
let out = std::process::Command::new( bin )
.args( [ "ps" ] )
.env( "PATH", &path_val )
.env( "CLR_PS_ANCIENT_SECS", "999999" )
.env( "CLR_PS_HIGH_RAM_MB", "999999" )
.output()
.expect( "run clr ps" );
let _ = bg.kill();
let _ = bg.wait();
let stdout = stdout_str( &out );
assert!( out.status.success(), "US-24: exit 0 expected, got {:?}", out.status.code() );
assert!(
stdout.contains( "🖨" ),
"US-24: 🖨 flag must appear for print-mode session. Got:\n{stdout}"
);
assert!(
stdout.contains( "Print mode" ),
"US-24: legend must contain 'Print mode'. Got:\n{stdout}"
);
}
#[ cfg( target_os = "linux" ) ]
#[ test ]
fn us25_legend_appears_when_flags_present()
{
use cli_binary_test_helpers::fake_claude_binary_dir;
let ( _bin_dir, path_val ) = fake_claude_binary_dir();
let temp_home = tempfile::TempDir::new().expect( "tmp home" );
let outside_home = tempfile::TempDir::new().expect( "outside home" );
let home_str = temp_home.path().to_string_lossy().to_string();
let outside_str = outside_home.path().to_string_lossy().to_string();
assert!( !outside_str.starts_with( &home_str ), "dirs must not overlap" );
let mut bg = std::process::Command::new( "claude" )
.env( "PATH", &path_val )
.arg( "30" )
.current_dir( outside_home.path() )
.stdout( std::process::Stdio::null() )
.stderr( std::process::Stdio::null() )
.spawn()
.expect( "spawn fake claude" );
std::thread::sleep( core::time::Duration::from_millis( 200 ) );
let bin = env!( "CARGO_BIN_EXE_clr" );
let out = std::process::Command::new( bin )
.args( [ "ps" ] )
.env( "PATH", &path_val )
.env( "HOME", temp_home.path() )
.output()
.expect( "run clr ps" );
let _ = bg.kill();
let _ = bg.wait();
let stdout = stdout_str( &out );
assert!( out.status.success(), "US-25: exit 0 expected, got {:?}", out.status.code() );
assert!(
stdout.contains( "Active Sessions" ),
"US-25: active table must appear. Got:\n{stdout}"
);
assert!(
stdout.contains( "🐳" ) && stdout.contains( "Container" ),
"US-25: legend must contain '🐳 Container'. Got:\n{stdout}"
);
}
#[ cfg( unix ) ]
#[ test ]
fn us26_legend_absent_when_no_flags_present()
{
use cli_binary_test_helpers::fake_claude_binary_dir;
let ( _bin_dir, path_val ) = fake_claude_binary_dir();
let temp_home = tempfile::TempDir::new().expect( "tmp home" );
let work_dir = temp_home.path().join( "project" );
std::fs::create_dir_all( &work_dir ).expect( "create work dir" );
let mut bg = std::process::Command::new( "claude" )
.env( "PATH", &path_val )
.arg( "30" )
.current_dir( &work_dir )
.stdout( std::process::Stdio::null() )
.stderr( std::process::Stdio::null() )
.spawn()
.expect( "spawn fake claude" );
std::thread::sleep( core::time::Duration::from_millis( 200 ) );
let bin = env!( "CARGO_BIN_EXE_clr" );
let out = std::process::Command::new( bin )
.args( [ "ps" ] )
.env( "PATH", &path_val )
.env( "HOME", temp_home.path() )
.env( "CLR_PS_ANCIENT_SECS", "999999" )
.env( "CLR_PS_HIGH_RAM_MB", "999999" )
.output()
.expect( "run clr ps" );
let _ = bg.kill();
let _ = bg.wait();
let stdout = stdout_str( &out );
assert!( out.status.success(), "US-26: exit 0 expected, got {:?}", out.status.code() );
for emoji in [ "👈", "🖨", "⚡", "🕰", "🐘", "⚠", "🐳" ]
{
assert!(
!stdout.contains( emoji ),
"US-26: flag emoji '{emoji}' must NOT appear when no flags fire. Got:\n{stdout}"
);
}
}
#[ cfg( target_os = "linux" ) ]
#[ test ]
fn e41_ancient_secs_env_var()
{
use cli_binary_test_helpers::fake_claude_binary_dir;
let ( _bin_dir, path_val ) = fake_claude_binary_dir();
let mut bg = std::process::Command::new( "claude" )
.env( "PATH", &path_val )
.arg( "30" )
.stdout( std::process::Stdio::null() )
.stderr( std::process::Stdio::null() )
.spawn()
.expect( "spawn fake claude" );
std::thread::sleep( core::time::Duration::from_millis( 1_100 ) );
let bin = env!( "CARGO_BIN_EXE_clr" );
let out_valid = std::process::Command::new( bin )
.args( [ "ps" ] )
.env( "PATH", &path_val )
.env( "CLR_PS_ANCIENT_SECS", "0" )
.env( "CLR_PS_HIGH_RAM_MB", "999999" )
.output()
.expect( "run clr ps (valid)" );
let _ = bg.kill();
let _ = bg.wait();
let stdout_valid = stdout_str( &out_valid );
assert!(
out_valid.status.success(),
"E41a: exit 0 expected, got {:?}", out_valid.status.code()
);
assert!(
stdout_valid.contains( "🕰" ),
"E41a: 🕰 must fire with CLR_PS_ANCIENT_SECS=0. Got:\n{stdout_valid}"
);
let ( _bin_dir2, path_val2 ) = fake_claude_binary_dir();
let mut bg2 = std::process::Command::new( "claude" )
.env( "PATH", &path_val2 )
.arg( "30" )
.stdout( std::process::Stdio::null() )
.stderr( std::process::Stdio::null() )
.spawn()
.expect( "spawn fake claude 2" );
std::thread::sleep( core::time::Duration::from_millis( 200 ) );
let out_invalid = std::process::Command::new( bin )
.args( [ "ps" ] )
.env( "PATH", &path_val2 )
.env( "CLR_PS_ANCIENT_SECS", "not_a_number" )
.env( "CLR_PS_HIGH_RAM_MB", "999999" )
.output()
.expect( "run clr ps (invalid)" );
let _ = bg2.kill();
let _ = bg2.wait();
let stdout_invalid = stdout_str( &out_invalid );
assert!(
out_invalid.status.success(),
"E41b: exit 0 expected with invalid CLR_PS_ANCIENT_SECS, got {:?}",
out_invalid.status.code()
);
assert!(
!stdout_invalid.contains( "🕰" ),
"E41b: 🕰 must NOT fire when CLR_PS_ANCIENT_SECS is invalid (default 28800 used). Got:\n{stdout_invalid}"
);
}
#[ cfg( target_os = "linux" ) ]
#[ test ]
fn e42_high_ram_mb_env_var()
{
use cli_binary_test_helpers::fake_claude_binary_dir;
let bin = env!( "CARGO_BIN_EXE_clr" );
let ( _bin_dir, path_val ) = fake_claude_binary_dir();
let mut bg = std::process::Command::new( "claude" )
.env( "PATH", &path_val )
.arg( "30" )
.stdout( std::process::Stdio::null() )
.stderr( std::process::Stdio::null() )
.spawn()
.expect( "spawn fake claude" );
std::thread::sleep( core::time::Duration::from_millis( 200 ) );
let out_valid = std::process::Command::new( bin )
.args( [ "ps" ] )
.env( "PATH", &path_val )
.env( "CLR_PS_ANCIENT_SECS", "999999" )
.env( "CLR_PS_HIGH_RAM_MB", "0" )
.output()
.expect( "run clr ps (valid)" );
let _ = bg.kill();
let _ = bg.wait();
let stdout_valid = stdout_str( &out_valid );
assert!(
out_valid.status.success(),
"E42a: exit 0 expected, got {:?}", out_valid.status.code()
);
assert!(
stdout_valid.contains( "🐘" ),
"E42a: 🐘 must fire with CLR_PS_HIGH_RAM_MB=0. Got:\n{stdout_valid}"
);
let ( _bin_dir2, path_val2 ) = fake_claude_binary_dir();
let mut bg2 = std::process::Command::new( "claude" )
.env( "PATH", &path_val2 )
.arg( "30" )
.stdout( std::process::Stdio::null() )
.stderr( std::process::Stdio::null() )
.spawn()
.expect( "spawn fake claude 2" );
std::thread::sleep( core::time::Duration::from_millis( 200 ) );
let out_invalid = std::process::Command::new( bin )
.args( [ "ps" ] )
.env( "PATH", &path_val2 )
.env( "CLR_PS_ANCIENT_SECS", "999999" )
.env( "CLR_PS_HIGH_RAM_MB", "bogus" )
.output()
.expect( "run clr ps (invalid)" );
let _ = bg2.kill();
let _ = bg2.wait();
let stdout_invalid = stdout_str( &out_invalid );
assert!(
out_invalid.status.success(),
"E42b: exit 0 expected with invalid CLR_PS_HIGH_RAM_MB, got {:?}",
out_invalid.status.code()
);
assert!(
!stdout_invalid.contains( "🐘" ),
"E42b: 🐘 must NOT fire when CLR_PS_HIGH_RAM_MB is invalid (default 400 used). Got:\n{stdout_invalid}"
);
}
#[ cfg( target_os = "linux" ) ]
#[ test ]
fn it39_sleeping_process_no_active_flag()
{
use std::os::unix::process::CommandExt as _;
use cli_binary_test_helpers::fake_claude_binary_dir;
let ( _bin_dir, path_val ) = fake_claude_binary_dir();
let mut bg = std::process::Command::new( "/bin/sh" )
.arg0( "claude" )
.arg( "-c" )
.arg( "sleep 300" )
.env( "PATH", &path_val )
.stdout( std::process::Stdio::null() )
.stderr( std::process::Stdio::null() )
.spawn()
.expect( "spawn sleeping claude" );
std::thread::sleep( core::time::Duration::from_millis( 200 ) );
let bin = env!( "CARGO_BIN_EXE_clr" );
let out = std::process::Command::new( bin )
.args( [ "ps" ] )
.env( "PATH", &path_val )
.env( "CLR_PS_ANCIENT_SECS", "999999" )
.env( "CLR_PS_HIGH_RAM_MB", "999999" )
.output()
.expect( "run clr ps" );
let _ = bg.kill();
let _ = bg.wait();
let stdout = stdout_str( &out );
assert!( out.status.success(), "IT-39: exit 0 expected, got {:?}", out.status.code() );
assert!(
!stdout.contains( "⚡" ),
"IT-39: ⚡ must NOT appear for sleeping process (CPU delta = 0). Got:\n{stdout}"
);
}
#[ cfg( target_os = "linux" ) ]
#[ test ]
fn it40_busy_loop_process_active_flag()
{
use std::os::unix::process::CommandExt as _;
use cli_binary_test_helpers::fake_claude_binary_dir;
let ( _bin_dir, path_val ) = fake_claude_binary_dir();
let mut bg = std::process::Command::new( "/bin/sh" )
.arg0( "claude" )
.arg( "-c" )
.arg( "while :; do :; done" )
.env( "PATH", &path_val )
.stdout( std::process::Stdio::null() )
.stderr( std::process::Stdio::null() )
.spawn()
.expect( "spawn busy-loop claude" );
std::thread::sleep( core::time::Duration::from_millis( 200 ) );
let bin = env!( "CARGO_BIN_EXE_clr" );
let out = std::process::Command::new( bin )
.args( [ "ps" ] )
.env( "PATH", &path_val )
.env( "CLR_PS_ANCIENT_SECS", "999999" )
.env( "CLR_PS_HIGH_RAM_MB", "999999" )
.output()
.expect( "run clr ps" );
let _ = bg.kill();
let _ = bg.wait();
let stdout = stdout_str( &out );
assert!( out.status.success(), "IT-40: exit 0 expected, got {:?}", out.status.code() );
assert!(
stdout.contains( "⚡" ),
"IT-40: ⚡ must appear for busy-loop process (CPU delta >> 3). Got:\n{stdout}"
);
assert!(
stdout.contains( "Active" ),
"IT-40: legend must contain 'Active'. Got:\n{stdout}"
);
}