Пример #1
0
def test_new_wpt_pr(env, git_gecko, git_wpt, pull_request, set_pr_status,
                    mock_mach, mock_wpt):
    pr = pull_request([("Test commit", {
        "README": "Example change\n"
    })], "Test PR")

    mock_mach.set_data(
        "file-info", """Testing :: web-platform-tests
  testing/web-platform/tests/README
""")

    mock_wpt.set_data("files-changed", "README\n")

    downstream.new_wpt_pr(git_gecko, git_wpt, pr)
    sync = load.get_pr_sync(git_gecko, git_wpt, pr["number"])
    env.gh_wpt.set_status(pr["number"], "success", "http://test/",
                          "description", "continuous-integration/travis-ci/pr")
    assert sync is not None
    assert sync.status == "open"
    assert len(sync.gecko_commits) == 1
    assert len(sync.wpt_commits) == 1
    assert sync.gecko_commits[0].metadata == {
        "wpt-pr": str(pr["number"]),
        "wpt-commit": pr["head"]
    }
    assert "Creating a bug in component Testing :: web-platform" in env.bz.output.getvalue(
    )
Пример #2
0
def test_metadata_update(env, git_gecko, git_wpt, pull_request, pull_request_commit):
    from conftest import gecko_changes, git_commit
    pr = pull_request([("Test commit", {"README": "Example change\n"})],
                      "Test PR")

    downstream.new_wpt_pr(git_gecko, git_wpt, pr)
    sync = load.get_pr_sync(git_gecko, git_wpt, pr["number"])

    assert len(sync.gecko_commits) == 1

    with SyncLock.for_process(sync.process_name) as lock:
        with sync.as_mut(lock):
            gecko_work = sync.gecko_worktree.get()
            changes = gecko_changes(env, meta_changes={"example.ini": "Example change"})
            git_commit(gecko_work, """Update metadata

        wpt-pr: %s
        wpt-type: metadata
        """ % pr.number, changes)

            assert len(sync.gecko_commits) == 2
            assert sync.gecko_commits[-1].metadata.get("wpt-type") == "metadata"
            metadata_commit = sync.gecko_commits[-1]

            head_sha = pull_request_commit(pr.number,
                                           [("fixup! Test commit",
                                             {"README": "Example change 1\n"})])

            downstream.update_repositories(git_gecko, git_wpt)
            sync.update_commits()
            assert len(sync.gecko_commits) == 3
            assert sync.gecko_commits[-1].metadata.get("wpt-type") == "metadata"
            assert sync.gecko_commits[-1].msg == metadata_commit.msg
            assert sync.gecko_commits[-2].metadata.get("wpt-commit") == head_sha
Пример #3
0
def test_revert_pr(env, git_gecko, git_wpt, git_wpt_upstream, pull_request,
                   pull_request_fn, set_pr_status, wpt_worktree):
    pr = pull_request([("Test commit", {
        "README": "Example change\n"
    })], "Test PR")

    downstream.new_wpt_pr(git_gecko, git_wpt, pr)
    sync = load.get_pr_sync(git_gecko, git_wpt, pr["number"])

    commit = sync.wpt_commits[0]
    sync.wpt_commits.base = sync.data[
        "wpt-base"] = git_wpt_upstream.head.commit.hexsha
    git_wpt_upstream.git.merge(commit.sha1)

    def revert_fn():
        git_wpt.remotes["origin"].fetch()
        wpt_work = wpt_worktree()
        wpt_work.git.revert(commit.sha1, no_edit=True)
        wpt_work.git.push("origin", "HEAD:refs/heads/revert")
        git_wpt_upstream.commit("revert")
        return "revert"

    pr_revert = pull_request_fn(revert_fn, title="Revert Test PR")

    downstream.new_wpt_pr(git_gecko, git_wpt, pr_revert)
    sync_revert = load.get_pr_sync(git_gecko, git_wpt, pr_revert["number"])

    # Refresh the instance data
    sync.data._load()
    assert sync.skip
    assert sync_revert.skip
Пример #4
0
def test_dependent_commit(env, git_gecko, git_wpt, pull_request,
                          upstream_wpt_commit, pull_request_commit):
    upstream_wpt_commit("First change", {"README": "Example change\n"})

    pr = pull_request([("Test change", {
        "README": "Example change 1\n"
    })], "Test PR")

    downstream.new_wpt_pr(git_gecko, git_wpt, pr)
    sync = load.get_pr_sync(git_gecko, git_wpt, pr["number"])

    assert len(sync.gecko_commits) == 2
    assert sync.gecko_commits[0].msg.splitlines()[0] == "First change"
    assert sync.gecko_commits[0].metadata["wpt-type"] == "dependency"
    assert sync.gecko_commits[1].metadata.get("wpt-type") is None
    assert "Test change" in sync.gecko_commits[1].msg.splitlines()[0]
    old_gecko_commits = sync.gecko_commits[:]
    # Check that rerunning doesn't affect anything
    sync.update_commits()
    assert [item.sha1 for item in sync.gecko_commits
            ] == [item.sha1 for item in old_gecko_commits]

    head_sha = pull_request_commit(pr.number, [("fixup! Test change", {
        "README": "Example change 2\n"
    })])
    downstream.update_repositories(git_gecko, git_wpt)
    sync.update_commits()
    assert len(sync.gecko_commits) == 3
    assert ([item.sha1 for item in sync.gecko_commits[:2]
             ] == [item.sha1 for item in old_gecko_commits])
    assert sync.gecko_commits[-1].metadata["wpt-commit"] == head_sha
Пример #5
0
def test_relanding_unchanged_upstreamed_pr(env, git_gecko, git_wpt,
                                           hg_gecko_upstream, pull_request,
                                           upstream_gecko_commit, mock_mach,
                                           set_pr_status, git_wpt_upstream):
    trypush.Mach = mock_mach

    # Create an unrelated PR that didn't come from Gecko
    pr0 = pull_request([(b"Non Gecko PR", {"SOMEFILE": b"Made changes"})])
    unrelated_rev = pr0._commits[0]["sha"]
    downstream.new_wpt_pr(git_gecko, git_wpt, pr0)
    downstream_sync = set_pr_status(pr0.number, 'success')
    git_wpt_upstream.head.commit = unrelated_rev
    git_wpt.remotes.origin.fetch()

    sync = create_and_upstream_gecko_bug(env, git_gecko, git_wpt,
                                         hg_gecko_upstream,
                                         upstream_gecko_commit)

    # 'Merge' this upstream PR
    pr = env.gh_wpt.get_pull(sync.pr)
    pr["user"]["login"] = "******"
    with SyncLock.for_process(sync.process_name) as upstream_sync_lock:
        with sync.as_mut(upstream_sync_lock):
            sync.push_commits()

    assert str(git_wpt_upstream.active_branch) == "master"
    git_wpt_upstream.git.merge('gecko/1234')  # TODO avoid hardcoding?

    # Create a ref on the upstream to simulate the pr than GH would setup
    git_wpt_upstream.create_head(
        'pr/%d' % pr['number'],
        commit=git_wpt_upstream.refs['gecko/1234'].commit.hexsha)
    git_wpt.remotes.origin.fetch()
    pr['merge_commit_sha'] = str(git_wpt_upstream.active_branch.commit.hexsha)
    pr['base'] = {'sha': unrelated_rev}
    env.gh_wpt.commit_prs[pr['merge_commit_sha']] = pr['number']

    # Update landing, the Non Gecko PR should be applied but not the Gecko one we upstreamed
    def mock_create(repo,
                    msg,
                    metadata,
                    author=None,
                    amend=False,
                    allow_empty=False):
        # This commit should not be making it this far, should've been dropped earlier
        assert b'Bug 1234 [wpt PR 2] - [Gecko Bug 1234]' not in msg
        return DEFAULT

    m = Mock(side_effect=mock_create, wraps=sync_commit.Commit.create)
    with patch('sync.commit.Commit.create', m):
        landing_sync = landing.update_landing(git_gecko,
                                              git_wpt,
                                              include_incomplete=True)

    commits = landing_sync.gecko_commits._commits

    # Check that the upstreamed gecko PR didnt get pushed to try
    assert not any([c.bug == sync.bug for c in commits])
    # Check that our unrelated PR got pushed to try
    assert any([c.bug == downstream_sync.bug for c in commits])
Пример #6
0
def test_landing_pr_on_central(env, git_gecko, git_wpt, git_wpt_upstream, pull_request,
                               set_pr_status, upstream_gecko_commit, mock_mach):
    # Ensure we handle the case where a PR already identical changes on central

    trypush.Mach = mock_mach

    test_changes = {"example/test.html": b"Change test\n"}
    more_changes = {"LICENSE": b"Change license\n"}

    for changes in [test_changes, more_changes]:
        pr = pull_request([(b"Test commit", changes)])
        downstream.new_wpt_pr(git_gecko, git_wpt, pr)
        downstream_sync = set_pr_status(pr.number, "success")
        head_rev = pr._commits[0]["sha"]
        git_wpt_upstream.head.commit = head_rev
        git_wpt.remotes.origin.fetch()
        landing.wpt_push(git_gecko, git_wpt, [head_rev], create_missing=False)

        with SyncLock.for_process(downstream_sync.process_name) as downstream_lock:
            with downstream_sync.as_mut(downstream_lock):
                downstream_sync.data["force-metadata-ready"] = True

    # Repeat the changes in m-c
    upstream_gecko_commit(test_changes=test_changes, bug=1234,
                          message=b"Change README")

    tree.is_open = lambda x: True
    sync = landing.update_landing(git_gecko, git_wpt)

    assert len(sync.wpt_commits) == 2
    assert len(sync.gecko_commits) == 3
    assert sync.gecko_commits[0].is_empty()
    assert sync.gecko_commits[-1].is_landing
Пример #7
0
def try_push(env, git_gecko, git_wpt, git_wpt_upstream, pull_request, set_pr_status,
             hg_gecko_try, mock_mach):
    pr = pull_request([(b"Test commit", {"README": b"example_change",
                                         "LICENSE": b"Some change"})])
    head_rev = pr._commits[0]["sha"]

    trypush.Mach = mock_mach
    with patch("sync.tree.is_open", Mock(return_value=True)):
        downstream.new_wpt_pr(git_gecko, git_wpt, pr)
        sync = set_pr_status(pr.number, "success")

        with SyncLock.for_process(sync.process_name) as sync_lock:
            git_wpt_upstream.head.commit = head_rev
            git_wpt.remotes.origin.fetch()
            landing.wpt_push(git_gecko, git_wpt, [head_rev], create_missing=False)

            with sync.as_mut(sync_lock):
                env.gh_wpt.get_pull(sync.pr).merged = True
                sync.data["affected-tests"] = {"Example": "affected"}
                sync.next_try_push()
                sync.data["force-metadata-ready"] = True

            try_push = sync.latest_try_push
            with try_push.as_mut(sync_lock):
                try_push.taskgroup_id = "abcdef"
    return sync.latest_try_push
Пример #8
0
def test_land_commit(env, git_gecko, git_wpt, git_wpt_upstream, pull_request, set_pr_status,
                     hg_gecko_try, mock_mach, mock_tasks):
    pr = pull_request([(b"Test commit", {"README": b"example_change"})])
    head_rev = pr._commits[0]["sha"]

    trypush.Mach = mock_mach

    downstream.new_wpt_pr(git_gecko, git_wpt, pr)
    downstream_sync = set_pr_status(pr.number, "success")

    git_wpt_upstream.head.commit = head_rev
    git_wpt.remotes.origin.fetch()
    landing.wpt_push(git_gecko, git_wpt, [head_rev], create_missing=False)

    with SyncLock.for_process(downstream_sync.process_name) as downstream_lock:
        with downstream_sync.as_mut(downstream_lock):
            downstream_sync.data["force-metadata-ready"] = True

    tree.is_open = lambda x: True
    sync = landing.update_landing(git_gecko, git_wpt)

    assert ("Setting bug %s add_blocks %s" % (sync.bug, downstream_sync.bug)
            in env.bz.output.getvalue())

    try_push = sync.latest_try_push
    with SyncLock.for_process(sync.process_name) as lock:
        with sync.as_mut(lock), try_push.as_mut(lock):
            try_push.taskgroup_id = "abcdef"
            with patch.object(try_push, "download_logs", Mock(return_value=[])):
                with patch.object(tc.TaskGroup, "tasks",
                                  property(Mock(return_value=mock_tasks(completed=["foo"])))):
                    landing.try_push_complete(git_gecko, git_wpt, try_push, sync)

    assert "Pushed to try (stability)" in env.bz.output.getvalue()
    assert try_push.status == "complete"
    assert sync.status == "open"

    try_push = sync.latest_try_push
    with SyncLock.for_process(sync.process_name) as lock:
        with sync.as_mut(lock), try_push.as_mut(lock):
            try_push.taskgroup_id = "abcdef2"
            with patch.object(try_push, "download_logs", Mock(return_value=[])):
                with patch.object(tc.TaskGroup, "tasks",
                                  property(Mock(return_value=mock_tasks(completed=["foo"])))):
                    landing.try_push_complete(git_gecko, git_wpt, try_push, sync)

    new_head = git_gecko.remotes.mozilla.refs["bookmarks/mozilla/autoland"].commit
    assert "Update web-platform-tests to %s" % head_rev in new_head.message
    assert (new_head.tree["testing/web-platform/tests/README"].data_stream.read() ==
            b"example_change")
    sync_point = landing.load_sync_point(git_gecko, git_wpt)
    assert sync_point["upstream"] == head_rev
    # Update central to contain the landing
    git_gecko.refs["mozilla/bookmarks/mozilla/central"].commit = new_head
    with patch("sync.landing.start_next_landing") as start_next_landing:
        landing.gecko_push(git_gecko, git_wpt, "mozilla-central",
                           git_gecko.cinnabar.git2hg(new_head))
        assert start_next_landing.call_count == 1
    assert sync.status == "complete"
Пример #9
0
def test_downstream_move(git_gecko, git_wpt, pull_request, set_pr_status,
                         hg_gecko_try, local_gecko_commit,
                         sample_gecko_metadata, initial_wpt_content, mock_mach):
    local_gecko_commit(message="Add wpt metadata", meta_changes=sample_gecko_metadata)
    pr = pull_request([("Test commit",
                        {"example/test.html": None,
                         "example/test1.html": initial_wpt_content["example/test.html"]})],
                      "Test PR")
    with patch("sync.tree.is_open", Mock(return_value=True)), patch("sync.trypush.Mach", mock_mach):
        downstream.new_wpt_pr(git_gecko, git_wpt, pr)
        sync = set_pr_status(pr, "success")
    assert sync.gecko_commits[-1].metadata["wpt-type"] == "metadata"
Пример #10
0
def test_wpt_pr_status_success(git_gecko, git_wpt, pull_request, set_pr_status,
                               hg_gecko_try, mock_wpt, mock_mach):
    with patch("sync.trypush.Mach", mock_mach):
        mock_wpt.set_data("tests-affected", "")

        pr = pull_request([("Test commit", {"README": "Example change\n"})],
                          "Test PR")
        downstream.new_wpt_pr(git_gecko, git_wpt, pr)
        with patch("sync.tree.is_open", Mock(return_value=True)):
            sync = set_pr_status(pr, "success")
        try_push = sync.latest_try_push
        assert sync.last_pr_check == {"state": "success", "sha": pr.head}
        assert try_push is None  # No Try push for the status check passing.
Пример #11
0
def test_downstream_move(git_gecko, git_wpt, pull_request, set_pr_status,
                         hg_gecko_try, local_gecko_commit,
                         sample_gecko_metadata, initial_wpt_content):
    local_gecko_commit(message="Add wpt metadata",
                       meta_changes=sample_gecko_metadata)
    pr = pull_request(
        [("Test commit", {
            "example/test.html": None,
            "example/test1.html": initial_wpt_content["example/test.html"]
        })], "Test PR")
    downstream.new_wpt_pr(git_gecko, git_wpt, pr)
    sync = set_pr_status(pr, "success")
    assert sync.gecko_commits[-1].metadata["wpt-type"] == "metadata"
Пример #12
0
def test_next_try_push(git_gecko, git_wpt, pull_request, set_pr_status,
                       MockTryCls, hg_gecko_try, pull_request_commit):
    pr = pull_request([("Test commit", {
        "README": "Example change\n"
    })], "Test PR")
    downstream.new_wpt_pr(git_gecko, git_wpt, pr)
    sync = set_pr_status(pr, "success")

    assert sync.next_try_push() is None
    assert sync.metadata_ready is False

    # No affected tests and one try push, means we should be ready
    sync.data["affected-tests"] = []

    assert sync.requires_try
    assert not sync.requires_stability_try

    try_push = trypush.TryPush.create(sync, try_cls=MockTryCls)
    try_push.status = "complete"

    assert try_push.wpt_head == sync.wpt_commits.head.sha1

    assert sync.metadata_ready
    assert sync.next_try_push() is None

    sync.data["affected-tests"] = ["example"]

    assert sync.requires_stability_try
    assert not sync.metadata_ready

    new_try_push = sync.next_try_push(try_cls=MockTryCls)
    assert new_try_push is not None
    assert new_try_push.stability
    assert not sync.metadata_ready

    new_try_push.status = "complete"
    assert sync.metadata_ready
    assert not sync.next_try_push()

    pull_request_commit(pr.number, [("Second test commit", {
        "README": "Another change\n"
    })])
    git_wpt.remotes.origin.fetch()

    sync.update_commits()
    assert sync.latest_try_push is not None
    assert sync.latest_valid_try_push is None
    assert not sync.metadata_ready

    updated_try_push = sync.next_try_push(try_cls=MockTryCls)
    assert not updated_try_push.stability
Пример #13
0
def test_land_try(env, git_gecko, git_wpt, git_wpt_upstream, pull_request,
                  set_pr_status, hg_gecko_try, mock_mach):
    pr = pull_request([(b"Test commit", {
        "README": b"example_change",
        "resources/testdriver_vendor.js": b"Some change"
    })])
    head_rev = pr._commits[0]["sha"]

    trypush.Mach = mock_mach
    downstream.new_wpt_pr(git_gecko, git_wpt, pr)
    sync = set_pr_status(pr.number, "success")

    git_wpt_upstream.head.commit = head_rev
    git_wpt.remotes.origin.fetch()
    landing.wpt_push(git_gecko, git_wpt, [head_rev], create_missing=False)

    with SyncLock.for_process(sync.process_name) as downstream_lock:
        with sync.as_mut(downstream_lock):
            sync.data["force-metadata-ready"] = True

    tree.is_open = lambda x: True
    landing_sync = landing.update_landing(git_gecko, git_wpt)

    assert landing_sync is not None
    with SyncLock("landing", None) as lock:
        with landing_sync.as_mut(lock):
            worktree = landing_sync.gecko_worktree.get()
            # Check that files we shouldn't move aren't
            assert not os.path.exists(
                os.path.join(worktree.working_dir,
                             env.config["gecko"]["path"]["wpt"], ".git"))
            with open(
                    os.path.join(worktree.working_dir,
                                 env.config["gecko"]["path"]["wpt"],
                                 "resources/testdriver_vendor.js"), "rb") as f:
                assert f.read() == b"Initial testdriver_vendor\n"

    try_push = sync.latest_try_push
    assert try_push is None
    mach_command = mock_mach.get_log()[-1]
    assert mach_command["command"] == "mach"
    assert mach_command["args"] == ("try", "fuzzy", "-q",
                                    "web-platform-tests !ccov !shippable",
                                    "-q",
                                    "web-platform-tests linux-32 shippable",
                                    "-q",
                                    "web-platform-tests mac !debug shippable",
                                    "--disable-target-task-filter",
                                    "--artifact")
Пример #14
0
def test_wpt_pr_status_success(git_gecko, git_wpt, pull_request, set_pr_status,
                               hg_gecko_try, mock_wpt):
    mock_wpt.set_data("tests-affected", "")

    pr = pull_request([("Test commit", {
        "README": "Example change\n"
    })], "Test PR")
    downstream.new_wpt_pr(git_gecko, git_wpt, pr)
    sync = set_pr_status(pr, "success")
    try_push = sync.latest_try_push
    assert sync.last_pr_check == {"state": "success", "sha": pr.head}
    assert try_push is not None
    assert try_push.status == "open"
    assert try_push.try_rev == hg_gecko_try.log("-l1", "--template={node}")
    assert try_push.stability is False
Пример #15
0
def test_next_try_push_infra_fail(env, git_gecko, git_wpt, pull_request,
                                  set_pr_status, MockTryCls, hg_gecko_try,
                                  mock_mach, mock_taskgroup):
    taskgroup = mock_taskgroup("taskgroup-complete-build-failed.json")
    try_tasks = trypush.TryPushTasks(taskgroup)

    pr = pull_request([("Test commit", {
        "README": "Example change\n"
    })], "Test PR")
    downstream.new_wpt_pr(git_gecko, git_wpt, pr)

    try_patch = patch("sync.trypush.TryPush.tasks",
                      Mock(return_value=try_tasks))
    tree_open_patch = patch("sync.tree.is_open", Mock(return_value=True))
    taskgroup_patch = patch("sync.tc.TaskGroup", Mock(return_value=taskgroup))
    mach_patch = patch("sync.trypush.Mach", mock_mach)

    with tree_open_patch, try_patch, taskgroup_patch, mach_patch:
        sync = set_pr_status(pr, "success")
        env.gh_wpt.get_pull(sync.pr).merged = True

        with SyncLock.for_process(sync.process_name) as lock:
            with sync.as_mut(lock):
                assert len(sync.try_pushes()) == 0

                sync.data["affected-tests"] = {"testharness": ["example"]}

                try_push = sync.next_try_push(try_cls=MockTryCls)
                with try_push.as_mut(lock):
                    try_push["taskgroup-id"] = taskgroup.taskgroup_id
                    try_push.status = "complete"
                    try_push.infra_fail = True

                # This try push still has completed builds and tests, so we say metadata is ready.
                assert sync.next_action == downstream.DownstreamAction.ready
                assert sync.next_try_push(try_cls=MockTryCls) is None

                # There should be a comment to flag failed builds
                msg = "There were infrastructure failures for the Try push (%s):\nbuild-win32/opt\nbuild-win32/debug\nbuild-win64/opt\nbuild-win64/debug\n" % try_push.treeherder_url  # noqa: E501
                assert msg in env.bz.output.getvalue()

                # Replace the taskgroup with one where there were no completed tests
                taskgroup = mock_taskgroup(
                    "taskgroup-no-tests-build-failed.json")
                try_tasks = trypush.TryPushTasks(taskgroup)

                # The next action should flag for manual fix now
                assert sync.next_action == downstream.DownstreamAction.manual_fix
Пример #16
0
def test_land_commit(env, git_gecko, git_wpt, git_wpt_upstream, pull_request,
                     set_pr_status, hg_gecko_try, mock_mach, mock_tasks):
    pr = pull_request([("Test commit", {"README": "example_change"})])
    head_rev = pr._commits[0]["sha"]

    trypush.Mach = mock_mach

    downstream.new_wpt_pr(git_gecko, git_wpt, pr)
    downstream_sync = set_pr_status(pr, "success")

    git_wpt_upstream.head.commit = head_rev
    git_wpt.remotes.origin.fetch()
    landing.wpt_push(git_gecko, git_wpt, [head_rev], create_missing=False)

    downstream_sync.data["force-metadata-ready"] = True

    tree.is_open = lambda x: True
    sync = landing.update_landing(git_gecko, git_wpt)

    # Set the landing sync point to current central
    sync.last_sync_point(git_gecko, "mozilla-central",
                         env.config["gecko"]["refs"]["central"])

    try_push = sync.latest_try_push
    try_push.taskgroup_id = "abcdef"
    with patch.object(try_push, "download_logs", Mock(return_value=[])):
        with patch.object(
                tc.TaskGroup, "tasks",
                property(Mock(return_value=mock_tasks(completed=["foo"])))):
            landing.try_push_complete(git_gecko, git_wpt, try_push, sync)

    assert sync.status == "open"
    new_head = git_gecko.remotes.mozilla.refs[
        "bookmarks/mozilla/inbound"].commit
    assert "Update web-platform-tests to %s" % head_rev in new_head.message
    assert new_head.tree["testing/web-platform/tests/README"].data_stream.read(
    ) == "example_change"
    sync_point = landing.load_sync_point(git_gecko, git_wpt)
    assert sync_point["local"] == new_head.parents[0].hexsha
    assert sync_point["upstream"] == head_rev
    # Update central to contain the landing
    git_gecko.refs["mozilla/bookmarks/mozilla/central"].commit = new_head
    with patch("sync.landing.tasks.land.apply_async") as mock_apply:
        landing.gecko_push(git_gecko, git_wpt, "mozilla-central",
                           git_gecko.cinnabar.git2hg(new_head))
        assert mock_apply.call_count == 1
    assert sync.status == "complete"
Пример #17
0
def test_github_label_on_error(env, git_gecko, git_wpt, pull_request):
    pr = pull_request([("Testing", {"README": "Example change\n"})], "Test PR")

    downstream.new_wpt_pr(git_gecko, git_wpt, pr)
    sync = load.get_pr_sync(git_gecko, git_wpt, pr["number"])
    with SyncLock.for_process(sync.process_name) as lock:
        with sync.as_mut(lock):
            sync.error = "Infrastructure Failed"

    assert env.gh_wpt.get_pull(
        pr["number"])["labels"] == ["mozilla:gecko-blocked"]

    with SyncLock.for_process(sync.process_name) as lock:
        with sync.as_mut(lock):
            sync.update_commits()

    assert env.gh_wpt.get_pull(pr["number"])["labels"] == []
Пример #18
0
def test_landing_metadata(env, git_gecko, git_wpt, git_wpt_upstream,
                          pull_request, set_pr_status, hg_gecko_try,
                          mock_mach):
    from conftest import create_file_data, gecko_changes

    trypush.Mach = mock_mach

    pr = pull_request([("Test commit", {
        "example/test1.html": "example_change"
    })])
    head_rev = pr._commits[0]["sha"]

    downstream.new_wpt_pr(git_gecko, git_wpt, pr)
    downstream_sync = set_pr_status(pr, "success")

    # Create a metadata commit
    with SyncLock.for_process(downstream_sync.process_name) as downstream_lock:
        with downstream_sync.as_mut(downstream_lock):
            git_work = downstream_sync.gecko_worktree.get()

            changes = gecko_changes(env,
                                    meta_changes={
                                        "example/test1.html":
                                        "[test1.html]\n  expected: FAIL"
                                    })
            file_data, _ = create_file_data(changes, git_work.working_dir)
            downstream_sync.ensure_metadata_commit()
            git_work.index.add(file_data)
            downstream_sync._commit_metadata()

            assert downstream_sync.metadata_commit is not None
            downstream_sync.data["force-metadata-ready"] = True

    git_wpt_upstream.head.commit = head_rev
    git_wpt.remotes.origin.fetch()

    landing.wpt_push(git_gecko, git_wpt, [head_rev], create_missing=False)

    tree.is_open = lambda x: True
    landing_sync = landing.update_landing(git_gecko, git_wpt)

    assert len(landing_sync.gecko_commits) == 3
    assert landing_sync.gecko_commits[-1].metadata["wpt-type"] == "landing"
    assert landing_sync.gecko_commits[-2].metadata["wpt-type"] == "metadata"
    for item in file_data:
        assert item in landing_sync.gecko_commits[-2].commit.stats.files
Пример #19
0
def test_wpt_pr_approved(env, git_gecko, git_wpt, pull_request, set_pr_status,
                         hg_gecko_try, mock_wpt, mock_tasks, mock_mach):
    mock_wpt.set_data("tests-affected", "")

    pr = pull_request([("Test commit", {
        "README": "Example change\n"
    })], "Test PR")
    pr._approved = False
    with patch("sync.tree.is_open",
               Mock(return_value=True)), patch("sync.trypush.Mach", mock_mach):
        downstream.new_wpt_pr(git_gecko, git_wpt, pr)
        sync = set_pr_status(pr, "success")

        with SyncLock.for_process(sync.process_name) as lock:
            with sync.as_mut(lock):
                sync.data["affected-tests"] = {"testharness": ["example"]}

            assert sync.latest_try_push is None

            assert sync.last_pr_check == {"state": "success", "sha": pr.head}

        pr._approved = True
        # A Try push is not run after approval.
        assert sync.latest_try_push is None

        # If we 'merge' the PR, then we will see a stability try push
        handlers.handle_pr(
            git_gecko, git_wpt, {
                "action": "closed",
                "number": pr.number,
                "pull_request": {
                    "number": pr.number,
                    "merge_commit_sha": "a" * 25,
                    "base": {
                        "sha": "b" * 25
                    },
                    "merged": True,
                    "state": "closed",
                    "merged_by": {
                        "login": "******"
                    }
                }
            })
        try_push = sync.latest_try_push
        assert try_push.stability
Пример #20
0
def test_try_push_expiration(git_gecko, git_wpt, pull_request, set_pr_status,
                             MockTryCls, hg_gecko_try):
    pr = pull_request([("Test commit", {
        "README": "Example change\n"
    })], "Test PR")
    today = datetime.today().date()
    downstream.new_wpt_pr(git_gecko, git_wpt, pr)
    sync = set_pr_status(pr, "success")
    try_push = sync.latest_valid_try_push
    created_date = datetime.strptime(try_push.created, tc._DATE_FMT)
    assert today == created_date.date()
    assert not try_push.expired()
    try_push.created = taskcluster.fromNowJSON("-15 days")
    assert try_push.expired()
    try_push.created = None
    with patch("sync.trypush.tc.get_task",
               return_value={"created": taskcluster.fromNowJSON("-5 days")}):
        assert not try_push.expired()
Пример #21
0
def test_update_metadata(env, git_gecko, git_wpt, pull_request,
                         git_wpt_metadata, mock_mach):
    results_obj = fx_only_failure()

    pr = pull_request([("Test commit", {
        "README": "Example change\n"
    })], "Test PR")

    downstream.new_wpt_pr(git_gecko, git_wpt, pr)
    sync = load.get_pr_sync(git_gecko, git_wpt, pr["number"])

    mock_mach.set_data(
        "wpt-test-paths",
        json.dumps(bugs.fallback_test_ids_to_paths(["/test/test.html"])))

    with patch(
            "sync.notify.bugs.components_for_wpt_paths",
            return_value={"Testing :: web-platform-tests":
                          ["test/test.html"]}):
        with patch("sync.notify.bugs.Mach", return_value=mock_mach(None)):
            with patch("sync.meta.Metadata.github") as mock_github:
                with SyncLock.for_process(sync.process_name) as lock:
                    with sync.as_mut(lock):
                        bug_data = bugs.for_sync(sync, results_obj)
                        bugs.update_metadata(sync, bug_data)

                assert mock_github.create_pull.called
                head = mock_github.method_calls[0].args[-1]

    bugs_filed = bug_data.keys()
    assert len(bugs_filed) == 1
    bug = bugs_filed[0]

    metadata = meta.Metadata(sync.process_name, branch=head)
    links = list(metadata.iterbugs("/test/test.html"))
    assert len(links) == 1
    link = links[0]
    assert link.url == "%s/show_bug.cgi?id=%s" % (env.bz.bz_url, bug)
    assert link.test_id == "/test/test.html"
    assert link.product == "firefox"
    assert link.subtest is None
    assert link.status is None
Пример #22
0
def test_gecko_rebase(env, git_gecko, git_wpt, pull_request):
    pr = pull_request([("Test commit", {
        "README": "Example change\n"
    })], "Test PR")

    downstream.new_wpt_pr(git_gecko, git_wpt, pr)
    sync = load.get_pr_sync(git_gecko, git_wpt, pr["number"])

    assert len(sync.gecko_commits) == 1

    with SyncLock.for_process(sync.process_name) as lock:
        with sync.as_mut(lock):
            assert sync.data[
                "gecko-base"] == downstream.DownstreamSync.gecko_landing_branch(
                )
            sync.gecko_rebase(
                downstream.DownstreamSync.gecko_integration_branch())
            assert sync.data[
                "gecko-base"] == downstream.DownstreamSync.gecko_integration_branch(
                )
Пример #23
0
def test_land_try(env, git_gecko, git_wpt, git_wpt_upstream, pull_request,
                  set_pr_status, hg_gecko_try, mock_mach):
    pr = pull_request([("Test commit", {
        "README": "example_change",
        "LICENSE": "Some change"
    })])
    head_rev = pr._commits[0]["sha"]

    trypush.Mach = mock_mach
    downstream.new_wpt_pr(git_gecko, git_wpt, pr)
    sync = set_pr_status(pr, "success")

    git_wpt_upstream.head.commit = head_rev
    git_wpt.remotes.origin.fetch()
    landing.wpt_push(git_gecko, git_wpt, [head_rev], create_missing=False)

    sync.data["force-metadata-ready"] = True

    tree.is_open = lambda x: True
    landing_sync = landing.update_landing(git_gecko, git_wpt)

    assert landing_sync is not None
    worktree = landing_sync.gecko_worktree.get()
    # Check that files we shouldn't move aren't
    assert not os.path.exists(
        os.path.join(worktree.working_dir, env.config["gecko"]["path"]["wpt"],
                     ".git"))
    with open(
            os.path.join(worktree.working_dir,
                         env.config["gecko"]["path"]["wpt"], "LICENSE")) as f:
        assert f.read() == "Initial license\n"

    try_push = sync.latest_try_push
    assert try_push is not None
    assert try_push.status == "open"
    assert try_push.stability is False
    mach_command = mock_mach.get_log()[-1]
    assert mach_command["command"] == "mach"
    assert mach_command["args"] == ("try", "fuzzy", "-q",
                                    "web-platform-tests !pgo !ccov !msvc",
                                    "--artifact")
Пример #24
0
def test_next_try_push(git_gecko, git_wpt, pull_request, set_pr_status,
                       MockTryCls, hg_gecko_try, pull_request_commit,
                       mock_mach):
    pr = pull_request([("Test commit", {
        "README": "Example change\n"
    })], "Test PR")
    downstream.new_wpt_pr(git_gecko, git_wpt, pr)
    with patch("sync.tree.is_open",
               Mock(return_value=True)), patch("sync.trypush.Mach", mock_mach):
        sync = set_pr_status(pr, "success")

        with SyncLock.for_process(sync.process_name) as lock:
            with sync.as_mut(lock):
                assert sync.next_try_push() is None
                assert sync.metadata_ready is False

                # No affected tests and one try push, means we should be ready
                sync.data["affected-tests"] = {}

                assert sync.requires_try
                assert not sync.requires_stability_try

                sync.data["affected-tests"] = {"testharness": ["example"]}

                assert sync.requires_stability_try
                assert not sync.metadata_ready

                # The PR has not yet been merged, so no Try push should happen
                assert sync.next_try_push() is None

                pr.merged = True

                new_try_push = sync.next_try_push(try_cls=MockTryCls)
                assert new_try_push is not None
                assert new_try_push.stability
                assert not sync.metadata_ready

                with new_try_push.as_mut(lock):
                    new_try_push.status = "complete"
                assert sync.metadata_ready
                assert not sync.next_try_push()
Пример #25
0
def try_push(env, git_gecko, git_wpt, git_wpt_upstream, pull_request,
             set_pr_status, hg_gecko_try, mock_mach):
    pr = pull_request([("Test commit", {
        "README": "example_change",
        "LICENSE": "Some change"
    })])
    head_rev = pr._commits[0]["sha"]

    trypush.Mach = mock_mach
    downstream.new_wpt_pr(git_gecko, git_wpt, pr)
    sync = set_pr_status(pr, "success")

    git_wpt_upstream.head.commit = head_rev
    git_wpt.remotes.origin.fetch()
    landing.wpt_push(git_gecko, git_wpt, [head_rev], create_missing=False)

    sync.data["force-metadata-ready"] = True

    tree.is_open = lambda x: True
    sync.latest_try_push.taskgroup_id = "abcdef"
    return sync.latest_try_push
Пример #26
0
def test_wpt_pr_approved(git_gecko, git_wpt, pull_request, set_pr_status,
                         hg_gecko_try, mock_wpt, mock_tasks):
    mock_wpt.set_data("tests-affected", "")

    pr = pull_request([("Test commit", {
        "README": "Example change\n"
    })], "Test PR")
    pr._approved = False
    tree.is_open = lambda x: True
    downstream.new_wpt_pr(git_gecko, git_wpt, pr)
    sync = set_pr_status(pr, "success")

    sync.data["affected-tests"] = ["example"]

    try_push = sync.latest_try_push
    try_push.taskgroup_id = "abcdef"
    assert sync.last_pr_check == {"state": "success", "sha": pr.head}
    try_push.success = lambda: True

    tasks = Mock(return_value=mock_tasks(completed=["foo", "bar"] * 5))
    with patch.object(tc.TaskGroup, 'tasks', property(tasks)):
        downstream.try_push_complete(git_gecko, git_wpt, try_push, sync)
    assert try_push.status == "complete"
    assert sync.latest_try_push == try_push

    pr._approved = True
    handlers.handle_pull_request_review(
        git_gecko, git_wpt, {
            "action": "submitted",
            "review": {
                "state": "approved"
            },
            "pull_request": {
                "number": pr.number
            }
        })
    assert sync.latest_try_push != try_push
    assert sync.latest_try_push.stability
Пример #27
0
def test_landable_skipped(env, git_gecko, git_wpt, git_wpt_upstream, pull_request, set_pr_status,
                          mock_mach):
    prev_wpt_head = git_wpt_upstream.head.commit
    pr = pull_request([(b"Test commit", {"README": b"example_change"})])
    head_rev = pr._commits[0]["sha"]

    trypush.Mach = mock_mach

    downstream.new_wpt_pr(git_gecko, git_wpt, pr)
    downstream_sync = set_pr_status(pr.number, "success")

    with SyncLock.for_process(downstream_sync.process_name) as downstream_lock:
        with downstream_sync.as_mut(downstream_lock):
            downstream_sync.skip = True

    git_wpt_upstream.head.commit = head_rev
    git_wpt.remotes.origin.fetch()
    landing.wpt_push(git_gecko, git_wpt, [head_rev], create_missing=False)

    wpt_head, landable_commits = landing.landable_commits(git_gecko, git_wpt, prev_wpt_head.hexsha)
    assert len(landable_commits) == 1
    assert landable_commits[0][0] == pr.number
    assert landable_commits[0][1] == downstream_sync
Пример #28
0
def test_next_try_push_infra_fail(git_gecko, git_wpt, pull_request,
                                  set_pr_status, MockTryCls, hg_gecko_try):
    pr = pull_request([("Test commit", {
        "README": "Example change\n"
    })], "Test PR")
    downstream.new_wpt_pr(git_gecko, git_wpt, pr)
    sync = set_pr_status(pr, "success")
    assert len(sync.try_pushes()) == 1

    # no stability try push needed
    sync.data["affected-tests"] = []

    try_push = sync.latest_valid_try_push
    try_push.status = "complete"
    try_push.infra_fail = True

    for i in range(4):
        another_try_push = sync.next_try_push(try_cls=MockTryCls)
        assert not sync.metadata_ready
        assert another_try_push is not None
        another_try_push.infra_fail = True
        another_try_push.status = "complete"

    assert len(sync.latest_busted_try_pushes()) == 5

    another_try_push.infra_fail = False
    # Now most recent try push isn't busted, so count goes back to 0
    assert len(sync.latest_busted_try_pushes()) == 0
    # Reset back to 5
    another_try_push.infra_fail = True
    # After sixth consecutive infra_failure, we should get sync error
    another_try_push = sync.next_try_push(try_cls=MockTryCls)
    another_try_push.infra_fail = True
    another_try_push.status = "complete"
    another_try_push = sync.next_try_push(try_cls=MockTryCls)
    assert another_try_push is None
    assert sync.next_action == downstream.DownstreamAction.manual_fix
Пример #29
0
def test_landing_reapply(env, git_gecko, git_wpt, git_wpt_upstream, pull_request, set_pr_status,
                         hg_gecko_upstream, upstream_gecko_commit, upstream_wpt_commit,
                         hg_gecko_try, mock_mach, mock_tasks):
    # Test that we reapply the correct commits when landing patches on upstream
    # First we need to create 3 gecko commits:
    # Two that are landed
    # One that is still a PR
    # Then we create a landing that points at the first gecko commit that is landed
    # upstream. Locally we expect the code to reapply the two other gecko commits, so
    # we should end up with no overall change.

    trypush.Mach = mock_mach

    # Add first gecko change
    test_changes = {"change1": b"CHANGE1\n"}
    rev = upstream_gecko_commit(test_changes=test_changes, bug=1111,
                                message=b"Add change1 file")

    update_repositories(git_gecko, git_wpt, wait_gecko_commit=rev)
    pushed, _, _ = upstream.gecko_push(git_gecko, git_wpt, "autoland", rev,
                                       raise_on_error=True)
    sync_1 = pushed.pop()

    # Update central
    hg_gecko_upstream.bookmark("mozilla/central", "-r", rev)

    # Merge the upstream change
    with SyncLock.for_process(sync_1.process_name) as lock:
        with sync_1.as_mut(lock):
            remote_branch = sync_1.remote_branch
            git_wpt_upstream.git.checkout(remote_branch)
            git_wpt_upstream.git.rebase("master")
            git_wpt_upstream.git.checkout("master")
            git_wpt_upstream.git.merge(remote_branch, ff_only=True)

            sync_1.finish()

    # Add second gecko change
    test_changes = {"change2": b"CHANGE2\n"}
    rev = upstream_gecko_commit(test_changes=test_changes, bug=1112,
                                message=b"Add change2 file")

    update_repositories(git_gecko, git_wpt, wait_gecko_commit=rev)
    pushed, _, _ = upstream.gecko_push(git_gecko, git_wpt, "autoland", rev,
                                       raise_on_error=True)
    sync_2 = pushed.pop()

    hg_gecko_upstream.bookmark("mozilla/central", "-r", rev)

    # Merge the gecko change
    remote_branch = sync_2.remote_branch
    git_wpt_upstream.git.checkout(remote_branch)
    git_wpt_upstream.git.rebase("master")
    git_wpt_upstream.git.checkout("master")
    git_wpt_upstream.git.merge(remote_branch, ff_only=True)

    # Add an upstream commit that has metadata
    pr = pull_request([(b"Upstream change 1", {"upstream1": b"UPSTREAM1\n"})])
    head_rev = pr._commits[0]["sha"]
    downstream.new_wpt_pr(git_gecko, git_wpt, pr)
    downstream_sync = set_pr_status(pr.number, "success")
    git_wpt_upstream.head.commit = head_rev
    git_wpt_upstream.git.reset(hard=True)
    with SyncLock.for_process(downstream_sync.process_name) as downstream_lock:
        with downstream_sync.as_mut(downstream_lock):
            downstream_sync.data["force-metadata-ready"] = True

    # This is the commit we should land to
    landing_rev = git_wpt_upstream.git.rev_parse("HEAD")

    # Add an upstream commit that doesn't have metadata
    pr = pull_request([(b"Upstream change 2", {"upstream2": b"UPSTREAM2\n"})])
    head_rev = pr._commits[0]["sha"]
    downstream.new_wpt_pr(git_gecko, git_wpt, pr)
    downstream_sync = set_pr_status(pr.number, "success")
    git_wpt_upstream.head.commit = head_rev
    git_wpt_upstream.git.reset(hard=True)

    # Add third gecko change
    test_changes = {"change3": b"CHANGE3\n"}
    rev = upstream_gecko_commit(test_changes=test_changes, bug=1113,
                                message=b"Add change3 file")

    update_repositories(git_gecko, git_wpt, wait_gecko_commit=rev)
    pushed, _, _ = upstream.gecko_push(git_gecko, git_wpt, "autoland", rev,
                                       raise_on_error=True)

    # Now start a landing
    tree.is_open = lambda x: True
    sync = landing.update_landing(git_gecko, git_wpt)

    assert sync is not None

    for i in xrange(2):
        with SyncLock.for_process(sync.process_name) as lock:
            try_push = sync.latest_try_push
            with sync.as_mut(lock), try_push.as_mut(lock):
                try_push.taskgroup_id = "abcde" + str(i)
                try_push.download_logs = Mock(return_value=[])
                with patch.object(tc.TaskGroup, "tasks",
                                  property(Mock(return_value=mock_tasks(completed=["foo"])))):
                    landing.try_push_complete(git_gecko, git_wpt, try_push, sync)

    hg_gecko_upstream.update()
    gecko_root = hg_gecko_upstream.root().strip().decode("utf8")
    assert (hg_gecko_upstream
            .log("-l1", "--template={desc|firstline}")
            .strip()
            .endswith(b"[wpt-sync] Update web-platform-tests to %s, a=testonly" %
                      landing_rev.encode("utf8")))
    for file in ["change1", "change2", "change3", "upstream1"]:
        path = os.path.join(gecko_root,
                            env.config["gecko"]["path"]["wpt"],
                            file)
        assert os.path.exists(path)
        with open(path) as f:
            assert f.read() == file.upper() + "\n"
    assert not os.path.exists(os.path.join(gecko_root,
                                           env.config["gecko"]["path"]["wpt"],
                                           "upstream2"))
    sync_point = landing.load_sync_point(git_gecko, git_wpt)
    assert sync_point["upstream"] == landing_rev