def test_revision_for_date_raise_appropriate_error(): jpushes = JsonPushes(branch='inbound') jpushes.pushlog_within_changes = Mock(side_effect=EmptyPushlogError) with pytest.raises(EmptyPushlogError) as ctx: jpushes.revision_for_date(date(2015, 1, 1)) assert str(ctx.value) == \ 'No pushes available for the date 2015-01-01 on inbound.'
def test_revision_for_date_raise_appropriate_error(): jpushes = JsonPushes(branch='inbound') jpushes.pushlog_within_changes = Mock(side_effect=EmptyPushlogError) with pytest.raises(EmptyPushlogError) as ctx: jpushes.revision_for_date(date(2015, 1, 1)) assert str(ctx.value) == \ 'No pushes available for the date 2015-01-01 on inbound.'
def check_taskcluster(options, fetch_config, logger): if not options.taskcluster or not options.artifact_name: raise MozRegressionError('--taskcluster and --artifact-name are' ' required for taskcluster regression' ' finding') if options.repo and options.inbound_branch: raise MozRegressionError('unable to define both --repo and' ' --inbound-branch for b2g-device') if options.repo: # if repo is defined, use that to bisect using taskcluster, # ie the "inbound way" for now. Just remove the "integration" # branch path. fetch_config.set_branch_path(None) fetch_config.set_inbound_branch(options.repo) if options.last_good_revision and options.first_bad_revision: # If we have revisions, use those check_inbounds(options, fetch_config, logger) print "Using revs: %s - %s" % ( options.last_good_revision, options.first_bad_revision, ) else: # If we don't have revisions, use the nightly-style date range and # convert it into a good/bad rev. check_nightlies(options, fetch_config, logger) from mozregression.json_pushes import JsonPushes jpushes = JsonPushes(branch=fetch_config.inbound_branch, path=fetch_config.branch_path) options.last_good_revision = jpushes.revision_for_date( options.good_date ) options.first_bad_revision = jpushes.revision_for_date( options.bad_date, last=True ) print "Using good rev %s for date %s" % ( options.last_good_revision, options.good_date ) print "Using bad rev %s for date %s" % ( options.first_bad_revision, options.bad_date )
class InboundInfoFetcher(InfoFetcher): def __init__(self, fetch_config): InfoFetcher.__init__(self, fetch_config) options = fetch_config.tk_options() self.index = taskcluster.client.Index(options) self.queue = taskcluster.Queue(options) self.jpushes = JsonPushes(branch=fetch_config.inbound_branch) def _check_changeset(self, changeset): # return the full changeset return self.jpushes.pushlog_for_change(changeset)['changesets'][-1] def find_build_info(self, changeset, fetch_txt_info=True, check_changeset=False): """ Find build info for an inbound build, given a changeset or a date. if `check_changeset` is True, the given changeset might be partial (< 40 chars) because it will be verified and updated using json pushes. Return a :class:`InboundBuildInfo` instance. """ if is_date_or_datetime(changeset): changeset = self.jpushes.revision_for_date(changeset) check_changeset = False # find a task id if check_changeset: try: changeset = self._check_changeset(changeset) except MozRegressionError, exc: raise BuildInfoNotFound(str(exc)) tk_route = self.fetch_config.tk_inbound_route(changeset) LOG.debug('using taskcluster route %r' % tk_route) try: task_id = self.index.findTask(tk_route)['taskId'] except TaskclusterFailure: # HACK because of # https://bugzilla.mozilla.org/show_bug.cgi?id=1199618 # and https://bugzilla.mozilla.org/show_bug.cgi?id=1211251 # TODO remove the if statement once these tasks no longer exists # (just raise BuildInfoNotFound) err = True if self.fetch_config.app_name in ('firefox', 'fennec', 'fennec-2.3'): err = False try: tk_route = tk_route.replace(changeset, changeset[:12]) task_id = self.index.findTask(tk_route)['taskId'] except TaskclusterFailure: err = True if err: raise BuildInfoNotFound("Unable to find build info using the" " taskcluster route %r" % tk_route) # find a completed run for that task run_id, build_date = None, None status = self.queue.status(task_id)['status'] for run in reversed(status['runs']): if run['state'] == 'completed': run_id = run['runId'] build_date = datetime.strptime(run["resolved"], '%Y-%m-%dT%H:%M:%S.%fZ') break if run_id is None: raise BuildInfoNotFound( "Unable to find completed runs for task %s" % task_id) artifacts = self.queue.listArtifacts(task_id, run_id)['artifacts'] # look over the artifacts of that run build_url = None for a in artifacts: name = os.path.basename(a['name']) if self.build_regex.search(name): meth = self.queue.buildUrl if self.fetch_config.tk_needs_auth(): meth = self.queue.buildSignedUrl build_url = meth('getArtifact', task_id, run_id, a['name']) break if build_url is None: raise BuildInfoNotFound("unable to find a build url for the" " changeset %r" % changeset) return InboundBuildInfo( self.fetch_config, build_url=build_url, build_date=build_date, changeset=changeset, repo_url=self.jpushes.repo_url(), task_id=task_id, )
class InboundInfoFetcher(InfoFetcher): def __init__(self, fetch_config): InfoFetcher.__init__(self, fetch_config) options = fetch_config.tk_options() self.index = taskcluster.client.Index(options) self.queue = taskcluster.Queue(options) self.jpushes = JsonPushes(branch=fetch_config.inbound_branch) def _check_changeset(self, changeset): # return the full changeset return self.jpushes.pushlog_for_change(changeset)['changesets'][-1] def find_build_info(self, changeset, fetch_txt_info=True, check_changeset=False): """ Find build info for an inbound build, given a changeset or a date. if `check_changeset` is True, the given changeset might be partial (< 40 chars) because it will be verified and updated using json pushes. Return a :class:`InboundBuildInfo` instance. """ if is_date_or_datetime(changeset): changeset = self.jpushes.revision_for_date(changeset) check_changeset = False # find a task id if check_changeset: try: changeset = self._check_changeset(changeset) except MozRegressionError, exc: raise BuildInfoNotFound(str(exc)) tk_route = self.fetch_config.tk_inbound_route(changeset) self._logger.debug('using taskcluster route %r' % tk_route) try: task_id = self.index.findTask(tk_route)['taskId'] except TaskclusterFailure: # HACK because of # https://bugzilla.mozilla.org/show_bug.cgi?id=1199618 # and https://bugzilla.mozilla.org/show_bug.cgi?id=1211251 # TODO remove the if statement once these tasks no longer exists # (just raise BuildInfoNotFound) err = True if self.fetch_config.app_name in ('firefox', 'fennec', 'fennec-2.3'): err = False try: tk_route = tk_route.replace(changeset, changeset[:12]) task_id = self.index.findTask(tk_route)['taskId'] except TaskclusterFailure: err = True if err: raise BuildInfoNotFound("Unable to find build info using the" " taskcluster route %r" % tk_route) # find a completed run for that task run_id, build_date = None, None status = self.queue.status(task_id)['status'] for run in reversed(status['runs']): if run['state'] == 'completed': run_id = run['runId'] build_date = datetime.strptime(run["resolved"], '%Y-%m-%dT%H:%M:%S.%fZ') break if run_id is None: raise BuildInfoNotFound("Unable to find completed runs for task %s" % task_id) artifacts = self.queue.listArtifacts(task_id, run_id)['artifacts'] # look over the artifacts of that run build_url = None for a in artifacts: name = os.path.basename(a['name']) if self.build_regex.search(name): meth = self.queue.buildUrl if self.fetch_config.tk_needs_auth(): meth = self.queue.buildSignedUrl build_url = meth( 'getArtifact', task_id, run_id, a['name'] ) break if build_url is None: raise BuildInfoNotFound("unable to find a build url for the" " changeset %r" % changeset) return InboundBuildInfo( self.fetch_config, build_url=build_url, build_date=build_date, changeset=changeset, repo_url=self.jpushes.repo_url(), task_id=task_id, )