blob: 3316dec9fe1aefcb723e533766d0f71b0b552a28 [file] [log] [blame]
Kuang-che Wu708310b2018-03-28 17:24:34 +08001#!/usr/bin/env python2
2# Copyright 2018 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"""Android bisector to bisect a range of android build id.
6
7Example:
8 $ ./bisect_android_build_id.py init --old rev1 --new rev2 --dut DUT
9 $ ./bisect_android_build_id.py config switch ./switch_arc_prebuilt.py
10 $ ./bisect_android_build_id.py config eval ./eval-manually.sh
11 $ ./bisect_android_build_id.py run
12
13When running switcher and evaluator, following environment variables
14will be set:
15 ANDROID_BRANCH (e.g. git_mnc-dr-arc-dev),
16 ANDROID_FLAVOR (e.g. cheets_x86-user),
17 ANDROID_BUILD_ID (e.g. 9876543),
18 DEFAULT_ANDROID_ROOT (if available), and
19 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)')
65 parser.add_argument(
66 '--android_root',
67 type=cli.argtype_dir_path,
68 default=configure.get('ANDROID_ROOT'),
69 help='For ChromeOS, default android tree to search push_to_device.py')
70
71 @staticmethod
72 def init(opts):
73 if opts.dut:
74 assert cros_util.is_dut(opts.dut)
75
76 if not opts.flavor:
77 assert opts.dut
78 opts.flavor = arc_util.query_flavor(opts.dut)
79
80 if not opts.branch:
81 assert opts.dut
82 board = cros_util.query_dut_board(opts.dut)
83 version = cros_util.query_dut_short_version(opts.dut)
84 opts.branch = cros_util.query_android_branch(board, version)
85 assert opts.branch
86
87 config = dict(
88 branch=opts.branch, flavor=opts.flavor, android_root=opts.android_root)
89 if opts.dut:
90 config['dut'] = opts.dut
91
92 revlist = android_util.get_build_ids_between(opts.branch, opts.old,
93 opts.new)
94
95 if opts.only_good_build:
96 revlist = [
97 bid for bid in revlist
98 if android_util.is_good_build(opts.branch, opts.flavor, bid)
99 ]
100
101 return config, revlist
102
103 def __init__(self, config):
104 self.config = config
105
106 def setenv(self, env, rev):
107 env['ANDROID_BRANCH'] = self.config['branch']
108 env['ANDROID_FLAVOR'] = self.config['flavor']
109 env['ANDROID_BUILD_ID'] = rev
110 if self.config.get('dut'):
111 env['DUT'] = self.config['dut']
112 if self.config.get('android_root'):
113 env['ANDROID_ROOT'] = self.config['android_root']
114
115 def view(self, old, new):
116 url_template = (
117 'https://android-build.googleplex.com/'
118 'builds/{new}/branches/{branch}/targets/{flavor}/cls?end={old}')
119 print(url_template.format(
120 old=old,
121 new=new,
122 branch=self.config['branch'],
123 flavor=self.config['flavor']))
124 print('Minus')
125 print(url_template.format(
126 old=old,
127 new=old,
128 branch=self.config['branch'],
129 flavor=self.config['flavor']))
130 print('because this diff viewer is inclusive: '
131 'including changes in %s, which is old' % old)
132
133
134if __name__ == '__main__':
135 cli.BisectorCommandLineInterface(AndroidBuildIDDomain).main()