[go: up one dir, main page]

blob: 748c975cb78d0d76ddebd380e5f52e05e94504ca [file] [log] [blame]
Brian Rynerc4e7fc62024-02-07 23:06:391#!/usr/bin/env vpython3
iannuccid5935d92014-07-26 01:08:212# Copyright 2014 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
Philippe Gervaiseeb839c2015-02-03 23:19:505"""Convenience script for expect_tests"""
iannuccid5935d92014-07-26 01:08:216
Andrew Chang6e831492020-09-16 23:21:527from __future__ import absolute_import
8from __future__ import print_function
iannuccid5935d92014-07-26 01:08:219assert __name__ == '__main__'
10
11import os
eseidelc35bb7f2014-09-02 22:36:0312import subprocess
Philippe Gervaiseeb839c2015-02-03 23:19:5013import sys
iannuccid5935d92014-07-26 01:08:2114
eseidelbda32352014-09-04 23:08:4715
Vadim Shtayura28b57b12016-12-15 22:45:3116INFRA_ROOT = os.path.dirname(os.path.abspath(__file__))
17
18
Gregory Nisbet2c366ec2022-03-30 03:43:4619# Allowlist of packages to test on Windows.
Vadim Shtayura28b57b12016-12-15 22:45:3120WIN_ENABLED_PACKAGES = [
Vadim Shtayura28b57b12016-12-15 22:45:3121 'packages/infra_libs/infra_libs/infra_types',
22 'packages/infra_libs/infra_libs/logs',
Vadim Shtayura28b57b12016-12-15 22:45:3123 'packages/infra_libs/infra_libs/ts_mon',
24]
25
Brian Rynerf1ccfdb2024-02-15 02:34:2226WIN_ENABLED_PACKAGES_PY3_ONLY = [
27 'infra/libs/decorators',
28 'infra/libs/service_utils',
29]
30
Brian Ryneraee4d422024-02-14 22:24:2731# Test shared GAE code and individual GAE apps only on 64-bit Posix. This
32# matches GAE environment.
33TEST_GAE = sys.platform != 'win32' and sys.maxsize == (2**63) - 1
34
Brian Rynerc7b2a202024-01-02 07:02:5435# Tests to run under vpython3. These should not be part of any
36# of the py2 modules listed below, and must contain their own
37# __main__ implementation.
38VPYTHON3_TESTS = [
39 'infra/tools/dockerbuild/test/smoke_test.py',
40]
Vadim Shtayura28b57b12016-12-15 22:45:3141
Brian Ryneraee4d422024-02-14 22:24:2742if TEST_GAE and os.path.isdir(os.path.join(INFRA_ROOT, 'appengine_module')):
43 VPYTHON3_TESTS += [
44 'appengine_module/gae_ts_mon/test/test.py',
45 ]
46
47
pgervais3a1b7272014-10-01 18:53:5448def usage():
Brian Rynerc4e7fc62024-02-07 23:06:3949 print("""\nUsage: %s <action> [--py3] [<test names>] [<expect_tests options>]
pgervais3a1b7272014-10-01 18:53:5450
51 where <action> is one of: list, test, train, debug.
52
53 Examples:
54 Run all tests:
55 ./test.py test
Aaron Gable56f4df62016-10-13 18:04:2556 Run all tests in the given package:
Philippe Gervaisff601c32014-12-02 00:49:2957 ./test.py test infra
Aaron Gable56f4df62016-10-13 18:04:2558 ./test.py test appengine/cr-buildbucket
sergeyberezin0e47fe72016-04-27 18:47:3459 Run all tests and generate an HTML report:
60 ./test.py test infra --html-report /path/to/report/folder
pgervais3a1b7272014-10-01 18:53:5461 Run one given test in the infra package:
Philippe Gervaisff601c32014-12-02 00:49:2962 ./test.py test infra/libs/git2/test:*testCommitBogus
pgervais3a1b7272014-10-01 18:53:5463
Brian Rynerc4e7fc62024-02-07 23:06:3964 --py3 runs python 3 tests; otherwise python 2 tests are run.
65
pgervais3a1b7272014-10-01 18:53:5466 See expect_tests documentation for more details
Andrew Chang6e831492020-09-16 23:21:5267 """ % sys.argv[0])
pgervais3a1b7272014-10-01 18:53:5468
69
Vadim Shtayura28b57b12016-12-15 22:45:3170def get_modules_with_coveragerc(root_module):
71 """Returns submodules that have .coveragerc file present."""
72 root_dir = os.path.join(INFRA_ROOT, root_module.replace('/', os.sep))
73 if not os.path.isdir(root_dir):
74 return []
75 return [
76 '%s/%s' % (root_module, d)
77 for d in os.listdir(root_dir)
78 if os.path.isfile(os.path.join(root_dir, d, '.coveragerc'))
79 ]
vadimsh908a1aa2015-07-31 00:32:2880
81
pgervais3a1b7272014-10-01 18:53:5482# Parse command-line arguments
83if len(sys.argv) == 1:
Philippe Gervaisff601c32014-12-02 00:49:2984 usage()
sergeyberezin0e47fe72016-04-27 18:47:3485 sys.exit(1)
pgervais3a1b7272014-10-01 18:53:5486else:
87 if not sys.argv[1] in ('list', 'train', 'test', 'debug'):
88 usage()
sergeyberezin0e47fe72016-04-27 18:47:3489 sys.exit(1)
pgervais3a1b7272014-10-01 18:53:5490
sergeyberezin0e47fe72016-04-27 18:47:3491command = sys.argv[1]
92args = sys.argv[2:]
93
94modules = []
95flags = []
Brian Rynerc4e7fc62024-02-07 23:06:3996py3 = False
wrengr8542d922016-09-06 22:03:3197# BUG: this will append everything after the first flag to `flags`. Thus,
98# it fails to catch when (a) someone doesn't pass a directory after
99# "--html-report", nor (b) if they pass multiple directories after that
100# flag.
sergeyberezin0e47fe72016-04-27 18:47:34101for arg in args:
102 if arg.startswith('-'):
Brian Rynerc4e7fc62024-02-07 23:06:39103 if arg == '--py3':
104 py3 = True
105 else:
106 flags.append(arg)
sergeyberezin0e47fe72016-04-27 18:47:34107 continue
108 if flags:
109 flags.append(arg)
110 else:
111 modules.append(arg)
pgervais3a1b7272014-10-01 18:53:54112
Brian Rynerc4e7fc62024-02-07 23:06:39113if py3:
114 python_bin = sys.executable
115 expect_tests_path = os.path.join(
116 os.path.dirname(sys.executable), 'expect_tests')
117else:
Robert Iannucci6c4eebb2024-10-08 20:23:36118 vpyout = subprocess.run([
119 os.path.join(INFRA_ROOT, 'cipd', 'legacy', 'vpython'),
120 '-c', 'import sys;sys.stdout.write(sys.executable)',
121 ], capture_output=True, encoding='utf-8')
122 if vpyout.returncode != 0:
123 sys.stderr.write(vpyout.stderr)
124 sys.stdout.write(vpyout.stdout)
125 vpyout.check_returncode()
126 python_bin = vpyout.stdout
127 expect_tests_path = os.path.join(os.path.dirname(python_bin), 'expect_tests')
Brian Rynerc4e7fc62024-02-07 23:06:39128
pgervais3a1b7272014-10-01 18:53:54129# Set up default list of packages/directories if none have been provided.
sergeyberezin0e47fe72016-04-27 18:47:34130if not modules:
Gregory Nisbet2c366ec2022-03-30 03:43:46131 # On Windows, test only allowlisted subset of 'infra' and 'packages' modules.
vadimsh908a1aa2015-07-31 00:32:28132 if sys.platform == 'win32':
Vadim Shtayura28b57b12016-12-15 22:45:31133 modules.extend([
134 p for p in WIN_ENABLED_PACKAGES
135 if os.path.isdir(os.path.join(INFRA_ROOT, p))
136 ])
Brian Rynerf1ccfdb2024-02-15 02:34:22137 if py3:
138 modules.extend([
139 p for p in WIN_ENABLED_PACKAGES_PY3_ONLY
140 if os.path.isdir(os.path.join(INFRA_ROOT, p))
141 ])
vadimsh908a1aa2015-07-31 00:32:28142 else:
Brian Rynerf1ccfdb2024-02-15 02:34:22143 if py3:
144 modules.extend(['infra'])
Vadim Shtayura28b57b12016-12-15 22:45:31145 modules.extend(get_modules_with_coveragerc('packages'))
146
Brian Ryner80458312024-03-20 06:17:07147 # Skip py2.7 GAE tests for any builders that don't pull the appengine
148 # directory. For py3, these tests run via their own test.py rather than
149 # expect_tests.
Brian Rynerc4e7fc62024-02-07 23:06:39150 if not py3 and os.path.isdir(os.path.join(INFRA_ROOT, 'appengine')):
Brian Ryneraee4d422024-02-14 22:24:27151 if TEST_GAE:
Vadim Shtayurabaad3332016-12-15 23:51:54152 modules.append('appengine_module')
153 modules.extend(get_modules_with_coveragerc('appengine'))
pgervais3a1b7272014-10-01 18:53:54154
Philippe Gervaiseeb839c2015-02-03 23:19:50155os.environ['PYTHONPATH'] = ''
eseidelbda32352014-09-04 23:08:47156os.chdir(INFRA_ROOT)
sergeyberezin0e47fe72016-04-27 18:47:34157if '--help' not in flags and '-h' not in flags:
vadimshaa470f52015-05-13 22:32:11158 subprocess.check_call(
Brian Ryner652a91b2022-12-15 21:57:27159 ['python3', '-u',
Robert Iannucci6c4eebb2024-10-08 20:23:36160 os.path.join('bootstrap', 'remove_orphaned_pycs.py'),
161 'infra', 'appengine', 'packages', 'luci'])
sergeyberezin0e47fe72016-04-27 18:47:34162else:
163 usage()
164 sys.exit(subprocess.call([python_bin, expect_tests_path, command, '--help']))
165
166if sys.platform == 'win32' and '--force-coverage' not in flags:
167 flags.append('--no-coverage')
168
169exit_code = 0
170failed_modules = []
171for module in modules:
Brian Rynerc4e7fc62024-02-07 23:06:39172 print('Running %s...%s' % (module, ' (py3)' if py3 else ''))
sergeyberezin0e47fe72016-04-27 18:47:34173 module_flags = flags[:]
Vadim Shtayura28b57b12016-12-15 22:45:31174 # Remove any test glob, which comes after semicolon (:) and convert to a path.
175 module_path = module.split(':')[0].replace('/', os.sep)
Sergiy Byelozyorovb2200952017-08-07 09:43:48176 if not any(flag.startswith('--coveragerc') for flag in module_flags):
177 module_coveragerc = os.path.join(INFRA_ROOT, module_path, '.coveragerc')
178 module_flags.append('--coveragerc=%s' % module_coveragerc)
179 if not any(flag.startswith('--html-report-subdir') for flag in module_flags):
180 module_flags.append('--html-report-subdir=%s' % module_path)
sergeyberezin0e47fe72016-04-27 18:47:34181 cmd = [python_bin, expect_tests_path, command, module] + module_flags
182 module_exit_code = subprocess.call(cmd)
183 exit_code = module_exit_code or exit_code
184 if module_exit_code:
185 failed_modules.append(module)
186
Brian Rynerc7b2a202024-01-02 07:02:54187# Tests to run with vpython3
Brian Rynerc4e7fc62024-02-07 23:06:39188if py3:
189 VPYTHON = 'vpython3' + ('.bat' if sys.platform == 'win32' else '')
190 for test in VPYTHON3_TESTS:
191 print('Running %s... (py3)' % test)
192 cmd = [VPYTHON, test]
193 test_exit_code = subprocess.call(cmd)
194 exit_code = test_exit_code or exit_code
195 if test_exit_code:
196 failed_modules.append(test)
Brian Rynerc7b2a202024-01-02 07:02:54197
sergeyberezin0e47fe72016-04-27 18:47:34198if exit_code:
Andrew Chang6e831492020-09-16 23:21:52199 print()
200 print('Tests failed in modules:\n %s' % '\n '.join(failed_modules))
sergeyberezine2eeb962016-05-10 21:40:38201 if '--html-report' not in flags:
Andrew Chang6e831492020-09-16 23:21:52202 print('\nFor detailed coverage report and per-line branch coverage,')
203 print('rerun with --html-report <dir>')
sergeyberezin0e47fe72016-04-27 18:47:34204else:
Andrew Chang6e831492020-09-16 23:21:52205 print('All tests passed.')
sergeyberezin0e47fe72016-04-27 18:47:34206
207sys.exit(exit_code)