# Row 77 mutants: each edit applied alone to , the service and pinned-copy # tests run, the file restored. Usage: python3 mutants.py import subprocess, shutil, sys W=sys.argv[1] # the tree with the candidate applied S='scripts/webui-service.sh' M=[ ('failed counts as running', S, '&& $3 != "failed" {', '{'), ('reloading not running', S, '$3 != "failed" {', '$3 != "failed" && $3 != "reloading" {'), ('list-units failure ignored', S, '2>/dev/null)" || die "refusing: systemctl --user list-units', '2>/dev/null)" || true; : "refusing: systemctl --user list-units'), ('install skips state read', S, ' state="$(running)" || exit 1\n [ -z "$state" ] || die "refusing: $UNIT_NAME is running', ' state=""\n [ -z "$state" ] || die "refusing: $UNIT_NAME is running'), ('uninstall skips state read with --no-reload', S, '[ -z "$state" ] || die "refusing: $UNIT_NAME is still running', '[ -z "$state" ] || [ "$RELOAD" = 0 ] || die "refusing: $UNIT_NAME is still running'), ('uid header case-sensitive', S, '"${AUTH_HEADER,,}" = x-authentik-uid', '"$AUTH_HEADER" = X-authentik-uid'), ('uid allows upper hex', S, '^[0-9a-f]{64}$ ]]; then', '^[0-9a-fA-F]{64}$ ]]; then'), ('allowed user may start with -', S, 'case "$ALLOW_USER" in [A-Za-z0-9]*) ;;', 'case "$ALLOW_USER" in *) ;;'), ('no --checkout in unit', S, 'flags="--checkout $REPO $flags"', 'flags="$flags"'), ('canonical always passes', S, '[ -d "$REPO/.git" ] || [ "$ALLOW_WORKTREE" = 1 ] ||', 'true ||'), ('install without --copy', S, '[ -n "$COPY_ID" ] || die "install needs --copy ID', 'true || die "install needs --copy ID'), ('missing copy accepted', S, '[ -f "$COPIES/$COPY_ID/packages/webui/src/cli.mjs" ] ||', 'true ||'), ('status drift wrong', S, 'if [ "$head" = "$copy" ]; then', 'if true; then'), ('copy misses seat', S, ' packages/seat/src\n', ''), ('copy stays writable', S, '-exec chmod a-w', '-exec true'), ('copy off-branch accepted', S, 'merge-base --is-ancestor "$id" refs/heads/refactor ||', 'true ||'), ('queue reads root', 'packages/webui/src/reads.mjs', 'root: queueRoot', 'root'), ('--checkout relative ok', 'packages/webui/src/cli.mjs', 'isAbsolute(', '!!('), ] res=[] for name,f,a,b in M: p=f'{W}/{f}'; s=open(p).read() if s.count(a)<1: res.append(f'NOMATCH {name}'); continue shutil.copy(p,p+'.bak'); open(p,'w').write(s.replace(a,b)) try: r=subprocess.run(['node','--test','tests/service.test.mjs','tests/pinned-copy.test.mjs'],cwd=f'{W}/packages/webui',capture_output=True,text=True,timeout=300) fails=[l for l in r.stdout.splitlines() if l.startswith('✖') and 'failing tests' not in l] res.append(f"{'KILLED' if r.returncode else 'SURVIVED'} {name}: {len(set(fails))} failing") finally: shutil.move(p+'.bak',p) print('\n'.join(res))