github.com/google/osv-scalibr@v0.4.1/converter/spdx/spdx_test.go (about) 1 // Copyright 2025 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package spdx_test 16 17 import ( 18 "math/rand" 19 "testing" 20 21 "github.com/google/go-cmp/cmp" 22 scalibr "github.com/google/osv-scalibr" 23 "github.com/google/osv-scalibr/converter" 24 "github.com/google/osv-scalibr/converter/spdx" 25 "github.com/google/osv-scalibr/extractor" 26 "github.com/google/osv-scalibr/extractor/filesystem/language/python/wheelegg" 27 "github.com/google/osv-scalibr/inventory" 28 "github.com/google/osv-scalibr/purl" 29 "github.com/google/uuid" 30 "github.com/spdx/tools-golang/spdx/v2/common" 31 "github.com/spdx/tools-golang/spdx/v2/v2_3" 32 ) 33 34 func TestToSPDX23(t *testing.T) { 35 // Make UUIDs deterministic 36 uuid.SetRand(rand.New(rand.NewSource(1))) 37 38 testCases := []struct { 39 desc string 40 scanResult *scalibr.ScanResult 41 config spdx.Config 42 want *v2_3.Document 43 }{ 44 { 45 desc: "Package_with_no_custom_config", 46 scanResult: &scalibr.ScanResult{ 47 Inventory: inventory.Inventory{ 48 Packages: []*extractor.Package{{ 49 Name: "software", 50 Version: "1.2.3", 51 PURLType: purl.TypePyPi, 52 Plugins: []string{wheelegg.Name}, 53 }}, 54 }, 55 }, 56 want: &v2_3.Document{ 57 SPDXVersion: "SPDX-2.3", 58 DataLicense: "CC0-1.0", 59 SPDXIdentifier: "DOCUMENT", 60 DocumentName: "SCALIBR-generated SPDX", 61 DocumentNamespace: "https://spdx.google/81855ad8-681d-4d86-91e9-1e00167939cb", 62 CreationInfo: &v2_3.CreationInfo{ 63 Creators: []common.Creator{ 64 { 65 CreatorType: "Tool", 66 Creator: "SCALIBR", 67 }, 68 }, 69 }, 70 Packages: []*v2_3.Package{ 71 { 72 PackageName: "main", 73 PackageSPDXIdentifier: "SPDXRef-Package-main-52fdfc07-2182-454f-963f-5f0f9a621d72", 74 PackageVersion: "0", 75 PackageSupplier: &common.Supplier{ 76 Supplier: spdx.NoAssertion, 77 SupplierType: spdx.NoAssertion, 78 }, 79 PackageDownloadLocation: spdx.NoAssertion, 80 IsFilesAnalyzedTagPresent: false, 81 }, 82 { 83 PackageName: "software", 84 PackageSPDXIdentifier: "SPDXRef-Package-software-9566c74d-1003-4c4d-bbbb-0407d1e2c649", 85 PackageVersion: "1.2.3", 86 PackageSupplier: &common.Supplier{ 87 Supplier: spdx.NoAssertion, 88 SupplierType: spdx.NoAssertion, 89 }, 90 PackageDownloadLocation: spdx.NoAssertion, 91 PackageLicenseConcluded: spdx.NoAssertion, 92 PackageLicenseDeclared: spdx.NoAssertion, 93 IsFilesAnalyzedTagPresent: false, 94 PackageSourceInfo: "Identified by the python/wheelegg extractor", 95 PackageExternalReferences: []*v2_3.PackageExternalReference{ 96 { 97 Category: "PACKAGE-MANAGER", 98 RefType: "purl", 99 Locator: "pkg:pypi/software@1.2.3", 100 }, 101 }, 102 }, 103 }, 104 Relationships: []*v2_3.Relationship{ 105 { 106 RefA: common.DocElementID{ 107 ElementRefID: "SPDXRef-DOCUMENT", 108 }, 109 RefB: common.DocElementID{ 110 ElementRefID: "SPDXRef-Package-main-52fdfc07-2182-454f-963f-5f0f9a621d72", 111 }, 112 Relationship: "DESCRIBES", 113 }, 114 { 115 RefA: common.DocElementID{ 116 ElementRefID: "SPDXRef-Package-main-52fdfc07-2182-454f-963f-5f0f9a621d72", 117 }, 118 RefB: common.DocElementID{ 119 ElementRefID: "SPDXRef-Package-software-9566c74d-1003-4c4d-bbbb-0407d1e2c649", 120 }, 121 Relationship: "CONTAINS", 122 }, 123 { 124 RefA: common.DocElementID{ 125 ElementRefID: "SPDXRef-Package-software-9566c74d-1003-4c4d-bbbb-0407d1e2c649", 126 }, 127 RefB: common.DocElementID{ 128 SpecialID: spdx.NoAssertion, 129 }, 130 Relationship: "CONTAINS", 131 }, 132 }, 133 }, 134 }, 135 { 136 desc: "Package_with_custom_config", 137 scanResult: &scalibr.ScanResult{ 138 Inventory: inventory.Inventory{ 139 Packages: []*extractor.Package{{ 140 Name: "software", 141 Version: "1.2.3", 142 PURLType: purl.TypePyPi, 143 Plugins: []string{wheelegg.Name}, 144 }}, 145 }, 146 }, 147 config: spdx.Config{ 148 DocumentName: "Custom name", 149 DocumentNamespace: "Custom namespace", 150 Creators: []common.Creator{ 151 { 152 CreatorType: "Person", 153 Creator: "Custom creator", 154 }, 155 }, 156 }, 157 want: &v2_3.Document{ 158 SPDXVersion: "SPDX-2.3", 159 DataLicense: "CC0-1.0", 160 SPDXIdentifier: "DOCUMENT", 161 DocumentName: "Custom name", 162 DocumentNamespace: "Custom namespace", 163 CreationInfo: &v2_3.CreationInfo{ 164 Creators: []common.Creator{ 165 { 166 CreatorType: "Tool", 167 Creator: "SCALIBR", 168 }, 169 { 170 CreatorType: "Person", 171 Creator: "Custom creator", 172 }, 173 }, 174 }, 175 Packages: []*v2_3.Package{ 176 { 177 PackageName: "main", 178 PackageSPDXIdentifier: "SPDXRef-Package-main-6694d2c4-22ac-4208-a007-2939487f6999", 179 PackageVersion: "0", 180 PackageSupplier: &common.Supplier{ 181 Supplier: spdx.NoAssertion, 182 SupplierType: spdx.NoAssertion, 183 }, 184 PackageDownloadLocation: spdx.NoAssertion, 185 IsFilesAnalyzedTagPresent: false, 186 }, 187 { 188 PackageName: "software", 189 PackageSPDXIdentifier: "SPDXRef-Package-software-eb9d18a4-4784-445d-87f3-c67cf22746e9", 190 PackageVersion: "1.2.3", 191 PackageSupplier: &common.Supplier{ 192 Supplier: spdx.NoAssertion, 193 SupplierType: spdx.NoAssertion, 194 }, 195 PackageDownloadLocation: spdx.NoAssertion, 196 PackageLicenseConcluded: spdx.NoAssertion, 197 PackageLicenseDeclared: spdx.NoAssertion, 198 IsFilesAnalyzedTagPresent: false, 199 PackageSourceInfo: "Identified by the python/wheelegg extractor", 200 PackageExternalReferences: []*v2_3.PackageExternalReference{ 201 { 202 Category: "PACKAGE-MANAGER", 203 RefType: "purl", 204 Locator: "pkg:pypi/software@1.2.3", 205 }, 206 }, 207 }, 208 }, 209 Relationships: []*v2_3.Relationship{ 210 { 211 RefA: common.DocElementID{ 212 ElementRefID: "SPDXRef-DOCUMENT", 213 }, 214 RefB: common.DocElementID{ 215 ElementRefID: "SPDXRef-Package-main-6694d2c4-22ac-4208-a007-2939487f6999", 216 }, 217 Relationship: "DESCRIBES", 218 }, 219 { 220 RefA: common.DocElementID{ 221 ElementRefID: "SPDXRef-Package-main-6694d2c4-22ac-4208-a007-2939487f6999", 222 }, 223 RefB: common.DocElementID{ 224 ElementRefID: "SPDXRef-Package-software-eb9d18a4-4784-445d-87f3-c67cf22746e9", 225 }, 226 Relationship: "CONTAINS", 227 }, 228 { 229 RefA: common.DocElementID{ 230 ElementRefID: "SPDXRef-Package-software-eb9d18a4-4784-445d-87f3-c67cf22746e9", 231 }, 232 RefB: common.DocElementID{ 233 SpecialID: spdx.NoAssertion, 234 }, 235 Relationship: "CONTAINS", 236 }, 237 }, 238 }, 239 }, 240 { 241 desc: "Packages_with_licenses", 242 scanResult: &scalibr.ScanResult{ 243 Inventory: inventory.Inventory{ 244 Packages: []*extractor.Package{{ 245 Name: "software-1", 246 Version: "1.2.3", 247 PURLType: purl.TypePyPi, 248 Licenses: []string{"MIT"}, 249 Plugins: []string{wheelegg.Name}, 250 }, { 251 Name: "software-2", 252 Version: "4.5.6", 253 PURLType: purl.TypePyPi, 254 Licenses: []string{"Apache-2.0", "MIT", "MADE UP"}, 255 Plugins: []string{wheelegg.Name}, 256 }}, 257 }, 258 }, 259 want: &v2_3.Document{ 260 SPDXVersion: "SPDX-2.3", 261 DataLicense: "CC0-1.0", 262 SPDXIdentifier: "DOCUMENT", 263 DocumentName: "SCALIBR-generated SPDX", 264 DocumentNamespace: "https://spdx.google/6325253f-ec73-4dd7-a9e2-8bf921119c16", 265 CreationInfo: &v2_3.CreationInfo{ 266 Creators: []common.Creator{ 267 { 268 CreatorType: "Tool", 269 Creator: "SCALIBR", 270 }, 271 }, 272 }, 273 Packages: []*v2_3.Package{ 274 { 275 PackageName: "main", 276 PackageSPDXIdentifier: "SPDXRef-Package-main-95af5a25-3679-41ba-a2ff-6cd471c483f1", 277 PackageVersion: "0", 278 PackageSupplier: &common.Supplier{ 279 Supplier: spdx.NoAssertion, 280 SupplierType: spdx.NoAssertion, 281 }, 282 PackageDownloadLocation: spdx.NoAssertion, 283 IsFilesAnalyzedTagPresent: false, 284 }, 285 { 286 PackageName: "software-1", 287 PackageSPDXIdentifier: "SPDXRef-Package-software-1-5fb90bad-b37c-4821-b6d9-5526a41a9504", 288 PackageVersion: "1.2.3", 289 PackageSupplier: &common.Supplier{ 290 Supplier: spdx.NoAssertion, 291 SupplierType: spdx.NoAssertion, 292 }, 293 PackageDownloadLocation: spdx.NoAssertion, 294 PackageLicenseConcluded: "MIT", 295 PackageLicenseDeclared: spdx.NoAssertion, 296 IsFilesAnalyzedTagPresent: false, 297 PackageSourceInfo: "Identified by the python/wheelegg extractor", 298 PackageExternalReferences: []*v2_3.PackageExternalReference{ 299 { 300 Category: "PACKAGE-MANAGER", 301 RefType: "purl", 302 Locator: "pkg:pypi/software-1@1.2.3", 303 }, 304 }, 305 }, 306 { 307 PackageName: "software-2", 308 PackageSPDXIdentifier: "SPDXRef-Package-software-2-680b4e7c-8b76-4a1b-9d49-d4955c848621", 309 PackageVersion: "4.5.6", 310 PackageSupplier: &common.Supplier{ 311 Supplier: spdx.NoAssertion, 312 SupplierType: spdx.NoAssertion, 313 }, 314 PackageDownloadLocation: spdx.NoAssertion, 315 PackageLicenseConcluded: "Apache-2.0 AND LicenseRef-MADE-UP AND MIT", 316 PackageLicenseDeclared: spdx.NoAssertion, 317 IsFilesAnalyzedTagPresent: false, 318 PackageSourceInfo: "Identified by the python/wheelegg extractor", 319 PackageExternalReferences: []*v2_3.PackageExternalReference{ 320 { 321 Category: "PACKAGE-MANAGER", 322 RefType: "purl", 323 Locator: "pkg:pypi/software-2@4.5.6", 324 }, 325 }, 326 }, 327 }, 328 Relationships: []*v2_3.Relationship{ 329 { 330 RefA: common.DocElementID{ 331 ElementRefID: "SPDXRef-DOCUMENT", 332 }, 333 RefB: common.DocElementID{ 334 ElementRefID: "SPDXRef-Package-main-95af5a25-3679-41ba-a2ff-6cd471c483f1", 335 }, 336 Relationship: "DESCRIBES", 337 }, 338 { 339 RefA: common.DocElementID{ 340 ElementRefID: "SPDXRef-Package-main-95af5a25-3679-41ba-a2ff-6cd471c483f1", 341 }, 342 RefB: common.DocElementID{ 343 ElementRefID: "SPDXRef-Package-software-1-5fb90bad-b37c-4821-b6d9-5526a41a9504", 344 }, 345 Relationship: "CONTAINS", 346 }, 347 { 348 RefA: common.DocElementID{ 349 ElementRefID: "SPDXRef-Package-software-1-5fb90bad-b37c-4821-b6d9-5526a41a9504", 350 }, 351 RefB: common.DocElementID{ 352 SpecialID: spdx.NoAssertion, 353 }, 354 Relationship: "CONTAINS", 355 }, 356 { 357 RefA: common.DocElementID{ 358 ElementRefID: "SPDXRef-Package-main-95af5a25-3679-41ba-a2ff-6cd471c483f1", 359 }, 360 RefB: common.DocElementID{ 361 ElementRefID: "SPDXRef-Package-software-2-680b4e7c-8b76-4a1b-9d49-d4955c848621", 362 }, 363 Relationship: "CONTAINS", 364 }, 365 { 366 RefA: common.DocElementID{ 367 ElementRefID: "SPDXRef-Package-software-2-680b4e7c-8b76-4a1b-9d49-d4955c848621", 368 }, 369 RefB: common.DocElementID{ 370 SpecialID: spdx.NoAssertion, 371 }, 372 Relationship: "CONTAINS", 373 }, 374 }, 375 OtherLicenses: []*v2_3.OtherLicense{{LicenseIdentifier: "LicenseRef-MADE-UP", ExtractedText: "MADE UP"}}, 376 }, 377 }, 378 { 379 desc: "Package_with_invalid_PURLs_skipped", 380 scanResult: &scalibr.ScanResult{ 381 Inventory: inventory.Inventory{ 382 Packages: []*extractor.Package{ 383 // PURL field missing 384 {Plugins: []string{wheelegg.Name}}, 385 // No name 386 { 387 Version: "1.2.3", PURLType: purl.TypePyPi, Plugins: []string{wheelegg.Name}, 388 }, 389 // No version 390 { 391 Name: "software", PURLType: purl.TypePyPi, Plugins: []string{wheelegg.Name}, 392 }, 393 }, 394 }, 395 }, 396 want: &v2_3.Document{ 397 SPDXVersion: "SPDX-2.3", 398 DataLicense: "CC0-1.0", 399 SPDXIdentifier: "DOCUMENT", 400 DocumentName: "SCALIBR-generated SPDX", 401 DocumentNamespace: "https://spdx.google/0bf50598-7592-4e66-8a5b-df2c7fc48445", 402 CreationInfo: &v2_3.CreationInfo{ 403 Creators: []common.Creator{ 404 { 405 CreatorType: "Tool", 406 Creator: "SCALIBR", 407 }, 408 }, 409 }, 410 Packages: []*v2_3.Package{{ 411 PackageName: "main", 412 PackageSPDXIdentifier: "SPDXRef-Package-main-0f070244-8615-4bda-8831-3f6a8eb668d2", 413 PackageVersion: "0", 414 PackageSupplier: &common.Supplier{ 415 Supplier: spdx.NoAssertion, 416 SupplierType: spdx.NoAssertion, 417 }, 418 PackageDownloadLocation: spdx.NoAssertion, 419 IsFilesAnalyzedTagPresent: false, 420 }}, 421 Relationships: []*v2_3.Relationship{ 422 { 423 RefA: common.DocElementID{ 424 ElementRefID: "SPDXRef-DOCUMENT", 425 }, 426 RefB: common.DocElementID{ 427 ElementRefID: "SPDXRef-Package-main-0f070244-8615-4bda-8831-3f6a8eb668d2", 428 }, 429 Relationship: "DESCRIBES", 430 }, 431 }, 432 }, 433 }, 434 { 435 desc: "Invalid_chars_in_package_name_replaced", 436 scanResult: &scalibr.ScanResult{ 437 Inventory: inventory.Inventory{ 438 Packages: []*extractor.Package{{ 439 Name: "softw@re&", 440 Version: "1.2.3", 441 PURLType: purl.TypePyPi, 442 Plugins: []string{wheelegg.Name}, 443 }}, 444 }, 445 }, 446 want: &v2_3.Document{ 447 SPDXVersion: "SPDX-2.3", 448 DataLicense: "CC0-1.0", 449 SPDXIdentifier: "DOCUMENT", 450 DocumentName: "SCALIBR-generated SPDX", 451 DocumentNamespace: "https://spdx.google/172ed857-94bb-458b-8c3b-525da1786f9f", 452 CreationInfo: &v2_3.CreationInfo{ 453 Creators: []common.Creator{ 454 { 455 CreatorType: "Tool", 456 Creator: "SCALIBR", 457 }, 458 }, 459 }, 460 Packages: []*v2_3.Package{ 461 { 462 PackageName: "main", 463 PackageSPDXIdentifier: "SPDXRef-Package-main-92d2572b-cd06-48d2-96c5-2f5054e2d083", 464 PackageVersion: "0", 465 PackageSupplier: &common.Supplier{ 466 Supplier: spdx.NoAssertion, 467 SupplierType: spdx.NoAssertion, 468 }, 469 PackageDownloadLocation: spdx.NoAssertion, 470 IsFilesAnalyzedTagPresent: false, 471 }, 472 { 473 PackageName: "softw@re&", 474 PackageSPDXIdentifier: "SPDXRef-Package-softw-re--6bf84c71-74cb-4476-b64c-c3dbd968b0f7", 475 PackageVersion: "1.2.3", 476 PackageSupplier: &common.Supplier{ 477 Supplier: spdx.NoAssertion, 478 SupplierType: spdx.NoAssertion, 479 }, 480 PackageDownloadLocation: spdx.NoAssertion, 481 PackageLicenseConcluded: spdx.NoAssertion, 482 PackageLicenseDeclared: spdx.NoAssertion, 483 IsFilesAnalyzedTagPresent: false, 484 PackageSourceInfo: "Identified by the python/wheelegg extractor", 485 PackageExternalReferences: []*v2_3.PackageExternalReference{ 486 { 487 Category: "PACKAGE-MANAGER", 488 RefType: "purl", 489 Locator: "pkg:pypi/softw%40re%26@1.2.3", 490 }, 491 }, 492 }, 493 }, 494 Relationships: []*v2_3.Relationship{ 495 { 496 RefA: common.DocElementID{ 497 ElementRefID: "SPDXRef-DOCUMENT", 498 }, 499 RefB: common.DocElementID{ 500 ElementRefID: "SPDXRef-Package-main-92d2572b-cd06-48d2-96c5-2f5054e2d083", 501 }, 502 Relationship: "DESCRIBES", 503 }, 504 { 505 RefA: common.DocElementID{ 506 ElementRefID: "SPDXRef-Package-main-92d2572b-cd06-48d2-96c5-2f5054e2d083", 507 }, 508 RefB: common.DocElementID{ 509 ElementRefID: "SPDXRef-Package-softw-re--6bf84c71-74cb-4476-b64c-c3dbd968b0f7", 510 }, 511 Relationship: "CONTAINS", 512 }, 513 { 514 RefA: common.DocElementID{ 515 ElementRefID: "SPDXRef-Package-softw-re--6bf84c71-74cb-4476-b64c-c3dbd968b0f7", 516 }, 517 RefB: common.DocElementID{ 518 SpecialID: spdx.NoAssertion, 519 }, 520 Relationship: "CONTAINS", 521 }, 522 }, 523 }, 524 }, 525 { 526 desc: "One_location_reported", 527 scanResult: &scalibr.ScanResult{ 528 Inventory: inventory.Inventory{ 529 Packages: []*extractor.Package{{ 530 Name: "software", 531 Version: "1.2.3", 532 PURLType: purl.TypePyPi, 533 Plugins: []string{wheelegg.Name}, 534 Locations: []string{"/file1"}, 535 }}, 536 }, 537 }, 538 want: &v2_3.Document{ 539 SPDXVersion: "SPDX-2.3", 540 DataLicense: "CC0-1.0", 541 SPDXIdentifier: "DOCUMENT", 542 DocumentName: "SCALIBR-generated SPDX", 543 DocumentNamespace: "https://spdx.google/29b0223b-eea5-44f7-8391-f445d15afd42", 544 CreationInfo: &v2_3.CreationInfo{ 545 Creators: []common.Creator{ 546 { 547 CreatorType: "Tool", 548 Creator: "SCALIBR", 549 }, 550 }, 551 }, 552 Packages: []*v2_3.Package{ 553 { 554 PackageName: "main", 555 PackageSPDXIdentifier: "SPDXRef-Package-main-ff094279-db19-44eb-97a1-9d0f7bbacbe0", 556 PackageVersion: "0", 557 PackageSupplier: &common.Supplier{ 558 Supplier: spdx.NoAssertion, 559 SupplierType: spdx.NoAssertion, 560 }, 561 PackageDownloadLocation: spdx.NoAssertion, 562 IsFilesAnalyzedTagPresent: false, 563 }, 564 { 565 PackageName: "software", 566 PackageSPDXIdentifier: "SPDXRef-Package-software-255aa5b7-d44b-4c40-b84c-892b9bffd436", 567 PackageVersion: "1.2.3", 568 PackageSupplier: &common.Supplier{ 569 Supplier: spdx.NoAssertion, 570 SupplierType: spdx.NoAssertion, 571 }, 572 PackageDownloadLocation: spdx.NoAssertion, 573 PackageLicenseConcluded: spdx.NoAssertion, 574 PackageLicenseDeclared: spdx.NoAssertion, 575 IsFilesAnalyzedTagPresent: false, 576 PackageSourceInfo: "Identified by the python/wheelegg extractor from /file1", 577 PackageExternalReferences: []*v2_3.PackageExternalReference{ 578 { 579 Category: "PACKAGE-MANAGER", 580 RefType: "purl", 581 Locator: "pkg:pypi/software@1.2.3", 582 }, 583 }, 584 }, 585 }, 586 Relationships: []*v2_3.Relationship{ 587 { 588 RefA: common.DocElementID{ 589 ElementRefID: "SPDXRef-DOCUMENT", 590 }, 591 RefB: common.DocElementID{ 592 ElementRefID: "SPDXRef-Package-main-ff094279-db19-44eb-97a1-9d0f7bbacbe0", 593 }, 594 Relationship: "DESCRIBES", 595 }, 596 { 597 RefA: common.DocElementID{ 598 ElementRefID: "SPDXRef-Package-main-ff094279-db19-44eb-97a1-9d0f7bbacbe0", 599 }, 600 RefB: common.DocElementID{ 601 ElementRefID: "SPDXRef-Package-software-255aa5b7-d44b-4c40-b84c-892b9bffd436", 602 }, 603 Relationship: "CONTAINS", 604 }, 605 { 606 RefA: common.DocElementID{ 607 ElementRefID: "SPDXRef-Package-software-255aa5b7-d44b-4c40-b84c-892b9bffd436", 608 }, 609 RefB: common.DocElementID{ 610 SpecialID: spdx.NoAssertion, 611 }, 612 Relationship: "CONTAINS", 613 }, 614 }, 615 }, 616 }, 617 { 618 desc: "Multiple_locations_reported", 619 scanResult: &scalibr.ScanResult{ 620 Inventory: inventory.Inventory{ 621 Packages: []*extractor.Package{{ 622 Name: "software", 623 Version: "1.2.3", 624 Plugins: []string{wheelegg.Name}, 625 PURLType: purl.TypePyPi, 626 Locations: []string{"/file1", "/file2", "/file3"}, 627 }}, 628 }, 629 }, 630 want: &v2_3.Document{ 631 SPDXVersion: "SPDX-2.3", 632 DataLicense: "CC0-1.0", 633 SPDXIdentifier: "DOCUMENT", 634 DocumentName: "SCALIBR-generated SPDX", 635 DocumentNamespace: "https://spdx.google/b14323a6-bc8f-4e7d-b1d9-29333ff99393", 636 CreationInfo: &v2_3.CreationInfo{ 637 Creators: []common.Creator{ 638 { 639 CreatorType: "Tool", 640 Creator: "SCALIBR", 641 }, 642 }, 643 }, 644 Packages: []*v2_3.Package{ 645 { 646 PackageName: "main", 647 PackageSPDXIdentifier: "SPDXRef-Package-main-94040374-f692-4b98-8bf8-713f8d962d7c", 648 PackageVersion: "0", 649 PackageSupplier: &common.Supplier{ 650 Supplier: spdx.NoAssertion, 651 SupplierType: spdx.NoAssertion, 652 }, 653 PackageDownloadLocation: spdx.NoAssertion, 654 IsFilesAnalyzedTagPresent: false, 655 }, 656 { 657 PackageName: "software", 658 PackageSPDXIdentifier: "SPDXRef-Package-software-8d019192-c242-44e2-8afc-cae3a61fb586", 659 PackageVersion: "1.2.3", 660 PackageSupplier: &common.Supplier{ 661 Supplier: spdx.NoAssertion, 662 SupplierType: spdx.NoAssertion, 663 }, 664 PackageDownloadLocation: spdx.NoAssertion, 665 PackageLicenseConcluded: spdx.NoAssertion, 666 PackageLicenseDeclared: spdx.NoAssertion, 667 IsFilesAnalyzedTagPresent: false, 668 PackageSourceInfo: "Identified by the python/wheelegg extractor from 3 locations, including /file1 and /file2", 669 PackageExternalReferences: []*v2_3.PackageExternalReference{ 670 { 671 Category: "PACKAGE-MANAGER", 672 RefType: "purl", 673 Locator: "pkg:pypi/software@1.2.3", 674 }, 675 }, 676 }, 677 }, 678 Relationships: []*v2_3.Relationship{ 679 { 680 RefA: common.DocElementID{ 681 ElementRefID: "SPDXRef-DOCUMENT", 682 }, 683 RefB: common.DocElementID{ 684 ElementRefID: "SPDXRef-Package-main-94040374-f692-4b98-8bf8-713f8d962d7c", 685 }, 686 Relationship: "DESCRIBES", 687 }, 688 { 689 RefA: common.DocElementID{ 690 ElementRefID: "SPDXRef-Package-main-94040374-f692-4b98-8bf8-713f8d962d7c", 691 }, 692 RefB: common.DocElementID{ 693 ElementRefID: "SPDXRef-Package-software-8d019192-c242-44e2-8afc-cae3a61fb586", 694 }, 695 Relationship: "CONTAINS", 696 }, 697 { 698 RefA: common.DocElementID{ 699 ElementRefID: "SPDXRef-Package-software-8d019192-c242-44e2-8afc-cae3a61fb586", 700 }, 701 RefB: common.DocElementID{ 702 SpecialID: spdx.NoAssertion, 703 }, 704 Relationship: "CONTAINS", 705 }, 706 }, 707 }, 708 }, 709 } 710 711 for _, tc := range testCases { 712 t.Run(tc.desc, func(t *testing.T) { 713 got := converter.ToSPDX23(tc.scanResult, tc.config) 714 // Can't mock time.Now() so skip verifying the timestamp. 715 tc.want.CreationInfo.Created = got.CreationInfo.Created 716 717 if diff := cmp.Diff(tc.want, got, cmp.AllowUnexported(v2_3.Package{})); diff != "" { 718 t.Errorf("converter.ToSPDX23(%v): unexpected diff (-want +got):\n%s", tc.scanResult, diff) 719 } 720 }) 721 } 722 }