diff --git a/functest_requirements.txt b/functest_requirements.txt index 32e5c1bd6..9f63a9ae7 100644 --- a/functest_requirements.txt +++ b/functest_requirements.txt @@ -1,5 +1,4 @@ django # TODO: test_sync.py has a dependency on date parsing functions -git+https://github.com/pulp/pulp-smash.git#egg=pulp-smash productmd>=1.25 pytest<8 dictdiffer diff --git a/pulp_rpm/app/serializers/modulemd.py b/pulp_rpm/app/serializers/modulemd.py index 596651365..8f574a714 100644 --- a/pulp_rpm/app/serializers/modulemd.py +++ b/pulp_rpm/app/serializers/modulemd.py @@ -3,7 +3,7 @@ from pulpcore.plugin.serializers import DetailRelatedField, NoArtifactContentSerializer from rest_framework import serializers -from pulp_rpm.app.fields import CustomJSONField +from pulpcore.plugin.serializers import JSONDictField from pulp_rpm.app.models import Modulemd, ModulemdDefaults, ModulemdObsolete, Package @@ -32,8 +32,8 @@ class ModulemdSerializer(NoArtifactContentSerializer): arch = serializers.CharField( help_text=_("Modulemd architecture."), ) - artifacts = CustomJSONField(help_text=_("Modulemd artifacts."), allow_null=True) - dependencies = CustomJSONField(help_text=_("Modulemd dependencies."), allow_null=True) + artifacts = JSONDictField(help_text=_("Modulemd artifacts."), allow_null=True) + dependencies = JSONDictField(help_text=_("Modulemd dependencies."), allow_null=True) # TODO: The performance of this is not great, there's a noticable difference in response # time before/after. Since this will only return Package content hrefs, we might benefit # from creating a specialized version of this Field that can skip some of the work. @@ -46,7 +46,7 @@ class ModulemdSerializer(NoArtifactContentSerializer): view_name="content-rpm/packages-detail", many=True, ) - profiles = CustomJSONField(help_text=_("Modulemd profiles."), allow_null=True) + profiles = JSONDictField(help_text=_("Modulemd profiles."), allow_null=True) snippet = serializers.CharField(help_text=_("Modulemd snippet"), write_only=True) def create(self, validated_data): @@ -88,7 +88,7 @@ class ModulemdDefaultsSerializer(NoArtifactContentSerializer): module = serializers.CharField(help_text=_("Modulemd name.")) stream = serializers.CharField(help_text=_("Modulemd default stream.")) - profiles = CustomJSONField(help_text=_("Default profiles for modulemd streams.")) + profiles = serializers.JSONField(help_text=_("Default profiles for modulemd streams.")) snippet = serializers.CharField(help_text=_("Modulemd default snippet"), write_only=True) def create(self, validated_data): diff --git a/pulp_rpm/app/serializers/package.py b/pulp_rpm/app/serializers/package.py index 9e9afc5b6..e8cafdf00 100644 --- a/pulp_rpm/app/serializers/package.py +++ b/pulp_rpm/app/serializers/package.py @@ -11,6 +11,7 @@ from pulp_rpm.app.fields import CustomJSONField from rest_framework.exceptions import NotAcceptable +from pulpcore.plugin.serializers import JSONDictField, JSONListField from pulp_rpm.app.models import Package from pulp_rpm.app.shared_utils import format_nvra, read_crpackage_from_artifact @@ -78,62 +79,62 @@ class PackageSerializer(SingleArtifactContentUploadSerializer, ContentChecksumSe read_only=True, ) - changelogs = CustomJSONField( + changelogs = JSONListField( help_text=_("Changelogs that package contains"), default="[]", required=False, read_only=True, ) - files = CustomJSONField( + files = JSONListField( help_text=_("Files that package contains"), default="[]", required=False, read_only=True, ) - requires = CustomJSONField( + requires = JSONListField( help_text=_("Capabilities the package requires"), default="[]", required=False, read_only=True, ) - provides = CustomJSONField( + provides = JSONListField( help_text=_("Capabilities the package provides"), default="[]", required=False, read_only=True, ) - conflicts = CustomJSONField( + conflicts = JSONListField( help_text=_("Capabilities the package conflicts"), default="[]", required=False, read_only=True, ) - obsoletes = CustomJSONField( + obsoletes = JSONListField( help_text=_("Capabilities the package obsoletes"), default="[]", required=False, read_only=True, ) - suggests = CustomJSONField( + suggests = JSONListField( help_text=_("Capabilities the package suggests"), default="[]", required=False, read_only=True, ) - enhances = CustomJSONField( + enhances = JSONListField( help_text=_("Capabilities the package enhances"), default="[]", required=False, read_only=True, ) - recommends = CustomJSONField( + recommends = JSONListField( help_text=_("Capabilities the package recommends"), default="[]", required=False, read_only=True, ) - supplements = CustomJSONField( + supplements = JSONListField( help_text=_("Capabilities the package supplements"), default="[]", required=False, diff --git a/pulp_rpm/tests/functional/api/test_crud_content_unit.py b/pulp_rpm/tests/functional/api/test_crud_content_unit.py index 2baa93e25..07a7ca995 100644 --- a/pulp_rpm/tests/functional/api/test_crud_content_unit.py +++ b/pulp_rpm/tests/functional/api/test_crud_content_unit.py @@ -30,46 +30,48 @@ def test_crud_content_unit( ): """Test creating, reading, updating, and deleting a content unit of package type.""" # Create content unit - content_unit_original = {} + # content_unit_original = {} attrs = gen_rpm_content_attrs(signed_artifact, RPM_PACKAGE_FILENAME) response = rpm_package_api.create(**attrs) content_unit = rpm_package_api.read(monitor_task(response.task).created_resources[0]) + print("*" * 100) + print(content_unit) + print("*" * 100) # rpm package doesn't keep relative_path but the location href del attrs["relative_path"] - content_unit_original.update(content_unit.to_dict()) + # content_unit_original.update(content_unit.to_dict()) + for key, val in attrs.items(): - assert content_unit_original[key] == val + assert getattr(content_unit, key) == val # Read a content unit by its href - content_unit = rpm_package_api.read(content_unit_original["pulp_href"]).to_dict() - for key, val in content_unit_original.items(): - assert content_unit[key] == val + response = rpm_package_api.read(content_unit.pulp_href) + assert response == content_unit # Read a content unit by its pkg_id - page = rpm_package_api.list(pkg_id=content_unit_original["pkg_id"]) + page = rpm_package_api.list(pkg_id=content_unit.pkg_id) assert len(page.results) == 1 - for key, val in content_unit_original.items(): - assert page.results[0].to_dict()[key] == val + assert page.results[0] == content_unit # Attempt to update a content unit using HTTP PATCH attrs = gen_rpm_content_attrs(signed_artifact, RPM_PACKAGE_FILENAME2) with pytest.raises(AttributeError) as exc: - rpm_package_api.partial_update(content_unit_original["pulp_href"], attrs) + rpm_package_api.partial_update(content_unit.pulp_href, attrs) msg = "object has no attribute 'partial_update'" assert msg in str(exc) # Attempt to update a content unit using HTTP PUT attrs = gen_rpm_content_attrs(signed_artifact, RPM_PACKAGE_FILENAME2) with pytest.raises(AttributeError) as exc: - rpm_package_api.update(content_unit_original["pulp_href"], attrs) + rpm_package_api.update(content_unit.pulp_href, attrs) msg = "object has no attribute 'update'" assert msg in str(exc) # Attempt to delete a content unit using HTTP DELETE with pytest.raises(AttributeError) as exc: - rpm_package_api.delete(content_unit_original["pulp_href"]) + rpm_package_api.delete(content_unit.pulp_href) msg = "object has no attribute 'delete'" assert msg in str(exc) @@ -77,7 +79,7 @@ def test_crud_content_unit( attrs = gen_rpm_content_attrs(signed_artifact, RPM_PACKAGE_FILENAME) response = rpm_package_api.create(**attrs) duplicate = rpm_package_api.read(monitor_task(response.task).created_resources[0]) - assert duplicate.pulp_href == content_unit_original["pulp_href"] + assert duplicate.pulp_href == content_unit.pulp_href # Attempt to create duplicate package while specifying a repository repo = rpm_repository_factory() @@ -87,7 +89,7 @@ def test_crud_content_unit( monitored_response = monitor_task(response.task) duplicate = rpm_package_api.read(monitored_response.created_resources[1]) - assert duplicate.pulp_href == content_unit_original["pulp_href"] + assert duplicate.pulp_href == content_unit.pulp_href repo = rpm_repository_api.read(repo.pulp_href) assert repo.latest_version_href.endswith("/versions/1/") @@ -131,7 +133,7 @@ def test_remove_content_unit(url, init_and_sync, rpm_repository_version_api, bin # iterate over particular content units and issue delete requests for content_unit in response["results"]: - url = urljoin(bindings_cfg.host, content_unit["pulp_href"]) + url = urljoin(bindings_cfg.host, content_unit.pulp_href) resp = requests.delete(url, auth=auth) # check that '405' (method not allowed) is returned @@ -147,7 +149,7 @@ def test_create_modulemd_defaults(monitor_task, gen_object_with_cleanup, rpm_mod request_1 = { "module": "squid", "stream": "4", - "profiles": '{"4": ["common"]}', + "profiles": {"4": ["common"]}, "snippet": dedent( """\ --- diff --git a/pulp_rpm/tests/functional/api/test_crud_remotes.py b/pulp_rpm/tests/functional/api/test_crud_remotes.py index 3364c409f..6f61a177f 100644 --- a/pulp_rpm/tests/functional/api/test_crud_remotes.py +++ b/pulp_rpm/tests/functional/api/test_crud_remotes.py @@ -115,15 +115,15 @@ def test_policy_update_changes(rpm_rpmremote_api, rpm_rpmremote_factory, monitor # Verify ability to change policy to value other than the default changed_policy = choice([item for item in DOWNLOAD_POLICIES if item != "immediate"]) - response = rpm_rpmremote_api.partial_update(remote["pulp_href"], {"policy": changed_policy}) + response = rpm_rpmremote_api.partial_update(remote.pulp_href, {"policy": changed_policy}) monitor_task(response.task) - remote = rpm_rpmremote_api.read(remote["pulp_href"]).to_dict() - assert remote["policy"] == changed_policy, remote + remote = rpm_rpmremote_api.read(remote.pulp_href) + assert remote.policy == changed_policy, remote # Verify an invalid policy does not update the remote policy with pytest.raises(ApiException): - rpm_rpmremote_api.partial_update(remote["pulp_href"], {"policy": str(uuid4())}) + rpm_rpmremote_api.partial_update(remote.pulp_href, {"policy": str(uuid4())}) def test_raise_on_invalid_remote_url( diff --git a/pulp_rpm/tests/functional/api/test_rbac_crud.py b/pulp_rpm/tests/functional/api/test_rbac_crud.py index a8347fd75..f185274de 100644 --- a/pulp_rpm/tests/functional/api/test_rbac_crud.py +++ b/pulp_rpm/tests/functional/api/test_rbac_crud.py @@ -52,14 +52,14 @@ def test_rbac_repositories(gen_user, rpm_repository_factory, rpm_repository_api, with user_creator: repo_data = repo.to_dict() repo_data.update(name="rpm_repo_test_modify") - response = rpm_repository_api.update(repo_data["pulp_href"], repo_data) + response = rpm_repository_api.update(repo_data.pulp_href, repo_data) monitor_task(response.task) assert rpm_repository_api.read(repo.pulp_href).name == "rpm_repo_test_modify" with user_no, pytest.raises(ApiException) as exc: repo_data = repo.to_dict() repo_data.update(name="rpm_repo_test_modify_without_perms") - rpm_repository_api.update(repo_data["pulp_href"], repo_data) + rpm_repository_api.update(repo_data.pulp_href, repo_data) # Here is response `404` as user doesn't have even permission to retrieve repo data # so pulp response with not found instead `access denied` to not expose it exists assert exc.value.status == 404 @@ -67,7 +67,7 @@ def test_rbac_repositories(gen_user, rpm_repository_factory, rpm_repository_api, with user_viewer, pytest.raises(ApiException) as exc: repo_data = repo.to_dict() repo_data.update(name="rpm_repo_test_modify_with_view_perms") - rpm_repository_api.update(repo_data["pulp_href"], repo_data) + rpm_repository_api.update(repo_data.pulp_href, repo_data) # Fails with '403' as a repo can be seen but not updated. assert exc.value.status == 403 diff --git a/pulp_rpm/tests/functional/api/test_sync.py b/pulp_rpm/tests/functional/api/test_sync.py index 103606df3..ec41f57ce 100644 --- a/pulp_rpm/tests/functional/api/test_sync.py +++ b/pulp_rpm/tests/functional/api/test_sync.py @@ -14,7 +14,6 @@ get_added_content_summary, get_added_content, get_content, - get_content_summary, get_removed_content, wget_download_on_host, ) @@ -79,22 +78,22 @@ @pytest.mark.parallel -def test_sync(init_and_sync): +def test_sync(init_and_sync, rpm_repository_version_api): """Sync repositories with the rpm plugin.""" # Create a remote (default) and empty repository - repository, remote = init_and_sync() + repository_s0, remote = init_and_sync() # Assert that it's synced properly - latest_version_href = repository.latest_version_href - assert get_content_summary(repository.to_dict()) == RPM_FIXTURE_SUMMARY - assert get_added_content_summary(repository.to_dict()) == RPM_FIXTURE_SUMMARY + response = rpm_repository_version_api.read(repository_s0.latest_version_href) + assert response.content_summary.model_dump()["present"] == RPM_FIXTURE_SUMMARY # Sync the same repository again - repository, _ = init_and_sync(repository=repository, remote=remote) + repository_s1, _ = init_and_sync(repository=repository_s0, remote=remote) # Assert that the repository has not changed, the latest version stays the same - assert latest_version_href == repository.latest_version_href - assert get_content_summary(repository.to_dict()) == RPM_FIXTURE_SUMMARY + assert repository_s0.latest_version_href == repository_s1.latest_version_href + response = rpm_repository_version_api.read(repository_s1.latest_version_href) + assert response.content_summary.model_dump()["present"] == RPM_FIXTURE_SUMMARY @pytest.mark.parallel @@ -379,7 +378,7 @@ def test_optimize( repository = rpm_repository_api.read(repository.pulp_href) content = choice(get_content(repository.to_dict())[RPM_PACKAGE_CONTENT_NAME]) response = rpm_repository_api.modify( - repository.pulp_href, {"remove_content_units": [content["pulp_href"]]} + repository.pulp_href, {"remove_content_units": [content.pulp_href]} ) monitor_task(response.task) @@ -969,9 +968,6 @@ def test_treeinfo_metadata(init_and_sync, rpm_content_distribution_trees_api): repository_version=repository.latest_version_href ).results[0] distribution_tree = distribution_tree.to_dict() - # delete pulp-specific metadata - distribution_tree.pop("pulp_href") - distribution_tree.pop("prn") # sort kickstart metadata so that we can compare the dicts properly for d in [distribution_tree, RPM_KICKSTART_DATA]: diff --git a/pulp_rpm/tests/functional/conftest.py b/pulp_rpm/tests/functional/conftest.py index 60cec36b4..af1a490ef 100644 --- a/pulp_rpm/tests/functional/conftest.py +++ b/pulp_rpm/tests/functional/conftest.py @@ -118,13 +118,13 @@ def signed_artifact(pulpcore_bindings, tmp_path): sha256=hashlib.sha256(data).hexdigest(), limit=1 ) try: - return artifacts.results[0].to_dict() + return artifacts.results[0] except IndexError: pass temp_file = tmp_path / str(uuid.uuid4()) temp_file.write_bytes(data) - return pulpcore_bindings.ArtifactsApi.create(temp_file).to_dict() + return pulpcore_bindings.ArtifactsApi.create(str(temp_file)) @pytest.fixture diff --git a/pulp_rpm/tests/functional/utils.py b/pulp_rpm/tests/functional/utils.py index 41823b874..bcea21a9a 100644 --- a/pulp_rpm/tests/functional/utils.py +++ b/pulp_rpm/tests/functional/utils.py @@ -79,7 +79,7 @@ def gen_rpm_content_attrs(artifact, rpm_name): :param artifact: A dict of info about the artifact. :returns: A semi-random dict for use in creating a content unit. """ - return {"artifact": artifact["pulp_href"], "relative_path": rpm_name} + return {"artifact": artifact.pulp_href, "relative_path": rpm_name} def rpm_copy(cfg, config, recursive=False): @@ -113,7 +113,7 @@ def publish(cfg, repo, version_href=None, repo_config=None): if version_href: body = {"repository_version": version_href} else: - body = {"repository": repo["pulp_href"]} + body = {"repository": repo.pulp_href} body.update({"repo_config": repo_config})