Files

27 lines
1.9 KiB
Python
Raw Permalink Normal View History

import json,subprocess
from application_harness import Application,PHP,ROOT
for operation in ['activate','deactivate']:
app=Application();workers=[]
try:
ids=app.fixture('tenantSeed');env=app.env.copy();env['HCR_TENANT_IDS']=json.dumps(ids)
record=app.fixture('repairConcurrencySeed',str(ids['clubA']),str(ids['invitee']),str(ids['admina']))
for mode,ident,ready in [(operation,record['membership'],'LOCKED'),('accept',record['invitation'],'WAITING')]:
p=subprocess.Popen(PHP+['tests/tenant_repair_worker.php',mode,str(ident)],cwd=ROOT,env=env,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE,text=True);workers.append(p)
assert p.stdout.readline().strip()==ready,p.stderr.read()
workers[0].stdin.write('go\n');workers[0].stdin.flush();results=[]
for p in workers:
output,error=p.communicate(timeout=20);assert p.returncode==0,error+output;results.append(json.loads(output))
if operation=='activate':
assert all(x['ok'] for x in results),results
assert sum(x['user_serial']==ids['invitee'] and x['club_serial']==ids['clubA'] for x in app.fixture('inspect')['club_memberships'])==1
print('PASS: Invitation acceptance racing membership activation completes both requests without duplicate membership.')
else:
assert results[0]['ok'] and not results[1]['ok'] and results[1]['status']==404,results
member=next(x for x in app.fixture('inspect')['club_memberships'] if x['membership_serial']==record['membership']);assert member['membership_status']=='inactive'
print('PASS: Membership deactivation racing acceptance revokes the invitation and preserves denied access.')
finally:
for p in workers:
if p.poll() is None:p.terminate();p.wait(timeout=10)
app.close()
print('2 tenant repair concurrency scenarios passed.')