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