def validatePage(self): start, end = self.get_start(), self.get_end() if isinstance(start, basestring) or isinstance(end, basestring): # do not check revisions return True try: start_date = to_datetime(start) end_date = to_datetime(end) except DateFormatError as exc: QMessageBox.critical(self, "Error", unicode(exc)) return False current = datetime.datetime.now() if start_date < end_date: if end_date <= current: return True else: QMessageBox.critical( self, "Error", "You can't define a date in the future.") else: QMessageBox.critical( self, "Error", "The first date must be earlier than the second one.") return False
def validatePage(self): start, end = self.get_start(), self.get_end() if isinstance(start, basestring) or isinstance(end, basestring): # do not check revisions return True try: start_date = to_datetime(start) end_date = to_datetime(end) except DateFormatError as exc: QMessageBox.critical(self, "Error", unicode(exc)) return False current = datetime.datetime.now() if start_date < end_date: if end_date <= current: return True else: QMessageBox.critical( self, "Error", "You can't define a date in the future.") else: QMessageBox.critical( self, "Error", "The first date must be earlier than the second one.") return False
def _print_progress(self, new_data): next_good_date = new_data[0].build_date next_bad_date = new_data[-1].build_date next_days_range = abs( (to_datetime(next_bad_date) - to_datetime(next_good_date)).days) LOG.info("Narrowed nightly regression window from" " [%s, %s] (%d days) to [%s, %s] (%d days)" " (~%d steps left)" % (self.good_date, self.bad_date, abs((to_datetime(self.bad_date) - to_datetime( self.good_date)).days), next_good_date, next_bad_date, next_days_range, compute_steps_left(next_days_range)))
def _print_progress(self, new_data): next_good_date = new_data[0].build_date next_bad_date = new_data[-1].build_date next_days_range = abs((to_datetime(next_bad_date) - to_datetime(next_good_date)).days) LOG.info("Narrowed nightly regression window from" " [%s, %s] (%d days) to [%s, %s] (%d days)" " (~%d steps left)" % (self.good_date, self.bad_date, abs((to_datetime(self.bad_date) - to_datetime(self.good_date)).days), next_good_date, next_bad_date, next_days_range, compute_steps_left(next_days_range)))
def _check_date(obj): if is_date_or_datetime(obj): if to_datetime(obj) < time_limit: LOG.info("TaskCluster only keeps builds for one year." " Using %s instead of %s." % (time_limit, obj)) obj = time_limit return obj
def find_inbound_changesets(self, days_required=4): self._logger.info("... attempting to bisect inbound builds (starting" " from %d days prior, to make sure no inbound" " revision is missed)" % days_required) infos = None days = days_required - 1 too_many_attempts = False max_attempts = 3 first_date = min(to_datetime(self.good_date), to_datetime(self.bad_date)) while not infos or not infos.changeset: days += 1 if days >= days_required + max_attempts: too_many_attempts = True break prev_date = first_date - datetime.timedelta(days=days) build_range = self.build_range infos = build_range.build_info_fetcher.find_build_info( prev_date.date()) if days > days_required and not too_many_attempts: self._logger.info("At least one build folder was invalid, we have" " to start from %d days ago." % days) if not self.find_fix: good_rev = infos.changeset bad_rev = self.bad_revision else: good_rev = self.good_revision bad_rev = infos.changeset if bad_rev is None or good_rev is None: # we cannot find valid nightly builds in the searched range. # two possible causes: # - old nightly builds do not have the changeset information # so we can't go on inbound. Anyway, these are probably too # old and won't even exists on inbound. # - something else (builds were not updated on archive.mozilla.org, # or all invalid) start_range = first_date - datetime.timedelta(days=days_required) end_range = start_range - datetime.timedelta(days=max_attempts) raise MozRegressionError( "Not enough changeset information to produce initial inbound" " regression range (failed to find metadata between %s and %s)" ". Nightly build folders are invalids or too old in this" " range." % (start_range, end_range)) return good_rev, bad_rev
def validatePage(self): try: start_date = to_datetime(self.get_start_date()) end_date = to_datetime(self.get_end_date()) except DateFormatError as exc: QMessageBox.critical(self, "Error", unicode(exc)) return False current = datetime.datetime.now() if start_date < end_date: if end_date <= current: return True else: QMessageBox.critical(self, "Error", "You can't define a date in the future.") else: QMessageBox.critical(self, "Error", "The first date must be earlier than the second one.") return False
def check_nightlies(options, fetch_config, logger): default_bad_date = str(datetime.date.today()) default_good_date = "2009-01-01" if mozinfo.os == 'win' and options.bits == 64: # first firefox build date for win64 is 2010-05-28 default_good_date = "2010-05-28" if options.find_fix: default_bad_date, default_good_date = \ default_good_date, default_bad_date # TODO: currently every fetch_config is nightly aware. Shoud we test # for this to be sure here ? fetch_config.set_nightly_repo(options.repo) if not options.bad_release and not options.bad_date: options.bad_date = default_bad_date logger.info("No 'bad' date specified, using %s" % options.bad_date) elif options.bad_release and options.bad_date: raise MozRegressionError("Options '--bad-release' and '--bad'" " are incompatible.") elif options.bad_release: options.bad_date = date_of_release(options.bad_release) logger.info("Using 'bad' date %s for release %s" % (options.bad_date, options.bad_release)) if not options.good_release and not options.good_date: options.good_date = default_good_date logger.info("No 'good' date specified, using %s" % options.good_date) elif options.good_release and options.good_date: raise MozRegressionError("Options '--good-release' and '--good'" " are incompatible.") elif options.good_release: options.good_date = date_of_release(options.good_release) logger.info("Using 'good' date %s for release %s" % (options.good_date, options.good_release)) options.good_date = good_date = parse_date(options.good_date) options.bad_date = bad_date = parse_date(options.bad_date) if not options.find_fix and to_datetime(good_date) > to_datetime(bad_date): raise MozRegressionError(("Good date %s is later than bad date %s." " Maybe you wanted to use the --find-fix" " flag ?") % (good_date, bad_date)) elif options.find_fix and to_datetime(good_date) < to_datetime(bad_date): raise MozRegressionError(("Bad date %s is later than good date %s." " You should not use the --find-fix flag" " in this case...") % (bad_date, good_date))
def _check_date(obj): if is_date_or_datetime(obj): if to_datetime(obj) < time_limit: logger.info( "TaskCluster only keeps builds for one year." " Using %s instead of %s." % (time_limit, obj) ) obj = time_limit return obj
def _print_progress(self, new_data): good_date, bad_date = self._reverse_if_find_fix( self.good_date, self.bad_date) next_good_date = new_data[0].build_date next_bad_date = new_data[-1].build_date next_days_range = abs( (to_datetime(next_bad_date) - to_datetime(next_good_date)).days) LOG.info("Narrowed nightly %s window from" " [%s, %s] (%d days) to [%s, %s] (%d days)" " (~%d steps left)" % ( "fix" if self.find_fix else "regression", good_date, bad_date, abs((to_datetime(self.bad_date) - to_datetime(self.good_date)).days), next_good_date, next_bad_date, next_days_range, compute_steps_left(next_days_range), ))
def validate(self): """ Validate the options, define the `action` and `fetch_config` that should be used to run the application. """ options = self.options user_defined_bits = options.bits is not None options.bits = parse_bits(options.bits or mozinfo.bits) fetch_config = create_config(options.app, mozinfo.os, options.bits) try: fetch_config.set_build_type(options.build_type) except MozRegressionError as msg: self.logger.warning( "%s (Defaulting to %r)" % (msg, fetch_config.build_type) ) self.fetch_config = fetch_config fetch_config.set_repo(options.repo) if fetch_config.is_nightly(): fetch_config.set_base_url(options.archive_base_url) if not user_defined_bits and \ options.bits == 64 and \ mozinfo.os == 'win' and \ 32 in fetch_config.available_bits(): # inform users on windows that we are using 64 bit builds. self.logger.info("bits option not specified, using 64-bit builds.") if options.bits == 32 and mozinfo.os == 'mac': self.logger.info("only 64-bit builds available for mac, using " "64-bit builds") if fetch_config.is_inbound() and fetch_config.tk_needs_auth(): creds = tc_authenticate(self.logger) fetch_config.set_tk_credentials(creds) # set action for just use changset or data to bisect if options.launch: options.launch = self._convert_to_bisect_arg(options.launch) self.action = "launch_inbound" if is_date_or_datetime(options.launch) and \ not fetch_config.should_use_taskcluster(): self.action = "launch_nightlies" else: # define good/bad default values if required default_good_date, default_bad_date = \ get_default_date_range(fetch_config) if options.find_fix: default_bad_date, default_good_date = \ default_good_date, default_bad_date if not options.bad: options.bad = default_bad_date self.logger.info("No 'bad' option specified, using %s" % options.bad) else: options.bad = self._convert_to_bisect_arg(options.bad) if not options.good: options.good = default_good_date self.logger.info("No 'good' option specified, using %s" % options.good) else: options.good = self._convert_to_bisect_arg(options.good) self.action = "bisect_inbounds" if is_date_or_datetime(options.good) and \ is_date_or_datetime(options.bad): if not options.find_fix and \ to_datetime(options.good) > to_datetime(options.bad): raise MozRegressionError( ("Good date %s is later than bad date %s." " Maybe you wanted to use the --find-fix" " flag?") % (options.good, options.bad)) elif options.find_fix and \ to_datetime(options.good) < to_datetime(options.bad): raise MozRegressionError( ("Bad date %s is later than good date %s." " You should not use the --find-fix flag" " in this case...") % (options.bad, options.good)) if not fetch_config.should_use_taskcluster(): self.action = "bisect_nightlies" if self.action in ('launch_inbound', 'bisect_inbounds')\ and not fetch_config.is_inbound(): raise MozRegressionError('Unable to bisect inbound for `%s`' % fetch_config.app_name) options.preferences = preferences(options.prefs_files, options.prefs) # convert GiB to bytes. options.persist_size_limit = \ int(abs(float(options.persist_size_limit)) * 1073741824)
def validate(self): """ Validate the options, define the `action` and `fetch_config` that should be used to run the application. """ options = self.options user_defined_bits = options.bits is not None options.bits = parse_bits(options.bits or mozinfo.bits) if options.arch is not None: if options.app != "gve": self.logger.warning("--arch ignored for non-GVE app.") options.arch = None fetch_config = create_config(options.app, mozinfo.os, options.bits, mozinfo.processor, options.arch) if options.lang: if options.app != "firefox-l10n": raise MozRegressionError( "--lang is only valid with --app=firefox-l10n") fetch_config.set_lang(options.lang) elif options.app == "firefox-l10n": raise MozRegressionError( "app 'firefox-l10n' requires a --lang argument") if options.build_type: try: fetch_config.set_build_type(options.build_type) except MozRegressionError as msg: self.logger.warning("%s (Defaulting to %r)" % (msg, fetch_config.build_type)) self.fetch_config = fetch_config fetch_config.set_repo(options.repo) fetch_config.set_base_url(options.archive_base_url) if (not user_defined_bits and options.bits == 64 and mozinfo.os == "win" and 32 in fetch_config.available_bits()): # inform users on windows that we are using 64 bit builds. self.logger.info("bits option not specified, using 64-bit builds.") if options.bits == 32 and mozinfo.os == "mac": self.logger.info("only 64-bit builds available for mac, using " "64-bit builds") if fetch_config.is_integration() and fetch_config.tk_needs_auth(): creds = tc_authenticate(self.logger) fetch_config.set_tk_credentials(creds) # set action for just use changset or data to bisect if options.launch: options.launch = self._convert_to_bisect_arg(options.launch) self.action = "launch_integration" if is_date_or_datetime( options.launch) and fetch_config.should_use_archive(): self.action = "launch_nightlies" else: # define good/bad default values if required default_good_date, default_bad_date = get_default_date_range( fetch_config) if options.find_fix: default_bad_date, default_good_date = ( default_good_date, default_bad_date, ) if not options.bad: options.bad = default_bad_date self.logger.info("No 'bad' option specified, using %s" % options.bad) else: options.bad = self._convert_to_bisect_arg(options.bad) if not options.good: options.good = default_good_date self.logger.info("No 'good' option specified, using %s" % options.good) else: options.good = self._convert_to_bisect_arg(options.good) self.action = "bisect_integration" if is_date_or_datetime(options.good) and is_date_or_datetime( options.bad): if not options.find_fix and to_datetime( options.good) > to_datetime(options.bad): raise MozRegressionError( ("Good date %s is later than bad date %s." " Maybe you wanted to use the --find-fix" " flag?") % (options.good, options.bad)) elif options.find_fix and to_datetime( options.good) < to_datetime(options.bad): raise MozRegressionError( ("Bad date %s is later than good date %s." " You should not use the --find-fix flag" " in this case...") % (options.bad, options.good)) if fetch_config.should_use_archive(): self.action = "bisect_nightlies" if (self.action in ("launch_integration", "bisect_integration") and not fetch_config.is_integration()): raise MozRegressionError("Unable to bisect integration for `%s`" % fetch_config.app_name) options.preferences = preferences(options.prefs_files, options.prefs, self.logger) # convert GiB to bytes. options.persist_size_limit = int( abs(float(options.persist_size_limit)) * 1073741824)
def validate(self): """ Validate the options, define the `action` and `fetch_config` that should be used to run the application. """ options = self.options user_defined_bits = options.bits is not None options.bits = parse_bits(options.bits or mozinfo.bits) fetch_config = create_config(options.app, mozinfo.os, options.bits, mozinfo.processor) if options.build_type: try: fetch_config.set_build_type(options.build_type) except MozRegressionError as msg: self.logger.warning( "%s (Defaulting to %r)" % (msg, fetch_config.build_type) ) self.fetch_config = fetch_config fetch_config.set_repo(options.repo) if fetch_config.is_nightly(): fetch_config.set_base_url(options.archive_base_url) if not user_defined_bits and \ options.bits == 64 and \ mozinfo.os == 'win' and \ 32 in fetch_config.available_bits(): # inform users on windows that we are using 64 bit builds. self.logger.info("bits option not specified, using 64-bit builds.") if options.bits == 32 and mozinfo.os == 'mac': self.logger.info("only 64-bit builds available for mac, using " "64-bit builds") if fetch_config.is_inbound() and fetch_config.tk_needs_auth(): creds = tc_authenticate(self.logger) fetch_config.set_tk_credentials(creds) # set action for just use changset or data to bisect if options.launch: options.launch = self._convert_to_bisect_arg(options.launch) self.action = "launch_inbound" if is_date_or_datetime(options.launch) and \ not fetch_config.should_use_taskcluster(): self.action = "launch_nightlies" else: # define good/bad default values if required default_good_date, default_bad_date = \ get_default_date_range(fetch_config) if options.find_fix: default_bad_date, default_good_date = \ default_good_date, default_bad_date if not options.bad: options.bad = default_bad_date self.logger.info("No 'bad' option specified, using %s" % options.bad) else: options.bad = self._convert_to_bisect_arg(options.bad) if not options.good: options.good = default_good_date self.logger.info("No 'good' option specified, using %s" % options.good) else: options.good = self._convert_to_bisect_arg(options.good) self.action = "bisect_inbounds" if is_date_or_datetime(options.good) and \ is_date_or_datetime(options.bad): if not options.find_fix and \ to_datetime(options.good) > to_datetime(options.bad): raise MozRegressionError( ("Good date %s is later than bad date %s." " Maybe you wanted to use the --find-fix" " flag?") % (options.good, options.bad)) elif options.find_fix and \ to_datetime(options.good) < to_datetime(options.bad): raise MozRegressionError( ("Bad date %s is later than good date %s." " You should not use the --find-fix flag" " in this case...") % (options.bad, options.good)) if not fetch_config.should_use_taskcluster(): self.action = "bisect_nightlies" if self.action in ('launch_inbound', 'bisect_inbounds')\ and not fetch_config.is_inbound(): raise MozRegressionError('Unable to bisect inbound for `%s`' % fetch_config.app_name) options.preferences = preferences(options.prefs_files, options.prefs, self.logger) # convert GiB to bytes. options.persist_size_limit = \ int(abs(float(options.persist_size_limit)) * 1073741824)