You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
124 lines
4.1 KiB
124 lines
4.1 KiB
#!/usr/bin/env python3
|
|
import time
|
|
import threading
|
|
import unittest
|
|
from collections import namedtuple
|
|
from pathlib import Path
|
|
from typing 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'])
|
|
|
|
|
|
class TestDeleter(UploaderTestCase):
|
|
def fake_statvfs(self, d):
|
|
return self.fake_stats
|
|
|
|
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
|
|
deleter.ROOT = str(self.root)
|
|
|
|
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()
|
|
|
|
def join_thread(self):
|
|
self.end_event.set()
|
|
self.del_thread.join()
|
|
|
|
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()
|
|
|
|
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")
|
|
|
|
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),
|
|
])
|
|
|
|
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)
|
|
])
|
|
|
|
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]),
|
|
])
|
|
|
|
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")
|
|
|
|
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()
|
|
|