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:
1 parent
21b7fedb6f
commit
56308e3aab
5 files changed
+154
-14
No files matched your search
@@ -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."""
|
||||
|
||||
Reference in new issue
Block a user