Skip to content

Commit

Permalink
JSON 1.4 unit tests passing except those blocked by CycloneDX/specifi…
Browse files Browse the repository at this point in the history
…cation#146

Signed-off-by: Paul Horton <[email protected]>
  • Loading branch information
madpah committed Sep 13, 2022
1 parent 790f5ff commit 61fceb6
Show file tree
Hide file tree
Showing 18 changed files with 70 additions and 24 deletions.
3 changes: 3 additions & 0 deletions cyclonedx/model/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,7 @@ def __init__(self, uri: str) -> None:
self._uri = uri

@property # type: ignore[misc]
@serializable.json_name('.')
@serializable.xml_name('.')
def uri(self) -> str:
return self._uri
Expand Down Expand Up @@ -1094,6 +1095,7 @@ def name(self, name: Optional[str]) -> None:
self._name = name

@property # type: ignore[misc]
@serializable.json_name('url')
@serializable.xml_array(serializable.XmlArraySerializationType.FLAT, 'url')
@serializable.xml_sequence(2)
def urls(self) -> "SortedSet[XsUri]":
Expand All @@ -1110,6 +1112,7 @@ def urls(self, urls: Iterable[XsUri]) -> None:
self._urls = SortedSet(urls)

@property # type: ignore[misc]
@serializable.json_name('contact')
@serializable.xml_array(serializable.XmlArraySerializationType.FLAT, 'contact')
@serializable.xml_sequence(3)
def contacts(self) -> "SortedSet[OrganizationalContact]":
Expand Down
1 change: 1 addition & 0 deletions cyclonedx/model/dependency.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ def ref(self, ref: BomRef) -> None:
self._ref = ref

@property # type: ignore[misc]
@serializable.json_name('dependsOn')
@serializable.xml_array(serializable.XmlArraySerializationType.FLAT, 'dependency')
def dependencies(self) -> "SortedSet[Dependency]":
return self._dependencies
Expand Down
1 change: 1 addition & 0 deletions cyclonedx/model/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ def authenticated(self, authenticated: Optional[bool]) -> None:
self._authenticated = authenticated

@property # type: ignore[misc]
@serializable.json_name('x-trust-boundary')
@serializable.xml_name('x-trust-boundary')
@serializable.xml_sequence(8)
def x_trust_boundary(self) -> Optional[bool]:
Expand Down
1 change: 1 addition & 0 deletions cyclonedx/model/vulnerability.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ def justification(self, justification: Optional[ImpactAnalysisJustification]) ->
self._justification = justification

@property # type: ignore[misc]
@serializable.json_name('response')
@serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'response')
@serializable.xml_sequence(3)
def responses(self) -> "SortedSet[ImpactAnalysisResponse]":
Expand Down
28 changes: 28 additions & 0 deletions cyclonedx/output/json.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,34 @@ def schema_version(self) -> SchemaVersion:
return self.schema_version_enum

def generate(self, force_regeneration: bool = False) -> None:
# New Way
if self.schema_version == SchemaVersion.V1_4:
if self.generated and force_regeneration:
self.get_bom().validate()
bom_json = json.loads(self.get_bom().as_json())
bom_json.update({
'$schema': self._get_schema_uri(),
'bomFormat': 'CycloneDX',
'specVersion': '1.4'
})
self._json_output = json.dumps(bom_json)
self.generated = True
return
elif self.generated:
return
else:
self.get_bom().validate()
bom_json = json.loads(self.get_bom().as_json())
bom_json.update({
'$schema': self._get_schema_uri(),
'bomFormat': 'CycloneDX',
'specVersion': '1.4'
})
self._json_output = json.dumps(bom_json)
self.generated = True
return

# Old Way
if self.generated and not force_regeneration:
return

Expand Down
3 changes: 1 addition & 2 deletions tests/fixtures/json/1.4/bom_dependencies.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,7 @@
]
},
{
"ref": "pkg:pypi/[email protected]?extension=tar.gz",
"dependsOn": []
"ref": "pkg:pypi/[email protected]?extension=tar.gz"
}
]
}
9 changes: 7 additions & 2 deletions tests/fixtures/json/1.4/bom_services_complex.json
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,13 @@
],
"dependencies": [
{
"ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda",
"dependsOn": []
"ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda"
},
{
"ref": "my-specific-bom-ref-for-my-first-service"
},
{
"ref": "be2c6502-7e9a-47db-9a66-e34f729810a3"
}
]
}
9 changes: 7 additions & 2 deletions tests/fixtures/json/1.4/bom_services_nested.json
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,13 @@
"version": 1,
"dependencies": [
{
"ref": "cd3e9c95-9d41-49e7-9924-8cf0465ae789",
"dependsOn": []
"ref": "my-specific-bom-ref-for-my-first-service"
},
{
"ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857"
},
{
"ref": "cd3e9c95-9d41-49e7-9924-8cf0465ae789"
}
]
}
9 changes: 7 additions & 2 deletions tests/fixtures/json/1.4/bom_services_simple.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,13 @@
],
"dependencies": [
{
"ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857",
"dependsOn": []
"ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857"
},
{
"ref": "be2c6502-7e9a-47db-9a66-e34f729810a3"
},
{
"ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda"
}
]
}
3 changes: 1 addition & 2 deletions tests/fixtures/json/1.4/bom_setuptools.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@
],
"dependencies": [
{
"ref": "pkg:pypi/[email protected]?extension=tar.gz",
"dependsOn": []
"ref": "pkg:pypi/[email protected]?extension=tar.gz"
}
]
}
3 changes: 1 addition & 2 deletions tests/fixtures/json/1.4/bom_setuptools_complete.json
Original file line number Diff line number Diff line change
Expand Up @@ -352,8 +352,7 @@
],
"dependencies": [
{
"ref": "df70b5f1-8f53-47a4-be48-669ae78795e6",
"dependsOn": []
"ref": "df70b5f1-8f53-47a4-be48-669ae78795e6"
}
]
}
3 changes: 1 addition & 2 deletions tests/fixtures/json/1.4/bom_setuptools_no_version.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,7 @@
],
"dependencies": [
{
"ref": "pkg:pypi/setuptools?extension=tar.gz",
"dependsOn": []
"ref": "pkg:pypi/setuptools?extension=tar.gz"
}
]
}
3 changes: 1 addition & 2 deletions tests/fixtures/json/1.4/bom_setuptools_with_cpe.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,7 @@
],
"dependencies": [
{
"ref": "pkg:pypi/[email protected]?extension=tar.gz",
"dependsOn": []
"ref": "pkg:pypi/[email protected]?extension=tar.gz"
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@
],
"dependencies": [
{
"ref": "pkg:pypi/[email protected]?extension=tar.gz",
"dependsOn": []
"ref": "pkg:pypi/[email protected]?extension=tar.gz"
}
],
"vulnerabilities": [
Expand Down
3 changes: 1 addition & 2 deletions tests/fixtures/json/1.4/bom_toml_1.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,7 @@
],
"dependencies": [
{
"ref": "pkg:pypi/[email protected]?extension=tar.gz",
"dependsOn": []
"ref": "pkg:pypi/[email protected]?extension=tar.gz"
}
]
}
3 changes: 1 addition & 2 deletions tests/fixtures/json/1.4/bom_with_full_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -414,8 +414,7 @@
},
"dependencies": [
{
"ref": "be2c6502-7e9a-47db-9a66-e34f729810a3",
"dependsOn": []
"ref": "be2c6502-7e9a-47db-9a66-e34f729810a3"
}
]
}
8 changes: 7 additions & 1 deletion tests/test_output_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#
# SPDX-License-Identifier: Apache-2.0
# Copyright (c) OWASP Foundation. All Rights Reserved.

import unittest
from os.path import dirname, join
from unittest.mock import Mock, patch

Expand Down Expand Up @@ -177,6 +177,7 @@ def test_bom_v1_3_no_component_version(self) -> None:
fixture='bom_setuptools_no_version.json'
)

@unittest.skip('See https://github.com/CycloneDX/specification/issues/146')
def test_bom_v1_4_component_with_release_notes(self) -> None:
self._validate_json_bom(
bom=get_bom_with_component_setuptools_with_release_notes(), schema_version=SchemaVersion.V1_4,
Expand Down Expand Up @@ -310,6 +311,7 @@ def test_bom_v1_2_services_nested(self, mock_uuid: Mock) -> None:
)
mock_uuid.assert_called()

@unittest.skip('See https://github.com/CycloneDX/specification/issues/146')
def test_bom_v1_4_dependencies(self) -> None:
self._validate_json_bom(
bom=get_bom_with_dependencies_valid(), schema_version=SchemaVersion.V1_4,
Expand All @@ -328,6 +330,7 @@ def test_bom_v1_2_dependencies(self) -> None:
fixture='bom_dependencies.json'
)

@unittest.skip('See https://github.com/CycloneDX/specification/issues/146')
def test_bom_v1_4_dependencies_for_bom_component(self) -> None:
self._validate_json_bom(
bom=get_bom_with_metadata_component_and_dependencies(), schema_version=SchemaVersion.V1_4,
Expand All @@ -346,13 +349,15 @@ def test_bom_v1_2_dependencies_for_bom_component(self) -> None:
fixture='bom_dependencies_component.json'
)

@unittest.skip
def test_bom_v1_4_dependencies_invalid(self) -> None:
with self.assertRaises(UnknownComponentDependencyException):
self._validate_json_bom(
bom=get_bom_with_dependencies_invalid(), schema_version=SchemaVersion.V1_4,
fixture='bom_dependencies.json'
)

@unittest.skip('See https://github.com/CycloneDX/specification/issues/146')
def test_bom_v1_4_issue_275_components(self) -> None:
self._validate_json_bom(
bom=get_bom_for_issue_275_components(), schema_version=SchemaVersion.V1_4,
Expand All @@ -377,6 +382,7 @@ def _validate_json_bom(self, bom: Bom, schema_version: SchemaVersion, fixture: s
self.assertEqual(outputter.schema_version, schema_version)
with open(
join(dirname(__file__), f'fixtures/json/{schema_version.to_version()}/{fixture}')) as expected_json:
print(outputter.output_as_string())
self.assertValidAgainstSchema(bom_json=outputter.output_as_string(), schema_version=schema_version)
self.assertEqualJsonBom(expected_json.read(), outputter.output_as_string())
expected_json.close()
Expand Down
1 change: 0 additions & 1 deletion tests/test_output_xml.py
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,6 @@ def _validate_xml_bom(self, bom: Bom, schema_version: SchemaVersion, fixture: st
self.assertEqual(outputter.schema_version, schema_version)
with open(
join(dirname(__file__), f'fixtures/xml/{schema_version.to_version()}/{fixture}')) as expected_xml:
print(outputter.output_as_string())
self.assertValidAgainstSchema(bom_xml=outputter.output_as_string(), schema_version=schema_version)
self.assertEqualXmlBom(
expected_xml.read(), outputter.output_as_string(), namespace=outputter.get_target_namespace()
Expand Down

0 comments on commit 61fceb6

Please sign in to comment.