예제 #1
0
def get_central_tasks(git_gecko, sync):
    central_commit = sync_commit.GeckoCommit(
        git_gecko,
        git_gecko.merge_base(sync.gecko_commits.head.sha1,
                             env.config["gecko"]["refs"]["central"])[0])
    taskgroup_id, state, result = tc.get_taskgroup_id(
        "mozilla-central", central_commit.canonical_rev)
    if taskgroup_id is None or state != "completed":
        return None

    if result != "success":
        logger.info("mozilla-central decision task has status %s" % result)
        return None

    taskgroup_id = tc.normalize_task_id(taskgroup_id)
    tasks = tc.TaskGroup(taskgroup_id)

    wpt_tasks = tasks.view(tc.is_suite_fn("web-platform-tests"))

    if not wpt_tasks:
        return None

    if not wpt_tasks.is_complete(allow_unscheduled=True):
        return None

    dest = os.path.join(env.config["root"], env.config["paths"]["try_logs"],
                        "central", central_commit.sha1)

    wpt_tasks.download_logs(dest, ["wptreport.json"])

    return wpt_tasks
예제 #2
0
    def tasks(self, force_update=False):
        """Get a list of all the taskcluster tasks for web-platform-tests
        jobs associated with the current try push.

        :param bool force_update: Force the tasks to be refreshed from the
                                  server
        :return: List of tasks
        """
        if not force_update and "tasks" in self._data:
            tasks = tc.TaskGroup(self.taskgroup_id, self._data["tasks"])
        else:
            task_id = tc.normalize_task_id(self.taskgroup_id)
            if task_id != self.taskgroup_id:
                self.taskgroup_id = task_id

            tasks = tc.TaskGroup(self.taskgroup_id)
            tasks.refresh()

        if tasks.view().is_complete(allow_unscheduled=True):
            self._data["tasks"] = tasks.tasks
        return tasks
예제 #3
0
    def tasks(self):
        """Get a list of all the taskcluster tasks for web-platform-tests
        jobs associated with the current try push.

        :return: List of tasks
        """
        task_id = tc.normalize_task_id(self.taskgroup_id)
        if task_id != self.taskgroup_id:
            self.taskgroup_id = task_id

        tasks = tc.TaskGroup(self.taskgroup_id)
        tasks.refresh()

        return TryPushTasks(tasks)
예제 #4
0
    def __call__(self, git_gecko, git_wpt, body):
        sha1 = body["origin"]["revision"]
        task_id = tc.normalize_task_id(body["taskId"])
        state = body["state"]
        result = body["result"]

        try_push = trypush.TryPush.for_commit(git_gecko, sha1)
        if not try_push:
            logger.debug("No try push for SHA1 %s taskId %s" % (sha1, task_id))
            return

        # Enforce the invariant that the taskgroup id is not set until
        # the decision task is complete. This allows us to determine if a
        # try push should have the expected wpt tasks just by checking if
        # this is set
        if state != "completed" or result == "superseded":
            logger.info("Decision task is not yet complete, status %s" %
                        result)
            return

        # If we retrigger, we create a new taskgroup, with id equal to the new task_id.
        # But the retriggered decision task itself is still in the original taskgroup
        if result == "success":
            logger.info("Setting taskgroup id for try push %r to %s" %
                        (try_push, task_id))
            try_push.taskgroup_id = task_id
        elif result in ("fail", "exception"):
            sync = try_push.sync(git_gecko, git_wpt)
            message = (
                "Decision task got status %s for task %s%s" %
                (result, sha1, " PR %s" % sync.pr if sync and sync.pr else ""))
            logger.error(message)
            task = tc.get_task(task_id)
            taskgroup = tc.TaskGroup(task["taskGroupId"])
            if len(
                    taskgroup.view(lambda x: x["metadata"]["name"] ==
                                   "Gecko Decision Task")) > 5:
                try_push.status = "complete"
                try_push.infra_fail = True
                if sync and sync.bug:
                    # TODO this is commenting too frequently on bugs
                    env.bz.comment(
                        sync.bug,
                        "Try push failed: decision task %i returned error" %
                        task_id)
            else:
                client = tc.TaskclusterClient()
                client.retrigger(task_id)
예제 #5
0
def do_download_logs(git_gecko, git_wpt, log_path, taskgroup_id, **kwargs):
    import tc
    import trypush
    import tempfile

    if log_path is None:
        log_path = tempfile.mkdtemp()

    taskgroup_id = tc.normalize_task_id(taskgroup_id)

    tasks = tc.TaskGroup(taskgroup_id)
    tasks.refresh()

    try_tasks = trypush.TryPushTasks(tasks)
    try_tasks.wpt_tasks.download_logs(os.path.join(log_path, taskgroup_id),
                                      ["wptreport.json"])
예제 #6
0
    def notify_failed_builds(self):
        tasks = tc.TaskGroup(self.taskgroup_id).view()
        failed = tasks.failed_builds()

        if not failed:
            logger.error("No failed builds to report for Try push: %s" % self)
            return

        bug = self.bug

        if not bug:
            logger.error("No associated bug found for Try push: %s" % self)
            return

        msg = "There were infrastructure failures for the Try push (%s):\n" % self.treeherder_url
        msg += "\n".join(task.get("task", {}).get("metadata", {}).get("name")
                         for task in failed.tasks)
        env.bz.comment(self.bug, msg)
예제 #7
0
    def __call__(self, git_gecko, git_wpt, body):
        newrelic.agent.set_transaction_name("TaskHandler")
        task_id = body["status"]["taskId"]
        state = body["status"]["state"]

        newrelic.agent.add_custom_parameter("tc_task", task_id)
        newrelic.agent.add_custom_parameter("state", state)

        # Enforce the invariant that the taskgroup id is not set until
        # the decision task is complete. This allows us to determine if a
        # try push should have the expected wpt tasks just by checking if
        # this is set
        if state not in ("completed", "failed", "exception"):
            logger.info("Decision task is not yet complete, status %s" % state)
            return

        task = tc.get_task(task_id)
        sha1 = task.get("payload", {}).get("env", {}).get("GECKO_HEAD_REV")

        if sha1 is None:
            raise ValueError("Failed to get commit sha1 from task message")

        if state == "exception":
            run_id = body.get("runId")
            runs = body.get("status", {}).get("runs", [])
            if 0 <= run_id < len(runs):
                reason = runs[run_id].get("reasonResolved")
                if reason in [
                        "superseded", "claim-expired", "worker-shutdown",
                        "intermittent-task"
                ]:
                    logger.info("Task %s had an exception for reason %s, "
                                "assuming taskcluster will retry" %
                                (task_id, reason))
                    return

        try_push = trypush.TryPush.for_commit(git_gecko, sha1)
        if not try_push:
            logger.debug("No try push for SHA1 %s taskId %s" % (sha1, task_id))
            owner = task.get("metadata", {}).get("owner")
            if owner == "*****@*****.**":
                # This could be a race condition if the decision task completes before this
                # task is in the index
                raise RetryableError(
                    "Got a wptsync task with no corresponding try push")
            return

        with SyncLock.for_process(try_push.process_name) as lock:
            with try_push.as_mut(lock):
                # If we retrigger, we create a new taskgroup, with id equal to the new task_id.
                # But the retriggered decision task itself is still in the original taskgroup
                if state == "completed":
                    logger.info("Setting taskgroup id for try push %r to %s" %
                                (try_push, task_id))
                    try_push.taskgroup_id = task_id
                elif state in ("failed", "exception"):
                    sync = try_push.sync(git_gecko, git_wpt)
                    message = ("Decision task got status %s for task %s%s" %
                               (state, sha1, " PR %s" %
                                sync.pr if sync and sync.pr else ""))
                    logger.error(message)
                    task = tc.get_task(task_id)
                    taskgroup = tc.TaskGroup(task["taskGroupId"])
                    if len(
                            taskgroup.view(lambda x: x["task"]["metadata"][
                                "name"] == "Gecko Decision Task")) > 5:
                        try_push.status = "complete"
                        try_push.infra_fail = True
                        if sync and sync.bug:
                            # TODO this is commenting too frequently on bugs
                            env.bz.comment(
                                sync.bug,
                                "Try push failed: decision task %i returned error"
                                % task_id)
                    else:
                        client = tc.TaskclusterClient()
                        client.retrigger(task_id)