diff --git a/cyclonedx/model/component.py b/cyclonedx/model/component.py index 2990c3903..6b106c312 100644 --- a/cyclonedx/model/component.py +++ b/cyclonedx/model/component.py @@ -212,8 +212,8 @@ class ComponentIdentityEvidenceField(str, Enum): VERSION = 'version' PURL = 'purl' CPE = 'cpe' - OMNIBOR_ID = 'omniborId' - SWHID = 'swhid' + OMNIBOR_ID = 'omniborId' # Only supported in >= 1.6 + SWHID = 'swhid' # Only supported in >= 1.6 SWID = 'swid' HASH = 'hash' @@ -307,9 +307,11 @@ def __normalize( cs: ComponentIdentityEvidenceMethodTechnique, view: Type[serializable.ViewType] ) -> Optional[str]: - return cs.value \ - if cs in cls.__CASES.get(view, ()) \ - else None + return ( + cs + if cs in cls.__CASES.get(view, ()) + else ComponentIdentityEvidenceMethodTechnique.OTHER + ).value @classmethod def json_normalize(cls, o: Any, *, @@ -354,6 +356,7 @@ def __init__( @property @serializable.type_mapping(_ComponentIdentityEvidenceMethodTechniqueSerializationHelper) + @serializable.xml_sequence(1) def technique(self) -> Optional[ComponentIdentityEvidenceMethodTechnique]: """ The evidence technique used by the method of the component which the evidence describes. @@ -368,6 +371,7 @@ def technique(self, technique: Optional[ComponentIdentityEvidenceMethodTechnique self._technique = technique @property + @serializable.xml_sequence(2) def confidence(self) -> float: """ The overall confidence of the evidence from 0 - 1, where 1 is 100% confidence. @@ -389,6 +393,7 @@ def confidence(self, confidence: float) -> None: self._confidence = confidence @property + @serializable.xml_sequence(3) def value(self) -> Optional[str]: """ The value or contents of the evidence. @@ -452,6 +457,7 @@ def __init__( @property @serializable.type_mapping(_ComponentIdentityEvidenceFieldSerializationHelper) + @serializable.xml_sequence(1) def field(self) -> Optional[ComponentIdentityEvidenceField]: """ The identity field of the component which the evidence describes. @@ -466,6 +472,7 @@ def field(self, field: Optional[ComponentIdentityEvidenceField]) -> None: self._field = field @property + @serializable.xml_sequence(2) def confidence(self) -> Optional[float]: """ The overall confidence of the evidence from 0 - 1, where 1 is 100% confidence. @@ -486,6 +493,7 @@ def confidence(self, confidence: Optional[float]) -> None: @property @serializable.type_mapping(ComponentIdentityEvidenceMethod) + @serializable.xml_sequence(3) def methods(self) -> 'SortedSet[ComponentIdentityEvidenceMethod]': """ Optional list of methods used to extract and/or analyze the evidence. @@ -500,6 +508,7 @@ def methods(self, methods: Iterable[ComponentIdentityEvidenceMethod]) -> None: self._methods = SortedSet(methods) @property + @serializable.xml_sequence(4) def tools(self) -> 'SortedSet[str]': """ Optional list of tools used to extract and/or analyze the evidence. @@ -547,36 +556,36 @@ class ComponentEvidence: def __init__( self, *, - identity: Optional[ComponentIdentityEvidence] = None, + identity: Optional[Iterable[ComponentIdentityEvidence]] = None, licenses: Optional[Iterable[License]] = None, copyright: Optional[Iterable[Copyright]] = None, ) -> None: if not licenses and not copyright and not identity: raise NoPropertiesProvidedException( - 'At least one of `licenses` or `copyright` must be supplied for a `ComponentEvidence`.' + 'At least one of `licenses`, `copyright` or `identity` must be supplied for a `ComponentEvidence`.' ) - self.identity = identity + self.identity = identity or [] # type:ignore[assignment] self.licenses = licenses or [] # type:ignore[assignment] self.copyright = copyright or [] # type:ignore[assignment] @property @serializable.view(SchemaVersion1Dot5) @serializable.view(SchemaVersion1Dot6) + @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'identity') @serializable.xml_sequence(1) - def identity(self) -> Optional[ComponentIdentityEvidence]: + def identity(self) -> 'SortedSet[ComponentIdentityEvidence]': """ Optional list of evidence that substantiates the identity of a component. Returns: - `ComponentIdentityEvidence` or `None` + Set of `ComponentIdentityEvidence` """ - return self._identity @identity.setter - def identity(self, identity: Optional[ComponentIdentityEvidence]) -> None: - self._identity = identity + def identity(self, identity: Iterable[ComponentIdentityEvidence]) -> None: + self._identity = SortedSet(identity) # @property # ... @@ -647,7 +656,7 @@ def __lt__(self, other: Any) -> bool: return NotImplemented def __hash__(self) -> int: - return hash((self.identity, tuple(self.licenses), tuple(self.copyright))) + return hash((tuple(self.identity), tuple(self.licenses), tuple(self.copyright))) def __repr__(self) -> str: return f'' diff --git a/tests/_data/models.py b/tests/_data/models.py index d82d2090c..150739a0e 100644 --- a/tests/_data/models.py +++ b/tests/_data/models.py @@ -47,10 +47,6 @@ Commit, Component, ComponentEvidence, - ComponentIdentityEvidence, - ComponentIdentityEvidenceField, - ComponentIdentityEvidenceMethod, - ComponentIdentityEvidenceMethodTechnique, ComponentScope, ComponentType, Diff, @@ -934,15 +930,6 @@ def get_swid_2() -> Swid: ) -def get_evidence_identity() -> ComponentIdentityEvidence: - return ComponentIdentityEvidence( - field=ComponentIdentityEvidenceField.NAME, confidence=0.5, methods=[ - ComponentIdentityEvidenceMethod(technique=ComponentIdentityEvidenceMethodTechnique.FILENAME, confidence=0.5) - ], - tools=['cyclonedx-python-lib'] - ) - - def get_vulnerability_source_nvd() -> VulnerabilitySource: return VulnerabilitySource(name='NVD', url=XsUri('https://nvd.nist.gov/vuln/detail/CVE-2018-7489')) diff --git a/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.0.xml.bin b/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.0.xml.bin new file mode 100644 index 000000000..acb066124 --- /dev/null +++ b/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.0.xml.bin @@ -0,0 +1,4 @@ + + + + diff --git a/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.1.xml.bin b/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.1.xml.bin new file mode 100644 index 000000000..55ef5cda2 --- /dev/null +++ b/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.1.xml.bin @@ -0,0 +1,4 @@ + + + + diff --git a/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.2.json.bin b/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.2.json.bin new file mode 100644 index 000000000..fafe615c9 --- /dev/null +++ b/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.2.json.bin @@ -0,0 +1,17 @@ +{ + "metadata": { + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.2" +} diff --git a/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.2.xml.bin b/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.2.xml.bin new file mode 100644 index 000000000..bc36ede08 --- /dev/null +++ b/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.2.xml.bin @@ -0,0 +1,13 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + diff --git a/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.3.json.bin b/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.3.json.bin new file mode 100644 index 000000000..d2e65ac15 --- /dev/null +++ b/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.3.json.bin @@ -0,0 +1,17 @@ +{ + "metadata": { + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.3" +} diff --git a/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.3.xml.bin b/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.3.xml.bin new file mode 100644 index 000000000..1ebd391f9 --- /dev/null +++ b/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.3.xml.bin @@ -0,0 +1,13 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + diff --git a/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.4.json.bin b/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.4.json.bin new file mode 100644 index 000000000..513c4f0f5 --- /dev/null +++ b/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.4.json.bin @@ -0,0 +1,17 @@ +{ + "metadata": { + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.4" +} diff --git a/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.4.xml.bin b/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.4.xml.bin new file mode 100644 index 000000000..21093ed67 --- /dev/null +++ b/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.4.xml.bin @@ -0,0 +1,14 @@ + + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + diff --git a/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.5.json.bin b/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.5.json.bin new file mode 100644 index 000000000..b533e71c3 --- /dev/null +++ b/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.5.json.bin @@ -0,0 +1,73 @@ +{ + "components": [ + { + "bom-ref": "dummy", + "name": "dummy", + "type": "application", + "evidence": { + "identity": { + "field": "group" + } + } + } + ], + "metadata": { + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "externalReferences": [ + { + "type": "build-system", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions" + }, + { + "type": "distribution", + "url": "https://pypi.org/project/cyclonedx-python-lib/" + }, + { + "type": "documentation", + "url": "https://cyclonedx-python-library.readthedocs.io/" + }, + { + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues" + }, + { + "type": "license", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE" + }, + { + "type": "release-notes", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md" + }, + { + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib" + }, + { + "type": "website", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/#readme" + } + ], + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "properties": [ + { + "name": "key1", + "value": "val1" + }, + { + "name": "key2", + "value": "val2" + } + ], + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.5" +} diff --git a/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.5.xml.bin b/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.5.xml.bin new file mode 100644 index 000000000..67d8e9bdb --- /dev/null +++ b/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.5.xml.bin @@ -0,0 +1,53 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + https://github.com/CycloneDX/cyclonedx-python-lib/actions + + + https://pypi.org/project/cyclonedx-python-lib/ + + + https://cyclonedx-python-library.readthedocs.io/ + + + https://github.com/CycloneDX/cyclonedx-python-lib/issues + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md + + + https://github.com/CycloneDX/cyclonedx-python-lib + + + https://github.com/CycloneDX/cyclonedx-python-lib/#readme + + + + + + + + dummy + + + group + + + + + + val1 + val2 + + diff --git a/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.6.json.bin b/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.6.json.bin new file mode 100644 index 000000000..62c96b5da --- /dev/null +++ b/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.6.json.bin @@ -0,0 +1,99 @@ +{ + "components": [ + { + "bom-ref": "dummy", + "name": "dummy", + "type": "application", + "evidence": { + "identity": [ + { + "field": "group" + }, + { + "field": "name" + }, + { + "field": "version" + }, + { + "field": "purl" + }, + { + "field": "cpe" + }, + { + "field": "omniborId" + }, + { + "field": "swhid" + }, + { + "field": "swid" + }, + { + "field": "hash" + } + ] + } + } + ], + "metadata": { + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "externalReferences": [ + { + "type": "build-system", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions" + }, + { + "type": "distribution", + "url": "https://pypi.org/project/cyclonedx-python-lib/" + }, + { + "type": "documentation", + "url": "https://cyclonedx-python-library.readthedocs.io/" + }, + { + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues" + }, + { + "type": "license", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE" + }, + { + "type": "release-notes", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md" + }, + { + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib" + }, + { + "type": "website", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/#readme" + } + ], + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "properties": [ + { + "name": "key1", + "value": "val1" + }, + { + "name": "key2", + "value": "val2" + } + ], + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.6" +} diff --git a/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.6.xml.bin b/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.6.xml.bin new file mode 100644 index 000000000..bc7e7b68d --- /dev/null +++ b/tests/_data/snapshots/enum_ComponentIdentityEvidenceField-1.6.xml.bin @@ -0,0 +1,53 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + https://github.com/CycloneDX/cyclonedx-python-lib/actions + + + https://pypi.org/project/cyclonedx-python-lib/ + + + https://cyclonedx-python-library.readthedocs.io/ + + + https://github.com/CycloneDX/cyclonedx-python-lib/issues + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md + + + https://github.com/CycloneDX/cyclonedx-python-lib + + + https://github.com/CycloneDX/cyclonedx-python-lib/#readme + + + + + + + + dummy + + + group + + + + + + val1 + val2 + + diff --git a/tests/test_enums.py b/tests/test_enums.py index ba5c6c5f6..fec8fa9de 100644 --- a/tests/test_enums.py +++ b/tests/test_enums.py @@ -29,7 +29,16 @@ from cyclonedx.exception.serialization import SerializationOfUnsupportedComponentTypeException from cyclonedx.model import AttachedText, ExternalReference, HashType, XsUri from cyclonedx.model.bom import Bom -from cyclonedx.model.component import Component, Patch, Pedigree +from cyclonedx.model.component import ( + Component, + ComponentEvidence, + ComponentIdentityEvidence, + ComponentIdentityEvidenceField, + ComponentIdentityEvidenceMethod, + ComponentIdentityEvidenceMethodTechnique, + Patch, + Pedigree, +) from cyclonedx.model.issue import IssueType from cyclonedx.model.license import DisjunctiveLicense from cyclonedx.model.service import DataClassification, Service @@ -355,6 +364,37 @@ def test_cases_render_valid(self, of: OutputFormat, sv: SchemaVersion, *_: Any, super()._test_cases_render(bom, of, sv) +@ddt +class TestEnumComponentIdentityEvidenceField(_EnumTestCase): + + @idata(set(chain( + # dp_cases_from_xml_schemas(f"./{SCHEMA_NS}simpleType[@name='componentIdentityEvidence']"), + dp_cases_from_json_schemas('definitions', 'componentIdentityEvidence', 'properties', 'field'), + ))) + def test_knows_value(self, value: str) -> None: + super()._test_knows_value(ComponentIdentityEvidenceField, value) + + @named_data(*NAMED_OF_SV) + @patch('cyclonedx.model.ThisTool._version', 'TESTING') + def test_cases_render_valid(self, of: OutputFormat, sv: SchemaVersion, *_: Any, **__: Any) -> None: + bom = _make_bom(components=[ + Component(name='dummy', type=ComponentType.LIBRARY, bom_ref='dummy', evidence=ComponentEvidence( + identity=[ + ComponentIdentityEvidence( + field=cief, + confidence=0.5, + methods=[ + ComponentIdentityEvidenceMethod(technique=ciemt, confidence=0.5) + for ciemt in ComponentIdentityEvidenceMethodTechnique + ] + ) + ] + )) + for cief in ComponentIdentityEvidenceField + ]) + super()._test_cases_render(bom, of, sv) + + @ddt class TestEnumImpactAnalysisJustification(_EnumTestCase): diff --git a/tests/test_model_component.py b/tests/test_model_component.py index 6a821262e..047eb342d 100644 --- a/tests/test_model_component.py +++ b/tests/test_model_component.py @@ -308,64 +308,72 @@ def test_same_2(self) -> None: def test_same_3(self) -> None: ce_1 = ComponentEvidence( - identity=ComponentIdentityEvidence( - field=ComponentIdentityEvidenceField.NAME, - confidence=0.5, - methods=[ - ComponentIdentityEvidenceMethod( - technique=ComponentIdentityEvidenceMethodTechnique.HASH_COMPARISON, - confidence=0.5 - ) - ] - ) + identity=[ + ComponentIdentityEvidence( + field=ComponentIdentityEvidenceField.NAME, + confidence=0.5, + methods=[ + ComponentIdentityEvidenceMethod( + technique=ComponentIdentityEvidenceMethodTechnique.HASH_COMPARISON, + confidence=0.5 + ) + ] + ) + ] ) ce_2 = ComponentEvidence( - identity=ComponentIdentityEvidence( - field=ComponentIdentityEvidenceField.NAME, - confidence=0.5, - methods=[ - ComponentIdentityEvidenceMethod( - technique=ComponentIdentityEvidenceMethodTechnique.HASH_COMPARISON, - confidence=0.5 - ) - ] - ) + identity=[ + ComponentIdentityEvidence( + field=ComponentIdentityEvidenceField.NAME, + confidence=0.5, + methods=[ + ComponentIdentityEvidenceMethod( + technique=ComponentIdentityEvidenceMethodTechnique.HASH_COMPARISON, + confidence=0.5 + ) + ] + ) + ] ) self.assertEqual(hash(ce_1), hash(ce_2)) self.assertTrue(ce_1 == ce_2) def test_same_4(self) -> None: ce_1 = ComponentEvidence( - identity=ComponentIdentityEvidence( - field=ComponentIdentityEvidenceField.NAME, - confidence=0.5, - methods=[ - ComponentIdentityEvidenceMethod( - technique=ComponentIdentityEvidenceMethodTechnique.HASH_COMPARISON, - confidence=0.5 - ), - ComponentIdentityEvidenceMethod( - technique=ComponentIdentityEvidenceMethodTechnique.FILENAME, - confidence=0.2 - ) - ] - ) + identity=[ + ComponentIdentityEvidence( + field=ComponentIdentityEvidenceField.NAME, + confidence=0.5, + methods=[ + ComponentIdentityEvidenceMethod( + technique=ComponentIdentityEvidenceMethodTechnique.HASH_COMPARISON, + confidence=0.5 + ), + ComponentIdentityEvidenceMethod( + technique=ComponentIdentityEvidenceMethodTechnique.FILENAME, + confidence=0.2 + ) + ] + ) + ] ) ce_2 = ComponentEvidence( - identity=ComponentIdentityEvidence( - field=ComponentIdentityEvidenceField.NAME, - confidence=0.5, - methods=[ - ComponentIdentityEvidenceMethod( - technique=ComponentIdentityEvidenceMethodTechnique.FILENAME, - confidence=0.2 - ), - ComponentIdentityEvidenceMethod( - technique=ComponentIdentityEvidenceMethodTechnique.HASH_COMPARISON, - confidence=0.5 - ) - ] - ) + identity=[ + ComponentIdentityEvidence( + field=ComponentIdentityEvidenceField.NAME, + confidence=0.5, + methods=[ + ComponentIdentityEvidenceMethod( + technique=ComponentIdentityEvidenceMethodTechnique.FILENAME, + confidence=0.2 + ), + ComponentIdentityEvidenceMethod( + technique=ComponentIdentityEvidenceMethodTechnique.HASH_COMPARISON, + confidence=0.5 + ) + ] + ) + ] ) self.assertEqual(hash(ce_1), hash(ce_2)) self.assertTrue(ce_1 == ce_2) @@ -378,71 +386,79 @@ def test_not_same_1(self) -> None: def test_not_same_2(self) -> None: ce_1 = ComponentEvidence( - identity=ComponentIdentityEvidence( - field=ComponentIdentityEvidenceField.NAME, - confidence=0.5, - methods=[ - ComponentIdentityEvidenceMethod( - technique=ComponentIdentityEvidenceMethodTechnique.HASH_COMPARISON, - confidence=0.5 - ), - ComponentIdentityEvidenceMethod( - technique=ComponentIdentityEvidenceMethodTechnique.BINARY_ANALYSIS, - confidence=0.7 - ) - ] - ) + identity=[ + ComponentIdentityEvidence( + field=ComponentIdentityEvidenceField.NAME, + confidence=0.5, + methods=[ + ComponentIdentityEvidenceMethod( + technique=ComponentIdentityEvidenceMethodTechnique.HASH_COMPARISON, + confidence=0.5 + ), + ComponentIdentityEvidenceMethod( + technique=ComponentIdentityEvidenceMethodTechnique.BINARY_ANALYSIS, + confidence=0.7 + ) + ] + ) + ] ) ce_2 = ComponentEvidence( - identity=ComponentIdentityEvidence( - field=ComponentIdentityEvidenceField.NAME, - confidence=0.5, - methods=[ - ComponentIdentityEvidenceMethod( - technique=ComponentIdentityEvidenceMethodTechnique.BINARY_ANALYSIS, - confidence=0.5 - ), - ComponentIdentityEvidenceMethod( - technique=ComponentIdentityEvidenceMethodTechnique.HASH_COMPARISON, - confidence=0.5 - ) - ] - ) + identity=[ + ComponentIdentityEvidence( + field=ComponentIdentityEvidenceField.NAME, + confidence=0.5, + methods=[ + ComponentIdentityEvidenceMethod( + technique=ComponentIdentityEvidenceMethodTechnique.BINARY_ANALYSIS, + confidence=0.5 + ), + ComponentIdentityEvidenceMethod( + technique=ComponentIdentityEvidenceMethodTechnique.HASH_COMPARISON, + confidence=0.5 + ) + ] + ) + ] ) self.assertNotEqual(hash(ce_1), hash(ce_2)) def test_not_same_3(self) -> None: ce_1 = ComponentEvidence( - identity=ComponentIdentityEvidence( - field=ComponentIdentityEvidenceField.NAME, - confidence=0.5, - methods=[ - ComponentIdentityEvidenceMethod( - technique=ComponentIdentityEvidenceMethodTechnique.HASH_COMPARISON, - confidence=0.5 - ), - ComponentIdentityEvidenceMethod( - technique=ComponentIdentityEvidenceMethodTechnique.BINARY_ANALYSIS, - confidence=0.7 - ) - ] - ) + identity=[ + ComponentIdentityEvidence( + field=ComponentIdentityEvidenceField.NAME, + confidence=0.5, + methods=[ + ComponentIdentityEvidenceMethod( + technique=ComponentIdentityEvidenceMethodTechnique.HASH_COMPARISON, + confidence=0.5 + ), + ComponentIdentityEvidenceMethod( + technique=ComponentIdentityEvidenceMethodTechnique.BINARY_ANALYSIS, + confidence=0.7 + ) + ] + ) + ] ) ce_2 = ComponentEvidence( - identity=ComponentIdentityEvidence( - field=ComponentIdentityEvidenceField.HASH, - confidence=0.5, - methods=[ - ComponentIdentityEvidenceMethod( - technique=ComponentIdentityEvidenceMethodTechnique.BINARY_ANALYSIS, - confidence=0.7 - ), - ComponentIdentityEvidenceMethod( - technique=ComponentIdentityEvidenceMethodTechnique.HASH_COMPARISON, - confidence=0.5 - ) - ] - ) + identity=[ + ComponentIdentityEvidence( + field=ComponentIdentityEvidenceField.HASH, + confidence=0.5, + methods=[ + ComponentIdentityEvidenceMethod( + technique=ComponentIdentityEvidenceMethodTechnique.BINARY_ANALYSIS, + confidence=0.7 + ), + ComponentIdentityEvidenceMethod( + technique=ComponentIdentityEvidenceMethodTechnique.HASH_COMPARISON, + confidence=0.5 + ) + ] + ) + ] ) self.assertNotEqual(hash(ce_1), hash(ce_2)) self.assertFalse(ce_1 == ce_2)