Exemplo n.º 1
0
def test_publish_fail(fast_poller, requests_mocker, client):
    """publish raises TaskFailedException if publish task fails"""
    repo = YumRepository(
        id="some-repo",
        distributors=(Distributor(id="yum_distributor",
                                  type_id="yum_distributor"), ),
    )
    repo.__dict__["_client"] = client

    requests_mocker.post(
        "https://pulp.example.com/pulp/api/v2/repositories/some-repo/actions/publish/",
        json={"spawned_tasks": [{
            "task_id": "task1"
        }]},
    )

    requests_mocker.post(
        "https://pulp.example.com/pulp/api/v2/tasks/search/",
        json=[{
            "task_id": "task1",
            "state": "error"
        }],
    )

    publish_f = repo.publish()

    # It should raise this exception
    with pytest.raises(TaskFailedException) as error:
        publish_f.result()

    # The exception should have a reference to the task which failed
    assert error.value.task.id == "task1"
    assert "Task task1 failed" in str(error.value)
Exemplo n.º 2
0
def test_publish_retries(fast_poller, requests_mocker, client, caplog):
    """publish retries distributors as they fail"""
    caplog.set_level(logging.WARNING)

    repo = YumRepository(
        id="some-repo",
        distributors=(
            Distributor(id="yum_distributor", type_id="yum_distributor"),
            Distributor(id="cdn_distributor", type_id="cdn_distributor"),
        ),
    )
    repo.__dict__["_client"] = client

    requests_mocker.post(
        "https://pulp.example.com/pulp/api/v2/repositories/some-repo/actions/publish/",
        [
            {"json": {"spawned_tasks": [{"task_id": "task1"}]}},
            {"json": {"spawned_tasks": [{"task_id": "task2"}]}},
            {"json": {"spawned_tasks": [{"task_id": "task3"}]}},
        ],
    )

    requests_mocker.post(
        "https://pulp.example.com/pulp/api/v2/tasks/search/",
        [
            {"json": [{"task_id": "task1", "state": "finished"}]},
            {"json": [{"task_id": "task2", "state": "error"}]},
            {"json": [{"task_id": "task3", "state": "finished"}]},
        ],
    )

    publish_f = repo.publish()

    # It should succeed
    tasks = publish_f.result()

    # It should return only the *successful* tasks
    assert sorted([t.id for t in tasks]) == ["task1", "task3"]

    # Pick out the HTTP requests triggering distributors
    publish_reqs = [
        req
        for req in requests_mocker.request_history
        if req.url
        == "https://pulp.example.com/pulp/api/v2/repositories/some-repo/actions/publish/"
    ]
    publish_distributors = [req.json()["id"] for req in publish_reqs]

    # It should have triggered cdn_distributor twice, since the first attempt failed
    assert publish_distributors == [
        "yum_distributor",
        "cdn_distributor",
        "cdn_distributor",
    ]

    # The retry should have been logged
    messages = caplog.messages
    assert (
        messages[-1].splitlines()[0] == "Retrying due to error: Task task2 failed [1/6]"
    )
def test_publish_cancel(fast_poller, requests_mocker, client, caplog):
    """Cancelling a publish future will cancel running Pulp task(s)."""

    repo = YumRepository(
        id="some-repo",
        distributors=(
            Distributor(id="yum_distributor", type_id="yum_distributor"),
            Distributor(id="cdn_distributor", type_id="cdn_distributor"),
        ),
    )
    repo.__dict__["_client"] = client

    requests_mocker.post(
        "https://pulp.example.com/pulp/api/v2/repositories/some-repo/actions/publish/",
        [{
            "json": {
                "spawned_tasks": [{
                    "task_id": "task1"
                }]
            }
        }],
    )

    task_search_url = "https://pulp.example.com/pulp/api/v2/tasks/search/"
    requests_mocker.post(task_search_url, [{
        "json": [{
            "task_id": "task1",
            "state": "running"
        }]
    }])

    requests_mocker.delete("https://pulp.example.com/pulp/api/v2/tasks/task1/")

    # Start the publish
    publish_f = repo.publish()

    # Wait until we're sure poll thread has seen this task
    for _ in range(0, 1000):
        if (requests_mocker.last_request
                and requests_mocker.last_request.url == task_search_url):
            break
        time.sleep(0.001)
    assert requests_mocker.last_request.url == task_search_url

    # We should be able to cancel it
    assert publish_f.cancel()

    # It should have cancelled the underlying Pulp task
    task_req = [
        r for r in requests_mocker.request_history
        if r.url == "https://pulp.example.com/pulp/api/v2/tasks/task1/"
    ]
    assert len(task_req) == 1
    assert task_req[0].method == "DELETE"
Exemplo n.º 4
0
def test_publish_with_options(requests_mocker, client):
    """publish passes expected config into distributors based on publish options"""
    repo = YumRepository(
        id="some-repo",
        distributors=(
            Distributor(id="yum_distributor", type_id="yum_distributor"),
            Distributor(id="cdn_distributor", type_id="rpm_rsync_distributor"),
        ),
    )
    repo.__dict__["_client"] = client

    requests_mocker.post(
        "https://pulp.example.com/pulp/api/v2/repositories/some-repo/actions/publish/",
        [
            {"json": {"spawned_tasks": [{"task_id": "task1"}]}},
            {"json": {"spawned_tasks": [{"task_id": "task2"}]}},
        ],
    )

    requests_mocker.post(
        "https://pulp.example.com/pulp/api/v2/tasks/search/",
        [
            {"json": [{"task_id": "task1", "state": "finished"}]},
            {"json": [{"task_id": "task2", "state": "finished"}]},
        ],
    )

    options = PublishOptions(
        clean=True, force=True, origin_only=True, rsync_extra_args=["-a"]
    )

    # It should have succeeded, with the tasks as retrieved from Pulp
    assert sorted(repo.publish(options)) == [
        Task(id="task1", succeeded=True, completed=True),
        Task(id="task2", succeeded=True, completed=True),
    ]

    req = requests_mocker.request_history

    # The yum_distributor request should have set force_full, but not
    # delete since it's not recognized by that distributor
    assert req[0].json()["override_config"] == {"force_full": True}

    # The cdn_distributor request should have set force_full, delete
    # and content_units_only
    assert req[2].json()["override_config"] == {
        "force_full": True,
        "delete": True,
        "content_units_only": True,
        "rsync_extra_args": ["-a"],
    }
Exemplo n.º 5
0
def test_publish_broken_response(fast_poller, requests_mocker, client):
    """publish raises an exception if Pulp /publish/ responded with parseable
    JSON, but not of the expected structure
    """

    repo = YumRepository(
        id="some-repo",
        distributors=(Distributor(id="yum_distributor", type_id="yum_distributor"),),
    )
    repo.__dict__["_client"] = client

    requests_mocker.post(
        "https://pulp.example.com/pulp/api/v2/repositories/some-repo/actions/publish/",
        json={"spawned_tasks": ["oops, not a valid response"]},
    )

    publish_f = repo.publish()

    # It should raise some kind of exception due to the invalid spawned_tasks structure
    assert publish_f.exception()
Exemplo n.º 6
0
def test_publish_distributors(fast_poller, requests_mocker, client):
    """publish succeeds and returns tasks from each applicable distributor"""
    repo = YumRepository(
        id="some-repo",
        distributors=(
            Distributor(id="yum_distributor", type_id="yum_distributor"),
            Distributor(id="other_distributor", type_id="other_distributor"),
            Distributor(id="cdn_distributor", type_id="rpm_rsync_distributor"),
        ),
    )
    repo.__dict__["_client"] = client

    requests_mocker.post(
        "https://pulp.example.com/pulp/api/v2/repositories/some-repo/actions/publish/",
        [
            {
                "json": {
                    "spawned_tasks": [{
                        "task_id": "task1"
                    }, {
                        "task_id": "task2"
                    }]
                }
            },
            {
                "json": {
                    "spawned_tasks": [{
                        "task_id": "task3"
                    }]
                }
            },
        ],
    )

    requests_mocker.post(
        "https://pulp.example.com/pulp/api/v2/tasks/search/",
        [
            {
                "json": [
                    {
                        "task_id": "task1",
                        "state": "finished"
                    },
                    {
                        "task_id": "task2",
                        "state": "skipped"
                    },
                ]
            },
            {
                "json": [{
                    "task_id": "task3",
                    "state": "finished"
                }]
            },
        ],
    )

    # It should have succeeded, with the tasks as retrieved from Pulp
    assert sorted(repo.publish()) == [
        Task(id="task1", succeeded=True, completed=True),
        Task(id="task2", succeeded=True, completed=True),
        Task(id="task3", succeeded=True, completed=True),
    ]

    # It should have first issued a request to publish yum_distributor
    req = requests_mocker.request_history
    assert (
        req[0].url ==
        "https://pulp.example.com/pulp/api/v2/repositories/some-repo/actions/publish/"
    )
    assert req[0].json() == {"id": "yum_distributor", "override_config": {}}

    # Then polled for resulting tasks to succeed
    assert req[1].url == "https://pulp.example.com/pulp/api/v2/tasks/search/"
    assert req[1].json() == {
        "criteria": {
            "filters": {
                "task_id": {
                    "$in": ["task1", "task2"]
                }
            }
        }
    }

    # Then published the next distributor
    assert (
        req[2].url ==
        "https://pulp.example.com/pulp/api/v2/repositories/some-repo/actions/publish/"
    )
    assert req[2].json() == {"id": "cdn_distributor", "override_config": {}}

    # Then waited for those tasks to finish too
    assert req[3].url == "https://pulp.example.com/pulp/api/v2/tasks/search/"
    assert req[3].json() == {
        "criteria": {
            "filters": {
                "task_id": {
                    "$in": ["task3"]
                }
            }
        }
    }

    # And there should have been no more requests
    assert len(req) == 4