Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add unittests #119

Merged
merged 5 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions tools/openchain_telco_sbom_validator/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
from setuptools import setup

setup()

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
# SPDX-License-Identifier: Apache-2.0

import logging
import sys
import re
import json
from spdx_tools.spdx.model.document import Document
Expand All @@ -16,7 +15,6 @@
from spdx_tools.spdx.parser.error import SPDXParsingError
from spdx_tools.spdx.model.package import ExternalPackageRefCategory
from spdx_tools.spdx import document_utils
from prettytable import PrettyTable
from packageurl.contrib import purl2url
import ntia_conformance_checker as ntia
import validators
Expand Down Expand Up @@ -96,23 +94,29 @@ def __init__(self):
return None

def validate(self, filePath, strict_purl_check=False, strict_url_check=False, functionRegistry:FunctionRegistry = FunctionRegistry()):
""" Validates, Returns a status and a list of problems. filePath: Path to the SPDX file to validate. strict_purl_check: Not only checks the syntax of the PURL, but also checks if the package can be downloaded. strict_url_check: Checks if the given URLs in PackageHomepages can be accessed."""
""" Validates, Returns a status and a list of problems.
filePath: Path to the SPDX file to validate.
strict_purl_check: Not only checks the syntax of the PURL, but also checks if the package can be downloaded.
strict_url_check: Checks if the given URLs in PackageHomepages can be accessed."""

self.__test()
problems = Problems()

try:
doc = parse_anything.parse_file(filePath)
except json.decoder.JSONDecodeError as e:
logger.error("JSON syntax error at line " + str(e.lineno) + " column " + str(e.colno))
logger.error(e.msg)
sys.exit(1)
problems.append("File error", "", "", f"JSON syntax error at line {e.lineno} column {e.colno})")
return False, problems
except SPDXParsingError as e:
logger.error("ERROR! The file is not an SPDX file")
for message in e.messages:
logger.error(message)
logger.error("Exiting")
sys.exit(1)
logger.debug("Start validating.")
problems.append("File error", "", "", "The file is not an SPDX file")
return False, problems

problems = Problems()
logger.debug("Start validating.")

errors = validate_full_spdx_document(doc)
if errors:
Expand All @@ -136,26 +140,29 @@ def validate(self, filePath, strict_purl_check=False, strict_url_check=False, fu
if not sbomNTIA.ntia_minimum_elements_compliant:
logger.debug("NTIA validation failed")
components = sbomNTIA.get_components_without_names()
self.ntiaErrorLog(components, problems, doc,"Package without a name")
self.components = sbomNTIA.get_components_without_versions(return_tuples=True)
self.ntiaErrorLogNew(components, problems, doc,"Package without a version")
#logger.debug(f"components: {components}, problems: {str(problems)}, doc: {doc}")
self.__ntiaErrorLog(components, problems, doc, "Package without a name")

#self.ntiaErrorLog(components, problems, doc, "Package without a name")
#self.ntiaErrorLogNew(components, problems, doc, "Package without a version")
components = sbomNTIA.get_components_without_versions(return_tuples=True)
self.__ntiaErrorLogNew(components, problems, doc, "Package without a version")
components = sbomNTIA.get_components_without_suppliers(return_tuples=True)
self.ntiaErrorLogNew(components, problems, doc,"Package without a package supplier or package originator")
self.__ntiaErrorLogNew(components, problems, doc, "Package without a package supplier or package originator")
components = sbomNTIA.get_components_without_identifiers()
self.ntiaErrorLog(components, problems, doc,"Package without an identifyer")
self.__ntiaErrorLog(components, problems, doc, "Package without an identifyer")

else:
logger.debug("NTIA validation succesful")

if doc.creation_info.creator_comment:
logger.debug(f"CreatorComment: {doc.creation_info.creator_comment}")
cisaSBOMTypes = ["Design", "Source", "Build", "Analyzed", "Deployed", "Runtime"]
cisaSBOMTypes = ["design", "source", "build", "analyzed", "deployed", "runtime"]

typeFound = False
for cisaSBOMType in cisaSBOMTypes:
logger.debug(f"Checking {cisaSBOMType} against {doc.creation_info.creator_comment} ({doc.creation_info.creator_comment.find(cisaSBOMType)})")
creator_comment = doc.creation_info.creator_comment.lower();
if -1 != doc.creation_info.creator_comment.find(cisaSBOMType):
if -1 != doc.creation_info.creator_comment.lower().find(cisaSBOMType):
logger.debug("Found")
typeFound = True

Expand Down Expand Up @@ -185,9 +192,13 @@ def validate(self, filePath, strict_purl_check=False, strict_url_check=False, fu
for package in doc.packages:
logger.debug(f"Package: {package}")
if not package.version:
problems.append("Missing mandatory field from Package", package.spdx_id, package.name, "Version field is missing")
pass
### This is already detected during the NTIA check.
#problems.append("Missing mandatory field from Package", package.spdx_id, package.name, "Version field is missing")
if not package.supplier:
problems.append("Missing mandatory field from Package", package.spdx_id, package.name, "Supplier field is missing")
pass
### This is already detected during the NTIA check.
#problems.append("Missing mandatory field from Package", package.spdx_id, package.name, "Supplier field is missing")
if not package.checksums:
problems.append("Missing mandatory field from Package", package.spdx_id, package.name, "Checksum field is missing")
if package.external_references:
Expand Down Expand Up @@ -244,7 +255,7 @@ def validate(self, filePath, strict_purl_check=False, strict_url_check=False, fu
else:
return True, None

def ntiaErrorLog(self, components, problems, doc, problemText):
def __ntiaErrorLog(self, components, problems, doc, problemText):
logger.debug(f"# of components: {len(components)}")
for component in components:
logger.debug(f"Erroneous component: {component}")
Expand All @@ -255,7 +266,7 @@ def ntiaErrorLog(self, components, problems, doc, problemText):
else:
problems.append("NTIA validation error", "Cannot be provided", component, problemText)

def ntiaErrorLogNew(self, components, problems, doc, problemText):
def __ntiaErrorLogNew(self, components, problems, doc, problemText):
logger.debug(f"# of components: {len(components)}")
for component in components:
logger.debug(f"Erroneous component: {component}")
Expand All @@ -269,6 +280,5 @@ def ntiaErrorLogNew(self, components, problems, doc, problemText):
else:
problems.append("NTIA validation error", "Cannot be provided", component, problemText)


if __name__ == "__main__":
main()
def __test(self):
pass
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ LicenseListVersion: 3.21
Creator: Organization: Anchore, Inc
Creator: Tool: syft-0.85.0
Created: 2023-07-19T08:04:05Z
CreatorComment: CISA SBOM Type: analyzed
CreatorComment: CISA SBOM Type: Analyzed

##### Package: libldap-2.4-2

Expand Down
8 changes: 1 addition & 7 deletions tools/openchain_telco_sbom_validator/testing/test-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ function test_no_supplier_no_checksum
assert_terminated_normally
assert_exit_fail
assert_has_output
assert_output_contains "libldap-2.4-2 | Supplier field is missing"
assert_output_contains "libldap-2.4-2 | Checksum field is missing"
assert_output_contains "The SPDX file test-sbom-01.spdx is not compliant with the OpenChain Telco SBOM Guide"
}
Expand All @@ -44,12 +43,7 @@ function test_no_name_no_version_no_supplier
assert_output_contains "Package without a name"
assert_output_contains "golang.org/x/sync-empty- | Package without a package"
assert_output_contains "golang.org/x/sync- | Package without a package"
assert_output_contains "libldap-2.4-2 | Supplier field is missing"
assert_output_contains "golang.org/x/sync-empty- | Version field is missing"
assert_output_contains "golang.org/x/sync-empty- | Supplier field is missing"
assert_output_contains "golang.org/x/sync-empty- | Checksum field is missing"
assert_output_contains "golang.org/x/sync- | Version field is missing"
assert_output_contains "golang.org/x/sync- | Supplier field is missing"
assert_output_contains "golang.org/x/sync- | Checksum field is missing"
assert_output_contains "The SPDX file test-sbom-02.spdx is not compliant with the OpenChain Telco SBOM Guide"
}
Expand Down Expand Up @@ -114,7 +108,7 @@ function test_no_version_json
assert_terminated_normally
assert_exit_fail
assert_has_output
assert_output_contains "scanoss/engine | Version field is missing"
assert_output_contains "scanoss/engine | Package without a version"
assert_output_contains "The SPDX file test-sbom-06.spdx.json is not compliant with the OpenChain Telco SBOM Guide"
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"spdxVersion": "SPDX-2.2",
"dataLicense": "CC0-1.0",
"SPDXID": "SPDXRef-DOCUMENT",
"name": "SBOM for scanoss/engine",
"documentNamespace": "https://spdx.org/spdxdocs/scanner.c-master-f804e73240bc7f145d226c2aebccd094a30bf5156514b8ba24216b4d44e7b06b",
"creationInfo": {
"creators": [
"Tool: SCANOSS SBOM Workbench-1-15.0",
"Person: agustin",
"Organization: SCANOSS"
],
"created": "2024-10-02T14:02:58Z",
"comment": "SBOM Build information - SBOM Type: Build"
},
"packages": [
{
"name": "scanoss/engine",
"SPDXID": "SPDXRef-e92b7b118e817b7c62494b38f693d2d3",
"versionInfo": "5.4.0",
"supplier": "Organization: SCANOSS",
"downloadLocation": "https://github.com/scanoss/engine",
"filesAnalyzed": false,
"checksums": [
{
"algorithm": "SHA1",
"checksumValue": "5d21f846c3bd1a7c91c4cf2ac57d3299dfcc2f67"
}
],
"homepage": "https://github.com/scanoss/engine",
"licenseDeclared": "GPL-2.0-only",
"licenseConcluded": "GPL-2.0-only",
"copyrightText": "NOASSERTION",
"externalRefs": [
{
"referenceCategory": "PACKAGE-MANAGER",
"referenceLocator": "pkg:github/scanoss/engine@5.4.0",
"referenceType": "purl"
}
]
}
],
"relationships": [
{
"spdxElementId": "SPDXRef-DOCUMENT",
"relatedSpdxElement": "SPDXRef-e92b7b118e817b7c62494b38f693d2d3",
"relationshipType": "DESCRIBES"
},
{
"spdxElementId": "SPDXRef-DOCUMENT",
"relatedSpdxElement": "SPDXRef-e92b7b118e817b7c62494b38f693d2d3",
"relationshipType": "CONTAINS"
}
],
"documentDescribes": ["SPDXRef-e92b7b118e817b7c62494b38f693d2d3"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
SPDXVersion: SPDX-2.3
DataLicense: CC0-1.0
SPDXID: SPDXRef-DOCUMENT
DocumentName: bitnami/mongodb-sharded:6.0-debian-11
DocumentNamespace: https://anchore.com/syft/image/bitnami/mongodb-sharded-6.0-debian-11-272a0a56-d03f-4239-8205-42267d6d0d29
LicenseListVersion: 3.21
Creator: Organization: Anchore, Inc
Creator: Tool: syft-0.85.0
Created: 2023-07-19T08:04:05Z
CreatorComment: CISA SBOM Type: Analyzed

##### Package: libldap-2.4-2

PackageName: Correct-libldap-2.4-2
SPDXID: SPDXRef-Package-deb-libldap-2.4-2-796a192b709a2a2b
PackageVersion: 2.4.57+dfsg-3+deb11u1
PackageOriginator: Person: Debian OpenLDAP Maintainers <pkg-openldap-devel@lists.alioth.debian.org>
PackageSupplier: Person: Jane Doe (jane.doe@example.com)
PackageChecksum: SHA256: e325881d738b1091d0105778523ad60eb61e62557b9dc15624e08144b3991d08
PackageDownloadLocation: NOASSERTION
FilesAnalyzed: true
PackageHomePage: https://www.openldap.org/
PackageVerificationCode: 8360ca10f484b118d367165552d0b934835d128a
PackageSourceInfo: acquired package info from DPKG DB: /usr/share/doc/libldap-2.4-2/copyright, /var/lib/dpkg/info/libldap-2.4-2:amd64.md5sums, /var/lib/dpkg/status
PackageLicenseConcluded: NOASSERTION
PackageLicenseDeclared: NOASSERTION
PackageCopyrightText: NOASSERTION
ExternalRef: SECURITY cpe23Type cpe:2.3:a:libldap-2.4-2:libldap-2.4-2:2.4.57\+dfsg-3\+deb11u1:*:*:*:*:*:*:*
ExternalRef: SECURITY cpe23Type cpe:2.3:a:libldap-2.4-2:libldap_2.4_2:2.4.57\+dfsg-3\+deb11u1:*:*:*:*:*:*:*
ExternalRef: SECURITY cpe23Type cpe:2.3:a:libldap_2.4_2:libldap-2.4-2:2.4.57\+dfsg-3\+deb11u1:*:*:*:*:*:*:*
ExternalRef: SECURITY cpe23Type cpe:2.3:a:libldap_2.4_2:libldap_2.4_2:2.4.57\+dfsg-3\+deb11u1:*:*:*:*:*:*:*
ExternalRef: SECURITY cpe23Type cpe:2.3:a:libldap-2.4:libldap-2.4-2:2.4.57\+dfsg-3\+deb11u1:*:*:*:*:*:*:*
ExternalRef: SECURITY cpe23Type cpe:2.3:a:libldap-2.4:libldap_2.4_2:2.4.57\+dfsg-3\+deb11u1:*:*:*:*:*:*:*
ExternalRef: SECURITY cpe23Type cpe:2.3:a:libldap_2.4:libldap-2.4-2:2.4.57\+dfsg-3\+deb11u1:*:*:*:*:*:*:*
ExternalRef: SECURITY cpe23Type cpe:2.3:a:libldap_2.4:libldap_2.4_2:2.4.57\+dfsg-3\+deb11u1:*:*:*:*:*:*:*
ExternalRef: SECURITY cpe23Type cpe:2.3:a:libldap:libldap-2.4-2:2.4.57\+dfsg-3\+deb11u1:*:*:*:*:*:*:*
ExternalRef: SECURITY cpe23Type cpe:2.3:a:libldap:libldap_2.4_2:2.4.57\+dfsg-3\+deb11u1:*:*:*:*:*:*:*
ExternalRef: PACKAGE-MANAGER purl pkg:deb/debian/libldap-2.4-2@2.4.57+dfsg-3+deb11u1?arch=amd64&upstream=openldap&distro=debian-11

LicenseID: LicenseRef-Autoconf
ExtractedText: Autoconf
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"spdxVersion": "SPDX-2.2",
"dataLicense": "CC0-1.0",
"SPDXID": "SPDXRef-DOCUMENT",
"name": "SBOM for scanoss/engine",
"documentNamespace": "https://spdx.org/spdxdocs/scanner.c-master-f804e73240bc7f145d226c2aebccd094a30bf5156514b8ba24216b4d44e7b06b",
"creationInfo": {
"creators": [
"Tool: SCANOSS SBOM Workbench-1-15.0",
"Person: agustin",
"Organization: SCANOSS"
],
"created": "2024-10-02T14:02:58Z",
"comment": "SBOM Build information - SBOM Type: Build"
},
"packages": [}
{
"name": "scanoss/engine",
"SPDXID": "SPDXRef-e92b7b118e817b7c62494b38f693d2d3",
"versionInfo": "5.4.0",
"supplier": "Organization: SCANOSS",
"downloadLocation": "https://github.com/scanoss/engine",
"filesAnalyzed": false,
"checksums": [
{
"algorithm": "SHA1",
"checksumValue": "5d21f846c3bd1a7c91c4cf2ac57d3299dfcc2f67"
}
],
"homepage": "https://github.com/scanoss/engine",
"licenseDeclared": "GPL-2.0-only",
"licenseConcluded": "GPL-2.0-only",
"copyrightText": "NOASSERTION",
"externalRefs": [
{
"referenceCategory": "PACKAGE-MANAGER",
"referenceLocator": "pkg:github/scanoss/engine@5.4.0",
"referenceType": "purl"
}
]
}
],
"relationships": [
{
"spdxElementId": "SPDXRef-DOCUMENT",
"relatedSpdxElement": "SPDXRef-e92b7b118e817b7c62494b38f693d2d3",
"relationshipType": "DESCRIBES"
},
{
"spdxElementId": "SPDXRef-DOCUMENT",
"relatedSpdxElement": "SPDXRef-e92b7b118e817b7c62494b38f693d2d3",
"relationshipType": "CONTAINS"
}
],
"documentDescribes": ["SPDXRef-e92b7b118e817b7c62494b38f693d2d3"]
}
Loading