def test_remove_with_type_ids(fast_poller, requests_mocker, client):
    """Remove succeeds when given specific type_ids."""

    repo = Repository(id="some-repo")
    repo.__dict__["_client"] = client

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

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

    assert repo.remove_content(type_ids=["type1", "type2"]).result() == [
        Task(id="task1", completed=True, succeeded=True)
    ]

    # It should have passed those type_ids to Pulp
    req = requests_mocker.request_history
    assert (
        req[0].url
        == "https://pulp.example.com/pulp/api/v2/repositories/some-repo/actions/unassociate/"
    )
    assert req[0].json() == {"criteria": {"type_ids": ["type1", "type2"]}}
def test_delete_success(fast_poller, requests_mocker, client):
    """delete succeeds and returns spawned tasks"""

    repo = Repository(id="some-repo")
    repo.__dict__["_client"] = client

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

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

    # It should have succeeded, with the tasks as retrieved from Pulp
    assert sorted(repo.delete().result()) == [
        Task(id="task1", succeeded=True, completed=True),
        Task(id="task2", succeeded=True, completed=True),
    ]
def test_search_distributor_with_relative_url():
    controller = FakeController()

    dist1 = Distributor(
        id="yum_distributor",
        type_id="yum_distributor",
        repo_id="repo1",
        relative_url="relative/path",
    )
    dist2 = Distributor(
        id="cdn_distributor",
        type_id="rpm_rsync_distributor",
        repo_id="repo1",
        relative_url="relative/path",
    )
    repo1 = Repository(id="repo1", distributors=(dist1, dist2))

    dist3 = Distributor(
        id="yum_distributor",
        type_id="yum_distributor",
        repo_id="repo2",
        relative_url="another/path",
    )

    repo2 = Repository(id="repo2", distributors=(dist3, ))

    controller.insert_repository(repo1)
    controller.insert_repository(repo2)

    client = controller.client
    crit = Criteria.with_field("relative_url", Matcher.regex("relative/path"))

    found = client.search_distributor(crit).result().data

    assert sorted(found) == [dist2, dist1]
Beispiel #4
0
def test_maintenance_on_with_regex(command_tester):
    """Test set maintenance by using regex"""
    repo1 = Repository(id="repo1")

    dist1 = Distributor(
        id="yum_distributor",
        type_id="yum_distributor",
        relative_url="rhel/7",
        repo_id="repo2",
    )

    repo2 = Repository(id="repo2", distributors=(dist1, ))

    with get_task_instance(True, repo1, repo2) as task_instance:
        command_tester.test(
            task_instance.main,
            [
                "test-maintenance-on",
                "--pulp-url",
                "http://some.url",
                "--repo-url-regex",
                "rhel",
            ],
        )

    assert_expected_report(["repo2"], task_instance.pulp_client)
def test_srpm_content(client, requests_mocker):
    """srpm_content returns correct unit types"""
    repo = Repository(id="some-repo")
    repo.__dict__["_client"] = client
    requests_mocker.post(
        "https://pulp.example.com/pulp/api/v2/repositories/some-repo/search/units/",
        json=[
            {
                "metadata": {
                    "_content_type_id": "srpm",
                    "name": "bash",
                    "epoch": "0",
                    "filename": "bash-x86_64.srpm",
                    "version": "4.0",
                    "release": "1",
                    "arch": "x86_64",
                }
            }
        ],
    )

    srpms = repo.srpm_content

    assert len(srpms) == 1
    assert srpms[0].content_type_id == "srpm"
def test_remove_no_type_ids(fast_poller, requests_mocker, client):
    """Remove succeeds when given no type_ids."""

    repo = Repository(id="some-repo")
    repo.__dict__["_client"] = client

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

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

    assert repo.remove_content().result() == [
        Task(id="task1", completed=True, succeeded=True),
        Task(id="task2", completed=True, succeeded=True),
    ]
Beispiel #7
0
def test_maintenance_off(command_tester):
    repo1 = Repository(id="repo1")
    repo2 = Repository(id="repo2")

    with get_task_instance(False, repo1, repo2) as task_instance:
        controller = task_instance.pulp_client_controller

        # Initially, there has already been a publish because get_task_instance already
        # sets maintenance report to [repo1, repo2] at beginning of this test.
        assert len(controller.publish_history) == 1

        command_tester.test(
            lambda: pubtools._pulp.tasks.set_maintenance.set_maintenance_off.
            entry_point(lambda: task_instance),
            [
                "test-maintenance-off",
                "--pulp-url",
                "http://some.url",
                "--repo-ids",
                "repo2",
            ],
        )

    # It should have taken repo2 out of maintenance, leaving just repo1.
    assert_expected_report(["repo1"], task_instance.pulp_client)

    # It should have also published the maintenance repo once more.
    assert len(controller.publish_history) == 2
Beispiel #8
0
def test_maintenance_on(command_tester):
    """Test set maintenance by passing repo ids."""
    repo1 = Repository(id="repo1")
    repo2 = Repository(id="repo2")

    with get_task_instance(True, repo1, repo2) as task_instance:
        command_tester.test(
            task_instance.main,
            [
                "test-maintenance-on",
                "--pulp-url",
                "http://some.url",
                "--repo-ids",
                "repo1,repo2",
                "--message",
                "Now in Maintenance",
            ],
        )

    # It should have set the maintenance report to our requested value.
    assert_expected_report(["repo1", "repo2"],
                           task_instance.pulp_client,
                           message="Now in Maintenance")

    controller = task_instance.pulp_client_controller
    # It should have published the repo containing the maintenance report.
    assert len(controller.publish_history) == 1
    assert controller.publish_history[0].repository.id == "redhat-maintenance"
def test_maintenance_on(command_tester):
    """Test set maintenance by passing repo ids."""
    repo1 = Repository(id="repo1")
    repo2 = Repository(id="repo2")

    task_instance = get_task_instance(True, repo1, repo2)

    command_tester.test(
        task_instance.main,
        [
            "test-maintenance-on",
            "--pulp-url",
            "http://some.url",
            "--repo-ids",
            "repo1",
            "repo2",
            "--message",
            "Now in Maintenance",
        ],
    )

    controller = task_instance.pulp_client_controller
    # upload and publish should be called once each
    assert len(controller.upload_history) == 1
    assert controller.upload_history[0].repository.id == "redhat-maintenance"
    assert len(controller.publish_history) == 1
    assert controller.publish_history[0].repository.id == "redhat-maintenance"

    assert_expected_report(
        ["repo1", "repo2"], task_instance.pulp_client, message="Now in Maintenance"
    )
def test_maintenance_off(command_tester):
    repo1 = Repository(id="repo1")
    repo2 = Repository(id="repo2")

    task_instance = get_task_instance(False, repo1, repo2)

    command_tester.test(
        lambda: pubtools._pulp.tasks.set_maintenance.set_maintenance_off.entry_point(
            lambda: task_instance
        ),
        [
            "test-maintenance-off",
            "--pulp-url",
            "http://some.url",
            "--repo-ids",
            "repo2",
        ],
    )

    controller = task_instance.pulp_client_controller
    # upload and publish should be called twice each
    assert len(controller.upload_history) == 2
    assert len(controller.publish_history) == 2

    assert_expected_report(["repo1"], task_instance.pulp_client)
Beispiel #11
0
def _add_repo(controller):
    # test repos added to the controller
    dt1 = datetime(2019, 9, 10, 0, 0, 0)
    r1_d1 = Distributor(
        id="yum_distributor",
        type_id="yum_distributor",
        repo_id="repo1",
        last_publish=dt1,
        relative_url="content/unit/1/client",
    )
    r1_d2 = Distributor(
        id="cdn_distributor",
        type_id="rpm_rsync_distributor",
        repo_id="repo1",
        last_publish=dt1,
        relative_url="content/unit/1/client",
    )
    repo1 = Repository(
        id="repo1",
        eng_product_id=101,
        distributors=[r1_d1, r1_d2],
        relative_url="content/unit/1/client",
        mutable_urls=["mutable1", "mutable2"],
    )

    dt2 = datetime(2019, 9, 12, 0, 0, 0)
    d2 = Distributor(
        id="yum_distributor",
        type_id="yum_distributor",
        repo_id="repo2",
        last_publish=dt2,
        relative_url="content/unit/2/client",
    )
    repo2 = Repository(
        id="repo2",
        eng_product_id=102,
        distributors=[d2],
        relative_url="content/unit/2/client",
    )

    dt3 = datetime(2019, 9, 7, 0, 0, 0)
    d3 = Distributor(
        id="cdn_distributor",
        type_id="rpm_rsync_distributor",
        repo_id="repo3",
        last_publish=dt3,
        relative_url="content/unit/3/client",
    )
    repo3 = Repository(
        id="repo3",
        eng_product_id=103,
        distributors=[d3],
        relative_url="content/unit/3/client",
    )

    controller.insert_repository(repo1)
    controller.insert_repository(repo2)
    controller.insert_repository(repo3)
def test_bad_created():
    """from_data raises if input data has created of wrong type"""
    with pytest.raises(InvalidDataException):
        Repository.from_data({
            "id": "some-repo",
            "notes": {
                "created": "whoops"
            }
        })
def test_bad_created(caplog):
    """from_data logs and raises if input data has created of wrong type"""
    with pytest.raises(InvalidDataException):
        Repository.from_data({"id": "some-repo", "notes": {"created": "whoops"}})

    # It should have logged about the bad data. We don't verify details
    # of the failure message since it relies too heavily on implementation
    # details (e.g. stringification of class)
    assert "An error occurred while loading Pulp data!" in caplog.text
def test_complex_type_ids(client):
    """content searches raise if using criteria with unsupported operators on content_type_id"""
    repo = Repository(id="some-repo")
    repo.__dict__["_client"] = client

    with pytest.raises(ValueError) as e:
        repo.search_content(
            Criteria.with_field("content_type_id", Matcher.regex("foobar")))

    assert "unsupported expression for content_type_id" in str(e.value)
def test_remove_fail_without_type_id(fast_poller, client):
    """Remove fails when a critria is provided without unit type"""
    repo = Repository(id="some-repo")
    repo.__dict__["_client"] = client

    criteria = Criteria.and_(
        Criteria.with_field("filename", "some.rpm"),
        Criteria.with_field("signing_key", Matcher.in_(["key123"])),
    )

    with pytest.raises(ValueError):
        repo.remove_content(criteria=criteria)
def test_can_search(client, requests_mocker):
    """search_repository issues /search/ POST requests as expected."""
    requests_mocker.post(
        "https://pulp.example.com/pulp/api/v2/repositories/search/",
        json=[{"id": "repo1"}, {"id": "repo2"}],
    )

    repos = client.search_repository()

    # It should have returned the repos as objects
    assert sorted(repos) == [Repository(id="repo1"), Repository(id="repo2")]

    # It should have issued only a single search
    assert requests_mocker.call_count == 1
def test_search_no_result():
    controller = FakeController()

    repo1 = Repository(id="repo1")
    repo2 = Repository(id="repo2")

    controller.insert_repository(repo1)
    controller.insert_repository(repo2)

    client = controller.client
    crit = Criteria.with_field("notes.whatever", "foobar")
    found = client.search_repository(crit).data

    assert found == []
def test_can_get():
    """get_repository returns repository inserted via controller."""
    controller = FakeController()

    repo1 = Repository(id="repo1")
    repo2 = Repository(id="repo2")

    controller.insert_repository(repo1)
    controller.insert_repository(repo2)

    client = controller.client
    found = client.get_repository("repo2").result()

    assert found == repo2
def test_search_content_type_id_in_or(client, requests_mocker):
    """Searching with a content_type_id within $or fails as unsupported"""
    repo = Repository(id="some-repo")
    repo.__dict__["_client"] = client

    crit = Criteria.or_(
        Criteria.with_field("name", "hello.txt"),
        Criteria.with_field_in("content_type_id", ["rpm", "iso"]),
    )

    with pytest.raises(ValueError) as e:
        repo.search_content(crit).result()

    assert "Can't serialize criteria for Pulp query; too complicated" in str(
        e.value)
def test_can_search_id_exists():
    """Can search for a repo using exists operator with fake client."""
    controller = FakeController()

    repo1 = Repository(id="repo1")
    repo2 = Repository(id="repo2")

    controller.insert_repository(repo1)
    controller.insert_repository(repo2)

    client = controller.client
    crit = Criteria.with_field("id", Matcher.exists())
    found = client.search_repository(crit).data

    assert sorted(found) == [repo1, repo2]
def test_can_search_id():
    """Can search for a repo by ID with fake client."""
    controller = FakeController()

    repo1 = Repository(id="repo1")
    repo2 = Repository(id="repo2")

    controller.insert_repository(repo1)
    controller.insert_repository(repo2)

    client = controller.client
    crit = Criteria.with_id("repo1")
    found = client.search_repository(crit).data

    assert found == [repo1]
def test_mixed_search(client, requests_mocker):
    """Searching with a criteria mixing several fields works correctly"""
    repo = Repository(id="some-repo")
    repo.__dict__["_client"] = client
    requests_mocker.post(
        "https://pulp.example.com/pulp/api/v2/repositories/some-repo/search/units/",
        json=[{
            "metadata": {
                "_content_type_id": "iso",
                "name": "hello.txt",
                "size": 23,
                "checksum": "a" * 64,
            }
        }],
    )

    crit = Criteria.and_(
        Criteria.with_field_in("content_type_id", ["rpm", "iso"]),
        Criteria.with_field("name", "hello.txt"),
    )

    files = list(repo.search_content(crit))

    assert files == [FileUnit(path="hello.txt", size=23, sha256sum="a" * 64)]

    history = requests_mocker.request_history

    # There should have been just one request
    assert len(history) == 1

    request = history[0]
    body = request.json()

    # This should have been the request body.
    assert body == {
        "criteria": {
            "type_ids": ["rpm", "iso"],
            "skip": 0,
            "limit": 2000,
            "filters": {
                "unit": {
                    "name": {
                        "$eq": "hello.txt"
                    }
                }
            },
        }
    }
def test_delete_missing_repo_fails():
    """dist.delete() of distributor with absent repo fails."""
    controller = FakeController()

    controller.insert_repository(
        Repository(
            id="repo",
            distributors=[
                Distributor(id="somedist", type_id="sometype", repo_id="repo")
            ],
        ))

    client = controller.client

    # Get two handles to the repo, to set up the situation that
    # the distributor is not detached despite repo deletion
    repo1 = client.get_repository("repo")
    repo2 = client.get_repository("repo")
    dist = repo2.distributors[0]

    # We can delete the repo
    assert repo1.delete().result()

    # The distributor (obtained via repo2) is not detached, but nevertheless
    # deletion should fail as repo no longer exists
    assert "Repository id=repo not found" in str(dist.delete().exception())
def test_gc_error(mock_logger):
    """logs error when repo delete task returns an error reponse"""
    repo = Repository(
        id="rhel-test-garbage-collect-7-days-old",
        created=_get_created(7),
        is_temporary=True,
    )
    controller = _get_fake_controller(repo)
    gc = GarbageCollect()
    arg = ["", "--pulp-url", "http://some.url", "--verbose"]

    with patch("sys.argv", arg):
        with patch.object(controller.client,
                          "_delete_repository") as repo_delete:
            with patch("pubtools._pulp.task.PulpTask.pulp_client",
                       controller.client):
                repo_delete.return_value = f_return([
                    Task(
                        id="12334",
                        completed=True,
                        succeeded=False,
                        error_summary="Error occured",
                    )
                ])
                gc.main()

    mock_logger.error.assert_any_call("Error occured")
def test_garbage_collect():
    """deletes the repo that confirms to garbage collect criteria"""
    repo1 = Repository(
        id="rhel-test-garbage-collect-7-days-old",
        created=_get_created(7),
        is_temporary=True,
    )
    repo2 = Repository(
        id="rhel-test-garbage-collect-3-days-old",
        created=_get_created(3),
        is_temporary=True,
    )
    controller = _run_test(repo1, repo2)
    assert len(controller.repositories) == 1
    assert controller.repositories[
        0].id == "rhel-test-garbage-collect-3-days-old"
def test_gc_no_created_date(mock_logger):
    """no repo returned for gc when creatd date is missing"""
    repo = Repository(id="rhel-test-garbage-collect", is_temporary=True)

    _run_test(repo)
    mock_logger.info.assert_any_call("No repo(s) found older than %s day(s)",
                                     5)
def test_search_mapped_field_less_than():
    controller = FakeController()

    dist1 = Distributor(
        id="yum_distributor",
        type_id="yum_distributor",
        repo_id="repo1",
        last_publish=datetime.datetime(2019, 8, 23, 2, 5, 0, tzinfo=None),
    )
    dist2 = Distributor(
        id="cdn_distributor",
        type_id="rpm_rsync_distributor",
        repo_id="repo1",
        last_publish=datetime.datetime(2019, 8, 27, 2, 5, 0, tzinfo=None),
    )
    repo1 = Repository(id="repo1", distributors=(dist1, dist2))

    controller.insert_repository(repo1)

    client = controller.client
    crit = Criteria.with_field(
        "last_publish",
        Matcher.less_than(datetime.datetime(2019, 8, 24, 0, 0, 0)))
    found = client.search_distributor(crit).result().data

    assert found == [dist1]
def test_delete_missing_distributor_succeeds():
    """dist.delete() of absent distributor with fake client succeeds.

    Deleting a distributor succeeds with the fake client since it also succeeds
    with the real client.
    """
    controller = FakeController()

    controller.insert_repository(
        Repository(
            id="repo",
            distributors=[
                Distributor(id="somedist", type_id="sometype", repo_id="repo")
            ],
        ))

    client = controller.client

    # Get two handles to the repos/distributors so we can delete via one handle
    # and try to delete again via the other
    repo_copy1 = client.get_repository("repo")
    repo_copy2 = client.get_repository("repo")

    dist_copy1 = repo_copy1.distributors[0]
    dist_copy2 = repo_copy2.distributors[0]

    # First delete succeeds, with some tasks
    assert dist_copy1.delete().result()

    # Second delete also succeeds, but there are no tasks since distributor
    # already doesn't exist
    assert dist_copy2.delete().result() == []
def test_search_paginates():
    controller = FakeController()

    repos = []
    for i in range(0, 1000):
        repo = Repository(id="repo-%s" % i)
        repos.append(repo)
        controller.insert_repository(repo)

    client = controller.client
    crit = Criteria.true()

    page = client.search_repository(crit)
    found_repos = list(page)

    page_count = 1
    while page.next:
        page_count += 1
        page = page.next.result()

    # There should have been several pages (it is not defined exactly
    # what page size the fake client uses, but it should be relatively
    # small to enforce that clients think about pagination)
    assert page_count >= 10

    # All repos should have been found
    assert sorted(found_repos) == sorted(repos)
def test_search_created_exists():
    controller = FakeController()

    repo1 = Repository(id="repo1")
    repo2 = Repository(id="repo2", created=datetime.datetime.utcnow())
    repo3 = Repository(id="repo3", created=datetime.datetime.utcnow())

    controller.insert_repository(repo1)
    controller.insert_repository(repo2)
    controller.insert_repository(repo3)

    client = controller.client
    crit = Criteria.with_field("notes.created", Matcher.exists())
    found = client.search_repository(crit).data

    assert sorted(found) == [repo2, repo3]