Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,7 @@ _check $BASE $TEST:
just rs media-features
just --justfile bench/justfile check
quest check
just test drill-sensitivity --apply-only
# Not covered by the line above: moq-wasm only exists on the wasm32 target.
just rs wasm
just py check
Expand All @@ -570,6 +571,12 @@ _check $BASE $TEST:
if echo "$files" | grep -qE '^(quest/|flake\.lock$)'; then
quest check
fi
# The drill mutations patch Rust source, so a Rust change can move the
# code they target. Only nightly runs the drills against them; this
# catches a stale patch in the PR that moved its code.
if echo "$files" | grep -qE '^(rs/|test/drill/)'; then
just test drill-sensitivity --apply-only
fi
just py check "$files"
just kt check "$files"
just swift check "$files"
Expand Down
1 change: 0 additions & 1 deletion quest/m1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ transport, benchmark tooling); worktrees isolate commits, not semantics.

## Required

- [Drill sensitivity](/quest/m1/drill-sensitivity.md) - the nightly drill-sensitivity job passes: the subscriber-leaks-broadcasts mutation applies to the current lite subscriber again
- [Cluster routing](/quest/m1/cluster-routing.md) - an announcement says where a broadcast originates, not how to reach it, and a relay hears only the prefixes its clients asked for
- [lite-07 count settle](/quest/m1/lite-count-settle.md) - moq-lite-07 subscribers stop waiting for a subscription's tail once SUBSCRIBE_END's stream count is reached
- [Dropped sources](/quest/m1/dropped-sources.md) - track consumers see the producer's real error on every end path, never `Dropped`
Expand Down
22 changes: 0 additions & 22 deletions quest/m1/drill-sensitivity.md

This file was deleted.

4 changes: 3 additions & 1 deletion test/drill/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,9 @@ protocol's reaction to loss and delay, not the kernel's rendering of them.
## Sensitivity

The Nightly workflow runs all mutations, so patches that stop applying and drills
that stop detecting their recovery failures fail CI.
that stop detecting their recovery failures fail CI. `just check` also runs
`--apply-only` whenever Rust or this directory changes, so a patch that no longer
applies fails the PR that moved its code rather than the next nightly.

`sensitivity.sh` removes one recovery behavior at a time and requires the drill
covering it to fail. Each mutation is a patch under `mutations/`, applied to a
Expand Down
14 changes: 7 additions & 7 deletions test/drill/mutations/relay-withdraws-lost-publisher.patch
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,25 @@
# means a route outlives the session that announced it, so a crashed publisher's
# name stays announced with nothing behind it.
diff --git a/rs/moq-net/src/lite/subscriber.rs b/rs/moq-net/src/lite/subscriber.rs
index 729a23e4b..dac9990c6 100644
index 8a0259fec..0b6035640 100644
--- a/rs/moq-net/src/lite/subscriber.rs
+++ b/rs/moq-net/src/lite/subscriber.rs
@@ -2566,7 +2566,8 @@ struct AnnouncedRoute {
@@ -2842,7 +2842,8 @@ struct AnnouncedRoute {
/// without recomputing the chain.
route: crate::origin::Route,
/// Dropping it retracts the route and rejects its queued requests.
- dynamic: crate::origin::Dynamic,
+ // MUTATION: never dropped, so a route outlives the session that announced it.
+ dynamic: std::mem::ManuallyDrop<crate::origin::Dynamic>,
/// One minted source per requested path, finished on a clean retraction and
/// aborted (via drop) when the session dies.
/// One minted source per requested path, each closed when its guard drops.
sources: HashMap<PathOwned, crate::model::broadcast::SourceGuard>,
@@ -2578,7 +2579,7 @@ impl AnnouncedRoute {
fn new(route: crate::origin::Route, dynamic: crate::origin::Dynamic) -> Self {
/// Whether the GOAWAY drain already re-priced this route.
@@ -2858,7 +2859,7 @@ impl AnnouncedRoute {
fn new(route: crate::origin::Route, dynamic: crate::origin::Dynamic, wake: Arc<RouteWake>) -> Self {
Self {
route,
- dynamic,
+ dynamic: std::mem::ManuallyDrop::new(dynamic),
sources: HashMap::new(),
drained: false,
}
waker: std::task::Waker::from(wake.clone()),
18 changes: 8 additions & 10 deletions test/drill/mutations/subscriber-leaks-broadcasts.patch
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
#
# Removes the release a subscribing session performs when it ends: each announce
# stream's `Announced` collection owns the routes and source guards for every
# broadcast the session fed, and dropping it aborts them. Wrapping it in
# `ManuallyDrop` keeps every handle downstream of it alive after the session is
# gone, so a cancelled reader's broadcast parks forever instead of closing.
# broadcast the session fed, and dropping it retracts and closes them. Wrapping
# it in `ManuallyDrop` keeps every handle downstream of it alive after the session
# is gone, so a cancelled reader's broadcast parks forever instead of closing.
diff --git a/rs/moq-net/src/lite/subscriber.rs b/rs/moq-net/src/lite/subscriber.rs
index 729a23e4b..54aa7a5be 100644
index 8a0259fec..92febbcdf 100644
--- a/rs/moq-net/src/lite/subscriber.rs
+++ b/rs/moq-net/src/lite/subscriber.rs
@@ -1087,7 +1087,8 @@ struct PrefixRun {
@@ -1142,7 +1142,8 @@ struct PrefixRun {
/// it comes from the connect config or the peer's SETUP, neither of which
/// changes for the life of the session.
link_cost: u64,
Expand All @@ -19,13 +19,11 @@ index 729a23e4b..54aa7a5be 100644
+ announced: std::mem::ManuallyDrop<Announced>,
// Lite06+: announce ids. Each received `active` implicitly assigns the next
// per-stream ordinal; `ended`/`restart` reference it instead of repeating the
// path. Tracked even for announces we drop locally (reflected loops), since
@@ -1175,7 +1176,7 @@ impl<S: crate::transport::poll::Session> AnnouncePrefix<S> {
let run = PrefixRun {
// path, and lite-07 bases name it too. Tracked even for announces we drop
@@ -1233,5 +1234,5 @@ impl<S: crate::transport::poll::Session> AnnouncePrefix<S> {
responder_origin,
link_cost,
- announced: Announced::default(),
+ announced: std::mem::ManuallyDrop::new(Announced::default()),
next_announce_id: 0,
announced_by_id: HashMap::new(),
decoder: lite::AnnounceDecoder::default(),
};
23 changes: 23 additions & 0 deletions test/drill/sensitivity.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ CARGO=cargo

KEEP=0
BASELINE=1
APPLY_ONLY=0
SELECTED=()
dir=
log=
Expand Down Expand Up @@ -68,6 +69,7 @@ Options:
--list list the mutations and the drill each one must break
--keep keep the mutated snapshots (prints each path)
--no-baseline skip the unmutated run of each drill
--apply-only only check that each mutation still applies; builds nothing
-h, --help this

With no mutation named, every mutation runs.
Expand All @@ -88,6 +90,10 @@ while [[ $# -gt 0 ]]; do
BASELINE=0
shift
;;
--apply-only)
APPLY_ONLY=1
shift
;;
-h | --help)
usage
exit 0
Expand Down Expand Up @@ -157,6 +163,14 @@ for patch in "$MUTATIONS"/*.patch; do
checked=$((checked + 1))
echo "=== $name -> $drill"

if [[ $APPLY_ONLY -eq 1 ]]; then
if ! patch -p1 -d "$WORKSPACE" --dry-run --batch --forward --silent <"$patch"; then
echo " FAIL: '$name' does not apply to this tree" >&2
failed=$((failed + 1))
fi
continue
fi

if [[ $BASELINE -eq 1 ]]; then
log=$(mktemp "${TMPDIR:-/tmp}/drill-baseline.XXXXXX")
status=$(run_drill "$WORKSPACE" "$drill" "$log")
Expand Down Expand Up @@ -221,6 +235,15 @@ if [[ $checked -eq 0 ]]; then
exit 2
fi

if [[ $APPLY_ONLY -eq 1 ]]; then
if [[ $failed -gt 0 ]]; then
echo "$failed of $checked mutations do not apply; retarget them at the current code" >&2
exit 1
fi
echo "$checked of $checked mutations apply"
exit 0
fi

if [[ $failed -gt 0 ]]; then
echo "$failed of $checked mutations did not prove sensitivity" >&2
exit 1
Expand Down
Loading