import os
import select
import sys
import subprocess
SEND_AFTER = (b"Rust user shell", b">>")
SEND_LINE = b"usertests\n"
SUCCESS_MARKERS = (b"usertests passed!",)
def main():
try:
sep = sys.argv.index("--")
except ValueError:
print("Usage: ci_run_qemu_nimbos.py -- <command> [args...]", file=sys.stderr)
sys.exit(2)
cmd = sys.argv[sep + 1 :]
if not cmd:
print("No command after --", file=sys.stderr)
sys.exit(2)
import pty
master, slave = pty.openpty()
try:
proc = subprocess.Popen(
cmd,
stdin=slave,
stdout=slave,
stderr=slave,
close_fds=True,
)
finally:
os.close(slave)
sent = False
saw_success = False
buffer = b""
try:
while True:
r, _, _ = select.select([master], [], [], 0.1)
if r:
try:
chunk = os.read(master, 4096)
except OSError:
break
if not chunk:
break
sys.stdout.buffer.write(chunk)
sys.stdout.buffer.flush()
buffer = (buffer + chunk)[-1024:]
if not saw_success and any(marker in buffer for marker in SUCCESS_MARKERS):
saw_success = True
if not sent and any(trigger in buffer for trigger in SEND_AFTER):
try:
os.write(master, SEND_LINE)
sent = True
except OSError:
pass
if proc.poll() is not None:
while True:
r, _, _ = select.select([master], [], [], 0.05)
if not r:
break
try:
chunk = os.read(master, 4096)
except OSError:
break
if not chunk:
break
sys.stdout.buffer.write(chunk)
sys.stdout.buffer.flush()
break
finally:
os.close(master)
if saw_success:
sys.exit(0)
sys.exit(proc.returncode if proc.returncode is not None else 1)
if __name__ == "__main__":
main()