daemon: Share credential lifecycle across transports - #224
Open
Preovaleo wants to merge 3 commits into
Open
Conversation
added 3 commits
September 5, 2026 15:52
The push-based helper was embedded in the credential service tests, and its cancellation-focused names hid that it could script any transport state. Move it to test_support, rename it around that broader role, and share typed completion and failure helpers across USB, hybrid, and NFC tests.
USB, hybrid, and NFC duplicated state conversion and request completion in separate stream wrappers, making their terminal behavior easy to desynchronize. Route typed transport events through one lifecycle stream and cover success and failure for every backend.
This was referenced Sep 5, 2026
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.
Split and stacked review
Original PR: linux-credentials/credentialsd#220.
The replacement is split into four parts. Parts 1 → 2 → 3 form native GitHub stack #4 on the fork; part 4 is independent.
main)/1→main/2→/1/3→/2Review and integrate parts 1 → 2 → 3 in order. Part 4 can be reviewed and merged independently.
GitHub does not support native stacks across forks. Use Files changed on the fork PRs for incremental review of each layer. The upstream PRs target
main; #225 and #226 include earlier layers until their dependencies land and the branches are rebased. Integration into the main project happens through the upstream PRs; merging the fork stack only updates the fork.Hello 👋,
Summary
Follow-up to #204 and #214. This PR extracts the shared transport lifecycle work from #220.
USB, hybrid, and NFC previously handled state conversion and request completion in separate stream wrappers. These implementations duplicated the same lifecycle logic, making changes harder to review and allowing terminal behavior to diverge between transports.
This PR:
Result
Transport-specific code remains responsible for interpreting its internal events and exposing the corresponding public state and optional credential result.
The shared stream handles request completion, cancellation checks, and termination after a terminal event. This gives subsequent lifecycle fixes a common implementation point across transports.
The scripted test fixtures allow tests to emit intermediate states, complete or fail a transport, and inspect cancellation without physical authenticators.
Scope and dependencies
This is the first part of the split and is based on
main.The remaining work is handled by separate PRs:
Authenticator enumeration and dynamic source-list updates remain outside this change.
Diff composition
mainebf5eb8— Extract test fixtures775f07f— Share transport lifecycleCommit sequence and rationale
The commit order follows the dependencies between these changes:
daemon: Extract scripted transport test fixtures
Sharing lifecycle code also means being able to exercise the same outcomes across transports. The existing push-based helper already supported scripted events, but lived inside the service tests and was named around cancellation. Extracting it into typed fixtures makes success, failure, and cancellation available to USB, hybrid, and NFC tests. This preparation comes first so the following commit can introduce the common stream together with coverage of each transport.
daemon: Share credential lifecycle across transports
The repeated responsibility is the transition from a transport event to a public state and, when terminal, a request result. That is the boundary represented by
TransportEvent: each transport supplies its own conversion, whilecredential_state_streamowns completion and stream termination. Keeping that boundary narrow preserves the transport-specific state models and gives the later lifecycle fixes one implementation point. The success and failure tests accompany the extraction because equivalent terminal behavior across the three transports is what justifies sharing this code.docs: Describe shared transport lifecycle handling
The architecture text records this division of responsibility. It stops at the common lifecycle introduced here; the cancellation and request ownership guarantees are documented with the commits that add them in part 2.
Testing
Validation performed at the branch tip:
cargo test -p credentialsd --bin credentialsd— 29 tests passedcargo clippy -p credentialsd --bin credentialsd -- -Dwarnings— passedcargo fmt --all --check— passedgit diff --check— passedCoverage includes transport success and failure, response propagation, cancellation after request completion, cancellation of competing transports, and discarding events after cancellation.