blob: 84630c96d8c7befacba3dcdd7bf7f1679681f379 [file] [log] [blame]
Kuang-che Wu875c89a2020-01-08 14:30:55 +08001#!/usr/bin/env python3
Kuang-che Wu6e4beca2018-06-27 17:45:02 +08002# -*- coding: utf-8 -*-
Kuang-che Wu2ea804f2017-11-28 17:11:41 +08003# Copyright 2017 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"""ChromeOS bisector to bisect a range of chromeos versions.
7
8Example:
9 $ ./bisect_cros_version.py init --old rev1 --new rev2 --dut DUT
10 $ ./bisect_cros_version.py config switch ./switch_cros_prebuilt.py
11 $ ./bisect_cros_version.py config eval ./eval-manually.sh
12 $ ./bisect_cros_version.py run
13
14When running switcher and evaluator, following environment variables
15will be set:
16 BOARD (e.g. samus),
17 CROS_FULL_VERSION (e.g. R62-9876.0.0),
18 CROS_SHORT_VERSION (e.g. 9876.0.0),
19 CROS_VERSION (e.g. R62-9876.0.0).
20 DUT (e.g. samus-dut), and
21 MILESTONE (e.g. 62).
22"""
23
24from __future__ import print_function
Kuang-che Wu2ea804f2017-11-28 17:11:41 +080025import logging
26
Kuang-che Wu2526a672019-09-10 16:23:59 +080027from bisect_kit import bisector_cli
Kuang-che Wu2ea804f2017-11-28 17:11:41 +080028from bisect_kit import cli
29from bisect_kit import configure
30from bisect_kit import core
31from bisect_kit import cros_util
Kuang-che Wue121fae2018-11-09 16:18:39 +080032from bisect_kit import errors
Kuang-che Wu2ea804f2017-11-28 17:11:41 +080033
34logger = logging.getLogger(__name__)
35
36
Zheng-Jie Chang127c3302019-09-10 17:17:04 +080037def get_revlist(board, old, new, use_snapshot=False):
Kuang-che Wu2ea804f2017-11-28 17:11:41 +080038 logger.info('get_revlist %s %s %s', board, old, new)
Zheng-Jie Chang127c3302019-09-10 17:17:04 +080039 logger.info('use_snapshot: %s', use_snapshot)
40 full_versions = cros_util.list_chromeos_prebuilt_versions(
41 board, old, new, use_snapshot=use_snapshot)
Kuang-che Wuc89f2a22019-11-26 15:30:50 +080042 short_versions = [cros_util.version_to_short(v) for v in full_versions]
Kuang-che Wu2ea804f2017-11-28 17:11:41 +080043
Zheng-Jie Changfaed6aa2019-12-17 16:50:51 +080044 if cros_util.is_cros_snapshot_version(old):
45 old_idx = full_versions.index(old)
46 else:
47 old_idx = short_versions.index(cros_util.version_to_short(old))
48 if cros_util.is_cros_snapshot_version(new):
49 new_idx = full_versions.index(new)
50 else:
51 new_idx = short_versions.index(cros_util.version_to_short(new))
Kuang-che Wu575dc442019-03-05 10:30:55 +080052 return full_versions[old_idx], full_versions[new_idx], full_versions
Kuang-che Wu2ea804f2017-11-28 17:11:41 +080053
54
55class ChromeOSVersionDomain(core.BisectDomain):
Kuang-che Wu68db08a2018-03-30 11:50:34 +080056 """BisectDomain for chromeos versions."""
Kuang-che Wu2ea804f2017-11-28 17:11:41 +080057 revtype = staticmethod(cros_util.argtype_cros_version)
58 help = globals()['__doc__']
59
60 @staticmethod
61 def add_init_arguments(parser):
62 parser.add_argument(
63 '--dut',
64 type=cli.argtype_notempty,
65 metavar='DUT',
66 default=configure.get('DUT'),
67 help='Address of DUT (Device Under Test). Either --dut or '
68 '--board need to be specified')
69 parser.add_argument(
70 '--board',
71 metavar='BOARD',
72 default=configure.get('BOARD'),
73 help='ChromeOS board name. Either --dut or --board need '
74 'to be specified')
Zheng-Jie Chang127c3302019-09-10 17:17:04 +080075 parser.add_argument(
Zheng-Jie Chang3f576ad2019-12-06 13:17:44 +080076 '--disable_snapshot',
Zheng-Jie Chang127c3302019-09-10 17:17:04 +080077 action='store_true',
Zheng-Jie Chang3f576ad2019-12-06 13:17:44 +080078 help='Disable snapshot for bisect chromeos prebuilt')
Kuang-che Wu2ea804f2017-11-28 17:11:41 +080079
80 @staticmethod
81 def init(opts):
82 if not opts.dut and not opts.board:
Kuang-che Wue121fae2018-11-09 16:18:39 +080083 raise errors.ArgumentError('--dut and --board', 'Neither is specified')
Kuang-che Wu430c5282021-01-27 21:10:25 +080084 if not cros_util.is_ancestor_version(opts.old, opts.new):
85 raise errors.ArgumentError(
86 '--old and --new', '%s is not ancestor of %s' % (opts.old, opts.new))
Kuang-che Wu2ea804f2017-11-28 17:11:41 +080087 if opts.dut:
88 assert cros_util.is_dut(opts.dut)
89 if not opts.board:
90 opts.board = cros_util.query_dut_board(opts.dut)
Kuang-che Wue1808402020-01-06 20:27:45 +080091 if not cros_util.has_test_image(opts.board, opts.old):
92 raise errors.ArgumentError(
93 '--old', '%s has no image for %s' % (opts.board, opts.old))
94 if not cros_util.has_test_image(opts.board, opts.new):
95 raise errors.ArgumentError(
96 '--new', '%s has no image for %s' % (opts.board, opts.new))
Kuang-che Wu2ea804f2017-11-28 17:11:41 +080097
Zheng-Jie Chang127c3302019-09-10 17:17:04 +080098 old, new, revlist = get_revlist(
Zheng-Jie Chang3f576ad2019-12-06 13:17:44 +080099 opts.board, opts.old, opts.new, use_snapshot=not opts.disable_snapshot)
Kuang-che Wu2ea804f2017-11-28 17:11:41 +0800100 config = dict(dut=opts.dut, board=opts.board, old=old, new=new)
Kuang-che Wu13acc7b2020-06-15 10:45:35 +0800101
102 details = {}
103 for i in range(1, len(revlist)):
104 link = cros_util.get_crosland_link(revlist[i - 1], revlist[i])
105 details[revlist[i]] = {'actions': [{'link': link}]}
106
Zheng-Jie Chang03a55e42020-06-16 07:29:19 +0800107 return config, {'revlist': revlist, 'details': details}
Kuang-che Wu2ea804f2017-11-28 17:11:41 +0800108
109 def __init__(self, config):
110 self.config = config
111
112 def setenv(self, env, rev):
113 if self.config['dut']:
114 env['DUT'] = self.config['dut']
115 env['BOARD'] = self.config['board']
116
Zheng-Jie Chang127c3302019-09-10 17:17:04 +0800117 assert cros_util.is_cros_full_version(
118 rev) or cros_util.is_cros_snapshot_version(rev)
119 if cros_util.is_cros_snapshot_version(rev):
120 milestone, short_version, _ = cros_util.snapshot_version_split(rev)
121 else:
122 milestone, short_version = cros_util.version_split(rev)
123
Kuang-che Wu2ea804f2017-11-28 17:11:41 +0800124 env['MILESTONE'] = milestone
125 env['CROS_SHORT_VERSION'] = short_version
Kuang-che Wu575dc442019-03-05 10:30:55 +0800126 env['CROS_FULL_VERSION'] = rev
127 env['CROS_VERSION'] = rev
Kuang-che Wu2ea804f2017-11-28 17:11:41 +0800128
Kuang-che Wu13acc7b2020-06-15 10:45:35 +0800129 def fill_candidate_summary(self, summary):
Kuang-che Wu948a79c2019-06-19 19:13:56 +0800130 if 'current_range' in summary:
131 old, new = summary['current_range']
Zheng-Jie Chang8f94da62020-02-05 14:22:34 +0800132 summary['links'] = [
133 {
134 'name': 'change_list',
Zheng-Jie Chang5f9ae4e2020-02-07 14:26:06 +0800135 'url': cros_util.get_crosland_link(old, new),
Zheng-Jie Chang8f94da62020-02-05 14:22:34 +0800136 },
137 ]
Kuang-che Wue80bb872018-11-15 19:45:25 +0800138
Kuang-che Wu2ea804f2017-11-28 17:11:41 +0800139
140if __name__ == '__main__':
Kuang-che Wu2526a672019-09-10 16:23:59 +0800141 bisector_cli.BisectorCommandLine(ChromeOSVersionDomain).main()