bisect-kit: bisector 'run --force'
This CL changed the behavior of bisector 'run' subcommand slightly.
Original behavior:
If bisect failed (verify failed or skip too many times), the result
is not saved and terminated.
So users can resume by just calling 'run' directly. However, there is
a problem when integrated with diagnose_cros_autotest.py. Assume the
culprit is inside chromeos tree, so android bisector and chrome
bisector would fail as expected. When diagnose_cros_autotest.py
resume, it will waste time to run android and chrome bisector again.
New behavior:
Bisect result will always be saved even the result is failure. If
users want to resume failed session, they can do 'run --force', which
switch and eval at least one more time even if last run failed.
BUG=None
TEST=When bisector failed, run again to resume.
Change-Id: I91036c8e22b4c8c037d0e0fb702c709762b28777
Reviewed-on: https://chromium-review.googlesource.com/1304233
Commit-Ready: Kuang-che Wu <kcwu@chromium.org>
Tested-by: Kuang-che Wu <kcwu@chromium.org>
Reviewed-by: Chung-yih Wang <cywang@chromium.org>
diff --git a/bisect_kit/cli.py b/bisect_kit/cli.py
index ef399ae..4a369c1 100644
--- a/bisect_kit/cli.py
+++ b/bisect_kit/cli.py
@@ -396,7 +396,7 @@
return 'eval', status, values
- def _next_idx_iter(self, opts):
+ def _next_idx_iter(self, opts, force):
if opts.revs:
for rev in opts.revs:
idx = self.states.rev2idx(rev)
@@ -405,11 +405,12 @@
if opts.once:
break
else:
- while not self.strategy.is_done():
+ while force or not self.strategy.is_done():
idx = self.strategy.next_idx()
rev = self.states.idx2rev(idx)
logger.info('try idx=%d rev=%s', idx, rev)
yield idx, rev
+ force = False
if opts.once:
break
@@ -430,22 +431,23 @@
self.strategy.rebuild()
prev_rev = None
- for idx, rev in self._next_idx_iter(opts):
- # Bail out if bisection range is unlikely true in order to prevent
- # wasting time. This is necessary because some configurations (say,
- # confidence) may be changed before cmd_run() and thus the bisection
- # range becomes not acceptable.
- self.strategy.check_verification_range()
+ force = opts.force
+ for idx, rev in self._next_idx_iter(opts, force):
+ if not force:
+ # Bail out if bisection range is unlikely true in order to prevent
+ # wasting time. This is necessary because some configurations (say,
+ # confidence) may be changed before cmd_run() and thus the bisection
+ # range becomes not acceptable.
+ self.strategy.check_verification_range()
step, status, values = self._switch_and_eval(rev, prev_rev=prev_rev)
logger.info('rev=%s => status %s', rev, status)
+ force = False
self._add_status(rev, status, values=values)
- # Bail out if bisection range is unlikely true. Don't save.
- # The last failing results are likely something wrong in bisection setup,
- # bisector, and/or evaluator. The benefits of not saving the last failing
- # results, are that users can just resume bisector directly without needs
- # of erasing bad results after they fixed the problems.
+ self.states.save()
+
+ # Bail out if bisection range is unlikely true.
self.strategy.check_verification_range()
if status == 'skip':
@@ -455,8 +457,6 @@
current_state['old'] + current_state['new'] + 1) * 5:
raise core.ExecutionFatalError('too much "skip" for rev=%r' % rev)
- self.states.save()
-
self.strategy.show_summary()
if step == 'switch' and status == 'skip':
@@ -731,6 +731,10 @@
parser_run.add_argument(
'-1', '--once', action='store_true', help='Only run one step')
parser_run.add_argument(
+ '--force',
+ action='store_true',
+ help="Run at least once even it's already done")
+ parser_run.add_argument(
'revs',
nargs='*',
type=self.domain_cls.intra_revtype,