github.com/lineaje-labs/syft@v0.98.1-0.20231227153149-9e393f60ff1b/syft/format/common/cyclonedxhelpers/format_test.go (about) 1 package cyclonedxhelpers 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/CycloneDX/cyclonedx-go" 8 "github.com/google/go-cmp/cmp" 9 "github.com/stretchr/testify/assert" 10 "github.com/stretchr/testify/require" 11 12 "github.com/anchore/syft/syft/artifact" 13 "github.com/anchore/syft/syft/pkg" 14 "github.com/anchore/syft/syft/sbom" 15 "github.com/anchore/syft/syft/source" 16 ) 17 18 func Test_formatCPE(t *testing.T) { 19 tests := []struct { 20 cpe string 21 expected string 22 }{ 23 { 24 cpe: "cpe:2.3:o:amazon:amazon_linux:2", 25 expected: "cpe:2.3:o:amazon:amazon_linux:2:*:*:*:*:*:*:*", 26 }, 27 { 28 cpe: "cpe:/o:opensuse:leap:15.2", 29 expected: "cpe:2.3:o:opensuse:leap:15.2:*:*:*:*:*:*:*", 30 }, 31 { 32 cpe: "invalid-cpe", 33 expected: "", 34 }, 35 } 36 37 for _, test := range tests { 38 t.Run(test.cpe, func(t *testing.T) { 39 out := formatCPE(test.cpe) 40 assert.Equal(t, test.expected, out) 41 }) 42 } 43 } 44 45 func Test_relationships(t *testing.T) { 46 p1 := pkg.Package{ 47 Name: "p1", 48 } 49 50 p2 := pkg.Package{ 51 Name: "p2", 52 } 53 54 p3 := pkg.Package{ 55 Name: "p3", 56 } 57 58 p4 := pkg.Package{ 59 Name: "p4", 60 } 61 62 for _, p := range []*pkg.Package{&p1, &p2, &p3, &p4} { 63 p.PURL = fmt.Sprintf("pkg:generic/%s@%s", p.Name, p.Name) 64 p.SetID() 65 } 66 67 tests := []struct { 68 name string 69 sbom sbom.SBOM 70 expected *[]cyclonedx.Dependency 71 }{ 72 { 73 name: "package dependencyOf relationships output as dependencies", 74 sbom: sbom.SBOM{ 75 Artifacts: sbom.Artifacts{ 76 Packages: pkg.NewCollection(p1, p2, p3, p4), 77 }, 78 Relationships: []artifact.Relationship{ 79 { 80 From: p2, 81 To: p1, 82 Type: artifact.DependencyOfRelationship, 83 }, 84 { 85 From: p3, 86 To: p1, 87 Type: artifact.DependencyOfRelationship, 88 }, 89 { 90 From: p4, 91 To: p2, 92 Type: artifact.DependencyOfRelationship, 93 }, 94 }, 95 }, 96 expected: &[]cyclonedx.Dependency{ 97 { 98 Ref: deriveBomRef(p1), 99 Dependencies: &[]string{ 100 deriveBomRef(p2), 101 deriveBomRef(p3), 102 }, 103 }, 104 { 105 Ref: deriveBomRef(p2), 106 Dependencies: &[]string{ 107 deriveBomRef(p4), 108 }, 109 }, 110 }, 111 }, 112 { 113 name: "package contains relationships not output", 114 sbom: sbom.SBOM{ 115 Artifacts: sbom.Artifacts{ 116 Packages: pkg.NewCollection(p1, p2, p3), 117 }, 118 Relationships: []artifact.Relationship{ 119 { 120 From: p2, 121 To: p1, 122 Type: artifact.ContainsRelationship, 123 }, 124 { 125 From: p3, 126 To: p1, 127 Type: artifact.ContainsRelationship, 128 }, 129 }, 130 }, 131 expected: nil, 132 }, 133 } 134 135 for _, test := range tests { 136 t.Run(test.name, func(t *testing.T) { 137 cdx := ToFormatModel(test.sbom) 138 got := cdx.Dependencies 139 require.Equal(t, test.expected, got) 140 }) 141 } 142 } 143 144 func Test_toBomDescriptor(t *testing.T) { 145 type args struct { 146 name string 147 version string 148 srcMetadata source.Description 149 } 150 tests := []struct { 151 name string 152 args args 153 want *cyclonedx.Metadata 154 }{ 155 { 156 name: "with image labels source metadata", 157 args: args{ 158 name: "test-image", 159 version: "1.0.0", 160 srcMetadata: source.Description{ 161 Metadata: source.StereoscopeImageSourceMetadata{ 162 Labels: map[string]string{ 163 "key1": "value1", 164 }, 165 }, 166 }, 167 }, 168 want: &cyclonedx.Metadata{ 169 Timestamp: "", 170 Lifecycles: nil, 171 Tools: &[]cyclonedx.Tool{ 172 { 173 Vendor: "anchore", 174 Name: "test-image", 175 Version: "1.0.0", 176 Hashes: nil, 177 ExternalReferences: nil, 178 }, 179 }, 180 Authors: nil, 181 Component: &cyclonedx.Component{ 182 BOMRef: "", 183 MIMEType: "", 184 Type: "container", 185 Supplier: nil, 186 Author: "", 187 Publisher: "", 188 Group: "", 189 Name: "", 190 Version: "", 191 Description: "", 192 Scope: "", 193 Hashes: nil, 194 Licenses: nil, 195 Copyright: "", 196 CPE: "", 197 PackageURL: "", 198 SWID: nil, 199 Modified: nil, 200 Pedigree: nil, 201 ExternalReferences: nil, 202 Properties: nil, 203 Components: nil, 204 Evidence: nil, 205 ReleaseNotes: nil, 206 }, 207 Manufacture: nil, 208 Supplier: nil, 209 Licenses: nil, 210 Properties: &[]cyclonedx.Property{ 211 { 212 Name: "syft:image:labels:key1", 213 Value: "value1", 214 }, 215 }}, 216 }, 217 } 218 for _, tt := range tests { 219 t.Run(tt.name, func(t *testing.T) { 220 subject := toBomDescriptor(tt.args.name, tt.args.version, tt.args.srcMetadata) 221 222 require.NotEmpty(t, subject.Component.BOMRef) 223 subject.Timestamp = "" // not under test 224 225 require.NotNil(t, subject.Component) 226 require.NotEmpty(t, subject.Component.BOMRef) 227 subject.Component.BOMRef = "" // not under test 228 229 if d := cmp.Diff(tt.want, subject); d != "" { 230 t.Errorf("toBomDescriptor() mismatch (-want +got):\n%s", d) 231 } 232 }) 233 } 234 }