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" ]
@@ -305,14 +305,22 @@ async fn vlt_pinned_matrix_migration_hosted_then_vendored() {
305305 fx. vlt_ok ( & fx. proj , & fx. leg . locked_install_args ( ) ) ;
306306 for driver in [ "scan" , "vendor" ] {
307307 let dir = copy_project ( & fx, & fx. proj , & format ! ( "drv-{driver}" ) ) ;
308- let out = if driver == "scan" {
309- vendored_scan ( & fx, & dir, & [ ] )
310- } else {
308+ let eject = driver == "vendor" ;
309+ let out = if eject {
311310 stage_manifest ( & dir, & [ fx. t ( ) ] ) ;
312- 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, & [ ] )
313321 } ;
314322 assert_eq ! ( out. code, 0 , "{driver}: {out}" ) ;
315- assert_vendored_over_hosted ( driver, & out) ;
323+ assert_vendored_over_hosted ( eject , driver, & out) ;
316324 assert_pure_vendored ( & dir, fx. t ( ) ) ;
317325 assert_fresh (
318326 & fx,
@@ -332,28 +340,24 @@ async fn vlt_pinned_matrix_migration_hosted_then_vendored() {
332340 fx. leg . ran ( ) ;
333341}
334342
335- /// The wet hosted → vendored advisory for `driver` . `scan --mode vendored`
336- /// announces its per-purl takeover; plain `vendor` with a hosted pin in
337- /// scope runs the eject instead, which announces no takeover but, having
338- /// healed the warm vlt store, asks for a `vlt install`.
339- fn assert_vendored_over_hosted ( driver : & str , out : & SocketOut ) {
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 ) {
340348 let doc = out. json ( ) ;
341- assert ! ( !has_code( & doc, "redirect_revert_failed" ) , "{driver}: {out}" ) ;
342- if driver == "scan" {
343- assert ! (
344- has_code( & doc, "vendor_takeover_reverted_redirect" ) ,
345- "{driver}: {out}"
346- ) ;
347- } else {
348- assert ! (
349- !has_code( & doc, "vendor_takeover_reverted_redirect" ) ,
350- "{driver}: the eject is not a takeover: {out}"
351- ) ;
352- assert ! (
353- has_code( & doc, "redirect_vlt_reinstall_required" ) ,
354- "{driver}: {out}"
355- ) ;
356- }
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+ ) ;
357361}
358362
359363fn vendor_revert_all ( dir : & Path ) -> SocketOut {
@@ -363,8 +367,8 @@ fn vendor_revert_all(dir: &Path) -> SocketOut {
363367// ── 3. dry-run parity ─────────────────────────────────────────────────────
364368
365369/// Over a live hosted redirect `vendor --dry-run` previews the eject of
366- /// the hosted pin (`eject_planned`) and `scan --mode vendored --dry-run` says `would_vendor`; over a live
367- /// vendored state `scan --mode hosted --dry-run` previews
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
368372/// `redirect_would_revert_vendored`. No preview writes a byte, and the wet
369373/// runs then do what was previewed.
370374#[ tokio:: test( flavor = "multi_thread" ) ]
@@ -382,7 +386,18 @@ async fn vlt_pinned_matrix_migration_dry_run_parity() {
382386 let out = vendor_upstream ( & fx, & fx. proj , & [ "--dry-run" ] ) ;
383387 assert_eq ! ( out. code, 0 , "{out}" ) ;
384388 let doc = out. json ( ) ;
385- assert ! ( has_code( & doc, "eject_planned" ) , "{out}" ) ;
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 ( ) ;
397+ assert ! (
398+ planned. len( ) == 1 && planned[ 0 ] [ "purl" ] == fx. t( ) . purl( ) ,
399+ "one eject planned, for the hosted pin only: {out}"
400+ ) ;
386401 assert ! ( !has_code( & doc, "vendor_would_revert_redirect" ) , "{out}" ) ;
387402 assert ! ( !out. stdout. contains( "vendor_lock_entry_not_found" ) , "{out}" ) ;
388403 let out = vendored_scan ( & fx, & fx. proj , & [ "--dry-run" ] ) ;
@@ -405,7 +420,7 @@ async fn vlt_pinned_matrix_migration_dry_run_parity() {
405420 ) ;
406421 let out = vendor_upstream ( & fx, & fx. proj , & [ ] ) ;
407422 assert_eq ! ( out. code, 0 , "{out}" ) ;
408- assert_vendored_over_hosted ( "vendor" , & out) ;
423+ assert_vendored_over_hosted ( true , "vendor" , & out) ;
409424 assert_pure_vendored ( & fx. proj , fx. t ( ) ) ;
410425 let before = project_bytes ( & fx. proj ) ;
411426 let out = hosted_scan ( & fx, & fx. proj , & [ "--dry-run" ] ) ;
0 commit comments