def generate_tc_graph_from_builders(builders, repo_name, revision):
    """ Return TC graph based on a list of builders.

    :param builders: List of builder names
    :type builders: list
    :param repo_name: push revision
    :type repo_name: str
    :param revision: push revision
    :type revision: str
    :return: TC graph
    :rtype: dict

    """
    return generate_task_graph(
        scopes=[
            # This is needed to define tasks which take advantage of the BBB
            'queue:define-task:buildbot-bridge/buildbot-bridge',
        ],
        tasks=_generate_tc_tasks_from_builders(
            builders=builders,
            repo_name=repo_name,
            revision=revision
        ),
        metadata=generate_metadata(
            repo_name=repo_name,
            revision=revision,
            name='Mozci BBB graph'
        )
    )
Example #2
0
    def test_metadata_contains_matches_name(self,
                                            query_repo_url,
                                            query_push_by_revision):
        ''' We want to test that the builder will show up in the name of the metadata.

        This helps when we look at tasks when inspecting a graph scheduled via BBB.
        See https://github.com/mozilla/mozilla_ci_tools/issues/444 for details.
        '''
        query_repo_url.return_value = self.repo_url
        query_push_by_revision.return_value = self.push_info

        builder = 'Platform1 try leak test build'
        metadata = {
            'name': builder,
            'description': 'Task graph generated via Mozilla CI tools',
            'owner': self.push_info.user,
            'source': u'%s/rev/%s' % (self.repo_url, self.revision)
        }

        self.assertEquals(
            generate_metadata(
                repo_name=self.repo_name,
                revision=self.revision,
                name=builder
            ),
            metadata
        )
def trigger_builders_based_on_task_id(repo_name, revision, task_id, builders,
                                      *args, **kwargs):
    """ Create a graph of tasks which will use a TC task as their parent task.

    :param repo_name The name of a repository e.g. mozilla-inbound
    :type repo_name: str
    :param revision: push revision
    :type revision: str
    :returns: Result of scheduling a TC graph
    :rtype: dict

    """
    if not builders:
        return None

    if type(builders) != list:
        raise MozciError("builders must be a list")

    # If the task_id is of a task which is running we want to extend the graph
    # instead of submitting an independent one
    task = get_task(task_id)
    task_graph_id = task['taskGroupId']
    state = get_task_graph_status(task_graph_id)
    builders_graph, _ = buildbot_graph_builder(builders, revision)

    if state == "running":
        required_task_ids = [task_id]
    else:
        required_task_ids = []

    task_graph = generate_task_graph(
        scopes=[
            # This is needed to define tasks which take advantage of the BBB
            'queue:define-task:buildbot-bridge/buildbot-bridge',
        ],
        tasks=_generate_tasks(
            repo_name=repo_name,
            revision=revision,
            builders_graph=builders_graph,
            # This points to which parent to grab artifacts from
            parent_task_id=task_id,
            # This creates dependencies on other tasks
            required_task_ids=required_task_ids,
        ),
        metadata=generate_metadata(
            repo_name=repo_name,
            revision=revision,
            name='Mozci BBB graph'
        )
    )

    if state == "running":
        result = extend_task_graph(task_graph_id, task_graph)
    else:
        result = schedule_graph(task_graph, *args, **kwargs)

    LOG.info("Result from scheduling: %s" % result)
    return result
def trigger_builders_based_on_task_id(repo_name, revision, task_id, builders,
                                      *args, **kwargs):
    """ Create a graph of tasks which will use a TC task as their parent task.

    :param repo_name The name of a repository e.g. mozilla-inbound
    :type repo_name: str
    :param revision: push revision
    :type revision: str
    :returns: Result of scheduling a TC graph
    :rtype: dict

    """
    if not builders:
        return None

    if type(builders) != list:
        raise MozciError("builders must be a list")

    # If the task_id is of a task which is running we want to extend the graph
    # instead of submitting an independent one
    task = get_task(task_id)
    task_graph_id = task['taskGroupId']
    state = get_task_graph_status(task_graph_id)
    builders_graph, _ = buildbot_graph_builder(builders, revision)

    if state == "running":
        required_task_ids = [task_id]
    else:
        required_task_ids = []

    task_graph = generate_task_graph(
        scopes=[
            # This is needed to define tasks which take advantage of the BBB
            'queue:define-task:buildbot-bridge/buildbot-bridge',
        ],
        tasks=_generate_tasks(
            repo_name=repo_name,
            revision=revision,
            builders_graph=builders_graph,
            # This points to which parent to grab artifacts from
            parent_task_id=task_id,
            # This creates dependencies on other tasks
            required_task_ids=required_task_ids,
        ),
        metadata=generate_metadata(repo_name=repo_name,
                                   revision=revision,
                                   name='Mozci BBB graph'))

    if state == "running":
        result = extend_task_graph(task_graph_id, task_graph)
    else:
        result = schedule_graph(task_graph, *args, **kwargs)

    LOG.info("Result from scheduling: %s" % result)
    return result
def generate_builders_tc_graph(repo_name, revision, builders_graph, *args, **kwargs):
    """Return TaskCluster graph based on builders_graph.

    NOTE: We currently only support depending on one single parent.

    :param repo_name The name of a repository e.g. mozilla-inbound
    :type repo_name: str
    :param revision: push revision
    :type revision: str
    :param builders_graph:
        It is a graph made up of a dictionary where each
        key is a Buildbot buildername. The value for each key is either None
        or another graph of dependent builders.
    :type builders_graph: dict
    :returns: return None or a valid taskcluster task graph.
    :rtype: dict

    """
    LOG.debug("Generating TaskCluster BBB graph...")
    if builders_graph is None:
        return None

    metadata = kwargs.get('metadata')
    if metadata is None:
        metadata = generate_metadata(repo_name=repo_name,
                                     revision=revision,
                                     name='Mozci BBB graph')
    # This is the initial task graph which we're defining
    task_graph = generate_task_graph(
        scopes=[
            # This is needed to define tasks which take advantage of the BBB
            'queue:define-task:buildbot-bridge/buildbot-bridge',
        ],
        tasks=_generate_tasks(
            repo_name=repo_name,
            revision=revision,
            builders_graph=builders_graph,
            metadata=metadata,
        ),
        metadata=metadata
    )

    return task_graph
def generate_builders_tc_graph(repo_name, revision, builders_graph, *args,
                               **kwargs):
    """Return TaskCluster graph based on builders_graph.

    NOTE: We currently only support depending on one single parent.

    :param repo_name The name of a repository e.g. mozilla-inbound
    :type repo_name: str
    :param revision: push revision
    :type revision: str
    :param builders_graph:
        It is a graph made up of a dictionary where each
        key is a Buildbot buildername. The value for each key is either None
        or another graph of dependent builders.
    :type builders_graph: dict
    :returns: return None or a valid taskcluster task graph.
    :rtype: dict

    """
    LOG.debug("Generating TaskCluster BBB graph...")
    if builders_graph is None:
        return None

    metadata = kwargs.get('metadata')
    if metadata is None:
        metadata = generate_metadata(repo_name=repo_name,
                                     revision=revision,
                                     name='Mozci BBB graph')
    # This is the initial task graph which we're defining
    task_graph = generate_task_graph(
        scopes=[
            # This is needed to define tasks which take advantage of the BBB
            'queue:define-task:buildbot-bridge/buildbot-bridge',
        ],
        tasks=_generate_tasks(
            repo_name=repo_name,
            revision=revision,
            builders_graph=builders_graph,
            metadata=metadata,
        ),
        metadata=metadata)

    return task_graph
    def test_metadata_contains_matches_name(self, query_repo_url,
                                            query_push_by_revision):
        ''' We want to test that the builder will show up in the name of the metadata.

        This helps when we look at tasks when inspecting a graph scheduled via BBB.
        See https://github.com/mozilla/mozilla_ci_tools/issues/444 for details.
        '''
        query_repo_url.return_value = self.repo_url
        query_push_by_revision.return_value = self.push_info

        builder = 'Platform1 mozilla-central leak test build'
        metadata = {
            'name': builder,
            'description': 'Task graph generated via Mozilla CI tools',
            'owner': self.push_info.user,
            'source': u'%s/rev/%s' % (self.repo_url, self.revision)
        }

        self.assertEquals(
            generate_metadata(repo_name=self.repo_name,
                              revision=self.revision,
                              name=builder), metadata)
def generate_tc_graph_from_builders(builders, repo_name, revision):
    """ Return TC graph based on a list of builders.

    :param builders: List of builder names
    :type builders: list
    :param repo_name: push revision
    :type repo_name: str
    :param revision: push revision
    :type revision: str
    :return: TC graph
    :rtype: dict

    """
    return generate_task_graph(
        scopes=[
            # This is needed to define tasks which take advantage of the BBB
            'queue:define-task:buildbot-bridge/buildbot-bridge',
        ],
        tasks=_generate_tc_tasks_from_builders(builders=builders,
                                               repo_name=repo_name,
                                               revision=revision),
        metadata=generate_metadata(repo_name=repo_name,
                                   revision=revision,
                                   name='Mozci BBB graph'))
def _create_task(buildername, repo_name, revision, metadata=None, task_graph_id=None,
                 parent_task_id=None, requires=None, properties={}, *args, **kwargs):
    """Return takcluster task to trigger a buildbot builder.

    This function creates a generic task with the minimum amount of
    information required for the buildbot-bridge to consider it valid.
    You can establish a list dependencies to other tasks through the requires
    field.

    :param buildername: The name of a buildbot builder.
    :type buildername: str
    :param repo_name: The name of a repository e.g. mozilla-inbound
    :type repo_name: str
    :param revision: Changeset ID of a revision.
    :type revision: str
    :param metadata: Metadata for the task. If not specified, generate it.
    :type metadata: json
    :param task_graph_id: TC graph id to which this task belongs to
    :type task_graph_id: str
    :param parent_task_id: Task from which to find artifacts. It is not a dependency.
    :type parent_task_id: str
    :param requires: List of taskIds of other tasks which this task depends on.
    :type requires: list
    :returns: TaskCluster graph
    :rtype: dict

    """
    if not valid_builder(buildername):
        raise MozciError("The builder '%s' is not a valid one." % buildername)

    builder_info = get_buildername_metadata(buildername)
    if builder_info['repo_name'] != repo_name:
        raise MozciError(
            "The builder '%s' should be for repo: %s." % (buildername, repo_name)
        )

    repo_url = query_repo_url(repo_name)
    push_info = query_push_by_revision(repo_url=repo_url, revision=revision)
    full_revision = str(push_info.changesets[0].node)

    # Needed because of bug 1195751
    all_properties = {
        'product': builder_info['product'],
        'who': push_info.user,
    }
    all_properties.update(properties)

    all_properties.update(get_builder_extra_properties(buildername))

    metadata = metadata if metadata is not None else \
        generate_metadata(repo_name=repo_name,
                          revision=revision,
                          name=buildername)

    # The task's name is used in the task-graph-inspector to list all tasks
    # and using the buildername makes it easy for a person to recognize each job.
    metadata['name'] = buildername

    # XXX: We should validate that the parent task is a valid parent platform
    #      e.g. do not schedule Windows tests against Linux builds
    task = create_task(
        repo_name=repo_name,
        revision=revision,
        taskGroupId=task_graph_id,
        workerType='buildbot-bridge',
        provisionerId='buildbot-bridge',
        payload={
            'buildername': buildername,
            'sourcestamp': {
                'branch': repo_name,
                'revision': full_revision
            },
            'properties': all_properties,
        },
        metadata=metadata,
    )

    if requires:
        task['requires'] = requires

    # Setting a parent_task_id as a property allows Mozharness to
    # determine the artifacts we need for this job to run properly
    if parent_task_id:
        task['task']['payload']['properties']['parent_task_id'] = parent_task_id

    return task
Example #10
0
def _create_task(buildername,
                 repo_name,
                 revision,
                 metadata=None,
                 task_graph_id=None,
                 parent_task_id=None,
                 requires=None,
                 properties={},
                 *args,
                 **kwargs):
    """Return takcluster task to trigger a buildbot builder.

    This function creates a generic task with the minimum amount of
    information required for the buildbot-bridge to consider it valid.
    You can establish a list dependencies to other tasks through the requires
    field.

    :param buildername: The name of a buildbot builder.
    :type buildername: str
    :param repo_name: The name of a repository e.g. mozilla-inbound
    :type repo_name: str
    :param revision: Changeset ID of a revision.
    :type revision: str
    :param metadata: Metadata for the task. If not specified, generate it.
    :type metadata: json
    :param task_graph_id: TC graph id to which this task belongs to
    :type task_graph_id: str
    :param parent_task_id: Task from which to find artifacts. It is not a dependency.
    :type parent_task_id: str
    :param requires: List of taskIds of other tasks which this task depends on.
    :type requires: list
    :returns: TaskCluster graph
    :rtype: dict

    """
    if not valid_builder(buildername):
        raise MozciError("The builder '%s' is not a valid one." % buildername)

    builder_info = get_buildername_metadata(buildername)
    if builder_info['repo_name'] != repo_name:
        raise MozciError("The builder '%s' should be for repo: %s." %
                         (buildername, repo_name))

    repo_url = query_repo_url(repo_name)
    push_info = query_push_by_revision(repo_url=repo_url, revision=revision)
    full_revision = str(push_info.changesets[0].node)

    # Needed because of bug 1195751
    all_properties = {
        'product': builder_info['product'],
        'who': push_info.user,
    }
    all_properties.update(properties)

    all_properties.update(get_builder_extra_properties(buildername))

    metadata = metadata if metadata is not None else \
        generate_metadata(repo_name=repo_name,
                          revision=revision,
                          name=buildername)

    # The task's name is used in the task-graph-inspector to list all tasks
    # and using the buildername makes it easy for a person to recognize each job.
    metadata['name'] = buildername

    # XXX: We should validate that the parent task is a valid parent platform
    #      e.g. do not schedule Windows tests against Linux builds
    task = create_task(
        repo_name=repo_name,
        revision=revision,
        taskGroupId=task_graph_id,
        workerType='buildbot-bridge',
        provisionerId='buildbot-bridge',
        payload={
            'buildername': buildername,
            'sourcestamp': {
                'branch': repo_name,
                'revision': full_revision
            },
            'properties': all_properties,
        },
        metadata=metadata,
    )

    if requires:
        task['requires'] = requires

    # Setting a parent_task_id as a property allows Mozharness to
    # determine the artifacts we need for this job to run properly
    if parent_task_id:
        task['task']['payload']['properties'][
            'parent_task_id'] = parent_task_id

    return task