Skip to content

Flaky: dbus_client_isolation::a_second_operation_is_refused_while_one_is_in_flight races the enroll in-flight window #24

Description

@P4suta

Symptom

Intermittent failure in the linux verify CI job:

thread 'a_second_operation_is_refused_while_one_is_in_flight' panicked at crates/fprintd/tests/dbus_client_isolation.rs:174:
assertion `left == right` failed: one operation in flight per device
  left: None
 right: Some("net.reactivated.Fprint.Error.AlreadyInUse")

Passed on most runs (e.g. the #18/#20 merges), failed on the c43350a (#21) merge. So ~intermittent, not a code regression from any specific change.

Root cause

The daemon guard is correct: Device::start_active (crates/fprintd/src/device.rs) refuses a second operation only while the first is still running (!op.finished()). A completed pump is cleared.

The test races that window. The virtual device's enroll (fprint-backend-native, device.rs::enroll) runs enroll_stages iterations of yield_now().await with no blocking, so it completes in microseconds. By the time the test issues the second enroll_start, the first enroll has often already finished, the guard has cleared, and the second call succeeds (None) instead of returning AlreadyInUse.

So it is a timing race in the test's observation window, not a daemon bug.

Why not just retry

.config/nextest.toml is explicit: retries = 0 — "a nondeterministic one is a bug to fix, not to retry away." A deterministic fix is required.

Proposed deterministic fix

Give the virtual device a way to hold an operation genuinely in-flight until the test releases it:

  • Add a runtime-agnostic gate (e.g. a futures_channel::oneshot) to VirtualDeviceBuilder/VirtualDevice; enroll awaits it before completing when set. fprint-backend-native is publish = false, so this test-support hook does not ship.
  • Change Harness::serve (crates/fprintd/tests/common) from backend: fn() -> VirtualBackend to impl Fn() -> VirtualBackend so a test can capture the gate handle (a bare fn coerces, so existing callers are unaffected).
  • The test then: enroll_start (blocks on the gate, genuinely in-flight) → assert the second enroll_start is AlreadyInUse → open the gate → enroll_stop.

Impact

Blocks ci-required intermittently, so it can stall auto-merge of unrelated PRs (surfaced while finishing the 0.1.0 release).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions