예제 #1
0
    def _set_fetch_config(self, index):
        app_name = str(self.ui.app_combo.currentText())
        bits = int(self.ui.bits_combo.currentText())

        self.fetch_config = create_config(app_name, mozinfo.os, bits,
                                          mozinfo.processor)

        self.build_type_model = QStringListModel(
            self.fetch_config.available_build_types())
        self.ui.build_type.setModel(self.build_type_model)

        if not self.fetch_config.available_bits():
            self.ui.bits_combo.hide()
            self.ui.label_4.hide()
        else:
            self.ui.bits_combo.show()
            self.ui.label_4.show()

        # URL doesn't make sense for Thunderbird
        if app_name == "thunderbird":
            self.ui.url.hide()
            self.ui.url_label.hide()
        else:
            self.ui.url.show()
            self.ui.url_label.show()
예제 #2
0
    def setUp(self):
        good_date = datetime.date(2014, 11, 10)
        bad_date = datetime.date(2014, 11, 20)
        fetch_config = fetch_configs.create_config('firefox', 'linux', 64)

        self.build_data = build_data.NightlyBuildData(fetch_config, good_date,
                                                      bad_date)
예제 #3
0
def test_runner_started_multiple_times():
    class Worker(QObject):
        def __init__(self, *args):
            QObject.__init__(self)

    class BuildRunner(build_runner.AbstractBuildRunner):
        worker_class = Worker

        def init_worker(self, fetch_config, options):
            build_runner.AbstractBuildRunner.init_worker(
                self, fetch_config, options)
            return lambda: 1

    fetch_config = create_config('firefox', 'linux', 64, 'x86_64')
    options = {
        'addons': (),
        'profile': '/path/to/profile',
        'profile_persistence': 'clone'
    }

    runner = BuildRunner(Mock(persist='.'))
    assert not runner.stopped
    runner.start(fetch_config, options)
    assert not runner.stopped
    runner.stop()
    assert runner.stopped
    runner.start(fetch_config, options)
    assert not runner.stopped
    runner.stop()
    assert runner.stopped
예제 #4
0
def test_get_default_date_range(app, os, bits, processor, build_type,
                                expected_range):
    fetch_config = create_config(app, os, bits, processor)
    if build_type:
        fetch_config.set_build_type(build_type)

    assert expected_range == cli.get_default_date_range(fetch_config)
 def setUp(self):
     self.conf = create_config(self.app_name, self.os, self.bits, self.processor)
     self.conf.BUILD_TYPES = (
         "excluded[win64]",
         "included[win64-aarch64]",
         "default",
     )
def test_set_firefox_build_type_pgo(os, bits, processor, tc_suffix):
    conf = create_config("firefox", os, bits, processor)
    if type(tc_suffix) is not str:
        with pytest.raises(tc_suffix):
            conf.set_build_type("pgo")
    else:
        conf.set_build_type("pgo")
        assert conf.tk_route(create_push(CHSET, TIMESTAMP_TEST)).endswith("." + tc_suffix)
예제 #7
0
def cli(argv=None):
    """
    main entry point of mozregression command line.
    """
    options = parse_args(argv)
    logger = commandline.setup_logging("mozregression", options,
                                       {"mach": sys.stdout})
    check_mozregression_version(logger)

    if options.list_releases:
        print(formatted_valid_release_dates())
        sys.exit()

    cache_session = limitedfilecache.get_cache(
        options.http_cache_dir,
        limitedfilecache.ONE_GIGABYTE,
        logger=get_default_logger('Limited File Cache'))
    set_http_cache_session(cache_session,
                           get_defaults={"timeout": options.http_timeout})

    fetch_config = create_config(options.app, mozinfo.os, options.bits)

    if options.command is None:
        launcher_kwargs = dict(
            addons=options.addons,
            profile=options.profile,
            cmdargs=options.cmdargs,
            preferences=preference(options.prefs_files, options.prefs),
        )
        test_runner = ManualTestRunner(launcher_kwargs=launcher_kwargs)
    else:
        test_runner = CommandTestRunner(options.command)

    runner = ResumeInfoBisectRunner(fetch_config, test_runner, options)

    if fetch_config.is_inbound():
        # this can be useful for both inbound and nightly, because we
        # can go to inbound from nightly.
        fetch_config.set_inbound_branch(options.inbound_branch)

    # bisect inbound if last good revision or first bad revision are set
    if options.first_bad_revision or options.last_good_revision:
        bisect = bisect_inbound
    else:
        bisect = bisect_nightlies

    try:
        launcher_class = APP_REGISTRY.get(fetch_config.app_name)
        launcher_class.check_is_runnable()

        sys.exit(bisect(runner, logger))
    except KeyboardInterrupt:
        sys.exit("\nInterrupted.")
    except UnavailableRelease as exc:
        sys.exit("%s\n%s" % (exc, formatted_valid_release_dates()))
    except (MozRegressionError, RequestException) as exc:
        sys.exit(str(exc))
예제 #8
0
    def __init__(self, good, bad, platform, warning, warning_limit, warning_re,
                 ignore_lines, required_test):

        init_logger()
        self.use_nightly = True
        try:
            self.good = parse_date(good)
            self.bad = parse_date(bad)
        except DateFormatError:
            # This hopefully a revision range. We can bypass nightly and
            # go directly to InboundHandler. That itself is a bit of a misnomer,
            # it will still bisect m-c builds, but by changeset range, not date
            # range.
            self.use_nightly = False
            self.good = good
            self.bad = bad

        self.ignore_lines = ignore_lines
        self.test_runner = WarningTestRunner(warning,
                                             platform,
                                             ignore_lines=ignore_lines,
                                             warning_re=warning_re,
                                             warning_limit=warning_limit,
                                             required_test=required_test)

        # Convert the platform to a mozregression friendly version.
        # Also avoid overwriting the os module by *not* using |os| for a
        # variable name.
        (_os, bits) = re.match(r'([a-zA-Z]+)-?([0-9]+)?', platform).groups()
        if not bits or bits not in (32, 64):
            bits = 32

        # windows7-32
        # windows7-32-vm
        # win32
        # win64
        if '64' in platform:
            bits = 64

        if _os.startswith('win'):
            _os = 'win'

        print("_os = %s bits = %s" % (_os, bits))

        # TODO(ER): We might be able to ditch this.
        self.fetch_config = create_config('firefox', _os, int(bits))
        # Hardcode to m-c for now.
        self.fetch_config.set_repo('mozilla-central')
        self.fetch_config.set_build_type('debug')

        class FakeDownloadManager:
            def focus_download(self, foo):
                pass

        dm = FakeDownloadManager()
        self.bisector = Bisector(self.fetch_config, self.test_runner, dm,
                                 False, None)
def create_build_info(klass, **attrs):
    defaults = dict(
        fetch_config=create_config('firefox', 'linux', 64),
        build_url='http://build/url',
        build_date=date(2015, 9, 1),
        changeset='12ab' * 10,
        repo_url='http://repo:url',
    )
    defaults.update(attrs)
    return klass(**defaults)
예제 #10
0
def create_build_info(klass, **attrs):
    defaults = dict(
        fetch_config=create_config("firefox", "linux", 64, "x86_64"),
        build_url="http://build/url",
        build_date=date(2015, 9, 1),
        changeset="12ab" * 10,
        repo_url="http://repo:url",
    )
    defaults.update(attrs)
    return klass(**defaults)
def test_set_firefox_build_type_pgo(os, bits, tc_suffix):
    conf = create_config('firefox', os, bits)
    if type(tc_suffix) is not str:
        with pytest.raises(tc_suffix):
            conf.set_build_type('pgo')
    else:
        conf.set_build_type('pgo')
        assert conf.tk_inbound_route(
            create_push(CHSET, TIMESTAMP_GECKO_V2)) \
            .endswith('.' + tc_suffix)
예제 #12
0
def test_range_for_nightlies():
    fetch_config = create_config('firefox', 'linux', 64, 'x86_64')

    b_range = build_range.range_for_nightlies(fetch_config, date(2015, 01, 01),
                                              date(2015, 01, 03))

    assert isinstance(b_range, build_range.BuildRange)
    assert len(b_range) == 3

    b_range.build_info_fetcher.find_build_info = lambda v: v
    assert b_range[0] == date(2015, 01, 01)
    assert b_range[1] == date(2015, 01, 02)
    assert b_range[2] == date(2015, 01, 03)
예제 #13
0
    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',
        })
예제 #14
0
def test_get_nightly_range():
    fetch_config = create_config("firefox", "linux", 64, "x86_64")

    b_range = build_range.get_nightly_range(fetch_config, date(2015, 1, 1),
                                            date(2015, 1, 3))

    assert isinstance(b_range, build_range.BuildRange)
    assert len(b_range) == 3

    b_range.build_info_fetcher.find_build_info = lambda v: v
    assert b_range[0] == date(2015, 1, 1)
    assert b_range[1] == date(2015, 1, 2)
    assert b_range[2] == date(2015, 1, 3)
    def create_inbound_build_data(self, good, bad, get_pushlogs, url_links):
        fetch_config = fetch_configs.create_config('firefox', 'linux', 64)
        # create fake pushlog returns
        pushlogs = [
            {'date': d, 'changesets': ['c' + str(d)]}
            for d in xrange(int(good[1:]), int(bad[1:]))
        ]
        get_pushlogs.return_value = pushlogs
        # returns 100 possible build folders

        def inbound_links(url, regex=None):
            return ['%i/' % i for i in xrange(100)]
        url_links.side_effect = inbound_links
        return build_data.InboundBuildData(fetch_config, good, bad, range=5)
예제 #16
0
def test_range_for_inbounds_with_dates(mocker, start_date, end_date,
                                       start_call, end_call):
    fetch_config = create_config('firefox', 'linux', 64, 'x86_64')
    jpush_class = mocker.patch('mozregression.fetch_build_info.JsonPushes')
    jpush = mocker.Mock(pushes_within_changes=mocker.Mock(return_value=[]),
                        spec=JsonPushes)
    jpush_class.return_value = jpush

    build_range.range_for_inbounds(fetch_config,
                                   start_date,
                                   end_date,
                                   time_limit=DATE_YEAR_BEFORE)

    jpush.pushes_within_changes.assert_called_once_with(start_call, end_call)
예제 #17
0
def test_get_integration_range_with_dates(mocker, start_date, end_date,
                                          start_call, end_call):
    fetch_config = create_config("firefox", "linux", 64, "x86_64")
    jpush_class = mocker.patch("mozregression.fetch_build_info.JsonPushes")
    jpush = mocker.Mock(pushes_within_changes=mocker.Mock(return_value=[]),
                        spec=JsonPushes)
    jpush_class.return_value = jpush

    build_range.get_integration_range(fetch_config,
                                      start_date,
                                      end_date,
                                      time_limit=DATE_YEAR_BEFORE)

    jpush.pushes_within_changes.assert_called_once_with(start_call, end_call)
예제 #18
0
def test_range_for_nightlies_datetime(start, end, range_size):
    fetch_config = create_config('firefox', 'linux', 64, 'x86_64')

    b_range = build_range.range_for_nightlies(fetch_config, start, end)

    assert isinstance(b_range, build_range.BuildRange)
    assert len(b_range) == range_size

    b_range.build_info_fetcher.find_build_info = lambda v: v
    assert b_range[0] == start
    assert b_range[-1] == end
    # between, we only have date instances
    for i in range(1, range_size - 1):
        assert isinstance(b_range[i], date)
예제 #19
0
def test_get_nightly_range_datetime(start, end, range_size):
    fetch_config = create_config("firefox", "linux", 64, "x86_64")

    b_range = build_range.get_nightly_range(fetch_config, start, end)

    assert isinstance(b_range, build_range.BuildRange)
    assert len(b_range) == range_size

    b_range.build_info_fetcher.find_build_info = lambda v: v
    assert b_range[0] == start
    assert b_range[-1] == end
    # between, we only have date instances
    for i in range(1, range_size - 1):
        assert isinstance(b_range[i], date)
예제 #20
0
    def test_build_infos(self):
        fetch_config = create_config('fennec-2.3', 'linux', 64)
        fetch_config.set_nightly_repo('my-repo')

        def get_associated_data(index):
            return index
        new_data = MagicMock(get_associated_data=get_associated_data)
        self.handler.set_build_data(new_data)
        result = self.handler.build_infos(1, fetch_config)
        self.assertEqual(result, {
            'build_type': 'nightly',
            'build_date': 1,
            'app_name': 'fennec',
            'repo': 'my-repo'
        })
예제 #21
0
    def _set_fetch_config(self, index):
        app_name = str(self.ui.app_combo.currentText())
        bits = int(self.ui.bits_combo.currentText())

        self.fetch_config = create_config(app_name, mozinfo.os, bits)

        self.build_type_model = QStringListModel(
            [i for i in REGISTRY.get(app_name).BUILD_TYPES])
        self.ui.build_type.setModel(self.build_type_model)

        if not self.fetch_config.available_bits():
            self.ui.bits_combo.hide()
            self.ui.label_4.hide()
        else:
            self.ui.bits_combo.show()
            self.ui.label_4.show()
예제 #22
0
def test_get_integration_range_with_expand(mocker):
    fetch_config = create_config("firefox", "linux", 64, "x86_64")
    jpush_class = mocker.patch("mozregression.fetch_build_info.JsonPushes")
    pushes = [create_push("b", 1), create_push("d", 2), create_push("f", 3)]
    jpush = mocker.Mock(pushes_within_changes=mocker.Mock(return_value=pushes),
                        spec=JsonPushes)
    jpush_class.return_value = jpush

    check_expand = mocker.patch(
        "mozregression.build_range.BuildRange.check_expand")

    build_range.get_integration_range(fetch_config, "a", "e", expand=10)

    check_expand.assert_called_once_with(10,
                                         build_range.tc_range_before,
                                         build_range.tc_range_after,
                                         interrupt=None)
예제 #23
0
def test_range_for_inbounds_with_expand(mocker):
    fetch_config = create_config('firefox', 'linux', 64, 'x86_64')
    jpush_class = mocker.patch('mozregression.fetch_build_info.JsonPushes')
    pushes = [create_push('b', 1), create_push('d', 2), create_push('f', 3)]
    jpush = mocker.Mock(pushes_within_changes=mocker.Mock(return_value=pushes),
                        spec=JsonPushes)
    jpush_class.return_value = jpush

    check_expand = mocker.patch(
        'mozregression.build_range.BuildRange.check_expand')

    build_range.range_for_inbounds(fetch_config, 'a', 'e', expand=10)

    check_expand.assert_called_once_with(10,
                                         build_range.tc_range_before,
                                         build_range.tc_range_after,
                                         interrupt=None)
예제 #24
0
def test_abstract_build_runner(qtbot):
    main_thread = QThread.currentThread()

    class Worker(QObject):
        call_started = Signal()

        def __init__(self, *args):
            QObject.__init__(self)

        @Slot()
        def my_slot(self):
            assert main_thread != self.thread()
            self.call_started.emit()

    class BuildRunner(build_runner.AbstractBuildRunner):
        call_started = Signal()
        thread_finished = Signal()
        worker_class = Worker

        def init_worker(self, fetch_config, options):
            build_runner.AbstractBuildRunner.init_worker(
                self, fetch_config, options)
            self.thread.finished.connect(self.thread_finished)
            self.worker.call_started.connect(self.call_started)
            return self.worker.my_slot

    # instantiate the runner
    runner = BuildRunner(Mock(persist='.'))

    assert not runner.thread

    with qtbot.waitSignal(runner.thread_finished, raising=True):
        with qtbot.waitSignal(runner.call_started, raising=True):
            runner.start(
                create_config('firefox', 'linux', 64, 'x86_64'),
                {
                    'addons': (),
                    'profile': '/path/to/profile',
                    'profile_persistence': 'clone'
                },
            )

        runner.stop(True)

    assert not runner.pending_threads
예제 #25
0
    def _set_fetch_config(self, index):
        app_name = str(self.ui.app_combo.currentText())
        bits = int(self.ui.bits_combo.currentText())

        self.fetch_config = create_config(app_name, mozinfo.os, bits, mozinfo.processor)

        self.arch_model = QStringListModel(self.fetch_config.available_archs())
        self.ui.arch_combo.setModel(self.arch_model)
        if not self.arch_model.stringList():
            self.ui.arch_label.setDisabled(True)
            self.ui.arch_combo.setDisabled(True)
        else:
            self.ui.arch_label.setEnabled(True)
            self.ui.arch_combo.setEnabled(True)

        self.build_type_model = QStringListModel(self.fetch_config.available_build_types())
        self.ui.build_type.setModel(self.build_type_model)

        if not self.fetch_config.available_bits():
            self.ui.bits_combo.setDisabled(True)
            self.ui.label_4.setDisabled(True)
        else:
            self.ui.bits_combo.setEnabled(True)
            self.ui.label_4.setEnabled(True)

        # URL doesn't make sense for Thunderbird
        if app_name == "thunderbird":
            self.ui.url.setDisabled(True)
            self.ui.url_label.setDisabled(True)
        else:
            self.ui.url.setEnabled(True)
            self.ui.url_label.setEnabled(True)

        # lang only makes sense for firefox-l10n, and repo doesn't
        if app_name == "firefox-l10n":
            self.ui.lang.setEnabled(True)
            self.ui.lang_label.setEnabled(True)
            self.ui.repository.setDisabled(True)
            self.ui.repository_label.setDisabled(True)
        else:
            self.ui.lang.setDisabled(True)
            self.ui.lang_label.setDisabled(True)
            self.ui.repository.setEnabled(True)
            self.ui.repository_label.setEnabled(True)
예제 #26
0
def cli(args=sys.argv[1:]):
    from mozregression.fetch_configs import create_config
    parser = OptionParser()
    parser.add_option("--start-rev", dest="start_rev", help="start revision")
    parser.add_option("--end-rev", dest="end_rev", help="end revision")
    parser.add_option("--os",
                      dest="os",
                      help="override operating system "
                      "autodetection (mac, linux, win)",
                      default=mozinfo.os)
    parser.add_option("--bits",
                      dest="bits",
                      help="override operating system "
                      "bits autodetection",
                      default=mozinfo.bits)
    parser.add_option("-n",
                      "--app",
                      dest="app",
                      help="application name "
                      "(firefox, fennec or b2g)",
                      metavar="[firefox|fennec|b2g]",
                      default="firefox")
    parser.add_option("--inbound-branch",
                      dest="inbound_branch",
                      help="inbound branch name on ftp.mozilla.org",
                      metavar="[tracemonkey|mozilla-1.9.2]",
                      default=None)

    options, args = parser.parse_args(args)
    if not options.start_rev or not options.end_rev:
        sys.exit("start revision and end revision must be specified")

    fetch_config = create_config(options.app, options.os, options.bits)

    build_finder = BuildsFinder(fetch_config)

    revisions = build_finder.get_build_infos(options.start_rev,
                                             options.end_rev,
                                             range=60 * 60 * 12)
    print("Revision, Timestamp")
    for revision in revisions:
        print("%s %s" % (revision['revision'], revision['timestamp']))
예제 #27
0
 def _set_fetch_config(self, index):
     # limit bisection type given the application
     bits = int(self.ui.bits_combo.currentText())
     old_bisect_index = self.ui.bisect_combo.currentIndex()
     self.fetch_config = create_config(
         str(self.ui.app_combo.itemText(index)), mozinfo.os, bits)
     bisect_types = ['nightlies']
     if self.fetch_config.is_inbound():
         bisect_types.append('inbound')
     self.bisect_model.setStringList(bisect_types)
     bisect_index = 0
     if old_bisect_index == 1 and len(bisect_types) == 2:
         bisect_index = 1
     self.ui.bisect_combo.setCurrentIndex(bisect_index)
     available_bits = self.fetch_config.available_bits()
     if not available_bits:
         self.ui.bits_combo.hide()
         self.ui.label_4.hide()
     else:
         self.ui.bits_combo.show()
         self.ui.label_4.show()
예제 #28
0
def test_get_integration_range(mocker):
    fetch_config = create_config("firefox", "linux", 64, "x86_64")
    jpush_class = mocker.patch("mozregression.fetch_build_info.JsonPushes")
    pushes = [create_push("b", 1), create_push("d", 2), create_push("f", 3)]
    jpush = mocker.Mock(pushes_within_changes=mocker.Mock(return_value=pushes),
                        spec=JsonPushes)
    jpush_class.return_value = jpush

    b_range = build_range.get_integration_range(fetch_config, "a", "e")

    jpush_class.assert_called_once_with(branch="mozilla-central")
    jpush.pushes_within_changes.assert_called_once_with("a", "e")
    assert isinstance(b_range, build_range.BuildRange)
    assert len(b_range) == 3

    b_range.build_info_fetcher.find_build_info = lambda v: v
    assert b_range[0] == pushes[0]
    assert b_range[1] == pushes[1]
    assert b_range[2] == pushes[2]

    b_range.future_build_infos[0].date_or_changeset() == "b"
예제 #29
0
def test_range_for_inbounds(mocker):
    fetch_config = create_config('firefox', 'linux', 64, 'x86_64')
    jpush_class = mocker.patch('mozregression.fetch_build_info.JsonPushes')
    pushes = [create_push('b', 1), create_push('d', 2), create_push('f', 3)]
    jpush = mocker.Mock(pushes_within_changes=mocker.Mock(return_value=pushes),
                        spec=JsonPushes)
    jpush_class.return_value = jpush

    b_range = build_range.range_for_inbounds(fetch_config, 'a', 'e')

    jpush_class.assert_called_once_with(branch='mozilla-inbound')
    jpush.pushes_within_changes.assert_called_once_with('a', 'e')
    assert isinstance(b_range, build_range.BuildRange)
    assert len(b_range) == 3

    b_range.build_info_fetcher.find_build_info = lambda v: v
    assert b_range[0] == pushes[0]
    assert b_range[1] == pushes[1]
    assert b_range[2] == pushes[2]

    b_range.future_build_infos[0].date_or_changeset() == 'b'
예제 #30
0
def test_range_for_inbounds(mocker):
    fetch_config = create_config('firefox', 'linux', 64)
    jpush_class = mocker.patch('mozregression.fetch_build_info.JsonPushes')
    jpush = mocker.Mock(pushlog_within_changes=mocker.Mock(return_value=[{
        'changesets': ['a', 'b']
    }, {
        'changesets': ['c', 'd']
    }, {
        'changesets': ['e', 'f']
    }]),
                        spec=JsonPushes)
    jpush_class.return_value = jpush

    b_range = build_range.range_for_inbounds(fetch_config, 'a', 'e')

    jpush_class.assert_called_once_with(branch='mozilla-inbound')
    jpush.pushlog_within_changes.assert_called_once_with('a', 'e')
    assert isinstance(b_range, build_range.BuildRange)
    assert len(b_range) == 3

    b_range.build_info_fetcher.find_build_info = lambda v: v
    assert b_range[0] == 'b'
    assert b_range[1] == 'd'
    assert b_range[2] == 'f'