|
13 | 13 | from pathlib import Path
|
14 | 14 | from typing import Any, Dict, Final, Generator, Mapping, Literal, Optional
|
15 | 15 | from unittest.mock import patch
|
| 16 | +import requests |
16 | 17 |
|
17 | 18 | import pytest
|
18 | 19 | from ci_tools.variables import in_ci
|
@@ -301,7 +302,9 @@ def redirect_openai_requests():
|
301 | 302 |
|
302 | 303 |
|
303 | 304 | @pytest.fixture
|
304 |
| -def recorded_test(recorded_test, redirect_openai_requests, redirect_asyncio_requests_traffic): |
| 305 | +def recorded_test( |
| 306 | + recorded_test, redirect_openai_requests, redirect_asyncio_requests_traffic, mock_azure_management_api |
| 307 | +): |
305 | 308 | return recorded_test
|
306 | 309 |
|
307 | 310 |
|
@@ -628,3 +631,58 @@ def run_from_temp_dir(tmp_path):
|
628 | 631 | os.chdir(tmp_path)
|
629 | 632 | yield
|
630 | 633 | os.chdir(original_cwd)
|
| 634 | + |
| 635 | + |
| 636 | +@pytest.fixture |
| 637 | +def mock_azure_management_api(project_scope: dict): |
| 638 | + """Mock Azure Management API calls for service discovery during playback mode.""" |
| 639 | + if is_live(): |
| 640 | + # In live mode, let the real API calls go through |
| 641 | + yield |
| 642 | + return |
| 643 | + |
| 644 | + # Mock response for the Azure Management API workspace discovery call |
| 645 | + mock_response_data = { |
| 646 | + "id": f"/subscriptions/{project_scope['subscription_id']}/resourceGroups/{project_scope['resource_group_name']}/providers/Microsoft.MachineLearningServices/workspaces/{project_scope['project_name']}", |
| 647 | + "name": project_scope["project_name"], |
| 648 | + "type": "Microsoft.MachineLearningServices/workspaces", |
| 649 | + "location": "swedencentral", |
| 650 | + "properties": { |
| 651 | + "discoveryUrl": "https://swedencentral.api.azureml.ms", |
| 652 | + "mlFlowTrackingUri": f"https://swedencentral.api.azureml.ms/mlflow/v1.0/subscriptions/{project_scope['subscription_id']}/resourceGroups/{project_scope['resource_group_name']}/providers/Microsoft.MachineLearningServices/workspaces/{project_scope['project_name']}", |
| 653 | + "workspaceId": project_scope["subscription_id"], |
| 654 | + "friendlyName": project_scope["project_name"], |
| 655 | + "description": "Test workspace for Azure AI evaluation", |
| 656 | + "keyVault": f"/subscriptions/{project_scope['subscription_id']}/resourceGroups/{project_scope['resource_group_name']}/providers/Microsoft.KeyVault/vaults/kv-{project_scope['project_name']}", |
| 657 | + "applicationInsights": f"/subscriptions/{project_scope['subscription_id']}/resourceGroups/{project_scope['resource_group_name']}/providers/Microsoft.Insights/components/ai-{project_scope['project_name']}", |
| 658 | + "storageAccount": f"/subscriptions/{project_scope['subscription_id']}/resourceGroups/{project_scope['resource_group_name']}/providers/Microsoft.Storage/storageAccounts/st{project_scope['project_name']}", |
| 659 | + }, |
| 660 | + } |
| 661 | + |
| 662 | + class MockResponse: |
| 663 | + def __init__(self, json_data, status_code): |
| 664 | + self.json_data = json_data |
| 665 | + self.status_code = status_code |
| 666 | + |
| 667 | + def json(self): |
| 668 | + return self.json_data |
| 669 | + |
| 670 | + def mock_requests_get(url, **kwargs): |
| 671 | + # Check if this is an Azure Management API call for workspace discovery |
| 672 | + if ( |
| 673 | + "management.azure.com" in url |
| 674 | + and "Microsoft.MachineLearningServices/workspaces" in url |
| 675 | + and "api-version=" in url |
| 676 | + ): |
| 677 | + return MockResponse(mock_response_data, 200) |
| 678 | + |
| 679 | + # For any other requests, call the original function |
| 680 | + # This preserves other functionality while only mocking the specific API we need |
| 681 | + return original_requests_get(url, **kwargs) |
| 682 | + |
| 683 | + # Store the original requests.get function |
| 684 | + original_requests_get = requests.get |
| 685 | + |
| 686 | + # Apply the mock |
| 687 | + with patch("requests.get", side_effect=mock_requests_get): |
| 688 | + yield |
0 commit comments