Skip to content

Commit

Permalink
Add testing and version bump
Browse files Browse the repository at this point in the history
Signed-off-by: Gergely Csatari <gergely.csatari@nokia.com>
  • Loading branch information
CsatariGergely committed Nov 26, 2024
1 parent a1f8bc6 commit a63e9b9
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 35 deletions.
19 changes: 18 additions & 1 deletion tools/openchain_telco_sbom_validator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,13 @@ options:
--strict-url-check Runs a strict check on the URLs of the PackageHomepages. Strict check means that the
validator checks also if the given URL can be accessed. The default behaviour is to run a non
strict URL check what means that it is not checked if the URL points to a valid page. Strict
URL check requires access to the internet and takes some time.')
URL check requires access to the internet and takes some time.'
--reference-logic REFERENCE_LOGIC
Defines the logic how the referenced files are accessible. If not added the referencedfiles will
not be investigated. Built in supported logics are none (no linked files are investigated)
yocto-all (all externalrefs are investigated) and yocto-contains-only (only those files are
investigated which are inCONTAIN relatioships). It is possible to
register more reference logics in library mode
```

## As a library
Expand Down Expand Up @@ -132,6 +138,17 @@ def checkJustLogPackage(problems: Problems, package: Package): # Signature is im
```

#### Referring logics

Referring SPDX files is based on URLs what assues that all the SBOMs are always public. This is not always the case,
therefore the validator provides a possibility to resolve the references in a local disk. This resolution can be
different depending on the tool generated the SBOMs. It is possible to register referring logics to the validator using
its `addReferringLogics(name, function)` method the function will get a `Document` from `spdx_tools.spdx.model.document`
what is the parsed SPDX model of the currently validated document and a string with the location of the currently
validated document. The function is expected to return a list of file locations with all the referred SPDX files.
Each of these files will be validated as well. The referring logic can be triggered by adding the name of the function
to the `referringLogic` parameter of the `validate()` function of the `Validator` class.

# License

This software is Copyright Nokia and is licensed under the Apache 2.0 license.
Expand Down
2 changes: 1 addition & 1 deletion tools/openchain_telco_sbom_validator/setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = openchain-telco-sbom-validator
version = 0.1.7
version = 0.2.0
author = Gergely Csatari, Marc-Etienne Vargenau
author_email = gergely.csatari@nokia.com, marc-etienne.vargenau@nokia.com
description = Validator against version 1 of the OpenChain Telco SBOM Guide
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ def __getitem__(self, index):

def __len__(self):
return len(self.items)

def __bool__(self):
if len(self.items) > 0:
return True
else:
return False
def __str__(self):
return f"I have {len(self.items)} problems"

class FunctionRegistry:
def __init__(self):
Expand Down Expand Up @@ -123,9 +131,21 @@ def addReferringLogics(self, name, function):
functSignature = inspect.signature(function)
if functSignature != requiredSignature:
raise TypeError(f"Function {function.__name__} does not match the required signature")

self.referringLogics[name] = function

def getReferringLogicNames(self):
name_list = ""
keys = self.referringLogics.keys()
keys_len = len(self.referringLogics.keys())
i = 1
for name in keys:
if i < keys_len:
name_list += f"{name}, "
else:
name_list += f"{name}"
i += 1
return name_list

def validate(self,
filePath,
strict_purl_check=False,
Expand Down Expand Up @@ -315,8 +335,10 @@ def validate(self,
list_of_referred_sboms = []

if referringLogic in self.referringLogics:
logger.debug(f"What is this: {referringLogic}, {self.referringLogics[referringLogic]}")
logger.debug(f"Executing referring logic: {referringLogic}, {self.referringLogics[referringLogic]}")
list_of_referred_sboms = self.referringLogics[referringLogic](self, doc, dir_name)
else:
logger.warning(f"Referring logic {referringLogic} is not in the registered referring logic list {self.getReferringLogicNames()}")

for referred_sbom in list_of_referred_sboms:
self.validate(
Expand Down
13 changes: 13 additions & 0 deletions tools/openchain_telco_sbom_validator/testing/test-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -192,5 +192,18 @@ function test_linked_yocto-contains-only
assert_output_contains "One or more of the SPDX files linked-sbom-01.spdx.json, alarm.spdx.json, alignmentpavendors.spdx.json, alps.spdx.json are not compliant with the OpenChain Telco SBOM Guide"
}

function test_linked_nonexistent
{
echo "Test: test_linked_none"
run "openchain-telco-sbom-validator --reference-logic nonexistent linked-sboms-01/linked-sbom-01.spdx.json"
echo "$output"
assert_terminated_normally
assert_exit_fail
assert_has_output
assert_output_contains "10 | Missing"
assert_output_contains "One or more of the SPDX files linked-sbom-01.spdx.json, alarm.spdx.json, alignmentpavendors.spdx.json, alps.spdx.json are not compliant with the OpenChain Telco SBOM Guide"
}



testrunner
45 changes: 18 additions & 27 deletions tools/openchain_telco_sbom_validator/unittests/test_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,17 @@ def test_nok_package_function():
functions.registerPackage(checkPackageHomepage)
result, problems = v.validate(filePath = "sboms/unittest-sbom-12.spdx", functionRegistry=functions)
assert result == False
assert len(problems) == 3
assert problems[0].ErrorType == "Invalid CreationInfo"
assert problems[0].Reason == "CreatorComment (runtime) is not in the CISA SBOM Type list (https://www.cisa.gov/sites/default/files/2023-04/sbom-types-document-508c.pdf)"
assert problems[0].SPDX_ID == "General"
assert problems[0].PackageName == "General"
assert len(problems) == 2

assert problems[1].ErrorType == "Missing mandatory field from Package"
assert problems[1].Reason == "There is no purl type ExternalRef field in the Package"
assert problems[1].SPDX_ID == "SPDXRef-Package-deb-nopurl-libldap-2.4-2-796a192b709a2a2b"
assert problems[1].PackageName == "nopurl-libldap-2.4-2"
assert problems[0].ErrorType == "Missing mandatory field from Package"
assert problems[0].Reason == "There is no purl type ExternalRef field in the Package"
assert problems[0].SPDX_ID == "SPDXRef-Package-deb-nopurl-libldap-2.4-2-796a192b709a2a2b"
assert problems[0].PackageName == "nopurl-libldap-2.4-2"

assert problems[2].ErrorType == "Missing mandatory field from Package"
assert problems[2].Reason == "PackageHomePage field is missing"
assert problems[2].SPDX_ID == "SPDXRef-Package-deb-nohomepage-libldap-2.4-2-796a192b709a2a2b"
assert problems[2].PackageName == "nohomepage-libldap-2.4-2"
assert problems[1].ErrorType == "Missing mandatory field from Package"
assert problems[1].Reason == "PackageHomePage field is missing"
assert problems[1].SPDX_ID == "SPDXRef-Package-deb-nohomepage-libldap-2.4-2-796a192b709a2a2b"
assert problems[1].PackageName == "nohomepage-libldap-2.4-2"


def checkPackageHomepage(problems: validator.Problems, package: Package):
Expand All @@ -36,22 +32,17 @@ def test_nok_global_function():
functions.registerGlobal(checkSPDXVersion)
result, problems = v.validate(filePath = "sboms/unittest-sbom-12.spdx", functionRegistry=functions)
assert result == False
assert len(problems) == 3
assert len(problems) == 2

assert problems[0].ErrorType == "Invalid CreationInfo"
assert problems[0].Reason == "CreatorComment (runtime) is not in the CISA SBOM Type list (https://www.cisa.gov/sites/default/files/2023-04/sbom-types-document-508c.pdf)"
assert problems[0].SPDX_ID == "General"
assert problems[0].PackageName == "General"
assert problems[0].ErrorType == "Missing mandatory field from Package"
assert problems[0].Reason == "There is no purl type ExternalRef field in the Package"
assert problems[0].SPDX_ID == "SPDXRef-Package-deb-nopurl-libldap-2.4-2-796a192b709a2a2b"
assert problems[0].PackageName == "nopurl-libldap-2.4-2"

assert problems[1].ErrorType == "Missing mandatory field from Package"
assert problems[1].Reason == "There is no purl type ExternalRef field in the Package"
assert problems[1].SPDX_ID == "SPDXRef-Package-deb-nopurl-libldap-2.4-2-796a192b709a2a2b"
assert problems[1].PackageName == "nopurl-libldap-2.4-2"

assert problems[2].ErrorType == "SPDX Version"
assert problems[2].Reason == "SPDX Version is SPDX-2.3"
assert problems[2].SPDX_ID == "General"
assert problems[2].PackageName == "General"
assert problems[1].ErrorType == "SPDX Version"
assert problems[1].Reason == "SPDX Version is SPDX-2.3"
assert problems[1].SPDX_ID == "General"
assert problems[1].PackageName == "General"

def checkSPDXVersion(problems: validator.Problems, doc: Document):
if doc.creation_info.spdx_version == "SPDX-2.3":
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
from openchain_telco_sbom_validator import validator

import logging


logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)

def test_ok_creator_comment():
v = validator.Validator()
# CreatorComment: CISA SBOM Type: Analyzed
result, problems = v.validate(filePath = "sboms/unittest-sbom-02.spdx")
assert problems is None
assert len(problems) == 0
assert result == True
# CreatorComment: CISA SBOM Type: analyzed
result, problems = v.validate(filePath = "sboms/unittest-sbom-07.spdx")
Expand All @@ -21,7 +27,7 @@ def test_ok_creator_comment():

# CreatorComment: runtime
result, problems = v.validate(filePath = "sboms/unittest-sbom-08.spdx")
assert problems is None
assert len(problems) == 0
assert result == True

def test_nok_creater_comment_incorrect_cisa():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
def test_ok_json():
v = validator.Validator()
result, problems = v.validate(filePath = "sboms/unittest-sbom-01.spdx.json")
assert problems is None
assert len(problems) == 0
assert result == True

def test_ok():
v = validator.Validator()
result, problems = v.validate(filePath = "sboms/unittest-sbom-02.spdx")
assert problems is None
assert len(problems) == 0
assert result == True

0 comments on commit a63e9b9

Please sign in to comment.