aboutsummaryrefslogtreecommitdiff
path: root/llvm_tools
diff options
context:
space:
mode:
authorJian Cai <jiancai@google.com>2020-04-20 17:58:02 -0700
committerJian Cai <jiancai@google.com>2020-04-21 18:59:28 +0000
commit089004cd44039fd9d57fab03093a0e3a9e5d9c10 (patch)
tree6fefb74945d4cf2cebf4c8212908a187b381b42b /llvm_tools
parent9c17d84bcb0f4465c611e1304cdfa7d1d47a8301 (diff)
downloadtoolchain-utils-089004cd44039fd9d57fab03093a0e3a9e5d9c10.tar.gz
llvm_tot: add an option for recipe builders.
Add an option to launch LLVM TOT builders with recipe builders to update_packages_and_run_tests.py. The builders launched will not run hwtests for now. BUG=chromium:1072063 TEST=local tests. Change-Id: I1c34090f2d2ea6d9b7efab0a0dccf795396c96d1 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/toolchain-utils/+/2157624 Tested-by: Jian Cai <jiancai@google.com> Reviewed-by: Manoj Gupta <manojgupta@chromium.org> Reviewed-by: George Burgess <gbiv@chromium.org>
Diffstat (limited to 'llvm_tools')
-rw-r--r--llvm_tools/README.md10
-rwxr-xr-xllvm_tools/update_packages_and_run_tests.py170
-rwxr-xr-xllvm_tools/update_packages_and_run_tests_unittest.py159
3 files changed, 220 insertions, 119 deletions
diff --git a/llvm_tools/README.md b/llvm_tools/README.md
index ce094e98..b0fbea5a 100644
--- a/llvm_tools/README.md
+++ b/llvm_tools/README.md
@@ -21,6 +21,8 @@ password)**
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 tests after updating the git hash.
+There are three ways to test the change, including starting tryjobs,
+recipe builders or using cq+1.
An example when this script should be run is when certain boards would like
to be tested with the updated `LLVM_NEXT_HASH`.
@@ -56,15 +58,15 @@ $ ./update_packages_and_run_tests.py \
```
Similarly as the previous example, but for updating `LLVM_NEXT_HASH` to
-the git hash of revision 367622 and test with tryobs:
+the git hash of revision 367622 and test with recipe builders:
```
$ ./update_packages_and_run_tests.py \
--is_llvm_next \
--llvm_version 367622 \
- tryjobs \
- --options nochromesdk latest-toolchain \
- --builders kevin-release-tryjob nocturne-release-tryjob
+ recipe \
+ --options -nocanary \
+ --builders chromeos/toolchain/kevin-llvm chromeos/toolchain/nocturne-llvm
```
## `update_chromeos_llvm_hash.py`
diff --git a/llvm_tools/update_packages_and_run_tests.py b/llvm_tools/update_packages_and_run_tests.py
index 9fe4fe02..f47b5cda 100755
--- a/llvm_tools/update_packages_and_run_tests.py
+++ b/llvm_tools/update_packages_and_run_tests.py
@@ -12,11 +12,11 @@ import argparse
import datetime
import json
import os
+import subprocess
import chroot
import failure_modes
import get_llvm_hash
-import subprocess_helpers
import update_chromeos_llvm_hash
@@ -93,8 +93,10 @@ def GetCommandLineArgs():
'(default: %(default)s)')
subparsers = parser.add_subparsers(dest='subparser_name')
+ subparser_names = []
# Testing with the tryjobs.
tryjob_subparser = subparsers.add_parser('tryjobs')
+ subparser_names.append('tryjobs')
tryjob_subparser.add_argument(
'--builders',
required=True,
@@ -110,12 +112,29 @@ def GetCommandLineArgs():
default=[],
help='options to use for the tryjob testing')
+ # Testing with the recipe builders
+ recipe_subparser = subparsers.add_parser('recipe')
+ subparser_names.append('recipe')
+ recipe_subparser.add_argument(
+ '--options',
+ required=False,
+ nargs='+',
+ default=[],
+ help='options passed to the recipe builders')
+
+ recipe_subparser.add_argument(
+ '--builders',
+ required=True,
+ nargs='+',
+ default=[],
+ help='recipe builders to launch')
+
# Testing with CQ.
subparsers.add_parser('cq')
+ subparser_names.append('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)
@@ -157,11 +176,11 @@ def AddReviewers(cl, reviewers, chroot_path):
for reviewer in reviewers:
cmd = [gerrit_abs_path, 'reviewers', str(cl), reviewer]
- subprocess_helpers.ExecCommandAndCaptureOutput(cmd)
+ subprocess.check_output(cmd)
-def AddTryjobLinkToCL(tryjobs, cl, chroot_path):
- """Adds the tryjob link(s) to the CL as a comment."""
+def AddLinksToCL(tests, cl, chroot_path):
+ """Adds the test 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`
@@ -171,15 +190,12 @@ def AddTryjobLinkToCL(tryjobs, cl, chroot_path):
# 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)
+ links = ['Started the following tests:']
+ links.extend(test['link'] for test in tests)
- add_message_cmd = [
- gerrit_abs_path, 'message',
- str(cl), '\n'.join(tryjob_links)
- ]
+ add_message_cmd = [gerrit_abs_path, 'message', str(cl), '\n'.join(links)]
- subprocess_helpers.ExecCommandAndCaptureOutput(add_message_cmd)
+ subprocess.check_output(add_message_cmd)
# Testing with tryjobs
@@ -209,16 +225,15 @@ def GetTryJobCommand(change_list, extra_change_lists, options, builder):
for extra_cl in extra_change_lists:
tryjob_cmd.extend(['-g', '%d' % extra_cl])
- tryjob_cmd.append(builder)
-
if options:
tryjob_cmd.extend('--%s' % option for option in options)
+ tryjob_cmd.append(builder)
+
return tryjob_cmd
-def RunTryJobs(cl_number, extra_change_lists, options, builders, chroot_path,
- verbose):
+def RunTryJobs(cl_number, extra_change_lists, options, builders, chroot_path):
"""Runs a tryjob/tryjobs.
Args:
@@ -228,7 +243,6 @@ def RunTryJobs(cl_number, extra_change_lists, options, builders, chroot_path,
options: Any options to be passed into the 'tryjob' command.
builders: All the builders to run the 'tryjob' with.
chroot_path: The absolute path to the chroot.
- verbose: Print command contents to `stdout`.
Returns:
A list that contains stdout contents of each tryjob, where stdout is
@@ -239,42 +253,91 @@ def RunTryJobs(cl_number, extra_change_lists, options, builders, chroot_path,
ValueError: Failed to submit a tryjob.
"""
- # Contains the results of each tryjob. The results are retrieved from 'out'
- # which is stdout of the command executer.
- tryjob_results = []
+ # Contains the results of each builder.
+ tests = []
- # For each builder passed into the command line:
- #
- # Run a tryjob with the change list number obtained from updating the
+ # Run tryjobs with the change list number obtained from updating the
# packages and append additional changes lists and options obtained from the
# command line.
- for cur_builder in builders:
- tryjob_cmd = GetTryJobCommand(cl_number, extra_change_lists, options,
- cur_builder)
+ for builder in builders:
+ cmd = GetTryJobCommand(cl_number, extra_change_lists, options, builder)
+
+ out = subprocess.check_output(cmd, cwd=chroot_path, encoding='utf-8')
+
+ test_output = json.loads(out)
+
+ tests.append({
+ 'launch_time': str(GetCurrentTimeInUTC()),
+ 'link': str(test_output[0]['url']),
+ 'buildbucket_id': int(test_output[0]['buildbucket_id']),
+ 'extra_cls': extra_change_lists,
+ 'options': options,
+ 'builder': [builder]
+ })
- out = subprocess_helpers.ChrootRunCommand(
- chroot_path, tryjob_cmd, verbose=verbose)
+ AddLinksToCL(tests, cl_number, chroot_path)
- tryjob_launch_time = GetCurrentTimeInUTC()
+ return tests
- tryjob_contents = json.loads(out)
- buildbucket_id = int(tryjob_contents[0]['buildbucket_id'])
+def StartRecipeBuilders(cl_number, extra_change_lists, options, builders,
+ chroot_path):
+ """Launch recipe builders.
- new_tryjob = {
- 'launch_time': str(tryjob_launch_time),
- 'link': str(tryjob_contents[0]['url']),
- 'buildbucket_id': buildbucket_id,
+ Args:
+ cl_number: The CL created by updating the packages.
+ extra_change_lists: Any extra change lists that would run alongside the CL
+ that was created by updating the packages ('cl_number').
+ options: Any options to be passed into the 'tryjob' command.
+ builders: All the builders to run the 'tryjob' with.
+ chroot_path: The absolute path to the chroot.
+
+ Returns:
+ A list that contains stdout contents of each builder, where stdout is
+ information (a hashmap) about the tryjob. The hashmap also contains stderr
+ if there was an error when running a tryjob.
+
+ Raises:
+ ValueError: Failed to start a builder.
+ """
+
+ # Contains the results of each builder.
+ tests = []
+
+ # Launch a builders with the change list number obtained from updating the
+ # packages and append additional changes lists and options obtained from the
+ # command line.
+ for builder in builders:
+ cmd = ['bb', 'add', '-json']
+
+ if cl_number:
+ cmd.extend(['-cl', 'crrev.com/c/%d' % cl_number])
+
+ if extra_change_lists:
+ for cl in extra_change_lists:
+ cmd.extend(['-cl', 'crrev.com/c/%d' % cl])
+
+ if options:
+ cmd.extend(options)
+
+ cmd.append(builder)
+
+ out = subprocess.check_output(cmd, cwd=chroot_path, encoding='utf-8')
+
+ test_output = json.loads(out)
+
+ tests.append({
+ 'launch_time': test_output['createTime'],
+ 'link': 'http://ci.chromium.org/b/%s' % test_output['id'],
+ 'buildbucket_id': test_output['id'],
'extra_cls': extra_change_lists,
'options': options,
- 'builder': [cur_builder]
- }
-
- tryjob_results.append(new_tryjob)
+ 'builder': [builder]
+ })
- AddTryjobLinkToCL(tryjob_results, cl_number, chroot_path)
+ AddLinksToCL(tests, cl_number, chroot_path)
- return tryjob_results
+ return tests
# Testing with CQ
@@ -299,7 +362,7 @@ def StartCQDryRun(cl, dependent_cls, chroot_path):
for changes in cl_list:
cq_dry_run_cmd = [gerrit_abs_path, 'label-cq', str(changes), '1']
- subprocess_helpers.ExecCommandAndCaptureOutput(cq_dry_run_cmd)
+ subprocess.check_output(cq_dry_run_cmd)
def main():
@@ -338,7 +401,7 @@ def main():
'ebuilds': chroot_file_paths,
'extra_cls': args_output.extra_change_lists,
}
- if args_output.subparser_name == 'tryjobs':
+ if args_output.subparser_name in ('tryjobs', 'recipe'):
arg_dict['builders'] = args_output.builders
arg_dict['tryjob_options'] = args_output.options
if UnchangedSinceLastRun(args_output.last_tested, arg_dict):
@@ -373,13 +436,20 @@ def main():
print('Change list number: %d' % change_list.cl_number)
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)
+ tests = RunTryJobs(change_list.cl_number, args_output.extra_change_lists,
+ args_output.options, args_output.builders,
+ args_output.chroot_path)
+ print('Tests:')
+ for test in tests:
+ print(test)
+ elif args_output.subparser_name == 'recipe':
+ tests = StartRecipeBuilders(
+ change_list.cl_number, args_output.extra_change_lists,
+ args_output.options, args_output.builders, args_output.chroot_path)
+ print('Tests:')
+ for test in tests:
+ print(test)
+
else:
StartCQDryRun(change_list.cl_number, args_output.extra_change_lists,
args_output.chroot_path)
diff --git a/llvm_tools/update_packages_and_run_tests_unittest.py b/llvm_tools/update_packages_and_run_tests_unittest.py
index 70ecfffe..25a8f83c 100755
--- a/llvm_tools/update_packages_and_run_tests_unittest.py
+++ b/llvm_tools/update_packages_and_run_tests_unittest.py
@@ -9,13 +9,13 @@
from __future__ import print_function
import json
+import subprocess
import unittest
import unittest.mock as mock
import chroot
import get_llvm_hash
import git
-import subprocess_helpers
import test_helpers
import update_chromeos_llvm_hash
import update_packages_and_run_tests
@@ -68,112 +68,146 @@ class UpdatePackagesAndRunTryjobsTest(unittest.TestCase):
last_tested_file, arg_dict), True)
def testGetTryJobCommandWithNoExtraInformation(self):
- test_change_list = 1234
+ change_list = 1234
- test_builder = 'nocturne'
+ builder = 'nocturne'
- expected_tryjob_cmd_list = [
+ expected_cmd = [
'cros', 'tryjob', '--yes', '--json', '-g',
- '%d' % test_change_list, test_builder
+ '%d' % change_list, builder
]
self.assertEqual(
- update_packages_and_run_tests.GetTryJobCommand(test_change_list, None,
- None, test_builder),
- expected_tryjob_cmd_list)
+ update_packages_and_run_tests.GetTryJobCommand(change_list, None, None,
+ builder), expected_cmd)
def testGetTryJobCommandWithExtraInformation(self):
- test_change_list = 4321
- test_extra_cls = [1000, 10]
- test_options = ['report_error', 'delete_tryjob']
- test_builder = 'kevin'
+ change_list = 4321
+ extra_cls = [1000, 10]
+ options = ['option1', 'option2']
+ builder = 'kevin'
- expected_tryjob_cmd_list = [
+ expected_cmd = [
'cros',
'tryjob',
'--yes',
'--json',
'-g',
- '%d' % test_change_list,
+ '%d' % change_list,
'-g',
- '%d' % test_extra_cls[0],
+ '%d' % extra_cls[0],
'-g',
- '%d' % test_extra_cls[1],
- test_builder,
- '--%s' % test_options[0],
- '--%s' % test_options[1],
+ '%d' % extra_cls[1],
+ '--%s' % options[0],
+ '--%s' % options[1],
+ builder,
]
self.assertEqual(
update_packages_and_run_tests.GetTryJobCommand(
- test_change_list, test_extra_cls, test_options, test_builder),
- expected_tryjob_cmd_list)
+ change_list, extra_cls, options, builder), expected_cmd)
@mock.patch.object(
update_packages_and_run_tests,
'GetCurrentTimeInUTC',
return_value='2019-09-09')
- @mock.patch.object(update_packages_and_run_tests, 'AddTryjobLinkToCL')
- @mock.patch.object(subprocess_helpers, 'ChrootRunCommand')
- def testSuccessfullySubmittedTryJob(
- self, mock_chroot_cmd, mock_add_tryjob_link_to_cl, mock_launch_time):
+ @mock.patch.object(update_packages_and_run_tests, 'AddLinksToCL')
+ @mock.patch.object(subprocess, 'check_output')
+ def testSuccessfullySubmittedTryJob(self, mock_cmd, mock_add_links_to_cl,
+ mock_launch_time):
- expected_tryjob_cmd_list = [
+ expected_cmd = [
'cros', 'tryjob', '--yes', '--json', '-g',
'%d' % 900, '-g',
- '%d' % 1200, 'builder1', '--some_option'
+ '%d' % 1200, '--some_option', 'builder1'
]
- buildbucket_id = '1234'
+ bb_id = '1234'
url = 'https://some_tryjob_url.com'
- tryjob_launch_contents = [{'buildbucket_id': buildbucket_id, 'url': url}]
+ mock_cmd.return_value = json.dumps([{'buildbucket_id': bb_id, 'url': url}])
- mock_chroot_cmd.return_value = json.dumps(tryjob_launch_contents)
-
- extra_cls = [1200]
- tryjob_options = ['some_option']
- builder_list = ['builder1']
chroot_path = '/some/path/to/chroot'
- cl_to_launch_tryjob = 900
- verbose = False
+ cl = 900
+ extra_cls = [1200]
+ options = ['some_option']
+ builders = ['builder1']
- tryjob_results_list = update_packages_and_run_tests.RunTryJobs(
- cl_to_launch_tryjob, extra_cls, tryjob_options, builder_list,
- chroot_path, verbose)
+ tests = update_packages_and_run_tests.RunTryJobs(cl, extra_cls, options,
+ builders, chroot_path)
- expected_tryjob_dict = {
+ expected_tests = [{
'launch_time': mock_launch_time.return_value,
'link': url,
- 'buildbucket_id': int(buildbucket_id),
+ 'buildbucket_id': int(bb_id),
'extra_cls': extra_cls,
- 'options': tryjob_options,
- 'builder': builder_list
- }
+ 'options': options,
+ 'builder': builders
+ }]
- self.assertEqual(tryjob_results_list, [expected_tryjob_dict])
+ self.assertEqual(tests, expected_tests)
- mock_chroot_cmd.assert_called_once_with(
- chroot_path, expected_tryjob_cmd_list, verbose=False)
+ mock_cmd.assert_called_once_with(
+ expected_cmd, cwd=chroot_path, encoding='utf-8')
- mock_add_tryjob_link_to_cl.assert_called_once()
+ mock_add_links_to_cl.assert_called_once()
- @mock.patch.object(
- subprocess_helpers, 'ExecCommandAndCaptureOutput', return_value=None)
- def testSuccessfullyAddedTryjobLinkToCL(self, mock_exec_cmd):
+ @mock.patch.object(update_packages_and_run_tests, 'AddLinksToCL')
+ @mock.patch.object(subprocess, 'check_output')
+ def testSuccessfullySubmittedRecipeBuilders(self, mock_cmd,
+ mock_add_links_to_cl):
+
+ expected_cmd = [
+ 'bb', 'add', '-json', '-cl',
+ 'crrev.com/c/%s' % 900, '-cl',
+ 'crrev.com/c/%s' % 1200, 'some_option', 'builder1'
+ ]
+
+ bb_id = '1234'
+ create_time = '2020-04-18T00:03:53.978767Z'
+
+ mock_cmd.return_value = json.dumps({'id': bb_id, 'createTime': create_time})
+
+ chroot_path = '/some/path/to/chroot'
+ cl = 900
+ extra_cls = [1200]
+ options = ['some_option']
+ builders = ['builder1']
+
+ tests = update_packages_and_run_tests.StartRecipeBuilders(
+ cl, extra_cls, options, builders, chroot_path)
+
+ expected_tests = [{
+ 'launch_time': create_time,
+ 'link': 'http://ci.chromium.org/b/%s' % bb_id,
+ 'buildbucket_id': bb_id,
+ 'extra_cls': extra_cls,
+ 'options': options,
+ 'builder': builders
+ }]
+
+ self.assertEqual(tests, expected_tests)
+
+ mock_cmd.assert_called_once_with(
+ expected_cmd, cwd=chroot_path, encoding='utf-8')
+
+ mock_add_links_to_cl.assert_called_once()
+
+ @mock.patch.object(subprocess, 'check_output', return_value=None)
+ def testSuccessfullyAddedTestLinkToCL(self, mock_exec_cmd):
chroot_path = '/abs/path/to/chroot'
test_cl_number = 1000
- tryjob_result = [{'link': 'https://some_tryjob_link.com'}]
+ tests = [{'link': 'https://some_tryjob_link.com'}]
- update_packages_and_run_tests.AddTryjobLinkToCL(tryjob_result,
- test_cl_number, chroot_path)
+ update_packages_and_run_tests.AddLinksToCL(tests, test_cl_number,
+ chroot_path)
expected_gerrit_message = [
'%s/chromite/bin/gerrit' % chroot_path, 'message',
str(test_cl_number),
- 'Started the following tryjobs:\n%s' % tryjob_result[0]['link']
+ 'Started the following tests:\n%s' % tests[0]['link']
]
mock_exec_cmd.assert_called_once_with(expected_gerrit_message)
@@ -280,8 +314,7 @@ class UpdatePackagesAndRunTestCQTest(unittest.TestCase):
'\nCq-Depend: chromium:1234, chromium:5678')
# Mock ExecCommandAndCaptureOutput for the gerrit command execution.
- @mock.patch.object(
- subprocess_helpers, 'ExecCommandAndCaptureOutput', return_value=None)
+ @mock.patch.object(subprocess, 'check_output', return_value=None)
def testStartCQDryRunNoDeps(self, mock_exec_cmd):
chroot_path = '/abs/path/to/chroot'
test_cl_number = 1000
@@ -299,8 +332,7 @@ class UpdatePackagesAndRunTestCQTest(unittest.TestCase):
mock_exec_cmd.assert_called_once_with(expected_gerrit_message)
# Mock ExecCommandAndCaptureOutput for the gerrit command execution.
- @mock.patch.object(
- subprocess_helpers, 'ExecCommandAndCaptureOutput', return_value=None)
+ @mock.patch.object(subprocess, 'check_output', return_value=None)
# test with a single deps cl.
def testStartCQDryRunSingleDep(self, mock_exec_cmd):
chroot_path = '/abs/path/to/chroot'
@@ -326,8 +358,7 @@ class UpdatePackagesAndRunTestCQTest(unittest.TestCase):
mock.call(expected_gerrit_cmd_2))
# Mock ExecCommandAndCaptureOutput for the gerrit command execution.
- @mock.patch.object(
- subprocess_helpers, 'ExecCommandAndCaptureOutput', return_value=None)
+ @mock.patch.object(subprocess, 'check_output', return_value=None)
def testStartCQDryRunMultipleDep(self, mock_exec_cmd):
chroot_path = '/abs/path/to/chroot'
test_cl_number = 1000
@@ -359,8 +390,7 @@ class UpdatePackagesAndRunTestCQTest(unittest.TestCase):
mock.call(expected_gerrit_cmd_3))
# Mock ExecCommandAndCaptureOutput for the gerrit command execution.
- @mock.patch.object(
- subprocess_helpers, 'ExecCommandAndCaptureOutput', return_value=None)
+ @mock.patch.object(subprocess, 'check_output', return_value=None)
# test with no reviewers.
def testAddReviewersNone(self, mock_exec_cmd):
chroot_path = '/abs/path/to/chroot'
@@ -372,8 +402,7 @@ class UpdatePackagesAndRunTestCQTest(unittest.TestCase):
self.assertTrue(mock_exec_cmd.not_called)
# Mock ExecCommandAndCaptureOutput for the gerrit command execution.
- @mock.patch.object(
- subprocess_helpers, 'ExecCommandAndCaptureOutput', return_value=None)
+ @mock.patch.object(subprocess, 'check_output', return_value=None)
# test with multiple reviewers.
def testAddReviewersMultiple(self, mock_exec_cmd):
chroot_path = '/abs/path/to/chroot'