Skip to content

Commit

Permalink
Fix bug with merge tests modifying data for subsequent runs and add t…
Browse files Browse the repository at this point in the history
…ests for system relationship creation logic
  • Loading branch information
nightlark committed Jan 13, 2025
1 parent d44f7b1 commit 314f5ae
Showing 1 changed file with 158 additions and 22 deletions.
180 changes: 158 additions & 22 deletions tests/cmd/test_merge.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
from surfactant.sbomtypes import SBOM, Relationship

# Generate Sample SBOMs
sbom1 = SBOM.from_json(
"""{
sbom1_json = """{
"software": [
{
"UUID": "dd6f7f6b-7c31-4a4a-afef-14678b9942bf",
Expand Down Expand Up @@ -68,10 +67,11 @@
}
]
}"""
)

sbom2 = SBOM.from_json(
"""{
def get_sbom1():
return SBOM.from_json(sbom1_json)

sbom2_json = """{
"software": [
{
"UUID": "625a07da-7eed-47b9-a0fa-47dcbf76574a",
Expand Down Expand Up @@ -124,32 +124,40 @@
}
]
}"""
)

def get_sbom2():
return SBOM.from_json(sbom2_json)

sbom3 = None
sbom4 = None

config = {
"system": {
"UUID": "6a0ee431-842f-4963-8867-ef0ef6998003",
"name": "",
"vendor": None,
"captureStart": 1689186121,
"captureEnd": 1689186146,
}
}
def get_config():
return {
"system": {
"UUID": "6a0ee431-842f-4963-8867-ef0ef6998003",
"name": "",
"vendor": None,
"captureStart": 1689186121,
"captureEnd": 1689186146,
}
}

with open(
def get_sbom3():
with open(
pathlib.Path(__file__).parent / "../data/sample_sboms/helics_binaries_sbom.json",
"r",
) as f:
sbom3 = SBOM.from_json(f.read())
with open(pathlib.Path(__file__).parent / "../data/sample_sboms/helics_libs_sbom.json", "r") as f:
sbom4 = SBOM.from_json(f.read())
) as f:
return SBOM.from_json(f.read())

def get_sbom4():
with open(pathlib.Path(__file__).parent / "../data/sample_sboms/helics_libs_sbom.json", "r") as f:
return SBOM.from_json(f.read())


# Test Functions
def test_simple_merge_method():
sbom1 = get_sbom1()
sbom2 = get_sbom2()
merged_sbom = sbom1
merged_sbom.merge(sbom2)
softwares = sbom1.software
Expand All @@ -164,6 +172,8 @@ def test_simple_merge_method():

@pytest.mark.skip(reason="No way of validating this test yet")
def test_merge_with_circular_dependency():
sbom1 = get_sbom1()
sbom2 = get_sbom2()
circular_dependency_sbom = sbom1
circular_dependency_sbom.relationships.add(
Relationship(
Expand All @@ -178,18 +188,20 @@ def test_merge_with_circular_dependency():
output_writer = pm.get_plugin("surfactant.output.cytrics_writer")
input_sboms = [circular_dependency_sbom, sbom2]
with open(outfile_name, "w") as sbom_outfile:
merge(input_sboms, sbom_outfile, config, output_writer)
merge(input_sboms, sbom_outfile, get_config(), output_writer)
# TODO add validation checks here
os.remove(os.path.abspath(outfile_name))


@pytest.mark.skip(reason="No way of properly validating this test yet")
def test_cmdline_merge():
sbom3 = get_sbom3()
sbom4 = get_sbom4()
# Test simple merge of two sboms
outfile_name = generate_filename("test_cmdline_merge")
pm = get_plugin_manager()
output_writer = pm.get_plugin("surfactant.output.cytrics_writer")
config_file = config
config_file = get_config()
input_sboms = [sbom3, sbom4]
with open(outfile_name, "w") as sbom_outfile:
merge(input_sboms, sbom_outfile, config_file, output_writer)
Expand All @@ -202,6 +214,130 @@ def test_cmdline_merge():
os.remove(os.path.abspath(outfile_name))


def test_merge_with_add_system_true():
sbom1 = get_sbom1()
sbom2 = get_sbom2()
outfile_name = generate_filename("test_merge_with_add_system_true")
pm = get_plugin_manager()
output_writer = pm.get_plugin("surfactant.output.cytrics_writer")
input_sboms = [sbom1, sbom2]
config_file = get_config()
config_file["system"]["UUID"] = "6a0ee431-842f-4963-8867-ef0ef6998003"
with open(outfile_name, "w") as sbom_outfile:
merge(input_sboms, sbom_outfile, config_file, output_writer, add_system=True)

with open(outfile_name, "r") as j:
generated_sbom = json.loads(j.read())
assert generated_sbom["systems"]
assert generated_sbom["systems"][0]["UUID"] == config_file["system"]["UUID"]

os.remove(os.path.abspath(outfile_name))


def test_merge_with_add_system_false():
sbom1 = get_sbom1()
sbom2 = get_sbom2()
outfile_name = generate_filename("test_merge_with_add_system_false")
pm = get_plugin_manager()
output_writer = pm.get_plugin("surfactant.output.cytrics_writer")
input_sboms = [sbom1, sbom2]
config_file = get_config()
config_file["system"]["UUID"] = "6a0ee431-842f-4963-8867-ef0ef6998003"
with open(outfile_name, "w") as sbom_outfile:
merge(input_sboms, sbom_outfile, config_file, output_writer, add_system=False)

with open(outfile_name, "r") as j:
generated_sbom = json.loads(j.read())
assert not generated_sbom["systems"]

os.remove(os.path.abspath(outfile_name))


def test_merge_with_custom_system_relationship():
sbom1 = get_sbom1()
sbom2 = get_sbom2()
outfile_name = generate_filename("test_merge_with_custom_system_relationship")
pm = get_plugin_manager()
output_writer = pm.get_plugin("surfactant.output.cytrics_writer")
input_sboms = [sbom1, sbom2]
config_file = get_config()
config_file["systemRelationship"] = "DependsOn"
with open(outfile_name, "w") as sbom_outfile:
merge(input_sboms, sbom_outfile, config_file, output_writer, add_system=True)

with open(outfile_name, "r") as j:
generated_sbom = json.loads(j.read())
for relationship in generated_sbom["relationships"]:
if relationship["xUUID"] == config_file["system"]["UUID"]:
assert relationship["relationship"] == "DependsOn"

os.remove(os.path.abspath(outfile_name))


def test_merge_with_specified_system_uuid():
sbom1 = get_sbom1()
sbom2 = get_sbom2()
outfile_name = generate_filename("test_merge_with_specified_system_uuid")
pm = get_plugin_manager()
output_writer = pm.get_plugin("surfactant.output.cytrics_writer")
input_sboms = [sbom1, sbom2]
config_file = get_config()
system_uuid = "123e4567-e89b-12d3-a456-426614174000"
with open(outfile_name, "w") as sbom_outfile:
merge(input_sboms, sbom_outfile, config_file, output_writer, add_system=True, system_uuid=system_uuid)

with open(outfile_name, "r") as j:
generated_sbom = json.loads(j.read())
assert any(system["UUID"] == system_uuid for system in generated_sbom["systems"])

os.remove(os.path.abspath(outfile_name))


def test_prevent_orphaned_system_uuid():
sbom1 = get_sbom1()
sbom2 = get_sbom2()
outfile_name = generate_filename("test_prevent_orphaned_system_uuid")
pm = get_plugin_manager()
output_writer = pm.get_plugin("surfactant.output.cytrics_writer")
input_sboms = [sbom1, sbom2]
config_file = get_config()
# Get rid of the system UUID field from the config file
# This will make it try to generate a random UUID, but won't add it since add_system is False
del config_file["system"]["UUID"]
with open(outfile_name, "w") as sbom_outfile:
merge(input_sboms, sbom_outfile, config_file, output_writer, add_system=False)

with open(outfile_name, "r") as j:
generated_sbom = json.loads(j.read())
assert not generated_sbom["systems"]

os.remove(os.path.abspath(outfile_name))


def test_add_random_system_uuid():
sbom1 = get_sbom1()
sbom2 = get_sbom2()
outfile_name = generate_filename("test_prevent_orphaned_system_uuid")
pm = get_plugin_manager()
output_writer = pm.get_plugin("surfactant.output.cytrics_writer")
input_sboms = [sbom1, sbom2]
config_file = get_config()
# Get rid of the system UUID field from the config file
# This will make it try to generate a random UUID, but won't add it since add_system is False
original_config_system_UUID = config_file["system"]["UUID"]
del config_file["system"]["UUID"]
with open(outfile_name, "w") as sbom_outfile:
merge(input_sboms, sbom_outfile, config_file, output_writer, add_system=True)

with open(outfile_name, "r") as j:
generated_sbom = json.loads(j.read())
assert generated_sbom["systems"]
# Check that the UUID of the generated system is actually random
assert generated_sbom["systems"][0]["UUID"] != original_config_system_UUID

os.remove(os.path.abspath(outfile_name))


def generate_filename(name, ext=".json"):
res = "".join(random.choices(string.ascii_uppercase + string.digits, k=7))
return str(name + "_" + res + ext)

0 comments on commit 314f5ae

Please sign in to comment.