Пример #1
0
    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
Пример #2
0
    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")
Пример #3
0
    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)
Пример #4
0
    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()]
Пример #5
0
    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")
Пример #6
0
    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")
Пример #7
0
    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")
Пример #8
0
    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
Пример #9
0
 def run_incomplete(self, **context):
     raise ContractNotFilled(self.name, "incomplete", "testing")