52 lines
2.1 KiB
Python
52 lines
2.1 KiB
Python
#!/usr/bin/env python3
|
|
"""R7 mutants. Run only on Sage CLEAR in Lena's isolated candidate.
|
|
|
|
Every replacement must occur once. Product bytes are restored even on timeout
|
|
or failure. A killed mutant must contain the named assertion in the script's
|
|
output; startup errors and timeout alone are not evidence. The shell owns its
|
|
own timeout and EXIT/TERM cleanup. Do not put a killing Python timeout around it.
|
|
"""
|
|
from pathlib import Path
|
|
import subprocess
|
|
import sys
|
|
|
|
repo = Path(__file__).resolve().parents[4]
|
|
mutants = {
|
|
'M1': (
|
|
'packages/cli/src/access.mjs',
|
|
'projects: resolveProjects(list(parsed.values["--projects"]), rows),',
|
|
'projects: ["*"],',
|
|
'R7 ungranted project must not appear',
|
|
),
|
|
'M2': (
|
|
'packages/bus/src/broker.mjs',
|
|
"this.#claimEnd({ business: t.business }, h, 'revoke', null, 'access-revoked', by);",
|
|
"/* R7 mutant: skip ending the revoked claim */",
|
|
'R7 revoke must end the claim as access-revoked',
|
|
),
|
|
}
|
|
if len(sys.argv) != 2 or sys.argv[1] not in mutants:
|
|
raise SystemExit('usage: mutants.py M1|M2')
|
|
name = sys.argv[1]
|
|
file, before, after, assertion = mutants[name]
|
|
path = repo / file
|
|
original = path.read_bytes()
|
|
text = original.decode()
|
|
if text.count(before) != 1:
|
|
raise SystemExit(f'{name}: anchor count {text.count(before)}, expected 1')
|
|
try:
|
|
path.write_text(text.replace(before, after))
|
|
result = subprocess.run(['scripts/test-federation-acceptance.sh'], cwd=repo,
|
|
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
|
|
text=True)
|
|
print(result.stdout, end='')
|
|
if result.returncode == 0 or assertion not in result.stdout:
|
|
raise SystemExit(f'{name}: NOT KILLED by expected assertion')
|
|
if 'R7 cleanup: no child groups, ports or sockets remain; no units created' not in result.stdout:
|
|
raise SystemExit(f'{name}: cleanup not verified')
|
|
print(f'{name}: KILLED by {assertion}')
|
|
finally:
|
|
path.write_bytes(original)
|
|
if path.read_bytes() != original:
|
|
raise SystemExit(f'{name}: restore failed')
|