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]
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), ]
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
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)
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]