def run_push_test_selection_data(self, branch, rev): task_name = f"gecko.v2.{branch}.revision.{rev}.taskgraph.decision" try: decision_task_id = taskcluster.find_task_id(task_name) except requests.exceptions.HTTPError as e: # If the decision task was not indexed, it means it was broken. So we can # assume we didn't run any task for this push. if e.response.status_code == 404: logger.warning(f"Decision task broken in {rev} on {branch}") raise ContractNotFilled( self.name, "push_test_selection_data", f"could not retrieve decision task '{task_name}'", ) try: results = taskcluster.get_artifact( decision_task_id, "public/bugbug-push-schedules.json") except requests.exceptions.HTTPError: raise ContractNotFilled( self.name, "push_test_selection_data", "could not retrieve schedules from cache", ) return results
def run_push_existing_classification(self, branch, rev, environment): # Non-production environments are exposed in sub routes route_prefix = ("project.mozci.classification" if environment == "production" else f"project.mozci.{environment}.classification") try: # Proxy authentication does not seem to work here index = Index( {"rootUrl": taskcluster.COMMUNITY_TASKCLUSTER_ROOT_URL}) response = index.findArtifactFromTask( f"{route_prefix}.{branch}.revision.{rev}", "public/classification.json", ) except TaskclusterRestFailure as e: raise ContractNotFilled( self.name, "push_existing_classification", f"Failed to load existing classification for {branch} {rev}: {e}", ) try: return response["push"]["classification"] except KeyError: raise ContractNotFilled(self.name, "push_existing_classification", "Invalid classification data")
def get_push_test_groups(self, branch, rev) -> Dict[str, List[str]]: if not Push: raise ContractNotFilled(self.name, "push_test_groups", "could not import Push model") push = Push.objects.get(repository__name=branch, revision=rev) return get_group_results(push)
def run_push_tasks(self, branch, rev): keys = ("id", "label", "result", "duration", "tags", "state") if not Job: raise ContractNotFilled(self.name, "push_tasks", "could not import Job model") tasks = self._get_tasks(branch, rev) return [{ key: task_data[key] for key in keys if not (key == "result" and task_data[key] == "unknown") } for task_id, task_data in tasks.items()]
def run_push_existing_classification(self, branch, rev, environment): # Non-production environments are exposed in sub routes route_prefix = ("project.mozci.classification" if environment == "production" else f"project.mozci.{environment}.classification") # We use buildUrl and manual requests.get instead of directly findArtifactFromTask from the taskcluster library # because the taskcluster library fails with redirects (https://github.com/taskcluster/taskcluster/issues/4998). try: # Proxy authentication does not seem to work here index = Index( {"rootUrl": taskcluster.COMMUNITY_TASKCLUSTER_ROOT_URL}) url = index.buildUrl( "findArtifactFromTask", f"{route_prefix}.{branch}.revision.{rev}", "public/classification.json", ) except TaskclusterRestFailure as e: raise ContractNotFilled( self.name, "push_existing_classification", f"Failed to load existing classification for {branch} {rev}: {e}", ) try: r = requests.get(url, allow_redirects=True) r.raise_for_status() except requests.exceptions.HTTPError as e: raise ContractNotFilled( self.name, "push_existing_classification", f"Failed to load existing classification for {branch} {rev}: {e}", ) try: return r.json()["push"]["classification"] except KeyError: raise ContractNotFilled(self.name, "push_existing_classification", "Invalid classification data")
def run_test_task_groups(self, branch, rev, task): # Use a lock since push.py invokes this across many threads (which is # useful for the 'errorsummary' data source, but not here). This ensures # we don't make more than one request to Treeherder. with self.lock: if task.id not in self.groups_cache: self.groups_cache.update(self.get_push_test_groups( branch, rev)) try: return self.groups_cache.pop(task.id) except KeyError: raise ContractNotFilled(self.name, "test_task_groups", "groups are missing")
def run_test_task_groups(self, branch, rev, task): # Use a lock since push.py invokes this across many threads (which is # useful for the 'errorsummary' data source, but not here). This ensures # we don't make more than one request to Treeherder. with self.lock: if task.id not in self.groups_cache: self.groups_cache.update(self.get_push_test_groups( branch, rev)) try: # TODO: Once https://github.com/mozilla/mozci/issues/662 is fixed, we should return the actual duration instead of None. return { group: (status, None) for group, status in self.groups_cache.pop(task.id).items() } except KeyError: raise ContractNotFilled(self.name, "test_task_groups", "groups are missing")
def run_push_tasks_classifications(self, branch, rev): if not Job: raise ContractNotFilled(self.name, "push_tasks_classifications", "could not import Job model") tasks = self._get_tasks(branch, rev) result = {} for task_id, task_data in tasks.items(): result[task_id] = { "classification": task_data["classification"], } if task_data.get("classification_note"): result[task_id]["classification_note"] = task_data[ "classification_note"] return result
def run_incomplete(self, **context): raise ContractNotFilled(self.name, "incomplete", "testing")