Background compiles give way to the lander: the Logbook statistics and the results refresher wait while [logbook] lander_lock is fresh (under 60 min); the statistics tools run below normal priority and a timeout ends the whole tree (an orphaned cl.exe went on compiling main at normal priority); a retried statistics run no longer relogs the same commits

This commit is contained in:
KeelrLeek committed 2026-10-09 10:46:40 -05:00
1 parent 21b7fedb6f
commit 56308e3aab
5 files changed
+154 -14

No files matched your search

+48
View File
@@ -58,6 +58,54 @@ class LogbookAuto(HarborCase):
self.assertTrue(entry["at"].endswith("Z"))
self.assertFalse(logbook_auto.refresh(self.h.project)["changed"])
def test_waits_for_the_lander_and_a_failed_stats_run_logs_nothing_twice(self):
import os
import time
from unittest import mock
logbook_auto._save_state(self.h.project, {"last_head": self.first})
lock = self.dir / "lander-busy.lock"
lock.write_text("x", encoding="utf-8")
self.h.project.logbook.update(lander_lock=str(lock), stats_repo=str(self.dir / "stats"))
out = logbook_auto.refresh(self.h.project)
self.assertFalse(out["changed"])
self.assertIn("lander", out["waiting"])
self.assertEqual(logbook.read_all(self.h.project)["log"], [])
old = time.time() - 61 * 60
os.utime(lock, (old, old)) # stale: ignored
with mock.patch.object(logbook_auto, "rebuild_stats", side_effect=RuntimeError("timed out")):
out = logbook_auto.refresh(self.h.project)
self.assertEqual((out["entries"], out["stats_error"]), (1, "timed out"))
again = logbook_auto.refresh(self.h.project) # the statistics are retried ...
self.assertIn("stats_error", again)
self.assertNotIn("entries", again) # ... but the commit is not relogged
self.assertEqual(len(logbook.read_all(self.h.project)["log"]), 1)
class LanderGate(unittest.TestCase):
def test_run_low_lowers_priority_and_ends_the_tree_on_timeout(self):
import os
import sys
import time
from harbor import lander_gate
script = "import subprocess, sys, time; subprocess.Popen([sys.executable, '-c', 'import time; time.sleep(60)']);" \
" print('ok', flush=True); time.sleep(60)"
from unittest import mock
seen = {}
real = subprocess.Popen
def popen(argv, **kw):
seen.update(kw)
return real([sys.executable, "-c", "pass"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
with mock.patch.object(lander_gate.subprocess, "Popen", popen):
self.assertEqual(lander_gate.run_low(["x"], 60).returncode, 0)
if os.name == "nt":
self.assertTrue(seen["creationflags"] & subprocess.BELOW_NORMAL_PRIORITY_CLASS)
start = time.monotonic()
with self.assertRaises(subprocess.TimeoutExpired):
lander_gate.run_low([sys.executable, "-c", script], 3)
self.assertLess(time.monotonic() - start, 45) # the grandchild did not hold the pipes
class ProgressMapTests(HarborCase):
"""GET /api/logbook/progress-map: units, tiers and the headline, by the Logbook's own definitions."""