1#!/usr/bin/env python3
2
3# This script expect to run from the Buildroot top directory.
4
5import os
6import pexpect
7import sys
8import time
9
10
11def main():
12    if not (len(sys.argv) == 2):
13        print("Error: incorrect number of arguments")
14        print("""Usage: boot-qemu-image.py <qemu_arch_defconfig>""")
15        sys.exit(1)
16
17    # Ignore non Qemu defconfig
18    if not sys.argv[1].startswith('qemu_'):
19        sys.exit(0)
20
21    if not os.path.exists('output/images/start-qemu.sh'):
22        print('qemu-start.sh is missing, cannot test.')
23        sys.exit(0)
24
25    qemu_start = os.path.join(os.getcwd(), 'output/images/start-qemu.sh')
26
27    child = pexpect.spawn(qemu_start, ['serial-only'],
28                          timeout=50, encoding='utf-8',
29                          env={"QEMU_AUDIO_DRV": "none"})
30
31    # We want only stdout into the log to avoid double echo
32    child.logfile = sys.stdout
33
34    # Let the spawn actually try to fork+exec to the wrapper, and then
35    # let the wrapper exec the qemu process.
36    time.sleep(1)
37
38    try:
39        child.expect(["buildroot login:"], timeout=600)
40    except pexpect.EOF as e:
41        # Some emulations require a fork of qemu-system, which may be
42        # missing on the system, and is not provided by Buildroot.
43        # In this case, spawn above will succeed at starting the wrapper
44        # start-qemu.sh, but that one will fail (exit with 127) in such
45        # a situation.
46        exit = [int(line.split(' ')[1])
47                for line in e.value.splitlines()
48                if line.startswith('exitstatus: ')]
49        if len(exit) and exit[0] == 127:
50            print('qemu-start.sh could not find the qemu binary')
51            sys.exit(0)
52        print("Connection problem, exiting.")
53        sys.exit(1)
54    except pexpect.TIMEOUT:
55        print("System did not boot in time, exiting.")
56        sys.exit(1)
57
58    child.sendline("root\r")
59
60    try:
61        child.expect(["# "], timeout=600)
62    except pexpect.EOF:
63        print("Cannot connect to shell")
64        sys.exit(1)
65    except pexpect.TIMEOUT:
66        print("Timeout while waiting for shell")
67        sys.exit(1)
68
69    child.sendline("poweroff\r")
70
71    try:
72        child.expect(["System halted"], timeout=600)
73        child.expect(pexpect.EOF)
74    except pexpect.EOF:
75        pass
76    except pexpect.TIMEOUT:
77        # Qemu may not exit properly after "System halted", ignore.
78        print("Cannot halt machine")
79
80    sys.exit(0)
81
82
83if __name__ == "__main__":
84    main()
85