blob: 30de7a16b6692e70734ef59b44340a6200200604 [file] [log] [blame]
#!/usr/bin/env python3
# Copyright 2019 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#### CATEGORY=Other
import argparse
import json
import os
import subprocess
import sys
import textwrap
# Colors and helpers for terminal pretty-printing.
BOLD_BLACK = '\033[1;30m'
BOLD_RED = '\033[1;31m'
NO_COLOR = '\033[0m'
def info_print(s):
print('\n%s%s%s' % (BOLD_BLACK, s, NO_COLOR))
def error_print(s):
print('\n%s%s%s' % (BOLD_RED, s, NO_COLOR))
def main():
parser = argparse.ArgumentParser(
description=(textwrap.dedent('''\
Executes a test in the GN graph.
Note that the name of the test is just the name of a binary in the
output folder.
For example, if you have this binary:
out/default/host_x64/my_test
You just specify "my_test" as the test name.
Also note that the binary need to be part of your GN build graph,
even if you are not interested in delivering this binary as part of
the image. This means that, if your test is generated by the
//system/src/my_package/my_test
target, you might need to add this target to your GN build graph by
adjusting your "fx set" arguments like this:
fx set ... --with //system/src/my_package/my_test
''')),
formatter_class=argparse.RawDescriptionHelpFormatter,
)
parser.add_argument('--manifest',
help='The path to the manifest of tests',
required=True)
parser.add_argument('--names',
help='The names of the tests to execute',
nargs='*',
required=True)
parser.add_argument('test_args',
help='Arguments to pass to the tests on execution',
nargs='*')
parser.add_argument('--build-dir',
help='The path to the root build directory',
required=True)
parser.add_argument('--ninja',
help='The path to the ninja binary',
required=True)
args = parser.parse_args()
if not args.names:
error_print('no tests provided')
return 1
with open(args.manifest, 'r') as f:
entries = json.load(f)
tests = []
unmatched = set(args.names)
for entry in entries:
test = entry['test']
if test['os'] == 'fuchsia':
continue
# some tests have no "path" property
if 'path' not in test:
continue
path = test['path']
name = os.path.basename(path)
if name not in args.names:
continue
tests.append(test)
unmatched.remove(name)
if unmatched:
error_print(
'could not find tests with the following names:\n' +
'\n'.join(unmatched))
return 1
# test['path'] gives the path to the test relative build directory,
# which is a valid ninja target.
ret = subprocess.call(
[args.ninja, '-C', args.build_dir] +
[test['path'] for test in tests])
if ret:
error_print('failed to compile tests')
return 1
failed = []
for test in tests:
target = test['name']
info_print('<< running %s >>' % target)
if 'command' in test and len(test['command']) > 1:
location, extra_args = test['command'][0], test['command'][1:]
else:
location, extra_args = test['path'], []
ret = subprocess.call(
[os.path.join(args.build_dir, location)] + extra_args + args.test_args)
if ret != 0:
failed.append(target)
num_tests = len(tests)
if not num_tests:
error_print('no tests found with names %s' % ', '.join(args.names))
return 1
if failed:
error_print(
'%d of %d test%s failed:' % (
len(failed), num_tests, 's' if num_tests > 1 else ''
) +
'\n'.join(failed))
return 1
else:
info_print('%d of %d test%s passed' % (
num_tests, num_tests, 's' if num_tests > 1 else ''))
if __name__ == '__main__':
sys.exit(main())