Skip to content

RSDK-14783 components/camera: flaky test fix TestWhyMustTimeoutOnReadRTP subscription torn down by remote shutdown ordering - #6663

Merged
Cheuk (cheukt) merged 2 commits into
mainfrom
claude/RSDK-14783/readrtp-close-order
Oct 16, 2026
Merged

Cheuk (cheukt) merged 2 commits into
mainfrom
claude/RSDK-14783/readrtp-close-order

Conversation

@viambot

@viambot viambot commented Oct 16, 2026

Copy link
Copy Markdown
Member

Problem

TestWhyMustTimeoutOnReadRTP intermittently fails on CI at client_test.go:1062:

Expected: nil
Actual:   'context canceled'

The assertion checks that main's RTP subscription survives the grand remote (remote-2) going offline.

Root cause

Both tests shut remote-2 down with:

test.That(t, remoteRobot2.Close(...), test.ShouldBeNil)   // robot torn down first
test.That(t, remoteWebSvc2.Close(...), test.ShouldBeNil)  // ...still serving until here

setupRealRobot starts a web service that is separate from the robot's own, so between those two
calls a live web server answers requests on behalf of an already dismantled robot — it advertises an
empty resource list. (A real viam-server never exposes this window: localRobot.Close calls
webSvc.Stop() before closing resources.)

If remote-1's robot client refresh lands in that window, it sees the camera as removed rather than
the machine as offline, so instead of the intended markRemoteUnreachable path it:

  1. closes its camera client to remote-2 (updateResourceClients → unsubscribeAll),
  2. removes remote-2:rtpPassthroughCamera from its resource graph, so it stops advertising it,
  3. which makes main's next refresh close its camera client → unsubscribeAll → the test's
    sub.Terminated is canceled with context canceled.

The window is ~200 ms against a 10 s client refresh interval, hence the rare, timing-dependent
failure (more likely on loaded CI runners).

Reproduction

Temporarily shrinking configTickerInterval and the robot client refresh/check intervals to 300 ms
makes the failure deterministic: TestWhyMustTimeoutOnReadRTP and TestGrandRemoteRebooting fail
100% of the time on main, with logs showing exactly the chain above
(Removing resource from remote client → unsubscribeAll terminating sub). With this change both
pass 100% of the time under the same accelerated timers, and they keep passing with the real timers
(verified repeatedly, including under -race alongside the other remote/passthrough tests in the
package).

Fix

Close the web service before the robot, matching real viam-server shutdown ordering (and the order
these tests already use in their deferred cleanup). The parent then observes a clean disconnect,
which only marks the remote's resources unreachable and leaves main's subscription intact.

TestGrandRemoteRebooting has the identical shutdown sequence and the same latent flake (it asserts
the same thing plus continued liveness across remote-2's reboot), so it gets the same fix.

Key: RSDK-14783

Co-authored by Claude agent for Jira.

…ot in RTP passthrough tests

TestWhyMustTimeoutOnReadRTP and TestGrandRemoteRebooting shut the grand remote
(remote-2) down by closing its robot first and its web service second. In that
window the web service keeps answering for an already dismantled robot, so a
refresh from remote-1 returns an empty resource list. remote-1 reads that as
"the camera was removed" instead of "the machine went offline": it closes its
camera client, drops the resource from its graph, and stops advertising it to
main. main then closes its own camera client, which terminates the subscription
both tests assert stays alive ("Expected: nil / Actual: 'context canceled'").

Closing the web service first matches how a real viam-server shuts down
(localRobot.Close stops web before tearing down resources) and leaves the parent
with a clean disconnect, which only marks the remote's resources unreachable.
@viambot viambot added the safe to test This pull request is marked safe to test from a trusted zone label Oct 16, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Review Required

This PR was opened by Claude and requires a minimum of 1 approving reviews before it can be merged.

Review process:

  1. the assignee — as the person who triggered this Claude workflow, you should review the code thoroughly and submit your approval.
  2. Request additional reviewers for the remaining required approvals.

Current status: 0/1 approvals.

@10zingpd
10zingpd requested review from a team and Cheuk (cheukt) and removed request for a team and Evan Dorsky (EvanDorsky) October 16, 2026 19:23
@cheukt

Copy link
Copy Markdown
Member

Claude (@claude) remove or shorten the comments

@claude

claude Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Claude finished Cheuk (@cheukt)'s task in 1m 10s —— View job


Removing/shortening comments

  • Read changed file
  • Remove or shorten comments
  • Commit and push

Condensed both multi-line comments to single one-liners:

  • TestWhyMustTimeoutOnReadRTP: 5 lines → // Web service before robot: matches real viam-server shutdown; prevents remote-1 misreading an empty resource list as removal.
  • TestGrandRemoteRebooting: 3 lines → // Web service before robot; see TestWhyMustTimeoutOnReadRTP for why order matters.
    | Branch

Co-authored-by: Cheuk <cheukt@users.noreply.github.com>
@viambot viambot added safe to test This pull request is marked safe to test from a trusted zone and removed safe to test This pull request is marked safe to test from a trusted zone labels Oct 16, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems fair.

@cheukt
Cheuk (cheukt) merged commit 3d8a7ce into main Oct 16, 2026
26 of 27 checks passed
@cheukt
Cheuk (cheukt) deleted the claude/RSDK-14783/readrtp-close-order branch October 16, 2026 20:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

safe to test This pull request is marked safe to test from a trusted zone

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants