blob: b7c08d3f39400db5a3ee5769687d29f8177ef3aa [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 Wuacb6efd2018-04-25 18:52:58 +080019 ANDROID_ROOT (if available), and
Kuang-che Wu708310b2018-03-28 17:24:34 +080020 DUT (e.g. samus-dut, if available).
21"""
22
23from __future__ import print_function
24import logging
25
26from bisect_kit import android_util
27from bisect_kit import arc_util
28from bisect_kit import cli
29from bisect_kit import configure
30from bisect_kit import core
31from bisect_kit import cros_util
32
33logger = logging.getLogger(__name__)
34
35
36class AndroidBuildIDDomain(core.BisectDomain):
37 """BisectDomain for Android build IDs."""
38 revtype = staticmethod(android_util.argtype_android_build_id)
39 help = globals()['__doc__']
40
41 @staticmethod
42 def add_init_arguments(parser):
43 parser.add_argument(
44 '--branch',
45 metavar='ANDROID_BRANCH',
46 default=configure.get('ANDROID_BRANCH'),
47 help='git branch like "git_mnc-dr-arc-dev"')
48 parser.add_argument(
49 '--flavor',
50 metavar='ANDROID_FLAVOR',
51 default=configure.get('ANDROID_FLAVOR'),
52 help='example: cheets_x86-user')
53 parser.add_argument(
54 '--only_good_build',
55 action='store_true',
56 help='Bisect only good builds. '
57 'This flag is only needed if weird builds blocked bisection')
58
59 # Only used for Android on ChromeOS.
60 parser.add_argument(
61 '--dut',
62 type=cli.argtype_notempty,
63 metavar='DUT',
64 default=configure.get('DUT'),
65 help='For ChromeOS, address of DUT (Device Under Test)')
66 parser.add_argument(
67 '--android_root',
68 type=cli.argtype_dir_path,
69 default=configure.get('ANDROID_ROOT'),
70 help='For ChromeOS, default android tree to search push_to_device.py')
71
72 @staticmethod
73 def init(opts):
74 if opts.dut:
75 assert cros_util.is_dut(opts.dut)
76
77 if not opts.flavor:
78 assert opts.dut
79 opts.flavor = arc_util.query_flavor(opts.dut)
80
81 if not opts.branch:
82 assert opts.dut
83 board = cros_util.query_dut_board(opts.dut)
84 version = cros_util.query_dut_short_version(opts.dut)
85 opts.branch = cros_util.query_android_branch(board, version)
86 assert opts.branch
87
88 config = dict(
89 branch=opts.branch, flavor=opts.flavor, android_root=opts.android_root)
90 if opts.dut:
91 config['dut'] = opts.dut
92
93 revlist = android_util.get_build_ids_between(opts.branch, opts.old,
94 opts.new)
95
96 if opts.only_good_build:
97 revlist = [
98 bid for bid in revlist
99 if android_util.is_good_build(opts.branch, opts.flavor, bid)
100 ]
101
102 return config, revlist
103
104 def __init__(self, config):
105 self.config = config
106
107 def setenv(self, env, rev):
108 env['ANDROID_BRANCH'] = self.config['branch']
109 env['ANDROID_FLAVOR'] = self.config['flavor']
110 env['ANDROID_BUILD_ID'] = rev
111 if self.config.get('dut'):
112 env['DUT'] = self.config['dut']
113 if self.config.get('android_root'):
114 env['ANDROID_ROOT'] = self.config['android_root']
115
116 def view(self, old, new):
117 url_template = (
118 'https://android-build.googleplex.com/'
119 'builds/{new}/branches/{branch}/targets/{flavor}/cls?end={old}')
120 print(url_template.format(
121 old=old,
122 new=new,
123 branch=self.config['branch'],
124 flavor=self.config['flavor']))
125 print('Minus')
126 print(url_template.format(
127 old=old,
128 new=old,
129 branch=self.config['branch'],
130 flavor=self.config['flavor']))
131 print('because this diff viewer is inclusive: '
132 'including changes in %s, which is old' % old)
133
134
135if __name__ == '__main__':
Kuang-che Wudd7f6f02018-06-28 18:19:30 +0800136 cli.BisectorCommandLine(AndroidBuildIDDomain).main()