github.com/google/osv-scalibr@v0.4.1/extractor/filesystem/os/purl/purl_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 purl_test 16 17 import ( 18 "testing" 19 20 "github.com/google/go-cmp/cmp" 21 apkmeta "github.com/google/osv-scalibr/extractor/filesystem/os/apk/metadata" 22 cosmeta "github.com/google/osv-scalibr/extractor/filesystem/os/cos/metadata" 23 dpkgmeta "github.com/google/osv-scalibr/extractor/filesystem/os/dpkg/metadata" 24 flatpakmeta "github.com/google/osv-scalibr/extractor/filesystem/os/flatpak/metadata" 25 nixmeta "github.com/google/osv-scalibr/extractor/filesystem/os/nix/metadata" 26 pacmanmeta "github.com/google/osv-scalibr/extractor/filesystem/os/pacman/metadata" 27 portagemeta "github.com/google/osv-scalibr/extractor/filesystem/os/portage/metadata" 28 ospurl "github.com/google/osv-scalibr/extractor/filesystem/os/purl" 29 rpmmeta "github.com/google/osv-scalibr/extractor/filesystem/os/rpm/metadata" 30 snapmeta "github.com/google/osv-scalibr/extractor/filesystem/os/snap/metadata" 31 "github.com/google/osv-scalibr/purl" 32 ) 33 34 func TestMakePackageURLDebian(t *testing.T) { 35 pkgname := "pkgname" 36 sourcename := "sourcename" 37 name := "name" 38 version := "1.2.3" 39 sourceversion := "1.2.4" 40 source := "sourcename" 41 tests := []struct { 42 desc string 43 purlType string 44 metadata *dpkgmeta.Metadata 45 want *purl.PackageURL 46 }{ 47 { 48 desc: "both OS versions present", 49 purlType: purl.TypeDebian, 50 metadata: &dpkgmeta.Metadata{ 51 PackageName: pkgname, 52 SourceName: sourcename, 53 SourceVersion: sourceversion, 54 OSID: "debian", 55 OSVersionCodename: "jammy", 56 OSVersionID: "22.04", 57 }, 58 want: &purl.PackageURL{ 59 Type: purl.TypeDebian, 60 Name: pkgname, 61 Namespace: "debian", 62 Version: version, 63 Qualifiers: purl.QualifiersFromMap(map[string]string{ 64 purl.Source: source, 65 purl.SourceVersion: sourceversion, 66 purl.Distro: "jammy", 67 }), 68 }, 69 }, 70 { 71 desc: "only VERSION_ID set", 72 purlType: purl.TypeDebian, 73 metadata: &dpkgmeta.Metadata{ 74 PackageName: pkgname, 75 SourceName: sourcename, 76 SourceVersion: sourceversion, 77 OSID: "debian", 78 OSVersionID: "22.04", 79 }, 80 want: &purl.PackageURL{ 81 Type: purl.TypeDebian, 82 Name: pkgname, 83 Namespace: "debian", 84 Version: version, 85 Qualifiers: purl.QualifiersFromMap(map[string]string{ 86 purl.Source: source, 87 purl.SourceVersion: sourceversion, 88 purl.Distro: "22.04", 89 }), 90 }, 91 }, 92 { 93 desc: "ID not set, fallback to linux", 94 purlType: purl.TypeDebian, 95 metadata: &dpkgmeta.Metadata{ 96 PackageName: pkgname, 97 SourceName: sourcename, 98 SourceVersion: sourceversion, 99 OSVersionCodename: "jammy", 100 OSVersionID: "22.04", 101 }, 102 want: &purl.PackageURL{ 103 Type: purl.TypeDebian, 104 Name: pkgname, 105 Namespace: "linux", 106 Version: version, 107 Qualifiers: purl.QualifiersFromMap(map[string]string{ 108 purl.Source: source, 109 purl.SourceVersion: sourceversion, 110 purl.Distro: "jammy", 111 }), 112 }, 113 }, 114 { 115 desc: "OS ID and OS Version set (OpenWrt)", 116 purlType: purl.TypeOpkg, 117 metadata: &dpkgmeta.Metadata{ 118 PackageName: pkgname, 119 OSID: "openwrt", 120 OSVersionID: "22.03.5", 121 }, 122 want: &purl.PackageURL{ 123 Type: purl.TypeOpkg, 124 Name: pkgname, 125 Namespace: "openwrt", 126 Version: version, 127 Qualifiers: purl.QualifiersFromMap(map[string]string{ 128 purl.Distro: "22.03.5", 129 }), 130 }, 131 }, 132 { 133 desc: "OS ID not set, fallback to linux", 134 purlType: purl.TypeOpkg, 135 metadata: &dpkgmeta.Metadata{ 136 PackageName: pkgname, 137 OSVersionCodename: "jammy", 138 OSVersionID: "5.10", 139 }, 140 want: &purl.PackageURL{ 141 Type: purl.TypeOpkg, 142 Name: pkgname, 143 Namespace: "linux", 144 Version: version, 145 Qualifiers: purl.QualifiersFromMap(map[string]string{ 146 purl.Distro: "jammy", 147 }), 148 }, 149 }, 150 } 151 for _, tt := range tests { 152 t.Run(tt.desc, func(t *testing.T) { 153 got := ospurl.MakePackageURL(name, version, tt.purlType, tt.metadata) 154 if diff := cmp.Diff(tt.want, got); diff != "" { 155 t.Errorf("ospurl.MakePackageURL(%v, %v, %v, %v): unexpected PURL (-want +got):\n%s", name, version, tt.purlType, tt.metadata, diff) 156 } 157 }) 158 } 159 } 160 161 func TestMakePackageURLFlatpak(t *testing.T) { 162 pkgname := "pkgname" 163 pkgid := "pkgid" 164 pkgversion := "1.2.3" 165 releasedate := "2024-05-02" 166 osname := "Debian GNU/Linux" 167 osid := "debian" 168 osversionid := "12" 169 osbuildid := "bookworm" 170 developer := "developer" 171 tests := []struct { 172 desc string 173 metadata *flatpakmeta.Metadata 174 want *purl.PackageURL 175 }{ 176 { 177 desc: "Both_VERSION_ID_and_BUILD_ID_is_set", 178 metadata: &flatpakmeta.Metadata{ 179 PackageName: pkgname, 180 PackageID: pkgid, 181 PackageVersion: pkgversion, 182 ReleaseDate: releasedate, 183 OSName: osname, 184 OSID: osid, 185 OSVersionID: osversionid, 186 OSBuildID: osbuildid, 187 Developer: developer, 188 }, 189 want: &purl.PackageURL{ 190 Type: purl.TypeFlatpak, 191 Name: pkgname, 192 Namespace: "debian", 193 Version: pkgversion, 194 Qualifiers: purl.QualifiersFromMap(map[string]string{ 195 purl.Distro: "debian-12", 196 }), 197 }, 198 }, 199 { 200 desc: "only_BUILD_ID_set", 201 metadata: &flatpakmeta.Metadata{ 202 PackageName: pkgname, 203 PackageID: pkgid, 204 PackageVersion: pkgversion, 205 ReleaseDate: releasedate, 206 OSName: osname, 207 OSID: osid, 208 OSBuildID: osbuildid, 209 Developer: developer, 210 }, 211 want: &purl.PackageURL{ 212 Type: purl.TypeFlatpak, 213 Name: pkgname, 214 Namespace: "debian", 215 Version: pkgversion, 216 Qualifiers: purl.QualifiersFromMap(map[string]string{ 217 purl.Distro: "debian-bookworm", 218 }), 219 }, 220 }, 221 { 222 desc: "OS_ID_not_set", 223 metadata: &flatpakmeta.Metadata{ 224 PackageName: pkgname, 225 PackageID: pkgid, 226 PackageVersion: pkgversion, 227 ReleaseDate: releasedate, 228 OSName: osname, 229 OSVersionID: osversionid, 230 OSBuildID: osbuildid, 231 Developer: developer, 232 }, 233 want: &purl.PackageURL{ 234 Type: purl.TypeFlatpak, 235 Name: pkgname, 236 Namespace: "", 237 Version: pkgversion, 238 Qualifiers: purl.QualifiersFromMap(map[string]string{ 239 purl.Distro: "12", 240 }), 241 }, 242 }, 243 } 244 for _, tt := range tests { 245 t.Run(tt.desc, func(t *testing.T) { 246 got := ospurl.MakePackageURL(pkgname, pkgversion, purl.TypeFlatpak, tt.metadata) 247 if diff := cmp.Diff(tt.want, got); diff != "" { 248 t.Errorf("ospurl.MakePackageURL(%v, %v, %v, %v): unexpected PURL (-want +got):\n%s", pkgname, pkgversion, purl.TypeFlatpak, tt.metadata, diff) 249 } 250 }) 251 } 252 } 253 254 func TestMakePackageURLAPK(t *testing.T) { 255 tests := []struct { 256 desc string 257 metadata *apkmeta.Metadata 258 want *purl.PackageURL 259 }{ 260 { 261 desc: "all_fields_present", 262 metadata: &apkmeta.Metadata{ 263 PackageName: "Name", 264 OriginName: "originName", 265 OSID: "id", 266 OSVersionID: "4.5.6", 267 }, 268 want: &purl.PackageURL{ 269 Type: purl.TypeApk, 270 Name: "name", 271 Namespace: "id", 272 Version: "1.2.3", 273 Qualifiers: purl.QualifiersFromMap(map[string]string{purl.Distro: "4.5.6", purl.Origin: "originName"}), 274 }, 275 }, 276 { 277 desc: "OS_ID_missing", 278 metadata: &apkmeta.Metadata{ 279 PackageName: "Name", 280 OriginName: "originName", 281 OSVersionID: "4.5.6", 282 }, 283 want: &purl.PackageURL{ 284 Type: purl.TypeApk, 285 Name: "name", 286 Namespace: "alpine", 287 Version: "1.2.3", 288 Qualifiers: purl.QualifiersFromMap(map[string]string{purl.Distro: "4.5.6", purl.Origin: "originName"}), 289 }, 290 }, 291 { 292 desc: "OS_version_ID_missing", 293 metadata: &apkmeta.Metadata{ 294 PackageName: "Name", 295 OriginName: "originName", 296 OSID: "id", 297 }, 298 want: &purl.PackageURL{ 299 Type: purl.TypeApk, 300 Name: "name", 301 Namespace: "id", 302 Version: "1.2.3", 303 Qualifiers: purl.QualifiersFromMap(map[string]string{purl.Origin: "originName"}), 304 }, 305 }, 306 } 307 for _, tt := range tests { 308 t.Run(tt.desc, func(t *testing.T) { 309 got := ospurl.MakePackageURL("name", "1.2.3", purl.TypeApk, tt.metadata) 310 if diff := cmp.Diff(tt.want, got); diff != "" { 311 t.Errorf("ospurl.MakePackageURL(%v): unexpected PURL (-want +got):\n%s", tt.metadata, diff) 312 } 313 }) 314 } 315 } 316 317 func TestMakePackageURLCOS(t *testing.T) { 318 tests := []struct { 319 desc string 320 metadata *cosmeta.Metadata 321 want *purl.PackageURL 322 }{ 323 { 324 desc: "both_versions_present", 325 metadata: &cosmeta.Metadata{ 326 OSVersionID: "101", 327 OSVersion: "97", 328 }, 329 want: &purl.PackageURL{ 330 Type: purl.TypeCOS, 331 Name: "name", 332 Version: "1.2.3", 333 Qualifiers: purl.QualifiersFromMap(map[string]string{purl.Distro: "cos-101"}), 334 }, 335 }, 336 { 337 desc: "only_VERSION_set", 338 metadata: &cosmeta.Metadata{ 339 OSVersion: "97", 340 }, 341 want: &purl.PackageURL{ 342 Type: purl.TypeCOS, 343 Name: "name", 344 Version: "1.2.3", 345 Qualifiers: purl.QualifiersFromMap(map[string]string{purl.Distro: "cos-97"}), 346 }, 347 }, 348 { 349 desc: "only_VERSION_ID_set", 350 metadata: &cosmeta.Metadata{ 351 OSVersionID: "101", 352 }, 353 want: &purl.PackageURL{ 354 Type: purl.TypeCOS, 355 Name: "name", 356 Version: "1.2.3", 357 Qualifiers: purl.QualifiersFromMap(map[string]string{purl.Distro: "cos-101"}), 358 }, 359 }, 360 { 361 desc: "no versions set", 362 metadata: &cosmeta.Metadata{}, 363 want: &purl.PackageURL{ 364 Type: purl.TypeCOS, 365 Name: "name", 366 Version: "1.2.3", 367 Qualifiers: purl.Qualifiers{}, 368 }, 369 }, 370 } 371 for _, tt := range tests { 372 t.Run(tt.desc, func(t *testing.T) { 373 got := ospurl.MakePackageURL("name", "1.2.3", purl.TypeCOS, tt.metadata) 374 if diff := cmp.Diff(tt.want, got); diff != "" { 375 t.Errorf("ospurl.MakePackageURL(%v): unexpected PURL (-want +got):\n%s", tt.metadata, diff) 376 } 377 }) 378 } 379 } 380 381 func TestMakePackageURLRPM(t *testing.T) { 382 pkgname := "pkgname" 383 source := "source.rpm" 384 version := "1.2.3" 385 epoch := 1 386 tests := []struct { 387 desc string 388 metadata *rpmmeta.Metadata 389 want *purl.PackageURL 390 }{ 391 { 392 desc: "version_ID_and_build_ID_present", 393 metadata: &rpmmeta.Metadata{ 394 PackageName: pkgname, 395 SourceRPM: source, 396 Epoch: epoch, 397 OSID: "fedora", 398 OSVersionID: "32", 399 OSBuildID: "asdf", 400 }, 401 want: &purl.PackageURL{ 402 Type: purl.TypeRPM, 403 Name: pkgname, 404 Namespace: "fedora", 405 Version: version, 406 Qualifiers: purl.QualifiersFromMap(map[string]string{ 407 purl.Epoch: "1", 408 purl.Distro: "fedora-32", 409 purl.SourceRPM: source, 410 }), 411 }, 412 }, 413 { 414 desc: "only_build_ID_present", 415 metadata: &rpmmeta.Metadata{ 416 PackageName: pkgname, 417 SourceRPM: source, 418 Epoch: epoch, 419 OSID: "fedora", 420 OSBuildID: "asdf", 421 }, 422 want: &purl.PackageURL{ 423 Type: purl.TypeRPM, 424 Name: pkgname, 425 Namespace: "fedora", 426 Version: version, 427 Qualifiers: purl.QualifiersFromMap(map[string]string{ 428 purl.Epoch: "1", 429 purl.Distro: "fedora-asdf", 430 purl.SourceRPM: source, 431 }), 432 }, 433 }, 434 { 435 desc: "ID_missing", 436 metadata: &rpmmeta.Metadata{ 437 PackageName: pkgname, 438 SourceRPM: source, 439 Epoch: epoch, 440 OSVersionID: "32", 441 OSBuildID: "asdf", 442 }, 443 want: &purl.PackageURL{ 444 Type: purl.TypeRPM, 445 Name: pkgname, 446 Namespace: "", 447 Version: version, 448 Qualifiers: purl.QualifiersFromMap(map[string]string{ 449 purl.Epoch: "1", 450 purl.Distro: "32", 451 purl.SourceRPM: source, 452 }), 453 }, 454 }, 455 } 456 for _, tt := range tests { 457 t.Run(tt.desc, func(t *testing.T) { 458 got := ospurl.MakePackageURL(pkgname, version, purl.TypeRPM, tt.metadata) 459 if diff := cmp.Diff(tt.want, got); diff != "" { 460 t.Errorf("ospurl.MakePackageURL(%v): unexpected PURL (-want +got):\n%s", tt.metadata, diff) 461 } 462 }) 463 } 464 } 465 466 func TestMakePackageURLSnap(t *testing.T) { 467 snapName := "testSnap" 468 snapVersion := "1.2.3" 469 snapGrade := "stable" 470 snapType := "os" 471 architectures := []string{"amd64", "arm64"} 472 osID := "debian" 473 osVersionCodename := "bookworm" 474 osVersionID := "12" 475 476 tests := []struct { 477 desc string 478 metadata *snapmeta.Metadata 479 want *purl.PackageURL 480 }{ 481 { 482 desc: "Both_VERSION_CODENAME_and_VERSION_ID_are_set", 483 metadata: &snapmeta.Metadata{ 484 Name: snapName, 485 Version: snapVersion, 486 Grade: snapGrade, 487 Type: snapType, 488 Architectures: architectures, 489 OSID: osID, 490 OSVersionCodename: osVersionCodename, 491 OSVersionID: osVersionID, 492 }, 493 want: &purl.PackageURL{ 494 Type: purl.TypeSnap, 495 Name: snapName, 496 Namespace: osID, 497 Version: snapVersion, 498 Qualifiers: purl.QualifiersFromMap(map[string]string{ 499 purl.Distro: osVersionCodename, 500 }), 501 }, 502 }, 503 { 504 desc: "Only_VERSION_ID_is_set", 505 metadata: &snapmeta.Metadata{ 506 Name: snapName, 507 Version: snapVersion, 508 Grade: snapGrade, 509 Type: snapType, 510 Architectures: architectures, 511 OSID: osID, 512 OSVersionID: osVersionID, 513 }, 514 want: &purl.PackageURL{ 515 Type: purl.TypeSnap, 516 Name: snapName, 517 Namespace: osID, 518 Version: snapVersion, 519 Qualifiers: purl.QualifiersFromMap(map[string]string{ 520 purl.Distro: osVersionID, 521 }), 522 }, 523 }, 524 { 525 desc: "OSID,_VERSION_CODENAME_and_VERSION_ID_all_are_not_set", 526 metadata: &snapmeta.Metadata{ 527 Name: snapName, 528 Version: snapVersion, 529 Grade: snapGrade, 530 Type: snapType, 531 Architectures: architectures, 532 }, 533 want: &purl.PackageURL{ 534 Type: purl.TypeSnap, 535 Name: snapName, 536 Namespace: "", 537 Version: snapVersion, 538 Qualifiers: purl.QualifiersFromMap(map[string]string{}), 539 }, 540 }, 541 } 542 for _, tt := range tests { 543 t.Run(tt.desc, func(t *testing.T) { 544 got := ospurl.MakePackageURL(snapName, snapVersion, purl.TypeSnap, tt.metadata) 545 if diff := cmp.Diff(tt.want, got); diff != "" { 546 t.Errorf("ospurl.MakePackageURL(%v): unexpected PURL (-want +got):\n%s", tt.metadata, diff) 547 } 548 }) 549 } 550 } 551 552 func TestMakePackageURLPacman(t *testing.T) { 553 pkgName := "pkgName" 554 pkgVersion := "pkgVersion" 555 PackageDependencies := "pkgDependencies1, pkgDependencies2" 556 557 tests := []struct { 558 desc string 559 metadata *pacmanmeta.Metadata 560 want *purl.PackageURL 561 }{ 562 { 563 desc: "all_fields_present", 564 metadata: &pacmanmeta.Metadata{ 565 PackageName: pkgName, 566 PackageVersion: pkgVersion, 567 OSID: "arch", 568 OSVersionID: "20241201.0.284684", 569 PackageDependencies: PackageDependencies, 570 }, 571 want: &purl.PackageURL{ 572 Type: purl.TypePacman, 573 Name: pkgName, 574 Namespace: "arch", 575 Version: pkgVersion, 576 Qualifiers: purl.QualifiersFromMap(map[string]string{ 577 purl.Distro: "20241201.0.284684", 578 purl.PackageDependencies: PackageDependencies, 579 }), 580 }, 581 }, 582 { 583 desc: "only_VERSION_ID_set", 584 metadata: &pacmanmeta.Metadata{ 585 PackageName: pkgName, 586 PackageVersion: pkgVersion, 587 OSID: "arch", 588 OSVersionID: "20241201.0.284684", 589 PackageDependencies: PackageDependencies, 590 }, 591 want: &purl.PackageURL{ 592 Type: purl.TypePacman, 593 Name: pkgName, 594 Namespace: "arch", 595 Version: pkgVersion, 596 Qualifiers: purl.QualifiersFromMap(map[string]string{ 597 purl.Distro: "20241201.0.284684", 598 purl.PackageDependencies: PackageDependencies, 599 }), 600 }, 601 }, 602 { 603 desc: "OS_ID_not_set,_fallback_to_Linux", 604 metadata: &pacmanmeta.Metadata{ 605 PackageName: pkgName, 606 PackageVersion: pkgVersion, 607 OSVersionID: "20241201.0.284684", 608 PackageDependencies: PackageDependencies, 609 }, 610 want: &purl.PackageURL{ 611 Type: purl.TypePacman, 612 Name: pkgName, 613 Namespace: "linux", 614 Version: pkgVersion, 615 Qualifiers: purl.QualifiersFromMap(map[string]string{ 616 purl.Distro: "20241201.0.284684", 617 purl.PackageDependencies: PackageDependencies, 618 }), 619 }, 620 }, 621 } 622 for _, tt := range tests { 623 t.Run(tt.desc, func(t *testing.T) { 624 got := ospurl.MakePackageURL(pkgName, pkgVersion, purl.TypePacman, tt.metadata) 625 if diff := cmp.Diff(tt.want, got); diff != "" { 626 t.Errorf("ospurl.MakePackageURL(%v): unexpected PURL (-want +got):\n%s", tt.metadata, diff) 627 } 628 }) 629 } 630 } 631 632 func TestMakePackageURLPortage(t *testing.T) { 633 pkgName := "pkgName" 634 pkgVersion := "pkgVersion" 635 636 tests := []struct { 637 desc string 638 metadata *portagemeta.Metadata 639 want *purl.PackageURL 640 }{ 641 { 642 desc: "all_fields_present", 643 metadata: &portagemeta.Metadata{ 644 PackageName: pkgName, 645 PackageVersion: pkgVersion, 646 OSID: "Gentoo", 647 OSVersionID: "20241201.0.284684", 648 }, 649 want: &purl.PackageURL{ 650 Type: purl.TypePortage, 651 Name: pkgName, 652 Namespace: "Gentoo", 653 Version: pkgVersion, 654 Qualifiers: purl.QualifiersFromMap(map[string]string{ 655 purl.Distro: "20241201.0.284684", 656 }), 657 }, 658 }, 659 { 660 desc: "only_VERSION_ID_set", 661 metadata: &portagemeta.Metadata{ 662 PackageName: pkgName, 663 PackageVersion: pkgVersion, 664 OSID: "linux", 665 OSVersionID: "2.17", 666 }, 667 want: &purl.PackageURL{ 668 Type: purl.TypePortage, 669 Name: pkgName, 670 Namespace: "linux", 671 Version: pkgVersion, 672 Qualifiers: purl.QualifiersFromMap(map[string]string{ 673 purl.Distro: "2.17", 674 }), 675 }, 676 }, 677 { 678 desc: "ID_not_set,_fallback_to_linux", 679 metadata: &portagemeta.Metadata{ 680 PackageName: pkgName, 681 PackageVersion: pkgVersion, 682 OSVersionID: "jammy", 683 }, 684 want: &purl.PackageURL{ 685 Type: purl.TypePortage, 686 Name: pkgName, 687 Namespace: "linux", 688 Version: pkgVersion, 689 Qualifiers: purl.QualifiersFromMap(map[string]string{ 690 purl.Distro: "jammy", 691 }), 692 }, 693 }, 694 } 695 for _, tt := range tests { 696 t.Run(tt.desc, func(t *testing.T) { 697 got := ospurl.MakePackageURL(pkgName, pkgVersion, purl.TypePortage, tt.metadata) 698 if diff := cmp.Diff(tt.want, got); diff != "" { 699 t.Errorf("ospurl.MakePackageURL(%v): unexpected PURL (-want +got):\n%s", tt.metadata, diff) 700 } 701 }) 702 } 703 } 704 705 func TestMakePackageURLNix(t *testing.T) { 706 pkgName := "pkgName" 707 pkgVersion := "pkgVersion" 708 pkgHash := "pkgHash" 709 pkgOutput := "pkgOutput" 710 711 tests := []struct { 712 desc string 713 metadata *nixmeta.Metadata 714 want *purl.PackageURL 715 }{ 716 { 717 desc: "all_fields_present", 718 metadata: &nixmeta.Metadata{ 719 PackageName: pkgName, 720 PackageVersion: pkgVersion, 721 PackageHash: pkgHash, 722 PackageOutput: pkgOutput, 723 OSID: "nixos", 724 OSVersionCodename: "vicuna", 725 OSVersionID: "24.11", 726 }, 727 want: &purl.PackageURL{ 728 Type: purl.TypeNix, 729 Name: pkgName, 730 Version: pkgVersion, 731 Qualifiers: purl.QualifiersFromMap(map[string]string{ 732 "distro": "vicuna", 733 }), 734 }, 735 }, 736 { 737 desc: "only_VERSION_ID_set", 738 metadata: &nixmeta.Metadata{ 739 PackageName: pkgName, 740 PackageVersion: pkgVersion, 741 PackageHash: pkgHash, 742 PackageOutput: pkgOutput, 743 OSID: "nixos", 744 OSVersionID: "24.11", 745 }, 746 want: &purl.PackageURL{ 747 Type: purl.TypeNix, 748 Name: pkgName, 749 Version: pkgVersion, 750 Qualifiers: purl.QualifiersFromMap(map[string]string{ 751 "distro": "24.11", 752 }), 753 }, 754 }, 755 { 756 desc: "OS_ID_not_set,_fallback_to_Nixos", 757 metadata: &nixmeta.Metadata{ 758 PackageName: pkgName, 759 PackageVersion: pkgVersion, 760 PackageHash: pkgHash, 761 PackageOutput: pkgOutput, 762 OSVersionCodename: "vicuna", 763 OSVersionID: "24.11", 764 }, 765 want: &purl.PackageURL{ 766 Type: purl.TypeNix, 767 Name: pkgName, 768 Version: pkgVersion, 769 Qualifiers: purl.QualifiersFromMap(map[string]string{ 770 "distro": "vicuna", 771 }), 772 }, 773 }, 774 } 775 for _, tt := range tests { 776 t.Run(tt.desc, func(t *testing.T) { 777 got := ospurl.MakePackageURL(pkgName, pkgVersion, purl.TypeNix, tt.metadata) 778 if diff := cmp.Diff(tt.want, got); diff != "" { 779 t.Errorf("ospurl.MakePackageURL(%v): unexpected PURL (-want +got):\n%s", tt.metadata, diff) 780 } 781 }) 782 } 783 }