blob: 621c73f8e1ae33b91158e56806b353cc5a453c26 [file] [log] [blame]
#!/usr/bin/env python
# Copyright 2018 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.
import argparse
import os
from subprocess import check_output, Popen
import sys
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
ARCHES = [
% for arch in data.arches:
'${arch.short_name}',
% endfor
]
def program_exists(name):
"""Returns True if an executable with the name exists"""
if len(name) > 0 and name[0] == '/':
return os.path.isfile(name) and os.access(name, os.X_OK)
for path in os.environ["PATH"].split(os.pathsep):
fname = os.path.join(path, name)
if os.path.isfile(fname) and os.access(fname, os.X_OK):
return True
return False
class BazelTester(object):
def __init__(self, without_sdk, with_ignored, bazel_bin,
optional_flags=[]):
self.without_sdk = without_sdk
self.with_ignored = with_ignored
self.bazel_bin = bazel_bin
self.optional_flags = optional_flags
def _invoke_bazel(self, command, targets):
command = [self.bazel_bin, command, '--keep_going']
command += self.optional_flags
command += targets
job = Popen(command, cwd=SCRIPT_DIR)
job.communicate()
return job.returncode
def _build(self, targets):
return self._invoke_bazel('build', targets)
def _test(self, targets):
return self._invoke_bazel('test', targets)
def _query(self, query):
command = [self.bazel_bin, 'query', query]
return set(check_output(command, cwd=SCRIPT_DIR).splitlines())
def run(self):
if not self.without_sdk:
# Build the SDK contents.
print('Building SDK contents')
if self._build(['@fuchsia_sdk//...']):
return False
targets = ['//...']
if not self.with_ignored:
# Identify and remove ignored targets.
all_targets = self._query('//...')
ignored_targets = self._query('attr("tags", "ignored", //...)')
if ignored_targets:
# Targets which depend on an ignored target should be ignored too.
all_ignored_targets = set()
for target in ignored_targets:
all_ignored_targets.add(target)
dep_query = 'rdeps("//...", "{}")'.format(target)
dependent_targets = self._query(dep_query)
all_ignored_targets.update(dependent_targets)
print('Ignored targets:')
for target in sorted(all_ignored_targets):
print(' - ' + target)
targets = list(all_targets - all_ignored_targets)
# Build the tests targets.
print('Building test targets')
if self._build(targets):
return False
# Run tests.
args = ('attr("tags", "^((?!compile-only).)*$",' +
' kind(".*test rule", //...))')
test_targets = list(self._query(args))
print('Running test targets')
return self._test(test_targets) == 0
def main():
parser = argparse.ArgumentParser(
description='Runs the SDK tests')
parser.add_argument('--no-sdk',
help='If set, SDK targets are not built.',
action='store_true')
parser.add_argument('--ignored',
help='If set, ignored tests are run too.',
action='store_true')
parser.add_argument('--bazel',
help='Path to the Bazel tool',
default='bazel')
parser.add_argument('--once',
help='Whether to only run tests once',
action='store_true')
args = parser.parse_args()
if not program_exists(args.bazel):
print('"%s": command not found' % (args.bazel))
return 1
def print_test_start(arch, cpp_version):
print('')
print('-----------------------------------')
print('| Testing %s / %s' % (arch, cpp_version))
print('-----------------------------------')
for arch in ARCHES:
print_test_start(arch, 'C++14')
config_flags = ['--config=fuchsia_%s' % arch]
cpp14_flags = ['--cxxopt=-Wc++14-compat', '--cxxopt=-Wc++17-extensions']
if not BazelTester(args.no_sdk, args.ignored, args.bazel,
optional_flags=config_flags + cpp14_flags).run():
return 1
if args.once:
print('Single iteration requested, done.')
break
print_test_start(arch, 'C++17')
cpp17_flags = ['--cxxopt=-std=c++17', '--cxxopt=-Wc++17-compat']
if not BazelTester(args.no_sdk, args.ignored, args.bazel,
optional_flags=config_flags + cpp17_flags).run():
return 1
return 0
if __name__ == '__main__':
sys.exit(main())