← back to Tk11438 Postgres Migration

verification/ken-rollout/rollback-test.cjs

22 lines

// Fault-inject the actual launchd recovery branch without system tools or live IO.
const fs=require('fs'),vm=require('vm'),assert=require('assert/strict');
const source=fs.readFileSync(__dirname+'/rollout.cjs','utf8');
const start=source.indexOf("  if(fs.existsSync(OUT+'/reload-started.json')){");
const end=source.indexOf("  record('rollback'",start);assert(start>0&&end>start);
const branch=source.slice(start,end),results=[];
for(const state of ['loaded','unloaded','unexpected-error']){
 const calls=[],records=[];const old='postgresql://localhost:5432/ken';
 const context={OUT:'/fake',PRIV:'/fake/private',PLIST:'/fake/canary.plist',assert,JSON,process:{getuid:()=>501},fs:{existsSync:()=>true},cp:{spawnSync:()=>state==='loaded'?{status:0}:state==='unloaded'?{status:113,stderr:'Could not find service'}:{status:1,stderr:'Permission denied'}},record:(name,v)=>records.push({name,...v}),run:(cmd,args)=>{calls.push({cmd,args});if(cmd==='/usr/bin/plutil')return JSON.stringify({EnvironmentVariables:{KEN_DATABASE_URL:old}});if(args[0]==='print')return 'KEN_DATABASE_URL => '+old+'\n';return '';}};
 let error;try{vm.runInNewContext(branch,context,{timeout:1000});}catch(e){error=e;}
 if(state==='unexpected-error'){assert(error);assert(!calls.length);}else{assert(!error);assert.equal(calls.filter(x=>x.args[0]==='bootstrap').length,1);assert.equal(calls.filter(x=>x.args[0]==='bootout').length,state==='loaded'?1:0);assert.equal(records[0].verdict,'PASS');}
 results.push({scenario:state,verdict:'PASS'});
}
const forwardStart=source.indexOf("  record('reload-started',{target,prior_loaded:true,phase:'before-bootout'});");
const forwardEnd=source.indexOf(" }else if(mode===",forwardStart);assert(forwardStart>0&&forwardEnd>forwardStart);
const journal=[],calls=[];let failed=false;
try{vm.runInNewContext(source.slice(forwardStart,forwardEnd),{target:'gui/501/test',PLIST:'/fake',process:{getuid:()=>501},record:(name,v)=>journal.push({name,...v}),run:(cmd,args)=>{calls.push(args[0]);if(args[0]==='bootstrap')throw Error('injected bootstrap failure');return '';},assert,URL},{timeout:1000});}catch(e){failed=true;}
assert(failed);assert.deepEqual(calls,['bootout','bootstrap']);assert.equal(journal.at(-1).phase,'bootout-complete');assert(journal.every(x=>x.name==='reload-started'));
results.push({scenario:'bootstrap-failure-retains-recovery-journal',verdict:'PASS'});
fs.writeFileSync(__dirname+'/rollback-fault-proof.json',JSON.stringify({at:new Date().toISOString(),results,live_commands:0},null,2)+'\n');
console.log(JSON.stringify(results));