• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/sh
2"exec" "`dirname $0`/py3-cmd" "$0" "-c" "`dirname $0`/config.json" "$@"
3
4import argparse
5import logging
6import os
7from typing import List, Optional
8import sys
9
10
11import qemu
12import qemu_error
13
14__all__ = ["init", "run_test", "shutdown"]
15
16
17TRUSTY_PROJECT_FOLDER = os.path.dirname(os.path.realpath(__file__))
18
19
20def init(*, android=None, instance_dir: os.PathLike, disable_rpmb=False,
21         verbose=False, debug_on_error=False
22) -> qemu.Runner:
23
24    with open(f"{TRUSTY_PROJECT_FOLDER}/config.json", encoding="utf-8") as json:
25        config = qemu.Config(json)
26
27    if android:
28        config.android_image_dir = qemu.find_android_image_dir(android)
29        config.adb = qemu.find_adb_path(android)
30        config.boot_android = True
31
32    runner = qemu.Runner(config,
33                         interactive=False,
34                         instance_dir=instance_dir,
35                         verbose=verbose,
36                         rpmb=not disable_rpmb,
37                         debug=False,
38                         debug_on_error=debug_on_error)
39    return runner
40
41
42def _check_args(args):
43    """Validate arguments passed to run_test."""
44    assert args.headless, args
45    assert not args.linux, args
46    assert not args.initrd, args
47    assert not args.atf, args
48    assert not args.qemu, args
49    assert not args.arch, args
50    assert not args.debug, args
51    assert not args.extra_linux_args, args
52    assert not args.extra_qemu_flags, args
53    assert not args.disable_rpmb, args
54
55
56def _prepare_runner_for_test(runner, args):
57    """Check if the runner is in the correct state (BOOTLOADER, ANDROID)
58    to run a given test and reboot the emulator if it is not.
59
60    TODO: Remove the unconditional reboot after boot tests once the test harness
61          no longers requires it.
62    """
63    if args.boot_test:
64        target_state = qemu.RunnerState.BOOTLOADER
65    elif args.shell_command or args.host_command:
66        target_state = qemu.RunnerState.ANDROID
67    else:
68        raise qemu_error.ConfigError(
69            "Command must request exactly one Android, boot test, or"
70            " host command to run"
71        )
72
73    # Due to limitations in the test runner, always reboot between boot tests
74    if (runner.state != target_state or
75            runner.state == qemu.RunnerState.BOOTLOADER):
76        runner.reboot(target_state, factory_reset=True, full_wipe=False)
77
78def run_test(runner: qemu.Runner, cmd: List[str]) -> int:
79    args = build_argparser().parse_args(cmd)
80    _check_args(args)
81    _prepare_runner_for_test(runner, args)
82
83    timeout = args.timeout if args.timeout else runner.default_timeout
84    if args.boot_test:
85        return runner.boottest_run(args.boot_test, timeout)
86    if args.shell_command:
87        return runner.androidtest_run(args.shell_command, timeout)
88    if args.host_command:
89        return runner.hostcommandtest_run(args.host_command[0], timeout)
90
91    raise qemu.RunnerGenericError(
92        "Command contained neither a boot test nor an Android test to run")
93
94
95def shutdown(runner: Optional[qemu.Runner],
96             factory_reset: bool = True,
97             full_wipe: bool = False):
98    if runner:
99        runner.shutdown(factory_reset, full_wipe)
100
101
102def build_argparser():
103    argument_parser = argparse.ArgumentParser()
104    argument_parser.add_argument("-c", "--config", type=argparse.FileType("r"))
105    argument_parser.add_argument("--headless", action="store_true")
106    argument_parser.add_argument("-v", "--verbose", action="store_true")
107    argument_parser.add_argument("--debug", action="store_true")
108    argument_parser.add_argument("--debug-on-error", action="store_true")
109    argument_parser.add_argument("--boot-test", action="append")
110    argument_parser.add_argument("--shell-command", action="append")
111    argument_parser.add_argument("--host-command", action="append")
112    argument_parser.add_argument("--android")
113    argument_parser.add_argument("--linux")
114    argument_parser.add_argument("--initrd")
115    argument_parser.add_argument("--instance-dir", type=str,
116                                 default="/tmp/trusty-qemu-generic-arm64")
117    argument_parser.add_argument("--atf")
118    argument_parser.add_argument("--qemu")
119    argument_parser.add_argument("--arch")
120    argument_parser.add_argument("--disable-rpmb", action="store_true")
121    argument_parser.add_argument("--timeout", type=int)
122    argument_parser.add_argument('-n', '--extra-linux-args', nargs='+', default=[])
123    argument_parser.add_argument("extra_qemu_flags", nargs="*")
124    return argument_parser
125
126
127def main():
128    args = build_argparser().parse_args()
129    log_level = logging.DEBUG if args.verbose else logging.WARN
130    logging.basicConfig(level=log_level)
131
132    config = qemu.Config(args.config)
133    if args.android:
134        config.android_image_dir = qemu.find_android_image_dir(args.android)
135        config.adb = qemu.find_adb_path(args.android)
136        config.boot_android = True
137    if args.linux:
138        config.linux = args.linux
139    if args.initrd:
140        config.initrd = args.initrd
141    if args.atf:
142        config.atf = args.atf
143    if args.qemu:
144        config.qemu = args.qemu
145    if args.arch:
146        config.arch = args.arch
147    if args.extra_linux_args:
148        config.extra_linux_args = args.extra_linux_args
149    if args.extra_qemu_flags:
150        config.extra_qemu_flags += args.extra_qemu_flags
151
152    runner = qemu.Runner(config,
153                         interactive=not args.headless,
154                         instance_dir=args.instance_dir,
155                         verbose=args.verbose,
156                         rpmb=not args.disable_rpmb,
157                         debug=args.debug,
158                         debug_on_error=args.debug_on_error)
159
160    try:
161        results = runner.run(args.boot_test, args.shell_command,
162                             args.host_command, args.timeout)
163        print("Command results: " + repr(results))
164
165        if any(results):
166            sys.exit(1)
167        else:
168            sys.exit(0)
169    except qemu_error.RunnerError as exn:
170        print(exn)
171        sys.exit(2)
172
173
174if __name__ == "__main__":
175    main()
176