Skip to content

Commit 920f2f1

Browse files
committed
Merge main after #1752 landed
Assisted-by: Claude Code:claude-opus-5-5
2 parents d882a61 + eb094a5 commit 920f2f1

1 file changed

Lines changed: 62 additions & 27 deletions

File tree

‎crates/socket-patch-cli/tests/mode_migration_vlt.rs‎

Lines changed: 62 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
//! Real-vlt mode migrations (suite `migration`, DESIGN §8.3, §4.10).
22
//!
3-
//! Hosted ⇄ vendored takeovers (both drivers), dry-run parity, scoped and
4-
//! unscoped unwinds, agent-mode interplay (r-tests T21), package-manager
5-
//! switches (T37) and the vlt upgrade (T19, `SOCKET_PATCH_VLT_E2E_UPGRADE_JS`)
6-
//! against the REAL vlt under test, every terminal state proven by a fresh
7-
//! checkout's locked install. Each leg is `vlt_pinned_matrix_migration_<leg>`
3+
//! Hosted ⇄ vendored migrations (scan takeovers, the `vendor` eject),
4+
//! dry-run parity, scoped and unscoped unwinds, agent-mode interplay
5+
//! (r-tests T21), package-manager switches (T37) and the vlt upgrade (T19,
6+
//! `SOCKET_PATCH_VLT_E2E_UPGRADE_JS`) against the REAL vlt under test,
7+
//! every terminal state proven by a fresh checkout's locked install. Each leg is `vlt_pinned_matrix_migration_<leg>`
88
//! and prints one `VLT-LEG` line.
99
1010
#[path = "common/rollback_json.rs"]
@@ -111,7 +111,8 @@ fn api_upstream(fx: &Fixture, dir: &Path, head: &[&str], extra: &[&str]) -> Sock
111111
}
112112

113113
/// `vendor` over a (possibly) hosted project: no `--offline`, since the
114-
/// takeover restores the hosted pin's upstream entry first.
114+
/// eject fetches the hosted pin's record and restores its upstream entry
115+
/// first.
115116
fn vendor_upstream(fx: &Fixture, dir: &Path, extra: &[&str]) -> SocketOut {
116117
api_upstream(fx, dir, &["vendor"], extra)
117118
}
@@ -286,10 +287,12 @@ async fn vlt_pinned_matrix_migration_vendored_then_hosted() {
286287
fx.leg.ran();
287288
}
288289

289-
/// Hosted → vendored through `scan --mode vendored` and through `vendor`
290-
/// (a staged manifest): the takeover restores the hosted pin's upstream
291-
/// entry first, the lock is vendored, fresh checkouts are patched, and
292-
/// `vendor --revert` restores the pristine (upstream) lock.
290+
/// Hosted → vendored through `scan --mode vendored` (a per-purl takeover)
291+
/// and through `vendor` (a staged manifest, but a hosted pin is in scope,
292+
/// so `vendor` ejects the lockfile's hosted pin instead): either way the
293+
/// hosted pin's upstream entry is restored first, the lock is vendored,
294+
/// fresh checkouts are patched, and `vendor --revert` restores the
295+
/// pristine (upstream) lock.
293296
#[tokio::test(flavor = "multi_thread")]
294297
#[ignore = "real vlt: SOCKET_PATCH_VLT_E2E_JS"]
295298
async fn vlt_pinned_matrix_migration_hosted_then_vendored() {
@@ -302,17 +305,22 @@ async fn vlt_pinned_matrix_migration_hosted_then_vendored() {
302305
fx.vlt_ok(&fx.proj, &fx.leg.locked_install_args());
303306
for driver in ["scan", "vendor"] {
304307
let dir = copy_project(&fx, &fx.proj, &format!("drv-{driver}"));
305-
let out = if driver == "scan" {
306-
vendored_scan(&fx, &dir, &[])
307-
} else {
308+
let eject = driver == "vendor";
309+
let out = if eject {
308310
stage_manifest(&dir, &[fx.t()]);
309-
vendor_upstream(&fx, &dir, &[])
311+
let manifest = std::fs::read(dir.join(".socket/manifest.json")).unwrap();
312+
let out = vendor_upstream(&fx, &dir, &[]);
313+
assert_eq!(
314+
std::fs::read(dir.join(".socket/manifest.json")).unwrap(),
315+
manifest,
316+
"{driver}: the eject leaves the manifest untouched: {out}"
317+
);
318+
out
319+
} else {
320+
vendored_scan(&fx, &dir, &[])
310321
};
311322
assert_eq!(out.code, 0, "{driver}: {out}");
312-
assert!(
313-
has_code(&out.json(), "vendor_takeover_reverted_redirect"),
314-
"{driver}: {out}"
315-
);
323+
assert_vendored_over_hosted(eject, driver, &out);
316324
assert_pure_vendored(&dir, fx.t());
317325
assert_fresh(
318326
&fx,
@@ -332,15 +340,35 @@ async fn vlt_pinned_matrix_migration_hosted_then_vendored() {
332340
fx.leg.ran();
333341
}
334342

343+
/// The wet hosted → vendored advisories. `scan --mode vendored` announces
344+
/// its per-purl takeover; plain `vendor` with a hosted pin in scope
345+
/// (`eject`) runs the eject instead, which announces no takeover. Both
346+
/// heal the warm vlt store and ask for a `vlt install`.
347+
fn assert_vendored_over_hosted(eject: bool, tag: &str, out: &SocketOut) {
348+
let doc = out.json();
349+
assert_eq!(
350+
has_code(&doc, "vendor_takeover_reverted_redirect"),
351+
!eject,
352+
"{tag}: only the scan takeover announces a takeover: {out}"
353+
);
354+
// The eject reports a failed restore as a run error (exit 1); the scan
355+
// takeover reports it per event, so check it there.
356+
assert!(!has_code(&doc, "redirect_revert_failed"), "{tag}: {out}");
357+
assert!(
358+
has_code(&doc, "redirect_vlt_reinstall_required"),
359+
"{tag}: the warm vlt store is healed: {out}"
360+
);
361+
}
362+
335363
fn vendor_revert_all(dir: &Path) -> SocketOut {
336364
vendor_cmd(dir, &["--revert"])
337365
}
338366

339367
// ── 3. dry-run parity ─────────────────────────────────────────────────────
340368

341-
/// Over a live hosted redirect `vendor --dry-run` previews the takeover
342-
/// and `scan --mode vendored --dry-run` says `would_vendor`; over a live
343-
/// vendored state `scan --mode hosted --dry-run` previews
369+
/// Over a live hosted redirect `vendor --dry-run` previews the eject of
370+
/// the hosted pin (`eject_planned`) and `scan --mode vendored --dry-run`
371+
/// says `would_vendor`; over a live vendored state `scan --mode hosted --dry-run` previews
344372
/// `redirect_would_revert_vendored`. No preview writes a byte, and the wet
345373
/// runs then do what was previewed.
346374
#[tokio::test(flavor = "multi_thread")]
@@ -357,10 +385,20 @@ async fn vlt_pinned_matrix_migration_dry_run_parity() {
357385
let before = project_bytes(&fx.proj);
358386
let out = vendor_upstream(&fx, &fx.proj, &["--dry-run"]);
359387
assert_eq!(out.code, 0, "{out}");
388+
let doc = out.json();
389+
let planned: Vec<&Value> = doc["events"]
390+
.as_array()
391+
.map(|evs| {
392+
evs.iter()
393+
.filter(|e| e["errorCode"] == "eject_planned")
394+
.collect()
395+
})
396+
.unwrap_or_default();
360397
assert!(
361-
has_code(&out.json(), "vendor_would_revert_redirect"),
362-
"{out}"
398+
planned.len() == 1 && planned[0]["purl"] == fx.t().purl(),
399+
"one eject planned, for the hosted pin only: {out}"
363400
);
401+
assert!(!has_code(&doc, "vendor_would_revert_redirect"), "{out}");
364402
assert!(!out.stdout.contains("vendor_lock_entry_not_found"), "{out}");
365403
let out = vendored_scan(&fx, &fx.proj, &["--dry-run"]);
366404
assert_eq!(out.code, 0, "{out}");
@@ -382,10 +420,7 @@ async fn vlt_pinned_matrix_migration_dry_run_parity() {
382420
);
383421
let out = vendor_upstream(&fx, &fx.proj, &[]);
384422
assert_eq!(out.code, 0, "{out}");
385-
assert!(
386-
has_code(&out.json(), "vendor_takeover_reverted_redirect"),
387-
"{out}"
388-
);
423+
assert_vendored_over_hosted(true, "vendor", &out);
389424
assert_pure_vendored(&fx.proj, fx.t());
390425
let before = project_bytes(&fx.proj);
391426
let out = hosted_scan(&fx, &fx.proj, &["--dry-run"]);

0 commit comments

Comments
 (0)