diff --git a/src/log_pruner.py b/src/log_pruner.py index 0e0a338..71205f1 100644 --- a/src/log_pruner.py +++ b/src/log_pruner.py @@ -41,12 +41,24 @@ class LogPruner: for session_info in old_sessions_to_check: session_id = session_info['session_id'] session_path = session_info['path'] - if not session_path or not os.path.isdir(session_path): + if not session_path: continue - # Calculate total size of files in the directory + + # Resolve path + resolved_path = session_path + if not os.path.isabs(resolved_path): + if resolved_path.startswith('logs' + os.sep) or resolved_path.startswith('logs/'): + # Resolve relative to the project root (two levels up from self.logs_dir) + project_root = os.path.dirname(os.path.dirname(os.path.abspath(self.logs_dir))) + resolved_path = os.path.join(project_root, resolved_path) + + if not os.path.isdir(resolved_path): + continue + + # Calculate total size of files in the directory total_size = 0 try: - for entry in os.scandir(session_path): + for entry in os.scandir(resolved_path): if entry.is_file(): total_size += entry.stat().st_size except OSError: @@ -54,7 +66,7 @@ class LogPruner: # Prune if the total size is less than threshold if total_size < (min_size_kb * 1024): try: - shutil.rmtree(session_path) + shutil.rmtree(resolved_path) # Also remove from registry to keep it in sync if session_id in self.log_registry.data: del self.log_registry.data[session_id] diff --git a/tests/test_log_pruning_heuristic.py b/tests/test_log_pruning_heuristic.py index 624aa95..afee5da 100644 --- a/tests/test_log_pruning_heuristic.py +++ b/tests/test_log_pruning_heuristic.py @@ -10,7 +10,7 @@ class TestLogPruningHeuristic(unittest.TestCase): def setUp(self) -> None: self.temp_dir = tempfile.TemporaryDirectory() self.registry_path = os.path.join(self.temp_dir.name, "registry.toml") - self.logs_dir = os.path.join(self.temp_dir.name, "logs") + self.logs_dir = os.path.join(self.temp_dir.name, "logs", "sessions") os.makedirs(self.logs_dir, exist_ok=True) self.registry = LogRegistry(self.registry_path) self.pruner = LogPruner(self.registry, self.logs_dir) @@ -119,5 +119,31 @@ class TestLogPruningHeuristic(unittest.TestCase): self.assertFalse(os.path.exists(session_path)) self.assertNotIn(session_id, self.registry.data) + def test_prune_handles_relative_paths_starting_with_logs(self) -> None: + now = datetime.now() + # Create a session with a relative path + session_id = "rel_path_session" + # In this test, self.logs_dir = temp_dir/logs/sessions + # project_root will be resolved to temp_dir + # So the relative path starting with 'logs/' should be 'logs/rel_path_session' + rel_path = f"logs/{session_id}" + abs_path = os.path.join(self.temp_dir.name, "logs", session_id) + os.makedirs(abs_path, exist_ok=True) + + with open(os.path.join(abs_path, "comms.log"), "w") as f: + f.write("small") # Tiny file + + # Register with the RELATIVE path + self.registry.register_session(session_id, rel_path, now - timedelta(days=10)) + self.registry.update_session_metadata(session_id, message_count=1, errors=0, size_kb=0, whitelisted=False, reason="Test") + + self.assertTrue(os.path.exists(abs_path)) + + # Prune. It should resolve 'logs/rel_path_session' relative to temp_dir.name + self.pruner.prune(max_age_days=1, min_size_kb=1) + + self.assertFalse(os.path.exists(abs_path)) + self.assertNotIn(session_id, self.registry.data) + if __name__ == '__main__': unittest.main()