Skip to content

Commit c9dc986

Browse files
committed
pre for live recoding cache test
1 parent 3850513 commit c9dc986

1 file changed

Lines changed: 50 additions & 29 deletions

File tree

src/azure-cli/azure/cli/command_modules/netappfiles/tests/latest/test_cache_commands.py

Lines changed: 50 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import time
99
import unittest
1010

11-
from azure.cli.testsdk import ScenarioTest, ResourceGroupPreparer, live_only
11+
from azure.cli.testsdk import ScenarioTest, ResourceGroupPreparer
1212
from azure.cli.testsdk.decorators import serial_test
1313

1414
LOCATION = "eastus"
@@ -25,34 +25,44 @@
2525

2626
# No tidy up of tests required. The resource group is automatically removed
2727
#
28-
# Cache Tests are failing due issues in the environment, no way to test until fixed re enable when fixed
29-
#
3028
# As a refactoring consideration for the future, consider use of authoring patterns described here
3129
# https://github.com/Azure/azure-cli/blob/dev/doc/authoring_tests.md#sample-5-get-more-from-resourcegrouppreparer
3230
#
3331
# -----------------------------------------------------------------------------
3432
# How to run these tests
3533
# -----------------------------------------------------------------------------
36-
# All cache tests are decorated with @live_only(), so they are skipped unless
37-
# AZURE_TEST_RUN_LIVE is set. `test_create_delete_cache` additionally requires
38-
# ANF_ALLOW_INTERACTIVE=1 because it pauses for an engineer to perform two
39-
# manual on-prem (CVO) peering steps; it polls cacheState as the sync signal
40-
# and prints copy-pasteable commands to STDERR.
34+
# These tests use the standard record/playback model. The cassette files under
35+
# `recordings/` capture the ARM/RP request/response traffic so the tests can
36+
# be replayed in CI without any Azure access or human interaction.
37+
#
38+
# Playback (default, no env vars):
39+
# - No Azure access required.
40+
# - The interactive on-prem (CVO) peering pause is suppressed; the recorded
41+
# cacheState transitions are replayed instantly so the polling loop
42+
# terminates without sleeping.
4143
#
42-
# IMPORTANT: pass `-s` (a.k.a. `--capture=no`) to pytest so the on-prem
43-
# instruction blocks written to stderr are shown in real time. Without `-s`
44-
# pytest will buffer the output and you won't see the commands until the test
45-
# ends (long after the engineer needed them).
44+
# pytest -vv \
45+
# src/azure-cli/azure/cli/command_modules/netappfiles/tests/latest/test_cache_commands.py
4646
#
47-
# PowerShell (Windows) - run the full interactive create/delete flow:
47+
# Recording (re-record cassettes against a real subscription):
48+
# - Set AZURE_TEST_RUN_LIVE=True to talk to ARM.
49+
# - For `test_create_delete_cache` ALSO set ANF_ALLOW_INTERACTIVE=1 because
50+
# the test pauses for an engineer to perform two manual on-prem (CVO)
51+
# peering steps; it polls cacheState as the sync signal and prints
52+
# copy-pasteable commands to STDERR. Without ANF_ALLOW_INTERACTIVE the
53+
# interactive test self-skips when running live.
54+
# - Pass `-s` (a.k.a. `--capture=no`) to pytest so the instruction blocks
55+
# written to stderr are shown in real time; otherwise pytest buffers them.
56+
#
57+
# PowerShell (Windows) - re-record the full interactive create/delete flow:
4858
#
4959
# $env:AZURE_TEST_RUN_LIVE = "True"
5060
# $env:ANF_ALLOW_INTERACTIVE = "1"
5161
# pytest -s -vv `
5262
# src/azure-cli/azure/cli/command_modules/netappfiles/tests/latest/test_cache_commands.py::AzureNetAppFilesCacheServiceScenarioTest::test_create_delete_cache
5363
#
54-
# PowerShell - run all live cache tests except the interactive one
55-
# (leave ANF_ALLOW_INTERACTIVE unset so the interactive test is skipped):
64+
# PowerShell - re-record all live cache tests except the interactive one
65+
# (leave ANF_ALLOW_INTERACTIVE unset so the interactive test self-skips):
5666
#
5767
# $env:AZURE_TEST_RUN_LIVE = "True"
5868
# Remove-Item Env:ANF_ALLOW_INTERACTIVE -ErrorAction SilentlyContinue
@@ -65,14 +75,15 @@
6575
# pytest -s -vv \
6676
# src/azure-cli/azure/cli/command_modules/netappfiles/tests/latest/test_cache_commands.py::AzureNetAppFilesCacheServiceScenarioTest::test_create_delete_cache
6777
#
68-
# Via azdev (also live):
78+
# Via azdev (live re-record):
6979
#
7080
# $env:AZURE_TEST_RUN_LIVE = "True"
7181
# $env:ANF_ALLOW_INTERACTIVE = "1"
7282
# azdev test test_create_delete_cache --live --pytest-args "-s -vv"
7383
#
7484
# Useful pytest flags:
75-
# -s / --capture=no show stderr/stdout live (REQUIRED for the interactive test)
85+
# -s / --capture=no show stderr/stdout live (REQUIRED when recording the
86+
# interactive test)
7687
# -vv verbose test names + full assert diffs
7788
# -k <expr> filter by test name substring
7889
# --log-cli-level=INFO show CLI logging in real time
@@ -148,12 +159,15 @@ def _wait_for_cache_state(self, account_name, pool_name, cache_name, target_stat
148159
last_state = cache.get('cacheState') or cache.get('properties', {}).get('cacheState')
149160
if last_state in target_states:
150161
return cache
151-
if self.is_live or self.in_recording:
162+
if self.in_recording:
163+
# Live or first-time recording: wait between polls.
152164
time.sleep(interval)
153165
else:
154-
# In playback we never reach here (test is @live_only), but
155-
# avoid a hot loop just in case.
156-
break
166+
# Playback: every recorded `cache show` response is consumed
167+
# in order from the cassette. If we have not yet hit a target
168+
# state, advance immediately to consume the next recorded
169+
# response without sleeping.
170+
continue
157171
self.fail("Timed out after %ds waiting for cacheState in %s; last observed state: %r" %
158172
(timeout, sorted(target_states), last_state))
159173

@@ -222,13 +236,18 @@ def _emit_engineer_instructions(passphrases_object, step):
222236
sys.stderr.write(block)
223237
sys.stderr.flush()
224238

225-
@live_only()
226-
@unittest.skipUnless(
227-
os.environ.get(INTERACTIVE_ENV_VAR) == "1",
228-
"Requires manual on-prem (CVO) peering steps; set %s=1 to run." % INTERACTIVE_ENV_VAR)
229239
@serial_test()
230240
@ResourceGroupPreparer(name_prefix='cli_netappfiles_test_cache_', additional_tags={'owner': 'cli_test'})
231241
def test_create_delete_cache(self):
242+
# In playback we replay the recorded cassette and never need a human;
243+
# in record/live we require the engineer to opt in to the manual
244+
# on-prem (CVO) peering steps so scheduled live pipelines don't hang
245+
# for up to an hour waiting for human input.
246+
if self.in_recording and os.environ.get(INTERACTIVE_ENV_VAR) != "1":
247+
self.skipTest(
248+
"Requires manual on-prem (CVO) peering steps when recording; "
249+
"set %s=1 to run live." % INTERACTIVE_ENV_VAR)
250+
232251
account_name = self.create_random_name(prefix='cli-acc-', length=24)
233252
pool_name = self.create_random_name(prefix='cli-pool-', length=24)
234253
cache_name = self.create_random_name(prefix='cli-cache-', length=24)
@@ -251,15 +270,19 @@ def test_create_delete_cache(self):
251270
"az netappfiles cache list-peering-passphrase -g {rg} -a %s -p %s -c %s" %
252271
(account_name, pool_name, cache_name)).get_output_in_json()
253272
assert passphrases_object is not None
254-
self._emit_engineer_instructions(passphrases_object, step="cluster")
273+
# Only pause for the engineer when actually talking to ARM. In playback
274+
# the recorded responses already reflect the post-peering cache state.
275+
if self.in_recording:
276+
self._emit_engineer_instructions(passphrases_object, step="cluster")
255277

256278
# 3) Engineer pastes the cluster peering command + passphrase on CVO.
257279
# The service advances cacheState to VserverPeeringOfferSent on success.
258280
self._wait_for_cache_state(account_name, pool_name, cache_name,
259281
target_states={"VserverPeeringOfferSent"})
260282

261283
# 4) Surface the vserver peering command for the second on-prem step.
262-
self._emit_engineer_instructions(passphrases_object, step="vserver")
284+
if self.in_recording:
285+
self._emit_engineer_instructions(passphrases_object, step="vserver")
263286

264287
# 5) Engineer pastes the vserver peering command on CVO.
265288
# The cache should now drive itself to a terminal state.
@@ -333,7 +356,6 @@ def test_create_delete_cache_with_wait(self):
333356
(account_name, pool_name)).get_output_in_json()
334357
assert len(cache_list) == 0
335358

336-
@live_only()
337359
@ResourceGroupPreparer(name_prefix='cli_netappfiles_test_cache_', additional_tags={'owner': 'cli_test'})
338360
def test_list_caches(self):
339361
account_name = self.create_random_name(prefix='cli-acc-', length=24)
@@ -375,7 +397,6 @@ def test_list_caches(self):
375397
# - `az netappfiles cache list-peering-passphrase`
376398
# - `az netappfiles cache reset-smb-password`
377399

378-
@live_only()
379400
@ResourceGroupPreparer(name_prefix='cli_netappfiles_test_cache_', additional_tags={'owner': 'cli_test'})
380401
def test_cache_pool_change(self):
381402
account_name = self.create_random_name(prefix='cli-acc-', length=24)

0 commit comments

Comments
 (0)