|
6 | 6 |
|
7 | 7 |
|
8 | 8 | def _mock_session(*inputs): |
9 | | - """Return a PromptSession mock whose .prompt() yields inputs in order.""" |
| 9 | + """Return a PromptSession mock whose .prompt_async() yields inputs in order.""" |
| 10 | + |
10 | 11 | session = MagicMock() |
| 12 | + |
| 13 | + async def _async_side_effect(*args, **kwargs): |
| 14 | + val = inputs_side_effect.pop(0) |
| 15 | + if isinstance(val, BaseException): |
| 16 | + raise val |
| 17 | + return val |
| 18 | + |
| 19 | + inputs_side_effect = list(inputs) |
| 20 | + session.prompt_async = MagicMock(side_effect=_async_side_effect) |
| 21 | + # Keep .prompt() too in case anything still references it |
11 | 22 | session.prompt.side_effect = list(inputs) |
12 | 23 | return session |
13 | 24 |
|
@@ -280,9 +291,31 @@ def test_main_token_refresh( |
280 | 291 | self, mock_ps, mock_chat, mock_cp, mock_load, mock_http |
281 | 292 | ): |
282 | 293 | mock_ps.return_value = _mock_session("hello", ".exit") |
| 294 | + # asyncio.run() calls time.monotonic() internally (shutdown_asyncgens |
| 295 | + # etc.), and since patch("iclaw.main.time.monotonic") patches the real |
| 296 | + # time.monotonic globally, those internal calls consume side_effect |
| 297 | + # entries too. Use a callable that tracks call count so we can |
| 298 | + # control exactly which value the application code sees. |
| 299 | + # |
| 300 | + # We need: startup monotonic() returns a low value T so that |
| 301 | + # token_expiry = T + TOKEN_REFRESH_INTERVAL |
| 302 | + # and later monotonic() returns a value >= token_expiry to trigger |
| 303 | + # refresh. asyncio internals may consume 0-2 calls before the app |
| 304 | + # code runs. |
| 305 | + call_count = {"n": 0} |
| 306 | + |
| 307 | + def _monotonic(): |
| 308 | + call_count["n"] += 1 |
| 309 | + # First few calls may be asyncio internals; return 0 for them |
| 310 | + # and for the startup call. Once we've had at least 2 calls |
| 311 | + # (startup done), switch to 99999 so the expiry check triggers. |
| 312 | + if call_count["n"] <= 2: |
| 313 | + return 0 |
| 314 | + return 99999 |
| 315 | + |
283 | 316 | with ( |
284 | 317 | patch("sys.stdout"), |
285 | | - patch("iclaw.main.time.monotonic", side_effect=[0, 99999, 99999, 99999]), |
| 318 | + patch("iclaw.main.time.monotonic", side_effect=_monotonic), |
286 | 319 | ): |
287 | 320 | main.main() |
288 | 321 | # get_copilot_token called twice: once at startup, once on refresh |
|
0 commit comments