207 lines
6.3 KiB
Python
Executable File
207 lines
6.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
#
|
|
# Copyright 2022 The Chromium Authors
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
import argparse
|
|
import json
|
|
import os
|
|
import re
|
|
import sys
|
|
|
|
# The basic shell script for client test run in Skylab. The arguments listed
|
|
# here will be fed by autotest at the run time.
|
|
#
|
|
# * test-launcher-summary-output: the path for the json result. It will be
|
|
# assigned by autotest, who will upload it to GCS upon test completion.
|
|
# * test-launcher-shard-index: the index for this test run.
|
|
# * test-launcher-total-shards: the total test shards.
|
|
# * test_args: arbitrary runtime arguments configured in test_suites.pyl,
|
|
# attached after '--'.
|
|
BASIC_SHELL_SCRIPT = """
|
|
#!/bin/sh
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--test-launcher-summary-output)
|
|
summary_output=$2
|
|
shift 2
|
|
;;
|
|
|
|
--test-launcher-shard-index)
|
|
shard_index=$2
|
|
shift 2
|
|
;;
|
|
|
|
--test-launcher-total-shards)
|
|
total_shards=$2
|
|
shift 2
|
|
;;
|
|
|
|
--)
|
|
test_args=$2
|
|
break
|
|
;;
|
|
|
|
*)
|
|
break
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [ ! -d $(dirname $summary_output) ] ; then
|
|
mkdir -p $(dirname $summary_output)
|
|
fi
|
|
|
|
cd `dirname $0` && cd ..
|
|
"""
|
|
|
|
|
|
def build_test_script(args):
|
|
# Build the shell script that will be used on the device to invoke the test.
|
|
# Stored here as a list of lines.
|
|
device_test_script_contents = BASIC_SHELL_SCRIPT.split('\n')
|
|
|
|
test_invocation = ('LD_LIBRARY_PATH=./ ./%s '
|
|
' --test-launcher-summary-output=$summary_output'
|
|
' --test-launcher-shard-index=$shard_index'
|
|
' --test-launcher-total-shards=$total_shards'
|
|
' $test_args' % args.test_exe)
|
|
|
|
device_test_script_contents.append(test_invocation)
|
|
with open(args.output, 'w') as w:
|
|
w.write('\n'.join(device_test_script_contents))
|
|
os.chmod(args.output, 0o755)
|
|
|
|
|
|
def build_filter_file(args):
|
|
# TODO(b/227381644): This expression is hard to follow and should be
|
|
# simplified. This would require a change on the cros infra side as well
|
|
tast_expr_dict = {}
|
|
default_disabled_tests = []
|
|
if args.disabled_tests is not None:
|
|
default_disabled_tests = [
|
|
'!"name:{0}"'.format(test) for test in args.disabled_tests
|
|
]
|
|
|
|
default_enabled_test_term = ''
|
|
if args.enabled_tests is not None:
|
|
default_enabled_test_term = (' || ').join(
|
|
['"name:{0}"'.format(test) for test in args.enabled_tests])
|
|
|
|
# Generate the default expression to be used when there is no known key
|
|
tast_expr = args.tast_expr if args.tast_expr else ""
|
|
|
|
if default_disabled_tests:
|
|
default_disabled_term = " && ".join(default_disabled_tests)
|
|
tast_expr = "{0} && {1}".format(tast_expr, default_disabled_term) if \
|
|
tast_expr else default_disabled_term
|
|
|
|
if default_enabled_test_term:
|
|
tast_expr = "{0} && ({1})".format(
|
|
tast_expr,
|
|
default_enabled_test_term) if tast_expr else default_enabled_test_term
|
|
|
|
tast_expr_dict['default'] = "({0})".format(tast_expr)
|
|
|
|
# Generate an expression for each collection in the gni file
|
|
if args.tast_control is not None:
|
|
with open(args.tast_control, 'r') as tast_control_file:
|
|
gni = tast_control_file.read()
|
|
filter_lists = re.findall(r'(.*) = \[([^\]]*)\]', gni)
|
|
for filter_list in filter_lists:
|
|
tast_expr = args.tast_expr if args.tast_expr else ""
|
|
|
|
milestone_disabled_tests = {
|
|
'!"name:{0}"'.format(test)
|
|
for test in re.findall(r'"([^"]+)"', filter_list[1])
|
|
}
|
|
|
|
milestone_disabled_tests.update(default_disabled_tests)
|
|
|
|
if milestone_disabled_tests:
|
|
tast_expr = "{0} && {1}".format(
|
|
tast_expr, " && ".join(milestone_disabled_tests)
|
|
) if tast_expr else " && ".join(milestone_disabled_tests)
|
|
|
|
if default_enabled_test_term:
|
|
tast_expr = "{0} && ({1})".format(
|
|
tast_expr, default_enabled_test_term
|
|
) if tast_expr else default_enabled_test_term
|
|
|
|
if tast_expr:
|
|
tast_expr_dict[filter_list[0]] = "({0})".format(tast_expr)
|
|
|
|
if len(tast_expr_dict) > 0:
|
|
with open(args.output, "w") as file:
|
|
json.dump(tast_expr_dict, file, indent=2)
|
|
os.chmod(args.output, 0o644)
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser()
|
|
subparsers = parser.add_subparsers(dest='command')
|
|
|
|
script_gen_parser = subparsers.add_parser('generate-runner')
|
|
script_gen_parser.add_argument(
|
|
'--test-exe',
|
|
type=str,
|
|
required=True,
|
|
help='Path to test executable to run inside the device.')
|
|
script_gen_parser.add_argument('--verbose', '-v', action='store_true')
|
|
script_gen_parser.add_argument(
|
|
'--output',
|
|
required=True,
|
|
type=str,
|
|
help='Path to create the runner script.')
|
|
script_gen_parser.set_defaults(func=build_test_script)
|
|
|
|
filter_gen_parser = subparsers.add_parser('generate-filter')
|
|
filter_gen_parser.add_argument(
|
|
'--tast-expr',
|
|
type=str,
|
|
required=False,
|
|
help='Tast expression to determine tests to run. This creates the '
|
|
'initial set of tests that can be further filtered.')
|
|
filter_gen_parser.add_argument(
|
|
'--enabled-tests',
|
|
type=str,
|
|
required=False,
|
|
action='append',
|
|
help='Name of tests to allow to test (unnamed tests will not run).')
|
|
filter_gen_parser.add_argument(
|
|
'--disabled-tests',
|
|
type=str,
|
|
required=False,
|
|
action='append',
|
|
help='Names of tests to disable from running')
|
|
filter_gen_parser.add_argument(
|
|
'--tast-control',
|
|
type=str,
|
|
required=False,
|
|
help='Filename for the tast_control file containing version skew '
|
|
'test filters to generate.')
|
|
filter_gen_parser.add_argument(
|
|
'--output',
|
|
required=True,
|
|
type=str,
|
|
help='Path to create the plain text filter file.')
|
|
filter_gen_parser.set_defaults(func=build_filter_file)
|
|
|
|
args = parser.parse_args()
|
|
|
|
if (args.command == "generate-filter" and args.disabled_tests is None and
|
|
args.enabled_tests is None and args.tast_expr is None):
|
|
parser.error(
|
|
'--disabled-tests, --enabled-tests, or --tast-expr must be provided '
|
|
'to generate-filter')
|
|
|
|
args.func(args)
|
|
|
|
return 0
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main())
|