Repository navigation
Hold the latency test's segment on its first attempt, so a slow host reads as waiting rather than failing (#506) - #517
Merged
Conversation
…low for the hold reads as waiting rather than failing AVFoundation gives up on a segment with no first byte within about a target duration and asks again from byte zero. A 1 s hold addressed to every attempt was therefore held twice on a loaded host, and the test read [[latency], [latency]] where it expected [[latency]] (#506). The hold now addresses the first attempt alone, and the test asserts what it is about: the held segment was held, any retry was served untouched, and the player asked for nothing past segment 1 until it had it. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01MJAhQmFgdRRAKUaMHibQLe
…n once a later one was Run together, the repeated requests showed only that segment 2 was first asked for after segment 1 was; a fetch of segment 2 between two of segment 1 passed. The order now has no segment twice, which is what "waits for it" means at the origin. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01MJAhQmFgdRRAKUaMHibQLe
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #506
The failure
The issue did not quote it. The #508 worker's local
ios/check(2026-10-13, load average near 56) recorded it in its result bundle:None of the failed CI runs still in the log window contain this test.
Cause
segment1.aacwas asked for twice, and both requests were held. The test scripted 1 000 ms of latency on segment index 1 with nofirstAttempts, so the hold applied to every attempt.AVFoundation gives up on a segment that has sent no first byte within about one target duration. For this stream that is two seconds ("No response for media file in 2s",
docs/testing.md's The fault sweep on iOS). It then asks again from byte zero.The 1 s hold is measured on the origin's clock. On a loaded host the player can see it run past its 2 s wait. When that happens:
[[latency], [latency]].A host slow enough to overrun every retry would never finish, and the test would fail on
playToEnd's 60 s bound instead.Probe evidence (a throwaway test, not committed). The probe printed the origin's responses for a hold applied to every attempt:
segment1asked for once; ended in 11.7 ssegment1asked for again every few seconds, from byte zero, interleaved withmedia.m3u8reloads; never ended within 90 s, and no segment after 1 was ever asked forReproduction (red before the fix, no host load)
The racing side was made to lose by lengthening only the first hold past AVFoundation's wait:
With the old assertions, this failed on the first run with exactly the recorded message,
[[latency], [latency]]against[[latency]].Fix (test only)
The hold is scripted on the first attempt alone (
firstAttempts: 1), the idiom the status, truncation and reset tests in this class already use. A retry, if there is one, is served untouched instead of being held again for the host to overrun.The assertions are about waiting for the segment, not about whether the hold fit the player's wait:
segment1response carried the latency, and every later one carried none;assertUntouchedis unchanged, so nothing else was faulted;segment0, segment1, segment2, and no segment appears twice. So every request forsegment1comes before the first request forsegment2: the player never skipped ahead of the held segment;Assertion strength. The old
[[.latency]](exactly one request) is the one claim given up. The number of attempts depends on host speed, which is what #506 says not to assert. Everything else is held as tightly as before or more tightly: the old order check covered only the first two segment requests.Kept as is:
forcedBy's register and the issue's references stay valid. The player still waits for the segment, either by waiting out the hold or by asking for it again.Verification
xcodebuild test -test-iterations 20 -only-testing:SuperPlayerTestkitTests/FaultScriptPlaybackTests/testALatencyHoldsTheAddressedSegmentAndThePlayerWaitsItOutonsp-506: 20/20 passed, on both commits.FaultScriptPlaybackTestsclass: 9/9 passed.SP_SIMULATOR=sp-506 ios/checkpassed on the final commit.ios/checkrun, while the host's load was near 40, failed one unrelated test:FrameOutputPacingTests/testTheLinkIsAskedForTwiceTheContentsFrameRate:XCTAssertEqualWithAccuracy failed: ("20.0") is not equal to ("60.0").Review summary
Standards: no hard findings.
FaultSweepTests.swift:170also holds every attempt (addLatencyMs(latencyMs, kind: segment, index: faultedSegment)), the same exposure. ADR-0021 rule 4's iOS i5: the fault sweep, the rung register and stale-live-playlist detection #421 addendum already records it as a margin.Spec:
prefix(3). A sequences0, s1, s2, s1would have passed it, so it did not establish that the player waited for the segment. The order is now required to contain no segment twice.segment1count, justified above.Skipped: no change to
docs/testing.mdor ADR-0021. The mechanism is already written there (The fault sweep on iOS), and this test asserts no duration, so rule 4 needs no addendum.🤖 Generated with Claude Code
https://claude.ai/code/session_01MJAhQmFgdRRAKUaMHibQLe