1// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 2package parser2v2 3 4import ( 5 "fmt" 6 "testing" 7 8 "github.com/spdx/tools-golang/spdx/common" 9 "github.com/spdx/tools-golang/spdx/v2_2" 10) 11 12// ===== Parser package section state change tests ===== 13func TestParser2_2PackageStartsNewPackageAfterParsingPackageNameTag(t *testing.T) { 14 // create the first package 15 pkgOldName := "p1" 16 17 parser := tvParser2_2{ 18 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 19 st: psPackage2_2, 20 pkg: &v2_2.Package{PackageName: pkgOldName, PackageSPDXIdentifier: "p1"}, 21 } 22 pkgOld := parser.pkg 23 parser.doc.Packages = append(parser.doc.Packages, pkgOld) 24 // the Document's Packages should have this one only 25 if parser.doc.Packages[0] != pkgOld { 26 t.Errorf("expected package %v, got %v", pkgOld, parser.doc.Packages[0]) 27 } 28 if len(parser.doc.Packages) != 1 { 29 t.Errorf("expected 1 package, got %d", len(parser.doc.Packages)) 30 } 31 32 // now add a new package 33 pkgName := "p2" 34 err := parser.parsePair2_2("PackageName", pkgName) 35 if err != nil { 36 t.Errorf("got error when calling parsePair2_2: %v", err) 37 } 38 // state should be correct 39 if parser.st != psPackage2_2 { 40 t.Errorf("expected state to be %v, got %v", psPackage2_2, parser.st) 41 } 42 // and a package should be created 43 if parser.pkg == nil { 44 t.Fatalf("parser didn't create new package") 45 } 46 // and it should not be pkgOld 47 if parser.pkg == pkgOld { 48 t.Errorf("expected new package, got pkgOld") 49 } 50 // and the package name should be as expected 51 if parser.pkg.PackageName != pkgName { 52 t.Errorf("expected package name %s, got %s", pkgName, parser.pkg.PackageName) 53 } 54 // and the package should default to true for FilesAnalyzed 55 if parser.pkg.FilesAnalyzed != true { 56 t.Errorf("expected FilesAnalyzed to default to true, got false") 57 } 58 if parser.pkg.IsFilesAnalyzedTagPresent != false { 59 t.Errorf("expected IsFilesAnalyzedTagPresent to default to false, got true") 60 } 61 // and the Document's Packages should still be of size 1 and have pkgOld only 62 if parser.doc.Packages[0] != pkgOld { 63 t.Errorf("Expected package %v, got %v", pkgOld, parser.doc.Packages[0]) 64 } 65 if len(parser.doc.Packages) != 1 { 66 t.Errorf("expected 1 package, got %d", len(parser.doc.Packages)) 67 } 68} 69 70func TestParser2_2PackageStartsNewPackageAfterParsingPackageNameTagWhileInUnpackaged(t *testing.T) { 71 // pkg is nil, so that Files appearing before the first PackageName tag 72 // are added to Files instead of Packages 73 parser := tvParser2_2{ 74 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 75 st: psFile2_2, 76 pkg: nil, 77 } 78 // the Document's Packages should be empty 79 if len(parser.doc.Packages) != 0 { 80 t.Errorf("Expected zero packages, got %d", len(parser.doc.Packages)) 81 } 82 83 // now add a new package 84 pkgName := "p2" 85 err := parser.parsePair2_2("PackageName", pkgName) 86 if err != nil { 87 t.Errorf("got error when calling parsePair2_2: %v", err) 88 } 89 // state should be correct 90 if parser.st != psPackage2_2 { 91 t.Errorf("expected state to be %v, got %v", psPackage2_2, parser.st) 92 } 93 // and a package should be created 94 if parser.pkg == nil { 95 t.Fatalf("parser didn't create new package") 96 } 97 // and the package name should be as expected 98 if parser.pkg.PackageName != pkgName { 99 t.Errorf("expected package name %s, got %s", pkgName, parser.pkg.PackageName) 100 } 101 // and the package should default to true for FilesAnalyzed 102 if parser.pkg.FilesAnalyzed != true { 103 t.Errorf("expected FilesAnalyzed to default to true, got false") 104 } 105 if parser.pkg.IsFilesAnalyzedTagPresent != false { 106 t.Errorf("expected IsFilesAnalyzedTagPresent to default to false, got true") 107 } 108 // and the Document's Packages should be of size 0, because the prior was 109 // unpackaged files and this one won't be added until an SPDXID is seen 110 if len(parser.doc.Packages) != 0 { 111 t.Errorf("Expected %v packages in doc, got %v", 0, len(parser.doc.Packages)) 112 } 113} 114 115func TestParser2_2PackageMovesToFileAfterParsingFileNameTag(t *testing.T) { 116 parser := tvParser2_2{ 117 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 118 st: psPackage2_2, 119 pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 120 } 121 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 122 pkgCurrent := parser.pkg 123 124 err := parser.parsePair2_2("FileName", "testFile") 125 if err != nil { 126 t.Errorf("got error when calling parsePair2_2: %v", err) 127 } 128 // state should be correct 129 if parser.st != psFile2_2 { 130 t.Errorf("expected state to be %v, got %v", psFile2_2, parser.st) 131 } 132 // and current package should remain what it was 133 if parser.pkg != pkgCurrent { 134 t.Fatalf("expected package to remain %v, got %v", pkgCurrent, parser.pkg) 135 } 136} 137 138func TestParser2_2PackageMovesToOtherLicenseAfterParsingLicenseIDTag(t *testing.T) { 139 parser := tvParser2_2{ 140 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 141 st: psPackage2_2, 142 pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 143 } 144 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 145 146 err := parser.parsePair2_2("LicenseID", "LicenseRef-TestLic") 147 if err != nil { 148 t.Errorf("got error when calling parsePair2_2: %v", err) 149 } 150 if parser.st != psOtherLicense2_2 { 151 t.Errorf("expected state to be %v, got %v", psOtherLicense2_2, parser.st) 152 } 153} 154 155func TestParser2_2PackageMovesToReviewAfterParsingReviewerTag(t *testing.T) { 156 parser := tvParser2_2{ 157 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 158 st: psPackage2_2, 159 pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 160 } 161 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 162 163 err := parser.parsePair2_2("Reviewer", "Person: John Doe") 164 if err != nil { 165 t.Errorf("got error when calling parsePair2_2: %v", err) 166 } 167 if parser.st != psReview2_2 { 168 t.Errorf("expected state to be %v, got %v", psReview2_2, parser.st) 169 } 170} 171 172func TestParser2_2PackageStaysAfterParsingRelationshipTags(t *testing.T) { 173 parser := tvParser2_2{ 174 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 175 st: psPackage2_2, 176 pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 177 } 178 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 179 180 err := parser.parsePair2_2("Relationship", "SPDXRef-blah CONTAINS SPDXRef-blah-else") 181 if err != nil { 182 t.Errorf("got error when calling parsePair2_2: %v", err) 183 } 184 // state should remain unchanged 185 if parser.st != psPackage2_2 { 186 t.Errorf("expected state to be %v, got %v", psPackage2_2, parser.st) 187 } 188 189 err = parser.parsePair2_2("RelationshipComment", "blah") 190 if err != nil { 191 t.Errorf("got error when calling parsePair2_2: %v", err) 192 } 193 // state should still remain unchanged 194 if parser.st != psPackage2_2 { 195 t.Errorf("expected state to be %v, got %v", psPackage2_2, parser.st) 196 } 197} 198 199func TestParser2_2PackageStaysAfterParsingAnnotationTags(t *testing.T) { 200 parser := tvParser2_2{ 201 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 202 st: psPackage2_2, 203 pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 204 } 205 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 206 207 err := parser.parsePair2_2("Annotator", "Person: John Doe ()") 208 if err != nil { 209 t.Errorf("got error when calling parsePair2_2: %v", err) 210 } 211 if parser.st != psPackage2_2 { 212 t.Errorf("parser is in state %v, expected %v", parser.st, psPackage2_2) 213 } 214 215 err = parser.parsePair2_2("AnnotationDate", "2018-09-15T00:36:00Z") 216 if err != nil { 217 t.Errorf("got error when calling parsePair2_2: %v", err) 218 } 219 if parser.st != psPackage2_2 { 220 t.Errorf("parser is in state %v, expected %v", parser.st, psPackage2_2) 221 } 222 223 err = parser.parsePair2_2("AnnotationType", "REVIEW") 224 if err != nil { 225 t.Errorf("got error when calling parsePair2_2: %v", err) 226 } 227 if parser.st != psPackage2_2 { 228 t.Errorf("parser is in state %v, expected %v", parser.st, psPackage2_2) 229 } 230 231 err = parser.parsePair2_2("SPDXREF", "SPDXRef-45") 232 if err != nil { 233 t.Errorf("got error when calling parsePair2_2: %v", err) 234 } 235 if parser.st != psPackage2_2 { 236 t.Errorf("parser is in state %v, expected %v", parser.st, psPackage2_2) 237 } 238 239 err = parser.parsePair2_2("AnnotationComment", "i guess i had something to say about this package") 240 if err != nil { 241 t.Errorf("got error when calling parsePair2_2: %v", err) 242 } 243 if parser.st != psPackage2_2 { 244 t.Errorf("parser is in state %v, expected %v", parser.st, psPackage2_2) 245 } 246} 247 248// ===== Package data section tests ===== 249func TestParser2_2CanParsePackageTags(t *testing.T) { 250 parser := tvParser2_2{ 251 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 252 st: psPackage2_2, 253 pkg: &v2_2.Package{}, 254 } 255 256 // should not yet be in Packages map, b/c no SPDX identifier 257 if len(parser.doc.Packages) != 0 { 258 t.Errorf("expected 0 packages, got %d", len(parser.doc.Packages)) 259 } 260 261 // Package Name 262 err := parser.parsePairFromPackage2_2("PackageName", "p1") 263 if err != nil { 264 t.Errorf("expected nil error, got %v", err) 265 } 266 if parser.pkg.PackageName != "p1" { 267 t.Errorf("got %v for PackageName", parser.pkg.PackageName) 268 } 269 // still should not yet be in Packages map, b/c no SPDX identifier 270 if len(parser.doc.Packages) != 0 { 271 t.Errorf("expected 0 packages, got %d", len(parser.doc.Packages)) 272 } 273 274 // Package SPDX Identifier 275 err = parser.parsePairFromPackage2_2("SPDXID", "SPDXRef-p1") 276 if err != nil { 277 t.Errorf("expected nil error, got %v", err) 278 } 279 // "SPDXRef-" prefix should be removed from the item 280 if parser.pkg.PackageSPDXIdentifier != "p1" { 281 t.Errorf("got %v for PackageSPDXIdentifier", parser.pkg.PackageSPDXIdentifier) 282 } 283 // and it should now be added to the Packages map 284 if len(parser.doc.Packages) != 1 { 285 t.Errorf("expected 1 package, got %d", len(parser.doc.Packages)) 286 } 287 if parser.doc.Packages[0] != parser.pkg { 288 t.Errorf("expected to point to parser.pkg, got %v", parser.doc.Packages[0]) 289 } 290 291 // Package Version 292 err = parser.parsePairFromPackage2_2("PackageVersion", "2.1.1") 293 if err != nil { 294 t.Errorf("expected nil error, got %v", err) 295 } 296 if parser.pkg.PackageVersion != "2.1.1" { 297 t.Errorf("got %v for PackageVersion", parser.pkg.PackageVersion) 298 } 299 300 // Package File Name 301 err = parser.parsePairFromPackage2_2("PackageFileName", "p1-2.1.1.tar.gz") 302 if err != nil { 303 t.Errorf("expected nil error, got %v", err) 304 } 305 if parser.pkg.PackageFileName != "p1-2.1.1.tar.gz" { 306 t.Errorf("got %v for PackageFileName", parser.pkg.PackageFileName) 307 } 308 309 // Package Supplier 310 // SKIP -- separate tests for subvalues below 311 312 // Package Originator 313 // SKIP -- separate tests for subvalues below 314 315 // Package Download Location 316 err = parser.parsePairFromPackage2_2("PackageDownloadLocation", "https://example.com/whatever") 317 if err != nil { 318 t.Errorf("expected nil error, got %v", err) 319 } 320 if parser.pkg.PackageDownloadLocation != "https://example.com/whatever" { 321 t.Errorf("got %v for PackageDownloadLocation", parser.pkg.PackageDownloadLocation) 322 } 323 324 // Files Analyzed 325 err = parser.parsePairFromPackage2_2("FilesAnalyzed", "false") 326 if err != nil { 327 t.Errorf("expected nil error, got %v", err) 328 } 329 if parser.pkg.FilesAnalyzed != false { 330 t.Errorf("got %v for FilesAnalyzed", parser.pkg.FilesAnalyzed) 331 } 332 if parser.pkg.IsFilesAnalyzedTagPresent != true { 333 t.Errorf("got %v for IsFilesAnalyzedTagPresent", parser.pkg.IsFilesAnalyzedTagPresent) 334 } 335 336 // Package Verification Code 337 // SKIP -- separate tests for "excludes", or not, below 338 339 testChecksums := map[common.ChecksumAlgorithm]string{ 340 "MD5": "624c1abb3664f4b35547e7c73864ad24", 341 "SHA1": "85ed0817af83a24ad8da68c2b5094de69833983c", 342 "SHA256": "11b6d3ee554eedf79299905a98f9b9a04e498210b59f15094c916c91d150efcd", 343 "SHA512": "4ced3267f5ed38df65ceebc43e97aa6c2948cc7ef3288c2e5074e7df7fab544cc93339604513ea5f65616f9ed1c48581465043c8a9b693ef20fd4fddaf25e1b9", 344 } 345 346 for algo, tc := range testChecksums { 347 if err := parser.parsePairFromPackage2_2( 348 "PackageChecksum", fmt.Sprintf("%s: %s", algo, tc)); err != nil { 349 t.Errorf("expected error, got %v", err) 350 } 351 } 352 353 for _, checksum := range parser.pkg.PackageChecksums { 354 if checksum.Value != testChecksums[checksum.Algorithm] { 355 t.Errorf( 356 "expected %s for PackageChecksum%s, got %s", 357 testChecksums[checksum.Algorithm], checksum.Algorithm, checksum.Value, 358 ) 359 } 360 } 361 362 // Package Home Page 363 err = parser.parsePairFromPackage2_2("PackageHomePage", "https://example.com/whatever2") 364 if err != nil { 365 t.Errorf("expected nil error, got %v", err) 366 } 367 if parser.pkg.PackageHomePage != "https://example.com/whatever2" { 368 t.Errorf("got %v for PackageHomePage", parser.pkg.PackageHomePage) 369 } 370 371 // Package Source Info 372 err = parser.parsePairFromPackage2_2("PackageSourceInfo", "random comment") 373 if err != nil { 374 t.Errorf("expected nil error, got %v", err) 375 } 376 if parser.pkg.PackageSourceInfo != "random comment" { 377 t.Errorf("got %v for PackageSourceInfo", parser.pkg.PackageSourceInfo) 378 } 379 380 // Package License Concluded 381 err = parser.parsePairFromPackage2_2("PackageLicenseConcluded", "Apache-2.0 OR GPL-2.0-or-later") 382 if err != nil { 383 t.Errorf("expected nil error, got %v", err) 384 } 385 if parser.pkg.PackageLicenseConcluded != "Apache-2.0 OR GPL-2.0-or-later" { 386 t.Errorf("got %v for PackageLicenseConcluded", parser.pkg.PackageLicenseConcluded) 387 } 388 389 // All Licenses Info From Files 390 lics := []string{ 391 "Apache-2.0", 392 "GPL-2.0-or-later", 393 "CC0-1.0", 394 } 395 for _, lic := range lics { 396 err = parser.parsePairFromPackage2_2("PackageLicenseInfoFromFiles", lic) 397 if err != nil { 398 t.Errorf("expected nil error, got %v", err) 399 } 400 } 401 for _, licWant := range lics { 402 flagFound := false 403 for _, licCheck := range parser.pkg.PackageLicenseInfoFromFiles { 404 if licWant == licCheck { 405 flagFound = true 406 } 407 } 408 if flagFound == false { 409 t.Errorf("didn't find %s in PackageLicenseInfoFromFiles", licWant) 410 } 411 } 412 if len(lics) != len(parser.pkg.PackageLicenseInfoFromFiles) { 413 t.Errorf("expected %d licenses in PackageLicenseInfoFromFiles, got %d", len(lics), 414 len(parser.pkg.PackageLicenseInfoFromFiles)) 415 } 416 417 // Package License Declared 418 err = parser.parsePairFromPackage2_2("PackageLicenseDeclared", "Apache-2.0 OR GPL-2.0-or-later") 419 if err != nil { 420 t.Errorf("expected nil error, got %v", err) 421 } 422 if parser.pkg.PackageLicenseDeclared != "Apache-2.0 OR GPL-2.0-or-later" { 423 t.Errorf("got %v for PackageLicenseDeclared", parser.pkg.PackageLicenseDeclared) 424 } 425 426 // Package License Comments 427 err = parser.parsePairFromPackage2_2("PackageLicenseComments", "this is a license comment") 428 if err != nil { 429 t.Errorf("expected nil error, got %v", err) 430 } 431 if parser.pkg.PackageLicenseComments != "this is a license comment" { 432 t.Errorf("got %v for PackageLicenseComments", parser.pkg.PackageLicenseComments) 433 } 434 435 // Package Copyright Text 436 err = parser.parsePairFromPackage2_2("PackageCopyrightText", "Copyright (c) me myself and i") 437 if err != nil { 438 t.Errorf("expected nil error, got %v", err) 439 } 440 if parser.pkg.PackageCopyrightText != "Copyright (c) me myself and i" { 441 t.Errorf("got %v for PackageCopyrightText", parser.pkg.PackageCopyrightText) 442 } 443 444 // Package Summary 445 err = parser.parsePairFromPackage2_2("PackageSummary", "i wrote this package") 446 if err != nil { 447 t.Errorf("expected nil error, got %v", err) 448 } 449 if parser.pkg.PackageSummary != "i wrote this package" { 450 t.Errorf("got %v for PackageSummary", parser.pkg.PackageSummary) 451 } 452 453 // Package Description 454 err = parser.parsePairFromPackage2_2("PackageDescription", "i wrote this package a lot") 455 if err != nil { 456 t.Errorf("expected nil error, got %v", err) 457 } 458 if parser.pkg.PackageDescription != "i wrote this package a lot" { 459 t.Errorf("got %v for PackageDescription", parser.pkg.PackageDescription) 460 } 461 462 // Package Comment 463 err = parser.parsePairFromPackage2_2("PackageComment", "i scanned this package") 464 if err != nil { 465 t.Errorf("expected nil error, got %v", err) 466 } 467 if parser.pkg.PackageComment != "i scanned this package" { 468 t.Errorf("got %v for PackageComment", parser.pkg.PackageComment) 469 } 470 471 // Package Attribution Text 472 attrs := []string{ 473 "Include this notice in all advertising materials", 474 "This is a \nmulti-line string", 475 } 476 for _, attr := range attrs { 477 err = parser.parsePairFromPackage2_2("PackageAttributionText", attr) 478 if err != nil { 479 t.Errorf("expected nil error, got %v", err) 480 } 481 } 482 for _, attrWant := range attrs { 483 flagFound := false 484 for _, attrCheck := range parser.pkg.PackageAttributionTexts { 485 if attrWant == attrCheck { 486 flagFound = true 487 } 488 } 489 if flagFound == false { 490 t.Errorf("didn't find %s in PackageAttributionText", attrWant) 491 } 492 } 493 if len(attrs) != len(parser.pkg.PackageAttributionTexts) { 494 t.Errorf("expected %d attribution texts in PackageAttributionTexts, got %d", len(attrs), 495 len(parser.pkg.PackageAttributionTexts)) 496 } 497 498 // Package External References and Comments 499 ref1 := "SECURITY cpe23Type cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*" 500 ref1Category := "SECURITY" 501 ref1Type := "cpe23Type" 502 ref1Locator := "cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*" 503 ref1Comment := "this is comment #1" 504 ref2 := "OTHER LocationRef-acmeforge acmecorp/acmenator/4.1.3alpha" 505 ref2Category := "OTHER" 506 ref2Type := "LocationRef-acmeforge" 507 ref2Locator := "acmecorp/acmenator/4.1.3alpha" 508 ref2Comment := "this is comment #2" 509 err = parser.parsePairFromPackage2_2("ExternalRef", ref1) 510 if err != nil { 511 t.Errorf("expected nil error, got %v", err) 512 } 513 if len(parser.pkg.PackageExternalReferences) != 1 { 514 t.Errorf("expected 1 external reference, got %d", len(parser.pkg.PackageExternalReferences)) 515 } 516 if parser.pkgExtRef == nil { 517 t.Errorf("expected non-nil pkgExtRef, got nil") 518 } 519 if parser.pkg.PackageExternalReferences[0] == nil { 520 t.Errorf("expected non-nil PackageExternalReferences[0], got nil") 521 } 522 if parser.pkgExtRef != parser.pkg.PackageExternalReferences[0] { 523 t.Errorf("expected pkgExtRef to match PackageExternalReferences[0], got no match") 524 } 525 err = parser.parsePairFromPackage2_2("ExternalRefComment", ref1Comment) 526 if err != nil { 527 t.Errorf("expected nil error, got %v", err) 528 } 529 err = parser.parsePairFromPackage2_2("ExternalRef", ref2) 530 if err != nil { 531 t.Errorf("expected nil error, got %v", err) 532 } 533 if len(parser.pkg.PackageExternalReferences) != 2 { 534 t.Errorf("expected 2 external references, got %d", len(parser.pkg.PackageExternalReferences)) 535 } 536 if parser.pkgExtRef == nil { 537 t.Errorf("expected non-nil pkgExtRef, got nil") 538 } 539 if parser.pkg.PackageExternalReferences[1] == nil { 540 t.Errorf("expected non-nil PackageExternalReferences[1], got nil") 541 } 542 if parser.pkgExtRef != parser.pkg.PackageExternalReferences[1] { 543 t.Errorf("expected pkgExtRef to match PackageExternalReferences[1], got no match") 544 } 545 err = parser.parsePairFromPackage2_2("ExternalRefComment", ref2Comment) 546 if err != nil { 547 t.Errorf("expected nil error, got %v", err) 548 } 549 // finally, check these values 550 gotRef1 := parser.pkg.PackageExternalReferences[0] 551 if gotRef1.Category != ref1Category { 552 t.Errorf("expected ref1 category to be %s, got %s", gotRef1.Category, ref1Category) 553 } 554 if gotRef1.RefType != ref1Type { 555 t.Errorf("expected ref1 type to be %s, got %s", gotRef1.RefType, ref1Type) 556 } 557 if gotRef1.Locator != ref1Locator { 558 t.Errorf("expected ref1 locator to be %s, got %s", gotRef1.Locator, ref1Locator) 559 } 560 if gotRef1.ExternalRefComment != ref1Comment { 561 t.Errorf("expected ref1 comment to be %s, got %s", gotRef1.ExternalRefComment, ref1Comment) 562 } 563 gotRef2 := parser.pkg.PackageExternalReferences[1] 564 if gotRef2.Category != ref2Category { 565 t.Errorf("expected ref2 category to be %s, got %s", gotRef2.Category, ref2Category) 566 } 567 if gotRef2.RefType != ref2Type { 568 t.Errorf("expected ref2 type to be %s, got %s", gotRef2.RefType, ref2Type) 569 } 570 if gotRef2.Locator != ref2Locator { 571 t.Errorf("expected ref2 locator to be %s, got %s", gotRef2.Locator, ref2Locator) 572 } 573 if gotRef2.ExternalRefComment != ref2Comment { 574 t.Errorf("expected ref2 comment to be %s, got %s", gotRef2.ExternalRefComment, ref2Comment) 575 } 576 577} 578 579func TestParser2_2CanParsePackageSupplierPersonTag(t *testing.T) { 580 parser := tvParser2_2{ 581 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 582 st: psPackage2_2, 583 pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 584 } 585 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 586 587 // Package Supplier: Person 588 err := parser.parsePairFromPackage2_2("PackageSupplier", "Person: John Doe") 589 if err != nil { 590 t.Errorf("expected nil error, got %v", err) 591 } 592 if parser.pkg.PackageSupplier.Supplier != "John Doe" { 593 t.Errorf("got %v for PackageSupplierPerson", parser.pkg.PackageSupplier.Supplier) 594 } 595} 596 597func TestParser2_2CanParsePackageSupplierOrganizationTag(t *testing.T) { 598 parser := tvParser2_2{ 599 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 600 st: psPackage2_2, 601 pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 602 } 603 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 604 605 // Package Supplier: Organization 606 err := parser.parsePairFromPackage2_2("PackageSupplier", "Organization: John Doe, Inc.") 607 if err != nil { 608 t.Errorf("expected nil error, got %v", err) 609 } 610 if parser.pkg.PackageSupplier.Supplier != "John Doe, Inc." { 611 t.Errorf("got %v for PackageSupplierOrganization", parser.pkg.PackageSupplier.Supplier) 612 } 613} 614 615func TestParser2_2CanParsePackageSupplierNOASSERTIONTag(t *testing.T) { 616 parser := tvParser2_2{ 617 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 618 st: psPackage2_2, 619 pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 620 } 621 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 622 623 // Package Supplier: NOASSERTION 624 err := parser.parsePairFromPackage2_2("PackageSupplier", "NOASSERTION") 625 if err != nil { 626 t.Errorf("expected nil error, got %v", err) 627 } 628 if parser.pkg.PackageSupplier.Supplier != "NOASSERTION" { 629 t.Errorf("got value for Supplier, expected NOASSERTION") 630 } 631} 632 633func TestParser2_2CanParsePackageOriginatorPersonTag(t *testing.T) { 634 parser := tvParser2_2{ 635 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 636 st: psPackage2_2, 637 pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 638 } 639 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 640 641 // Package Originator: Person 642 err := parser.parsePairFromPackage2_2("PackageOriginator", "Person: John Doe") 643 if err != nil { 644 t.Errorf("expected nil error, got %v", err) 645 } 646 if parser.pkg.PackageOriginator.Originator != "John Doe" { 647 t.Errorf("got %v for PackageOriginator", parser.pkg.PackageOriginator.Originator) 648 } 649} 650 651func TestParser2_2CanParsePackageOriginatorOrganizationTag(t *testing.T) { 652 parser := tvParser2_2{ 653 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 654 st: psPackage2_2, 655 pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 656 } 657 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 658 659 // Package Originator: Organization 660 err := parser.parsePairFromPackage2_2("PackageOriginator", "Organization: John Doe, Inc.") 661 if err != nil { 662 t.Errorf("expected nil error, got %v", err) 663 } 664 if parser.pkg.PackageOriginator.Originator != "John Doe, Inc." { 665 t.Errorf("got %v for PackageOriginator", parser.pkg.PackageOriginator.Originator) 666 } 667} 668 669func TestParser2_2CanParsePackageOriginatorNOASSERTIONTag(t *testing.T) { 670 parser := tvParser2_2{ 671 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 672 st: psPackage2_2, 673 pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 674 } 675 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 676 677 // Package Originator: NOASSERTION 678 err := parser.parsePairFromPackage2_2("PackageOriginator", "NOASSERTION") 679 if err != nil { 680 t.Errorf("expected nil error, got %v", err) 681 } 682 if parser.pkg.PackageOriginator.Originator != "NOASSERTION" { 683 t.Errorf("got false for PackageOriginatorNOASSERTION") 684 } 685} 686 687func TestParser2_2CanParsePackageVerificationCodeTagWithExcludes(t *testing.T) { 688 parser := tvParser2_2{ 689 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 690 st: psPackage2_2, 691 pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 692 } 693 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 694 695 // Package Verification Code with excludes parenthetical 696 code := "d6a770ba38583ed4bb4525bd96e50461655d2758" 697 fileName := "./package.spdx" 698 fullCodeValue := "d6a770ba38583ed4bb4525bd96e50461655d2758 (excludes: ./package.spdx)" 699 err := parser.parsePairFromPackage2_2("PackageVerificationCode", fullCodeValue) 700 if err != nil { 701 t.Errorf("expected nil error, got %v", err) 702 } 703 if parser.pkg.PackageVerificationCode.Value != code { 704 t.Errorf("got %v for PackageVerificationCode", parser.pkg.PackageVerificationCode) 705 } 706 if len(parser.pkg.PackageVerificationCode.ExcludedFiles) != 1 || parser.pkg.PackageVerificationCode.ExcludedFiles[0] != fileName { 707 t.Errorf("got %v for PackageVerificationCodeExcludedFile", parser.pkg.PackageVerificationCode.ExcludedFiles) 708 } 709 710} 711 712func TestParser2_2CanParsePackageVerificationCodeTagWithoutExcludes(t *testing.T) { 713 parser := tvParser2_2{ 714 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 715 st: psPackage2_2, 716 pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 717 } 718 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 719 720 // Package Verification Code without excludes parenthetical 721 code := "d6a770ba38583ed4bb4525bd96e50461655d2758" 722 err := parser.parsePairFromPackage2_2("PackageVerificationCode", code) 723 if err != nil { 724 t.Errorf("expected nil error, got %v", err) 725 } 726 if parser.pkg.PackageVerificationCode.Value != code { 727 t.Errorf("got %v for PackageVerificationCode", parser.pkg.PackageVerificationCode) 728 } 729 if len(parser.pkg.PackageVerificationCode.ExcludedFiles) != 0 { 730 t.Errorf("got %v for PackageVerificationCodeExcludedFile", parser.pkg.PackageVerificationCode.ExcludedFiles) 731 } 732 733} 734 735func TestParser2_2PackageExternalRefPointerChangesAfterTags(t *testing.T) { 736 parser := tvParser2_2{ 737 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 738 st: psPackage2_2, 739 pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 740 } 741 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 742 743 ref1 := "SECURITY cpe23Type cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*" 744 err := parser.parsePairFromPackage2_2("ExternalRef", ref1) 745 if err != nil { 746 t.Errorf("expected nil error, got %v", err) 747 } 748 if parser.pkgExtRef == nil { 749 t.Errorf("expected non-nil external reference pointer, got nil") 750 } 751 752 // now, a comment; pointer should go away 753 err = parser.parsePairFromPackage2_2("ExternalRefComment", "whatever") 754 if err != nil { 755 t.Errorf("expected nil error, got %v", err) 756 } 757 if parser.pkgExtRef != nil { 758 t.Errorf("expected nil external reference pointer, got non-nil") 759 } 760 761 ref2 := "Other LocationRef-something https://example.com/whatever" 762 err = parser.parsePairFromPackage2_2("ExternalRef", ref2) 763 if err != nil { 764 t.Errorf("expected nil error, got %v", err) 765 } 766 if parser.pkgExtRef == nil { 767 t.Errorf("expected non-nil external reference pointer, got nil") 768 } 769 770 // and some other random tag makes the pointer go away too 771 err = parser.parsePairFromPackage2_2("PackageSummary", "whatever") 772 if err != nil { 773 t.Errorf("expected nil error, got %v", err) 774 } 775 if parser.pkgExtRef != nil { 776 t.Errorf("expected nil external reference pointer, got non-nil") 777 } 778} 779 780func TestParser2_2PackageCreatesRelationshipInDocument(t *testing.T) { 781 parser := tvParser2_2{ 782 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 783 st: psPackage2_2, 784 pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 785 } 786 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 787 788 err := parser.parsePair2_2("Relationship", "SPDXRef-blah CONTAINS SPDXRef-blah-whatever") 789 if err != nil { 790 t.Errorf("got error when calling parsePair2_2: %v", err) 791 } 792 if parser.rln == nil { 793 t.Fatalf("parser didn't create and point to Relationship struct") 794 } 795 if parser.rln != parser.doc.Relationships[0] { 796 t.Errorf("pointer to new Relationship doesn't match idx 0 for doc.Relationships[]") 797 } 798} 799 800func TestParser2_2PackageCreatesAnnotationInDocument(t *testing.T) { 801 parser := tvParser2_2{ 802 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 803 st: psPackage2_2, 804 pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 805 } 806 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 807 808 err := parser.parsePair2_2("Annotator", "Person: John Doe ()") 809 if err != nil { 810 t.Errorf("got error when calling parsePair2_2: %v", err) 811 } 812 if parser.ann == nil { 813 t.Fatalf("parser didn't create and point to Annotation struct") 814 } 815 if parser.ann != parser.doc.Annotations[0] { 816 t.Errorf("pointer to new Annotation doesn't match idx 0 for doc.Annotations[]") 817 } 818} 819 820func TestParser2_2PackageUnknownTagFails(t *testing.T) { 821 parser := tvParser2_2{ 822 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 823 st: psPackage2_2, 824 pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 825 } 826 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 827 828 err := parser.parsePairFromPackage2_2("blah", "something") 829 if err == nil { 830 t.Errorf("expected error from parsing unknown tag") 831 } 832} 833 834func TestParser2_2FailsIfInvalidSPDXIDInPackageSection(t *testing.T) { 835 parser := tvParser2_2{ 836 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 837 st: psPackage2_2, 838 pkg: &v2_2.Package{}, 839 } 840 841 // start with Package Name 842 err := parser.parsePairFromPackage2_2("PackageName", "p1") 843 if err != nil { 844 t.Errorf("expected nil error, got %v", err) 845 } 846 // invalid ID format 847 err = parser.parsePairFromPackage2_2("SPDXID", "whoops") 848 if err == nil { 849 t.Errorf("expected non-nil error, got nil") 850 } 851} 852 853func TestParser2_2FailsIfInvalidPackageSupplierFormat(t *testing.T) { 854 parser := tvParser2_2{ 855 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 856 st: psPackage2_2, 857 pkg: &v2_2.Package{}, 858 } 859 860 // start with Package Name 861 err := parser.parsePairFromPackage2_2("PackageName", "p1") 862 if err != nil { 863 t.Errorf("expected nil error, got %v", err) 864 } 865 // invalid supplier format 866 err = parser.parsePairFromPackage2_2("PackageSupplier", "whoops") 867 if err == nil { 868 t.Errorf("expected non-nil error, got nil") 869 } 870} 871 872func TestParser2_2FailsIfUnknownPackageSupplierType(t *testing.T) { 873 parser := tvParser2_2{ 874 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 875 st: psPackage2_2, 876 pkg: &v2_2.Package{}, 877 } 878 879 // start with Package Name 880 err := parser.parsePairFromPackage2_2("PackageName", "p1") 881 if err != nil { 882 t.Errorf("expected nil error, got %v", err) 883 } 884 // invalid supplier type 885 err = parser.parsePairFromPackage2_2("PackageSupplier", "whoops: John Doe") 886 if err == nil { 887 t.Errorf("expected non-nil error, got nil") 888 } 889} 890 891func TestParser2_2FailsIfInvalidPackageOriginatorFormat(t *testing.T) { 892 parser := tvParser2_2{ 893 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 894 st: psPackage2_2, 895 pkg: &v2_2.Package{}, 896 } 897 898 // start with Package Name 899 err := parser.parsePairFromPackage2_2("PackageName", "p1") 900 if err != nil { 901 t.Errorf("expected nil error, got %v", err) 902 } 903 // invalid originator format 904 err = parser.parsePairFromPackage2_2("PackageOriginator", "whoops") 905 if err == nil { 906 t.Errorf("expected non-nil error, got nil") 907 } 908} 909 910func TestParser2_2FailsIfUnknownPackageOriginatorType(t *testing.T) { 911 parser := tvParser2_2{ 912 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 913 st: psPackage2_2, 914 pkg: &v2_2.Package{}, 915 } 916 917 // start with Package Name 918 err := parser.parsePairFromPackage2_2("PackageName", "p1") 919 if err != nil { 920 t.Errorf("expected nil error, got %v", err) 921 } 922 // invalid originator type 923 err = parser.parsePairFromPackage2_2("PackageOriginator", "whoops: John Doe") 924 if err == nil { 925 t.Errorf("expected non-nil error, got nil") 926 } 927} 928 929func TestParser2_2SetsFilesAnalyzedTagsCorrectly(t *testing.T) { 930 parser := tvParser2_2{ 931 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 932 st: psPackage2_2, 933 pkg: &v2_2.Package{}, 934 } 935 936 // start with Package Name 937 err := parser.parsePairFromPackage2_2("PackageName", "p1") 938 if err != nil { 939 t.Errorf("expected nil error, got %v", err) 940 } 941 // set tag 942 err = parser.parsePairFromPackage2_2("FilesAnalyzed", "true") 943 if err != nil { 944 t.Errorf("expected nil error, got %v", err) 945 } 946 if parser.pkg.FilesAnalyzed != true { 947 t.Errorf("expected %v, got %v", true, parser.pkg.FilesAnalyzed) 948 } 949 if parser.pkg.IsFilesAnalyzedTagPresent != true { 950 t.Errorf("expected %v, got %v", true, parser.pkg.IsFilesAnalyzedTagPresent) 951 } 952} 953 954func TestParser2_2FailsIfInvalidPackageChecksumFormat(t *testing.T) { 955 parser := tvParser2_2{ 956 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 957 st: psPackage2_2, 958 pkg: &v2_2.Package{}, 959 } 960 961 // start with Package Name 962 err := parser.parsePairFromPackage2_2("PackageName", "p1") 963 if err != nil { 964 t.Errorf("expected nil error, got %v", err) 965 } 966 // invalid checksum format 967 err = parser.parsePairFromPackage2_2("PackageChecksum", "whoops") 968 if err == nil { 969 t.Errorf("expected non-nil error, got nil") 970 } 971} 972 973func TestParser2_2FailsIfInvalidPackageChecksumType(t *testing.T) { 974 parser := tvParser2_2{ 975 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 976 st: psPackage2_2, 977 pkg: &v2_2.Package{}, 978 } 979 980 // start with Package Name 981 err := parser.parsePairFromPackage2_2("PackageName", "p1") 982 if err != nil { 983 t.Errorf("expected nil error, got %v", err) 984 } 985 // invalid checksum type 986 err = parser.parsePairFromPackage2_2("PackageChecksum", "whoops: blah") 987 if err == nil { 988 t.Errorf("expected non-nil error, got nil") 989 } 990} 991 992func TestParser2_2FailsIfInvalidExternalRefFormat(t *testing.T) { 993 parser := tvParser2_2{ 994 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 995 st: psPackage2_2, 996 pkg: &v2_2.Package{}, 997 } 998 999 // start with Package Name 1000 err := parser.parsePairFromPackage2_2("PackageName", "p1") 1001 if err != nil { 1002 t.Errorf("expected nil error, got %v", err) 1003 } 1004 // invalid external ref format 1005 err = parser.parsePairFromPackage2_2("ExternalRef", "whoops") 1006 if err == nil { 1007 t.Errorf("expected non-nil error, got nil") 1008 } 1009} 1010 1011func TestParser2_2FailsIfExternalRefCommentBeforeExternalRef(t *testing.T) { 1012 parser := tvParser2_2{ 1013 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 1014 st: psPackage2_2, 1015 pkg: &v2_2.Package{}, 1016 } 1017 1018 // start with Package Name 1019 err := parser.parsePairFromPackage2_2("PackageName", "p1") 1020 if err != nil { 1021 t.Errorf("expected nil error, got %v", err) 1022 } 1023 // external ref comment before external ref 1024 err = parser.parsePairFromPackage2_2("ExternalRefComment", "whoops") 1025 if err == nil { 1026 t.Errorf("expected non-nil error, got nil") 1027 } 1028} 1029 1030// ===== Helper function tests ===== 1031 1032func TestCanCheckAndExtractExcludesFilenameAndCode(t *testing.T) { 1033 code := "d6a770ba38583ed4bb4525bd96e50461655d2758" 1034 fileName := "./package.spdx" 1035 fullCodeValue := "d6a770ba38583ed4bb4525bd96e50461655d2758 (excludes: ./package.spdx)" 1036 1037 gotCode := extractCodeAndExcludes(fullCodeValue) 1038 if gotCode.Value != code { 1039 t.Errorf("got %v for gotCode", gotCode) 1040 } 1041 if len(gotCode.ExcludedFiles) != 1 || gotCode.ExcludedFiles[0] != fileName { 1042 t.Errorf("got %v for gotFileName", gotCode.ExcludedFiles) 1043 } 1044} 1045 1046func TestCanExtractPackageExternalReference(t *testing.T) { 1047 ref1 := "SECURITY cpe23Type cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*" 1048 category := "SECURITY" 1049 refType := "cpe23Type" 1050 location := "cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*" 1051 1052 gotCategory, gotRefType, gotLocation, err := extractPackageExternalReference(ref1) 1053 if err != nil { 1054 t.Errorf("got non-nil error: %v", err) 1055 } 1056 if gotCategory != category { 1057 t.Errorf("expected category %s, got %s", category, gotCategory) 1058 } 1059 if gotRefType != refType { 1060 t.Errorf("expected refType %s, got %s", refType, gotRefType) 1061 } 1062 if gotLocation != location { 1063 t.Errorf("expected location %s, got %s", location, gotLocation) 1064 } 1065} 1066 1067func TestCanExtractPackageExternalReferenceWithExtraWhitespace(t *testing.T) { 1068 ref1 := " SECURITY \t cpe23Type cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:* \t " 1069 category := "SECURITY" 1070 refType := "cpe23Type" 1071 location := "cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*" 1072 1073 gotCategory, gotRefType, gotLocation, err := extractPackageExternalReference(ref1) 1074 if err != nil { 1075 t.Errorf("got non-nil error: %v", err) 1076 } 1077 if gotCategory != category { 1078 t.Errorf("expected category %s, got %s", category, gotCategory) 1079 } 1080 if gotRefType != refType { 1081 t.Errorf("expected refType %s, got %s", refType, gotRefType) 1082 } 1083 if gotLocation != location { 1084 t.Errorf("expected location %s, got %s", location, gotLocation) 1085 } 1086} 1087 1088func TestFailsPackageExternalRefWithInvalidFormat(t *testing.T) { 1089 _, _, _, err := extractPackageExternalReference("whoops") 1090 if err == nil { 1091 t.Errorf("expected non-nil error, got nil") 1092 } 1093} 1094 1095func TestParser2_2PackageWithoutSpdxIdentifierThrowsError(t *testing.T) { 1096 // More than one package, the previous package doesn't contain an SPDX ID 1097 pkgOldName := "p1" 1098 parser := tvParser2_2{ 1099 doc: &v2_2.Document{Packages: []*v2_2.Package{}}, 1100 st: psPackage2_2, 1101 pkg: &v2_2.Package{PackageName: pkgOldName}, 1102 } 1103 pkgOld := parser.pkg 1104 parser.doc.Packages = append(parser.doc.Packages, pkgOld) 1105 // the Document's Packages should have this one only 1106 if parser.doc.Packages[0] != pkgOld { 1107 t.Errorf("expected package %v, got %v", pkgOld, parser.doc.Packages[0]) 1108 } 1109 if len(parser.doc.Packages) != 1 { 1110 t.Errorf("expected 1 package, got %d", len(parser.doc.Packages)) 1111 } 1112 1113 pkgName := "p2" 1114 err := parser.parsePair2_2("PackageName", pkgName) 1115 if err == nil { 1116 t.Errorf("package without SPDX Identifier getting accepted") 1117 } 1118} 1119