Пример #1
0
 def _bisect_inbounds(self, good_rev, bad_rev):
     self._logger.info("Getting %s builds between %s and %s"
                       % (self.fetch_config.inbound_branch, good_rev,
                          bad_rev))
     handler = InboundHandler(find_fix=self.options.find_fix)
     result = self._do_bisect(handler, good_rev, bad_rev)
     if result == Bisection.FINISHED:
         self._logger.info("Oh noes, no (more) inbound revisions :(")
         handler.print_range()
         if handler.good_revision == handler.bad_revision:
             self._logger.warning(
                 "It seems that you used two changesets that are in"
                 " in the same push. Check the pushlog url."
             )
         elif len(handler.build_range) == 2:
             # range reduced to 2 pushes: 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_inbounds(good_rev, bad_rev)
     elif result == Bisection.USER_EXIT:
         self._print_resume_info(handler)
     else:
         # NO_DATA. With inbounds, this can not happen if changesets
         # are incorrect - so builds are probably too old
         self._logger.info(
             'There are no build artifacts on inbound for these'
             ' changesets (they are probably too old).')
         return 1
     return 0
Пример #2
0
 def _bisect_inbounds(self, good_rev, bad_rev, ensure_good_and_bad=False):
     LOG.info("Getting %s builds between %s and %s" %
              (self.fetch_config.inbound_branch, good_rev, bad_rev))
     handler = InboundHandler(find_fix=self.options.find_fix,
                              ensure_good_and_bad=ensure_good_and_bad)
     result = self._do_bisect(handler, good_rev, bad_rev)
     if result == Bisection.FINISHED:
         LOG.info("Oh noes, no (more) inbound revisions :(")
         handler.print_range()
         if handler.good_revision == handler.bad_revision:
             LOG.warning("It seems that you used two changesets that are in"
                         " in the same push. Check the pushlog url.")
         elif len(handler.build_range) == 2:
             # range reduced to 2 pushes: 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_inbounds(good_rev, bad_rev)
     elif result == Bisection.USER_EXIT:
         self._print_resume_info(handler)
     else:
         # NO_DATA. With inbounds, this can not happen if changesets
         # are incorrect - so builds are probably too old
         LOG.info('There are no build artifacts on inbound for these'
                  ' changesets (they are probably too old).')
         return 1
     return 0
Пример #3
0
 def _bisect_inbounds(self,
                      good_rev,
                      bad_rev,
                      ensure_good_and_bad=False,
                      expand=0):
     LOG.info("Getting %s builds between %s and %s" %
              (self.fetch_config.inbound_branch, good_rev, bad_rev))
     handler = InboundHandler(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 inbound 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_inbounds(good_rev,
                                              bad_rev,
                                              expand=DEFAULT_EXPAND)
             else:
                 # This code is broken, it prints out the message even when
                 # there are multiple bug numbers or commits in the range.
                 # Somebody should fix it before re-enabling it.
                 return 0
                 # print a bug if:
                 # (1) there really is only one bad push (and we're not
                 # just missing the builds for some intermediate builds)
                 # (2) there is only one bug number in that push
                 jp = JsonPushes(handler.build_range[1].repo_name)
                 num_pushes = len(
                     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 inbounds, this can not happen if changesets
         # are incorrect - so builds are probably too old
         LOG.info('There are no build artifacts on inbound for these'
                  ' changesets (they are probably too old).')
         return 1
     return 0
Пример #4
0
 def _bisect_inbounds(self, good_rev, bad_rev, ensure_good_and_bad=False,
                      expand=0):
     LOG.info("Getting %s builds between %s and %s"
              % (self.fetch_config.inbound_branch, good_rev, bad_rev))
     handler = InboundHandler(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 inbound 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_inbounds(good_rev, bad_rev,
                                              expand=DEFAULT_EXPAND)
             else:
                 # This code is broken, it prints out the message even when
                 # there are multiple bug numbers or commits in the range.
                 # Somebody should fix it before re-enabling it.
                 return 0
                 # print a bug if:
                 # (1) there really is only one bad push (and we're not
                 # just missing the builds for some intermediate builds)
                 # (2) there is only one bug number in that push
                 jp = JsonPushes(handler.build_range[1].repo_name)
                 num_pushes = len(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 inbounds, this can not happen if changesets
         # are incorrect - so builds are probably too old
         LOG.info(
             'There are no build artifacts on inbound for these'
             ' changesets (they are probably too old).')
         return 1
     return 0
Пример #5
0
    def bisect_inbound(self, good_rev, bad_rev):
        # Remember, InboundHandler is just a changeset based bisector. It will
        # still potentially bisect m-c first.
        handler = InboundHandler()
        result = self.bisector.bisect(handler, good_rev, bad_rev, expand=0)
        if result == Bisection.FINISHED:
            print "No more m-c revisions :("
            handler.print_range()
            # Try switching over to the integration branch.
            if len(handler.build_range) == 2:
                result = handler.handle_merge()
                if result:
                    branch, good_rev, bad_rev = result
                    self.fetch_config.set_repo(branch)
                    return self.bisect_inbound(good_rev, bad_rev)

        return (handler.good_revision, handler.bad_revision)
Пример #6
0
 def _bisect_inbounds(self, good_rev, bad_rev, ensure_good_and_bad=False,
                      expand=0):
     LOG.info("Getting %s builds between %s and %s"
              % (self.fetch_config.inbound_branch, good_rev, bad_rev))
     handler = InboundHandler(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("Oh noes, no (more) inbound revisions :(")
         handler.print_range()
         if handler.good_revision == handler.bad_revision:
             LOG.warning(
                 "It seems that you used two changesets that are in"
                 " in the same push. Check the pushlog url."
             )
         elif len(handler.build_range) == 2:
             # range reduced to 2 pushes: 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_inbounds(good_rev, bad_rev,
                                              expand=DEFAULT_EXPAND)
             else:
                 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 inbounds, this can not happen if changesets
         # are incorrect - so builds are probably too old
         LOG.info(
             'There are no build artifacts on inbound for these'
             ' changesets (they are probably too old).')
         return 1
     return 0
Пример #7
0
 def bisect_further(self):
     assert self.bisection
     self.started.emit()
     handler = self.bisection.handler
     try:
         nhandler = InboundHandler(find_fix=self.bisection.handler.find_fix)
         Bisector.bisect(self, nhandler, handler.good_revision,
                         handler.bad_revision)
     except MozRegressionError:
         self._finish_on_exception(None)
Пример #8
0
 def _bisect_inbounds(self,
                      good_rev,
                      bad_rev,
                      ensure_good_and_bad=False,
                      expand=0):
     LOG.info("Getting %s builds between %s and %s" %
              (self.fetch_config.inbound_branch, good_rev, bad_rev))
     handler = InboundHandler(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("Oh noes, no (more) inbound revisions :(")
         handler.print_range()
         if handler.good_revision == handler.bad_revision:
             LOG.warning("It seems that you used two changesets that are in"
                         " in the same push. Check the pushlog url.")
         elif len(handler.build_range) == 2:
             # range reduced to 2 pushes: 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_inbounds(good_rev,
                                              bad_rev,
                                              expand=DEFAULT_EXPAND)
             else:
                 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 inbounds, this can not happen if changesets
         # are incorrect - so builds are probably too old
         LOG.info('There are no build artifacts on inbound for these'
                  ' changesets (they are probably too old).')
         return 1
     return 0
Пример #9
0
class TestInboundHandler(unittest.TestCase):
    def setUp(self):
        self.handler = InboundHandler()

    @patch('mozregression.bisector.LOG')
    def test_print_progress(self, logger):
        log = []
        logger.info = log.append
        self.handler.set_build_range([
            Mock(short_changeset='12'),
            Mock(short_changeset='123'),
            Mock(short_changeset='1234'),
            Mock(short_changeset='12345'),
        ])
        new_data = [
            Mock(short_changeset='1234'),
            Mock(short_changeset='12345')
        ]

        self.handler._print_progress(new_data)
        self.assertIn('from [12, 12345] (4 revisions)', log[0])
        self.assertIn('to [1234, 12345] (2 revisions)', log[0])
        self.assertIn('1 steps left', log[0])

    @patch('mozregression.bisector.LOG')
    def test_user_exit(self, logger):
        log = []
        logger.info = log.append
        self.handler.good_revision = '3'
        self.handler.bad_revision = '1'
        self.handler.user_exit(0)
        self.assertEqual('Newest known good inbound revision: 3', log[0])
        self.assertEqual('Oldest known bad inbound revision: 1', log[1])
Пример #10
0
class TestInboundHandler(unittest.TestCase):
    def setUp(self):
        self.handler = InboundHandler()

    @patch('mozregression.bisector.LOG')
    def test_print_progress(self, logger):
        log = []
        logger.info = log.append
        self.handler.set_build_range([
            Mock(short_changeset='12'),
            Mock(short_changeset='123'),
            Mock(short_changeset='1234'),
            Mock(short_changeset='12345'),
        ])
        new_data = [
            Mock(short_changeset='1234'),
            Mock(short_changeset='12345')
        ]

        self.handler._print_progress(new_data)
        self.assertIn('from [12, 12345] (4 builds)', log[0])
        self.assertIn('to [1234, 12345] (2 builds)', log[0])
        self.assertIn('1 steps left', log[0])

    @patch('mozregression.bisector.LOG')
    def test_user_exit(self, logger):
        log = []
        logger.info = log.append
        self.handler.good_revision = '3'
        self.handler.bad_revision = '1'
        self.handler.user_exit(0)
        self.assertEqual('Newest known good inbound revision: 3', log[0])
        self.assertEqual('Oldest known bad inbound revision: 1', log[1])
Пример #11
0
class TestInboundHandler(unittest.TestCase):
    def setUp(self):
        self.handler = InboundHandler()

    @patch("mozregression.bisector.LOG")
    def test_print_progress(self, logger):
        log = []
        logger.info = log.append
        self.handler.set_build_range(
            [
                Mock(short_changeset="12"),
                Mock(short_changeset="123"),
                Mock(short_changeset="1234"),
                Mock(short_changeset="12345"),
            ]
        )
        new_data = [Mock(short_changeset="1234"), Mock(short_changeset="12345")]

        self.handler._print_progress(new_data)
        self.assertIn("from [12, 12345] (4 revisions)", log[0])
        self.assertIn("to [1234, 12345] (2 revisions)", log[0])
        self.assertIn("1 steps left", log[0])

    @patch("mozregression.bisector.LOG")
    def test_user_exit(self, logger):
        log = []
        logger.info = log.append
        self.handler.good_revision = "3"
        self.handler.bad_revision = "1"
        self.handler.user_exit(0)
        self.assertEqual("Newest known good inbound revision: 3", log[0])
        self.assertEqual("Oldest known bad inbound revision: 1", log[1])
Пример #12
0
 def nightlies_to_inbound(self):
     """
     Call this when going from nightlies to inbound.
     """
     assert self.bisection
     self.started.emit()
     try:
         # first we need to find the changesets
         first, last = self.bisection.handler.find_inbound_changesets()
         # create the inbound handler, and go with that
         handler = InboundHandler(find_fix=self.bisection.handler.find_fix)
         Bisector.bisect(self, handler, first, last)
     except MozRegressionError:
         self._finish_on_exception(None)
Пример #13
0
class TestInboundHandler(unittest.TestCase):
    def setUp(self):
        self.handler = InboundHandler()

    def test_build_infos(self):
        fetch_config = create_config('firefox', 'linux', 64)
        fetch_config.set_inbound_branch('my-branch')

        self.handler.set_build_data([{'changeset': '1', 'repository': 'my'}])
        result = self.handler.build_infos(0, fetch_config)
        self.assertEqual(result, {
            'changeset': '1',
            'repository': 'my',
            'build_type': 'inbound',
            'app_name': 'firefox',
            'repo': 'my-branch',
        })

    def test_print_progress(self):
        log = []
        self.handler._logger = Mock(info=log.append)
        self.handler.set_build_data([
            {'revision': '12'},
            {'revision': '123'},
            {'revision': '1234'},
            {'revision': '12345'},
        ])
        new_data = [{'revision': '1234'}, {'revision': '12345'}]

        self.handler._print_progress(new_data)
        self.assertIn('from [12, 12345] (4 revisions)', log[0])
        self.assertIn('to [1234, 12345] (2 revisions)', log[0])
        self.assertIn('1 steps left', log[0])

    def test_user_exit(self):
        log = []
        self.handler._logger = Mock(info=log.append)
        self.handler.good_revision = '3'
        self.handler.bad_revision = '1'
        self.handler.user_exit(0)
        self.assertEqual('Newest known good inbound revision: 3', log[0])
        self.assertEqual('Oldest known bad inbound revision: 1', log[1])
Пример #14
0
 def bisect_further(self):
     assert self.bisection
     self.started.emit()
     handler = self.bisection.handler
     try:
         nhandler = InboundHandler(find_fix=self.bisection.handler.find_fix)
         Bisector.bisect(self,
                         nhandler,
                         handler.good_revision,
                         handler.bad_revision,
                         expand=DEFAULT_EXPAND,
                         interrupt=self.should_stop.is_set)
     except MozRegressionError:
         self._finish_on_exception(None)
     except StopIteration:
         self.finished.emit(None, Bisection.USER_EXIT)
Пример #15
0
    def bisect(self, fetch_config, options):
        self.stop()

        # global preferences
        global_prefs = get_prefs()
        # apply the global prefs now
        apply_prefs(global_prefs)

        self.bisector = GuiBisector(fetch_config,
                                    persist=global_prefs['persist'])
        # create a QThread, and move self.bisector in it. This will
        # allow to the self.bisector slots (connected after the move)
        # to be automatically called in the thread.
        self.thread = QThread()
        self.bisector.moveToThread(self.thread)
        self.bisector.download_manager.download_progress.connect(
            self.show_dl_progress)
        self.bisector.test_runner.evaluate_started.connect(self.evaluate)
        self.bisector.finished.connect(self.bisection_finished)
        self.bisector_created.emit(self.bisector)
        if options['bisect_type'] == 'nightlies':
            handler = NightlyHandler(find_fix=options['find_fix'])
            good = options['good_date']
            bad = options['bad_date']
        else:
            handler = InboundHandler(find_fix=options['find_fix'])
            good = options['good_changeset']
            bad = options['bad_changeset']

        # options for the app launcher
        launcher_kwargs = {}
        for name in ('profile', 'preferences'):
            if name in options:
                value = options[name]
                if value:
                    launcher_kwargs[name] = value
        self.bisector.test_runner.launcher_kwargs = launcher_kwargs

        self.thread.start()
        self.bisector._bisect_args = (handler, good, bad)
        # this will be called in the worker thread.
        QTimer.singleShot(0, self.bisector.bisect)

        self.running_state_changed.emit(True)
Пример #16
0
    def init_worker(self, fetch_config, options):
        AbstractBuildRunner.init_worker(self, fetch_config, options)

        self.worker.test_runner.evaluate_started.connect(self.evaluate)
        self.worker.finished.connect(self.bisection_finished)
        self.worker.handle_merge.connect(self.handle_merge)
        self.worker.choose_next_build.connect(self.choose_next_build)

        good, bad = options.pop('good'), options.pop('bad')
        if is_date_or_datetime(good) and is_date_or_datetime(bad) \
                and not fetch_config.should_use_taskcluster():
            handler = NightlyHandler(find_fix=options['find_fix'])
        else:
            handler = InboundHandler(find_fix=options['find_fix'])

        self.worker._bisect_args = (handler, good, bad)
        self.worker.download_in_background = \
            self.global_prefs['background_downloads']
        return self.worker.bisect
Пример #17
0
 def setUp(self):
     self.handler = InboundHandler()
Пример #18
0
 def setUp(self):
     self.handler = InboundHandler()