loggerd: speedup unit tests (#31115)

* first speed it up

* pytestify

* no sleep
old-commit-hash: 694fc378dd
chrysler-long2
Adeeb Shihadeh 1 year ago committed by GitHub
parent 4080bec11d
commit dc6a23a1bc
  1. 53
      system/loggerd/tests/test_loggerd.py

@ -5,7 +5,6 @@ import random
import string import string
import subprocess import subprocess
import time import time
import unittest
from collections import defaultdict from collections import defaultdict
from pathlib import Path from pathlib import Path
from typing import Dict, List from typing import Dict, List
@ -31,10 +30,7 @@ CEREAL_SERVICES = [f for f in log.Event.schema.union_fields if f in SERVICE_LIST
and SERVICE_LIST[f].should_log and "encode" not in f.lower()] and SERVICE_LIST[f].should_log and "encode" not in f.lower()]
class TestLoggerd(unittest.TestCase): class TestLoggerd:
def setUp(self):
os.environ.pop("LOG_ROOT", None)
def _get_latest_log_dir(self): def _get_latest_log_dir(self):
log_dirs = sorted(Path(Paths.log_root()).iterdir(), key=lambda f: f.stat().st_mtime) log_dirs = sorted(Path(Paths.log_root()).iterdir(), key=lambda f: f.stat().st_mtime)
return log_dirs[-1] return log_dirs[-1]
@ -68,21 +64,21 @@ class TestLoggerd(unittest.TestCase):
def _check_init_data(self, msgs): def _check_init_data(self, msgs):
msg = msgs[0] msg = msgs[0]
self.assertEqual(msg.which(), 'initData') assert msg.which() == 'initData'
def _check_sentinel(self, msgs, route): def _check_sentinel(self, msgs, route):
start_type = SentinelType.startOfRoute if route else SentinelType.startOfSegment start_type = SentinelType.startOfRoute if route else SentinelType.startOfSegment
self.assertTrue(msgs[1].sentinel.type == start_type) assert msgs[1].sentinel.type == start_type
end_type = SentinelType.endOfRoute if route else SentinelType.endOfSegment end_type = SentinelType.endOfRoute if route else SentinelType.endOfSegment
self.assertTrue(msgs[-1].sentinel.type == end_type) assert msgs[-1].sentinel.type == end_type
def _publish_random_messages(self, services: List[str]) -> Dict[str, list]: def _publish_random_messages(self, services: List[str]) -> Dict[str, list]:
pm = messaging.PubMaster(services) pm = messaging.PubMaster(services)
managed_processes["loggerd"].start() managed_processes["loggerd"].start()
for s in services: for s in services:
self.assertTrue(pm.wait_for_readers_to_update(s, timeout=5)) assert pm.wait_for_readers_to_update(s, timeout=5)
sent_msgs = defaultdict(list) sent_msgs = defaultdict(list)
for _ in range(random.randint(2, 10) * 100): for _ in range(random.randint(2, 10) * 100):
@ -93,10 +89,9 @@ class TestLoggerd(unittest.TestCase):
m = messaging.new_message(s, random.randint(2, 10)) m = messaging.new_message(s, random.randint(2, 10))
pm.send(s, m) pm.send(s, m)
sent_msgs[s].append(m) sent_msgs[s].append(m)
time.sleep(0.01)
for s in services: for s in services:
self.assertTrue(pm.wait_for_readers_to_update(s, timeout=5)) assert pm.wait_for_readers_to_update(s, timeout=5)
managed_processes["loggerd"].stop() managed_processes["loggerd"].stop()
return sent_msgs return sent_msgs
@ -121,15 +116,15 @@ class TestLoggerd(unittest.TestCase):
lr = list(LogReader(str(self._gen_bootlog()))) lr = list(LogReader(str(self._gen_bootlog())))
initData = lr[0].initData initData = lr[0].initData
self.assertTrue(initData.dirty != bool(os.environ["CLEAN"])) assert initData.dirty != bool(os.environ["CLEAN"])
self.assertEqual(initData.version, get_version()) assert initData.version == get_version()
if os.path.isfile("/proc/cmdline"): if os.path.isfile("/proc/cmdline"):
with open("/proc/cmdline") as f: with open("/proc/cmdline") as f:
self.assertEqual(list(initData.kernelArgs), f.read().strip().split(" ")) assert list(initData.kernelArgs) == f.read().strip().split(" ")
with open("/proc/version") as f: with open("/proc/version") as f:
self.assertEqual(initData.kernelVersion, f.read()) assert initData.kernelVersion == f.read()
# check params # check params
logged_params = {entry.key: entry.value for entry in initData.params.entries} logged_params = {entry.key: entry.value for entry in initData.params.entries}
@ -137,8 +132,8 @@ class TestLoggerd(unittest.TestCase):
assert set(logged_params.keys()) == expected_params, set(logged_params.keys()) ^ expected_params assert set(logged_params.keys()) == expected_params, set(logged_params.keys()) ^ expected_params
assert logged_params['AccessToken'] == b'', f"DONT_LOG param value was logged: {repr(logged_params['AccessToken'])}" assert logged_params['AccessToken'] == b'', f"DONT_LOG param value was logged: {repr(logged_params['AccessToken'])}"
for param_key, initData_key, v in fake_params: for param_key, initData_key, v in fake_params:
self.assertEqual(getattr(initData, initData_key), v) assert getattr(initData, initData_key) == v
self.assertEqual(logged_params[param_key].decode(), v) assert logged_params[param_key].decode() == v
params.put("AccessToken", "") params.put("AccessToken", "")
@ -162,11 +157,10 @@ class TestLoggerd(unittest.TestCase):
os.environ["LOGGERD_SEGMENT_LENGTH"] = str(length) os.environ["LOGGERD_SEGMENT_LENGTH"] = str(length)
managed_processes["loggerd"].start() managed_processes["loggerd"].start()
managed_processes["encoderd"].start() managed_processes["encoderd"].start()
time.sleep(1) assert pm.wait_for_readers_to_update("roadCameraState", timeout=5)
fps = 20.0 fps = 20.0
for n in range(1, int(num_segs*length*fps)+1): for n in range(1, int(num_segs*length*fps)+1):
time_start = time.monotonic()
for stream_type, frame_spec, state in streams: for stream_type, frame_spec, state in streams:
dat = np.empty(frame_spec[2], dtype=np.uint8) dat = np.empty(frame_spec[2], dtype=np.uint8)
vipc_server.send(stream_type, dat[:].flatten().tobytes(), n, n/fps, n/fps) vipc_server.send(stream_type, dat[:].flatten().tobytes(), n, n/fps, n/fps)
@ -175,7 +169,9 @@ class TestLoggerd(unittest.TestCase):
frame = getattr(camera_state, state) frame = getattr(camera_state, state)
frame.frameId = n frame.frameId = n
pm.send(state, camera_state) pm.send(state, camera_state)
time.sleep(max((1.0/fps) - (time.monotonic() - time_start), 0))
for _, _, state in streams:
assert pm.wait_for_readers_to_update(state, timeout=5, dt=0.001)
managed_processes["loggerd"].stop() managed_processes["loggerd"].stop()
managed_processes["encoderd"].stop() managed_processes["encoderd"].stop()
@ -185,7 +181,7 @@ class TestLoggerd(unittest.TestCase):
p = Path(f"{route_path}--{n}") p = Path(f"{route_path}--{n}")
logged = {f.name for f in p.iterdir() if f.is_file()} logged = {f.name for f in p.iterdir() if f.is_file()}
diff = logged ^ expected_files diff = logged ^ expected_files
self.assertEqual(len(diff), 0, f"didn't get all expected files. run={_} seg={n} {route_path=}, {diff=}\n{logged=} {expected_files=}") assert len(diff) == 0, f"didn't get all expected files. run={_} seg={n} {route_path=}, {diff=}\n{logged=} {expected_files=}"
def test_bootlog(self): def test_bootlog(self):
# generate bootlog with fake launch log # generate bootlog with fake launch log
@ -216,7 +212,7 @@ class TestLoggerd(unittest.TestCase):
with open(path, "rb") as f: with open(path, "rb") as f:
expected_val = f.read() expected_val = f.read()
bootlog_val = [e.value for e in boot.pstore.entries if e.key == fn][0] bootlog_val = [e.value for e in boot.pstore.entries if e.key == fn][0]
self.assertEqual(expected_val, bootlog_val) assert expected_val == bootlog_val
def test_qlog(self): def test_qlog(self):
qlog_services = [s for s in CEREAL_SERVICES if SERVICE_LIST[s].decimation is not None] qlog_services = [s for s in CEREAL_SERVICES if SERVICE_LIST[s].decimation is not None]
@ -242,11 +238,11 @@ class TestLoggerd(unittest.TestCase):
if s in no_qlog_services: if s in no_qlog_services:
# check services with no specific decimation aren't in qlog # check services with no specific decimation aren't in qlog
self.assertEqual(recv_cnt, 0, f"got {recv_cnt} {s} msgs in qlog") assert recv_cnt == 0, f"got {recv_cnt} {s} msgs in qlog"
else: else:
# check logged message count matches decimation # check logged message count matches decimation
expected_cnt = (len(msgs) - 1) // SERVICE_LIST[s].decimation + 1 expected_cnt = (len(msgs) - 1) // SERVICE_LIST[s].decimation + 1
self.assertEqual(recv_cnt, expected_cnt, f"expected {expected_cnt} msgs for {s}, got {recv_cnt}") assert recv_cnt == expected_cnt, f"expected {expected_cnt} msgs for {s}, got {recv_cnt}"
def test_rlog(self): def test_rlog(self):
services = random.sample(CEREAL_SERVICES, random.randint(5, 10)) services = random.sample(CEREAL_SERVICES, random.randint(5, 10))
@ -263,22 +259,19 @@ class TestLoggerd(unittest.TestCase):
for m in lr: for m in lr:
sent = sent_msgs[m.which()].pop(0) sent = sent_msgs[m.which()].pop(0)
sent.clear_write_flag() sent.clear_write_flag()
self.assertEqual(sent.to_bytes(), m.as_builder().to_bytes()) assert sent.to_bytes() == m.as_builder().to_bytes()
def test_preserving_flagged_segments(self): def test_preserving_flagged_segments(self):
services = set(random.sample(CEREAL_SERVICES, random.randint(5, 10))) | {"userFlag"} services = set(random.sample(CEREAL_SERVICES, random.randint(5, 10))) | {"userFlag"}
self._publish_random_messages(services) self._publish_random_messages(services)
segment_dir = self._get_latest_log_dir() segment_dir = self._get_latest_log_dir()
self.assertEqual(getxattr(segment_dir, PRESERVE_ATTR_NAME), PRESERVE_ATTR_VALUE) assert getxattr(segment_dir, PRESERVE_ATTR_NAME) == PRESERVE_ATTR_VALUE
def test_not_preserving_unflagged_segments(self): def test_not_preserving_unflagged_segments(self):
services = set(random.sample(CEREAL_SERVICES, random.randint(5, 10))) - {"userFlag"} services = set(random.sample(CEREAL_SERVICES, random.randint(5, 10))) - {"userFlag"}
self._publish_random_messages(services) self._publish_random_messages(services)
segment_dir = self._get_latest_log_dir() segment_dir = self._get_latest_log_dir()
self.assertIsNone(getxattr(segment_dir, PRESERVE_ATTR_NAME)) assert getxattr(segment_dir, PRESERVE_ATTR_NAME) is None
if __name__ == "__main__":
unittest.main()

Loading…
Cancel
Save