()
| 28 | raise |
| 29 | |
| 30 | async def test_shutdown_interruption(): |
| 31 | logger.info("Starting test_shutdown_interruption...") |
| 32 | |
| 33 | # Reset event just in case |
| 34 | GlobalState.IS_SHUTTING_DOWN.clear() |
| 35 | |
| 36 | # 1. Start the long running task (simulating waiting for element) |
| 37 | # Simulating 35000ms timeout like in the real code |
| 38 | expect_task = asyncio.create_task(mock_expect_async_visible(timeout=35000)) |
| 39 | |
| 40 | # 2. Start the shutdown waiter |
| 41 | shutdown_task = asyncio.create_task(_wait_for_shutdown()) |
| 42 | |
| 43 | # 3. Schedule the shutdown event trigger in 2 seconds (simulating user Ctrl+C) |
| 44 | def trigger_shutdown(): |
| 45 | logger.info("Simulating Ctrl+C (waiting 2s then setting IS_SHUTTING_DOWN)...") |
| 46 | time.sleep(2) |
| 47 | GlobalState.IS_SHUTTING_DOWN.set() |
| 48 | logger.info("IS_SHUTTING_DOWN set.") |
| 49 | |
| 50 | # Run trigger in a separate thread to simulate external signal/event |
| 51 | trigger_thread = threading.Thread(target=trigger_shutdown) |
| 52 | trigger_thread.start() |
| 53 | |
| 54 | start_time = time.time() |
| 55 | |
| 56 | # 4. Wait for FIRST_COMPLETED |
| 57 | logger.info("Waiting for tasks...") |
| 58 | done, pending = await asyncio.wait([expect_task, shutdown_task], return_when=asyncio.FIRST_COMPLETED) |
| 59 | |
| 60 | end_time = time.time() |
| 61 | duration = end_time - start_time |
| 62 | logger.info(f"Await finished in {duration:.2f} seconds.") |
| 63 | |
| 64 | if shutdown_task in done: |
| 65 | logger.info("🛑 Shutdown signal received during initialization. Aborting.") |
| 66 | expect_task.cancel() |
| 67 | try: |
| 68 | await expect_task |
| 69 | except asyncio.CancelledError: |
| 70 | pass |
| 71 | logger.info("Verified: expect_task cancelled successfully.") |
| 72 | |
| 73 | if duration < 5.0: |
| 74 | logger.info("✅ SUCCESS: Test completed quickly (well under 35s). Fix verified.") |
| 75 | else: |
| 76 | logger.error("❌ FAILURE: Test took too long.") |
| 77 | raise RuntimeError("Test failed: took too long") |
| 78 | else: |
| 79 | logger.error("❌ FAILURE: expect_task finished first (unexpected).") |
| 80 | raise RuntimeError("Test failed: expect_task finished first") |
| 81 | |
| 82 | # Wait for trigger thread to ensure clean exit |
| 83 | trigger_thread.join() |
| 84 | |
| 85 | if __name__ == "__main__": |
| 86 | asyncio.run(test_shutdown_interruption()) |
no test coverage detected