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:
1 parent
d1eb87ba25
commit
2b1e36634a
53 files changed
+4254
-636
No files matched your search
@@ -0,0 +1,79 @@
|
||||
"""Szenarien für einen physischen Druck = ein Lauf (ohne DB, mit Mocks)."""
|
||||
|
||||
import os
|
||||
import unittest
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from grotti import jobs
|
||||
|
||||
|
||||
class SyncOneJobShellTests(unittest.TestCase):
|
||||
def test_empty_shell_skipped(self):
|
||||
conn = MagicMock()
|
||||
printer = {"host": "h", "name": "P"}
|
||||
job = {
|
||||
"job_id": "000041",
|
||||
"filename": "a.gcode",
|
||||
"status": "in_progress",
|
||||
"start_time": 1000,
|
||||
"end_time": None,
|
||||
"print_duration": 0,
|
||||
"total_duration": 0,
|
||||
"metadata": {},
|
||||
}
|
||||
self.assertEqual(jobs._sync_one_job(conn, {"energy": {}}, printer, job), 0)
|
||||
conn.execute.assert_not_called()
|
||||
|
||||
|
||||
class FoldProofIntegrationLike(unittest.TestCase):
|
||||
def test_fold_requires_duration_proof(self):
|
||||
end = datetime(2026, 10, 25, 5, 48, 27, tzinfo=timezone.utc)
|
||||
start = end + timedelta(milliseconds=40)
|
||||
pred = {
|
||||
"id": 1,
|
||||
"ended_at": end,
|
||||
"duration_s": 11711,
|
||||
"moonraker_job_id": "000040",
|
||||
"verdict": "",
|
||||
}
|
||||
conn = MagicMock()
|
||||
conn.execute.return_value.fetchone.return_value = None
|
||||
with patch("grotti.jobs.store.find_resume_predecessor", return_value=pred), \
|
||||
patch("grotti.jobs.store.remember_run_job"), \
|
||||
patch("grotti.jobs.store.move_run_jobs"), \
|
||||
patch("grotti.jobs.store.set_printer_active_run"), \
|
||||
patch("grotti.jobs.undo_deduction"):
|
||||
# Frischer Neustart (Dauer 12) — kein Fold
|
||||
self.assertIsNone(jobs.fold_filament_resume(
|
||||
conn, "h", "a.gcode", "000041", start, print_duration_s=12
|
||||
))
|
||||
# Fortgesetzte Dauer — Fold
|
||||
self.assertEqual(
|
||||
jobs.fold_filament_resume(
|
||||
conn, "h", "a.gcode", "000041", start, print_duration_s=11711
|
||||
),
|
||||
1,
|
||||
)
|
||||
|
||||
|
||||
@unittest.skipUnless(os.environ.get("GROTTI_TEST_DB"), "GROTTI_TEST_DB nicht gesetzt")
|
||||
class LiveDbScenarios(unittest.TestCase):
|
||||
"""Gegen echte Test-DB: GROTTI_TEST_DB=postgresql://…"""
|
||||
|
||||
def setUp(self):
|
||||
import psycopg
|
||||
from psycopg.rows import dict_row
|
||||
|
||||
self.conn = psycopg.connect(os.environ["GROTTI_TEST_DB"], row_factory=dict_row)
|
||||
|
||||
def tearDown(self):
|
||||
self.conn.rollback()
|
||||
self.conn.close()
|
||||
|
||||
def test_connection(self):
|
||||
self.assertTrue(self.conn.execute("SELECT 1").fetchone())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user