blob: 8c2365f7af5b2ab9a4752630b6df142470d60e71 [file] [log] [blame]
Kuang-che Wu708310b2018-03-28 17:24:34 +08001#!/usr/bin/env python2
Kuang-che Wu6e4beca2018-06-27 17:45:02 +08002# -*- coding: utf-8 -*-
Kuang-che Wu708310b2018-03-28 17:24:34 +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"""Android bisector to bisect a range of android build id.
7
8Example:
9 $ ./bisect_android_build_id.py init --old rev1 --new rev2 --dut DUT
10 $ ./bisect_android_build_id.py config switch ./switch_arc_prebuilt.py
11 $ ./bisect_android_build_id.py config eval ./eval-manually.sh
12 $ ./bisect_android_build_id.py run
13
14When running switcher and evaluator, following environment variables
15will be set:
16 ANDROID_BRANCH (e.g. git_mnc-dr-arc-dev),
17 ANDROID_FLAVOR (e.g. cheets_x86-user),
18 ANDROID_BUILD_ID (e.g. 9876543),
Kuang-che Wu708310b2018-03-28 17:24:34 +080019 DUT (e.g. samus-dut, if available).
20"""
21
22from __future__ import print_function
23import logging
24
25from bisect_kit import android_util
26from bisect_kit import arc_util
27from bisect_kit import cli
28from bisect_kit import configure
29from bisect_kit import core
30from bisect_kit import cros_util
31
32logger = logging.getLogger(__name__)
33
34
35class AndroidBuildIDDomain(core.BisectDomain):
36 """BisectDomain for Android build IDs."""
37 revtype = staticmethod(android_util.argtype_android_build_id)
38 help = globals()['__doc__']
39
40 @staticmethod
41 def add_init_arguments(parser):
42 parser.add_argument(
43 '--branch',
44 metavar='ANDROID_BRANCH',
45 default=configure.get('ANDROID_BRANCH'),
46 help='git branch like "git_mnc-dr-arc-dev"')
47 parser.add_argument(
48 '--flavor',
49 metavar='ANDROID_FLAVOR',
50 default=configure.get('ANDROID_FLAVOR'),
51 help='example: cheets_x86-user')
52 parser.add_argument(
53 '--only_good_build',
54 action='store_true',
55 help='Bisect only good builds. '
56 'This flag is only needed if weird builds blocked bisection')
57
58 # Only used for Android on ChromeOS.
59 parser.add_argument(
60 '--dut',
61 type=cli.argtype_notempty,
62 metavar='DUT',
63 default=configure.get('DUT'),
64 help='For ChromeOS, address of DUT (Device Under Test)')
Kuang-che Wu708310b2018-03-28 17:24:34 +080065
66 @staticmethod
67 def init(opts):
68 if opts.dut:
69 assert cros_util.is_dut(opts.dut)
70
71 if not opts.flavor:
72 assert opts.dut
73 opts.flavor = arc_util.query_flavor(opts.dut)
74
75 if not opts.branch:
76 assert opts.dut
77 board = cros_util.query_dut_board(opts.dut)
78 version = cros_util.query_dut_short_version(opts.dut)
79 opts.branch = cros_util.query_android_branch(board, version)
80 assert opts.branch
81
Kuang-che Wu94ef56e2019-01-15 21:17:42 +080082 config = dict(branch=opts.branch, flavor=opts.flavor)
Kuang-che Wu708310b2018-03-28 17:24:34 +080083 if opts.dut:
84 config['dut'] = opts.dut
85
Kuang-che Wu0a902f42019-01-21 18:58:32 +080086 revlist = android_util.get_build_ids_between(opts.branch, opts.flavor,
87 opts.old, opts.new)
Kuang-che Wu708310b2018-03-28 17:24:34 +080088
89 if opts.only_good_build:
90 revlist = [
91 bid for bid in revlist
92 if android_util.is_good_build(opts.branch, opts.flavor, bid)
93 ]
94
95 return config, revlist
96
97 def __init__(self, config):
98 self.config = config
99
100 def setenv(self, env, rev):
101 env['ANDROID_BRANCH'] = self.config['branch']
102 env['ANDROID_FLAVOR'] = self.config['flavor']
103 env['ANDROID_BUILD_ID'] = rev
104 if self.config.get('dut'):
105 env['DUT'] = self.config['dut']
Kuang-che Wu708310b2018-03-28 17:24:34 +0800106
Kuang-che Wue80bb872018-11-15 19:45:25 +0800107 def fill_candidate_summary(self, summary, interesting_indexes):
Kuang-che Wue80bb872018-11-15 19:45:25 +0800108 url_template = ('https://android-build.googleplex.com/'
109 'builds/{new}/branches/%s/targets/%s/cls?end={old}') % (
110 self.config['branch'], self.config['flavor'])
Kuang-che Wu948a79c2019-06-19 19:13:56 +0800111 if 'current_range' in summary:
112 old, new = summary['current_range']
113 summary['links'] = [
114 {
115 'name': 'change_list',
116 'url': url_template.format(old=old, new=new),
117 'note':
118 'Because the diff viewer is inclusive, you need to ignore '
119 'changes from starting version by yourself (b/118564983)',
120 },
121 {
122 'name': 'minus',
123 'url': url_template.format(old=old, new=old),
124 },
125 ]
Kuang-che Wue80bb872018-11-15 19:45:25 +0800126
127 for i in interesting_indexes:
128 if i == 0:
129 continue
130 rev_info = summary['rev_info'][i]
131 rev_info.update({
132 'actions': [{
133 'link':
134 url_template.format(
135 old=summary['rev_info'][i - 1]['rev'],
136 new=rev_info['rev']),
137 }],
138 })
Kuang-che Wu708310b2018-03-28 17:24:34 +0800139
140
141if __name__ == '__main__':
Kuang-che Wudd7f6f02018-06-28 18:19:30 +0800142 cli.BisectorCommandLine(AndroidBuildIDDomain).main()