blob: c18bcd3c342529dc2d84b515700505acd3e21022 [file] [log] [blame]
Mike Frysingere58c0e22017-10-04 15:43:30 -04001# -*- coding: utf-8 -*-
Bertrand SIMONNETe025a0e2015-05-06 14:17:43 -07002# Copyright 2015 The Chromium OS 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.
5
6"""Tool to run ebuild unittests."""
7
8from __future__ import print_function
9
Alex Klein95843e82020-12-28 11:27:32 -070010import argparse
Aviv Keshet01fcca42016-07-25 16:34:59 -070011import multiprocessing
Bertrand SIMONNETe025a0e2015-05-06 14:17:43 -070012import os
Mike Frysinger6a2b0f22020-02-20 13:34:07 -050013import sys
Bertrand SIMONNETe025a0e2015-05-06 14:17:43 -070014
15from chromite.lib import commandline
Chris McDonalde69db662018-11-15 12:50:18 -070016from chromite.lib import constants
Bertrand SIMONNETe025a0e2015-05-06 14:17:43 -070017from chromite.lib import chroot_util
18from chromite.lib import cros_build_lib
19from chromite.lib import cros_logging as logging
20from chromite.lib import osutils
21from chromite.lib import workon_helper
22from chromite.lib import portage_util
Chris McDonalde69db662018-11-15 12:50:18 -070023from chromite.scripts import cros_extract_deps
24
Mike Frysinger6a2b0f22020-02-20 13:34:07 -050025
26assert sys.version_info >= (3, 6), 'This module requires Python 3.6+'
27
28
Chris McDonalde69db662018-11-15 12:50:18 -070029BOARD_VIRTUAL_PACKAGES = (constants.TARGET_OS_PKG,
30 constants.TARGET_OS_DEV_PKG,
Chris McDonaldb0c021c2019-01-07 15:04:22 -070031 constants.TARGET_OS_TEST_PKG,
32 constants.TARGET_OS_FACTORY_PKG)
Chris McDonalde69db662018-11-15 12:50:18 -070033IMPLICIT_TEST_DEPS = ('virtual/implicit-system',)
Bertrand SIMONNETe025a0e2015-05-06 14:17:43 -070034
35
36def ParseArgs(argv):
37 """Parse arguments.
38
39 Args:
40 argv: array of arguments passed to the script.
41 """
42 parser = commandline.ArgumentParser(description=__doc__)
43
44 target = parser.add_mutually_exclusive_group(required=True)
45 target.add_argument('--sysroot', type='path', help='Path to the sysroot.')
46 target.add_argument('--board', help='Board name.')
47
48 parser.add_argument('--pretend', default=False, action='store_true',
49 help='Show the list of packages to be tested and return.')
50 parser.add_argument('--noinstalled_only', dest='installed', default=True,
51 action='store_false',
52 help='Test all testable packages, even if they are not '
53 'currently installed.')
54 parser.add_argument('--package_file', type='path',
55 help='Path to a file containing the list of packages '
Alex Klein95843e82020-12-28 11:27:32 -070056 'that should be tested.')
Bertrand SIMONNETe025a0e2015-05-06 14:17:43 -070057 parser.add_argument('--packages',
58 help='Space-separated list of packages to test.')
Alex Klein95843e82020-12-28 11:27:32 -070059 parser.add_argument('--blacklist_packages',
60 dest='skip_packages',
61 deprecated='Use --skip-packages instead.',
62 help=argparse.SUPPRESS)
63 parser.add_argument('--skip-packages',
64 help='Space-separated list of packages to NOT test even '
65 'if they otherwise would have been tested.')
Bertrand SIMONNETe025a0e2015-05-06 14:17:43 -070066 parser.add_argument('--nowithdebug', action='store_true',
67 help="Don't build the tests with USE=cros-debug")
Chris McDonalde69db662018-11-15 12:50:18 -070068 parser.add_argument('--assume-empty-sysroot', default=False,
69 action='store_true', dest='empty_sysroot',
70 help='Set up dependencies and run unit tests for all '
71 'packages that could be installed on target board '
72 'without assuming that any packages have actually '
73 'been merged yet.')
Alex Kleinfe6081c2020-03-16 10:02:24 -060074 parser.add_argument(
75 '-j',
76 '--jobs',
77 type=int,
78 default=multiprocessing.cpu_count(),
79 help='The limit for the number of possible concurrent jobs.')
Navil Perezbcd69ba2020-09-02 23:13:36 +000080 parser.add_argument(
81 '--no-testable-packages-ok',
82 default=False,
83 action='store_true',
84 dest='testable_packages_optional',
85 help="If specified, don't fail if no testable packages are found.")
Bertrand SIMONNETe025a0e2015-05-06 14:17:43 -070086
87 options = parser.parse_args(argv)
88 options.Freeze()
89 return options
90
91
Chris McDonalde69db662018-11-15 12:50:18 -070092def determine_board_packages(sysroot, virtual_packages):
93 """Returns a set of the dependencies for the given packages"""
Chris McDonaldd8a7f112019-11-01 10:35:07 -060094 deps, _bdeps = cros_extract_deps.ExtractDeps(
95 sysroot, virtual_packages, include_bdepend=False)
96 return set(
97 '%s/%s' % (atom['category'], atom['name']) for atom in deps.values())
Chris McDonalde69db662018-11-15 12:50:18 -070098
99
Bertrand SIMONNETe025a0e2015-05-06 14:17:43 -0700100def main(argv):
101 opts = ParseArgs(argv)
102
103 cros_build_lib.AssertInsideChroot()
104
105 sysroot = opts.sysroot or cros_build_lib.GetSysroot(opts.board)
Alex Klein95843e82020-12-28 11:27:32 -0700106 skipped_packages = set()
107 if opts.skip_packages:
108 skipped_packages |= set(opts.skip_packages.split())
Bertrand SIMONNETe025a0e2015-05-06 14:17:43 -0700109
110 packages = set()
111 # The list of packages to test can be passed as a file containing a
112 # space-separated list of package names.
Nicolas Boichat02bb93e2021-04-01 09:01:44 +0800113 # This is used by the builder to test only the packages that were uprevved.
Bertrand SIMONNETe025a0e2015-05-06 14:17:43 -0700114 if opts.package_file and os.path.exists(opts.package_file):
115 packages = set(osutils.ReadFile(opts.package_file).split())
116
117 if opts.packages:
118 packages |= set(opts.packages.split())
119
120 # If no packages were specified, use all testable packages.
Chris McDonalde69db662018-11-15 12:50:18 -0700121 if not (opts.packages or opts.package_file) and not opts.empty_sysroot:
Bertrand SIMONNETe025a0e2015-05-06 14:17:43 -0700122 workon = workon_helper.WorkonHelper(sysroot)
123 packages = (workon.InstalledWorkonAtoms() if opts.installed
Chris McDonalde69db662018-11-15 12:50:18 -0700124 else set(workon.ListAtoms(use_all=True)))
125
126 if opts.empty_sysroot:
127 packages |= determine_board_packages(sysroot, BOARD_VIRTUAL_PACKAGES)
128 workon = workon_helper.WorkonHelper(sysroot)
129 workon_packages = set(workon.ListAtoms(use_all=True))
130 packages &= workon_packages
Bertrand SIMONNETe025a0e2015-05-06 14:17:43 -0700131
Alex Klein95843e82020-12-28 11:27:32 -0700132 for cp in packages & skipped_packages:
133 logging.info('Skipping package %s.', cp)
Bertrand SIMONNETe025a0e2015-05-06 14:17:43 -0700134
Alex Klein95843e82020-12-28 11:27:32 -0700135 packages = packages - skipped_packages
Bertrand SIMONNETe025a0e2015-05-06 14:17:43 -0700136 pkg_with_test = portage_util.PackagesWithTest(sysroot, packages)
137
138 if packages - pkg_with_test:
Mike Frysinger80aa9322019-09-01 15:38:56 -0400139 logging.warning('The following packages do not have tests:\n %s',
140 '\n '.join(sorted(packages - pkg_with_test)))
Bertrand SIMONNETe025a0e2015-05-06 14:17:43 -0700141
Mike Frysingerdcb680f2019-09-02 00:21:44 -0400142 if not pkg_with_test:
Navil Perezbcd69ba2020-09-02 23:13:36 +0000143 if opts.testable_packages_optional:
144 logging.warning('No testable packages found!')
145 return 0
Mike Frysingerdcb680f2019-09-02 00:21:44 -0400146 logging.error('No testable packages found!')
147 return 1
148
Bertrand SIMONNETe025a0e2015-05-06 14:17:43 -0700149 if opts.pretend:
150 print('\n'.join(sorted(pkg_with_test)))
Mike Frysingerdcb680f2019-09-02 00:21:44 -0400151 return 0
Bertrand SIMONNETe025a0e2015-05-06 14:17:43 -0700152
153 env = None
154 if opts.nowithdebug:
155 use_flags = os.environ.get('USE', '')
156 use_flags += ' -cros-debug'
157 env = {'USE': use_flags}
158
Chris McDonalde69db662018-11-15 12:50:18 -0700159 if opts.empty_sysroot:
160 try:
161 chroot_util.Emerge(list(IMPLICIT_TEST_DEPS), sysroot, rebuild_deps=False,
162 use_binary=False)
163 chroot_util.Emerge(list(pkg_with_test), sysroot, rebuild_deps=False,
164 use_binary=False)
165 except cros_build_lib.RunCommandError:
166 logging.error('Failed building dependencies for unittests.')
Mike Frysingerd56bb812019-09-01 15:42:24 -0400167 return 1
Chris McDonalde69db662018-11-15 12:50:18 -0700168
Bertrand SIMONNETe025a0e2015-05-06 14:17:43 -0700169 try:
Alex Kleinfe6081c2020-03-16 10:02:24 -0600170 chroot_util.RunUnittests(
171 sysroot, pkg_with_test, extra_env=env, jobs=opts.jobs)
Bertrand SIMONNETe025a0e2015-05-06 14:17:43 -0700172 except cros_build_lib.RunCommandError:
173 logging.error('Unittests failed.')
Mike Frysingerd56bb812019-09-01 15:42:24 -0400174 return 1