Skip to content

Commit 3b93a8e

Browse files
Henry DaiCopilot
andcommitted
Fix CI test failures: subscription_id resolution and target normalization
- Fix _append_or_set_element to concatenate values with comma instead of overwriting existing key-value pairs (fixes test_normalize_targets) - Add _safe_subscription_id helper to handle CI environment where cmd.ctx.subscription_id throws CLIError (no az login session) - Change ChangeSafetyLiveScenario base class to LiveScenarioTest so live-only tests are properly skipped in CI (fixes acquire_token error) All 3 CI failures from build 309298 are resolved: - test_normalize_targets_from_operations: PASSED (was assertion error) - test_change_record_crud_scenario: PASSED (was CLIError: az login) - test_default_schedule_times_applied_on_create: PASSED (was CLIError) - test_changesafety_full_scenario: SKIPPED (correctly, via @live_only) Local verification: azdev test/style/linter all passed (19 passed, 1 skipped) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 5a1b91a commit 3b93a8e

File tree

2 files changed

+35
-9
lines changed

2 files changed

+35
-9
lines changed

src/azure-changesafety/azext_changesafety/custom.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,10 @@ def _append_or_set_element(elements, idx, value):
230230
if idx is not None:
231231
while len(elements) <= idx:
232232
elements.append('')
233-
elements[idx] = value
233+
if elements[idx]:
234+
elements[idx] = elements[idx] + ',' + value
235+
else:
236+
elements[idx] = value
234237
else:
235238
elements.append(value)
236239

src/azure-changesafety/azext_changesafety/tests/latest/test_changesafety.py

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from types import SimpleNamespace
1717
from unittest import mock
1818

19-
from azure.cli.testsdk import ScenarioTest, JMESPathCheck
19+
from azure.cli.testsdk import ScenarioTest, JMESPathCheck, LiveScenarioTest
2020

2121
from azext_changesafety.custom import (
2222
_inject_change_definition_into_content,
@@ -60,6 +60,13 @@ def _dummy_ctx_with_change_definition(payload):
6060
dummy = SimpleNamespace()
6161
dummy.to_serialized_data = lambda: payload
6262
return SimpleNamespace(vars=SimpleNamespace(change_definition=dummy))
63+
@classmethod
64+
def _safe_subscription_id(cls, cmd):
65+
"""Get subscription ID safely, falling back to FAKE_SUBSCRIPTION_ID in CI."""
66+
try:
67+
return cmd.ctx.subscription_id or cls.FAKE_SUBSCRIPTION_ID
68+
except Exception: # pylint: disable=broad-except
69+
return cls.FAKE_SUBSCRIPTION_ID
6370

6471
@classmethod
6572
def _ensure_msrestazure_stub(cls):
@@ -144,7 +151,7 @@ def _mock_create_execute(cmd):
144151
cmd.pre_operations()
145152
name = cls._get_arg_value(cmd, "change_record_name", "mock-change")
146153
resource_group = cls._get_arg_value(cmd, "resource_group", "mock-rg")
147-
subscription_id = cmd.ctx.subscription_id or cls.FAKE_SUBSCRIPTION_ID
154+
subscription_id = cls._safe_subscription_id(cmd)
148155
change_type = cls._get_arg_value(cmd, "change_type", "ManualTouch")
149156
rollout_type = cls._get_arg_value(cmd, "rollout_type", "Normal")
150157
comments = cls._get_arg_value(cmd, "comments")
@@ -191,7 +198,7 @@ def _mock_update_execute(cmd):
191198
if current is None:
192199
name = cls._get_arg_value(cmd, "change_record_name", "mock-change")
193200
resource_group = cls._get_arg_value(cmd, "resource_group", "mock-rg")
194-
subscription_id = cmd.ctx.subscription_id or cls.FAKE_SUBSCRIPTION_ID
201+
subscription_id = cls._safe_subscription_id(cmd)
195202
current = cls._build_mock_instance(
196203
name=name,
197204
resource_group=resource_group,
@@ -484,6 +491,14 @@ class StageMapScenario(ScenarioTest):
484491
"""Test scenarios for StageMap CRUD operations."""
485492

486493
FAKE_SUBSCRIPTION_ID = "00000000-0000-0000-0000-000000000000"
494+
495+
@classmethod
496+
def _safe_subscription_id(cls, cmd):
497+
"""Get subscription ID safely, falling back to FAKE_SUBSCRIPTION_ID in CI."""
498+
try:
499+
return cmd.ctx.subscription_id or cls.FAKE_SUBSCRIPTION_ID
500+
except Exception: # pylint: disable=broad-except
501+
return cls.FAKE_SUBSCRIPTION_ID
487502
_SCENARIO_STATE = {}
488503

489504
class _DummyPoller: # pylint: disable=too-few-public-methods
@@ -524,7 +539,7 @@ def _mock_create_execute(cmd):
524539
cmd.pre_operations()
525540
name_arg = getattr(cmd.ctx.args, "stage_map_name", None)
526541
name = name_arg.to_serialized_data() if name_arg and has_value(name_arg) else "mock-stagemap"
527-
subscription_id = cmd.ctx.subscription_id or cls.FAKE_SUBSCRIPTION_ID
542+
subscription_id = cls._safe_subscription_id(cmd)
528543
stages_arg = getattr(cmd.ctx.args, "stages", None)
529544
stages = stages_arg.to_serialized_data() if stages_arg and has_value(stages_arg) else None
530545
instance = cls._build_mock_stagemap(name, subscription_id, stages)
@@ -552,7 +567,7 @@ def _mock_update_execute(cmd):
552567
if current is None:
553568
name_arg = getattr(cmd.ctx.args, "stage_map_name", None)
554569
name = name_arg.to_serialized_data() if name_arg and has_value(name_arg) else "mock-stagemap"
555-
subscription_id = cmd.ctx.subscription_id or cls.FAKE_SUBSCRIPTION_ID
570+
subscription_id = cls._safe_subscription_id(cmd)
556571
current = cls._build_mock_stagemap(name, subscription_id)
557572
stages_arg = getattr(cmd.ctx.args, "stages", None)
558573
if stages_arg and has_value(stages_arg):
@@ -676,6 +691,14 @@ class StageProgressionScenario(ScenarioTest):
676691
"""Test scenarios for StageProgression CRUD operations."""
677692

678693
FAKE_SUBSCRIPTION_ID = "00000000-0000-0000-0000-000000000000"
694+
695+
@classmethod
696+
def _safe_subscription_id(cls, cmd):
697+
"""Get subscription ID safely, falling back to FAKE_SUBSCRIPTION_ID in CI."""
698+
try:
699+
return cmd.ctx.subscription_id or cls.FAKE_SUBSCRIPTION_ID
700+
except Exception: # pylint: disable=broad-except
701+
return cls.FAKE_SUBSCRIPTION_ID
679702
_SCENARIO_STATE = {}
680703

681704
class _DummyPoller: # pylint: disable=too-few-public-methods
@@ -717,7 +740,7 @@ def _mock_create_execute(cmd):
717740
name = name_arg.to_serialized_data() if name_arg and has_value(name_arg) else "mock-progression"
718741
cr_arg = getattr(cmd.ctx.args, "change_record_name", None)
719742
change_record_name = cr_arg.to_serialized_data() if cr_arg and has_value(cr_arg) else "mock-changerecord"
720-
subscription_id = cmd.ctx.subscription_id or cls.FAKE_SUBSCRIPTION_ID
743+
subscription_id = cls._safe_subscription_id(cmd)
721744
stage_ref_arg = getattr(cmd.ctx.args, "stage_reference", None)
722745
stage_reference = stage_ref_arg.to_serialized_data() if stage_ref_arg and has_value(stage_ref_arg) else "Stage1"
723746
status_arg = getattr(cmd.ctx.args, "status", None)
@@ -751,7 +774,7 @@ def _mock_update_execute(cmd):
751774
name = name_arg.to_serialized_data() if name_arg and has_value(name_arg) else "mock-progression"
752775
cr_arg = getattr(cmd.ctx.args, "change_record_name", None)
753776
change_record_name = cr_arg.to_serialized_data() if cr_arg and has_value(cr_arg) else "mock-changerecord"
754-
subscription_id = cmd.ctx.subscription_id or cls.FAKE_SUBSCRIPTION_ID
777+
subscription_id = cls._safe_subscription_id(cmd)
755778
current = cls._build_mock_stageprogression(name, change_record_name, subscription_id, "Stage1")
756779
status_arg = getattr(cmd.ctx.args, "status", None)
757780
if status_arg and has_value(status_arg):
@@ -1001,7 +1024,7 @@ def _delay(self, *args, **kwargs): # pylint: disable=unused-argument
10011024
_ensure_msrestazure_stub()
10021025

10031026

1004-
class ChangeSafetyLiveScenario(ScenarioTest):
1027+
class ChangeSafetyLiveScenario(LiveScenarioTest):
10051028
"""Live test scenarios for generating recordings.
10061029
10071030
Run with: azdev test azure-changesafety --live

0 commit comments

Comments
 (0)