test: exercise real cross-tab replay coordinator
This commit is contained in:
parent
4a6a829401
commit
e92e476f49
|
|
@ -5,11 +5,13 @@ from pathlib import Path
|
||||||
|
|
||||||
FRONTEND = Path(__file__).parents[1] / "frontend"
|
FRONTEND = Path(__file__).parents[1] / "frontend"
|
||||||
CONTROLLER = FRONTEND / "week-plan.js"
|
CONTROLLER = FRONTEND / "week-plan.js"
|
||||||
|
COORDINATOR = FRONTEND / "outbox-coordinator.js"
|
||||||
|
|
||||||
|
|
||||||
def run_controller(scenario: str) -> dict:
|
def run_controller(scenario: str) -> dict:
|
||||||
harness = f"""
|
harness = f"""
|
||||||
const createWeekPlan = require({json.dumps(str(CONTROLLER))});
|
const createWeekPlan = require({json.dumps(str(CONTROLLER))});
|
||||||
|
const createOutboxCoordinator = require({json.dumps(str(COORDINATOR))});
|
||||||
(async()=>{{ {scenario} }})().catch(error=>{{console.error(error);process.exit(1);}});
|
(async()=>{{ {scenario} }})().catch(error=>{{console.error(error);process.exit(1);}});
|
||||||
"""
|
"""
|
||||||
completed = subprocess.run(["node", "-e", harness], check=True, capture_output=True, text=True)
|
completed = subprocess.run(["node", "-e", harness], check=True, capture_output=True, text=True)
|
||||||
|
|
@ -402,10 +404,12 @@ def test_week_controller_allows_only_one_tab_to_replay_the_shared_pull_queue():
|
||||||
result = run_controller("""
|
result = run_controller("""
|
||||||
const values=new Map(),held=new Set();
|
const values=new Map(),held=new Set();
|
||||||
const storage={getItem:key=>values.get(key)||null,setItem:(key,value)=>values.set(key,value),removeItem:key=>values.delete(key)};
|
const storage={getItem:key=>values.get(key)||null,setItem:(key,value)=>values.set(key,value),removeItem:key=>values.delete(key)};
|
||||||
const coordinator={runExclusive:async(queue,work)=>{
|
const locks={request:async(name,_options,work)=>{
|
||||||
if(held.has(queue))return {lease_skipped:true};
|
if(held.has(name))return work(null);
|
||||||
held.add(queue);try{return await work();}finally{held.delete(queue);}
|
held.add(name);try{return await work({name});}finally{held.delete(name);}
|
||||||
}};
|
}};
|
||||||
|
const coordinatorA=createOutboxCoordinator({storage,locks,channelFactory:null,tabId:'a'});
|
||||||
|
const coordinatorB=createOutboxCoordinator({storage,locks,channelFactory:null,tabId:'b'});
|
||||||
let offline=true,posts=0,release;
|
let offline=true,posts=0,release;
|
||||||
const gate=new Promise(resolve=>release=resolve);
|
const gate=new Promise(resolve=>release=resolve);
|
||||||
const fetchJson=async(_url,options={})=>{
|
const fetchJson=async(_url,options={})=>{
|
||||||
|
|
@ -415,11 +419,11 @@ const fetchJson=async(_url,options={})=>{
|
||||||
return {today:{revision:5,ids:['active',body.identity],capacity_minutes:180,estimates:{active:30,[body.identity]:35}},
|
return {today:{revision:5,ids:['active',body.identity],capacity_minutes:180,estimates:{active:30,[body.identity]:35}},
|
||||||
week:{revision:8,timezone:'UTC',days:[{plan_date:'2026-08-21',ids:[],capacity_minutes:150,estimates:{}}]}};
|
week:{revision:8,timezone:'UTC',days:[{plan_date:'2026-08-21',ids:[],capacity_minutes:150,estimates:{}}]}};
|
||||||
};
|
};
|
||||||
const options={storage,coordinator,getLogin:()=> 'timmy',fetchJson,localDate:()=> '2026-08-20',timeZone:()=> 'UTC'};
|
const options={storage,getLogin:()=> 'timmy',fetchJson,localDate:()=> '2026-08-20',timeZone:()=> 'UTC'};
|
||||||
const source=createWeekPlan(options);source.adopt({revision:7,timezone:'UTC',days:[{plan_date:'2026-08-21',ids:['first'],capacity_minutes:150,estimates:{first:35}}]});
|
const source=createWeekPlan({...options,coordinator:coordinatorA});source.adopt({revision:7,timezone:'UTC',days:[{plan_date:'2026-08-21',ids:['first'],capacity_minutes:150,estimates:{first:35}}]});
|
||||||
await source.pullItem('first',{revision:4,ids:['active'],capacity_minutes:180,estimates:{active:30}},'pull-first');
|
await source.pullItem('first',{revision:4,ids:['active'],capacity_minutes:180,estimates:{active:30}},'pull-first');
|
||||||
offline=false;
|
offline=false;
|
||||||
const first=createWeekPlan(options),second=createWeekPlan(options);
|
const first=createWeekPlan({...options,coordinator:coordinatorA}),second=createWeekPlan({...options,coordinator:coordinatorB});
|
||||||
const firstFlush=first.flushPull();
|
const firstFlush=first.flushPull();
|
||||||
await Promise.resolve();
|
await Promise.resolve();
|
||||||
setImmediate(release);
|
setImmediate(release);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user