""" Tests for bin/hermes_cleanup.py — Stale process detection and cleanup. """ import unittest from unittest.mock import patch, MagicMock import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).parent.parent / "bin")) from hermes_cleanup import ( get_process_age_hours, get_child_pids, identify_stale_sessions, kill_session, generate_report, ) class TestGetProcessAgeHours(unittest.TestCase): @patch("hermes_cleanup.subprocess.run") def test_returns_age(self, mock_run): mock_run.return_value = MagicMock(returncode=0, stdout="3600\n") age = get_process_age_hours(1234) self.assertAlmostEqual(age, 1.0, delta=0.01) @patch("hermes_cleanup.subprocess.run") def test_returns_none_on_error(self, mock_run): mock_run.return_value = MagicMock(returncode=1, stdout="") age = get_process_age_hours(9999) self.assertIsNone(age) class TestGetChildPids(unittest.TestCase): @patch("hermes_cleanup.subprocess.run") def test_returns_child_pids(self, mock_run): mock_run.return_value = MagicMock(returncode=0, stdout="1001\n1002\n") pids = get_child_pids(1234) self.assertEqual(pids, [1001, 1002]) @patch("hermes_cleanup.subprocess.run") def test_returns_empty_on_no_children(self, mock_run): mock_run.return_value = MagicMock(returncode=1, stdout="") pids = get_child_pids(1234) self.assertEqual(pids, []) class TestKillSession(unittest.TestCase): def test_dry_run_does_not_kill(self): session = { "session_key": "test", "main_pid": 99999, # unlikely to exist "children": [], } result = kill_session(session, dry_run=True) self.assertTrue(result["dry_run"]) self.assertIn(99999, result["killed"]) @patch("hermes_cleanup.os.kill") def test_kill_terminates_process(self, mock_kill): session = { "session_key": "test", "main_pid": 1234, "children": [1235], } result = kill_session(session, dry_run=False) self.assertFalse(result["dry_run"]) self.assertEqual(mock_kill.call_count, 2) class TestGenerateReport(unittest.TestCase): def test_empty_report(self): report = generate_report([]) self.assertIn("No stale sessions", report) def test_report_with_stale(self): stale = [{ "session_key": "test", "main_pid": 1234, "age_hours": 48.5, "cpu_percent": 0.1, "total_rss_kb": 20480, "total_rss_mb": 20.0, "process_count": 2, "command": "python3 -m hermes.cli chat", "children": [1235], }] report = generate_report(stale) self.assertIn("48.5h", report) self.assertIn("20.0 MB", report) if __name__ == "__main__": unittest.main()