mirror of
https://github.com/hansjone/netx.git
synced 2026-10-09 02:00:46 +08:00
Add collect stop, cutover nav prefetch/cache, and lane labels.
Let operators abort queued/running biz_state batches, speed cutover page switches, and show light/heavy collect lanes on monitor items. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
305822aa4f
commit
924f9bd2f7
16 changed files with 779 additions and 112 deletions
111
tests/test_biz_state_collect_stop.py
Normal file
111
tests/test_biz_state_collect_stop.py
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
"""biz_state collect stop: cancel queued / signal running."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from sqlalchemy.pool import StaticPool
|
||||
|
||||
from netx_api.biz_state import collect_stop as stop_mod
|
||||
from netx_api.db import Base
|
||||
from netx_api.models import BizStateBatch, BizStateTask
|
||||
|
||||
|
||||
class BizStateCollectStopTests(unittest.TestCase):
|
||||
def setUp(self) -> None:
|
||||
engine = create_engine(
|
||||
"sqlite+pysqlite:///:memory:",
|
||||
future=True,
|
||||
connect_args={"check_same_thread": False},
|
||||
poolclass=StaticPool,
|
||||
)
|
||||
TestingSession = sessionmaker(
|
||||
bind=engine, autoflush=False, autocommit=False, expire_on_commit=False
|
||||
)
|
||||
Base.metadata.create_all(bind=engine)
|
||||
self.Session = TestingSession
|
||||
self.db = TestingSession()
|
||||
self._session_patch = patch.object(stop_mod, "SessionLocal", TestingSession)
|
||||
self._session_patch.start()
|
||||
stop_mod._stop_batches.clear()
|
||||
stop_mod._holders.clear()
|
||||
stop_mod._db_cache.clear()
|
||||
|
||||
self.task = BizStateTask(
|
||||
id="t-stop",
|
||||
source="managed",
|
||||
ne_id="ne-1",
|
||||
ne_name="NE1",
|
||||
status="running",
|
||||
collect_running=True,
|
||||
)
|
||||
self.db.add(self.task)
|
||||
self.db.commit()
|
||||
|
||||
def tearDown(self) -> None:
|
||||
self._session_patch.stop()
|
||||
self.db.close()
|
||||
|
||||
def test_stop_cancels_queued_batch(self) -> None:
|
||||
batch = BizStateBatch(
|
||||
id="b-q",
|
||||
task_id=self.task.id,
|
||||
status="queued",
|
||||
message="queued_manual",
|
||||
)
|
||||
self.db.add(batch)
|
||||
self.db.commit()
|
||||
|
||||
out = stop_mod.request_stop_collect(self.task.id)
|
||||
self.assertTrue(out.get("ok"))
|
||||
self.assertTrue(out.get("stopped"))
|
||||
self.assertEqual(out.get("cancelled_batches"), ["b-q"])
|
||||
self.assertEqual(out.get("signaled_batches"), [])
|
||||
|
||||
self.db.expire_all()
|
||||
b = self.db.get(BizStateBatch, "b-q")
|
||||
t = self.db.get(BizStateTask, self.task.id)
|
||||
assert b is not None and t is not None
|
||||
self.assertEqual(b.status, "cancelled")
|
||||
self.assertEqual(b.message, stop_mod.STOP_USER_MESSAGE)
|
||||
self.assertFalse(t.collect_running)
|
||||
|
||||
def test_stop_signals_running_batch(self) -> None:
|
||||
batch = BizStateBatch(
|
||||
id="b-r",
|
||||
task_id=self.task.id,
|
||||
status="running",
|
||||
message="",
|
||||
)
|
||||
self.db.add(batch)
|
||||
self.db.commit()
|
||||
|
||||
out = stop_mod.request_stop_collect(self.task.id)
|
||||
self.assertTrue(out.get("ok"))
|
||||
self.assertTrue(out.get("stopped"))
|
||||
self.assertEqual(out.get("signaled_batches"), ["b-r"])
|
||||
self.assertTrue(stop_mod.is_stop_requested("b-r"))
|
||||
|
||||
self.db.expire_all()
|
||||
b = self.db.get(BizStateBatch, "b-r")
|
||||
t = self.db.get(BizStateTask, self.task.id)
|
||||
assert b is not None and t is not None
|
||||
self.assertEqual(b.status, "running")
|
||||
self.assertEqual(b.message, stop_mod.STOP_REQUEST_TOKEN)
|
||||
# Still running until worker finishes.
|
||||
self.assertTrue(t.collect_running)
|
||||
|
||||
def test_stop_idle(self) -> None:
|
||||
self.task.collect_running = False
|
||||
self.db.commit()
|
||||
out = stop_mod.request_stop_collect(self.task.id)
|
||||
self.assertTrue(out.get("ok"))
|
||||
self.assertFalse(out.get("stopped"))
|
||||
self.assertEqual(out.get("reason"), "not_collecting")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue