mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-10-28 22:52:00 +08:00
Bulk rebuild candidate indexes and retain concurrent config edits
This commit is contained in:
@@ -5,6 +5,7 @@ const {CodeGraph,createExtensionProject,packExtension}=require('../../dist');con
|
||||
const {DatabaseSync}=require('node:sqlite');
|
||||
Object.assign(process.env,{CODEGRAPH_TELEMETRY:'0',CODEGRAPH_PARSE_WORKERS:'2',CODEGRAPH_RESOLVE_WORKERS:'2',CODEGRAPH_PARALLEL_RESOLVE_MIN:'0'});
|
||||
const phases=['candidate_ready','before_commit','copy_started','in_commit','committed'];
|
||||
function schema(root){const db=new DatabaseSync(path.join(root,'.codegraph/codegraph.db'),{readOnly:true});try{return db.prepare("SELECT name,sql FROM sqlite_master WHERE type IN ('index','trigger') AND sql IS NOT NULL ORDER BY name").all().map(r=>[r.name,r.sql])}finally{db.close()}}
|
||||
function ftsAdded(root){const db=new DatabaseSync(path.join(root,'.codegraph/codegraph.db'),{readOnly:true});try{return db.prepare("SELECT count(*) n FROM nodes_fts WHERE nodes_fts MATCH 'added_function'").get().n}finally{db.close()}}
|
||||
function snapshot(root){const db=new DatabaseSync(path.join(root,'.codegraph/codegraph.db'),{readOnly:true});try{return db.prepare("select a.name source,b.name target from edges e join nodes a on a.id=e.source join nodes b on b.id=e.target where e.metadata like '%\"synthesizedBy\":\"kill-fixture\"%' order by a.name,b.name").all().map(r=>[r.source,r.target]);}finally{db.close()}}
|
||||
if(process.argv[2]==='--child'){
|
||||
@@ -25,15 +26,15 @@ if(process.argv[2]==='--child'){
|
||||
try{
|
||||
const author=path.join(lab,'author');createExtensionProject(author,'kill-fixture');const manifest=JSON.parse(fs.readFileSync(path.join(author,'package.json'),'utf8'));manifest.codegraph.capabilities=['synthPasses'];fs.writeFileSync(path.join(author,'package.json'),JSON.stringify(manifest));
|
||||
fs.writeFileSync(path.join(author,'index.cjs'),`module.exports=()=>({synthPasses:[{name:'binding',languages:['python'],run(ctx){const name=(ctx.readFile('binding.py')||'').trim();const a=ctx.getNodesByName('dispatch'),b=ctx.getNodesByName(name);if(a.length!==1||b.length!==1)return [];return [{source:a[0].id,target:b[0].id,kind:'calls',metadata:{label:'fixture'}}]}}]});`);const bytes=packExtension(author);
|
||||
for(const phase of phases){const root=path.join(lab,phase);fs.mkdirSync(root);fs.writeFileSync(path.join(root,'handlers.py'),'def dispatch():\n missing()\ndef receipt():\n pass\ndef cancel():\n pass\n');fs.writeFileSync(path.join(root,'binding.py'),'receipt');await new ExtensionManager(root).install({bytes});const config=fs.readFileSync(path.join(root,'codegraph.json'),'utf8');
|
||||
for(const phase of phases){const root=path.join(lab,phase);fs.mkdirSync(root);fs.writeFileSync(path.join(root,'handlers.py'),'def dispatch():\n missing()\ndef receipt():\n pass\ndef cancel():\n pass\n');fs.writeFileSync(path.join(root,'binding.py'),'receipt');await new ExtensionManager(root).install({bytes});const custom=new DatabaseSync(path.join(root,'.codegraph/codegraph.db'));custom.exec('CREATE INDEX user_fixture_name ON nodes(name)');custom.close();const originalSchema=schema(root);const config=fs.readFileSync(path.join(root,'codegraph.json'),'utf8');
|
||||
const reader=await CodeGraph.open(root);assert.deepEqual(snapshot(root),[['dispatch','receipt']]);reader.getNodesByKind('function');
|
||||
const c=child(root,'update',phase);let timer;try{await Promise.race([c.reached,c.done.then(r=>{throw Error('child ended '+r.stderr)}),new Promise((_,r)=>timer=setTimeout(()=>r(Error('timeout '+phase)),90000))])}finally{clearTimeout(timer)}
|
||||
const expected=phase==='committed'?'cancel':'receipt';assert.deepEqual(snapshot(root),[['dispatch',expected]]);assert.ok(reader.getStats().nodeCount>0);assert.equal(ftsAdded(root),phase==='committed'?1:0);
|
||||
const expected=phase==='committed'?'cancel':'receipt';assert.deepEqual(snapshot(root),[['dispatch',expected]]);assert.ok(reader.getStats().nodeCount>0);assert.equal(ftsAdded(root),phase==='committed'?1:0);assert.deepEqual(schema(root),originalSchema);
|
||||
const concurrent=await child(root,'retry').done;assert.notEqual(concurrent.exit,0);assert.match(concurrent.stderr,/operation is active/);
|
||||
assert.equal(c.p.kill('SIGKILL'),true);const killed=await c.done;assert.ok(killed.signal==='SIGKILL'||(process.platform==='win32'&&killed.exit!==0));
|
||||
fs.writeFileSync(path.join(root,'keep.txt'),'unrelated user file');const inspect=await child(root,'inspect').done;assert.equal(inspect.exit,0,inspect.stderr);assert.deepEqual(snapshot(root),[['dispatch',expected]]);assert.equal(ftsAdded(root),phase==='committed'?1:0);
|
||||
fs.writeFileSync(path.join(root,'keep.txt'),'unrelated user file');const inspect=await child(root,'inspect').done;assert.equal(inspect.exit,0,inspect.stderr);assert.deepEqual(snapshot(root),[['dispatch',expected]]);assert.equal(ftsAdded(root),phase==='committed'?1:0);assert.deepEqual(schema(root),originalSchema);
|
||||
assert.equal(fs.existsSync(path.join(root,'.codegraph/plugins/candidate.json')),false);assert.deepEqual(fs.readdirSync(path.join(root,'.codegraph')).filter(f=>f.startsWith('extension-stage-')),[]);
|
||||
assert.equal((await child(root,'inspect').done).exit,0);assert.equal((await child(root,'retry').done).exit,0);assert.deepEqual(snapshot(root),[['dispatch','cancel']]);assert.equal(ftsAdded(root),1);
|
||||
assert.equal((await child(root,'inspect').done).exit,0);assert.equal((await child(root,'retry').done).exit,0);assert.deepEqual(snapshot(root),[['dispatch','cancel']]);assert.equal(ftsAdded(root),1);assert.deepEqual(schema(root),originalSchema);
|
||||
const funcs=reader.getNodesByKind('function');const names=new Map(funcs.map(n=>[n.id,n.name]));assert.deepEqual(reader.getOutgoingEdgesFrom(funcs.map(n=>n.id)).filter(e=>e.metadata?.synthesizedBy==='kill-fixture').map(e=>[names.get(e.source),names.get(e.target)]),[['dispatch','cancel']]);reader.close();
|
||||
assert.equal(fs.readFileSync(path.join(root,'codegraph.json'),'utf8'),config);assert.equal(fs.readFileSync(path.join(root,'keep.txt'),'utf8'),'unrelated user file');rows.push({phase,passed:true,edgesAfterKill:expected,concurrentExcluded:true,repeatedRecovery:true,readerFresh:true});save();console.log('PASS',phase);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user