Commit e5e7dc37 authored by Ben Pastene's avatar Ben Pastene Committed by Commit Bot

Add a host-side mode of execution for cros vm test runner.

This will add a positional arg to run_vm_test.py that can take one of two
values:

- "host-cmd": Runs a command on the host. Just launches the vm then
immediately calls the passed in cmd on the host. It's assumed the cmd will
handle data deps, ssh commands, etc.

- "vm-test": Runs a test in the vm. Takes care of spawning the vm, pushing
the test and its deps to the vm, executing the test, and tears down the vm.
(This is the current default behavior.)

Bug: 832374
Change-Id: Ib8bd1b2e7dd393f8a4578979fa164381a8342ef2
Reviewed-on: https://chromium-review.googlesource.com/1038747
Commit-Queue: Ben Pastene <bpastene@chromium.org>
Reviewed-by: default avatarDirk Pranke <dpranke@chromium.org>
Cr-Commit-Position: refs/heads/master@{#555279}
parent 7b1f5a88
...@@ -58,16 +58,30 @@ def main(args): ...@@ -58,16 +58,30 @@ def main(args):
run_test_path = RelativizePathToScript( run_test_path = RelativizePathToScript(
os.path.join(os.path.dirname(__file__), 'run_vm_test.py')) os.path.join(os.path.dirname(__file__), 'run_vm_test.py'))
vm_test_args = [ vm_test_args = [
'--board', args.board, '--board', args.board,
'--test-exe', args.test_exe,
'-v', '-v',
] ]
if args.test_exe:
vm_test_args.extend([
'vm-test',
'--test-exe',
args.test_exe,
])
else:
vm_test_args.append('host-cmd')
vm_test_path_args = [ vm_test_path_args = [
('--path-to-outdir', RelativizePathToScript(args.output_directory)),
('--runtime-deps-path', RelativizePathToScript(args.runtime_deps_path)),
('--cros-cache', RelativizePathToScript(args.cros_cache)), ('--cros-cache', RelativizePathToScript(args.cros_cache)),
] ]
if args.runtime_deps_path:
vm_test_path_args.append(
('--runtime-deps-path', RelativizePathToScript(args.runtime_deps_path)))
if args.output_directory:
vm_test_path_args.append(
('--path-to-outdir', RelativizePathToScript(args.output_directory)))
with open(args.script_output_path, 'w') as script: with open(args.script_output_path, 'w') as script:
script.write(SCRIPT_TEMPLATE.format( script.write(SCRIPT_TEMPLATE.format(
vm_test_script=run_test_path, vm_test_script=run_test_path,
......
...@@ -18,6 +18,11 @@ CHROMIUM_SRC_PATH = os.path.abspath(os.path.join( ...@@ -18,6 +18,11 @@ CHROMIUM_SRC_PATH = os.path.abspath(os.path.join(
os.path.dirname(__file__), '..', '..')) os.path.dirname(__file__), '..', '..'))
CHROMITE_PATH = os.path.abspath(os.path.join( CHROMITE_PATH = os.path.abspath(os.path.join(
CHROMIUM_SRC_PATH, 'third_party', 'chromite')) CHROMIUM_SRC_PATH, 'third_party', 'chromite'))
# cros_vm is a tool for managing VMs.
CROS_VM_PATH = os.path.abspath(os.path.join(
CHROMITE_PATH, 'bin', 'cros_vm'))
# cros_run_vm_test is a helper tool for running tests inside VMs and wraps
# cros_vm.
CROS_RUN_VM_TEST_PATH = os.path.abspath(os.path.join( CROS_RUN_VM_TEST_PATH = os.path.abspath(os.path.join(
CHROMITE_PATH, 'bin', 'cros_run_vm_test')) CHROMITE_PATH, 'bin', 'cros_run_vm_test'))
...@@ -48,51 +53,35 @@ def read_runtime_files(runtime_deps_path, outdir): ...@@ -48,51 +53,35 @@ def read_runtime_files(runtime_deps_path, outdir):
return rel_file_paths return rel_file_paths
def main(): def host_cmd(args):
parser = argparse.ArgumentParser() if not args.cmd:
parser.add_argument('--verbose', '-v', action='store_true') logging.error('Must specify command to run on the host.')
parser.add_argument( return 1
'--path-to-outdir', type=str, required=True,
help='Path to output directory, all of whose contents will be deployed '
'to the device.')
parser.add_argument(
'--board', type=str, required=True, help='Type of CrOS device.')
parser.add_argument(
'--test-exe', type=str, required=True,
help='Path to test executable to run inside VM.')
parser.add_argument(
'--runtime-deps-path', type=str,
help='Runtime data dependency file from GN.')
parser.add_argument(
'--cros-cache', type=str, required=True, help='Path to cros cache.')
# Gtest args.
parser.add_argument(
'--test-launcher-summary-output', type=str,
help='When set, will pass the same option down to the test and retrieve '
'its result file at the specified location.')
parser.add_argument(
'--test-launcher-shard-index',
type=int, default=os.environ.get('GTEST_SHARD_INDEX', 0),
help='Index of the external shard to run.')
parser.add_argument(
'--test-launcher-total-shards',
type=int, default=os.environ.get('GTEST_TOTAL_SHARDS', 1),
help='Total number of external shards.')
args, unknown_args = parser.parse_known_args()
if unknown_args: cros_vm_cmd_args = [
logging.warning('Ignoring unknown args: %s' % unknown_args) CROS_VM_PATH,
'--board', args.board,
'--cache-dir', args.cros_cache,
]
if args.verbose:
cros_vm_cmd_args.append('--debug')
if not os.path.exists('/dev/kvm'): rc = subprocess.call(
logging.error('/dev/kvm is missing. Is KVM installed on this machine?') cros_vm_cmd_args + ['--start'], stdout=sys.stdout, stderr=sys.stderr)
return 1 if rc:
elif not os.access('/dev/kvm', os.W_OK): logging.error('VM start-up failed. Quitting early.')
logging.warning( return rc
'/dev/kvm is not writable as current user. Perhaps you should be root?')
return 1 try:
return subprocess.call(args.cmd, stdout=sys.stdout, stderr=sys.stderr)
finally:
rc = subprocess.call(
cros_vm_cmd_args + ['--stop'], stdout=sys.stdout, stderr=sys.stderr)
if rc:
logging.error('VM tear-down failed.')
args.cros_cache = os.path.abspath(os.path.join(
args.path_to_outdir, args.cros_cache)) def vm_test(args):
cros_run_vm_test_cmd = [ cros_run_vm_test_cmd = [
CROS_RUN_VM_TEST_PATH, CROS_RUN_VM_TEST_PATH,
'--start', '--start',
...@@ -100,8 +89,6 @@ def main(): ...@@ -100,8 +89,6 @@ def main():
'--cache-dir', args.cros_cache, '--cache-dir', args.cros_cache,
'--cwd', os.path.relpath(args.path_to_outdir, CHROMIUM_SRC_PATH), '--cwd', os.path.relpath(args.path_to_outdir, CHROMIUM_SRC_PATH),
] ]
if args.verbose:
cros_run_vm_test_cmd.append('--debug')
# cros_run_vm_test has trouble with relative paths that go up directories, so # cros_run_vm_test has trouble with relative paths that go up directories, so
# cd to src/, which should be the root of all data deps. # cd to src/, which should be the root of all data deps.
...@@ -156,5 +143,64 @@ def main(): ...@@ -156,5 +143,64 @@ def main():
return vm_proc.returncode return vm_proc.returncode
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--verbose', '-v', action='store_true')
# Required args.
parser.add_argument(
'--board', type=str, required=True, help='Type of CrOS device.')
subparsers = parser.add_subparsers(dest='test_type')
# Host-side test args.
host_cmd_parser = subparsers.add_parser(
'host-cmd',
help='Runs a host-side test. Pass the host-side command to run after '
'"--". Hostname and port for the VM will be 127.0.0.1:9222.')
host_cmd_parser.set_defaults(func=host_cmd)
host_cmd_parser.add_argument(
'--cros-cache', type=str, required=True, help='Path to cros cache.')
host_cmd_parser.add_argument('cmd', nargs=argparse.REMAINDER)
# VM-side test args.
vm_test_parser = subparsers.add_parser(
'vm-test',
help='Runs a vm-side gtest.')
vm_test_parser.set_defaults(func=vm_test)
vm_test_parser.add_argument(
'--cros-cache', type=str, required=True, help='Path to cros cache.')
vm_test_parser.add_argument(
'--test-exe', type=str, required=True,
help='Path to test executable to run inside VM.')
vm_test_parser.add_argument(
'--path-to-outdir', type=str, required=True,
help='Path to output directory, all of whose contents will be deployed '
'to the device.')
vm_test_parser.add_argument(
'--runtime-deps-path', type=str,
help='Runtime data dependency file from GN.')
vm_test_parser.add_argument(
'--test-launcher-summary-output', type=str,
help='When set, will pass the same option down to the test and retrieve '
'its result file at the specified location.')
vm_test_parser.add_argument(
'--test-launcher-shard-index',
type=int, default=os.environ.get('GTEST_SHARD_INDEX', 0),
help='Index of the external shard to run.')
vm_test_parser.add_argument(
'--test-launcher-total-shards',
type=int, default=os.environ.get('GTEST_TOTAL_SHARDS', 1),
help='Total number of external shards.')
args = parser.parse_args()
if not os.path.exists('/dev/kvm'):
logging.error('/dev/kvm is missing. Is KVM installed on this machine?')
return 1
elif not os.access('/dev/kvm', os.W_OK):
logging.error(
'/dev/kvm is not writable as current user. Perhaps you should be root?')
return 1
args.cros_cache = os.path.abspath(args.cros_cache)
return args.func(args)
if __name__ == '__main__': if __name__ == '__main__':
sys.exit(main()) sys.exit(main())
...@@ -31,20 +31,28 @@ template("generate_vm_runner_script") { ...@@ -31,20 +31,28 @@ template("generate_vm_runner_script") {
_qemu_dir, _qemu_dir,
] ]
# Arguments used at build time by the runner script generator. # Required arguments used at build time by the runner script generator.
args = [ args = [
"--script-output-path", "--script-output-path",
rebase_path(invoker.generated_script, root_build_dir), rebase_path(invoker.generated_script, root_build_dir),
"--output-directory",
rebase_path(root_out_dir, root_build_dir),
"--test-exe",
rebase_path(invoker.test_exe, root_build_dir),
"--runtime-deps-path",
rebase_path(invoker.runtime_deps_file, root_build_dir),
"--cros-cache", "--cros-cache",
rebase_path("//build/cros_cache/", root_build_dir), rebase_path("//build/cros_cache/", root_build_dir),
"--board", "--board",
cros_board, cros_board,
] ]
# When --test-exe is specified, run_vm_test will push the exe to the VM and
# execute it. Otherwise it wraps a host-side command and just takes care
# launching & tearing-down the VM.
if (defined(invoker.test_exe)) {
args += [
"--test-exe",
rebase_path(invoker.test_exe, root_build_dir),
"--output-directory",
rebase_path(root_out_dir, root_build_dir),
"--runtime-deps-path",
rebase_path(invoker.runtime_deps_file, root_build_dir),
]
}
} }
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment