blob: 9f807aa69239cc7c5b12314102ddcd68bdb62ec4 [file] [log] [blame]
Kuang-che Wuacb6efd2018-04-25 18:52:58 +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 local build commits.
6
7Example:
8 $ ./bisect_android_repo.py init --old rev1 --new rev2 --android_root ~/android
9 $ ./bisect_android_repo.py config switch ./switch_arc_localbuild.py
10 $ ./bisect_android_repo.py config eval ./eval-manually.sh
11 $ ./bisect_android_repo.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_ROOT,
18 DUT (e.g. samus-dut, if available).
19"""
20
21from __future__ import print_function
22import logging
23
24from bisect_kit import android_util
25from bisect_kit import arc_util
26from bisect_kit import cli
27from bisect_kit import configure
28from bisect_kit import core
29from bisect_kit import cros_util
30from bisect_kit import repo_util
31
32logger = logging.getLogger(__name__)
33
34
35def determine_android_build_id(opts, rev):
36 """Determine android build id.
37
38 If `rev` is ChromeOS version, query its corresponding Android build id.
39
40 Args:
41 opts: parse result of argparse
42 rev: Android build id or ChromeOS version
43
44 Returns:
45 Android build id
46 """
47 if cros_util.is_cros_version(rev):
48 assert opts.board, 'need to specify BOARD for cros version'
49 android_build_id = cros_util.query_android_build_id(opts.board, rev)
50 assert android_util.is_android_build_id(android_build_id)
51 logger.info('Converted given CrOS version %s to Android build id %s', rev,
52 android_build_id)
53 rev = android_build_id
54 return rev
55
56
57class AndroidRepoDomain(core.BisectDomain):
58 """BisectDomain for Android code changes."""
59 # Accepts Android build id or ChromeOS version
60 revtype = staticmethod(
61 cli.argtype_multiplexer(cros_util.argtype_cros_version,
62 android_util.argtype_android_build_id))
63 help = globals()['__doc__']
64
65 @staticmethod
66 def add_init_arguments(parser):
67 parser.add_argument(
68 '--dut',
69 type=cli.argtype_notempty,
70 metavar='DUT',
71 default=configure.get('DUT', ''),
72 help='DUT address')
73 parser.add_argument(
74 '--android_root',
75 metavar='ANDROID_ROOT',
76 type=cli.argtype_dir_path,
77 required=True,
78 default=configure.get('ANDROID_ROOT'),
79 help='Android tree root')
80 parser.add_argument(
81 '--branch',
82 metavar='ANDROID_BRANCH',
83 help='branch name like "git_mnc-dr-arc-dev"; '
84 'default is auto detect via DUT')
85 parser.add_argument(
86 '--flavor',
87 metavar='ANDROID_FLAVOR',
88 default=configure.get('ANDROID_FLAVOR'),
89 help='example: cheets_x86-user; default is auto detect via DUT')
90 parser.add_argument(
91 '--board',
92 metavar='BOARD',
93 default=configure.get('BOARD'),
94 help='ChromeOS board name, if ARC++')
95
96 @staticmethod
97 def init(opts):
98 if opts.dut:
99 assert cros_util.is_dut(opts.dut)
100
101 if not opts.flavor:
102 assert opts.dut
103 opts.flavor = arc_util.query_flavor(opts.dut)
104
105 if not opts.board:
106 assert opts.dut
107 opts.board = cros_util.query_dut_board(opts.dut)
108 if not opts.branch:
109 version = cros_util.query_dut_short_version(opts.dut)
110 if not cros_util.is_cros_short_localbuild_version(version):
111 base = '.'.join(version.split('.')[:-1] + ['0'])
112 logger.info('ChromeOS version of DUT (%s) is local build, '
113 'use its base version %s to determine Android branch',
114 version, base)
115 version = base
116 opts.branch = cros_util.query_android_branch(opts.board, version)
117 logger.debug('branch=%s', opts.branch)
118 assert opts.branch
119
120 old = determine_android_build_id(opts, opts.old)
121 new = determine_android_build_id(opts, opts.new)
122
123 config = dict(
124 dut=opts.dut,
125 android_root=opts.android_root,
126 branch=opts.branch,
127 flavor=opts.flavor,
128 old=old,
129 new=new)
130
131 manifest_manager = android_util.AndroidManifestManager(config)
132 dependency_manager = repo_util.DependencyManager(opts.android_root,
133 manifest_manager)
134 revlist = dependency_manager.get_revlist(old, new)
135
136 return config, revlist
137
138 def __init__(self, config):
139 self.config = config
140
141 def setenv(self, env, rev=None):
142 env['DUT'] = self.config['dut']
143 env['ANDROID_ROOT'] = self.config['android_root']
144 env['ANDROID_FLAVOR'] = self.config['flavor']
145 env['ANDROID_BRANCH'] = self.config['branch']
146 env['INTRA_REV'] = rev
147
148 def view(self, old, new):
149 print('old', old)
150 print('new', new)
151
152 manifest_manager = android_util.AndroidManifestManager(self.config)
153 dependency_manager = repo_util.DependencyManager(
154 self.config['android_root'], manifest_manager)
155 dependency_manager.view_rev_diff(old, new)
156
157
158if __name__ == '__main__':
159 cli.BisectorCommandLine(AndroidRepoDomain).main()