Spaces:
Paused
Paused
| import asyncio | |
| import json | |
| import os | |
| import sys | |
| from unittest.mock import AsyncMock, MagicMock, patch | |
| import pytest | |
| # Add repository root to sys.path | |
| sys.path.append(os.getcwd()) | |
| import browser_utils.operations # Import to ensure we can patch it | |
| from api_utils.response_generators import gen_sse_from_aux_stream | |
| from config.global_state import GlobalState | |
| from models import ChatCompletionRequest, Message | |
| # Mock ChatCompletionRequest | |
| def create_mock_request(): | |
| # Helper to create a dummy request object | |
| return ChatCompletionRequest( | |
| messages=[Message(role="user", content="test")], | |
| model="test-model" | |
| ) | |
| async def mock_use_stream_response(req_id, timeout=5.0, page=None, check_client_disconnected=None, enable_silence_detection=True): | |
| # Simulate empty stream that finishes immediately | |
| yield json.dumps({"done": True}) | |
| async def mock_check_quota_limit(page, req_id): | |
| print(f"DEBUG: mock_check_quota_limit called for {req_id}") | |
| # Simulate finding a quota error and setting the flag | |
| GlobalState.IS_QUOTA_EXCEEDED = True | |
| return | |
| async def test_quota_fix_logic(): | |
| print("Starting test_quota_fix") | |
| # Reset GlobalState | |
| GlobalState.IS_QUOTA_EXCEEDED = False | |
| GlobalState.IS_RECOVERING = False | |
| # Mock dependencies | |
| mock_page = AsyncMock() | |
| mock_event = asyncio.Event() | |
| mock_check_disconnect = MagicMock() | |
| # Patch dependencies | |
| # 1. Patch use_stream_response where it is used in response_generators | |
| # 2. Patch check_quota_limit in browser_utils.operations so the import inside the function gets the mock | |
| with patch('api_utils.response_generators.use_stream_response', side_effect=mock_use_stream_response), \ | |
| patch.object(browser_utils.operations, 'check_quota_limit', side_effect=mock_check_quota_limit): | |
| generator = gen_sse_from_aux_stream( | |
| req_id="test_req", | |
| request=create_mock_request(), | |
| model_name_for_stream="test-model", | |
| check_client_disconnected=mock_check_disconnect, | |
| event_to_set=mock_event, | |
| timeout=10.0, | |
| page=mock_page | |
| ) | |
| items = [] | |
| try: | |
| # Iterate through the generator | |
| # We expect it to yield heartbeats after setting the quota flag | |
| async for item in generator: | |
| print(f"Received item: {item.strip()[:100]}...") # Print first 100 chars | |
| items.append(item) | |
| if ": heartbeat" in item: | |
| print("Verified: Received heartbeat.") | |
| # We entered the holding pattern! Break loop to finish test. | |
| break | |
| if "Model finished thinking but generated no code/text output" in item: | |
| print("FAILURE: Received fallback text.") | |
| break | |
| # Safety break to prevent infinite loops if logic is wrong | |
| if len(items) > 20: | |
| print("FAILURE: Loop limit reached without heartbeat.") | |
| break | |
| except Exception as e: | |
| print(f"Exception during generation: {e}") | |
| import traceback | |
| traceback.print_exc() | |
| # --- Assertions --- | |
| print("\n--- Assertions ---") | |
| # 1. Assert GlobalState is updated | |
| if GlobalState.IS_QUOTA_EXCEEDED: | |
| print("PASS: GlobalState.IS_QUOTA_EXCEEDED is True") | |
| else: | |
| print("FAIL: GlobalState.IS_QUOTA_EXCEEDED is False") | |
| sys.exit(1) | |
| # 2. Assert NO fallback text | |
| has_fallback = any("Model finished thinking" in item for item in items) | |
| if not has_fallback: | |
| print("PASS: Fallback text was NOT sent") | |
| else: | |
| print("FAIL: Fallback text WAS sent") | |
| sys.exit(1) | |
| # 3. Assert heartbeat received | |
| has_heartbeat = any(": heartbeat" in item for item in items) | |
| if has_heartbeat: | |
| print("PASS: Heartbeat signal received") | |
| else: | |
| print("FAIL: Heartbeat signal NOT received") | |
| sys.exit(1) | |
| print("\nSUCCESS: All criteria met. Quota fix verified.") | |
| if __name__ == "__main__": | |
| loop = asyncio.new_event_loop() | |
| asyncio.set_event_loop(loop) | |
| try: | |
| loop.run_until_complete(test_quota_fix_logic()) | |
| finally: | |
| loop.close() | |