123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- #!/usr/bin/env python3
- #
- # Copyright 2022 The Chromium 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 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())
|