Skip to content

Commit e8496a2

Browse files
committed
test: enhance sound file update and patch verification with retry logic
Implemented retry logic in tests for sound file updates and patches to handle asynchronous processing via Redis queue. This allows for better handling of potential 422 validation errors and ensures that updates are confirmed after processing. Added detailed assertions to verify the final state of updated records, improving test reliability and robustness.
1 parent 971e964 commit e8496a2

File tree

1 file changed

+73
-6
lines changed

1 file changed

+73
-6
lines changed

tests/api/test_11_sound_files_prepare.py

Lines changed: 73 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -193,14 +193,50 @@ def test_07_update_sound_file(self, api_client):
193193
response = api_client.put(f'sound-files/{sound_id}', update_data)
194194
assert_api_success(response, "Failed to update sound file")
195195

196-
# Verify update
197-
updated = assert_record_exists(api_client, 'sound-files', sound_id)
198-
assert '(Updated)' in updated['name']
196+
# Verify update with retry logic (async API processing via Redis queue + worker)
197+
# Worker may still be processing the update, causing 422 validation errors
198+
max_verify_attempts = 5
199+
updated = None
200+
for attempt in range(max_verify_attempts):
201+
try:
202+
updated = assert_record_exists(api_client, 'sound-files', sound_id)
203+
204+
# Check if update actually applied (worker completed processing)
205+
if '(Updated)' in updated['name']:
206+
break # Update successful
207+
else:
208+
# Update not yet visible - worker still processing
209+
if attempt < max_verify_attempts - 1:
210+
print(f" Waiting for update to complete (attempt {attempt + 1}/{max_verify_attempts})...")
211+
time.sleep(1)
212+
else:
213+
pytest.fail(f"Update not applied after {max_verify_attempts} attempts. Name: {updated['name']}")
214+
215+
except Exception as e:
216+
# Handle 422 errors during async processing
217+
if '422' in str(e):
218+
# Validation error - record in intermediate state, worker still processing
219+
if attempt < max_verify_attempts - 1:
220+
print(f" Record validation failed (worker processing), retrying (attempt {attempt + 1}/{max_verify_attempts})...")
221+
time.sleep(1)
222+
else:
223+
pytest.fail(f"Persistent 422 validation error after {max_verify_attempts} attempts: {e}")
224+
# Handle record deletion during update
225+
elif 'not found' in str(e).lower() or '404' in str(e):
226+
pytest.skip(f"Sound file {sound_id} deleted during update (system restore)")
227+
else:
228+
raise
229+
230+
# Final assertion - ensure we got the updated data
231+
assert updated is not None, "Failed to retrieve updated record"
232+
assert '(Updated)' in updated['name'], f"Update not reflected. Expected '(Updated)' in name, got: {updated['name']}"
199233

200234
print(f"✓ Updated sound file: {updated['name']}")
201235

202236
def test_08_patch_sound_file(self, api_client):
203237
"""Test PATCH /sound-files/{id} - Partial update"""
238+
import time
239+
204240
if not self.created_ids:
205241
pytest.skip("No sound files created yet")
206242

@@ -221,9 +257,40 @@ def test_08_patch_sound_file(self, api_client):
221257
response = api_client.patch(f'sound-files/{sound_id}', patch_data)
222258
assert_api_success(response, "Failed to patch sound file")
223259

224-
# Verify patch
225-
updated = assert_record_exists(api_client, 'sound-files', sound_id)
226-
assert updated['description'] == 'Patched description'
260+
# Verify patch with retry logic (async API processing via Redis queue + worker)
261+
max_verify_attempts = 5
262+
updated = None
263+
for attempt in range(max_verify_attempts):
264+
try:
265+
updated = assert_record_exists(api_client, 'sound-files', sound_id)
266+
267+
# Check if patch actually applied
268+
if updated['description'] == 'Patched description':
269+
break # Patch successful
270+
else:
271+
# Patch not yet visible - worker still processing
272+
if attempt < max_verify_attempts - 1:
273+
print(f" Waiting for patch to complete (attempt {attempt + 1}/{max_verify_attempts})...")
274+
time.sleep(1)
275+
else:
276+
pytest.fail(f"Patch not applied after {max_verify_attempts} attempts. Description: {updated['description']}")
277+
278+
except Exception as e:
279+
# Handle 422 errors during async processing
280+
if '422' in str(e):
281+
if attempt < max_verify_attempts - 1:
282+
print(f" Record validation failed (worker processing), retrying (attempt {attempt + 1}/{max_verify_attempts})...")
283+
time.sleep(1)
284+
else:
285+
pytest.fail(f"Persistent 422 validation error after {max_verify_attempts} attempts: {e}")
286+
elif 'not found' in str(e).lower() or '404' in str(e):
287+
pytest.skip(f"Sound file {sound_id} deleted during patch (system restore)")
288+
else:
289+
raise
290+
291+
# Final assertion
292+
assert updated is not None, "Failed to retrieve patched record"
293+
assert updated['description'] == 'Patched description', f"Patch not reflected. Expected 'Patched description', got: {updated['description']}"
227294

228295
print(f"✓ Patched sound file description")
229296

0 commit comments

Comments
 (0)