Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
[
# first call
call(MyBuildData([1, 2, 3])),
# we asked for a retry
call(MyBuildData([1, 2, 3])),
# we skipped one
call(MyBuildData([1, 3])),
]
)
# ensure that we called the handler's methods
self.handler.initialize.assert_called_with()
self.handler.build_retry.assert_called_with(1)
self.handler.build_skip.assert_called_with(1)
self.assertTrue(self.handler.build_range.ensure_limits_called)
# bisection is finished
self.assertEqual(test_result["result"], Bisection.FINISHED)
def test__bisect_no_data(self):
build_range = MyBuildData()
result = self.bisector._bisect(self.handler, build_range)
# test that handler methods where called
self.handler.set_build_range.assert_called_with(build_range)
self.handler.no_data.assert_called_once_with()
# check return code
self.assertEqual(result, Bisection.NO_DATA)
def test_app_bisect_nightlies_no_data(create_app):
app = create_app(["-g=2015-06-01", "-b=2015-06-02"])
app.bisector.bisect = Mock(return_value=Bisection.NO_DATA)
assert app.bisect_nightlies() == 1
assert create_app.find_in_log("Unable to get valid builds within the given range.", False)
self.choose_next_build.emit()
return
if self._next_build_index is not None:
# here user asked for specific build (eg from choose_next_build)
self.mid = self._next_build_index
# this will download build infos if required
if self.bisection.build_range[self.mid] is False:
# in case no build info is found, ask to choose again
self.choose_next_build.emit()
return
self._next_build_index = None
self.step_started.emit(self.bisection)
result = self.bisection.init_handler(self.mid)
if result != Bisection.RUNNING:
self.finished.emit(self.bisection, result)
else:
self.build_infos = self.bisection.handler.build_range[self.mid]
(
found,
self.mid,
self.build_infos,
self._persist_files,
) = self.bisection._find_approx_build(self.mid, self.build_infos)
if not found:
self.download_manager.focus_download(self.build_infos)
self.step_build_found.emit(self.bisection, self.build_infos)
if found:
# to continue the bisection, act as if it was downloaded
self._build_dl_finished(None, self.build_infos.build_file)
def _finish_on_exception(self, bisection):
self.error = sys.exc_info()
self.finished.emit(bisection, Bisection.EXCEPTION)
def _bisect(self, handler, build_range):
self.bisection = Bisection(
handler,
build_range,
self.download_manager,
self.test_runner,
dl_in_background=False,
approx_chooser=self.approx_chooser,
)
self._bisect_next()
def bisect_nightlies(self):
good_date, bad_date = self.options.good, self.options.bad
handler = NightlyHandler(
find_fix=self.options.find_fix,
ensure_good_and_bad=self.options.mode != "no-first-check",
)
result = self._do_bisect(handler, good_date, bad_date)
if result == Bisection.FINISHED:
LOG.info("Got as far as we can go bisecting nightlies...")
handler.print_range()
if self.fetch_config.can_go_integration():
LOG.info("Switching bisection method to taskcluster")
self.fetch_config.set_repo(self.fetch_config.get_nightly_repo(handler.bad_date))
return self._bisect_integration(
handler.good_revision, handler.bad_revision, expand=DEFAULT_EXPAND
)
elif result == Bisection.USER_EXIT:
self._print_resume_info(handler)
else:
# NO_DATA
LOG.info(
"Unable to get valid builds within the given"
" range. You should try to launch mozregression"
" again with a larger date range."
def _bisect(self, handler, build_range):
"""
Starts a bisection for a :class:`mozregression.build_range.BuildData`.
"""
bisection = Bisection(
handler,
build_range,
self.download_manager,
self.test_runner,
dl_in_background=self.dl_in_background,
approx_chooser=self.approx_chooser,
)
previous_verdict = None
while True:
index = bisection.search_mid_point()
result = bisection.init_handler(index)
if result != bisection.RUNNING:
return result
if previous_verdict is None and handler.ensure_good_and_bad:
def _bisect_integration(self, good_rev, bad_rev, ensure_good_and_bad=False, expand=0):
LOG.info(
"Getting %s builds between %s and %s"
% (self.fetch_config.integration_branch, good_rev, bad_rev)
)
handler = IntegrationHandler(
find_fix=self.options.find_fix, ensure_good_and_bad=ensure_good_and_bad
)
result = self._do_bisect(handler, good_rev, bad_rev, expand=expand)
if result == Bisection.FINISHED:
LOG.info("No more integration revisions, bisection finished.")
handler.print_range()
if handler.good_revision == handler.bad_revision:
LOG.warning(
"It seems that you used two changesets that are in"
" the same push. Check the pushlog url."
)
elif len(handler.build_range) == 2:
# range reduced to 2 pushes (at least ones with builds):
# one good, one bad.
result = handler.handle_merge()
if result:
branch, good_rev, bad_rev = result
self.fetch_config.set_repo(branch)
return self._bisect_integration(good_rev, bad_rev, expand=DEFAULT_EXPAND)
else:
jp.pushes_within_changes(
handler.build_range[0].changeset, handler.build_range[1].changeset,
)
)
if num_pushes == 2:
bugids = find_bugids_in_push(
handler.build_range[1].repo_name, handler.build_range[1].changeset,
)
if len(bugids) == 1:
word = "fix" if handler.find_fix else "regression"
LOG.info(
"Looks like the following bug has the "
" changes which introduced the"
" {}:\n{}".format(word, bug_url(bugids[0]))
)
elif result == Bisection.USER_EXIT:
self._print_resume_info(handler)
else:
# NO_DATA. With integration branches, this can not happen if changesets
# are incorrect - so builds are probably too old
LOG.info(
"There are no build artifacts for these changesets (they are probably too old)."
)
return 1
return 0