From afb221fce2422770b941135eb3b0e02f8bbd6d16 Mon Sep 17 00:00:00 2001 From: James Tanner Date: Thu, 24 Oct 2024 18:16:47 -0400 Subject: [PATCH 1/5] Fix latest_version_modified annotation. The previous code was using the updated timestamp of the repository version the content was added into. That ended up with in some cases an updated_at timestamp that was older than the created_at timestamp. [noissue] Signed-off-by: James Tanner --- pulp_ansible/app/galaxy/v3/views.py | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/pulp_ansible/app/galaxy/v3/views.py b/pulp_ansible/app/galaxy/v3/views.py index 94bf2638b..6b5fd8a80 100644 --- a/pulp_ansible/app/galaxy/v3/views.py +++ b/pulp_ansible/app/galaxy/v3/views.py @@ -335,24 +335,6 @@ def get_queryset(self): .only("version") ) - latest_version_modified_qs = ( - RepositoryContent.objects.filter( - repository_id=repo_version.repository_id, - version_added__number__lte=repo_version.number, - ) - .select_related("content__ansible_collectionversion") - .select_related("version_added") - .select_related("version_removed") - .filter(content__ansible_collectionversion__collection_id=OuterRef("pk")) - .annotate( - last_updated=Greatest( - "version_added__pulp_created", "version_removed__pulp_created" - ) - ) - .order_by("-last_updated") - .only("last_updated") - ) - download_count_qs = CollectionDownloadCount.objects.filter( name=OuterRef("name"), namespace=OuterRef("namespace") ) @@ -360,9 +342,7 @@ def get_queryset(self): qs = ( Collection.objects.annotate( highest_version=Subquery(latest_cv_version_qs.values("version")[:1]), - latest_version_modified=Subquery( - latest_version_modified_qs.values("last_updated")[:1] - ), + latest_version_modified=Subquery(latest_cv_version_qs.values("pulp_last_updated")[:1]), ) .annotate( deprecated=Exists(deprecated_qs), From 1ca96ab24c27f4fac980b77cb66f5efb4e3dd8f8 Mon Sep 17 00:00:00 2001 From: James Tanner Date: Thu, 24 Oct 2024 18:40:47 -0400 Subject: [PATCH 2/5] Black fix. [noissue] Signed-off-by: James Tanner --- pulp_ansible/app/galaxy/v3/views.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pulp_ansible/app/galaxy/v3/views.py b/pulp_ansible/app/galaxy/v3/views.py index 6b5fd8a80..6c8adf533 100644 --- a/pulp_ansible/app/galaxy/v3/views.py +++ b/pulp_ansible/app/galaxy/v3/views.py @@ -342,7 +342,9 @@ def get_queryset(self): qs = ( Collection.objects.annotate( highest_version=Subquery(latest_cv_version_qs.values("version")[:1]), - latest_version_modified=Subquery(latest_cv_version_qs.values("pulp_last_updated")[:1]), + latest_version_modified=Subquery( + latest_cv_version_qs.values("pulp_last_updated")[:1] + ), ) .annotate( deprecated=Exists(deprecated_qs), From db3a56d8b30f7686025b182ab95640b236b4a3a2 Mon Sep 17 00:00:00 2001 From: James Tanner Date: Thu, 24 Oct 2024 18:42:38 -0400 Subject: [PATCH 3/5] More lint [noissue] Signed-off-by: James Tanner --- pulp_ansible/app/galaxy/v3/views.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/pulp_ansible/app/galaxy/v3/views.py b/pulp_ansible/app/galaxy/v3/views.py index 6c8adf533..6236d346a 100644 --- a/pulp_ansible/app/galaxy/v3/views.py +++ b/pulp_ansible/app/galaxy/v3/views.py @@ -5,7 +5,6 @@ from django.db import DatabaseError, IntegrityError from django.db.models import F, OuterRef, Exists, Subquery, Prefetch -from django.db.models.functions import Greatest from django.http import StreamingHttpResponse, HttpResponseNotFound from django.shortcuts import get_object_or_404, redirect from django.utils.dateparse import parse_datetime @@ -31,7 +30,6 @@ Artifact, Content, ContentArtifact, - RepositoryContent, Distribution, ) from pulpcore.plugin.serializers import AsyncOperationResponseSerializer From cd85827c2ea935a4359a69004cf7cb1bc3050be9 Mon Sep 17 00:00:00 2001 From: James Tanner Date: Fri, 25 Oct 2024 10:15:06 -0400 Subject: [PATCH 4/5] Update the functional test. [noissue] Signed-off-by: James Tanner --- .../api/collection/v3/test_serializers.py | 45 +++++++++++++++---- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/pulp_ansible/tests/functional/api/collection/v3/test_serializers.py b/pulp_ansible/tests/functional/api/collection/v3/test_serializers.py index 02a3e0699..e18f38c2b 100644 --- a/pulp_ansible/tests/functional/api/collection/v3/test_serializers.py +++ b/pulp_ansible/tests/functional/api/collection/v3/test_serializers.py @@ -1,6 +1,9 @@ """Tests related to Galaxy V3 serializers.""" +import yaml + from pulpcore.client.pulp_ansible import ( + AnsibleRepositorySyncURL, ContentCollectionVersionsApi, DistributionsAnsibleApi, PulpAnsibleApiV3CollectionsApi, @@ -12,6 +15,7 @@ from pulp_ansible.tests.functional.utils import SyncHelpersMixin, TestCaseUsingBindings from pulp_ansible.tests.functional.utils import gen_ansible_client, gen_ansible_remote +from pulp_ansible.tests.functional.utils import tasks class CollectionsV3TestCase(TestCaseUsingBindings, SyncHelpersMixin): @@ -30,9 +34,23 @@ def setUpClass(cls): def test_v3_updated_at(self): """Test Collections V3 endpoint field: ``updated_at``.""" + + requirements1 = """ + collections: + - name: "pulp.squeezer" + version: "0.0.7" + """ + + requirements2 = """ + collections: + - name: "pulp.squeezer" + version: "0.0.17" + """ + + # sync the first version ... body = gen_ansible_remote( url="https://galaxy.ansible.com", - requirements_file="collections:\n - pulp.squeezer", + requirements_file=requirements1, sync_dependencies=False, ) remote = self.remote_collection_api.create(body) @@ -51,20 +69,31 @@ def test_v3_updated_at(self): "squeezer", "pulp", distribution.base_path ).meta.count - data = {"remove_content_units": [versions.results[0].pulp_href]} - response = self.repo_api.modify(repo.pulp_href, data) - monitor_task(response.task) - + # sync the second version ... + body = gen_ansible_remote( + url="https://galaxy.ansible.com", + requirements_file=requirements2, + sync_dependencies=False, + ) + self.remote_collection_api.update(remote.pulp_href, body) + repository_sync_data = AnsibleRepositorySyncURL(remote=remote.pulp_href, optimize=True) + sync_response = self.repo_api.sync(repo.pulp_href, repository_sync_data) + monitor_task(sync_response.task) + task = tasks.read(sync_response.task) + self.assertEqual(task.state, "completed") + + # enumerate new data after 2nd sync ... collections = self.collections_api.list(distribution.base_path) highest_version = collections.data[0].highest_version["version"] updated_at = collections.data[0].updated_at - total_versions = self.collections_versions_v3api.list( "squeezer", "pulp", distribution.base_path ).meta.count - self.assertEqual(highest_version, original_highest_version) - self.assertEqual(original_total_versions, total_versions + 1) + self.assertEqual(original_highest_version, "0.0.7") + self.assertEqual(highest_version, "0.0.17") + self.assertEqual(original_total_versions, 1) + self.assertEqual(total_versions, 2) self.assertGreater(updated_at, original_updated_at) def test_v3_collection_version_from_synced_data(self): From 36294e96380b03a4b0058d78569698571692badb Mon Sep 17 00:00:00 2001 From: James Tanner Date: Fri, 25 Oct 2024 10:25:51 -0400 Subject: [PATCH 5/5] Fix flake8. [noissue] Signed-off-by: James Tanner --- .../tests/functional/api/collection/v3/test_serializers.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/pulp_ansible/tests/functional/api/collection/v3/test_serializers.py b/pulp_ansible/tests/functional/api/collection/v3/test_serializers.py index e18f38c2b..cf09229dc 100644 --- a/pulp_ansible/tests/functional/api/collection/v3/test_serializers.py +++ b/pulp_ansible/tests/functional/api/collection/v3/test_serializers.py @@ -1,7 +1,5 @@ """Tests related to Galaxy V3 serializers.""" -import yaml - from pulpcore.client.pulp_ansible import ( AnsibleRepositorySyncURL, ContentCollectionVersionsApi, @@ -64,7 +62,6 @@ def test_v3_updated_at(self): original_highest_version = collections.data[0].highest_version["version"] original_updated_at = collections.data[0].updated_at - versions = self.collections_versions_api.list(version="0.0.7") original_total_versions = self.collections_versions_v3api.list( "squeezer", "pulp", distribution.base_path ).meta.count