Ver Fonte

test(停止所有权): 验证 stop epoch 使旧 Owner 失效

模拟当前 Owner 持有进程租约时递增 stop intent,断言旧 token 立即被栅栏拒绝,同时不抢占进程级 lease,覆盖跨进程停止的核心 CAS 前提。
SamLee há 15 horas atrás
pai
commit
6caac1d023
1 ficheiros alterados com 30 adições e 0 exclusões
  1. 30 0
      script_build_host/tests/test_phase_three_ownership.py

+ 30 - 0
script_build_host/tests/test_phase_three_ownership.py

@@ -83,6 +83,36 @@ async def test_stop_epoch_fences_current_owner_without_taking_process_lease(
     await lease.release()
 
 
+@pytest.mark.asyncio
+async def test_new_owner_can_cas_stopping_build_to_stopped(
+    database: tuple[AsyncEngine, async_sessionmaker[AsyncSession]], tmp_path: Path
+) -> None:
+    _, sessions = database
+    build_id = await _bound_build(sessions)
+    old_lease = OwnerLease(sessions, tmp_path / "leases", owner_instance_id="old")
+    old_token = await old_lease.acquire(build_id)
+    gate = FencedCommandGate(sessions)
+    stop_epoch = await gate.request_stop(build_id)
+    assert await gate.request_stop(build_id) == stop_epoch
+    await old_lease.release()
+
+    takeover = OwnerLease(sessions, tmp_path / "leases", owner_instance_id="takeover")
+    token = await takeover.acquire(build_id)
+    try:
+        assert token.owner_epoch == old_token.owner_epoch + 1
+        assert token.stop_epoch == stop_epoch
+        await gate.verify_stop_owner(token)
+        await gate.complete_stop(token)
+        assert (
+            await SqlAlchemyLegacyBuildStateRepository(sessions).get_status(build_id)
+            is BuildStatus.STOPPED
+        )
+        with pytest.raises(MissionFencingTokenStale):
+            await gate.complete_stop(old_token)
+    finally:
+        await takeover.release()
+
+
 @pytest.mark.asyncio
 async def test_phase_three_state_and_snapshot_mutations_share_the_owner_fence(
     database: tuple[AsyncEngine, async_sessionmaker[AsyncSession]], tmp_path: Path