예제 #1
0
 def test_valid(self, fetch_allthethings_data):
     """Test if the function finds the right builder."""
     fetch_allthethings_data.return_value = ALLTHETHINGS
     assert determine_upstream_builder(
         'Windows 7 VM 32-bit try opt test mochitest-1') == 'WINNT 5.2 try build'
     assert determine_upstream_builder(
         'Windows 7 VM 32-bit try debug test mochitest-1') == 'WINNT 5.2 try leak test build'
     assert determine_upstream_builder(
         'Windows 7 32-bit mozilla-beta pgo talos tp5o') == 'WINNT 5.2 mozilla-beta build'
 def test_invalid(self, fetch_allthethings_data):
     """Raises Exception for buildernames not in allthethings.json."""
     fetch_allthethings_data.return_value = MOCK_ALLTHETHINGS
     with pytest.raises(Exception):
         determine_upstream_builder("Not a valid buildername")
     # Since "Platform1 mozilla-beta pgo talos tp5o" exists,
     # "Platform1 mozilla-beta talos tp5o" is an invalid buildername
     # and should return None
     self.assertEquals(
         determine_upstream_builder("Platform1 mozilla-beta talos tp5o"), None)
예제 #3
0
 def test_invalid(self, fetch_allthethings_data):
     """Raises Exception for buildernames not in allthethings.json."""
     fetch_allthethings_data.return_value = MOCK_ALLTHETHINGS
     with pytest.raises(Exception):
         determine_upstream_builder("Not a valid buildername")
     # Since "Platform1 mozilla-beta pgo talos tp5o" exists,
     # "Platform1 mozilla-beta talos tp5o" is an invalid buildername
     # and should return None
     self.assertEquals(
         determine_upstream_builder("Platform1 mozilla-beta talos tp5o"),
         None)
예제 #4
0
 def test_valid(self, fetch_allthethings_data):
     """Test if the function finds the right builder."""
     fetch_allthethings_data.return_value = ALLTHETHINGS
     assert determine_upstream_builder(
         'Windows 7 VM 32-bit try opt test mochitest-1'
     ) == 'WINNT 5.2 try build'
     assert determine_upstream_builder(
         'Windows 7 VM 32-bit try debug test mochitest-1'
     ) == 'WINNT 5.2 try leak test build'
     assert determine_upstream_builder(
         'Windows 7 32-bit mozilla-beta pgo talos tp5o-e10s'
     ) == 'WINNT 5.2 mozilla-beta build'
예제 #5
0
def generate_builders_relations_dictionary():
    """Create a dictionary that maps every upstream job to its downstream jobs."""
    builders = list_builders()
    relations = collections.defaultdict(list)
    for buildername in builders:
        if is_downstream(buildername):
            relations[determine_upstream_builder(buildername)].append(buildername)
    return relations
 def test_valid(self, fetch_allthethings_data):
     """Test if the function finds the right builder."""
     fetch_allthethings_data.return_value = MOCK_ALLTHETHINGS
     self.assertEquals(
         determine_upstream_builder('Platform1 repo opt test mochitest-1'),
         'Platform1 repo build')
     self.assertEquals(
         determine_upstream_builder('Platform1 repo debug test mochitest-1'),
         'Platform1 repo leak test build')
     self.assertEquals(
         determine_upstream_builder('Platform1 mozilla-beta pgo talos tp5o'),
         'Platform1 mozilla-beta build')
     # Since "Platform2 mozilla-beta pgo talos tp5o" does not exist,
     # "Platform2 mozilla-beta talos tp5o" is a valid buildername
     self.assertEquals(
         determine_upstream_builder('Platform2 mozilla-beta talos tp5o'),
         'Platform2 mozilla-beta build')
예제 #7
0
 def test_valid(self, fetch_allthethings_data):
     """Test if the function finds the right builder."""
     fetch_allthethings_data.return_value = MOCK_ALLTHETHINGS
     self.assertEquals(
         determine_upstream_builder('Platform1 repo opt test mochitest-1'),
         'Platform1 repo build')
     self.assertEquals(
         determine_upstream_builder(
             'Platform1 repo debug test mochitest-1'),
         'Platform1 repo leak test build')
     self.assertEquals(
         determine_upstream_builder(
             'Platform1 mozilla-beta pgo talos tp5o'),
         'Platform1 mozilla-beta build')
     # Since "Platform2 mozilla-beta pgo talos tp5o" does not exist,
     # "Platform2 mozilla-beta talos tp5o" is a valid buildername
     self.assertEquals(
         determine_upstream_builder('Platform2 mozilla-beta talos tp5o'),
         'Platform2 mozilla-beta build')
예제 #8
0
def main():
    orphan_builders = []

    for builder in sorted(query_builders()):
        # To be fixed in issue 124
        if "l10n" in builder or "nightly" in builder:
            continue
        try:
            if determine_upstream_builder(builder) is None:
                orphan_builders.append(builder)
        except:
            orphan_builders.append(builder)

    for x in sorted(orphan_builders):
        print x
def main():
    orphan_builders = []

    for builder in sorted(query_builders()):
        # To be fixed in issue 124
        if "l10n" in builder or "nightly" in builder:
            continue
        try:
            if determine_upstream_builder(builder) is None:
                orphan_builders.append(builder)
        except:
            orphan_builders.append(builder)

    for x in sorted(orphan_builders):
        print x
예제 #10
0
def test_no_testers_without_builders():
    # We need to assert that allthethings.json has been generated
    # before running this test rather than fetching the one from the server
    # This is important as we want to test against the latest list of builders
    assert os.path.exists("allthethings.json")

    orphan_builders = []

    j = fetch_allthethings_data(verify=False)
    builders = j["builders"].keys()
    assert builders is not None, "The list of builders cannot be empty."

    for builder in sorted(builders):
        if determine_upstream_builder(builder) is None:
            orphan_builders.append(builder)

    assert len(orphan_builders) == 0, \
        "There are downstream builders without upstream builders to trigger them."
예제 #11
0
def jobs_per_revision(revision):
    """Generate a json graph of existing and possible jobs."""
    load_relations()
    all_jobs = get_jobs(revision)

    if all_jobs is None:
        return

    upstream_jobs, downtream_jobs = separate_downstream(all_jobs)

    processed_jobs = {}
    processed_jobs["new_builds"] = {"existing": [], "possible": []}

    for build_job in upstream_jobs:
        buildername, status = build_job
        if status == 0:
            processed_jobs[buildername] = {"existing": [], "possible": []}
        else:
            processed_jobs["new_builds"]["existing"].append(buildername)

    for test_job in downtream_jobs:
        buildername = test_job[0]
        upstream = determine_upstream_builder(buildername)
        if upstream in processed_jobs:
            if buildername not in processed_jobs[upstream]["existing"]:
                processed_jobs[upstream]["existing"].append(buildername)

    for build_job in processed_jobs.keys():
        if build_job == "new_builds":
            continue

        existing_downstream = set(processed_jobs[build_job]["existing"])
        possible_downstream = sorted(list(set(UPSTREAM_TO_DOWNSTREAM[build_job]) - existing_downstream))
        processed_jobs[build_job]["possible"] = possible_downstream
        processed_jobs[build_job]["existing"].sort()

    all_build_jobs = get_upstream_buildernames(" try ") + get_upstream_buildernames("_try_")
    for build_job in all_build_jobs:
        if build_job not in processed_jobs.keys() + processed_jobs["new_builds"]["existing"]:
            processed_jobs["new_builds"]["possible"].append(build_job)
    processed_jobs["new_builds"]["possible"].sort()

    return processed_jobs
def test_no_testers_without_builders():
    # We need to assert that allthethings.json has been generated
    # before running this test rather than fetching the one from the server
    # This is important as we want to test against the latest list of builders
    assert os.path.exists("allthethings.json")

    orphan_builders = []

    j = fetch_allthethings_data(verify=False)
    builders = j["builders"].keys()
    assert builders is not None, "The list of builders cannot be empty."

    for builder in sorted(builders):
        # Bug 1330680 - patches to disable bb nightlies on linux32/linux64/android
        # there are talos jobs that don't have associated build jobs as part
        # of tc migration
        if 'talos' in builder and 'Ubuntu HW' in builder:
            return

        if determine_upstream_builder(builder) is None:
            orphan_builders.append(builder)

    assert len(orphan_builders) == 0, \
        "There are downstream builders without upstream builders to trigger them."
예제 #13
0
def determine_trigger_objective(revision,
                                buildername,
                                trigger_build_if_missing=True):
    """
    Determine if we need to trigger any jobs and which job.

    Returns:

    * The name of the builder we need to trigger
    * Files, if needed, to trigger such builder
    """
    builder_to_trigger = None
    files = None
    repo_name = query_repo_name_from_buildername(buildername)

    build_buildername = determine_upstream_builder(buildername)

    if VALIDATE and not valid_builder(build_buildername):
        raise MozciError("Our platforms mapping system has failed.")

    if build_buildername == buildername:
        # For a build job we know that we don't need files to
        # trigger it and it's the build job we want to trigger
        return build_buildername, None

    # Let's figure out which jobs are associated to such revision
    query_api = BuildApi()
    # Let's only look at jobs that match such build_buildername
    build_jobs = query_api.get_matching_jobs(repo_name, revision,
                                             build_buildername)

    # We need to determine if we need to trigger a build job
    # or the test job
    working_job = None
    running_job = None
    failed_job = None

    LOG.debug("List of matching jobs:")
    for job in build_jobs:
        try:
            status = query_api.get_job_status(job)
        except buildjson.BuildjsonException:
            LOG.debug(
                "We have hit bug 1159279 and have to work around it. We will "
                "pretend that we could not reach the files for it.")
            continue

        # Sometimes running jobs have status unknown in buildapi
        if status in (RUNNING, PENDING, UNKNOWN):
            LOG.debug(
                "We found a running/pending build job. We don't search anymore."
            )
            running_job = job
            # We cannot call _find_files for a running job
            continue

        # Having a coalesced build is the same as not having a build available
        if status == COALESCED:
            LOG.debug(
                "The build we found was a coalesced one; this is the same as "
                "non-existant.")
            continue

        # Successful or failed jobs may have the files we need
        files = _find_files(job)

        if files != [] and _all_urls_reachable(files.values()):
            working_job = job
            break
        else:
            LOG.debug("We can't determine the files for this build or "
                      "can't reach them.")
            files = None

        LOG.info("We found a job that finished but it did not "
                 "produced files. status: %d" % status)
        failed_job = job
    # End of for loop

    if working_job:
        # We found a build job with the necessary files. It could be a
        # successful job, a running job that already emitted files or a
        # testfailed job
        LOG.debug(str(working_job))
        LOG.info("We have the necessary files to trigger the downstream job.")
        # We have the files needed to trigger the test job
        builder_to_trigger = buildername

    elif running_job:
        LOG.info(
            "We found a running/pending build job. We will not trigger another one."
        )
        LOG.info(
            "You have to run the script again after the build job is finished to "
            "trigger %s." % buildername)
        builder_to_trigger = None

    elif failed_job:
        LOG.info(
            "The build job %s failed on revision %s without generating the "
            "necessary files. We will not trigger anything." %
            (build_buildername, revision))
        builder_to_trigger = None

    else:
        # We were trying to build a test job, however, we determined
        # that we need an upstream builder instead
        if not trigger_build_if_missing or not _unique_build_request(
                build_buildername, revision):
            # This is a safeguard to prevent triggering a build
            # job multiple times if it is not intentional
            builder_to_trigger = None
            if not trigger_build_if_missing:
                LOG.info(
                    "We would have to triggered build '%s' in order to trigger "
                    "job '%s'. On this mode we will not trigger either." %
                    (build_buildername, buildername))
        else:
            LOG.info("We will trigger 1) "
                     "'%s' instead of 2) '%s'" %
                     (build_buildername, buildername))
            LOG.info("We need to trigger the build job once (1) "
                     "in order to be able to run the test job (2).")
            if repo_name == 'try':
                LOG.info(
                    "You'll need to run the script again after (1) is done to "
                    "trigger (2).")
            else:
                LOG.info(
                    "After (1) is done and if no coalesccing happens the test "
                    "jobs associated with it will be triggered.")
            builder_to_trigger = build_buildername

    if files:
        return builder_to_trigger, files['packageUrl'], files[
            'testPackagesUrl']
    else:
        return builder_to_trigger, None, None
예제 #14
0
def determine_trigger_objective(revision, buildername, trigger_build_if_missing=True,
                                will_use_buildapi=False):
    """
    Determine if we need to trigger any jobs and which job.

    Returns:

    * The name of the builder we need to trigger
    * Files, if needed, to trigger such builder
    """
    builder_to_trigger = None
    files = None
    repo_name = query_repo_name_from_buildername(buildername)

    build_buildername = determine_upstream_builder(buildername)

    if VALIDATE and not valid_builder(build_buildername):
        raise MozciError("Our platforms mapping system has failed.")

    if build_buildername == buildername:
        # For a build job we know that we don't need files to
        # trigger it and it's the build job we want to trigger
        return build_buildername, None, None

    # Let's figure out which jobs are associated to such revision
    query_api = BuildApi()
    # Let's only look at jobs that match such build_buildername
    build_jobs = query_api.get_matching_jobs(repo_name, revision, build_buildername)

    # We need to determine if we need to trigger a build job
    # or the test job
    working_job = None
    running_job = None
    failed_job = None

    LOG.debug("List of matching jobs:")
    for job in build_jobs:
        try:
            status = query_api.get_job_status(job)
        except buildjson.BuildjsonException:
            LOG.debug("We have hit bug 1159279 and have to work around it. We will "
                      "pretend that we could not reach the files for it.")
            continue

        # Sometimes running jobs have status unknown in buildapi
        if status in (RUNNING, PENDING, UNKNOWN):
            LOG.debug("We found a running/pending build job. We don't search anymore.")
            running_job = job
            # We cannot call _find_files for a running job
            continue

        # Having a coalesced build is the same as not having a build available
        if status == COALESCED:
            LOG.debug("The build we found was a coalesced one; this is the same as "
                      "non-existant.")
            continue

        # Successful or failed jobs may have the files we need
        files = _find_files(job)

        if files != [] and _all_urls_reachable(files.values()):
            working_job = job
            break
        else:
            LOG.debug("We can't determine the files for this build or "
                      "can't reach them.")
            files = None

        LOG.info("We found a job that finished but it did not "
                 "produced files. status: %d" % status)
        failed_job = job
    # End of for loop

    if working_job:
        # We found a build job with the necessary files. It could be a
        # successful job, a running job that already emitted files or a
        # testfailed job
        LOG.debug(str(working_job))
        LOG.info("We have the necessary files to trigger the downstream job.")
        # We have the files needed to trigger the test job
        builder_to_trigger = buildername

    elif running_job:
        LOG.info("We found a running/pending build job. We will not trigger another one.")
        LOG.info("You have to run the script again after the build job is finished to "
                 "trigger %s." % buildername)
        builder_to_trigger = None

    elif failed_job:
        LOG.info("The build job %s failed on revision %s without generating the "
                 "necessary files. We will not trigger anything." %
                 (build_buildername, revision))
        builder_to_trigger = None

    else:
        # We were trying to build a test job, however, we determined
        # that we need an upstream builder instead
        if not trigger_build_if_missing or not _unique_build_request(build_buildername, revision):
            # This is a safeguard to prevent triggering a build
            # job multiple times if it is not intentional
            builder_to_trigger = None
            if not trigger_build_if_missing:
                LOG.info("We would have to triggered build '%s' in order to trigger "
                         "job '%s'. On this mode we will not trigger either." %
                         (build_buildername, buildername))
        else:
            if will_use_buildapi:
                LOG.info("We will trigger 1) '%s'" % build_buildername)
                LOG.info("instead of 2) '%s'" % buildername)
                LOG.info("We need to trigger the build job once (1) "
                         "in order to be able to run the test job (2).")
                if repo_name == 'try':
                    LOG.info("You'll need to run the script again after (1) is done to "
                             "trigger (2).")
                else:
                    LOG.info("After (1) is done and if no coalesccing happens the test "
                             "jobs associated with it will be triggered.")
            builder_to_trigger = build_buildername

    if files:
        return builder_to_trigger, files['packageUrl'], files['testsUrl']
    else:
        return builder_to_trigger, None, None
예제 #15
0
def _determine_trigger_objective(revision, buildername):
    """
    Determine if we need to trigger any jobs and which job.

    Returns:

    * The name of the builder we need to trigger
    * Files, if needed, to trigger such builder
    """
    builder_to_trigger = None
    files = None
    repo_name = query_repo_name_from_buildername(buildername)

    build_buildername = determine_upstream_builder(buildername)

    assert valid_builder(build_buildername), \
        "Our platforms mapping system has failed."

    if build_buildername == buildername:
        # For a build job we know that we don't need files to
        # trigger it and it's the build job we want to trigger
        return build_buildername, None

    # Let's figure out which jobs are associated to such revision
    all_jobs = query_jobs(repo_name, revision)
    # Let's only look at jobs that match such build_buildername
    build_jobs = _matching_jobs(build_buildername, all_jobs)

    # We need to determine if we need to trigger a build job
    # or the test job
    successful_job = None
    running_job = None

    LOG.debug("List of matching jobs:")
    for job in build_jobs:
        try:
            status = buildapi.query_job_status(job)
        except buildjson.BuildjsonException:
            LOG.debug("We have hit bug 1159279 and have to work around it. We will pretend that "
                      "we could not reach the files for it.")
            continue

        if status == buildapi.RUNNING:
            LOG.debug("We found a running build job. We don't search anymore.")
            running_job = job
        elif status == buildapi.SUCCESS:
            LOG.debug("We found a successful job. We don't search anymore.")
            files = _find_files(job)

            if files != [] and _all_urls_reachable(files):
                successful_job = job
                break
            else:
                LOG.debug("We can't determine the files for this build or "
                          "can't reach them.")
                files = None
        else:
            LOG.debug("We found a job that finished but its status "
                      "is not successful. status: %d" % status)

    if successful_job:
        # A build job has completed successfully and the files can be reached
        LOG.info("There is a _build_ job that has completed successfully.")
        LOG.debug(str(successful_job))
        LOG.info("We have the necessary files to trigger the downstream job.")
        # We have the files needed to trigger the test job
        builder_to_trigger = buildername
    elif running_job:
        # NOTE: Note that a build might have not finished yet
        # the installer and test.zip might already have been uploaded
        # For now, we will ignore this situation but need to take note of it
        LOG.info("We are waiting for the associated build job to finish.")
        LOG.debug(str(running_job))
        builder_to_trigger = None
    else:
        # We were trying to build a test job, however, we determined
        # that we need an upstream builder instead
        if not _unique_build_request(build_buildername, revision):
            # This is a safeguard to prevent triggering a build
            # job multiple times if it is not intentional
            builder_to_trigger = None
        else:
            LOG.info("We need to trigger the build job (1) in order to be able to run the test job (2)"
                     "which we'll be triggered later")
            LOG.info("We will trigger 1) '%s' instead of 2) '%s'" % (build_buildername, buildername))
            builder_to_trigger = build_buildername

    return builder_to_trigger, files
예제 #16
0
 def test_invalid(self, fetch_allthethings_data):
     fetch_allthethings_data.return_value = ALLTHETHINGS
     with pytest.raises(Exception):
         determine_upstream_builder("Not a valid buildername")
예제 #17
0
def test_has_buildbot_upstream_builder(fetch_allthethings_data):
    fetch_allthethings_data.return_value = ALLTHETHINGS
    assert determine_upstream_builder(
        "Rev7 MacOSX Yosemite 10.10.5 mozilla-esr52 debug test cppunit") == \
        'OS X 10.7 64-bit mozilla-esr52 leak test build'
예제 #18
0
def test_no_buildbot_upstream_builder(fetch_allthethings_data):
    fetch_allthethings_data.return_value = ALLTHETHINGS
    assert determine_upstream_builder(
        "Ubuntu HW 12.04 x64 autoland talos g2-e10s") is None
예제 #19
0
 def test_no_associated_build(self, fetch_allthethings_data):
     # XXX: Should this test instead raise an exception?
     assert determine_upstream_builder(
         'Windows 7 32-bit mozilla-beta talos tp5o-e10s') is None
 def test_invalid(self, fetch_allthethings_data):
     fetch_allthethings_data.return_value = MOCK_ALLTHETHINGS
     with pytest.raises(Exception):
         determine_upstream_builder("Not a valid buildername")
예제 #21
0
 def test_no_associated_build(self, fetch_allthethings_data):
     # XXX: Should this test instead raise an exception?
     assert determine_upstream_builder('Windows 7 32-bit mozilla-beta talos tp5o') is None
예제 #22
0
def _determine_trigger_objective(revision, buildername):
    """
    Determine if we need to trigger any jobs and which job.

    Returns:

    * The name of the builder we need to trigger
    * Files, if needed, to trigger such builder
    """
    builder_to_trigger = None
    files = None
    repo_name = query_repo_name_from_buildername(buildername)

    build_buildername = determine_upstream_builder(buildername)

    assert valid_builder(build_buildername), \
        "Our platforms mapping system has failed."

    if build_buildername == buildername:
        # For a build job we know that we don't need files to
        # trigger it and it's the build job we want to trigger
        return build_buildername, None

    # Let's figure out which jobs are associated to such revision
    all_jobs = query_jobs(repo_name, revision)
    # Let's only look at jobs that match such build_buildername
    build_jobs = _matching_jobs(build_buildername, all_jobs)

    # We need to determine if we need to trigger a build job
    # or the test job
    working_job = None
    running_job = None
    failed_job = None

    LOG.debug("List of matching jobs:")
    for job in build_jobs:
        # Successful, running and failed jobs may have the files we need
        files = _find_files(job)
        if files != [] and _all_urls_reachable(files):
            working_job = job
            break
        else:
            LOG.debug("We can't determine the files for this build or "
                      "can't reach them.")
            files = None

        try:
            status = buildapi.query_job_status(job)
        except buildjson.BuildjsonException:
            LOG.debug("We have hit bug 1159279 and have to work around it. We will pretend that "
                      "we could not reach the files for it.")
            continue

        if status == buildapi.RUNNING:
            LOG.debug("We found a running build job. We don't search anymore.")
            running_job = job

        else:
            LOG.info("We found a job that finished but its status "
                     "is not successful. status: %d" % status)
            failed_job = job

    if working_job:
        # We found a build job with the necessary files. It could be a
        # successful job, a running job that already emitted files or a
        # testfailed job
        LOG.debug(str(working_job))
        LOG.info("We have the necessary files to trigger the downstream job.")
        # We have the files needed to trigger the test job
        builder_to_trigger = buildername
    elif running_job:
        LOG.info("We found a running build job without files. We will not trigger another one. "
                 "You have to run the script again after the build job is finished to trigger %s." %
                 buildername)
        builder_to_trigger = None
    elif failed_job:
        LOG.info("The build job %s failed on revision %s without generating the necessary files. "
                 "We will not trigger anything." % (build_buildername, revision))
        builder_to_trigger = None
    else:
        # We were trying to build a test job, however, we determined
        # that we need an upstream builder instead
        if not _unique_build_request(build_buildername, revision):
            # This is a safeguard to prevent triggering a build
            # job multiple times if it is not intentional
            builder_to_trigger = None
        else:
            LOG.info("We will trigger 1) '%s' instead of 2) '%s'" % (build_buildername, buildername))
            LOG.info("We need to trigger the build job once (1) in order to be able to run the test job (2).")
            if repo_name == 'try':
                LOG.info("You'll need to run the script again after (1) is done to trigger (2).")
            else:
                LOG.info("After (1) is done every test job associated with it will be triggered.")
            builder_to_trigger = build_buildername

    return builder_to_trigger, files
예제 #23
0
 def test_invalid(self, fetch_allthethings_data):
     """Raises Exception for buildernames not in allthethings.json."""
     fetch_allthethings_data.return_value = ALLTHETHINGS
     with pytest.raises(Exception):
         determine_upstream_builder("Not a valid buildername")