Skip to content

Commit fd206c0

Browse files
committed
test: Load the changed file on demand when checking that a different failure is reported
The reloader test wrote a file with a new failure while the automatic retries were running and expected the next retry to report it. The write is ordinary, not atomic, so a retry can read the file while it is empty or half written. An empty document is valid, so such a retry succeeds and ends the retries, and the new failure is never read; a half-written file is reported as a failure of its own. The test now loads the final content on demand and inspects the reports as a whole, and a fixture helper collects the callbacks that arrive within a settle period.
1 parent 7f80543 commit fd206c0

1 file changed

Lines changed: 23 additions & 3 deletions

File tree

‎ldclient/testing/integrations/test_filedata.py‎

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import threading
44
import time
55
from queue import Empty, Queue
6-
from typing import Any, Dict, List, Set
6+
from typing import Any, Dict, List, Set, Tuple
77
from unittest import mock
88

99
import pytest
@@ -319,6 +319,19 @@ def require_quiet(self, duration: float = QUIET_PERIOD) -> None:
319319
pytest.fail("unexpected on_error call")
320320
time.sleep(0.01)
321321

322+
def drain(self, duration: float = QUIET_PERIOD) -> Tuple[List[MergeResult], List[Exception]]:
323+
"""Collects every apply and on_error call that arrives within the duration."""
324+
applied: List[MergeResult] = []
325+
errored: List[Exception] = []
326+
deadline = time.time() + duration
327+
while time.time() < deadline:
328+
while not self.applied.empty():
329+
applied.append(self.applied.get_nowait())
330+
while not self.errored.empty():
331+
errored.append(self.errored.get_nowait())
332+
time.sleep(0.01)
333+
return applied, errored
334+
322335
def close(self) -> None:
323336
self.reloader.close()
324337

@@ -437,9 +450,16 @@ def test_reloader_reports_identical_failure_only_once(make_fixture):
437450
# The automatic retries keep failing in the same way. They do not report again.
438451
f.require_quiet()
439452

440-
# A different failure is reported.
453+
# A different failure is reported. The write is ordinary, not atomic, and a retry that runs
454+
# while the file is being rewritten reads it empty or half written. An empty document is
455+
# valid, so such a retry succeeds and ends the retries; a half-written file is a failure of
456+
# its own. The final content is therefore loaded on demand, and everything that was reported
457+
# is inspected as a whole: the new failure is among the reports, and once it is the current
458+
# failure, the retries that repeat it stay silent.
441459
f.write('{"flags": {"flag1": "not an object"}}')
442-
f.require_errored()
460+
f.reloader.reload_now()
461+
_, errored = f.drain()
462+
assert any('must be an object' in str(e) for e in errored), errored
443463
f.require_quiet()
444464

445465

0 commit comments

Comments
 (0)