← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~enriqueesanchz/launchpad:fix-bugtask-model-sort-key into launchpad:master

 

Enrique Sánchez has proposed merging ~enriqueesanchz/launchpad:fix-bugtask-model-sort-key into launchpad:master.

Commit message:
Add packagetype, channel in bugtask model sort key

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~enriqueesanchz/launchpad/+git/launchpad/+merge/494915
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~enriqueesanchz/launchpad:fix-bugtask-model-sort-key into launchpad:master.
diff --git a/lib/lp/bugs/browser/bugtask.py b/lib/lp/bugs/browser/bugtask.py
index 270167d..3ead7cc 100644
--- a/lib/lp/bugs/browser/bugtask.py
+++ b/lib/lp/bugs/browser/bugtask.py
@@ -138,6 +138,7 @@ from lp.registry.interfaces.product import IProduct
 from lp.registry.interfaces.productseries import IProductSeries
 from lp.registry.interfaces.sourcepackage import ISourcePackage
 from lp.registry.model.personroles import PersonRoles
+from lp.services.channels import channel_list_to_string
 from lp.services.config import config
 from lp.services.features import getFeatureFlag
 from lp.services.feeds.browser import FeedsMixin
@@ -1885,7 +1886,7 @@ def bugtask_sort_key(bugtask):
             bugtask.target.sourcepackagename.name,
             bugtask.target.distribution.displayname,
             bugtask.target.packagetype,
-            bugtask.target.channel,
+            channel_list_to_string(*bugtask.target.channel),
             None,
             None,
             None,
@@ -1905,7 +1906,7 @@ def bugtask_sort_key(bugtask):
             bugtask.target.sourcepackagename.name,
             bugtask.target.distribution.displayname,
             bugtask.target.packagetype,
-            bugtask.target.channel,
+            channel_list_to_string(*bugtask.target.channel),
             Version(bugtask.target.distroseries.version),
             None,
             None,
diff --git a/lib/lp/bugs/configure.zcml b/lib/lp/bugs/configure.zcml
index ea98516..8ebd8c2 100644
--- a/lib/lp/bugs/configure.zcml
+++ b/lib/lp/bugs/configure.zcml
@@ -209,6 +209,7 @@
                     product_id
                     productseries_id
                     packagetype
+                    channel
                     sourcepackagename_id
                     task_age
                     bug_subscribers
diff --git a/lib/lp/bugs/model/bugtask.py b/lib/lp/bugs/model/bugtask.py
index c3fb364..a5499fd 100644
--- a/lib/lp/bugs/model/bugtask.py
+++ b/lib/lp/bugs/model/bugtask.py
@@ -103,6 +103,7 @@ from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet
 from lp.registry.model.pillar import pillar_sort_key
 from lp.registry.model.sourcepackagename import SourcePackageName
 from lp.services import features
+from lp.services.channels import channel_list_to_string
 from lp.services.database.bulk import create, load, load_related
 from lp.services.database.constants import UTC_NOW
 from lp.services.database.decoratedresultset import DecoratedResultSet
@@ -137,6 +138,8 @@ def bugtask_sort_key(bugtask):
     distroseries_name = ""
     sourcepackage_name = ""
     ociproject = ""
+    packagetype = ""
+    channel = ""
 
     if bugtask.product:
         product_name = bugtask.product.name
@@ -154,6 +157,12 @@ def bugtask_sort_key(bugtask):
     if bugtask.sourcepackagename:
         sourcepackage_name = bugtask.sourcepackagename.name
 
+    if bugtask.packagetype:
+        packagetype = bugtask.packagetype.name
+
+    if bugtask.channel:
+        channel = channel_list_to_string(*bugtask.channel)
+
     # Move ubuntu to the top.
     if distribution_name == "ubuntu":
         distribution_name = "-"
@@ -166,6 +175,8 @@ def bugtask_sort_key(bugtask):
         distroseries_name,
         sourcepackage_name,
         ociproject,
+        packagetype,
+        channel,
     )
 
 
diff --git a/lib/lp/bugs/model/tests/test_bugtask.py b/lib/lp/bugs/model/tests/test_bugtask.py
index 54a39e2..894da33 100644
--- a/lib/lp/bugs/model/tests/test_bugtask.py
+++ b/lib/lp/bugs/model/tests/test_bugtask.py
@@ -38,6 +38,7 @@ from lp.bugs.model.bugtask import (
     IllegalTarget,
     bug_target_from_key,
     bug_target_to_key,
+    bugtask_sort_key,
     validate_new_target,
     validate_target,
 )
@@ -61,6 +62,7 @@ from lp.registry.interfaces.person import IPersonSet
 from lp.registry.interfaces.product import IProductSet
 from lp.registry.interfaces.projectgroup import IProjectGroupSet
 from lp.registry.interfaces.sourcepackage import ISourcePackage
+from lp.registry.model.externalpackage import ExternalPackageType
 from lp.registry.model.sourcepackage import SourcePackage
 from lp.registry.tests.test_accesspolicy import get_policies_for_artifact
 from lp.services.database.sqlbase import (
@@ -4109,3 +4111,125 @@ class TestTargetNameCache(TestCase):
         self.assertEqual(
             upstream_task.bugtargetdisplayname, "Mozilla Thunderbird"
         )
+
+
+class TestBugTaskSortKey(TestCaseWithFactory):
+    layer = DatabaseFunctionalLayer
+
+    def setUp(self):
+        super().setUp()
+        # Set up group a
+        product_a = self.factory.makeProduct(name="product-a")
+        productseries_a = self.factory.makeProductSeries(
+            product=product_a, name="a"
+        )
+        distro_a = self.factory.makeDistribution(name="distro-a")
+        distroseries_a = self.factory.makeDistroSeries(
+            distribution=distro_a, name="a"
+        )
+        sourcepackage_a = self.factory.makeSourcePackage(
+            sourcepackagename="source-a",
+            distroseries=distroseries_a,
+        )
+        distrosourcepackage_a = self.factory.makeDistributionSourcePackage(
+            distribution=distro_a, sourcepackagename="source-a"
+        )
+        externalpackage_a = self.factory.makeExternalPackage(
+            distribution=distro_a,
+            sourcepackagename="source-a",
+            packagetype=ExternalPackageType.SNAP,
+            channel=("12.1", "stable", None),
+        )
+        externalpackage_a2 = self.factory.makeExternalPackage(
+            distribution=distro_a,
+            sourcepackagename="source-a",
+            packagetype=ExternalPackageType.SNAP,
+            channel=("12.1", "stable", "branch"),
+        )
+        externalpackageseries_a = self.factory.makeExternalPackageSeries(
+            distroseries=distroseries_a,
+            sourcepackagename="source-a",
+            packagetype=ExternalPackageType.SNAP,
+            channel=("12.1", "stable"),
+        )
+
+        # Set up group b
+        product_b = self.factory.makeProduct(name="product-b")
+        productseries_b = self.factory.makeProductSeries(
+            product=product_b, name="b"
+        )
+        distro_b = self.factory.makeDistribution(name="distro-b")
+        distroseries_b = self.factory.makeDistroSeries(
+            distribution=distro_b, name="b"
+        )
+        sourcepackage_b = self.factory.makeSourcePackage(
+            sourcepackagename="source-b",
+            distroseries=distroseries_b,
+        )
+        distrosourcepackage_b = self.factory.makeDistributionSourcePackage(
+            distribution=distro_b, sourcepackagename="source-b"
+        )
+        externalpackage_b = self.factory.makeExternalPackage(
+            distribution=distro_b,
+            sourcepackagename="source-b",
+            packagetype=ExternalPackageType.CHARM,
+            channel=("12.1", "stable", None),
+        )
+        externalpackageseries_b = self.factory.makeExternalPackageSeries(
+            distroseries=distroseries_b,
+            sourcepackagename="source-b",
+            packagetype=ExternalPackageType.CHARM,
+            channel="stable",
+        )
+        self.bugtasks_targets = [
+            product_a,
+            productseries_a,
+            distrosourcepackage_a,
+            sourcepackage_a,
+            externalpackage_a,
+            externalpackage_a2,
+            externalpackageseries_a,
+            product_b,
+            productseries_b,
+            sourcepackage_b,
+            distrosourcepackage_b,
+            externalpackage_b,
+            externalpackageseries_b,
+        ]
+        # Expected order after sorting
+        self.ordered_bugtasks_targets = [
+            product_a,
+            productseries_a,
+            product_b,
+            productseries_b,
+            distrosourcepackage_a,
+            externalpackage_a,
+            externalpackage_a2,
+            sourcepackage_a,
+            externalpackageseries_a,
+            distrosourcepackage_b,
+            externalpackage_b,
+            sourcepackage_b,
+            externalpackageseries_b,
+        ]
+
+    def test_sorting_key_comparisons(self):
+        """
+        Tests the 'bugtask_sort_key' logic.
+
+        The key function returns a tuple, and Python's tuple sorting rules
+        determine the order.
+        """
+        bug = self.factory.makeBug()
+
+        bugtasks = []
+        for target in self.bugtasks_targets:
+            bugtask = self.factory.makeBugTask(bug=bug, target=target)
+            bugtasks.append(bugtask)
+
+        bugtasks.sort(key=bugtask_sort_key)
+
+        for bugtask, expected_target in zip(
+            bugtasks, self.ordered_bugtasks_targets
+        ):
+            self.assertEqual(expected_target, bugtask.target)
diff --git a/lib/lp/bugs/scripts/soss/tests/test_sossimport.py b/lib/lp/bugs/scripts/soss/tests/test_sossimport.py
index 9321a65..8eb3e97 100644
--- a/lib/lp/bugs/scripts/soss/tests/test_sossimport.py
+++ b/lib/lp/bugs/scripts/soss/tests/test_sossimport.py
@@ -84,50 +84,50 @@ class TestSOSSImporter(TestCaseWithFactory):
             (
                 self.soss.getExternalPackage(
                     name=ray,
-                    packagetype=ExternalPackageType.CONDA,
-                    channel=("jammy:1.17.0", "stable"),
+                    packagetype=ExternalPackageType.CARGO,
+                    channel=("focal:0.27.0", "stable"),
                 ),
-                BugTaskStatus.INVALID,
+                BugTaskStatus.DEFERRED,
                 "2.22.0+soss.1",
                 {"repositories": ["nvidia-pb3-python-stable-local"]},
             ),
             (
                 self.soss.getExternalPackage(
                     name=ray,
-                    packagetype=ExternalPackageType.PYTHON,
-                    channel=("jammy:2.22.0", "stable"),
+                    packagetype=ExternalPackageType.CONDA,
+                    channel=("jammy:1.17.0", "stable"),
                 ),
-                BugTaskStatus.FIXRELEASED,
+                BugTaskStatus.INVALID,
                 "2.22.0+soss.1",
                 {"repositories": ["nvidia-pb3-python-stable-local"]},
             ),
             (
                 self.soss.getExternalPackage(
                     name=ray,
-                    packagetype=ExternalPackageType.CARGO,
-                    channel=("focal:0.27.0", "stable"),
+                    packagetype=ExternalPackageType.PYTHON,
+                    channel=("jammy:2.22.0", "stable"),
                 ),
-                BugTaskStatus.DEFERRED,
+                BugTaskStatus.FIXRELEASED,
                 "2.22.0+soss.1",
                 {"repositories": ["nvidia-pb3-python-stable-local"]},
             ),
             (
                 self.soss.getExternalPackage(
                     name=vllm,
-                    packagetype=ExternalPackageType.MAVEN,
+                    packagetype=ExternalPackageType.GENERIC,
                     channel=("noble:0.7.3", "stable"),
                 ),
-                BugTaskStatus.UNKNOWN,
+                BugTaskStatus.NEW,
                 "",
                 {"repositories": ["soss-src-stable-local"]},
             ),
             (
                 self.soss.getExternalPackage(
                     name=vllm,
-                    packagetype=ExternalPackageType.GENERIC,
+                    packagetype=ExternalPackageType.MAVEN,
                     channel=("noble:0.7.3", "stable"),
                 ),
-                BugTaskStatus.NEW,
+                BugTaskStatus.UNKNOWN,
                 "",
                 {"repositories": ["soss-src-stable-local"]},
             ),
@@ -286,7 +286,7 @@ class TestSOSSImporter(TestCaseWithFactory):
 
         self.soss_record.packages.pop(SOSSRecord.PackageTypeEnum.UNPACKAGED)
         self.soss_record.packages.pop(SOSSRecord.PackageTypeEnum.MAVEN)
-        self.soss_record.packages.pop(SOSSRecord.PackageTypeEnum.RUST)
+        self.soss_record.packages.pop(SOSSRecord.PackageTypeEnum.PYTHON)
 
         soss_importer = SOSSImporter(
             self.soss, information_type=InformationType.PROPRIETARY
@@ -302,7 +302,7 @@ class TestSOSSImporter(TestCaseWithFactory):
 
         # Check bugtasks
         bugtasks = bug.bugtasks
-        bugtask_reference = self.bugtask_reference[:3]
+        bugtask_reference = self.bugtask_reference[1:3]
         self._check_bugtasks(
             bugtasks, bugtask_reference, BugTaskImportance.LOW, self.janitor
         )
@@ -348,7 +348,7 @@ class TestSOSSImporter(TestCaseWithFactory):
         self.assertEqual(vulnerability.bugs[0], bug)
 
     def test_create_or_update_bugtasks(self):
-        """Test update bugtasks"""
+        """Test that bugtasks are updated, removed, and modified correctly."""
         soss_importer = SOSSImporter(self.soss)
         bug = soss_importer._create_bug(self.soss_record, self.cve)
         soss_importer._create_or_update_bugtasks(bug, self.soss_record)
@@ -360,41 +360,79 @@ class TestSOSSImporter(TestCaseWithFactory):
             self.janitor,
         )
 
-        # Update soss_record and check that the bugtasks change
-        self.soss_record.assigned_to = "bug-importer"
-        self.soss_record.priority = SOSSRecord.PriorityEnum.HIGH
+        ray = self.source_package_name_set.getOrCreateByName("ray")
+        vllm = self.source_package_name_set.getOrCreateByName("vllm")
 
-        # Remove 2 packages from the soss_record
+        # Remove the PYTHON packages
         self.soss_record.packages.pop(SOSSRecord.PackageTypeEnum.PYTHON)
 
-        # Modify a package
+        # The two PYTHON packages are gone, and the CONDA package is modified.
+        expected_updated_bugtasks = [
+            (
+                self.soss.getExternalPackage(
+                    name=ray,
+                    packagetype=ExternalPackageType.CARGO,
+                    channel=("focal:0.27.0", "stable"),
+                ),
+                BugTaskStatus.DEFERRED,
+                "2.22.0+soss.1",
+                {"repositories": ["nvidia-pb3-python-stable-local"]},
+            ),
+            (
+                self.soss.getExternalPackage(
+                    name=ray,
+                    packagetype=ExternalPackageType.CONDA,
+                    channel=("noble:5.23.1", "stable"),  # Changed channel
+                ),
+                BugTaskStatus.DEFERRED,  # Changed status
+                "test note",  # Changed note
+                {"repositories": ["test-repo"]},  # Changed repo
+            ),
+            (
+                self.soss.getExternalPackage(
+                    name=vllm,
+                    packagetype=ExternalPackageType.GENERIC,
+                    channel=("noble:0.7.3", "stable"),
+                ),
+                BugTaskStatus.NEW,
+                "",
+                {"repositories": ["soss-src-stable-local"]},
+            ),
+            (
+                self.soss.getExternalPackage(
+                    name=vllm,
+                    packagetype=ExternalPackageType.MAVEN,
+                    channel=("noble:0.7.3", "stable"),
+                ),
+                BugTaskStatus.UNKNOWN,
+                "",
+                {"repositories": ["soss-src-stable-local"]},
+            ),
+        ]
+
+        # Modify the soss_record to trigger the update
+        self.soss_record.assigned_to = "bug-importer"
+        self.soss_record.priority = SOSSRecord.PriorityEnum.HIGH
+
+        # Modify the CONDA package
         self.soss_record.packages[SOSSRecord.PackageTypeEnum.CONDA] = (
             SOSSRecord.Package(
-                name="aaa",
-                channel=SOSSRecord.Channel(value="noble:4.23.1/stable"),
+                name="ray",
+                channel=SOSSRecord.Channel(value="noble:5.23.1/stable"),
                 repositories=["test-repo"],
                 status=SOSSRecord.PackageStatusEnum.DEFERRED,
                 note="test note",
             ),
         )
-        # Modify its bugtask_reference
-        self.bugtask_reference[2] = (
-            self.soss.getExternalPackage(
-                name=self.source_package_name_set.getOrCreateByName("aaa"),
-                packagetype=ExternalPackageType.CONDA,
-                channel=("noble:4.23.1", "stable"),
-            ),
-            BugTaskStatus.DEFERRED,
-            "test note",
-            {"repositories": ["test-repo"]},
-        )
 
+        # Run the update
         soss_importer._create_or_update_bugtasks(bug, self.soss_record)
         transaction.commit()
 
+        # Check against the new expected list
         self._check_bugtasks(
             bug.bugtasks,
-            self.bugtask_reference[2:],
+            expected_updated_bugtasks,
             BugTaskImportance.HIGH,
             self.bug_importer,
         )
@@ -436,7 +474,7 @@ class TestSOSSImporter(TestCaseWithFactory):
             self.soss_record.packages[SOSSRecord.PackageTypeEnum.RUST][0],
             SOSSRecord.PackageTypeEnum.RUST,
         )
-        self.assertEqual(cargo_pkg, self.bugtask_reference[3][0])
+        self.assertEqual(cargo_pkg, self.bugtask_reference[1][0])
 
         generic_pkg = soss_importer._get_or_create_external_package(
             self.soss_record.packages[SOSSRecord.PackageTypeEnum.UNPACKAGED][
@@ -444,13 +482,13 @@ class TestSOSSImporter(TestCaseWithFactory):
             ],
             SOSSRecord.PackageTypeEnum.UNPACKAGED,
         )
-        self.assertEqual(generic_pkg, self.bugtask_reference[5][0])
+        self.assertEqual(generic_pkg, self.bugtask_reference[4][0])
 
         maven_pkg = soss_importer._get_or_create_external_package(
             self.soss_record.packages[SOSSRecord.PackageTypeEnum.MAVEN][0],
             SOSSRecord.PackageTypeEnum.MAVEN,
         )
-        self.assertEqual(maven_pkg, self.bugtask_reference[4][0])
+        self.assertEqual(maven_pkg, self.bugtask_reference[5][0])
 
     def test_prepare_cvss_data(self):
         """Test prepare the cvss json"""

Follow ups