Simon Strandgaard commited on
Commit
bb28e75
·
1 Parent(s): 977ad93

purge_old_runs() now also deletes files+dirs. Previously it was only dirs that could be purged.

Browse files
src/purge/purge_old_runs.py CHANGED
@@ -9,7 +9,7 @@ logger = logging.getLogger(__name__)
9
 
10
  def purge_old_runs(run_dir: str, max_age_hours: float = 1.0, prefix: str = "myrun_") -> None:
11
  """
12
- Deletes runs in the specified run_dir older than max_age_hours and matching the specified prefix.
13
  """
14
  if not os.path.isabs(run_dir):
15
  raise ValueError(f"run_dir must be an absolute path: {run_dir}")
@@ -17,26 +17,27 @@ def purge_old_runs(run_dir: str, max_age_hours: float = 1.0, prefix: str = "myru
17
  now = datetime.datetime.now()
18
  cutoff = now - datetime.timedelta(hours=max_age_hours)
19
 
20
- for run_id in os.listdir(run_dir):
21
- if not run_id.startswith(prefix):
22
  continue # Skip files and directories that don't match the prefix
23
 
24
- run_path = os.path.join(run_dir, run_id)
25
- if not os.path.isdir(run_path):
26
- continue # Skip files
27
 
28
  try:
29
- # Get the modification time of the directory
30
- mtime = datetime.datetime.fromtimestamp(os.path.getmtime(run_path))
31
 
32
  if mtime < cutoff:
33
- logger.debug(f"Deleting old run: {run_id} from {run_dir}")
34
- shutil.rmtree(run_path) # Delete the directory and all its contents
 
 
 
35
  else:
36
- logger.debug(f"Skipping {run_id} in {run_dir}, last modified: {mtime}")
37
 
38
  except Exception as e:
39
- logger.error(f"Error processing {run_id} in {run_dir}: {e}")
40
 
41
  def start_purge_scheduler(run_dir: str, purge_interval_seconds: float=3600, prefix: str = "myrun_") -> None:
42
  """
 
9
 
10
  def purge_old_runs(run_dir: str, max_age_hours: float = 1.0, prefix: str = "myrun_") -> None:
11
  """
12
+ Deletes files and directories in the specified run_dir older than max_age_hours and matching the specified prefix.
13
  """
14
  if not os.path.isabs(run_dir):
15
  raise ValueError(f"run_dir must be an absolute path: {run_dir}")
 
17
  now = datetime.datetime.now()
18
  cutoff = now - datetime.timedelta(hours=max_age_hours)
19
 
20
+ for item in os.listdir(run_dir):
21
+ if not item.startswith(prefix):
22
  continue # Skip files and directories that don't match the prefix
23
 
24
+ item_path = os.path.join(run_dir, item)
 
 
25
 
26
  try:
27
+ # Get the modification time of the item (file or directory)
28
+ mtime = datetime.datetime.fromtimestamp(os.path.getmtime(item_path))
29
 
30
  if mtime < cutoff:
31
+ logger.debug(f"Deleting old data: {item} from {run_dir}")
32
+ if os.path.isdir(item_path):
33
+ shutil.rmtree(item_path) # Delete the directory and all its contents
34
+ else:
35
+ os.remove(item_path) # Delete the file
36
  else:
37
+ logger.debug(f"Skipping {item} in {run_dir}, last modified: {mtime}")
38
 
39
  except Exception as e:
40
+ logger.error(f"Error processing {item} in {run_dir}: {e}")
41
 
42
  def start_purge_scheduler(run_dir: str, purge_interval_seconds: float=3600, prefix: str = "myrun_") -> None:
43
  """
src/purge/tests/test_purge_old_runs.py CHANGED
@@ -14,14 +14,16 @@ class TestPurgeOldRuns(unittest.TestCase):
14
  os.makedirs(self.test_run_dir, exist_ok=True)
15
 
16
  # Create some dummy run directories with different modification times
17
- self.create_dummy_run("myrun_run1", hours_old=0.5)
18
- self.create_dummy_run("myrun_run2", hours_old=1.5) # Should be purged
19
- self.create_dummy_run("myrun_run3", hours_old=2) # Should be purged
20
- self.create_dummy_run("myrun_run4", hours_old=0.25)
21
- self.create_dummy_run("myrun_run5", hours_old=1) # Boundary condition, might be purged
22
- self.create_dummy_run("myrun_run6", hours_old=0) # Today
23
- self.create_dummy_run("other_run7", hours_old=1.5) #Should NOT be purged
24
- self.create_dummy_file("not_a_run.txt") # a file that should be left alone
 
 
25
 
26
  def tearDown(self):
27
  """Clean up test environment after each test."""
@@ -29,29 +31,33 @@ class TestPurgeOldRuns(unittest.TestCase):
29
  if os.path.exists(self.test_run_dir):
30
  shutil.rmtree(self.test_run_dir)
31
 
32
- def create_dummy_run(self, run_id, hours_old):
33
  """Creates a dummy run directory with a specific modification time."""
34
- run_path = os.path.join(self.test_run_dir, run_id)
35
- os.makedirs(run_path, exist_ok=True)
36
 
37
  # Set the modification time of the directory
38
  mtime = time.time() - (hours_old * 3600) # seconds
39
- os.utime(run_path, (mtime, mtime))
40
 
41
- def create_dummy_file(self, filename):
42
  """Create a dummy file in the test directory."""
43
- filepath = os.path.join(self.test_run_dir, filename)
44
- with open(filepath, "w") as f:
45
  f.write("This is a dummy file.")
46
 
 
 
 
 
47
  def test_purge_old_runs(self):
48
  """Tests the purge_old_runs function."""
49
  max_age_hours = 0.95
50
  purge_old_runs(self.test_run_dir, max_age_hours=max_age_hours, prefix="myrun_") # Pass the directory
51
 
52
  # Check which runs should have been purged
53
- runs_to_keep = ["myrun_run1", "myrun_run4", "myrun_run6", "other_run7","not_a_run.txt"]
54
- runs_to_purge = ["myrun_run2", "myrun_run3", "myrun_run5"]
55
 
56
  for run_id in runs_to_keep:
57
  run_path = os.path.join(self.test_run_dir, run_id)
@@ -74,7 +80,7 @@ class TestPurgeOldRuns(unittest.TestCase):
74
  purge_old_runs(self.test_run_dir, max_age_hours=max_age_hours, prefix="myrun_") # Pass the directory
75
 
76
  # All runs should still exist, including the one with the wrong prefix.
77
- expected_runs = ["myrun_run1", "myrun_run2", "myrun_run3", "myrun_run4", "myrun_run5", "myrun_run6", "other_run7", "not_a_run.txt"]
78
  for run_id in expected_runs:
79
  run_path = os.path.join(self.test_run_dir, run_id)
80
  self.assertTrue(os.path.exists(run_path), f"Run {run_id} should not have been purged.")
 
14
  os.makedirs(self.test_run_dir, exist_ok=True)
15
 
16
  # Create some dummy run directories with different modification times
17
+ self.create_dummy_dir("myrun_dir1", hours_old=0.5)
18
+ self.create_dummy_dir("myrun_dir2", hours_old=1.5)
19
+ self.create_dummy_dir("myrun_dir3", hours_old=2)
20
+ self.create_dummy_dir("myrun_dir4", hours_old=0.25)
21
+ self.create_dummy_dir("myrun_dir5", hours_old=1)
22
+ self.create_dummy_dir("myrun_dir6", hours_old=0)
23
+ self.create_dummy_dir("other_dir7", hours_old=1.5) # doesn't have the prefix, so don't delete
24
+ self.create_dummy_file("other_file.txt", hours_old=5) # doesn't have the prefix, so don't delete
25
+ self.create_dummy_file("myrun_file1.txt", hours_old=0.25)
26
+ self.create_dummy_file("myrun_file2.txt", hours_old=1.5)
27
 
28
  def tearDown(self):
29
  """Clean up test environment after each test."""
 
31
  if os.path.exists(self.test_run_dir):
32
  shutil.rmtree(self.test_run_dir)
33
 
34
+ def create_dummy_dir(self, dirname: str, hours_old: float):
35
  """Creates a dummy run directory with a specific modification time."""
36
+ path = os.path.join(self.test_run_dir, dirname)
37
+ os.makedirs(path, exist_ok=True)
38
 
39
  # Set the modification time of the directory
40
  mtime = time.time() - (hours_old * 3600) # seconds
41
+ os.utime(path, (mtime, mtime))
42
 
43
+ def create_dummy_file(self, filename: str, hours_old: float):
44
  """Create a dummy file in the test directory."""
45
+ path = os.path.join(self.test_run_dir, filename)
46
+ with open(path, "w") as f:
47
  f.write("This is a dummy file.")
48
 
49
+ # Set the modification time of the file
50
+ mtime = time.time() - (hours_old * 3600) # seconds
51
+ os.utime(path, (mtime, mtime))
52
+
53
  def test_purge_old_runs(self):
54
  """Tests the purge_old_runs function."""
55
  max_age_hours = 0.95
56
  purge_old_runs(self.test_run_dir, max_age_hours=max_age_hours, prefix="myrun_") # Pass the directory
57
 
58
  # Check which runs should have been purged
59
+ runs_to_keep = ["myrun_dir1", "myrun_dir4", "myrun_dir6", "other_dir7", "other_file.txt", "myrun_file1.txt"]
60
+ runs_to_purge = ["myrun_dir2", "myrun_dir3", "myrun_dir5", "myrun_file2.txt"]
61
 
62
  for run_id in runs_to_keep:
63
  run_path = os.path.join(self.test_run_dir, run_id)
 
80
  purge_old_runs(self.test_run_dir, max_age_hours=max_age_hours, prefix="myrun_") # Pass the directory
81
 
82
  # All runs should still exist, including the one with the wrong prefix.
83
+ expected_runs = ["myrun_dir1", "myrun_dir2", "myrun_dir3", "myrun_dir4", "myrun_dir5", "myrun_dir6", "other_dir7", "other_file.txt", "myrun_file1.txt", "myrun_file2.txt"]
84
  for run_id in expected_runs:
85
  run_path = os.path.join(self.test_run_dir, run_id)
86
  self.assertTrue(os.path.exists(run_path), f"Run {run_id} should not have been purged.")