launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #32923
[Merge] ~enriqueesanchz/launchpad:add-soss-export-mapping into launchpad:master
Enrique Sánchez has proposed merging ~enriqueesanchz/launchpad:add-soss-export-mapping into launchpad:master.
Commit message:
Add SOSSExport
Update SOSS cves ordering for exact match between import and export.
Add support for status_explanation in SOSSImport.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~enriqueesanchz/launchpad/+git/launchpad/+merge/491712
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~enriqueesanchz/launchpad:add-soss-export-mapping into launchpad:master.
diff --git a/lib/lp/bugs/scripts/soss/models.py b/lib/lp/bugs/scripts/soss/models.py
index c557812..f8fe1a9 100644
--- a/lib/lp/bugs/scripts/soss/models.py
+++ b/lib/lp/bugs/scripts/soss/models.py
@@ -7,6 +7,7 @@ from enum import Enum
from typing import Any, Dict, List, Optional
import yaml
+from packaging.version import Version
__all__ = [
"SOSSRecord",
@@ -53,6 +54,14 @@ class SOSSRecord:
def __str__(self) -> str:
return self.value
+ def __lt__(self, other) -> bool:
+ try:
+ self_ver = self.value.split(":")[-1].split("/")[0]
+ other_ver = self.value.split(":")[-1].split("/")[0]
+ return Version(self_ver) < Version(other_ver)
+ except Exception:
+ return self.value < other.value
+
@dataclass
class CVSS:
source: str
@@ -95,6 +104,12 @@ class SOSSRecord:
"Note": self.note,
}
+ def __lt__(self, other: "SOSSRecord.Package") -> bool:
+ if self.name == other.name:
+ return self.channel < other.channel
+
+ return self.name <= other.name
+
references: List[str]
notes: List[str]
priority: PriorityEnum
diff --git a/lib/lp/bugs/scripts/soss/sossexport.py b/lib/lp/bugs/scripts/soss/sossexport.py
new file mode 100644
index 0000000..aae719f
--- /dev/null
+++ b/lib/lp/bugs/scripts/soss/sossexport.py
@@ -0,0 +1,211 @@
+# Copyright 2025 Canonical Ltd. This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+"""A SOSS (SOSS CVE Tracker) bug exporter"""
+import logging
+from collections import defaultdict
+from datetime import datetime
+from typing import Dict, List, Optional
+
+from zope.component import getUtility
+from zope.security.proxy import removeSecurityProxy
+
+from lp.app.enums import InformationType
+from lp.app.errors import NotFoundError
+from lp.bugs.interfaces.cve import ICveSet
+from lp.bugs.model.bug import Bug as BugModel
+from lp.bugs.model.bugtask import BugTask
+from lp.bugs.model.cve import Cve as CveModel
+from lp.bugs.model.vulnerability import Vulnerability
+from lp.bugs.scripts.soss.models import SOSSRecord
+from lp.bugs.scripts.soss.sossimport import (
+ DISTRIBUTION_NAME,
+ PACKAGE_STATUS_MAP,
+ PACKAGE_TYPE_MAP,
+ PRIORITY_ENUM_MAP,
+)
+from lp.registry.interfaces.distribution import IDistributionSet
+from lp.registry.model.distribution import Distribution
+
+__all__ = [
+ "SOSSExporter",
+]
+
+logger = logging.getLogger(__name__)
+
+# Constants moved to module level with proper naming
+PRIORITY_ENUM_MAP_REVERSE = {v: k for k, v in PRIORITY_ENUM_MAP.items()}
+
+PACKAGE_TYPE_MAP_REVERSE = {v: k for k, v in PACKAGE_TYPE_MAP.items()}
+
+PACKAGE_STATUS_MAP_REVERSE = {v: k for k, v in PACKAGE_STATUS_MAP.items()}
+
+
+class SOSSExporter:
+ """
+ SOSSExporter is used to export Launchpad Vulnerability data to SOSS CVE
+ files.
+ """
+
+ def __init__(
+ self,
+ information_type: InformationType = InformationType.PRIVATESECURITY,
+ dry_run: bool = False,
+ ) -> None:
+ self.dry_run = dry_run
+ self.cve_set = getUtility(ICveSet)
+ self.soss = getUtility(IDistributionSet).getByName(DISTRIBUTION_NAME)
+
+ if self.soss is None:
+ logger.error("[SOSSExporter] SOSS distribution not found")
+ raise NotFoundError("SOSS distribution not found")
+
+ def _get_packages(
+ self, bugtasks: List[BugTask]
+ ) -> Dict[SOSSRecord.PackageTypeEnum, SOSSRecord.Package]:
+ """Get a dict of SOSSRecord.PackageTypeEnum: SOSSRecord.Package from a
+ bugtask list.
+ """
+ packages = defaultdict(list)
+ for bugtask in bugtasks:
+ pkg = SOSSRecord.Package(
+ name=bugtask.target.name,
+ channel=SOSSRecord.Channel(
+ value="/".join(s for s in bugtask.channel if s is not None)
+ ),
+ repositories=bugtask.metadata.get("repositories"),
+ status=SOSSRecord.PackageStatusEnum(
+ PACKAGE_STATUS_MAP_REVERSE[bugtask.status]
+ ),
+ note=bugtask.status_explanation or "",
+ )
+ packages[PACKAGE_TYPE_MAP_REVERSE[bugtask.packagetype]].append(pkg)
+
+ ordered_packages = {
+ k: sorted(packages[k])
+ for k in PACKAGE_TYPE_MAP_REVERSE.values()
+ if packages[k]
+ }
+
+ return ordered_packages
+
+ def _get_cvss(self, cvss: Dict) -> List[SOSSRecord.CVSS]:
+ """Get a list of SOSSRecord.CVSS from a cvss dict"""
+ cvss_list = []
+ for authority in cvss.keys():
+ for c in cvss[authority]:
+ cvss_list.append(
+ SOSSRecord.CVSS(
+ c.get("source"),
+ c.get("vector"),
+ c.get("baseScore"),
+ c.get("baseSeverity"),
+ )
+ )
+ return cvss_list
+
+ def to_record(self, cve_sequence: str) -> SOSSRecord:
+ """Return a SOSSRecord exporting Launchpad data for the specified
+ cve_sequence.
+ """
+ lp_cve = self._get_launchpad_cve(cve_sequence)
+ if lp_cve is None:
+ logger.error(f"[SOSSExporter] {cve_sequence} not found")
+ return None
+
+ bug = self._find_existing_bug(cve_sequence, lp_cve, self.soss)
+ if bug is None:
+ logger.error(f"[SOSSExporter] No bug found for {cve_sequence}")
+ return None
+
+ vulnerability = self._find_existing_vulnerability(lp_cve, self.soss)
+ if vulnerability is None:
+ logger.error(
+ f"[SOSSExporter] No vulnerability found for {cve_sequence}"
+ )
+ return None
+
+ # Export bug
+ desc_parts = bug.description.rsplit("\n\nReferences:\n")
+ references = desc_parts[1].split("\n") if len(desc_parts) > 1 else []
+
+ # Export bug.bugtasks
+ packages = self._get_packages(bug.bugtasks)
+ assigned_to = (
+ bug.bugtasks[0].assignee.name if bug.bugtasks[0].assignee else ""
+ )
+
+ # Export vulnerability
+ description = vulnerability.description
+ public_date = vulnerability.date_made_public
+ notes = vulnerability.notes.split("\n") if vulnerability.notes else []
+ priority = SOSSRecord.PriorityEnum(
+ PRIORITY_ENUM_MAP_REVERSE[vulnerability.importance]
+ )
+ priority_reason = vulnerability.importance_explanation
+
+ # Export vulnerability.cvss
+ cvss = self._get_cvss(vulnerability.cvss)
+
+ candidate = f"CVE-{lp_cve.sequence}"
+
+ return SOSSRecord(
+ references=references,
+ notes=notes,
+ priority=priority,
+ priority_reason=priority_reason,
+ assigned_to=assigned_to,
+ packages=packages,
+ candidate=candidate,
+ description=description,
+ cvss=cvss,
+ public_date=self._normalize_date_without_timezone(public_date),
+ )
+
+ def _find_existing_bug(
+ self,
+ cve_sequence: str,
+ lp_cve: CveModel,
+ distribution: Distribution,
+ ) -> Optional[BugModel]:
+ """Find existing bug for the given CVE."""
+ for vulnerability in lp_cve.vulnerabilities:
+ if vulnerability.distribution == distribution:
+ bugs = vulnerability.bugs
+ if len(bugs) > 1:
+ raise ValueError(
+ "Multiple existing bugs found for CVE ",
+ cve_sequence,
+ )
+ if bugs:
+ return bugs[0]
+ return None
+
+ def _find_existing_vulnerability(
+ self, lp_cve: CveModel, distribution: Distribution
+ ) -> Optional[Vulnerability]:
+ """Find existing vulnerability for the current distribution"""
+ if not lp_cve:
+ return None
+
+ vulnerability = next(
+ (
+ v
+ for v in lp_cve.vulnerabilities
+ if v.distribution == distribution
+ ),
+ None,
+ )
+ return vulnerability
+
+ def _get_launchpad_cve(self, cve_sequence: str) -> Optional[CveModel]:
+ """Get CVE from Launchpad."""
+ return removeSecurityProxy(self.cve_set[cve_sequence])
+
+ def _normalize_date_without_timezone(
+ self, date_obj: datetime
+ ) -> Optional[datetime]:
+ """Normalize date to no timezone if needed."""
+ if date_obj and date_obj.tzinfo is not None:
+ return date_obj.replace(tzinfo=None)
+ return date_obj
diff --git a/lib/lp/bugs/scripts/soss/sossimport.py b/lib/lp/bugs/scripts/soss/sossimport.py
index 773caf4..e0026e1 100644
--- a/lib/lp/bugs/scripts/soss/sossimport.py
+++ b/lib/lp/bugs/scripts/soss/sossimport.py
@@ -13,6 +13,7 @@ from zope.component import getUtility
from zope.security.proxy import removeSecurityProxy
from lp.app.enums import InformationType
+from lp.app.errors import NotFoundError
from lp.app.interfaces.launchpad import ILaunchpadCelebrities
from lp.bugs.enums import VulnerabilityStatus
from lp.bugs.interfaces.bug import CreateBugParams, IBugSet
@@ -40,6 +41,10 @@ from lp.testing import person_logged_in
__all__ = [
"SOSSImporter",
+ "PRIORITY_ENUM_MAP",
+ "PACKAGE_TYPE_MAP",
+ "PACKAGE_STATUS_MAP",
+ "DISTRIBUTION_NAME",
]
logger = logging.getLogger(__name__)
@@ -55,11 +60,11 @@ PRIORITY_ENUM_MAP = {
}
PACKAGE_TYPE_MAP = {
- SOSSRecord.PackageTypeEnum.UNPACKAGED: ExternalPackageType.GENERIC,
- SOSSRecord.PackageTypeEnum.PYTHON: ExternalPackageType.PYTHON,
- SOSSRecord.PackageTypeEnum.MAVEN: ExternalPackageType.MAVEN,
SOSSRecord.PackageTypeEnum.CONDA: ExternalPackageType.CONDA,
+ SOSSRecord.PackageTypeEnum.MAVEN: ExternalPackageType.MAVEN,
+ SOSSRecord.PackageTypeEnum.PYTHON: ExternalPackageType.PYTHON,
SOSSRecord.PackageTypeEnum.RUST: ExternalPackageType.CARGO,
+ SOSSRecord.PackageTypeEnum.UNPACKAGED: ExternalPackageType.GENERIC,
}
PACKAGE_STATUS_MAP = {
@@ -97,7 +102,7 @@ class SOSSImporter:
if self.soss is None:
logger.error("[SOSSImporter] SOSS distribution not found")
- raise Exception("SOSS distribution not found")
+ raise NotFoundError("SOSS distribution not found")
def import_cve_from_file(
self, cve_path: str
@@ -131,7 +136,7 @@ class SOSSImporter:
else:
bug = self._update_bug(bug, soss_record, lp_cve)
- vulnerability = self._find_existing_vulnerability(bug, self.soss)
+ vulnerability = self._find_existing_vulnerability(lp_cve, self.soss)
if not vulnerability:
vulnerability = self._create_vulnerability(
bug, soss_record, lp_cve, self.soss
@@ -306,14 +311,18 @@ class SOSSImporter:
return None
def _find_existing_vulnerability(
- self, bug: BugModel, distribution: Distribution
+ self, lp_cve: CveModel, distribution: Distribution
) -> Optional[Vulnerability]:
"""Find existing vulnerability for the current distribution"""
- if not bug:
+ if not lp_cve:
return None
vulnerability = next(
- (v for v in bug.vulnerabilities if v.distribution == distribution),
+ (
+ v
+ for v in lp_cve.vulnerabilities
+ if v.distribution == distribution
+ ),
None,
)
return vulnerability
@@ -351,7 +360,7 @@ class SOSSImporter:
)
if target not in bugtask_by_target:
- self.bugtask_set.createTask(
+ bugtask = self.bugtask_set.createTask(
bug,
self.bug_importer,
target,
@@ -377,6 +386,8 @@ class SOSSImporter:
bugtask.transitionToAssignee(assignee, validate=False)
bugtask.metadata = metadata
+ bugtask.status_explanation = package.note
+
# Remove bugtasks that were deleted from the record
for bugtask in bugtask_by_target.values():
bugtask.destroySelf()
diff --git a/lib/lp/bugs/scripts/soss/tests/sampledata/CVE-2005-1544 b/lib/lp/bugs/scripts/soss/tests/sampledata/CVE-2005-1544
index 8788e47..15536ad 100644
--- a/lib/lp/bugs/scripts/soss/tests/sampledata/CVE-2005-1544
+++ b/lib/lp/bugs/scripts/soss/tests/sampledata/CVE-2005-1544
@@ -31,3 +31,4 @@ Packages:
- soss-src-stable-local
Status: ignored
Note: ''
+Candidate: CVE-2005-1544
diff --git a/lib/lp/bugs/scripts/soss/tests/sampledata/CVE-2011-5000 b/lib/lp/bugs/scripts/soss/tests/sampledata/CVE-2011-5000
index e92427b..76ce151 100644
--- a/lib/lp/bugs/scripts/soss/tests/sampledata/CVE-2011-5000
+++ b/lib/lp/bugs/scripts/soss/tests/sampledata/CVE-2011-5000
@@ -12,3 +12,4 @@ Packages:
- soss-conda-stable-local
Status: ignored
Note: ''
+Candidate: CVE-2011-5000
diff --git a/lib/lp/bugs/scripts/soss/tests/sampledata/CVE-2021-21300 b/lib/lp/bugs/scripts/soss/tests/sampledata/CVE-2021-21300
index 22ae13d..3997a96 100644
--- a/lib/lp/bugs/scripts/soss/tests/sampledata/CVE-2021-21300
+++ b/lib/lp/bugs/scripts/soss/tests/sampledata/CVE-2021-21300
@@ -11,3 +11,4 @@ Packages:
- soss-conda-candidate-local
Status: ignored
Note: was ignored
+Candidate: CVE-2021-21300
diff --git a/lib/lp/bugs/scripts/soss/tests/sampledata/CVE-2025-1979 b/lib/lp/bugs/scripts/soss/tests/sampledata/CVE-2025-1979
index 5d90588..a562efa 100644
--- a/lib/lp/bugs/scripts/soss/tests/sampledata/CVE-2025-1979
+++ b/lib/lp/bugs/scripts/soss/tests/sampledata/CVE-2025-1979
@@ -16,39 +16,32 @@ Priority-Reason: 'Unrealistic exploitation scenario. Logs are stored locally and
in this priority assignment. '
Assigned-To: janitor
Packages:
- unpackaged:
+ conda:
+ - Name: ray
+ Channel: jammy:1.17.0/stable
+ Repositories:
+ - nvidia-pb3-python-stable-local
+ Status: not-affected
+ Note: 2.22.0+soss.1
+ maven:
- Name: vllm
Channel: noble:0.7.3/stable
Repositories:
- soss-src-stable-local
- Status: needed
+ Status: needs-triage
Note: ''
python:
- - Name: ray
- Channel: jammy:2.22.0/stable
- Repositories:
- - nvidia-pb3-python-stable-local
- Status: released
- Note: 2.22.0+soss.1
- Name: pyyaml
Channel: jammy:2.22.0/stable
Repositories:
- nvidia-pb3-python-stable-local
Status: not-affected
Note: ''
- maven:
- - Name: vllm
- Channel: noble:0.7.3/stable
- Repositories:
- - soss-src-stable-local
- Status: needs-triage
- Note: ''
- conda:
- Name: ray
- Channel: jammy:1.17.0/stable
+ Channel: jammy:2.22.0/stable
Repositories:
- nvidia-pb3-python-stable-local
- Status: not-affected
+ Status: released
Note: 2.22.0+soss.1
rust:
- Name: ray
@@ -57,6 +50,13 @@ Packages:
- nvidia-pb3-python-stable-local
Status: deferred
Note: 2.22.0+soss.1
+ unpackaged:
+ - Name: vllm
+ Channel: noble:0.7.3/stable
+ Repositories:
+ - soss-src-stable-local
+ Status: needed
+ Note: ''
Candidate: CVE-2025-1979
Description: "Versions of the package ray before 2.43.0 are vulnerable to Insertion\
\ of Sensitive Information into Log File where the redis password is being logged\
diff --git a/lib/lp/bugs/scripts/soss/tests/test_sossexport.py b/lib/lp/bugs/scripts/soss/tests/test_sossexport.py
new file mode 100644
index 0000000..c7f315f
--- /dev/null
+++ b/lib/lp/bugs/scripts/soss/tests/test_sossexport.py
@@ -0,0 +1,108 @@
+from pathlib import Path
+
+import transaction
+from zope.component import getUtility
+from zope.security.proxy import removeSecurityProxy
+
+from lp.app.enums import InformationType
+from lp.app.interfaces.launchpad import ILaunchpadCelebrities
+from lp.bugs.interfaces.cve import ICveSet
+from lp.bugs.scripts.soss import SOSSRecord
+from lp.bugs.scripts.soss.sossexport import SOSSExporter
+from lp.bugs.scripts.soss.sossimport import SOSSImporter
+from lp.testing import TestCaseWithFactory, person_logged_in
+from lp.testing.layers import LaunchpadZopelessLayer
+
+
+class TestSOSSExporter(TestCaseWithFactory):
+
+ layer = LaunchpadZopelessLayer
+
+ def setUp(self):
+ super().setUp()
+ self.sampledata = Path(__file__).parent / "sampledata"
+ self.factory.makePerson(name="octagalland")
+ self.soss = self.factory.makeDistribution(
+ name="soss",
+ displayname="SOSS",
+ )
+ transaction.commit()
+
+ self.soss_importer = SOSSImporter()
+ self.soss_exporter = SOSSExporter()
+
+ self.cve_set = getUtility(ICveSet)
+ self.bug_importer = getUtility(ILaunchpadCelebrities).bug_importer
+
+ def test_get_packages(self):
+ """Test get SOSSRecord.Package list from bugtasks."""
+ for file in self.sampledata.iterdir():
+ cve_sequence = file.name.lstrip("CVE-")
+ if not self.cve_set[cve_sequence]:
+ self.factory.makeCVE(sequence=cve_sequence)
+
+ with open(file) as f:
+ soss_record = SOSSRecord.from_yaml(f)
+
+ bug, _ = self.soss_importer.import_cve_from_file(file)
+
+ naked_bug = removeSecurityProxy(bug)
+ packages = self.soss_exporter._get_packages(naked_bug.bugtasks)
+ self.assertEqual(soss_record.packages, packages)
+
+ def test_get_cvss(self):
+ """Test get SOSSRecord.CVSS list from vulnerability.cvss."""
+ for file in self.sampledata.iterdir():
+ cve_sequence = file.name.lstrip("CVE-")
+ if not self.cve_set[cve_sequence]:
+ self.factory.makeCVE(sequence=cve_sequence)
+
+ with open(file) as f:
+ soss_record = SOSSRecord.from_yaml(f)
+
+ _, vulnerability = self.soss_importer.import_cve_from_file(file)
+ naked_vulnerability = removeSecurityProxy(vulnerability)
+ cvss = self.soss_exporter._get_cvss(naked_vulnerability.cvss)
+
+ self.assertEqual(soss_record.cvss, cvss)
+
+ def test_to_record(self):
+ """Test that imported and exported SOSSRecords match."""
+ soss_importer = SOSSImporter(
+ information_type=InformationType.PRIVATESECURITY
+ )
+
+ for file in self.sampledata.iterdir():
+ cve_sequence = file.name.lstrip("CVE-")
+ if not self.cve_set[cve_sequence]:
+ self.factory.makeCVE(sequence=cve_sequence)
+
+ with open(file) as f:
+ soss_record = SOSSRecord.from_yaml(f)
+
+ bug, vulnerability = soss_importer.import_cve_from_file(file)
+
+ with person_logged_in(self.bug_importer):
+ exported = self.soss_exporter.to_record(file.name)
+
+ self.assertEqual(soss_record, exported)
+
+ def test_import_export(self):
+ """Integration test that checks that cve files imported and exported
+ match."""
+ soss_importer = SOSSImporter(
+ information_type=InformationType.PRIVATESECURITY
+ )
+
+ for file in self.sampledata.iterdir():
+ cve_sequence = file.name.lstrip("CVE-")
+ if not self.cve_set[cve_sequence]:
+ self.factory.makeCVE(sequence=cve_sequence)
+
+ bug, vulnerability = soss_importer.import_cve_from_file(file)
+
+ with person_logged_in(self.bug_importer):
+ exported = self.soss_exporter.to_record(file.name)
+
+ with open(file) as f:
+ self.assertEqual(f.read(), exported.to_yaml())
diff --git a/lib/lp/bugs/scripts/soss/tests/test_sossimport.py b/lib/lp/bugs/scripts/soss/tests/test_sossimport.py
index d577e6a..a79e5b2 100644
--- a/lib/lp/bugs/scripts/soss/tests/test_sossimport.py
+++ b/lib/lp/bugs/scripts/soss/tests/test_sossimport.py
@@ -76,24 +76,27 @@ class TestSOSSImporter(TestCaseWithFactory):
channel=("jammy:2.22.0", "stable"),
),
BugTaskStatus.INVALID,
+ "",
{"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.CONDA,
- channel=("jammy:1.17.0", "stable"),
+ packagetype=ExternalPackageType.PYTHON,
+ channel=("jammy:2.22.0", "stable"),
),
- BugTaskStatus.INVALID,
+ BugTaskStatus.FIXRELEASED,
+ "2.22.0+soss.1",
{"repositories": ["nvidia-pb3-python-stable-local"]},
),
(
@@ -103,24 +106,27 @@ class TestSOSSImporter(TestCaseWithFactory):
channel=("focal:0.27.0", "stable"),
),
BugTaskStatus.DEFERRED,
+ "2.22.0+soss.1",
{"repositories": ["nvidia-pb3-python-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"]},
),
(
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"]},
),
]
@@ -165,9 +171,14 @@ class TestSOSSImporter(TestCaseWithFactory):
):
self.assertEqual(len(bugtasks), len(bugtask_reference))
- for i, (target, status, metadata) in enumerate(bugtask_reference):
+ for i, (target, status, status_explanation, metadata) in enumerate(
+ bugtask_reference
+ ):
self.assertEqual(bugtasks[i].target, target)
self.assertEqual(bugtasks[i].status, status)
+ self.assertEqual(
+ bugtasks[i].status_explanation, status_explanation
+ )
self.assertEqual(bugtasks[i].importance, importance)
self.assertEqual(bugtasks[i].assignee, assignee)
self.assertEqual(bugtasks[i].metadata, metadata)
@@ -356,6 +367,7 @@ class TestSOSSImporter(TestCaseWithFactory):
channel=("noble:4.23.1", "stable"),
),
BugTaskStatus.DEFERRED,
+ "test note",
{"repositories": ["test-repo"]},
)
@@ -407,13 +419,13 @@ class TestSOSSImporter(TestCaseWithFactory):
],
SOSSRecord.PackageTypeEnum.UNPACKAGED,
)
- self.assertEqual(generic_pkg, self.bugtask_reference[4][0])
+ self.assertEqual(generic_pkg, self.bugtask_reference[5][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[5][0])
+ self.assertEqual(maven_pkg, self.bugtask_reference[4][0])
def test_prepare_cvss_data(self):
"""Test prepare the cvss json"""
diff --git a/lib/lp/bugs/scripts/soss/tests/test_sossrecord.py b/lib/lp/bugs/scripts/soss/tests/test_sossrecord.py
index fc3377c..a1cff07 100644
--- a/lib/lp/bugs/scripts/soss/tests/test_sossrecord.py
+++ b/lib/lp/bugs/scripts/soss/tests/test_sossrecord.py
@@ -47,48 +47,39 @@ class TestSOSSRecord(TestCase):
),
assigned_to="janitor",
packages={
- SOSSRecord.PackageTypeEnum.UNPACKAGED: [
+ SOSSRecord.PackageTypeEnum.CONDA: [
+ SOSSRecord.Package(
+ name="ray",
+ channel=SOSSRecord.Channel("jammy:1.17.0/stable"),
+ repositories=["nvidia-pb3-python-stable-local"],
+ status=SOSSRecord.PackageStatusEnum.NOT_AFFECTED,
+ note="2.22.0+soss.1",
+ )
+ ],
+ SOSSRecord.PackageTypeEnum.MAVEN: [
SOSSRecord.Package(
name="vllm",
channel=SOSSRecord.Channel("noble:0.7.3/stable"),
repositories=["soss-src-stable-local"],
- status=SOSSRecord.PackageStatusEnum.NEEDED,
+ status=SOSSRecord.PackageStatusEnum.NEEDS_TRIAGE,
note="",
)
],
SOSSRecord.PackageTypeEnum.PYTHON: [
SOSSRecord.Package(
- name="ray",
- channel=SOSSRecord.Channel("jammy:2.22.0/stable"),
- repositories=["nvidia-pb3-python-stable-local"],
- status=SOSSRecord.PackageStatusEnum.RELEASED,
- note="2.22.0+soss.1",
- ),
- SOSSRecord.Package(
name="pyyaml",
channel=SOSSRecord.Channel("jammy:2.22.0/stable"),
repositories=["nvidia-pb3-python-stable-local"],
status=SOSSRecord.PackageStatusEnum.NOT_AFFECTED,
note="",
),
- ],
- SOSSRecord.PackageTypeEnum.MAVEN: [
- SOSSRecord.Package(
- name="vllm",
- channel=SOSSRecord.Channel("noble:0.7.3/stable"),
- repositories=["soss-src-stable-local"],
- status=SOSSRecord.PackageStatusEnum.NEEDS_TRIAGE,
- note="",
- )
- ],
- SOSSRecord.PackageTypeEnum.CONDA: [
SOSSRecord.Package(
name="ray",
- channel=SOSSRecord.Channel("jammy:1.17.0/stable"),
+ channel=SOSSRecord.Channel("jammy:2.22.0/stable"),
repositories=["nvidia-pb3-python-stable-local"],
- status=SOSSRecord.PackageStatusEnum.NOT_AFFECTED,
+ status=SOSSRecord.PackageStatusEnum.RELEASED,
note="2.22.0+soss.1",
- )
+ ),
],
SOSSRecord.PackageTypeEnum.RUST: [
SOSSRecord.Package(
@@ -99,6 +90,15 @@ class TestSOSSRecord(TestCase):
note="2.22.0+soss.1",
)
],
+ SOSSRecord.PackageTypeEnum.UNPACKAGED: [
+ SOSSRecord.Package(
+ name="vllm",
+ channel=SOSSRecord.Channel("noble:0.7.3/stable"),
+ repositories=["soss-src-stable-local"],
+ status=SOSSRecord.PackageStatusEnum.NEEDED,
+ note="",
+ )
+ ],
},
candidate="CVE-2025-1979",
description=(
@@ -159,48 +159,39 @@ class TestSOSSRecord(TestCase):
),
"Assigned-To": "janitor",
"Packages": {
- "unpackaged": [
+ "conda": [
+ {
+ "Name": "ray",
+ "Channel": "jammy:1.17.0/stable",
+ "Repositories": ["nvidia-pb3-python-stable-local"],
+ "Status": "not-affected",
+ "Note": "2.22.0+soss.1",
+ }
+ ],
+ "maven": [
{
"Name": "vllm",
"Channel": "noble:0.7.3/stable",
"Repositories": ["soss-src-stable-local"],
- "Status": "needed",
+ "Status": "needs-triage",
"Note": "",
}
],
"python": [
{
- "Name": "ray",
- "Channel": "jammy:2.22.0/stable",
- "Repositories": ["nvidia-pb3-python-stable-local"],
- "Status": "released",
- "Note": "2.22.0+soss.1",
- },
- {
"Name": "pyyaml",
"Channel": "jammy:2.22.0/stable",
"Repositories": ["nvidia-pb3-python-stable-local"],
"Status": "not-affected",
"Note": "",
},
- ],
- "maven": [
- {
- "Name": "vllm",
- "Channel": "noble:0.7.3/stable",
- "Repositories": ["soss-src-stable-local"],
- "Status": "needs-triage",
- "Note": "",
- }
- ],
- "conda": [
{
"Name": "ray",
- "Channel": "jammy:1.17.0/stable",
+ "Channel": "jammy:2.22.0/stable",
"Repositories": ["nvidia-pb3-python-stable-local"],
- "Status": "not-affected",
+ "Status": "released",
"Note": "2.22.0+soss.1",
- }
+ },
],
"rust": [
{
@@ -211,6 +202,15 @@ class TestSOSSRecord(TestCase):
"Note": "2.22.0+soss.1",
}
],
+ "unpackaged": [
+ {
+ "Name": "vllm",
+ "Channel": "noble:0.7.3/stable",
+ "Repositories": ["soss-src-stable-local"],
+ "Status": "needed",
+ "Note": "",
+ }
+ ],
},
"Candidate": "CVE-2025-1979",
"Description": (