blob: 44a019d38c25df0bd1768606cc463c1434cfc025 [file] [log] [blame]
Kuang-che Wu875c89a2020-01-08 14:30:55 +08001#!/usr/bin/env python3
Kuang-che Wu6e4beca2018-06-27 17:45:02 +08002# -*- coding: utf-8 -*-
Kuang-che Wubfc4a642018-04-19 11:54:08 +08003# Copyright 2018 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6"""ChromeOS bisector to bisect local build commits.
7
8Example:
Kuang-che Wu94f48e52018-07-25 15:28:31 +08009 $ ./bisect_cros_repo.py init --old rev1 --new rev2 \\
10 --chromeos_root ~/chromiumos \\
Kuang-che Wud8fc9572018-10-03 21:00:41 +080011 --chromeos_mirror $CHROMEOS_MIRROR
Kuang-che Wubfc4a642018-04-19 11:54:08 +080012 $ ./bisect_cros_repo.py config switch ./switch_cros_localbuild.py
13 $ ./bisect_cros_repo.py config eval ./eval-manually.sh
14 $ ./bisect_cros_repo.py run
15
16When running switcher and evaluator, following environment variables
17will be set:
18 BOARD (e.g. samus),
19 DUT (e.g. samus-dut),
Kuang-che Wu99e808f2019-06-26 12:17:32 +080020 CROS_VERSION (e.g. 9901.0.0,9902.0.0+3), and
Kuang-che Wuc95fc152018-06-28 18:13:22 +080021 CHROMEOS_ROOT (e.g. ~/chromiumos).
Kuang-che Wubfc4a642018-04-19 11:54:08 +080022"""
23
24from __future__ import print_function
25import logging
26
Kuang-che Wu2526a672019-09-10 16:23:59 +080027from bisect_kit import bisector_cli
Kuang-che Wubfc4a642018-04-19 11:54:08 +080028from bisect_kit import cli
Kuang-che Wue4bae0b2018-07-19 12:10:14 +080029from bisect_kit import codechange
Kuang-che Wubfc4a642018-04-19 11:54:08 +080030from bisect_kit import configure
31from bisect_kit import core
Kuang-che Wue4bae0b2018-07-19 12:10:14 +080032from bisect_kit import cros_util
Kuang-che Wue121fae2018-11-09 16:18:39 +080033from bisect_kit import errors
Kuang-che Wue4bae0b2018-07-19 12:10:14 +080034from bisect_kit import repo_util
Kuang-che Wubfc4a642018-04-19 11:54:08 +080035
36logger = logging.getLogger(__name__)
37
38
Kuang-che Wue80bb872018-11-15 19:45:25 +080039def generate_action_link(action):
40 if action['action_type'] == 'commit':
41 repo_url = action['repo_url']
42 action['link'] = repo_url + '/+/' + action['rev']
43
44
Kuang-che Wubfc4a642018-04-19 11:54:08 +080045class ChromeOSRepoDomain(core.BisectDomain):
46 """BisectDomain for ChromeOS code changes."""
47 revtype = staticmethod(cros_util.argtype_cros_version)
Kuang-che Wu752228c2018-09-05 13:54:22 +080048 intra_revtype = staticmethod(
49 codechange.argtype_intra_rev(cros_util.argtype_cros_version))
Kuang-che Wubfc4a642018-04-19 11:54:08 +080050 help = globals()['__doc__']
51
52 @staticmethod
53 def add_init_arguments(parser):
54 parser.add_argument(
55 '--dut',
56 type=cli.argtype_notempty,
57 metavar='DUT',
Kuang-che Wue4bae0b2018-07-19 12:10:14 +080058 default=configure.get('DUT'),
Kuang-che Wubfc4a642018-04-19 11:54:08 +080059 help='DUT address')
60 parser.add_argument(
61 '--board',
62 metavar='BOARD',
63 default=configure.get('BOARD', ''),
64 help='ChromeOS board name')
65 parser.add_argument(
Kuang-che Wuc95fc152018-06-28 18:13:22 +080066 '--chromeos_root',
67 metavar='CHROMEOS_ROOT',
Kuang-che Wubfc4a642018-04-19 11:54:08 +080068 type=cli.argtype_dir_path,
69 required=True,
Kuang-che Wuc95fc152018-06-28 18:13:22 +080070 default=configure.get('CHROMEOS_ROOT'),
Kuang-che Wubfc4a642018-04-19 11:54:08 +080071 help='ChromeOS tree root')
Kuang-che Wue4bae0b2018-07-19 12:10:14 +080072 parser.add_argument(
Kuang-che Wud8fc9572018-10-03 21:00:41 +080073 '--chromeos_mirror',
Kuang-che Wue4bae0b2018-07-19 12:10:14 +080074 type=cli.argtype_dir_path,
Kuang-che Wud8fc9572018-10-03 21:00:41 +080075 default=configure.get('CHROMEOS_MIRROR', ''),
Kuang-che Wue4bae0b2018-07-19 12:10:14 +080076 help='ChromeOS repo mirror path')
Kuang-che Wubfc4a642018-04-19 11:54:08 +080077
78 @staticmethod
79 def init(opts):
80 if not opts.dut and not opts.board:
Kuang-che Wue121fae2018-11-09 16:18:39 +080081 raise errors.ArgumentError('--dut and --board', 'Neither is specified')
Kuang-che Wubfc4a642018-04-19 11:54:08 +080082
83 if opts.dut:
84 assert cros_util.is_dut(opts.dut)
85 else:
86 logger.info("Tips: unless you don't need to build, otherwise it's "
Kuang-che Wuae6824b2019-08-27 22:20:01 +080087 'recommended to specify --dut in bisector instead of '
88 'switcher and evaluator.')
Kuang-che Wubfc4a642018-04-19 11:54:08 +080089
90 if not opts.board:
91 opts.board = cros_util.query_dut_board(opts.dut)
92
93 if cros_util.is_cros_short_version(opts.old):
94 opts.old = cros_util.version_to_full(opts.board, opts.old)
95 if cros_util.is_cros_short_version(opts.new):
96 opts.new = cros_util.version_to_full(opts.board, opts.new)
97
98 logger.info('Clean up previous result of "mark as stable"')
Kuang-che Wuc95fc152018-06-28 18:13:22 +080099 repo_util.abandon(opts.chromeos_root, 'stabilizing_branch')
Kuang-che Wubfc4a642018-04-19 11:54:08 +0800100
Kuang-che Wuc95fc152018-06-28 18:13:22 +0800101 config = dict(
Kuang-che Wue4bae0b2018-07-19 12:10:14 +0800102 dut=opts.dut,
103 board=opts.board,
104 chromeos_root=opts.chromeos_root,
Kuang-che Wud8fc9572018-10-03 21:00:41 +0800105 chromeos_mirror=opts.chromeos_mirror)
Kuang-che Wubfc4a642018-04-19 11:54:08 +0800106
Kuang-che Wue4bae0b2018-07-19 12:10:14 +0800107 spec_manager = cros_util.ChromeOSSpecManager(config)
Kuang-che Wud8fc9572018-10-03 21:00:41 +0800108 cache = repo_util.RepoMirror(opts.chromeos_mirror)
Kuang-che Wue4bae0b2018-07-19 12:10:14 +0800109
110 # Make sure all repos in between are cached
111 float_specs = spec_manager.collect_float_spec(opts.old, opts.new)
112 for spec in reversed(float_specs):
113 spec_manager.parse_spec(spec)
114 if cache.are_spec_commits_available(spec):
115 continue
116 spec_manager.sync_disk_state(spec.name)
117
118 code_manager = codechange.CodeManager(opts.chromeos_root, spec_manager,
119 cache)
120 revlist = code_manager.build_revlist(opts.old, opts.new)
Kuang-che Wubfc4a642018-04-19 11:54:08 +0800121 return config, revlist
122
123 def __init__(self, config):
124 self.config = config
125
126 def setenv(self, env, rev):
127 if self.config['dut']:
128 env['DUT'] = self.config['dut']
129 if self.config['board']:
130 env['BOARD'] = self.config['board']
Kuang-che Wuc95fc152018-06-28 18:13:22 +0800131 env['CHROMEOS_ROOT'] = self.config['chromeos_root']
Kuang-che Wud8fc9572018-10-03 21:00:41 +0800132 env['CHROMEOS_MIRROR'] = self.config['chromeos_mirror']
Kuang-che Wu99e808f2019-06-26 12:17:32 +0800133 env['CROS_VERSION'] = rev
Kuang-che Wubfc4a642018-04-19 11:54:08 +0800134
Kuang-che Wue80bb872018-11-15 19:45:25 +0800135 def fill_candidate_summary(self, summary, interesting_indexes):
Kuang-che Wu948a79c2019-06-19 19:13:56 +0800136 if 'current_range' in summary:
137 old, new = summary['current_range']
138 old_base, _, _ = codechange.parse_intra_rev(old)
139 _, new_next, _ = codechange.parse_intra_rev(new)
140 old_short = cros_util.version_to_short(old_base)
141 new_short = cros_util.version_to_short(new_next)
142 url_template = 'https://crosland.corp.google.com/log/%s..%s'
143 summary['links'] = [
144 {
145 'name': 'change_list',
146 'url': url_template % (old_short, new_short),
147 },
148 ]
Kuang-che Wubfc4a642018-04-19 11:54:08 +0800149
Kuang-che Wud8fc9572018-10-03 21:00:41 +0800150 cache = repo_util.RepoMirror(self.config['chromeos_mirror'])
Kuang-che Wue80bb872018-11-15 19:45:25 +0800151 spec_manager = cros_util.ChromeOSSpecManager(self.config)
Kuang-che Wue4bae0b2018-07-19 12:10:14 +0800152 code_manager = codechange.CodeManager(self.config['chromeos_root'],
153 spec_manager, cache)
Kuang-che Wue80bb872018-11-15 19:45:25 +0800154 for i in interesting_indexes:
155 rev_info = summary['rev_info'][i]
156 rev_info.update(code_manager.get_rev_detail(rev_info['rev']))
157 for action in rev_info.get('actions', []):
158 generate_action_link(action)
Kuang-che Wubfc4a642018-04-19 11:54:08 +0800159
160
161if __name__ == '__main__':
Kuang-che Wu2526a672019-09-10 16:23:59 +0800162 bisector_cli.BisectorCommandLine(ChromeOSRepoDomain).main()