Grotti 3.6.0: Lauf-Identität nach Filament-Pause, robustere Queue, Projekte/Aufträge list-first und API-Polish.

This commit is contained in:
Dominic Gundel committed 2026-10-25 08:24:24 +01:00
1 parent d1eb87ba25
commit 2b1e36634a
53 files changed
+4254 -636

No files matched your search

+41 -1
View File
@@ -8,7 +8,15 @@ from unittest import mock
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT))
from grotti.print_queue import PRINT_START_TIMEOUT_S, PrintQueueDispatcher, _cool_wait_text
from datetime import datetime, timedelta, timezone
from grotti.jobs import is_filament_resume
from grotti.print_queue import (
PRINT_START_TIMEOUT_S,
TERMINAL_CONFIRM_HITS,
PrintQueueDispatcher,
_cool_wait_text,
)
class CoolTextTests(unittest.TestCase):
@@ -20,9 +28,26 @@ class CoolTextTests(unittest.TestCase):
self.assertNotIn(" · ", text)
class FilamentResumeTests(unittest.TestCase):
def test_same_moment_with_duration_is_resume(self):
end = datetime(2026, 10, 21, 19, 32, 20, tzinfo=timezone.utc)
start = end + timedelta(milliseconds=40)
self.assertTrue(is_filament_resume(
end, start, prev_duration_s=500, new_duration_s=520
))
def test_later_reprint_is_not_resume(self):
end = datetime(2026, 10, 21, 19, 32, 20, tzinfo=timezone.utc)
start = end + timedelta(minutes=10)
self.assertFalse(is_filament_resume(
end, start, prev_duration_s=500, new_duration_s=10
))
class DispatcherHelpers(unittest.TestCase):
def test_timeout_constant(self):
self.assertGreaterEqual(PRINT_START_TIMEOUT_S, 300)
self.assertGreaterEqual(TERMINAL_CONFIRM_HITS, 2)
def test_worker_busy_empty(self):
d = PrintQueueDispatcher("postgresql://x", {}, watcher=None)
@@ -34,6 +59,21 @@ class DispatcherHelpers(unittest.TestCase):
d.cfg = {"auto_queue": False}
self.assertFalse(d._auto_enabled())
def test_no_retry_after_abort(self):
d = PrintQueueDispatcher("postgresql://x", {}, watcher=None)
self.assertFalse(d._retryable_message("Druck abgebrochen."))
self.assertTrue(d._retryable_message("Start-Timeout"))
def test_advance_simple_ignores_single_cancelled(self):
d = PrintQueueDispatcher("postgresql://x", {}, watcher=None)
item = {"id": 1, "phase": "print_active", "filename": "a.gcode"}
printer = {"host": "h", "name": "P"}
live = {"state": "cancelled", "print_active": False}
with mock.patch("grotti.print_queue.store.update_print_queue") as upd:
d._advance_simple(mock.Mock(), item, printer, live)
upd.assert_not_called()
self.assertEqual(d._term_hits.get("1:end"), 1)
class ResolveSpoolTests(unittest.TestCase):
def test_material_match(self):