blob: b6256920ec01d8fb812d1cab5de29703ca53e2ac [file]
#!/usr/bin/env vpython3
#
# Copyright 2023 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
from glob import glob
import math
import os
import random
import sys
from pathlib import Path
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from devtools_paths import node_path, devtools_root_path
def parse_options(cli_args):
parser = argparse.ArgumentParser(description='Run tests')
parser.add_argument(
'--test-suite-source-dir',
dest='test_suite_source_dir',
default='test/e2e',
help=
'Path to the source folder containing the tests, relative to the current working directory.'
)
parser.add_argument(
'--jobs',
dest='jobs',
default=1,
help='Number of parallel runners to use (if supported). Defaults to 1.'
)
parser.add_argument(
'--test-file-pattern',
dest='test_file_pattern',
default=None,
help=
'A comma separated glob (or just a file path) to select specific test files to execute.'
)
parser.add_argument('--iterations',
dest='iterations',
default=1,
help='Number of test iterations.')
parser.add_argument('--shuffle',
dest='shuffle',
action='store_true',
help='Shuffles the order of the test files.')
return parser.parse_args(cli_args)
def divide_run(chunks,
test_suite_source_dir,
pattern=None,
iterations=1,
shuffle=False):
commands = []
test_files = []
if pattern:
test_files = pattern.split(',')
else:
test_suite_path = Path(
f'{devtools_root_path()}/{test_suite_source_dir}')
test_files = [
os.path.relpath(p, start=test_suite_path)
for p in glob(f'{test_suite_path}/**/*_test.ts', recursive=True)
]
if shuffle:
random.shuffle(test_files)
if iterations > 1:
for i in range(chunks):
commands.append({
'env': {
'ITERATIONS': str(math.ceil(iterations / chunks))
},
'command': [
node_path(),
str(
Path(
f'{devtools_root_path()}/scripts/test/run_test_suite.js'
)),
f'--config={Path(f"{test_suite_source_dir}/test-runner-config.json")}',
'--test-file-pattern=' + ','.join(test_files)
]
})
return commands
chunk_size = math.ceil(len(test_files) / chunks)
for l in [
test_files[i:i + chunk_size]
for i in range(0, len(test_files), chunk_size)
if test_files[i:i + chunk_size]
]:
commands.append({
'env': {},
'command': [
node_path(),
str(
Path(
f'{devtools_root_path()}/scripts/test/run_test_suite.js'
)),
f'--config={Path(f"{test_suite_source_dir}/test-runner-config.json")}',
'--test-file-pattern=' + ','.join(l)
]
})
return commands
if __name__ == '__main__':
args = parse_options(sys.argv[1:])
commands = divide_run(chunks=int(args.jobs),
test_suite_source_dir=args.test_suite_source_dir,
pattern=args.test_file_pattern,
iterations=int(args.iterations),
shuffle=args.shuffle)
for command in commands:
command_text = ' '.join(
[f'{k}={v}'
for k, v in command['env'].items()] + command['command'])
assert len(command_text) < 8191,\
'Command is too long for Windows, consider increasing the number of shards'
print(command_text)