From bd28599c730d1413fcff5e8e766d60a2a722f1cf Mon Sep 17 00:00:00 2001 From: Simon Kurtz Date: Thu, 27 Aug 2026 15:03:35 -0400 Subject: [PATCH 1/2] Amend legacy diagnostic settings process --- shared/python/azure_resources.py | 2 +- tests/python/test_azure_resources.py | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/shared/python/azure_resources.py b/shared/python/azure_resources.py index 35afd03e..6ab7babe 100644 --- a/shared/python/azure_resources.py +++ b/shared/python/azure_resources.py @@ -54,7 +54,7 @@ # cleanups reliable. _AZ_CLI_LOCK = threading.Lock() _NESTED_DEPLOYMENT_RESOURCE_TYPE = 'microsoft.resources/deployments' -_LEGACY_APIM_DIAGNOSTIC_SETTING_PATTERN = re.compile(r'^apim-(?:costing-diagnostics|inference-failover)-\d+$') +_LEGACY_APIM_DIAGNOSTIC_SETTING_PATTERN = re.compile(r'^apim-(?:diag|costing-diagnostics-\d+|inference-failover-\d+)$') def _strip_ansi(text: str) -> str: diff --git a/tests/python/test_azure_resources.py b/tests/python/test_azure_resources.py index e85b167f..0dc6ef50 100644 --- a/tests/python/test_azure_resources.py +++ b/tests/python/test_azure_resources.py @@ -117,7 +117,7 @@ def test_get_resource_group_location_empty(): def test_migrate_legacy_apim_diagnostic_settings_removes_only_repository_owned_settings(): - """Legacy sample settings using the infrastructure workspace should be removed.""" + """Legacy repository settings using the infrastructure workspace should be removed.""" apim_id = '/subscriptions/sub/resourceGroups/rg/providers/Microsoft.ApiManagement/service/apim-test' workspace_id = '/subscriptions/sub/resourceGroups/rg/providers/Microsoft.OperationalInsights/workspaces/log-test' outputs = [] @@ -125,6 +125,7 @@ def test_migrate_legacy_apim_diagnostic_settings_removes_only_repository_owned_s [apim_id], [workspace_id], [ + {'name': 'apim-diag', 'workspaceId': workspace_id}, {'name': 'apim-costing-diagnostics-1', 'workspaceId': workspace_id.upper()}, {'name': 'apim-inference-failover-60', 'workspaceId': workspace_id}, {'name': 'customer-diagnostics', 'workspaceId': workspace_id}, @@ -135,13 +136,14 @@ def test_migrate_legacy_apim_diagnostic_settings_removes_only_repository_owned_s output = Output(True, json.dumps(json_data)) output.json_data = json_data outputs.append(output) - outputs.extend((Output(True, ''), Output(True, ''))) + outputs.extend((Output(True, ''), Output(True, ''), Output(True, ''))) with patch('azure_resources.run', side_effect=outputs) as mock_run: removed = az.migrate_legacy_apim_diagnostic_settings('rg') - assert removed == ['apim-costing-diagnostics-1', 'apim-inference-failover-60'] - assert mock_run.call_args_list[-2:] == [ + assert removed == ['apim-diag', 'apim-costing-diagnostics-1', 'apim-inference-failover-60'] + assert mock_run.call_args_list[-3:] == [ + call(f'az monitor diagnostic-settings delete --name apim-diag --resource "{apim_id}"'), call(f'az monitor diagnostic-settings delete --name apim-costing-diagnostics-1 --resource "{apim_id}"'), call(f'az monitor diagnostic-settings delete --name apim-inference-failover-60 --resource "{apim_id}"'), ] From 24ac3cd48e8b64db4093018de2b989669705cef8 Mon Sep 17 00:00:00 2001 From: Simon Kurtz Date: Thu, 27 Aug 2026 15:05:30 -0400 Subject: [PATCH 2/2] Fix policy error and error display --- ...kend-pool-load-balancing-with-retry-tracked.xml | 12 ++++++------ shared/python/azure_resources.py | 6 +++--- tests/python/test_azure_resources_run.py | 1 + tests/python/test_load_balancing_helpers.py | 14 ++++++++++++++ 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/samples/load-balancing/apim-policies/aca-backend-pool-load-balancing-with-retry-tracked.xml b/samples/load-balancing/apim-policies/aca-backend-pool-load-balancing-with-retry-tracked.xml index 21cff6f9..f2dca3f7 100644 --- a/samples/load-balancing/apim-policies/aca-backend-pool-load-balancing-with-retry-tracked.xml +++ b/samples/load-balancing/apim-policies/aca-backend-pool-load-balancing-with-retry-tracked.xml @@ -20,12 +20,12 @@ - + - - + }}' /> + diff --git a/shared/python/azure_resources.py b/shared/python/azure_resources.py index 6ab7babe..6d1432bb 100644 --- a/shared/python/azure_resources.py +++ b/shared/python/azure_resources.py @@ -227,9 +227,6 @@ def _extract_arm_error_details(error_payload: Any) -> tuple[str, str]: code = error_payload.get('code') if isinstance(error_payload.get('code'), str) else '' message = error_payload.get('message') if isinstance(error_payload.get('message'), str) else '' - if message: - return code, message - details = error_payload.get('details') if isinstance(details, list): for detail in details: @@ -243,6 +240,9 @@ def _extract_arm_error_details(error_payload: Any) -> tuple[str, str]: if nested_message: return nested_code or code, nested_message + if message: + return code, message + return code, message diff --git a/tests/python/test_azure_resources_run.py b/tests/python/test_azure_resources_run.py index a8aab6b8..a4f0ff7b 100644 --- a/tests/python/test_azure_resources_run.py +++ b/tests/python/test_azure_resources_run.py @@ -127,6 +127,7 @@ def test_extract_group_deployment_context_returns_none_for_non_matching_commands def test_extract_arm_error_details_prefers_nested_detail_message() -> None: payload = { 'code': 'TopLevel', + 'message': 'One or more fields contain incorrect values:', 'details': [ { 'code': 'NestedCode', diff --git a/tests/python/test_load_balancing_helpers.py b/tests/python/test_load_balancing_helpers.py index 27068903..0ddd87cb 100644 --- a/tests/python/test_load_balancing_helpers.py +++ b/tests/python/test_load_balancing_helpers.py @@ -2,6 +2,7 @@ import json import sys +import xml.etree.ElementTree as ET from pathlib import Path from unittest.mock import MagicMock @@ -49,6 +50,19 @@ def test_load_balancing_policies_use_bounded_retry_count() -> None: assert expected_assignment in code_source assert ' None: + """Prevent multi-character C# values from being emitted as character literals.""" + policy = (LOAD_BALANCING_DIR / 'apim-policies' / 'aca-backend-pool-load-balancing-with-retry-tracked.xml').read_text(encoding='utf-8') + + assert 'ContainsKey("Retry-After")' in policy + assert 'GetValueOrDefault("Retry-After", "0")' in policy + assert 'ContainsKey("cachedRetryEpoch")' in policy + assert "ContainsKey('" not in policy + assert "GetValueOrDefault('" not in policy def _create_runner(*, responses=None, sleep=None, clock=None):