github.com/anchore/syft@v1.38.2/syft/pkg/cataloger/bitnami/cataloger_test.go (about) 1 package bitnami 2 3 import ( 4 "context" 5 "testing" 6 7 "github.com/stretchr/testify/require" 8 9 "github.com/anchore/syft/syft/artifact" 10 "github.com/anchore/syft/syft/cpe" 11 "github.com/anchore/syft/syft/file" 12 "github.com/anchore/syft/syft/license" 13 "github.com/anchore/syft/syft/pkg" 14 "github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest" 15 ) 16 17 func mustCPEs(s ...string) (c []cpe.CPE) { 18 for _, i := range s { 19 newCPE := cpe.Must(i, "") 20 newCPE.Source = cpe.DeclaredSource 21 c = append(c, newCPE) 22 } 23 return 24 } 25 26 func TestBitnamiCataloger(t *testing.T) { 27 ctx := context.TODO() 28 postgresqlMainPkg := pkg.Package{ 29 Name: "postgresql", 30 Version: "17.2.0-8", 31 Type: pkg.BitnamiPkg, 32 Locations: file.NewLocationSet(file.NewLocation("opt/bitnami/postgresql/.spdx-postgresql.spdx")), 33 Licenses: pkg.NewLicenseSet( 34 pkg.NewLicenseFromTypeWithContext(ctx, "PostgreSQL", license.Concluded), 35 pkg.NewLicenseFromTypeWithContext(ctx, "PostgreSQL", license.Declared), 36 ), 37 FoundBy: catalogerName, 38 PURL: "pkg:bitnami/postgresql@17.2.0-8?arch=arm64&distro=debian-12", 39 CPEs: mustCPEs( 40 "cpe:2.3:*:postgresql:postgresql:17.2.0:*:*:*:*:*:*:*", 41 ), 42 Metadata: &pkg.BitnamiSBOMEntry{ 43 Name: "postgresql", 44 Version: "17.2.0", 45 Revision: "8", 46 Architecture: "arm64", 47 Distro: "debian-12", 48 Path: "opt/bitnami/postgresql", 49 Files: []string{ 50 "opt/bitnami/postgresql/readme.txt", 51 }, 52 }, 53 } 54 postgresqlSecondaryPkgs := []pkg.Package{ 55 { 56 Name: "geos", 57 Version: "3.13.0", 58 Type: pkg.BitnamiPkg, 59 Locations: file.NewLocationSet(file.NewLocation("opt/bitnami/postgresql/.spdx-postgresql.spdx")), 60 Licenses: pkg.NewLicenseSet( 61 pkg.NewLicenseFromTypeWithContext(ctx, "LGPL-2.1-only", license.Concluded), 62 pkg.NewLicenseFromTypeWithContext(ctx, "LGPL-2.1-only", license.Declared), 63 ), 64 FoundBy: catalogerName, 65 PURL: "pkg:bitnami/geos@3.13.0?arch=arm64&distro=debian-12", 66 CPEs: mustCPEs( 67 "cpe:2.3:*:libgeos:geos:3.13.0:*:*:*:*:*:*:*", 68 ), 69 Metadata: &pkg.BitnamiSBOMEntry{ 70 Name: "geos", 71 Version: "3.13.0", 72 Architecture: "arm64", 73 Distro: "debian-12", 74 Path: "opt/bitnami/postgresql", 75 }, 76 }, 77 { 78 Name: "proj", 79 Version: "6.3.2", 80 Type: pkg.BitnamiPkg, 81 Locations: file.NewLocationSet(file.NewLocation("opt/bitnami/postgresql/.spdx-postgresql.spdx")), 82 Licenses: pkg.NewLicenseSet( 83 pkg.NewLicenseFromTypeWithContext(ctx, "MIT", license.Concluded), 84 pkg.NewLicenseFromTypeWithContext(ctx, "MIT", license.Declared), 85 ), 86 FoundBy: catalogerName, 87 PURL: "pkg:bitnami/proj@6.3.2?arch=arm64&distro=debian-12", 88 CPEs: mustCPEs( 89 "cpe:2.3:*:proj:proj:6.3.2:*:*:*:*:*:*:*", 90 ), 91 Metadata: &pkg.BitnamiSBOMEntry{ 92 Name: "proj", 93 Version: "6.3.2", 94 Architecture: "arm64", 95 Distro: "debian-12", 96 Path: "opt/bitnami/postgresql", 97 }, 98 }, 99 { 100 Name: "gdal", 101 Version: "3.10.1", 102 Type: pkg.BitnamiPkg, 103 Locations: file.NewLocationSet(file.NewLocation("opt/bitnami/postgresql/.spdx-postgresql.spdx")), 104 Licenses: pkg.NewLicenseSet( 105 pkg.NewLicenseFromTypeWithContext(ctx, "MIT", license.Concluded), 106 pkg.NewLicenseFromTypeWithContext(ctx, "MIT", license.Declared), 107 ), 108 FoundBy: catalogerName, 109 PURL: "pkg:bitnami/gdal@3.10.1?arch=arm64&distro=debian-12", 110 CPEs: mustCPEs( 111 "cpe:2.3:*:osgeo:gdal:3.10.1:*:*:*:*:*:*:*", 112 ), 113 Metadata: &pkg.BitnamiSBOMEntry{ 114 Name: "gdal", 115 Version: "3.10.1", 116 Architecture: "arm64", 117 Distro: "debian-12", 118 Path: "opt/bitnami/postgresql", 119 }, 120 }, 121 { 122 Name: "json-c", 123 Version: "0.16.20220414", 124 Type: pkg.BitnamiPkg, 125 Locations: file.NewLocationSet(file.NewLocation("opt/bitnami/postgresql/.spdx-postgresql.spdx")), 126 Licenses: pkg.NewLicenseSet( 127 pkg.NewLicenseFromTypeWithContext(ctx, "MIT", license.Concluded), 128 pkg.NewLicenseFromTypeWithContext(ctx, "MIT", license.Declared), 129 ), 130 FoundBy: catalogerName, 131 PURL: "pkg:bitnami/json-c@0.16.20220414?arch=arm64&distro=debian-12", 132 CPEs: mustCPEs( 133 "cpe:2.3:*:json-c_project:json-c:0.16.20220414:*:*:*:*:*:*:*", 134 ), 135 Metadata: &pkg.BitnamiSBOMEntry{ 136 Name: "json-c", 137 Version: "0.16.20220414", 138 Architecture: "arm64", 139 Distro: "debian-12", 140 Path: "opt/bitnami/postgresql", 141 }, 142 }, 143 { 144 Name: "orafce", 145 Version: "4.14.1", 146 Type: pkg.BitnamiPkg, 147 Locations: file.NewLocationSet(file.NewLocation("opt/bitnami/postgresql/.spdx-postgresql.spdx")), 148 Licenses: pkg.NewLicenseSet( 149 pkg.NewLicenseFromTypeWithContext(ctx, "0BSD", license.Concluded), 150 pkg.NewLicenseFromTypeWithContext(ctx, "0BSD", license.Declared), 151 ), 152 FoundBy: catalogerName, 153 PURL: "pkg:bitnami/orafce@4.14.1?arch=arm64&distro=debian-12", 154 CPEs: mustCPEs( 155 "cpe:2.3:*:orafce:orafce:4.14.1:*:*:*:*:*:*:*", 156 ), 157 Metadata: &pkg.BitnamiSBOMEntry{ 158 Name: "orafce", 159 Version: "4.14.1", 160 Architecture: "arm64", 161 Distro: "debian-12", 162 Path: "opt/bitnami/postgresql", 163 }, 164 }, 165 { 166 Name: "pljava", 167 Version: "1.6.8", 168 Type: pkg.BitnamiPkg, 169 Locations: file.NewLocationSet(file.NewLocation("opt/bitnami/postgresql/.spdx-postgresql.spdx")), 170 Licenses: pkg.NewLicenseSet( 171 pkg.NewLicenseFromTypeWithContext(ctx, "BSD-3-Clause", license.Concluded), 172 pkg.NewLicenseFromTypeWithContext(ctx, "BSD-3-Clause", license.Declared), 173 ), 174 FoundBy: catalogerName, 175 PURL: "pkg:bitnami/pljava@1.6.8?arch=arm64&distro=debian-12", 176 CPEs: mustCPEs( 177 "cpe:2.3:*:pl/java_project:pl/java:1.6.8:*:*:*:*:*:*:*", 178 ), 179 Metadata: &pkg.BitnamiSBOMEntry{ 180 Name: "pljava", 181 Version: "1.6.8", 182 Architecture: "arm64", 183 Distro: "debian-12", 184 Path: "opt/bitnami/postgresql", 185 Files: []string{ 186 "opt/bitnami/postgresql/share/pljava/pljava-api-1.6.8.jar", 187 "opt/bitnami/postgresql/share/pljava/pljava-1.6.8.jar", 188 "opt/bitnami/postgresql/share/pljava/pljava-examples-1.6.8.jar", 189 }, 190 }, 191 }, 192 { 193 Name: "unixodbc", 194 Version: "2.3.12", 195 Type: pkg.BitnamiPkg, 196 Locations: file.NewLocationSet(file.NewLocation("opt/bitnami/postgresql/.spdx-postgresql.spdx")), 197 Licenses: pkg.NewLicenseSet( 198 pkg.NewLicenseFromTypeWithContext(ctx, "LGPL-2.1-only", license.Concluded), 199 pkg.NewLicenseFromTypeWithContext(ctx, "LGPL-2.1-only", license.Declared), 200 ), 201 FoundBy: catalogerName, 202 PURL: "pkg:bitnami/unixodbc@2.3.12?arch=arm64&distro=debian-12", 203 CPEs: mustCPEs( 204 "cpe:2.3:*:unixodbc:unixodbc:2.3.12:*:*:*:*:*:*:*", 205 ), 206 Metadata: &pkg.BitnamiSBOMEntry{ 207 Name: "unixodbc", 208 Version: "2.3.12", 209 Architecture: "arm64", 210 Distro: "debian-12", 211 Path: "opt/bitnami/postgresql", 212 }, 213 }, 214 { 215 Name: "psqlodbc", 216 Version: "16.0.0", 217 Type: pkg.BitnamiPkg, 218 Locations: file.NewLocationSet(file.NewLocation("opt/bitnami/postgresql/.spdx-postgresql.spdx")), 219 Licenses: pkg.NewLicenseSet( 220 pkg.NewLicenseFromTypeWithContext(ctx, "LGPL-3.0-only", license.Concluded), 221 pkg.NewLicenseFromTypeWithContext(ctx, "LGPL-3.0-only", license.Declared), 222 ), 223 FoundBy: catalogerName, 224 PURL: "pkg:bitnami/psqlodbc@16.0.0?arch=arm64&distro=debian-12", 225 CPEs: mustCPEs( 226 "cpe:2.3:*:postgresql:psqlodbc:16.0.0:*:*:*:*:*:*:*", 227 ), 228 Metadata: &pkg.BitnamiSBOMEntry{ 229 Name: "psqlodbc", 230 Version: "16.0.0", 231 Architecture: "arm64", 232 Distro: "debian-12", 233 Path: "opt/bitnami/postgresql", 234 }, 235 }, 236 { 237 Name: "protobuf", 238 Version: "3.21.12", 239 Type: pkg.BitnamiPkg, 240 Locations: file.NewLocationSet(file.NewLocation("opt/bitnami/postgresql/.spdx-postgresql.spdx")), 241 Licenses: pkg.NewLicenseSet( 242 pkg.NewLicenseFromTypeWithContext(ctx, "BSD-3-Clause", license.Concluded), 243 pkg.NewLicenseFromTypeWithContext(ctx, "BSD-3-Clause", license.Declared), 244 ), 245 FoundBy: catalogerName, 246 PURL: "pkg:bitnami/protobuf@3.21.12?arch=arm64&distro=debian-12", 247 CPEs: mustCPEs( 248 "cpe:2.3:*:golang:protobuf:3.21.12:*:*:*:*:*:*:*", 249 ), 250 Metadata: &pkg.BitnamiSBOMEntry{ 251 Name: "protobuf", 252 Version: "3.21.12", 253 Architecture: "arm64", 254 Distro: "debian-12", 255 Path: "opt/bitnami/postgresql", 256 }, 257 }, 258 { 259 Name: "protobuf-c", 260 Version: "1.5.1", 261 Type: pkg.BitnamiPkg, 262 Locations: file.NewLocationSet(file.NewLocation("opt/bitnami/postgresql/.spdx-postgresql.spdx")), 263 Licenses: pkg.NewLicenseSet( 264 pkg.NewLicenseFromTypeWithContext(ctx, "BSD-2-Clause", license.Concluded), 265 pkg.NewLicenseFromTypeWithContext(ctx, "BSD-2-Clause", license.Declared), 266 ), 267 FoundBy: catalogerName, 268 PURL: "pkg:bitnami/protobuf-c@1.5.1?arch=arm64&distro=debian-12", 269 CPEs: mustCPEs( 270 "cpe:2.3:*:protobuf-c:protobuf-c:1.5.1:*:*:*:*:*:*:*", 271 ), 272 Metadata: &pkg.BitnamiSBOMEntry{ 273 Name: "protobuf-c", 274 Version: "1.5.1", 275 Architecture: "arm64", 276 Distro: "debian-12", 277 Path: "opt/bitnami/postgresql", 278 }, 279 }, 280 { 281 Name: "postgis", 282 Version: "3.4.4", 283 Type: pkg.BitnamiPkg, 284 Locations: file.NewLocationSet(file.NewLocation("opt/bitnami/postgresql/.spdx-postgresql.spdx")), 285 Licenses: pkg.NewLicenseSet( 286 pkg.NewLicenseFromTypeWithContext(ctx, "GPL-2.0-or-later", license.Concluded), 287 pkg.NewLicenseFromTypeWithContext(ctx, "GPL-2.0-or-later", license.Declared), 288 ), 289 FoundBy: catalogerName, 290 PURL: "pkg:bitnami/postgis@3.4.4?arch=arm64&distro=debian-12", 291 CPEs: mustCPEs( 292 "cpe:2.3:*:postgis:postgis:3.4.4:*:*:*:*:*:*:*", 293 ), 294 Metadata: &pkg.BitnamiSBOMEntry{ 295 Name: "postgis", 296 Version: "3.4.4", 297 Architecture: "arm64", 298 Distro: "debian-12", 299 Path: "opt/bitnami/postgresql", 300 }, 301 }, 302 { 303 Name: "pgaudit", 304 Version: "17.0.0", 305 Type: pkg.BitnamiPkg, 306 Locations: file.NewLocationSet(file.NewLocation("opt/bitnami/postgresql/.spdx-postgresql.spdx")), 307 Licenses: pkg.NewLicenseSet( 308 pkg.NewLicenseFromTypeWithContext(ctx, "PostgreSQL", license.Concluded), 309 pkg.NewLicenseFromTypeWithContext(ctx, "PostgreSQL", license.Declared), 310 ), 311 FoundBy: catalogerName, 312 PURL: "pkg:bitnami/pgaudit@17.0.0?arch=arm64&distro=debian-12", 313 Metadata: &pkg.BitnamiSBOMEntry{ 314 Name: "pgaudit", 315 Version: "17.0.0", 316 Architecture: "arm64", 317 Distro: "debian-12", 318 Path: "opt/bitnami/postgresql", 319 }, 320 }, 321 { 322 Name: "pgbackrest", 323 Version: "2.54.2", 324 Type: pkg.BitnamiPkg, 325 Locations: file.NewLocationSet(file.NewLocation("opt/bitnami/postgresql/.spdx-postgresql.spdx")), 326 Licenses: pkg.NewLicenseSet( 327 pkg.NewLicenseFromTypeWithContext(ctx, "MIT", license.Concluded), 328 pkg.NewLicenseFromTypeWithContext(ctx, "MIT", license.Declared), 329 ), 330 FoundBy: catalogerName, 331 PURL: "pkg:bitnami/pgbackrest@2.54.2?arch=arm64&distro=debian-12", 332 CPEs: mustCPEs( 333 "cpe:2.3:*:pgbackrest:pgbackrest:2.54.2:*:*:*:*:*:*:*", 334 ), 335 Metadata: &pkg.BitnamiSBOMEntry{ 336 Name: "pgbackrest", 337 Version: "2.54.2", 338 Architecture: "arm64", 339 Distro: "debian-12", 340 Path: "opt/bitnami/postgresql", 341 }, 342 }, 343 { 344 Name: "wal2json", 345 Version: "2.6.0", 346 Type: pkg.BitnamiPkg, 347 Locations: file.NewLocationSet(file.NewLocation("opt/bitnami/postgresql/.spdx-postgresql.spdx")), 348 Licenses: pkg.NewLicenseSet( 349 pkg.NewLicenseFromTypeWithContext(ctx, "BSD-3-Clause", license.Concluded), 350 pkg.NewLicenseFromTypeWithContext(ctx, "BSD-3-Clause", license.Declared), 351 ), 352 FoundBy: catalogerName, 353 PURL: "pkg:bitnami/wal2json@2.6.0?arch=arm64&distro=debian-12", 354 CPEs: mustCPEs( 355 "cpe:2.3:*:wal2json:wal2json:2.6.0:*:*:*:*:*:*:*", 356 ), 357 Metadata: &pkg.BitnamiSBOMEntry{ 358 Name: "wal2json", 359 Version: "2.6.0", 360 Architecture: "arm64", 361 Distro: "debian-12", 362 Path: "opt/bitnami/postgresql", 363 }, 364 }, 365 { 366 Name: "nss-wrapper", 367 Version: "1.1.16", 368 Type: pkg.BitnamiPkg, 369 Locations: file.NewLocationSet(file.NewLocation("opt/bitnami/postgresql/.spdx-postgresql.spdx")), 370 Licenses: pkg.NewLicenseSet( 371 pkg.NewLicenseFromTypeWithContext(ctx, "BSD-3-Clause", license.Concluded), 372 pkg.NewLicenseFromTypeWithContext(ctx, "BSD-3-Clause", license.Declared), 373 ), 374 FoundBy: catalogerName, 375 PURL: "pkg:bitnami/nss_wrapper@1.1.16?arch=arm64&distro=debian-12", 376 CPEs: mustCPEs( 377 "cpe:2.3:*:nss_wrapper:nss_wrapper:1.1.16:*:*:*:*:*:*:*", 378 ), 379 Metadata: &pkg.BitnamiSBOMEntry{ 380 Name: "nss_wrapper", 381 Version: "1.1.16", 382 Architecture: "arm64", 383 Distro: "debian-12", 384 Path: "opt/bitnami/postgresql", 385 }, 386 }, 387 } 388 389 postgresqlExpectedPkgs := []pkg.Package{postgresqlMainPkg} 390 postgresqlExpectedPkgs = append(postgresqlExpectedPkgs, postgresqlSecondaryPkgs...) 391 pkg.Sort(postgresqlExpectedPkgs) 392 var postgresqlExpectedRelationships []artifact.Relationship 393 for _, p := range postgresqlSecondaryPkgs { 394 postgresqlExpectedRelationships = append(postgresqlExpectedRelationships, artifact.Relationship{ 395 From: postgresqlMainPkg, 396 To: p, 397 Type: artifact.ContainsRelationship, 398 }) 399 } 400 401 renderTemplateMainPkg := pkg.Package{ 402 Name: "render-template", 403 Version: "1.0.7-4", 404 Type: pkg.BitnamiPkg, 405 Locations: file.NewLocationSet(file.NewLocation("opt/bitnami/render-template/.spdx-render-template.spdx")), 406 Licenses: pkg.NewLicenseSet( 407 pkg.NewLicenseFromTypeWithContext(ctx, "Apache-2.0", license.Concluded), 408 pkg.NewLicenseFromTypeWithContext(ctx, "Apache-2.0", license.Declared), 409 ), 410 FoundBy: catalogerName, 411 PURL: "pkg:bitnami/render-template@1.0.7-4?arch=arm64&distro=debian-12", 412 CPEs: mustCPEs( 413 "cpe:2.3:*:render-template:render-template:1.0.7:*:*:*:*:*:*:*", 414 ), 415 Metadata: &pkg.BitnamiSBOMEntry{ 416 Name: "render-template", 417 Version: "1.0.7", 418 Revision: "4", 419 Architecture: "arm64", 420 Distro: "debian-12", 421 Path: "opt/bitnami/render-template", 422 Files: []string{}, 423 }, 424 } 425 426 redisMainPkg := pkg.Package{ 427 Name: "redis", 428 Version: "7.4.0-0", 429 Type: pkg.BitnamiPkg, 430 Locations: file.NewLocationSet(file.NewLocation("opt/bitnami/redis/.spdx-redis.spdx")), 431 Licenses: pkg.NewLicenseSet( 432 pkg.NewLicenseFromTypeWithContext(ctx, "RSALv2", license.Concluded), 433 pkg.NewLicenseFromTypeWithContext(ctx, "RSALv2", license.Declared), 434 ), 435 FoundBy: catalogerName, 436 PURL: "pkg:bitnami/redis@7.4.0-0?arch=arm64&distro=debian-12", 437 CPEs: mustCPEs( 438 "cpe:2.3:*:redis:redis:7.4.0:*:*:*:*:*:*:*", 439 ), 440 Metadata: &pkg.BitnamiSBOMEntry{ 441 Name: "redis", 442 Version: "7.4.0", 443 Revision: "0", 444 Architecture: "arm64", 445 Distro: "debian-12", 446 Path: "opt/bitnami/redis", 447 Files: []string{"opt/bitnami/redis/bin/redis-server"}, 448 }, 449 } 450 451 tests := []struct { 452 name string 453 fixture string 454 wantPkgs []pkg.Package 455 wantRelationships []artifact.Relationship 456 wantErr require.ErrorAssertionFunc 457 }{ 458 { 459 name: "parse valid PostgreSQL SBOM", 460 fixture: "test-fixtures/json", 461 wantPkgs: postgresqlExpectedPkgs, 462 wantRelationships: postgresqlExpectedRelationships, 463 wantErr: require.NoError, 464 }, 465 { 466 name: "parse valid SBOM that includes both Bitnami and non-Bitnami packages", 467 fixture: "test-fixtures/mix", 468 wantPkgs: []pkg.Package{renderTemplateMainPkg}, 469 wantRelationships: nil, 470 wantErr: require.NoError, 471 }, 472 { 473 name: "Redis SBOM with not allowed tag-value format", 474 fixture: "test-fixtures/tag-value", 475 wantPkgs: nil, 476 wantRelationships: nil, 477 wantErr: require.NoError, 478 }, 479 { 480 name: "Invalid SBOM", 481 fixture: "test-fixtures/invalid", 482 wantPkgs: nil, 483 wantRelationships: nil, 484 wantErr: require.Error, 485 }, 486 { 487 name: "SBOM with no relationships", 488 fixture: "test-fixtures/no-rel", 489 wantPkgs: []pkg.Package{redisMainPkg}, 490 wantRelationships: nil, 491 }, 492 } 493 494 for _, tt := range tests { 495 t.Run(tt.name, func(t *testing.T) { 496 pkgtest.NewCatalogTester(). 497 FromDirectory(t, tt.fixture). 498 Expects(tt.wantPkgs, tt.wantRelationships). 499 WithErrorAssertion(tt.wantErr). 500 TestCataloger(t, NewCataloger()) 501 }) 502 } 503 }