diff --git a/pulp_deb/app/tasks/copy.py b/pulp_deb/app/tasks/copy.py index 96df5fa6..76b7236c 100644 --- a/pulp_deb/app/tasks/copy.py +++ b/pulp_deb/app/tasks/copy.py @@ -41,11 +41,14 @@ def find_structured_publish_content(content, source_repo_version): prc_qs = PackageReleaseComponent.objects.filter(pk__in=prc_content_qs.only("pk")) # ReleaseComponents: + release_components = prc_qs.values_list( + "release_component_id", "release_component__distribution" + ).distinct() release_component_ids = set() distributions = set() - for prc in prc_qs.select_related("release_component").iterator(): - release_component_ids.add(prc.release_component.pk) - distributions.add(prc.release_component.distribution) + for release_component_id, distribution in release_components: + release_component_ids.add(release_component_id) + distributions.add(distribution) release_component_content_qs = source_repo_version.content.filter( pk__in=release_component_ids diff --git a/pulp_deb/tests/unit/test_copy.py b/pulp_deb/tests/unit/test_copy.py new file mode 100644 index 00000000..033ec32d --- /dev/null +++ b/pulp_deb/tests/unit/test_copy.py @@ -0,0 +1,50 @@ +from uuid import UUID + +import pytest + +from pulp_deb.app.models import ( + AptRepository, + Package, + PackageReleaseComponent, + ReleaseComponent, +) +from pulp_deb.app.tasks.copy import find_structured_publish_content + + +@pytest.mark.django_db +def test_structured_copy_handles_query_exceeding_psycopg_parameter_limit(): + repository = AptRepository.objects.create(name="oversized-copy-source") + + package = Package.objects.create( + package="test-package", + version="1.0", + architecture="amd64", + relative_path="pool/t/test-package/test-package_1.0_amd64.deb", + sha256="a" * 64, + ) + release_component = ReleaseComponent.objects.create( + distribution="stable", + component="main", + ) + package_release_component = PackageReleaseComponent.objects.create( + package=package, + release_component=release_component, + ) + + with repository.new_version() as source_version: + source_version.add_content(Package.objects.filter(pk=package.pk)) + source_version.add_content( + PackageReleaseComponent.objects.filter(pk=package_release_component.pk) + ) + source_version.add_content(ReleaseComponent.objects.filter(pk=release_component.pk)) + + # Reproduce content selection large enhough to exceet postgres limits + # when evaluating through a server side cursor. + content_pks = [UUID(int=value) for value in range(1, 65_537)] + content_pks.append(package.pk) + content = source_version.content.filter(pk__in=content_pks) + + result = find_structured_publish_content(content, source_version) + assert result.filter(pk=package.pk).exists() + assert result.filter(pk=package_release_component.pk).exists() + assert result.filter(pk=release_component.pk).exists()