blob: d3715ab9bf8200b624a084c06714716f4b7f073c [file] [log] [blame]
#!/usr/bin/env python3
# Copyright 2018 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Android bisector to bisect a range of android build id.
Example:
$ ./bisect_android_build_id.py init --old rev1 --new rev2 --branch BRANCH \\
--flavor FLAVOR --dut DUT
$ ./bisect_android_build_id.py config switch ./switch_arc_prebuilt.py
$ ./bisect_android_build_id.py config eval ./eval-manually.sh
$ ./bisect_android_build_id.py run
When running switcher and evaluator, following environment variables
will be set:
ANDROID_BRANCH (e.g. git_mnc-dr-arc-dev),
ANDROID_FLAVOR (e.g. cheets_x86-user),
ANDROID_BUILD_ID (e.g. 9876543),
DUT (e.g. samus-dut, if available).
"""
import logging
import os
from bisect_kit import android_util
from bisect_kit import bisector_cli
from bisect_kit import cli
from bisect_kit import core
logger = logging.getLogger(__name__)
diff_url_template = (
'https://android-build.googleplex.com/'
'builds/{new}/branches/{branch}/targets/{flavor}/cls?end={old}'
)
class AndroidBuildIDDomain(core.BisectDomain):
"""BisectDomain for Android build IDs."""
revtype = staticmethod(android_util.argtype_android_build_id)
help = globals()['__doc__']
@staticmethod
def add_init_arguments(parser):
parser.add_argument(
'--branch',
type=cli.argtype_notempty,
metavar='ANDROID_BRANCH',
default=os.environ.get('ANDROID_BRANCH', ''),
help='git branch like "git_mnc-dr-arc-dev"',
)
parser.add_argument(
'--flavor',
type=cli.argtype_notempty,
metavar='ANDROID_FLAVOR',
default=os.environ.get('ANDROID_FLAVOR', ''),
help='example: cheets_x86-user',
)
parser.add_argument(
'--only-good-build',
action='store_true',
help='Bisect only good builds. '
'This flag is only needed if weird builds blocked bisection',
)
# Only used for Android on ChromeOS.
parser.add_argument(
'--dut',
type=cli.argtype_notempty,
metavar='DUT',
default=os.environ.get('DUT'),
help='For ChromeOS, address of DUT (Device Under Test)',
)
@staticmethod
def init(opts):
config = dict(branch=opts.branch, flavor=opts.flavor)
if opts.dut:
config['dut'] = opts.dut
revlist = android_util.get_build_ids_between(
opts.branch, opts.flavor, opts.old, opts.new
)
if opts.only_good_build:
revlist = [
bid
for bid in revlist
if android_util.is_good_build(opts.branch, opts.flavor, bid)
]
details = {}
for i in range(1, len(revlist)):
url = diff_url_template.format(
branch=opts.branch,
flavor=opts.flavor,
old=revlist[i - 1],
new=revlist[i],
)
details[revlist[i]] = {'actions': [{'link': url}]}
return config, {'revlist': revlist, 'details': details}
def __init__(self, config):
self.config = config
def setenv(self, env, rev):
env['ANDROID_BRANCH'] = self.config['branch']
env['ANDROID_FLAVOR'] = self.config['flavor']
env['ANDROID_BUILD_ID'] = rev
def fill_candidate_summary(self, summary):
if 'current_range' in summary:
old, new = summary['current_range']
url = diff_url_template.format(
branch=self.config['branch'],
flavor=self.config['flavor'],
old=old,
new=new,
)
summary['links'] = [dict(name='change_list', url=url)]
if __name__ == '__main__':
bisector_cli.BisectorCommandLine(AndroidBuildIDDomain).main()