Skip to content

Commit d189f2c

Browse files
authoredFeb 17, 2022
BREAKING CHANGE: added new model BomRef unlocking logic later to ensure uniquness and dependency references (#174)
Signed-off-by: Paul Horton <phorton@sonatype.com>
1 parent 020fcf0 commit d189f2c

27 files changed

+192
-185
lines changed
 

‎cyclonedx/model/bom_ref.py

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# encoding: utf-8
2+
3+
# This file is part of CycloneDX Python Lib
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
# SPDX-License-Identifier: Apache-2.0
18+
# Copyright (c) OWASP Foundation. All Rights Reserved.
19+
from typing import Optional
20+
from uuid import uuid4
21+
22+
23+
class BomRef:
24+
"""
25+
An identifier that can be used to reference objects elsewhere in the BOM.
26+
27+
This copies a similar pattern used in the CycloneDX Python Library.
28+
29+
.. note::
30+
See https://github.com/CycloneDX/cyclonedx-php-library/blob/master/docs/dev/decisions/BomDependencyDataModel.md
31+
"""
32+
33+
def __init__(self, value: Optional[str] = None) -> None:
34+
self.value = value or str(uuid4())
35+
36+
@property
37+
def value(self) -> str:
38+
return self._value
39+
40+
@value.setter
41+
def value(self, value: str) -> None:
42+
self._value = value
43+
44+
def __eq__(self, other: object) -> bool:
45+
if isinstance(other, BomRef):
46+
return hash(other) == hash(self)
47+
return False
48+
49+
def __hash__(self) -> int:
50+
return hash(self.value)
51+
52+
def __repr__(self) -> str:
53+
return self.value

‎cyclonedx/model/component.py

+4-8
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@
2020
from enum import Enum
2121
from os.path import exists
2222
from typing import Iterable, Optional, Set
23-
from uuid import uuid4
2423

2524
# See https://github.com/package-url/packageurl-python/issues/65
2625
from packageurl import PackageURL # type: ignore
2726

2827
from . import AttachedText, Copyright, ExternalReference, HashAlgorithm, HashType, IdentifiableAction, LicenseChoice, \
2928
OrganizationalEntity, Property, sha1sum, XsUri
29+
from .bom_ref import BomRef
3030
from .issue import IssueType
3131
from .release_note import ReleaseNotes
3232
from .vulnerability import Vulnerability
@@ -692,7 +692,7 @@ def __init__(self, *, name: str, component_type: ComponentType = ComponentType.L
692692
) -> None:
693693
self.type = component_type
694694
self.mime_type = mime_type
695-
self.bom_ref = bom_ref or str(uuid4())
695+
self._bom_ref = BomRef(value=bom_ref)
696696
self.supplier = supplier
697697
self.author = author
698698
self.publisher = publisher
@@ -766,22 +766,18 @@ def mime_type(self, mime_type: Optional[str]) -> None:
766766
self._mime_type = mime_type
767767

768768
@property
769-
def bom_ref(self) -> str:
769+
def bom_ref(self) -> BomRef:
770770
"""
771771
An optional identifier which can be used to reference the component elsewhere in the BOM. Every bom-ref MUST be
772772
unique within the BOM.
773773
774774
If a value was not provided in the constructor, a UUIDv4 will have been assigned.
775775
776776
Returns:
777-
`str` as a unique identifiers for this Component
777+
`BomRef`
778778
"""
779779
return self._bom_ref
780780

781-
@bom_ref.setter
782-
def bom_ref(self, bom_ref: str) -> None:
783-
self._bom_ref = bom_ref
784-
785781
@property
786782
def supplier(self) -> Optional[OrganizationalEntity]:
787783
"""

‎cyclonedx/model/service.py

+4-8
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
# SPDX-License-Identifier: Apache-2.0
1616
# Copyright (c) OWASP Foundation. All Rights Reserved.
1717
from typing import Iterable, Optional, Set
18-
from uuid import uuid4
1918

2019
from . import ExternalReference, DataClassification, LicenseChoice, OrganizationalEntity, Property, XsUri
20+
from .bom_ref import BomRef
2121
from .release_note import ReleaseNotes
2222

2323
"""
@@ -46,7 +46,7 @@ def __init__(self, *, name: str, bom_ref: Optional[str] = None, provider: Option
4646
services: Optional[Iterable['Service']] = None,
4747
release_notes: Optional[ReleaseNotes] = None,
4848
) -> None:
49-
self.bom_ref = bom_ref or str(uuid4())
49+
self._bom_ref = BomRef(value=bom_ref)
5050
self.provider = provider
5151
self.group = group
5252
self.name = name
@@ -63,22 +63,18 @@ def __init__(self, *, name: str, bom_ref: Optional[str] = None, provider: Option
6363
self.properties = set(properties or [])
6464

6565
@property
66-
def bom_ref(self) -> Optional[str]:
66+
def bom_ref(self) -> BomRef:
6767
"""
6868
An optional identifier which can be used to reference the service elsewhere in the BOM. Uniqueness is enforced
6969
within all elements and children of the root-level bom element.
7070
7171
If a value was not provided in the constructor, a UUIDv4 will have been assigned.
7272
7373
Returns:
74-
`str` unique identifier for this Service
74+
`BomRef` unique identifier for this Service
7575
"""
7676
return self._bom_ref
7777

78-
@bom_ref.setter
79-
def bom_ref(self, bom_ref: Optional[str]) -> None:
80-
self._bom_ref = bom_ref
81-
8278
@property
8379
def provider(self) -> Optional[OrganizationalEntity]:
8480
"""

‎cyclonedx/output/serializer/json.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
#
1717
# SPDX-License-Identifier: Apache-2.0
1818
# Copyright (c) OWASP Foundation. All Rights Reserved.
19-
2019
from datetime import datetime
2120
from decimal import Decimal
2221
from enum import Enum
@@ -28,8 +27,9 @@
2827
# See https://github.com/package-url/packageurl-python/issues/65
2928
from packageurl import PackageURL # type: ignore
3029

31-
from cyclonedx.model import XsUri
32-
from cyclonedx.model.component import Component
30+
from ...model import XsUri
31+
from ...model.bom_ref import BomRef
32+
from ...model.component import Component
3333

3434
HYPHENATED_ATTRIBUTES = [
3535
'bom_ref', 'mime_type', 'x_trust_boundary'
@@ -40,6 +40,10 @@
4040
class CycloneDxJSONEncoder(JSONEncoder):
4141

4242
def default(self, o: Any) -> Any:
43+
# BomRef
44+
if isinstance(o, BomRef):
45+
return str(o)
46+
4347
# datetime
4448
if isinstance(o, datetime):
4549
return o.isoformat()

‎cyclonedx/output/xml.py

+5-4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from ..model import AttachedText, ExternalReference, HashType, IdentifiableAction, LicenseChoice, \
2828
OrganizationalEntity, OrganizationalContact, Property, Tool
2929
from ..model.bom import Bom
30+
from ..model.bom_ref import BomRef
3031
from ..model.component import Component, Patch
3132
from ..model.release_note import ReleaseNotes
3233
from ..model.service import Service
@@ -174,7 +175,7 @@ def _add_metadata_element(self) -> None:
174175
def _add_component_element(self, component: Component) -> ElementTree.Element:
175176
element_attributes = {'type': component.type.value}
176177
if self.component_supports_bom_ref_attribute() and component.bom_ref:
177-
element_attributes['bom-ref'] = component.bom_ref
178+
element_attributes['bom-ref'] = str(component.bom_ref)
178179
if self.component_supports_mime_type_attribute() and component.mime_type:
179180
element_attributes['mime-type'] = component.mime_type
180181

@@ -450,7 +451,7 @@ def _add_properties_element(properties: Set[Property], parent_element: ElementTr
450451
def _add_service_element(self, service: Service) -> ElementTree.Element:
451452
element_attributes = {}
452453
if service.bom_ref:
453-
element_attributes['bom-ref'] = service.bom_ref
454+
element_attributes['bom-ref'] = str(service.bom_ref)
454455

455456
service_element = ElementTree.Element('service', element_attributes)
456457

@@ -654,10 +655,10 @@ def _get_vulnerability_as_xml_element_post_1_4(self, vulnerability: Vulnerabilit
654655
return vulnerability_element
655656

656657
@staticmethod
657-
def _get_vulnerability_as_xml_element_pre_1_3(bom_ref: str,
658+
def _get_vulnerability_as_xml_element_pre_1_3(bom_ref: BomRef,
658659
vulnerability: Vulnerability) -> ElementTree.Element:
659660
vulnerability_element = ElementTree.Element('v:vulnerability', {
660-
'ref': bom_ref
661+
'ref': str(bom_ref)
661662
})
662663

663664
# id

‎tests/data.py

+4
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@
4545
MOCK_UUID_5 = 'bb5911d6-1a1d-41c9-b6e0-46e848d16655'
4646
MOCK_UUID_6 = 'df70b5f1-8f53-47a4-be48-669ae78795e6'
4747

48+
TEST_UUIDS = [
49+
MOCK_UUID_1, MOCK_UUID_2, MOCK_UUID_3, MOCK_UUID_4, MOCK_UUID_5, MOCK_UUID_6
50+
]
51+
4852

4953
def get_bom_with_component_setuptools_basic() -> Bom:
5054
return Bom(components=[get_component_setuptools_simple()])

‎tests/fixtures/json/1.2/bom_services_complex.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
],
1616
"component": {
1717
"type": "library",
18-
"bom-ref": "cd3e9c95-9d41-49e7-9924-8cf0465ae789",
18+
"bom-ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda",
1919
"name": "cyclonedx-python-lib",
2020
"version": "1.0.0"
2121
}
@@ -76,7 +76,7 @@
7676
]
7777
},
7878
{
79-
"bom-ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda",
79+
"bom-ref": "be2c6502-7e9a-47db-9a66-e34f729810a3",
8080
"name": "my-second-service"
8181
}
8282
]

‎tests/fixtures/json/1.2/bom_services_nested.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"bomFormat": "CycloneDX",
44
"metadata": {
55
"component": {
6-
"bom-ref": "bb5911d6-1a1d-41c9-b6e0-46e848d16655",
6+
"bom-ref": "cd3e9c95-9d41-49e7-9924-8cf0465ae789",
77
"name": "cyclonedx-python-lib",
88
"type": "library",
99
"version": "1.0.0"
@@ -72,7 +72,7 @@
7272
},
7373
"services": [
7474
{
75-
"bom-ref": "df70b5f1-8f53-47a4-be48-669ae78795e6",
75+
"bom-ref": "be2c6502-7e9a-47db-9a66-e34f729810a3",
7676
"name": "first-nested-service"
7777
},
7878
{
@@ -105,11 +105,11 @@
105105
"x-trust-boundary": true
106106
},
107107
{
108-
"bom-ref": "df70b5f1-8f53-47a4-be48-669ae78795e6",
108+
"bom-ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857",
109109
"name": "my-second-service",
110110
"services": [
111111
{
112-
"bom-ref": "df70b5f1-8f53-47a4-be48-669ae78795e6",
112+
"bom-ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda",
113113
"group": "what-group",
114114
"name": "yet-another-nested-service",
115115
"provider": {

‎tests/fixtures/json/1.2/bom_services_simple.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,18 @@
1515
],
1616
"component": {
1717
"type": "library",
18-
"bom-ref": "cd3e9c95-9d41-49e7-9924-8cf0465ae789",
18+
"bom-ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857",
1919
"name": "cyclonedx-python-lib",
2020
"version": "1.0.0"
2121
}
2222
},
2323
"services": [
2424
{
25-
"bom-ref": "bb5911d6-1a1d-41c9-b6e0-46e848d16655",
25+
"bom-ref": "be2c6502-7e9a-47db-9a66-e34f729810a3",
2626
"name": "my-first-service"
2727
},
2828
{
29-
"bom-ref": "bb5911d6-1a1d-41c9-b6e0-46e848d16655",
29+
"bom-ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda",
3030
"name": "my-second-service"
3131
}
3232
]

‎tests/fixtures/json/1.3/bom_services_complex.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
],
1616
"component": {
1717
"type": "library",
18-
"bom-ref": "bb5911d6-1a1d-41c9-b6e0-46e848d16655",
18+
"bom-ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda",
1919
"name": "cyclonedx-python-lib",
2020
"version": "1.0.0"
2121
}
@@ -86,7 +86,7 @@
8686
]
8787
},
8888
{
89-
"bom-ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857",
89+
"bom-ref": "be2c6502-7e9a-47db-9a66-e34f729810a3",
9090
"name": "my-second-service"
9191
}
9292
]

‎tests/fixtures/json/1.3/bom_services_nested.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"bomFormat": "CycloneDX",
44
"metadata": {
55
"component": {
6-
"bom-ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857",
6+
"bom-ref": "cd3e9c95-9d41-49e7-9924-8cf0465ae789",
77
"name": "cyclonedx-python-lib",
88
"type": "library",
99
"version": "1.0.0"
@@ -82,7 +82,7 @@
8282
},
8383
"services": [
8484
{
85-
"bom-ref": "cd3e9c95-9d41-49e7-9924-8cf0465ae789",
85+
"bom-ref": "be2c6502-7e9a-47db-9a66-e34f729810a3",
8686
"name": "first-nested-service"
8787
},
8888
{
@@ -115,11 +115,11 @@
115115
"x-trust-boundary": true
116116
},
117117
{
118-
"bom-ref": "cd3e9c95-9d41-49e7-9924-8cf0465ae789",
118+
"bom-ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857",
119119
"name": "my-second-service",
120120
"services": [
121121
{
122-
"bom-ref": "cd3e9c95-9d41-49e7-9924-8cf0465ae789",
122+
"bom-ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda",
123123
"group": "what-group",
124124
"name": "yet-another-nested-service",
125125
"provider": {

‎tests/fixtures/json/1.3/bom_services_simple.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,18 @@
1515
],
1616
"component": {
1717
"type": "library",
18-
"bom-ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda",
18+
"bom-ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857",
1919
"name": "cyclonedx-python-lib",
2020
"version": "1.0.0"
2121
}
2222
},
2323
"services": [
2424
{
25-
"bom-ref": "cd3e9c95-9d41-49e7-9924-8cf0465ae789",
25+
"bom-ref": "be2c6502-7e9a-47db-9a66-e34f729810a3",
2626
"name": "my-first-service"
2727
},
2828
{
29-
"bom-ref": "cd3e9c95-9d41-49e7-9924-8cf0465ae789",
29+
"bom-ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda",
3030
"name": "my-second-service"
3131
}
3232
]

‎tests/fixtures/json/1.4/bom_services_complex.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
],
5050
"component": {
5151
"type": "library",
52-
"bom-ref": "df70b5f1-8f53-47a4-be48-669ae78795e6",
52+
"bom-ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda",
5353
"name": "cyclonedx-python-lib",
5454
"version": "1.0.0"
5555
}
@@ -179,7 +179,7 @@
179179
]
180180
},
181181
{
182-
"bom-ref": "cd3e9c95-9d41-49e7-9924-8cf0465ae789",
182+
"bom-ref": "be2c6502-7e9a-47db-9a66-e34f729810a3",
183183
"name": "my-second-service"
184184
}
185185
]

‎tests/fixtures/json/1.4/bom_services_nested.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"bomFormat": "CycloneDX",
44
"metadata": {
55
"component": {
6-
"bom-ref": "be2c6502-7e9a-47db-9a66-e34f729810a3",
6+
"bom-ref": "cd3e9c95-9d41-49e7-9924-8cf0465ae789",
77
"name": "cyclonedx-python-lib",
88
"type": "library",
99
"version": "1.0.0"
@@ -175,7 +175,7 @@
175175
},
176176
"services": [
177177
{
178-
"bom-ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda",
178+
"bom-ref": "be2c6502-7e9a-47db-9a66-e34f729810a3",
179179
"name": "first-nested-service"
180180
},
181181
{
@@ -208,7 +208,7 @@
208208
"x-trust-boundary": true
209209
},
210210
{
211-
"bom-ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda",
211+
"bom-ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857",
212212
"name": "my-second-service",
213213
"services": [
214214
{

‎tests/fixtures/json/1.4/bom_services_simple.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,18 @@
4949
],
5050
"component": {
5151
"type": "library",
52-
"bom-ref": "be2c6502-7e9a-47db-9a66-e34f729810a3",
52+
"bom-ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857",
5353
"name": "cyclonedx-python-lib",
5454
"version": "1.0.0"
5555
}
5656
},
5757
"services": [
5858
{
59-
"bom-ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857",
59+
"bom-ref": "be2c6502-7e9a-47db-9a66-e34f729810a3",
6060
"name": "my-first-service"
6161
},
6262
{
63-
"bom-ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857",
63+
"bom-ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda",
6464
"name": "my-second-service"
6565
}
6666
]

‎tests/fixtures/xml/1.2/bom_services_complex.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<version>VERSION</version>
1010
</tool>
1111
</tools>
12-
<component bom-ref="cd3e9c95-9d41-49e7-9924-8cf0465ae789" type="library">
12+
<component bom-ref="17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda" type="library">
1313
<name>cyclonedx-python-lib</name>
1414
<version>1.0.0</version>
1515
</component>

‎tests/fixtures/xml/1.2/bom_services_simple.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<version>VERSION</version>
1010
</tool>
1111
</tools>
12-
<component bom-ref="cd3e9c95-9d41-49e7-9924-8cf0465ae789" type="library">
12+
<component bom-ref="0b049d09-64c0-4490-a0f5-c84d9aacf857" type="library">
1313
<name>cyclonedx-python-lib</name>
1414
<version>1.0.0</version>
1515
</component>

‎tests/fixtures/xml/1.3/bom_services_complex.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<version>VERSION</version>
1010
</tool>
1111
</tools>
12-
<component bom-ref="bb5911d6-1a1d-41c9-b6e0-46e848d16655" type="library">
12+
<component bom-ref="17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda" type="library">
1313
<name>cyclonedx-python-lib</name>
1414
<version>1.0.0</version>
1515
</component>

‎tests/fixtures/xml/1.3/bom_services_nested.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<version>VERSION</version>
1010
</tool>
1111
</tools>
12-
<component bom-ref="bb5911d6-1a1d-41c9-b6e0-46e848d16655" type="library">
12+
<component bom-ref="cd3e9c95-9d41-49e7-9924-8cf0465ae789" type="library">
1313
<name>cyclonedx-python-lib</name>
1414
<version>1.0.0</version>
1515
</component>

‎tests/fixtures/xml/1.3/bom_services_simple.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<version>VERSION</version>
1010
</tool>
1111
</tools>
12-
<component bom-ref="bb5911d6-1a1d-41c9-b6e0-46e848d16655" type="library">
12+
<component bom-ref="0b049d09-64c0-4490-a0f5-c84d9aacf857" type="library">
1313
<name>cyclonedx-python-lib</name>
1414
<version>1.0.0</version>
1515
</component>

‎tests/fixtures/xml/1.4/bom_services_complex.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
</externalReferences>
3636
</tool>
3737
</tools>
38-
<component bom-ref="df70b5f1-8f53-47a4-be48-669ae78795e6" type="library">
38+
<component bom-ref="17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda" type="library">
3939
<name>cyclonedx-python-lib</name>
4040
<version>1.0.0</version>
4141
</component>

‎tests/fixtures/xml/1.4/bom_services_nested.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
</externalReferences>
3636
</tool>
3737
</tools>
38-
<component bom-ref="df70b5f1-8f53-47a4-be48-669ae78795e6" type="library">
38+
<component bom-ref="cd3e9c95-9d41-49e7-9924-8cf0465ae789" type="library">
3939
<name>cyclonedx-python-lib</name>
4040
<version>1.0.0</version>
4141
</component>

‎tests/fixtures/xml/1.4/bom_services_simple.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
</externalReferences>
3636
</tool>
3737
</tools>
38-
<component bom-ref="df70b5f1-8f53-47a4-be48-669ae78795e6" type="library">
38+
<component bom-ref="0b049d09-64c0-4490-a0f5-c84d9aacf857" type="library">
3939
<name>cyclonedx-python-lib</name>
4040
<version>1.0.0</version>
4141
</component>

‎tests/test_model_component.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def test_not_same(self) -> None:
5454

5555
class TestModelComponent(TestCase):
5656

57-
@patch('cyclonedx.model.component.uuid4', return_value='6f266d1c-760f-4552-ae3b-41a9b74232fa')
57+
@patch('cyclonedx.model.bom_ref.uuid4', return_value='6f266d1c-760f-4552-ae3b-41a9b74232fa')
5858
def test_empty_basic_component(self, mock_uuid: Mock) -> None:
5959
c = Component(
6060
name='test-component', version='1.2.3'
@@ -63,7 +63,7 @@ def test_empty_basic_component(self, mock_uuid: Mock) -> None:
6363
self.assertEqual(c.name, 'test-component')
6464
self.assertEqual(c.type, ComponentType.LIBRARY)
6565
self.assertIsNone(c.mime_type)
66-
self.assertEqual(c.bom_ref, '6f266d1c-760f-4552-ae3b-41a9b74232fa')
66+
self.assertEqual(str(c.bom_ref), '6f266d1c-760f-4552-ae3b-41a9b74232fa')
6767
self.assertIsNone(c.supplier)
6868
self.assertIsNone(c.author)
6969
self.assertIsNone(c.publisher)
@@ -81,7 +81,7 @@ def test_empty_basic_component(self, mock_uuid: Mock) -> None:
8181

8282
self.assertEqual(len(c.get_vulnerabilities()), 0)
8383

84-
@patch('cyclonedx.model.component.uuid4', return_value='6f266d1c-760f-4552-ae3b-41a9b74232fa')
84+
@patch('cyclonedx.model.bom_ref.uuid4', return_value='6f266d1c-760f-4552-ae3b-41a9b74232fa')
8585
def test_multiple_basic_components(self, mock_uuid: Mock) -> None:
8686
c1 = Component(
8787
name='test-component', version='1.2.3'

‎tests/test_model_service.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@
2424

2525
class TestModelService(TestCase):
2626

27-
@patch('cyclonedx.model.service.uuid4', return_value='77d15ab9-5602-4cca-8ed2-59ae579aafd3')
27+
@patch('cyclonedx.model.bom_ref.uuid4', return_value='77d15ab9-5602-4cca-8ed2-59ae579aafd3')
2828
def test_minimal_service(self, mock_uuid: Mock) -> None:
2929
s = Service(name='my-test-service')
3030
mock_uuid.assert_called()
3131
self.assertEqual(s.name, 'my-test-service')
32-
self.assertEqual(s.bom_ref, '77d15ab9-5602-4cca-8ed2-59ae579aafd3')
32+
self.assertEqual(str(s.bom_ref), '77d15ab9-5602-4cca-8ed2-59ae579aafd3')
3333
self.assertIsNone(s.provider)
3434
self.assertIsNone(s.group)
3535
self.assertIsNone(s.version)
@@ -44,7 +44,7 @@ def test_minimal_service(self, mock_uuid: Mock) -> None:
4444
self.assertFalse(s.release_notes)
4545
self.assertFalse(s.properties)
4646

47-
@patch('cyclonedx.model.service.uuid4', return_value='859ff614-35a7-4d37-803b-d89130cb2577')
47+
@patch('cyclonedx.model.bom_ref.uuid4', return_value='859ff614-35a7-4d37-803b-d89130cb2577')
4848
def test_service_with_services(self, mock_uuid: Mock) -> None:
4949
parent_service = Service(name='parent-service')
5050
parent_service.services = [
@@ -53,7 +53,7 @@ def test_service_with_services(self, mock_uuid: Mock) -> None:
5353
]
5454
mock_uuid.assert_called()
5555
self.assertEqual(parent_service.name, 'parent-service')
56-
self.assertEqual(parent_service.bom_ref, '859ff614-35a7-4d37-803b-d89130cb2577')
56+
self.assertEqual(str(parent_service.bom_ref), '859ff614-35a7-4d37-803b-d89130cb2577')
5757
self.assertIsNone(parent_service.provider)
5858
self.assertIsNone(parent_service.group)
5959
self.assertIsNone(parent_service.version)

‎tests/test_output_json.py

+32-51
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,8 @@
2626
get_bom_with_services_simple, get_bom_with_component_toml_1, \
2727
get_bom_with_component_setuptools_no_component_version, \
2828
get_bom_with_component_setuptools_with_release_notes, get_bom_with_component_setuptools_with_vulnerability, \
29-
MOCK_UUID_1, get_bom_just_complete_metadata, MOCK_UUID_2, MOCK_UUID_3, MOCK_UUID_4, MOCK_UUID_5, \
30-
get_bom_with_services_complex, MOCK_UUID_6, get_bom_with_nested_services, \
31-
get_bom_with_component_setuptools_complete, get_bom_with_external_references
29+
MOCK_UUID_1, get_bom_just_complete_metadata, MOCK_UUID_2, MOCK_UUID_3, TEST_UUIDS, get_bom_with_services_complex, \
30+
get_bom_with_nested_services, get_bom_with_component_setuptools_complete, get_bom_with_external_references
3231
from tests.base import BaseJsonTestCase
3332

3433

@@ -178,119 +177,101 @@ def test_bom_v1_3_component_with_vulnerability(self) -> None:
178177
fixture='bom_setuptools.json'
179178
)
180179

181-
@patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_1)
180+
@patch('cyclonedx.model.bom_ref.uuid4', return_value=MOCK_UUID_1)
182181
def test_bom_v1_4_with_metadata_component(self, mock_uuid: Mock) -> None:
183182
self._validate_json_bom(
184183
bom=get_bom_just_complete_metadata(), schema_version=SchemaVersion.V1_4,
185184
fixture='bom_with_full_metadata.json'
186185
)
187186
mock_uuid.assert_called()
188187

189-
@patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_2)
188+
@patch('cyclonedx.model.bom_ref.uuid4', return_value=MOCK_UUID_2)
190189
def test_bom_v1_3_with_metadata_component(self, mock_uuid: Mock) -> None:
191190
self._validate_json_bom(
192191
bom=get_bom_just_complete_metadata(), schema_version=SchemaVersion.V1_3,
193192
fixture='bom_with_full_metadata.json'
194193
)
195194
mock_uuid.assert_called()
196195

197-
@patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_3)
196+
@patch('cyclonedx.model.bom_ref.uuid4', return_value=MOCK_UUID_3)
198197
def test_bom_v1_2_with_metadata_component(self, mock_uuid: Mock) -> None:
199198
self._validate_json_bom(
200199
bom=get_bom_just_complete_metadata(), schema_version=SchemaVersion.V1_2,
201200
fixture='bom_with_full_metadata.json'
202201
)
203202
mock_uuid.assert_called()
204203

205-
@patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_1)
206-
@patch('cyclonedx.model.service.uuid4', return_value=MOCK_UUID_3)
207-
def test_bom_v1_4_services_simple(self, mock_uuid_c: Mock, mock_uuid_s: Mock) -> None:
204+
@patch('cyclonedx.model.bom_ref.uuid4', side_effect=TEST_UUIDS)
205+
def test_bom_v1_4_services_simple(self, mock_uuid: Mock) -> None:
208206
self._validate_json_bom(
209207
bom=get_bom_with_services_simple(), schema_version=SchemaVersion.V1_4,
210208
fixture='bom_services_simple.json'
211209
)
212-
mock_uuid_c.assert_called()
213-
mock_uuid_s.assert_called()
210+
mock_uuid.assert_called()
214211

215-
@patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_2)
216-
@patch('cyclonedx.model.service.uuid4', return_value=MOCK_UUID_4)
217-
def test_bom_v1_3_services_simple(self, mock_uuid_c: Mock, mock_uuid_s: Mock) -> None:
212+
@patch('cyclonedx.model.bom_ref.uuid4', side_effect=TEST_UUIDS)
213+
def test_bom_v1_3_services_simple(self, mock_uuid: Mock) -> None:
218214
self._validate_json_bom(
219215
bom=get_bom_with_services_simple(), schema_version=SchemaVersion.V1_3,
220216
fixture='bom_services_simple.json'
221217
)
222-
mock_uuid_c.assert_called()
223-
mock_uuid_s.assert_called()
218+
mock_uuid.assert_called()
224219

225-
@patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_4)
226-
@patch('cyclonedx.model.service.uuid4', return_value=MOCK_UUID_5)
227-
def test_bom_v1_2_services_simple(self, mock_uuid_c: Mock, mock_uuid_s: Mock) -> None:
220+
@patch('cyclonedx.model.bom_ref.uuid4', side_effect=TEST_UUIDS)
221+
def test_bom_v1_2_services_simple(self, mock_uuid: Mock) -> None:
228222
self._validate_json_bom(
229223
bom=get_bom_with_services_simple(), schema_version=SchemaVersion.V1_2,
230224
fixture='bom_services_simple.json'
231225
)
232-
mock_uuid_c.assert_called()
233-
mock_uuid_s.assert_called()
226+
mock_uuid.assert_called()
234227

235-
@patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_6)
236-
@patch('cyclonedx.model.service.uuid4', return_value=MOCK_UUID_4)
237-
def test_bom_v1_4_services_complex(self, mock_uuid_c: Mock, mock_uuid_s: Mock) -> None:
228+
@patch('cyclonedx.model.bom_ref.uuid4', side_effect=TEST_UUIDS)
229+
def test_bom_v1_4_services_complex(self, mock_uuid: Mock) -> None:
238230
self._validate_json_bom(
239231
bom=get_bom_with_services_complex(), schema_version=SchemaVersion.V1_4,
240232
fixture='bom_services_complex.json'
241233
)
242-
mock_uuid_c.assert_called()
243-
mock_uuid_s.assert_called()
234+
mock_uuid.assert_called()
244235

245-
@patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_5)
246-
@patch('cyclonedx.model.service.uuid4', return_value=MOCK_UUID_3)
247-
def test_bom_v1_3_services_complex(self, mock_uuid_c: Mock, mock_uuid_s: Mock) -> None:
236+
@patch('cyclonedx.model.bom_ref.uuid4', side_effect=TEST_UUIDS)
237+
def test_bom_v1_3_services_complex(self, mock_uuid: Mock) -> None:
248238
self._validate_json_bom(
249239
bom=get_bom_with_services_complex(), schema_version=SchemaVersion.V1_3,
250240
fixture='bom_services_complex.json'
251241
)
252-
mock_uuid_c.assert_called()
253-
mock_uuid_s.assert_called()
242+
mock_uuid.assert_called()
254243

255-
@patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_4)
256-
@patch('cyclonedx.model.service.uuid4', return_value=MOCK_UUID_2)
257-
def test_bom_v1_2_services_complex(self, mock_uuid_c: Mock, mock_uuid_s: Mock) -> None:
244+
@patch('cyclonedx.model.bom_ref.uuid4', side_effect=TEST_UUIDS)
245+
def test_bom_v1_2_services_complex(self, mock_uuid: Mock) -> None:
258246
self._validate_json_bom(
259247
bom=get_bom_with_services_complex(), schema_version=SchemaVersion.V1_2,
260248
fixture='bom_services_complex.json'
261249
)
262-
mock_uuid_c.assert_called()
263-
mock_uuid_s.assert_called()
250+
mock_uuid.assert_called()
264251

265-
@patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_1)
266-
@patch('cyclonedx.model.service.uuid4', return_value=MOCK_UUID_2)
267-
def test_bom_v1_4_services_nested(self, mock_uuid_c: Mock, mock_uuid_s: Mock) -> None:
252+
@patch('cyclonedx.model.bom_ref.uuid4', side_effect=TEST_UUIDS)
253+
def test_bom_v1_4_services_nested(self, mock_uuid: Mock) -> None:
268254
self._validate_json_bom(
269255
bom=get_bom_with_nested_services(), schema_version=SchemaVersion.V1_4,
270256
fixture='bom_services_nested.json'
271257
)
272-
mock_uuid_c.assert_called()
273-
mock_uuid_s.assert_called()
258+
mock_uuid.assert_called()
274259

275-
@patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_3)
276-
@patch('cyclonedx.model.service.uuid4', return_value=MOCK_UUID_4)
277-
def test_bom_v1_3_services_nested(self, mock_uuid_c: Mock, mock_uuid_s: Mock) -> None:
260+
@patch('cyclonedx.model.bom_ref.uuid4', side_effect=TEST_UUIDS)
261+
def test_bom_v1_3_services_nested(self, mock_uuid: Mock) -> None:
278262
self._validate_json_bom(
279263
bom=get_bom_with_nested_services(), schema_version=SchemaVersion.V1_3,
280264
fixture='bom_services_nested.json'
281265
)
282-
mock_uuid_c.assert_called()
283-
mock_uuid_s.assert_called()
266+
mock_uuid.assert_called()
284267

285-
@patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_5)
286-
@patch('cyclonedx.model.service.uuid4', return_value=MOCK_UUID_6)
287-
def test_bom_v1_2_services_nested(self, mock_uuid_c: Mock, mock_uuid_s: Mock) -> None:
268+
@patch('cyclonedx.model.bom_ref.uuid4', side_effect=TEST_UUIDS)
269+
def test_bom_v1_2_services_nested(self, mock_uuid: Mock) -> None:
288270
self._validate_json_bom(
289271
bom=get_bom_with_nested_services(), schema_version=SchemaVersion.V1_2,
290272
fixture='bom_services_nested.json'
291273
)
292-
mock_uuid_c.assert_called()
293-
mock_uuid_s.assert_called()
274+
mock_uuid.assert_called()
294275

295276
# Helper methods
296277
def _validate_json_bom(self, bom: Bom, schema_version: SchemaVersion, fixture: str) -> None:

‎tests/test_output_xml.py

+42-70
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,11 @@
2424
from data import get_bom_with_component_setuptools_basic, get_bom_with_component_setuptools_with_cpe, \
2525
get_bom_with_component_toml_1, get_bom_with_component_setuptools_no_component_version, \
2626
get_bom_with_component_setuptools_with_release_notes, get_bom_with_component_setuptools_with_vulnerability, \
27-
MOCK_UUID_1, MOCK_UUID_2, MOCK_UUID_3, MOCK_UUID_4, MOCK_UUID_5, MOCK_UUID_6, get_bom_just_complete_metadata, \
27+
MOCK_UUID_1, MOCK_UUID_4, MOCK_UUID_5, MOCK_UUID_6, TEST_UUIDS, get_bom_just_complete_metadata, \
2828
get_bom_with_nested_services, get_bom_with_services_simple, get_bom_with_services_complex, \
2929
get_bom_with_component_setuptools_complete, get_bom_with_external_references
3030
from tests.base import BaseXmlTestCase
3131

32-
TEST_UUIDS = [
33-
MOCK_UUID_1, MOCK_UUID_2, MOCK_UUID_3, MOCK_UUID_4, MOCK_UUID_5, MOCK_UUID_6
34-
]
35-
3632

3733
class TestOutputXml(BaseXmlTestCase):
3834

@@ -258,165 +254,141 @@ def test_bom_v1_0_component_with_vulnerability(self) -> None:
258254
fixture='bom_setuptools.xml'
259255
)
260256

261-
@patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_6)
257+
@patch('cyclonedx.model.bom_ref.uuid4', return_value=MOCK_UUID_6)
262258
def test_bom_v1_4_with_metadata_component(self, mock_uuid: Mock) -> None:
263259
self._validate_xml_bom(
264260
bom=get_bom_just_complete_metadata(), schema_version=SchemaVersion.V1_4,
265261
fixture='bom_with_full_metadata.xml'
266262
)
267263
mock_uuid.assert_called()
268264

269-
@patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_5)
265+
@patch('cyclonedx.model.bom_ref.uuid4', return_value=MOCK_UUID_5)
270266
def test_bom_v1_3_with_metadata_component(self, mock_uuid: Mock) -> None:
271267
self._validate_xml_bom(
272268
bom=get_bom_just_complete_metadata(), schema_version=SchemaVersion.V1_3,
273269
fixture='bom_with_full_metadata.xml'
274270
)
275271
mock_uuid.assert_called()
276272

277-
@patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_4)
273+
@patch('cyclonedx.model.bom_ref.uuid4', return_value=MOCK_UUID_4)
278274
def test_bom_v1_2_with_metadata_component(self, mock_uuid: Mock) -> None:
279275
self._validate_xml_bom(
280276
bom=get_bom_just_complete_metadata(), schema_version=SchemaVersion.V1_2,
281277
fixture='bom_with_full_metadata.xml'
282278
)
283279
mock_uuid.assert_called()
284280

285-
@patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_1)
281+
@patch('cyclonedx.model.bom_ref.uuid4', return_value=MOCK_UUID_1)
286282
def test_bom_v1_1_with_metadata_component(self, mock_uuid: Mock) -> None:
287283
self._validate_xml_bom(
288284
bom=get_bom_just_complete_metadata(), schema_version=SchemaVersion.V1_1,
289285
fixture='bom_empty.xml'
290286
)
291287
mock_uuid.assert_called()
292288

293-
@patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_1)
289+
@patch('cyclonedx.model.bom_ref.uuid4', return_value=MOCK_UUID_1)
294290
def test_bom_v1_0_with_metadata_component(self, mock_uuid: Mock) -> None:
295291
self._validate_xml_bom(
296292
bom=get_bom_just_complete_metadata(), schema_version=SchemaVersion.V1_0,
297293
fixture='bom_empty.xml'
298294
)
299295
mock_uuid.assert_called()
300296

301-
@patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_6)
302-
@patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS)
303-
def test_bom_v1_4_services_simple(self, mock_uuid_c: Mock, mock_uuid_s: Mock) -> None:
297+
@patch('cyclonedx.model.bom_ref.uuid4', side_effect=TEST_UUIDS)
298+
def test_bom_v1_4_services_simple(self, mock_uuid: Mock) -> None:
304299
self._validate_xml_bom(
305300
bom=get_bom_with_services_simple(), schema_version=SchemaVersion.V1_4,
306301
fixture='bom_services_simple.xml'
307302
)
308-
mock_uuid_c.assert_called()
309-
mock_uuid_s.assert_called()
303+
mock_uuid.assert_called()
310304

311-
@patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_5)
312-
@patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS)
313-
def test_bom_v1_3_services_simple(self, mock_uuid_c: Mock, mock_uuid_s: Mock) -> None:
305+
@patch('cyclonedx.model.bom_ref.uuid4', side_effect=TEST_UUIDS)
306+
def test_bom_v1_3_services_simple(self, mock_uuid: Mock) -> None:
314307
self._validate_xml_bom(
315308
bom=get_bom_with_services_simple(), schema_version=SchemaVersion.V1_3,
316309
fixture='bom_services_simple.xml'
317310
)
318-
mock_uuid_c.assert_called()
319-
mock_uuid_s.assert_called()
311+
mock_uuid.assert_called()
320312

321-
@patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_4)
322-
@patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS)
323-
def test_bom_v1_2_services_simple(self, mock_uuid_c: Mock, mock_uuid_s: Mock) -> None:
313+
@patch('cyclonedx.model.bom_ref.uuid4', side_effect=TEST_UUIDS)
314+
def test_bom_v1_2_services_simple(self, mock_uuid: Mock) -> None:
324315
self._validate_xml_bom(
325316
bom=get_bom_with_services_simple(), schema_version=SchemaVersion.V1_2,
326317
fixture='bom_services_simple.xml'
327318
)
328-
mock_uuid_c.assert_called()
329-
mock_uuid_s.assert_called()
319+
mock_uuid.assert_called()
330320

331-
@patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_1)
332-
@patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS)
333-
def test_bom_v1_1_services_simple(self, mock_uuid_c: Mock, mock_uuid_s: Mock) -> None:
321+
@patch('cyclonedx.model.bom_ref.uuid4', side_effect=TEST_UUIDS)
322+
def test_bom_v1_1_services_simple(self, mock_uuid: Mock) -> None:
334323
self._validate_xml_bom(
335324
bom=get_bom_with_services_simple(), schema_version=SchemaVersion.V1_1,
336325
fixture='bom_empty.xml'
337326
)
338-
mock_uuid_c.assert_called()
339-
mock_uuid_s.assert_called()
327+
mock_uuid.assert_called()
340328

341-
@patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_1)
342-
@patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS)
343-
def test_bom_v1_0_services_simple(self, mock_uuid_c: Mock, mock_uuid_s: Mock) -> None:
329+
@patch('cyclonedx.model.bom_ref.uuid4', side_effect=TEST_UUIDS)
330+
def test_bom_v1_0_services_simple(self, mock_uuid: Mock) -> None:
344331
self._validate_xml_bom(
345332
bom=get_bom_with_services_simple(), schema_version=SchemaVersion.V1_0,
346333
fixture='bom_empty.xml'
347334
)
348-
mock_uuid_c.assert_called()
349-
mock_uuid_s.assert_called()
335+
mock_uuid.assert_called()
350336

351-
@patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_6)
352-
@patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS)
353-
def test_bom_v1_4_services_complex(self, mock_uuid_c: Mock, mock_uuid_s: Mock) -> None:
337+
@patch('cyclonedx.model.bom_ref.uuid4', side_effect=TEST_UUIDS)
338+
def test_bom_v1_4_services_complex(self, mock_uuid4: Mock) -> None:
354339
self._validate_xml_bom(
355340
bom=get_bom_with_services_complex(), schema_version=SchemaVersion.V1_4,
356341
fixture='bom_services_complex.xml'
357342
)
358-
mock_uuid_c.assert_called()
359-
mock_uuid_s.assert_called()
343+
mock_uuid4.assert_called()
360344

361-
@patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_5)
362-
@patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS)
363-
def test_bom_v1_3_services_complex(self, mock_uuid_c: Mock, mock_uuid_s: Mock) -> None:
345+
@patch('cyclonedx.model.bom_ref.uuid4', side_effect=TEST_UUIDS)
346+
def test_bom_v1_3_services_complex(self, mock_uuid: Mock) -> None:
364347
self._validate_xml_bom(
365348
bom=get_bom_with_services_complex(), schema_version=SchemaVersion.V1_3,
366349
fixture='bom_services_complex.xml'
367350
)
368-
mock_uuid_c.assert_called()
369-
mock_uuid_s.assert_called()
351+
mock_uuid.assert_called()
370352

371-
@patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_4)
372-
@patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS)
373-
def test_bom_v1_2_services_complex(self, mock_uuid_c: Mock, mock_uuid_s: Mock) -> None:
353+
@patch('cyclonedx.model.bom_ref.uuid4', side_effect=TEST_UUIDS)
354+
def test_bom_v1_2_services_complex(self, mock_uuid: Mock) -> None:
374355
self._validate_xml_bom(
375356
bom=get_bom_with_services_complex(), schema_version=SchemaVersion.V1_2,
376357
fixture='bom_services_complex.xml'
377358
)
378-
mock_uuid_c.assert_called()
379-
mock_uuid_s.assert_called()
359+
mock_uuid.assert_called()
380360

381-
@patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_3)
382-
@patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS)
383-
def test_bom_v1_1_services_complex(self, mock_uuid_c: Mock, mock_uuid_s: Mock) -> None:
361+
@patch('cyclonedx.model.bom_ref.uuid4', side_effect=TEST_UUIDS)
362+
def test_bom_v1_1_services_complex(self, mock_uuid: Mock) -> None:
384363
self._validate_xml_bom(
385364
bom=get_bom_with_services_complex(), schema_version=SchemaVersion.V1_1,
386365
fixture='bom_empty.xml'
387366
)
388-
mock_uuid_c.assert_called()
389-
mock_uuid_s.assert_called()
367+
mock_uuid.assert_called()
390368

391-
@patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_6)
392-
@patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS)
393-
def test_bom_v1_4_services_nested(self, mock_uuid_c: Mock, mock_uuid_s: Mock) -> None:
369+
@patch('cyclonedx.model.bom_ref.uuid4', side_effect=TEST_UUIDS)
370+
def test_bom_v1_4_services_nested(self, mock_uuid: Mock) -> None:
394371
self._validate_xml_bom(
395372
bom=get_bom_with_nested_services(), schema_version=SchemaVersion.V1_4,
396373
fixture='bom_services_nested.xml'
397374
)
398-
mock_uuid_c.assert_called()
399-
mock_uuid_s.assert_called()
375+
mock_uuid.assert_called()
400376

401-
@patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_5)
402-
@patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS)
403-
def test_bom_v1_3_services_nested(self, mock_uuid_c: Mock, mock_uuid_s: Mock) -> None:
377+
@patch('cyclonedx.model.bom_ref.uuid4', side_effect=TEST_UUIDS)
378+
def test_bom_v1_3_services_nested(self, mock_uuid: Mock) -> None:
404379
self._validate_xml_bom(
405380
bom=get_bom_with_nested_services(), schema_version=SchemaVersion.V1_3,
406381
fixture='bom_services_nested.xml'
407382
)
408-
mock_uuid_c.assert_called()
409-
mock_uuid_s.assert_called()
383+
mock_uuid.assert_called()
410384

411-
@patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_4)
412-
@patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS)
413-
def test_bom_v1_2_services_nested(self, mock_uuid_c: Mock, mock_uuid_s: Mock) -> None:
385+
@patch('cyclonedx.model.bom_ref.uuid4', side_effect=TEST_UUIDS)
386+
def test_bom_v1_2_services_nested(self, mock_uuid: Mock) -> None:
414387
self._validate_xml_bom(
415388
bom=get_bom_with_nested_services(), schema_version=SchemaVersion.V1_2,
416389
fixture='bom_services_nested.xml'
417390
)
418-
mock_uuid_c.assert_called()
419-
mock_uuid_s.assert_called()
391+
mock_uuid.assert_called()
420392

421393
# Helper methods
422394
def _validate_xml_bom(self, bom: Bom, schema_version: SchemaVersion, fixture: str) -> None:

0 commit comments

Comments
 (0)
Please sign in to comment.