Skip to content

Commit 7838840

Browse files
committed
add tests for missing metadata fields
Signed-off-by: Kurt Boberg <[email protected]>
1 parent 0d557cb commit 7838840

File tree

4 files changed

+139
-1
lines changed

4 files changed

+139
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
{
2+
"$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json",
3+
"bomFormat": "CycloneDX",
4+
"specVersion": "1.4",
5+
"serialNumber": "urn:uuid:588bb01b-577e-4e1b-a055-b51b8f5f2ed1",
6+
"version": 1,
7+
"metadata": {
8+
"timestamp": "2023-04-18T21:47:45.707189+00:00",
9+
"tools": [
10+
{
11+
"vendor": "CycloneDX",
12+
"name": "cyclonedx-bom",
13+
"version": "3.11.0"
14+
},
15+
{
16+
"vendor": "CycloneDX",
17+
"name": "cyclonedx-python-lib",
18+
"version": "3.1.5",
19+
"externalReferences": [
20+
{
21+
"url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions",
22+
"type": "build-system"
23+
},
24+
{
25+
"url": "https://pypi.org/project/cyclonedx-python-lib/",
26+
"type": "distribution"
27+
},
28+
{
29+
"url": "https://cyclonedx.github.io/cyclonedx-python-lib/",
30+
"type": "documentation"
31+
},
32+
{
33+
"url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues",
34+
"type": "issue-tracker"
35+
},
36+
{
37+
"url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE",
38+
"type": "license"
39+
},
40+
{
41+
"url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md",
42+
"type": "release-notes"
43+
},
44+
{
45+
"url": "https://github.com/CycloneDX/cyclonedx-python-lib",
46+
"type": "vcs"
47+
},
48+
{
49+
"url": "https://cyclonedx.org",
50+
"type": "website"
51+
}
52+
]
53+
}
54+
]
55+
},
56+
"components": [
57+
{
58+
"type": "library",
59+
"bom-ref": "13ca86b0-38a2-47aa-9a39-b2b042da8bc4",
60+
"name": "ruamel.yaml",
61+
"version": "0.17.21",
62+
"purl": "pkg:pypi/[email protected]",
63+
"externalReferences": [
64+
{
65+
"url": "https://pypi.org/project/ruamel.yaml/0.17.21",
66+
"comment": "Distribution available from pypi.org",
67+
"type": "distribution",
68+
"hashes": [
69+
{
70+
"alg": "SHA-256",
71+
"content": "742b35d3d665023981bd6d16b3d24248ce5df75fdb4e2924e93a05c1f8b61ca7"
72+
}
73+
]
74+
},
75+
{
76+
"url": "https://pypi.org/project/ruamel.yaml/0.17.21",
77+
"comment": "Distribution available from pypi.org",
78+
"type": "distribution",
79+
"hashes": [
80+
{
81+
"alg": "SHA-256",
82+
"content": "8b7ce697a2f212752a35c1ac414471dc16c424c9573be4926b56ff3f5d23b7af"
83+
}
84+
]
85+
}
86+
]
87+
}
88+
],
89+
"dependencies": [
90+
{
91+
"ref": "13ca86b0-38a2-47aa-9a39-b2b042da8bc4",
92+
"dependsOn": []
93+
}
94+
]
95+
}

internal/testing/testdata/testdata.go

+27
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ var (
9191
//go:embed exampledata/no-dependent-components-cyclonedx.json
9292
CycloneDXExampleNoDependentComponents []byte
9393

94+
//go:embed exampledata/cyclonedx-bom-example.json
95+
CycloneDXExampleCycloneDXpyNoBOMRef []byte
96+
9497
//go:embed exampledata/crev-review.json
9598
ITE6CREVExample []byte
9699

@@ -798,6 +801,30 @@ var (
798801
HasSBOM: CdxNpmHasSBOM,
799802
}
800803

804+
cdxPyRuamelPackage, _ = asmhelpers.PurlToPkg("pkg:pypi/[email protected]")
805+
806+
CdxPipenvDeps = []assembler.IsDependencyIngest{
807+
{
808+
Pkg: cdxPyRuamelPackage,
809+
},
810+
}
811+
812+
CdxPipenvHasSBOM = []assembler.HasSBOMIngest{
813+
{
814+
Pkg: cdxPyRuamelPackage,
815+
HasSBOM: &model.HasSBOMInputSpec{
816+
Uri: "TestSource",
817+
Algorithm: "sha256",
818+
Digest: "35363f03c80f26a88db6f2400771bdcc6624bb7b61b96da8503be0f757605fde",
819+
DownloadLocation: "TestSource",
820+
},
821+
},
822+
}
823+
824+
CdxPipenvIngestionPredicates = assembler.IngestPredicates{
825+
//without a root node, the parser will return empty predicates. Not sure what the "correct" behavior here should be
826+
}
827+
801828
quarkusParentPackage, _ = asmhelpers.PurlToPkg("pkg:maven/io.quarkus/quarkus-parent@999-SNAPSHOT?type=pom")
802829

803830
quarkusParentPackageHasSBOM = []assembler.HasSBOMIngest{

pkg/ingestor/parser/cyclonedx/parser_cyclonedx.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,13 @@ func (c *cyclonedxParser) GetPredicates(ctx context.Context) *assembler.IngestPr
202202

203203
preds := &assembler.IngestPredicates{}
204204

205-
toplevel := c.getPackageElement(string(c.cdxBom.Metadata.Component.BOMRef))
205+
var toplevel []*model.PkgInputSpec = nil
206+
207+
if c.cdxBom.Metadata.Component != nil && c.cdxBom.Metadata.Component.BOMRef != "" {
208+
// BOMRef is not a required element
209+
toplevel = c.getPackageElement(string(c.cdxBom.Metadata.Component.BOMRef))
210+
}
211+
206212
// adding top level package edge manually for all depends on package
207213
// TODO: This is not based on the relationship so that can be inaccurate (can capture both direct and in-direct)...Remove this and be done below by the *c.cdxBom.Dependencies?
208214
// see https://github.com/CycloneDX/specification/issues/33

pkg/ingestor/parser/cyclonedx/parser_cyclonedx_test.go

+10
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,16 @@ func Test_cyclonedxParser(t *testing.T) {
8989
},
9090
wantPredicates: &testdata.CdxEmptyIngestionPredicates,
9191
wantErr: false,
92+
}, {
93+
name: "valid CycloneDX document generated by cyclonedx-bom Python utility with a single dependency",
94+
doc: &processor.Document{
95+
Blob: testdata.CycloneDXExampleCycloneDXpyNoBOMRef,
96+
Format: processor.FormatJSON,
97+
Type: processor.DocumentCycloneDX,
98+
SourceInformation: processor.SourceInformation{},
99+
},
100+
wantPredicates: &testdata.CdxPipenvIngestionPredicates,
101+
wantErr: false,
92102
},
93103
}
94104
for _, tt := range tests {

0 commit comments

Comments
 (0)