Source code for system.loggerd.tests.test_deleter

#!/usr/bin/env python3
import time
import threading
import unittest
from collections import namedtuple
from pathlib import Path
from collections.abc import Sequence

import openpilot.system.loggerd.deleter as deleter
from openpilot.common.timeout import Timeout, TimeoutException
from openpilot.system.loggerd.tests.loggerd_tests_common import UploaderTestCase

Stats = namedtuple("Stats", ['f_bavail', 'f_blocks', 'f_frsize'])


[docs] class TestDeleter(UploaderTestCase):
[docs] def fake_statvfs(self, d): return self.fake_stats
[docs] def setUp(self): self.f_type = "fcamera.hevc" super().setUp() self.fake_stats = Stats(f_bavail=0, f_blocks=10, f_frsize=4096) deleter.os.statvfs = self.fake_statvfs
[docs] def start_thread(self): self.end_event = threading.Event() self.del_thread = threading.Thread(target=deleter.deleter_thread, args=[self.end_event]) self.del_thread.daemon = True self.del_thread.start()
[docs] def join_thread(self): self.end_event.set() self.del_thread.join()
[docs] def test_delete(self): f_path = self.make_file_with_data(self.seg_dir, self.f_type, 1) self.start_thread() try: with Timeout(2, "Timeout waiting for file to be deleted"): while f_path.exists(): time.sleep(0.01) finally: self.join_thread()
[docs] def assertDeleteOrder(self, f_paths: Sequence[Path], timeout: int = 5) -> None: deleted_order = [] self.start_thread() try: with Timeout(timeout, "Timeout waiting for files to be deleted"): while True: for f in f_paths: if not f.exists() and f not in deleted_order: deleted_order.append(f) if len(deleted_order) == len(f_paths): break time.sleep(0.01) except TimeoutException: print("Not deleted:", [f for f in f_paths if f not in deleted_order]) raise finally: self.join_thread() self.assertEqual(deleted_order, f_paths, "Files not deleted in expected order")
[docs] def test_delete_order(self): self.assertDeleteOrder([ self.make_file_with_data(self.seg_format.format(0), self.f_type), self.make_file_with_data(self.seg_format.format(1), self.f_type), self.make_file_with_data(self.seg_format2.format(0), self.f_type), ])
[docs] def test_delete_many_preserved(self): self.assertDeleteOrder([ self.make_file_with_data(self.seg_format.format(0), self.f_type), self.make_file_with_data(self.seg_format.format(1), self.f_type, preserve_xattr=deleter.PRESERVE_ATTR_VALUE), self.make_file_with_data(self.seg_format.format(2), self.f_type), ] + [ self.make_file_with_data(self.seg_format2.format(i), self.f_type, preserve_xattr=deleter.PRESERVE_ATTR_VALUE) for i in range(5) ])
[docs] def test_delete_last(self): self.assertDeleteOrder([ self.make_file_with_data(self.seg_format.format(1), self.f_type), self.make_file_with_data(self.seg_format2.format(0), self.f_type), self.make_file_with_data(self.seg_format.format(0), self.f_type, preserve_xattr=deleter.PRESERVE_ATTR_VALUE), self.make_file_with_data("boot", self.seg_format[:-4]), self.make_file_with_data("crash", self.seg_format2[:-4]), ])
[docs] def test_no_delete_when_available_space(self): f_path = self.make_file_with_data(self.seg_dir, self.f_type) block_size = 4096 available = (10 * 1024 * 1024 * 1024) / block_size # 10GB free self.fake_stats = Stats(f_bavail=available, f_blocks=10, f_frsize=block_size) self.start_thread() start_time = time.monotonic() while f_path.exists() and time.monotonic() - start_time < 2: time.sleep(0.01) self.join_thread() self.assertTrue(f_path.exists(), "File deleted with available space")
[docs] def test_no_delete_with_lock_file(self): f_path = self.make_file_with_data(self.seg_dir, self.f_type, lock=True) self.start_thread() start_time = time.monotonic() while f_path.exists() and time.monotonic() - start_time < 2: time.sleep(0.01) self.join_thread() self.assertTrue(f_path.exists(), "File deleted when locked")
if __name__ == "__main__": unittest.main()