diff options
author | Jian Cai <jiancai@google.com> | 2020-04-13 18:51:44 -0700 |
---|---|---|
committer | Jian Cai <jiancai@google.com> | 2020-04-14 22:23:19 +0000 |
commit | 5d09ca047e14466720c080f0e7e627582fad8ec8 (patch) | |
tree | 156186ebb35534ddbb9b29dab0f70a95915417d9 /llvm_tools | |
parent | 624bdfc1e82dcaaf577bb843cafc2d4ec36b43fd (diff) | |
download | toolchain-utils-5d09ca047e14466720c080f0e7e627582fad8ec8.tar.gz |
llvm_tools: merge update_packages_*.py files
Merge update_packages_and_run_tryjobs.py and
update_packages_and_test_cq.py as the two modules share much command
code.
BUG=chromium:1001602
TEST=local tests.
Change-Id: Iac957ea77af4257e454fec99ff13424e778ec51a
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/toolchain-utils/+/2148478
Reviewed-by: Manoj Gupta <manojgupta@chromium.org>
Tested-by: Jian Cai <jiancai@google.com>
Diffstat (limited to 'llvm_tools')
-rw-r--r-- | llvm_tools/README.md | 27 | ||||
-rwxr-xr-x | llvm_tools/modify_a_tryjob.py | 2 | ||||
-rwxr-xr-x | llvm_tools/update_packages_and_run_tests.py (renamed from llvm_tools/update_packages_and_run_tryjobs.py) | 201 | ||||
-rwxr-xr-x | llvm_tools/update_packages_and_run_tests_unittest.py (renamed from llvm_tools/update_packages_and_run_tryjobs_unittest.py) | 206 | ||||
-rwxr-xr-x | llvm_tools/update_packages_and_test_cq.py | 226 | ||||
-rwxr-xr-x | llvm_tools/update_packages_and_test_cq_unittest.py | 174 |
6 files changed, 330 insertions, 506 deletions
diff --git a/llvm_tools/README.md b/llvm_tools/README.md index d42462ad..ce094e98 100644 --- a/llvm_tools/README.md +++ b/llvm_tools/README.md @@ -14,13 +14,13 @@ version. **NOTE: sudo must be permissive (i.e. **`cros_sdk`** should NOT prompt for a password)** -## `update_packages_and_run_tryjobs.py` +## `update_packages_and_run_tests.py` ### Usage -This script is used for updating a package's `LLVM_NEXT_HASH` (sys-devel/llvm, +This script is used for updating a package's LLVM hash (sys-devel/llvm, sys-libs/compiler-rt, sys-libs/libcxx, sys-libs/libcxxabi, and -sys-libs/llvm-libunwind) and then run tryjobs after updating the git hash. +sys-libs/llvm-libunwind) and then run tests after updating the git hash. An example when this script should be run is when certain boards would like to be tested with the updated `LLVM_NEXT_HASH`. @@ -28,8 +28,10 @@ to be tested with the updated `LLVM_NEXT_HASH`. For example: ``` -$ ./update_packages_and_run_tryjobs.py \ +$ ./update_packages_and_run_tests.py \ + --is_llvm_next \ --llvm_version tot \ + tryjobs \ --options nochromesdk latest-toolchain \ --builders kevin-release-tryjob nocturne-release-tryjob ``` @@ -41,25 +43,26 @@ in 'nochromesdk' and 'latest-toolchain' for each tryjob. For help with the command line arguments of the script, run: ``` -$ ./update_packages_and_run_tryjobs.py --help +$ ./update_packages_and_run_tests.py --help ``` -Similarly as the previous example, but for updating `LLVM_NEXT_HASH` to -google3: +Similarly as the previous example, but for updating `LLVM_HASH` to +google3 and test with cq+1: ``` -$ ./update_packages_and_run_tryjobs.py \ +$ ./update_packages_and_run_tests.py \ --llvm_version google3 \ - --options nochromesdk latest-toolchain \ - --builders kevin-release-tryjob nocturne-release-tryjob + cq ``` Similarly as the previous example, but for updating `LLVM_NEXT_HASH` to -the git hash of revision 367622: +the git hash of revision 367622 and test with tryobs: ``` -$ ./update_packages_and_run_tryjobs.py \ +$ ./update_packages_and_run_tests.py \ + --is_llvm_next \ --llvm_version 367622 \ + tryjobs \ --options nochromesdk latest-toolchain \ --builders kevin-release-tryjob nocturne-release-tryjob ``` diff --git a/llvm_tools/modify_a_tryjob.py b/llvm_tools/modify_a_tryjob.py index 5d04e7f4..41337257 100755 --- a/llvm_tools/modify_a_tryjob.py +++ b/llvm_tools/modify_a_tryjob.py @@ -17,7 +17,7 @@ import sys from assert_not_in_chroot import VerifyOutsideChroot from failure_modes import FailureModes from get_llvm_hash import GetLLVMHashAndVersionFromSVNOption -from update_packages_and_run_tryjobs import RunTryJobs +from update_packages_and_run_tests import RunTryJobs from update_tryjob_status import FindTryjobIndex from update_tryjob_status import TryjobStatus import update_chromeos_llvm_hash diff --git a/llvm_tools/update_packages_and_run_tryjobs.py b/llvm_tools/update_packages_and_run_tests.py index dc9e6643..ee57ea09 100755 --- a/llvm_tools/update_packages_and_run_tryjobs.py +++ b/llvm_tools/update_packages_and_run_tests.py @@ -38,15 +38,7 @@ def GetCommandLineArgs(): # Create parser and add optional command-line arguments. parser = argparse.ArgumentParser( - description= - 'Runs a tryjob if successfully updated LLVM_NEXT_HASH of packages.') - - # Add argument for the absolute path to the file that contains information on - # the previous tested svn version. - parser.add_argument( - '--last_tested', - help='the absolute path to the file that contains the last tested ' - 'arguments.') + description='Update an LLVM hash of packages and run tests.') # Add argument for other change lists that want to run alongside the tryjob # which has a change list of updating a package's git hash. @@ -54,42 +46,29 @@ def GetCommandLineArgs(): '--extra_change_lists', type=int, nargs='+', + default=[], help='change lists that would like to be run alongside the change list ' 'of updating the packages') - # Add argument for custom options for the tryjob. - parser.add_argument( - '--options', - required=False, - nargs='+', - help='options to use for the tryjob testing') - - # Add argument for builders for the tryjob. - parser.add_argument( - '--builders', - required=True, - nargs='+', - help='builders to use for the tryjob testing') - - # Add argument for the description of the tryjob. - parser.add_argument( - '--description', - required=False, - nargs='+', - help='the description of the tryjob') - # Add argument for a specific chroot path. parser.add_argument( '--chroot_path', default=cros_root, help='the path to the chroot (default: %(default)s)') - # Add argument for whether to display command contents to `stdout`. + # Add argument to choose between llvm and llvm-next. parser.add_argument( - '--verbose', + '--is_llvm_next', action='store_true', - help='display contents of a command to the terminal ' - '(default: %(default)s)') + help='which llvm hash to update. Update LLVM_NEXT_HASH if specified. ' + 'Otherwise, update LLVM_HASH') + + # Add argument for the absolute path to the file that contains information on + # the previous tested svn version. + parser.add_argument( + '--last_tested', + help='the absolute path to the file that contains the last tested ' + 'arguments.') # Add argument for the LLVM version to use. parser.add_argument( @@ -101,8 +80,47 @@ def GetCommandLineArgs(): '(default: finds the git hash of the google3 LLVM ' 'version)') + # Add argument to add reviewers for the created CL. + parser.add_argument( + '--reviewers', + nargs='+', + default=[], + help='The reviewers for the package update changelist') + + # Add argument for whether to display command contents to `stdout`. + parser.add_argument( + '--verbose', + action='store_true', + help='display contents of a command to the terminal ' + '(default: %(default)s)') + + subparsers = parser.add_subparsers(dest='subparser_name') + # Testing with the tryjobs. + tryjob_subparser = subparsers.add_parser('tryjobs') + tryjob_subparser.add_argument( + '--builders', + required=True, + nargs='+', + default=[], + help='builders to use for the tryjob testing') + + # Add argument for custom options for the tryjob. + tryjob_subparser.add_argument( + '--options', + required=False, + nargs='+', + default=[], + help='options to use for the tryjob testing') + + # Testing with CQ. + subparsers.add_parser('cq') + args_output = parser.parse_args() + subparser_names = ['tryjobs', 'cq'] + if args_output.subparser_name not in subparser_names: + parser.error('one of %s must be specified' % subparser_names) + return args_output @@ -134,6 +152,44 @@ def UnchangedSinceLastRun(last_tested_file, arg_dict): return arg_dict == last_arg_dict +def AddReviewers(cl, reviewers, chroot_path): + """Add reviewers for the created CL.""" + + gerrit_abs_path = os.path.join(chroot_path, 'chromite/bin/gerrit') + for reviewer in reviewers: + cmd = [gerrit_abs_path, 'reviewers', str(cl), reviewer] + + ExecCommandAndCaptureOutput(cmd) + + +def AddTryjobLinkToCL(tryjobs, cl, chroot_path): + """Adds the tryjob link(s) to the CL as a comment.""" + + # NOTE: Invoking `cros_sdk` does not make each tryjob link appear on its own + # line, so invoking the `gerrit` command directly instead of using `cros_sdk` + # to do it for us. + # + # FIXME: Need to figure out why `cros_sdk` does not add each tryjob link as a + # newline. + gerrit_abs_path = os.path.join(chroot_path, 'chromite/bin/gerrit') + + tryjob_links = ['Started the following tryjobs:'] + tryjob_links.extend(tryjob['link'] for tryjob in tryjobs) + + add_message_cmd = [ + gerrit_abs_path, 'message', + str(cl), '\n'.join(tryjob_links) + ] + + ExecCommandAndCaptureOutput(add_message_cmd) + + +# Testing with tryjobs +def GetCurrentTimeInUTC(): + """Returns the current time via `datetime.datetime.utcnow()`.""" + return datetime.datetime.utcnow() + + def GetTryJobCommand(change_list, extra_change_lists, options, builder): """Constructs the 'tryjob' command. @@ -163,11 +219,6 @@ def GetTryJobCommand(change_list, extra_change_lists, options, builder): return tryjob_cmd -def GetCurrentTimeInUTC(): - """Returns the current time via `datetime.datetime.utcnow()`.""" - return datetime.datetime.utcnow() - - def RunTryJobs(cl_number, extra_change_lists, options, builders, chroot_path, verbose): """Runs a tryjob/tryjobs. @@ -227,30 +278,33 @@ def RunTryJobs(cl_number, extra_change_lists, options, builders, chroot_path, return tryjob_results -def AddTryjobLinkToCL(tryjobs, cl, chroot_path): - """Adds the tryjob link(s) to the CL via `gerrit message <CL> <message>`.""" +# Testing with CQ +def GetCQDependString(dependent_cls): + """Get CQ dependency string e.g. `Cq-Depend: chromium:MM, chromium:NN`.""" + + if not dependent_cls: + return None + + # Cq-Depend must start a new paragraph prefixed with "Cq-Depend". + return '\nCq-Depend: ' + ', '.join(('chromium:%s' % i) for i in dependent_cls) + + +def StartCQDryRun(cl, dependent_cls, chroot_path): + """Start CQ dry run for the changelist and dependencies.""" - # NOTE: Invoking `cros_sdk` does not make each tryjob link appear on its own - # line, so invoking the `gerrit` command directly instead of using `cros_sdk` - # to do it for us. - # - # FIXME: Need to figure out why `cros_sdk` does not add each tryjob link as a - # newline. gerrit_abs_path = os.path.join(chroot_path, 'chromite/bin/gerrit') - tryjob_links = ['Started the following tryjobs:'] - tryjob_links.extend(tryjob['link'] for tryjob in tryjobs) + cl_list = [cl] + cl_list.extend(dependent_cls) - add_message_cmd = [ - gerrit_abs_path, 'message', - str(cl), '\n'.join(tryjob_links) - ] + for changes in cl_list: + cq_dry_run_cmd = [gerrit_abs_path, 'label-cq', str(changes), '1'] - ExecCommandAndCaptureOutput(add_message_cmd) + ExecCommandAndCaptureOutput(cq_dry_run_cmd) def main(): - """Updates the packages' 'LLVM_NEXT_HASH' and submits tryjobs. + """Updates the packages' LLVM hash and run tests. Raises: AssertionError: The script was run inside the chroot. @@ -282,40 +336,53 @@ def main(): arg_dict = { 'svn_version': svn_version, 'ebuilds': chroot_file_paths, - 'builders': args_output.builders, 'extra_cls': args_output.extra_change_lists, - 'tryjob_options': args_output.options } + if args_output.subparser_name == 'tryjobs': + arg_dict['builders'] = args_output.builders + arg_dict['tryjob_options'] = args_output.options if UnchangedSinceLastRun(args_output.last_tested, arg_dict): print('svn version (%d) matches the last tested svn version in %s' % (svn_version, args_output.last_tested)) return + llvm_variant = update_chromeos_llvm_hash.LLVMVariant.current + if args_output.is_llvm_next: + llvm_variant = update_chromeos_llvm_hash.LLVMVariant.next update_chromeos_llvm_hash.verbose = args_output.verbose + extra_commit_msg = None + if args_output.subparser_name == 'cq': + extra_commit_msg = GetCQDependString(args_output.extra_change_lists) change_list = update_chromeos_llvm_hash.UpdatePackages( update_packages, - update_chromeos_llvm_hash.LLVMVariant.next, + llvm_variant, git_hash, svn_version, args_output.chroot_path, patch_metadata_file, FailureModes.DISABLE_PATCHES, svn_option, - extra_commit_msg=None) + extra_commit_msg=extra_commit_msg) + + AddReviewers(change_list.cl_number, args_output.reviewers, + args_output.chroot_path) print('Successfully updated packages to %d' % svn_version) print('Gerrit URL: %s' % change_list.url) print('Change list number: %d' % change_list.cl_number) - tryjob_results = RunTryJobs(change_list.cl_number, - args_output.extra_change_lists, - args_output.options, args_output.builders, - args_output.chroot_path, args_output.verbose) - - print('Tryjobs:') - for tryjob in tryjob_results: - print(tryjob) + if args_output.subparser_name == 'tryjobs': + tryjob_results = RunTryJobs(change_list.cl_number, + args_output.extra_change_lists, + args_output.options, args_output.builders, + args_output.chroot_path, args_output.verbose) + print('Tryjobs:') + for tryjob in tryjob_results: + print(tryjob) + else: + StartCQDryRun(change_list.cl_number, args_output.extra_change_lists, + args_output.chroot_path) # If --last_tested is specified, record the arguments used if args_output.last_tested: diff --git a/llvm_tools/update_packages_and_run_tryjobs_unittest.py b/llvm_tools/update_packages_and_run_tests_unittest.py index 7352f4ca..721b995f 100755 --- a/llvm_tools/update_packages_and_run_tryjobs_unittest.py +++ b/llvm_tools/update_packages_and_run_tests_unittest.py @@ -4,7 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Unittests for running tryjobs after updating packages.""" +"""Unittests for running tests after updating packages.""" from __future__ import print_function @@ -16,20 +16,21 @@ from test_helpers import ArgsOutputTest from test_helpers import CreateTemporaryFile from update_chromeos_llvm_hash import CommitContents import update_chromeos_llvm_hash -import update_packages_and_run_tryjobs +import update_packages_and_run_tests +# Testing with tryjobs. class UpdatePackagesAndRunTryjobsTest(unittest.TestCase): """Unittests when running tryjobs after updating packages.""" def testNoLastTestedFile(self): self.assertEqual( - update_packages_and_run_tryjobs.UnchangedSinceLastRun(None, {}), False) + update_packages_and_run_tests.UnchangedSinceLastRun(None, {}), False) def testEmptyLastTestedFile(self): with CreateTemporaryFile() as temp_file: self.assertEqual( - update_packages_and_run_tryjobs.UnchangedSinceLastRun(temp_file, {}), + update_packages_and_run_tests.UnchangedSinceLastRun(temp_file, {}), False) def testLastTestedFileDoesNotExist(self): @@ -37,7 +38,7 @@ class UpdatePackagesAndRunTryjobsTest(unittest.TestCase): mock.mock_open(read_data='') self.assertEqual( - update_packages_and_run_tryjobs.UnchangedSinceLastRun( + update_packages_and_run_tests.UnchangedSinceLastRun( '/some/file/that/does/not/exist.txt', {}), False) def testMatchedLastTestedFile(self): @@ -61,7 +62,7 @@ class UpdatePackagesAndRunTryjobsTest(unittest.TestCase): f.write(json.dumps(arg_dict, indent=2)) self.assertEqual( - update_packages_and_run_tryjobs.UnchangedSinceLastRun( + update_packages_and_run_tests.UnchangedSinceLastRun( last_tested_file, arg_dict), True) def testGetTryJobCommandWithNoExtraInformation(self): @@ -75,8 +76,8 @@ class UpdatePackagesAndRunTryjobsTest(unittest.TestCase): ] self.assertEqual( - update_packages_and_run_tryjobs.GetTryJobCommand( - test_change_list, None, None, test_builder), + update_packages_and_run_tests.GetTryJobCommand(test_change_list, None, + None, test_builder), expected_tryjob_cmd_list) def testGetTryJobCommandWithExtraInformation(self): @@ -102,16 +103,16 @@ class UpdatePackagesAndRunTryjobsTest(unittest.TestCase): ] self.assertEqual( - update_packages_and_run_tryjobs.GetTryJobCommand( + update_packages_and_run_tests.GetTryJobCommand( test_change_list, test_extra_cls, test_options, test_builder), expected_tryjob_cmd_list) @mock.patch.object( - update_packages_and_run_tryjobs, + update_packages_and_run_tests, 'GetCurrentTimeInUTC', return_value='2019-09-09') - @mock.patch.object(update_packages_and_run_tryjobs, 'AddTryjobLinkToCL') - @mock.patch.object(update_packages_and_run_tryjobs, 'ChrootRunCommand') + @mock.patch.object(update_packages_and_run_tests, 'AddTryjobLinkToCL') + @mock.patch.object(update_packages_and_run_tests, 'ChrootRunCommand') def testSuccessfullySubmittedTryJob( self, mock_chroot_cmd, mock_add_tryjob_link_to_cl, mock_launch_time): @@ -135,12 +136,12 @@ class UpdatePackagesAndRunTryjobsTest(unittest.TestCase): cl_to_launch_tryjob = 900 verbose = False - tryjob_results_list = update_packages_and_run_tryjobs.RunTryJobs( + tryjob_results_list = update_packages_and_run_tests.RunTryJobs( cl_to_launch_tryjob, extra_cls, tryjob_options, builder_list, chroot_path, verbose) expected_tryjob_dict = { - 'launch_time': '2019-09-09', + 'launch_time': mock_launch_time.return_value, 'link': url, 'buildbucket_id': int(buildbucket_id), 'extra_cls': extra_cls, @@ -155,10 +156,8 @@ class UpdatePackagesAndRunTryjobsTest(unittest.TestCase): mock_add_tryjob_link_to_cl.assert_called_once() - mock_launch_time.assert_called_once() - @mock.patch.object( - update_packages_and_run_tryjobs, + update_packages_and_run_tests, 'ExecCommandAndCaptureOutput', return_value=None) def testSuccessfullyAddedTryjobLinkToCL(self, mock_exec_cmd): @@ -168,8 +167,8 @@ class UpdatePackagesAndRunTryjobsTest(unittest.TestCase): tryjob_result = [{'link': 'https://some_tryjob_link.com'}] - update_packages_and_run_tryjobs.AddTryjobLinkToCL( - tryjob_result, test_cl_number, chroot_path) + update_packages_and_run_tests.AddTryjobLinkToCL(tryjob_result, + test_cl_number, chroot_path) expected_gerrit_message = [ '%s/chromite/bin/gerrit' % chroot_path, 'message', @@ -179,13 +178,13 @@ class UpdatePackagesAndRunTryjobsTest(unittest.TestCase): mock_exec_cmd.assert_called_once_with(expected_gerrit_message) - @mock.patch.object(update_packages_and_run_tryjobs, 'RunTryJobs') + @mock.patch.object(update_packages_and_run_tests, 'RunTryJobs') @mock.patch.object(update_chromeos_llvm_hash, 'UpdatePackages') - @mock.patch.object(update_packages_and_run_tryjobs, 'GetCommandLineArgs') - @mock.patch.object(update_packages_and_run_tryjobs, + @mock.patch.object(update_packages_and_run_tests, 'GetCommandLineArgs') + @mock.patch.object(update_packages_and_run_tests, 'GetLLVMHashAndVersionFromSVNOption') @mock.patch.object( - update_packages_and_run_tryjobs, 'VerifyOutsideChroot', return_value=True) + update_packages_and_run_tests, 'VerifyOutsideChroot', return_value=True) @mock.patch.object(update_chromeos_llvm_hash, 'GetChrootBuildPaths') def testUpdatedLastTestedFileWithNewTestedRevision( self, mock_get_chroot_build_paths, mock_outside_chroot, @@ -218,10 +217,14 @@ class UpdatePackagesAndRunTryjobsTest(unittest.TestCase): # Call with a changed LLVM svn version args_output = ArgsOutputTest() - args_output.builders = builders + args_output.is_llvm_next = True args_output.extra_change_lists = extra_cls - args_output.options = tryjob_options args_output.last_tested = last_tested_file + args_output.reviewers = [] + + args_output.subparser_name = 'tryjobs' + args_output.builders = builders + args_output.options = tryjob_options mock_get_commandline_args.return_value = args_output @@ -237,7 +240,7 @@ class UpdatePackagesAndRunTryjobsTest(unittest.TestCase): 'buildbucket_id': 1234 }] - update_packages_and_run_tryjobs.main() + update_packages_and_run_tests.main() # Verify that the lasted tested file has been updated to the new LLVM # revision. @@ -257,5 +260,156 @@ class UpdatePackagesAndRunTryjobsTest(unittest.TestCase): mock_update_packages.assert_called_once() +class UpdatePackagesAndRunTestCQTest(unittest.TestCase): + """Unittests for CQ dry run after updating packages.""" + + def testGetCQDependString(self): + test_no_changelists = [] + test_single_changelist = [1234] + test_multiple_changelists = [1234, 5678] + + self.assertEqual( + update_packages_and_run_tests.GetCQDependString(test_no_changelists), + None) + + self.assertEqual( + update_packages_and_run_tests.GetCQDependString(test_single_changelist), + '\nCq-Depend: chromium:1234') + + self.assertEqual( + update_packages_and_run_tests.GetCQDependString( + test_multiple_changelists), + '\nCq-Depend: chromium:1234, chromium:5678') + + # Mock ExecCommandAndCaptureOutput for the gerrit command execution. + @mock.patch.object( + update_packages_and_run_tests, + 'ExecCommandAndCaptureOutput', + return_value=None) + def testStartCQDryRunNoDeps(self, mock_exec_cmd): + chroot_path = '/abs/path/to/chroot' + test_cl_number = 1000 + + # test with no deps cls. + extra_cls = [] + update_packages_and_run_tests.StartCQDryRun(test_cl_number, extra_cls, + chroot_path) + + expected_gerrit_message = [ + '%s/chromite/bin/gerrit' % chroot_path, 'label-cq', + str(test_cl_number), '1' + ] + + mock_exec_cmd.assert_called_once_with(expected_gerrit_message) + + # Mock ExecCommandAndCaptureOutput for the gerrit command execution. + @mock.patch.object( + update_packages_and_run_tests, + 'ExecCommandAndCaptureOutput', + return_value=None) + # test with a single deps cl. + def testStartCQDryRunSingleDep(self, mock_exec_cmd): + chroot_path = '/abs/path/to/chroot' + test_cl_number = 1000 + + extra_cls = [2000] + update_packages_and_run_tests.StartCQDryRun(test_cl_number, extra_cls, + chroot_path) + + expected_gerrit_cmd_1 = [ + '%s/chromite/bin/gerrit' % chroot_path, 'label-cq', + str(test_cl_number), '1' + ] + expected_gerrit_cmd_2 = [ + '%s/chromite/bin/gerrit' % chroot_path, 'label-cq', + str(2000), '1' + ] + + self.assertEqual(mock_exec_cmd.call_count, 2) + self.assertEqual(mock_exec_cmd.call_args_list[0], + mock.call(expected_gerrit_cmd_1)) + self.assertEqual(mock_exec_cmd.call_args_list[1], + mock.call(expected_gerrit_cmd_2)) + + # Mock ExecCommandAndCaptureOutput for the gerrit command execution. + @mock.patch.object( + update_packages_and_run_tests, + 'ExecCommandAndCaptureOutput', + return_value=None) + def testStartCQDryRunMultipleDep(self, mock_exec_cmd): + chroot_path = '/abs/path/to/chroot' + test_cl_number = 1000 + + # test with multiple deps cls. + extra_cls = [3000, 4000] + update_packages_and_run_tests.StartCQDryRun(test_cl_number, extra_cls, + chroot_path) + + expected_gerrit_cmd_1 = [ + '%s/chromite/bin/gerrit' % chroot_path, 'label-cq', + str(test_cl_number), '1' + ] + expected_gerrit_cmd_2 = [ + '%s/chromite/bin/gerrit' % chroot_path, 'label-cq', + str(3000), '1' + ] + expected_gerrit_cmd_3 = [ + '%s/chromite/bin/gerrit' % chroot_path, 'label-cq', + str(4000), '1' + ] + + self.assertEqual(mock_exec_cmd.call_count, 3) + self.assertEqual(mock_exec_cmd.call_args_list[0], + mock.call(expected_gerrit_cmd_1)) + self.assertEqual(mock_exec_cmd.call_args_list[1], + mock.call(expected_gerrit_cmd_2)) + self.assertEqual(mock_exec_cmd.call_args_list[2], + mock.call(expected_gerrit_cmd_3)) + + # Mock ExecCommandAndCaptureOutput for the gerrit command execution. + @mock.patch.object( + update_packages_and_run_tests, + 'ExecCommandAndCaptureOutput', + return_value=None) + # test with no reviewers. + def testAddReviewersNone(self, mock_exec_cmd): + chroot_path = '/abs/path/to/chroot' + reviewers = [] + test_cl_number = 1000 + + update_packages_and_run_tests.AddReviewers(test_cl_number, reviewers, + chroot_path) + self.assertTrue(mock_exec_cmd.not_called) + + # Mock ExecCommandAndCaptureOutput for the gerrit command execution. + @mock.patch.object( + update_packages_and_run_tests, + 'ExecCommandAndCaptureOutput', + return_value=None) + # test with multiple reviewers. + def testAddReviewersMultiple(self, mock_exec_cmd): + chroot_path = '/abs/path/to/chroot' + reviewers = ['none1@chromium.org', 'none2@chromium.org'] + test_cl_number = 1000 + + update_packages_and_run_tests.AddReviewers(test_cl_number, reviewers, + chroot_path) + + expected_gerrit_cmd_1 = [ + '%s/chromite/bin/gerrit' % chroot_path, 'reviewers', + str(test_cl_number), 'none1@chromium.org' + ] + expected_gerrit_cmd_2 = [ + '%s/chromite/bin/gerrit' % chroot_path, 'reviewers', + str(test_cl_number), 'none2@chromium.org' + ] + + self.assertEqual(mock_exec_cmd.call_count, 2) + self.assertEqual(mock_exec_cmd.call_args_list[0], + mock.call(expected_gerrit_cmd_1)) + self.assertEqual(mock_exec_cmd.call_args_list[1], + mock.call(expected_gerrit_cmd_2)) + + if __name__ == '__main__': unittest.main() diff --git a/llvm_tools/update_packages_and_test_cq.py b/llvm_tools/update_packages_and_test_cq.py deleted file mode 100755 index 15246e49..00000000 --- a/llvm_tools/update_packages_and_test_cq.py +++ /dev/null @@ -1,226 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# Copyright 2020 The Chromium OS Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Runs CQ dry run after updating the packages.""" - -from __future__ import print_function - -import argparse -import datetime -import json -import os - -from assert_not_in_chroot import VerifyOutsideChroot -from failure_modes import FailureModes -from get_llvm_hash import GetLLVMHashAndVersionFromSVNOption -from get_llvm_hash import is_svn_option -from subprocess_helpers import ChrootRunCommand -from subprocess_helpers import ExecCommandAndCaptureOutput -import update_chromeos_llvm_hash - - -def GetCommandLineArgs(): - """Parses the command line for the command line arguments. - - Returns: - The log level to use when retrieving the LLVM hash or google3 LLVM version, - the chroot path to use for executing chroot commands, - a list of a package or packages to update their LLVM next hash, - and the LLVM version to use when retrieving the LLVM hash. - """ - - # Default path to the chroot if a path is not specified. - cros_root = os.path.expanduser('~') - cros_root = os.path.join(cros_root, 'chromiumos') - - # Create parser and add optional command-line arguments. - parser = argparse.ArgumentParser( - description= - 'Runs a tryjob if successfully updated LLVM_NEXT_HASH of packages.') - - # Add argument for the absolute path to the file that contains information on - # the previous tested svn version. - parser.add_argument( - '--last_tested', - help='the absolute path to the file that contains the last tested ' - 'svn version') - - # Add argument for other change lists that want to run alongside the tryjob - # which has a change list of updating a package's git hash. - parser.add_argument( - '--extra_change_lists', - type=int, - default=[], - nargs='+', - help='change lists that would like to be run alongside the change list ' - 'of updating the packages') - - # Add argument for a specific chroot path. - parser.add_argument( - '--chroot_path', - default=cros_root, - help='the path to the chroot (default: %(default)s)') - - # Add argument to choose between llvm and llvm-next. - parser.add_argument( - '--is_llvm_next', - action='store_true', - help='which llvm hash to update. Update LLVM_NEXT_HASH if specified. ' - 'Otherwise, update LLVM_HASH') - - # Add argument to add reviewers for the created CL. - parser.add_argument( - '--reviewers', - nargs='+', - default=[], - help='The reviewers for the package update changelist') - - # Add argument for whether to display command contents to `stdout`. - parser.add_argument( - '--verbose', - action='store_true', - help='display contents of a command to the terminal ' - '(default: %(default)s)') - - # Add argument for the LLVM version to use. - parser.add_argument( - '--llvm_version', - type=is_svn_option, - required=True, - help='which git hash of LLVM to find ' - '{google3, ToT, <svn_version>} ' - '(default: finds the git hash of the google3 LLVM ' - 'version)') - - args_output = parser.parse_args() - - return args_output - - -def GetLastTestedSVNVersion(last_tested_file): - """Gets the lasted tested svn version from the file. - - Args: - last_tested_file: The absolute path to the file that contains the last - tested svn version. - - Returns: - The last tested svn version or 'None' if the file did not have a last tested - svn version (the file exists, but failed to convert the contents to an - integer) or the file does not exist. - """ - - if not last_tested_file: - return None - - last_svn_version = None - - # Get the last tested svn version if the file exists. - try: - with open(last_tested_file) as file_obj: - # For now, the first line contains the last tested svn version. - return int(file_obj.read().rstrip()) - - except (IOError, ValueError): - pass - - return last_svn_version - - -def GetCQDependString(dependent_cls): - """Get CQ dependency string e.g. `Cq-Depend: chromium:MM, chromium:NN`.""" - - if not dependent_cls: - return None - - # Cq-Depend must start a new paragraph prefixed with "Cq-Depend". - return '\nCq-Depend: ' + ', '.join(('chromium:%s' % i) for i in dependent_cls) - - -def AddReviewers(cl, reviewers, chroot_path): - """Add reviewers for the created CL.""" - - gerrit_abs_path = os.path.join(chroot_path, 'chromite/bin/gerrit') - for reviewer in reviewers: - cmd = [gerrit_abs_path, 'reviewers', str(cl), reviewer] - - ExecCommandAndCaptureOutput(cmd) - - -def StartCQDryRun(cl, dependent_cls, chroot_path): - """Start CQ dry run for the changelist and dependencies.""" - - gerrit_abs_path = os.path.join(chroot_path, 'chromite/bin/gerrit') - - cl_list = [cl] - cl_list.extend(dependent_cls) - - for changes in cl_list: - cq_dry_run_cmd = [gerrit_abs_path, 'label-cq', str(changes), '1'] - - ExecCommandAndCaptureOutput(cq_dry_run_cmd) - - -def main(): - """Updates the packages' 'LLVM_NEXT_HASH' and submits tryjobs. - - Raises: - AssertionError: The script was run inside the chroot. - """ - - VerifyOutsideChroot() - - args_output = GetCommandLineArgs() - - last_svn_version = GetLastTestedSVNVersion(args_output.last_tested) - - update_packages = [ - 'sys-devel/llvm', 'sys-libs/compiler-rt', 'sys-libs/libcxx', - 'sys-libs/libcxxabi', 'sys-libs/llvm-libunwind' - ] - - patch_metadata_file = 'PATCHES.json' - - svn_option = args_output.llvm_version - - git_hash, svn_version = GetLLVMHashAndVersionFromSVNOption(svn_option) - - # There is no need to run tryjobs when the SVN version matches the last tested - # SVN version. - if last_svn_version == svn_version: - print('svn version (%d) matches the last tested svn version (%d) in %s' % - (svn_version, last_svn_version, args_output.last_tested)) - return - - llvm_variant = update_chromeos_llvm_hash.LLVMVariant.current - if args_output.is_llvm_next: - llvm_variant = update_chromeos_llvm_hash.LLVMVariant.next - update_chromeos_llvm_hash.verbose = args_output.verbose - extra_commit_msg = GetCQDependString(args_output.extra_change_lists) - - change_list = update_chromeos_llvm_hash.UpdatePackages( - update_packages, llvm_variant, git_hash, svn_version, - args_output.chroot_path, patch_metadata_file, - FailureModes.DISABLE_PATCHES, svn_option, extra_commit_msg) - - print('Successfully updated packages to %d' % svn_version) - print('Gerrit URL: %s' % change_list.url) - print('Change list number: %d' % change_list.cl_number) - - AddReviewers(change_list.cl_number, args_output.reviewers, - args_output.chroot_path) - StartCQDryRun(change_list.cl_number, args_output.extra_change_lists, - args_output.chroot_path) - - # Updated the packages and submitted tryjobs successfully, so the file will - # contain 'svn_version' which will now become the last tested svn version. - if args_output.last_tested: - with open(args_output.last_tested, 'w', encoding='utf-8') as file_obj: - file_obj.write(str(svn_version)) - - -if __name__ == '__main__': - main() diff --git a/llvm_tools/update_packages_and_test_cq_unittest.py b/llvm_tools/update_packages_and_test_cq_unittest.py deleted file mode 100755 index acf17c6d..00000000 --- a/llvm_tools/update_packages_and_test_cq_unittest.py +++ /dev/null @@ -1,174 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# Copyright 2020 The Chromium OS Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Unittests for running tryjobs after updating packages.""" - -from __future__ import print_function - -import json -import unittest -import unittest.mock as mock - -from test_helpers import ArgsOutputTest -from test_helpers import CreateTemporaryFile -from update_chromeos_llvm_hash import CommitContents -import update_chromeos_llvm_hash -import update_packages_and_test_cq - - -class UpdatePackagesAndRunTestCQTest(unittest.TestCase): - """Unittests for CQ dry run after updating packages.""" - - def testGetCQDependString(self): - test_no_changelists = [] - test_single_changelist = [1234] - test_multiple_changelists = [1234, 5678] - - self.assertEqual( - update_packages_and_test_cq.GetCQDependString(test_no_changelists), - None) - - self.assertEqual( - update_packages_and_test_cq.GetCQDependString(test_single_changelist), - '\nCq-Depend: chromium:1234') - - self.assertEqual( - update_packages_and_test_cq.GetCQDependString( - test_multiple_changelists), - '\nCq-Depend: chromium:1234, chromium:5678') - - # Mock ExecCommandAndCaptureOutput for the gerrit command execution. - @mock.patch.object( - update_packages_and_test_cq, - 'ExecCommandAndCaptureOutput', - return_value=None) - def testStartCQDryRunNoDeps(self, mock_exec_cmd): - chroot_path = '/abs/path/to/chroot' - test_cl_number = 1000 - - # test with no deps cls. - extra_cls = [] - update_packages_and_test_cq.StartCQDryRun(test_cl_number, extra_cls, - chroot_path) - - expected_gerrit_message = [ - '%s/chromite/bin/gerrit' % chroot_path, 'label-cq', - str(test_cl_number), '1' - ] - - mock_exec_cmd.assert_called_once_with(expected_gerrit_message) - - # Mock ExecCommandAndCaptureOutput for the gerrit command execution. - @mock.patch.object( - update_packages_and_test_cq, - 'ExecCommandAndCaptureOutput', - return_value=None) - # test with a single deps cl. - def testStartCQDryRunSingleDep(self, mock_exec_cmd): - chroot_path = '/abs/path/to/chroot' - test_cl_number = 1000 - - extra_cls = [2000] - update_packages_and_test_cq.StartCQDryRun(test_cl_number, extra_cls, - chroot_path) - - expected_gerrit_cmd_1 = [ - '%s/chromite/bin/gerrit' % chroot_path, 'label-cq', - str(test_cl_number), '1' - ] - expected_gerrit_cmd_2 = [ - '%s/chromite/bin/gerrit' % chroot_path, 'label-cq', - str(2000), '1' - ] - - self.assertEqual(mock_exec_cmd.call_count, 2) - self.assertEqual(mock_exec_cmd.call_args_list[0], - mock.call(expected_gerrit_cmd_1)) - self.assertEqual(mock_exec_cmd.call_args_list[1], - mock.call(expected_gerrit_cmd_2)) - - # Mock ExecCommandAndCaptureOutput for the gerrit command execution. - @mock.patch.object( - update_packages_and_test_cq, - 'ExecCommandAndCaptureOutput', - return_value=None) - def testStartCQDryRunMultipleDep(self, mock_exec_cmd): - chroot_path = '/abs/path/to/chroot' - test_cl_number = 1000 - - # test with multiple deps cls. - extra_cls = [3000, 4000] - update_packages_and_test_cq.StartCQDryRun(test_cl_number, extra_cls, - chroot_path) - - expected_gerrit_cmd_1 = [ - '%s/chromite/bin/gerrit' % chroot_path, 'label-cq', - str(test_cl_number), '1' - ] - expected_gerrit_cmd_2 = [ - '%s/chromite/bin/gerrit' % chroot_path, 'label-cq', - str(3000), '1' - ] - expected_gerrit_cmd_3 = [ - '%s/chromite/bin/gerrit' % chroot_path, 'label-cq', - str(4000), '1' - ] - - self.assertEqual(mock_exec_cmd.call_count, 3) - self.assertEqual(mock_exec_cmd.call_args_list[0], - mock.call(expected_gerrit_cmd_1)) - self.assertEqual(mock_exec_cmd.call_args_list[1], - mock.call(expected_gerrit_cmd_2)) - self.assertEqual(mock_exec_cmd.call_args_list[2], - mock.call(expected_gerrit_cmd_3)) - - # Mock ExecCommandAndCaptureOutput for the gerrit command execution. - @mock.patch.object( - update_packages_and_test_cq, - 'ExecCommandAndCaptureOutput', - return_value=None) - # test with no reviewers. - def testAddReviewersNone(self, mock_exec_cmd): - chroot_path = '/abs/path/to/chroot' - reviewers = [] - test_cl_number = 1000 - - update_packages_and_test_cq.AddReviewers(test_cl_number, reviewers, - chroot_path) - self.assertTrue(mock_exec_cmd.not_called) - - # Mock ExecCommandAndCaptureOutput for the gerrit command execution. - @mock.patch.object( - update_packages_and_test_cq, - 'ExecCommandAndCaptureOutput', - return_value=None) - # test with multiple reviewers. - def testAddReviewersMultiple(self, mock_exec_cmd): - chroot_path = '/abs/path/to/chroot' - reviewers = ['none1@chromium.org', 'none2@chromium.org'] - test_cl_number = 1000 - - update_packages_and_test_cq.AddReviewers(test_cl_number, reviewers, - chroot_path) - - expected_gerrit_cmd_1 = [ - '%s/chromite/bin/gerrit' % chroot_path, 'reviewers', - str(test_cl_number), 'none1@chromium.org' - ] - expected_gerrit_cmd_2 = [ - '%s/chromite/bin/gerrit' % chroot_path, 'reviewers', - str(test_cl_number), 'none2@chromium.org' - ] - - self.assertEqual(mock_exec_cmd.call_count, 2) - self.assertEqual(mock_exec_cmd.call_args_list[0], - mock.call(expected_gerrit_cmd_1)) - self.assertEqual(mock_exec_cmd.call_args_list[1], - mock.call(expected_gerrit_cmd_2)) - - -if __name__ == '__main__': - unittest.main() |