aboutsummaryrefslogtreecommitdiff
path: root/tvloader/parser2v2/parse_package_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'tvloader/parser2v2/parse_package_test.go')
-rw-r--r--tvloader/parser2v2/parse_package_test.go1118
1 files changed, 1118 insertions, 0 deletions
diff --git a/tvloader/parser2v2/parse_package_test.go b/tvloader/parser2v2/parse_package_test.go
new file mode 100644
index 0000000..e07cf5a
--- /dev/null
+++ b/tvloader/parser2v2/parse_package_test.go
@@ -0,0 +1,1118 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+package parser2v2
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/spdx/tools-golang/spdx/common"
+ "github.com/spdx/tools-golang/spdx/v2_2"
+)
+
+// ===== Parser package section state change tests =====
+func TestParser2_2PackageStartsNewPackageAfterParsingPackageNameTag(t *testing.T) {
+ // create the first package
+ pkgOldName := "p1"
+
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{PackageName: pkgOldName, PackageSPDXIdentifier: "p1"},
+ }
+ pkgOld := parser.pkg
+ parser.doc.Packages = append(parser.doc.Packages, pkgOld)
+ // the Document's Packages should have this one only
+ if parser.doc.Packages[0] != pkgOld {
+ t.Errorf("expected package %v, got %v", pkgOld, parser.doc.Packages[0])
+ }
+ if len(parser.doc.Packages) != 1 {
+ t.Errorf("expected 1 package, got %d", len(parser.doc.Packages))
+ }
+
+ // now add a new package
+ pkgName := "p2"
+ err := parser.parsePair2_2("PackageName", pkgName)
+ if err != nil {
+ t.Errorf("got error when calling parsePair2_2: %v", err)
+ }
+ // state should be correct
+ if parser.st != psPackage2_2 {
+ t.Errorf("expected state to be %v, got %v", psPackage2_2, parser.st)
+ }
+ // and a package should be created
+ if parser.pkg == nil {
+ t.Fatalf("parser didn't create new package")
+ }
+ // and it should not be pkgOld
+ if parser.pkg == pkgOld {
+ t.Errorf("expected new package, got pkgOld")
+ }
+ // and the package name should be as expected
+ if parser.pkg.PackageName != pkgName {
+ t.Errorf("expected package name %s, got %s", pkgName, parser.pkg.PackageName)
+ }
+ // and the package should default to true for FilesAnalyzed
+ if parser.pkg.FilesAnalyzed != true {
+ t.Errorf("expected FilesAnalyzed to default to true, got false")
+ }
+ if parser.pkg.IsFilesAnalyzedTagPresent != false {
+ t.Errorf("expected IsFilesAnalyzedTagPresent to default to false, got true")
+ }
+ // and the Document's Packages should still be of size 1 and have pkgOld only
+ if parser.doc.Packages[0] != pkgOld {
+ t.Errorf("Expected package %v, got %v", pkgOld, parser.doc.Packages[0])
+ }
+ if len(parser.doc.Packages) != 1 {
+ t.Errorf("expected 1 package, got %d", len(parser.doc.Packages))
+ }
+}
+
+func TestParser2_2PackageStartsNewPackageAfterParsingPackageNameTagWhileInUnpackaged(t *testing.T) {
+ // pkg is nil, so that Files appearing before the first PackageName tag
+ // are added to Files instead of Packages
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psFile2_2,
+ pkg: nil,
+ }
+ // the Document's Packages should be empty
+ if len(parser.doc.Packages) != 0 {
+ t.Errorf("Expected zero packages, got %d", len(parser.doc.Packages))
+ }
+
+ // now add a new package
+ pkgName := "p2"
+ err := parser.parsePair2_2("PackageName", pkgName)
+ if err != nil {
+ t.Errorf("got error when calling parsePair2_2: %v", err)
+ }
+ // state should be correct
+ if parser.st != psPackage2_2 {
+ t.Errorf("expected state to be %v, got %v", psPackage2_2, parser.st)
+ }
+ // and a package should be created
+ if parser.pkg == nil {
+ t.Fatalf("parser didn't create new package")
+ }
+ // and the package name should be as expected
+ if parser.pkg.PackageName != pkgName {
+ t.Errorf("expected package name %s, got %s", pkgName, parser.pkg.PackageName)
+ }
+ // and the package should default to true for FilesAnalyzed
+ if parser.pkg.FilesAnalyzed != true {
+ t.Errorf("expected FilesAnalyzed to default to true, got false")
+ }
+ if parser.pkg.IsFilesAnalyzedTagPresent != false {
+ t.Errorf("expected IsFilesAnalyzedTagPresent to default to false, got true")
+ }
+ // and the Document's Packages should be of size 0, because the prior was
+ // unpackaged files and this one won't be added until an SPDXID is seen
+ if len(parser.doc.Packages) != 0 {
+ t.Errorf("Expected %v packages in doc, got %v", 0, len(parser.doc.Packages))
+ }
+}
+
+func TestParser2_2PackageMovesToFileAfterParsingFileNameTag(t *testing.T) {
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"},
+ }
+ parser.doc.Packages = append(parser.doc.Packages, parser.pkg)
+ pkgCurrent := parser.pkg
+
+ err := parser.parsePair2_2("FileName", "testFile")
+ if err != nil {
+ t.Errorf("got error when calling parsePair2_2: %v", err)
+ }
+ // state should be correct
+ if parser.st != psFile2_2 {
+ t.Errorf("expected state to be %v, got %v", psFile2_2, parser.st)
+ }
+ // and current package should remain what it was
+ if parser.pkg != pkgCurrent {
+ t.Fatalf("expected package to remain %v, got %v", pkgCurrent, parser.pkg)
+ }
+}
+
+func TestParser2_2PackageMovesToOtherLicenseAfterParsingLicenseIDTag(t *testing.T) {
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"},
+ }
+ parser.doc.Packages = append(parser.doc.Packages, parser.pkg)
+
+ err := parser.parsePair2_2("LicenseID", "LicenseRef-TestLic")
+ if err != nil {
+ t.Errorf("got error when calling parsePair2_2: %v", err)
+ }
+ if parser.st != psOtherLicense2_2 {
+ t.Errorf("expected state to be %v, got %v", psOtherLicense2_2, parser.st)
+ }
+}
+
+func TestParser2_2PackageMovesToReviewAfterParsingReviewerTag(t *testing.T) {
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"},
+ }
+ parser.doc.Packages = append(parser.doc.Packages, parser.pkg)
+
+ err := parser.parsePair2_2("Reviewer", "Person: John Doe")
+ if err != nil {
+ t.Errorf("got error when calling parsePair2_2: %v", err)
+ }
+ if parser.st != psReview2_2 {
+ t.Errorf("expected state to be %v, got %v", psReview2_2, parser.st)
+ }
+}
+
+func TestParser2_2PackageStaysAfterParsingRelationshipTags(t *testing.T) {
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"},
+ }
+ parser.doc.Packages = append(parser.doc.Packages, parser.pkg)
+
+ err := parser.parsePair2_2("Relationship", "SPDXRef-blah CONTAINS SPDXRef-blah-else")
+ if err != nil {
+ t.Errorf("got error when calling parsePair2_2: %v", err)
+ }
+ // state should remain unchanged
+ if parser.st != psPackage2_2 {
+ t.Errorf("expected state to be %v, got %v", psPackage2_2, parser.st)
+ }
+
+ err = parser.parsePair2_2("RelationshipComment", "blah")
+ if err != nil {
+ t.Errorf("got error when calling parsePair2_2: %v", err)
+ }
+ // state should still remain unchanged
+ if parser.st != psPackage2_2 {
+ t.Errorf("expected state to be %v, got %v", psPackage2_2, parser.st)
+ }
+}
+
+func TestParser2_2PackageStaysAfterParsingAnnotationTags(t *testing.T) {
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"},
+ }
+ parser.doc.Packages = append(parser.doc.Packages, parser.pkg)
+
+ err := parser.parsePair2_2("Annotator", "Person: John Doe ()")
+ if err != nil {
+ t.Errorf("got error when calling parsePair2_2: %v", err)
+ }
+ if parser.st != psPackage2_2 {
+ t.Errorf("parser is in state %v, expected %v", parser.st, psPackage2_2)
+ }
+
+ err = parser.parsePair2_2("AnnotationDate", "2018-09-15T00:36:00Z")
+ if err != nil {
+ t.Errorf("got error when calling parsePair2_2: %v", err)
+ }
+ if parser.st != psPackage2_2 {
+ t.Errorf("parser is in state %v, expected %v", parser.st, psPackage2_2)
+ }
+
+ err = parser.parsePair2_2("AnnotationType", "REVIEW")
+ if err != nil {
+ t.Errorf("got error when calling parsePair2_2: %v", err)
+ }
+ if parser.st != psPackage2_2 {
+ t.Errorf("parser is in state %v, expected %v", parser.st, psPackage2_2)
+ }
+
+ err = parser.parsePair2_2("SPDXREF", "SPDXRef-45")
+ if err != nil {
+ t.Errorf("got error when calling parsePair2_2: %v", err)
+ }
+ if parser.st != psPackage2_2 {
+ t.Errorf("parser is in state %v, expected %v", parser.st, psPackage2_2)
+ }
+
+ err = parser.parsePair2_2("AnnotationComment", "i guess i had something to say about this package")
+ if err != nil {
+ t.Errorf("got error when calling parsePair2_2: %v", err)
+ }
+ if parser.st != psPackage2_2 {
+ t.Errorf("parser is in state %v, expected %v", parser.st, psPackage2_2)
+ }
+}
+
+// ===== Package data section tests =====
+func TestParser2_2CanParsePackageTags(t *testing.T) {
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{},
+ }
+
+ // should not yet be in Packages map, b/c no SPDX identifier
+ if len(parser.doc.Packages) != 0 {
+ t.Errorf("expected 0 packages, got %d", len(parser.doc.Packages))
+ }
+
+ // Package Name
+ err := parser.parsePairFromPackage2_2("PackageName", "p1")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ if parser.pkg.PackageName != "p1" {
+ t.Errorf("got %v for PackageName", parser.pkg.PackageName)
+ }
+ // still should not yet be in Packages map, b/c no SPDX identifier
+ if len(parser.doc.Packages) != 0 {
+ t.Errorf("expected 0 packages, got %d", len(parser.doc.Packages))
+ }
+
+ // Package SPDX Identifier
+ err = parser.parsePairFromPackage2_2("SPDXID", "SPDXRef-p1")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ // "SPDXRef-" prefix should be removed from the item
+ if parser.pkg.PackageSPDXIdentifier != "p1" {
+ t.Errorf("got %v for PackageSPDXIdentifier", parser.pkg.PackageSPDXIdentifier)
+ }
+ // and it should now be added to the Packages map
+ if len(parser.doc.Packages) != 1 {
+ t.Errorf("expected 1 package, got %d", len(parser.doc.Packages))
+ }
+ if parser.doc.Packages[0] != parser.pkg {
+ t.Errorf("expected to point to parser.pkg, got %v", parser.doc.Packages[0])
+ }
+
+ // Package Version
+ err = parser.parsePairFromPackage2_2("PackageVersion", "2.1.1")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ if parser.pkg.PackageVersion != "2.1.1" {
+ t.Errorf("got %v for PackageVersion", parser.pkg.PackageVersion)
+ }
+
+ // Package File Name
+ err = parser.parsePairFromPackage2_2("PackageFileName", "p1-2.1.1.tar.gz")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ if parser.pkg.PackageFileName != "p1-2.1.1.tar.gz" {
+ t.Errorf("got %v for PackageFileName", parser.pkg.PackageFileName)
+ }
+
+ // Package Supplier
+ // SKIP -- separate tests for subvalues below
+
+ // Package Originator
+ // SKIP -- separate tests for subvalues below
+
+ // Package Download Location
+ err = parser.parsePairFromPackage2_2("PackageDownloadLocation", "https://example.com/whatever")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ if parser.pkg.PackageDownloadLocation != "https://example.com/whatever" {
+ t.Errorf("got %v for PackageDownloadLocation", parser.pkg.PackageDownloadLocation)
+ }
+
+ // Files Analyzed
+ err = parser.parsePairFromPackage2_2("FilesAnalyzed", "false")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ if parser.pkg.FilesAnalyzed != false {
+ t.Errorf("got %v for FilesAnalyzed", parser.pkg.FilesAnalyzed)
+ }
+ if parser.pkg.IsFilesAnalyzedTagPresent != true {
+ t.Errorf("got %v for IsFilesAnalyzedTagPresent", parser.pkg.IsFilesAnalyzedTagPresent)
+ }
+
+ // Package Verification Code
+ // SKIP -- separate tests for "excludes", or not, below
+
+ testChecksums := map[common.ChecksumAlgorithm]string{
+ "MD5": "624c1abb3664f4b35547e7c73864ad24",
+ "SHA1": "85ed0817af83a24ad8da68c2b5094de69833983c",
+ "SHA256": "11b6d3ee554eedf79299905a98f9b9a04e498210b59f15094c916c91d150efcd",
+ "SHA512": "4ced3267f5ed38df65ceebc43e97aa6c2948cc7ef3288c2e5074e7df7fab544cc93339604513ea5f65616f9ed1c48581465043c8a9b693ef20fd4fddaf25e1b9",
+ }
+
+ for algo, tc := range testChecksums {
+ if err := parser.parsePairFromPackage2_2(
+ "PackageChecksum", fmt.Sprintf("%s: %s", algo, tc)); err != nil {
+ t.Errorf("expected error, got %v", err)
+ }
+ }
+
+ for _, checksum := range parser.pkg.PackageChecksums {
+ if checksum.Value != testChecksums[checksum.Algorithm] {
+ t.Errorf(
+ "expected %s for PackageChecksum%s, got %s",
+ testChecksums[checksum.Algorithm], checksum.Algorithm, checksum.Value,
+ )
+ }
+ }
+
+ // Package Home Page
+ err = parser.parsePairFromPackage2_2("PackageHomePage", "https://example.com/whatever2")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ if parser.pkg.PackageHomePage != "https://example.com/whatever2" {
+ t.Errorf("got %v for PackageHomePage", parser.pkg.PackageHomePage)
+ }
+
+ // Package Source Info
+ err = parser.parsePairFromPackage2_2("PackageSourceInfo", "random comment")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ if parser.pkg.PackageSourceInfo != "random comment" {
+ t.Errorf("got %v for PackageSourceInfo", parser.pkg.PackageSourceInfo)
+ }
+
+ // Package License Concluded
+ err = parser.parsePairFromPackage2_2("PackageLicenseConcluded", "Apache-2.0 OR GPL-2.0-or-later")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ if parser.pkg.PackageLicenseConcluded != "Apache-2.0 OR GPL-2.0-or-later" {
+ t.Errorf("got %v for PackageLicenseConcluded", parser.pkg.PackageLicenseConcluded)
+ }
+
+ // All Licenses Info From Files
+ lics := []string{
+ "Apache-2.0",
+ "GPL-2.0-or-later",
+ "CC0-1.0",
+ }
+ for _, lic := range lics {
+ err = parser.parsePairFromPackage2_2("PackageLicenseInfoFromFiles", lic)
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ }
+ for _, licWant := range lics {
+ flagFound := false
+ for _, licCheck := range parser.pkg.PackageLicenseInfoFromFiles {
+ if licWant == licCheck {
+ flagFound = true
+ }
+ }
+ if flagFound == false {
+ t.Errorf("didn't find %s in PackageLicenseInfoFromFiles", licWant)
+ }
+ }
+ if len(lics) != len(parser.pkg.PackageLicenseInfoFromFiles) {
+ t.Errorf("expected %d licenses in PackageLicenseInfoFromFiles, got %d", len(lics),
+ len(parser.pkg.PackageLicenseInfoFromFiles))
+ }
+
+ // Package License Declared
+ err = parser.parsePairFromPackage2_2("PackageLicenseDeclared", "Apache-2.0 OR GPL-2.0-or-later")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ if parser.pkg.PackageLicenseDeclared != "Apache-2.0 OR GPL-2.0-or-later" {
+ t.Errorf("got %v for PackageLicenseDeclared", parser.pkg.PackageLicenseDeclared)
+ }
+
+ // Package License Comments
+ err = parser.parsePairFromPackage2_2("PackageLicenseComments", "this is a license comment")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ if parser.pkg.PackageLicenseComments != "this is a license comment" {
+ t.Errorf("got %v for PackageLicenseComments", parser.pkg.PackageLicenseComments)
+ }
+
+ // Package Copyright Text
+ err = parser.parsePairFromPackage2_2("PackageCopyrightText", "Copyright (c) me myself and i")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ if parser.pkg.PackageCopyrightText != "Copyright (c) me myself and i" {
+ t.Errorf("got %v for PackageCopyrightText", parser.pkg.PackageCopyrightText)
+ }
+
+ // Package Summary
+ err = parser.parsePairFromPackage2_2("PackageSummary", "i wrote this package")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ if parser.pkg.PackageSummary != "i wrote this package" {
+ t.Errorf("got %v for PackageSummary", parser.pkg.PackageSummary)
+ }
+
+ // Package Description
+ err = parser.parsePairFromPackage2_2("PackageDescription", "i wrote this package a lot")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ if parser.pkg.PackageDescription != "i wrote this package a lot" {
+ t.Errorf("got %v for PackageDescription", parser.pkg.PackageDescription)
+ }
+
+ // Package Comment
+ err = parser.parsePairFromPackage2_2("PackageComment", "i scanned this package")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ if parser.pkg.PackageComment != "i scanned this package" {
+ t.Errorf("got %v for PackageComment", parser.pkg.PackageComment)
+ }
+
+ // Package Attribution Text
+ attrs := []string{
+ "Include this notice in all advertising materials",
+ "This is a \nmulti-line string",
+ }
+ for _, attr := range attrs {
+ err = parser.parsePairFromPackage2_2("PackageAttributionText", attr)
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ }
+ for _, attrWant := range attrs {
+ flagFound := false
+ for _, attrCheck := range parser.pkg.PackageAttributionTexts {
+ if attrWant == attrCheck {
+ flagFound = true
+ }
+ }
+ if flagFound == false {
+ t.Errorf("didn't find %s in PackageAttributionText", attrWant)
+ }
+ }
+ if len(attrs) != len(parser.pkg.PackageAttributionTexts) {
+ t.Errorf("expected %d attribution texts in PackageAttributionTexts, got %d", len(attrs),
+ len(parser.pkg.PackageAttributionTexts))
+ }
+
+ // Package External References and Comments
+ ref1 := "SECURITY cpe23Type cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*"
+ ref1Category := "SECURITY"
+ ref1Type := "cpe23Type"
+ ref1Locator := "cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*"
+ ref1Comment := "this is comment #1"
+ ref2 := "OTHER LocationRef-acmeforge acmecorp/acmenator/4.1.3alpha"
+ ref2Category := "OTHER"
+ ref2Type := "LocationRef-acmeforge"
+ ref2Locator := "acmecorp/acmenator/4.1.3alpha"
+ ref2Comment := "this is comment #2"
+ err = parser.parsePairFromPackage2_2("ExternalRef", ref1)
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ if len(parser.pkg.PackageExternalReferences) != 1 {
+ t.Errorf("expected 1 external reference, got %d", len(parser.pkg.PackageExternalReferences))
+ }
+ if parser.pkgExtRef == nil {
+ t.Errorf("expected non-nil pkgExtRef, got nil")
+ }
+ if parser.pkg.PackageExternalReferences[0] == nil {
+ t.Errorf("expected non-nil PackageExternalReferences[0], got nil")
+ }
+ if parser.pkgExtRef != parser.pkg.PackageExternalReferences[0] {
+ t.Errorf("expected pkgExtRef to match PackageExternalReferences[0], got no match")
+ }
+ err = parser.parsePairFromPackage2_2("ExternalRefComment", ref1Comment)
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ err = parser.parsePairFromPackage2_2("ExternalRef", ref2)
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ if len(parser.pkg.PackageExternalReferences) != 2 {
+ t.Errorf("expected 2 external references, got %d", len(parser.pkg.PackageExternalReferences))
+ }
+ if parser.pkgExtRef == nil {
+ t.Errorf("expected non-nil pkgExtRef, got nil")
+ }
+ if parser.pkg.PackageExternalReferences[1] == nil {
+ t.Errorf("expected non-nil PackageExternalReferences[1], got nil")
+ }
+ if parser.pkgExtRef != parser.pkg.PackageExternalReferences[1] {
+ t.Errorf("expected pkgExtRef to match PackageExternalReferences[1], got no match")
+ }
+ err = parser.parsePairFromPackage2_2("ExternalRefComment", ref2Comment)
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ // finally, check these values
+ gotRef1 := parser.pkg.PackageExternalReferences[0]
+ if gotRef1.Category != ref1Category {
+ t.Errorf("expected ref1 category to be %s, got %s", gotRef1.Category, ref1Category)
+ }
+ if gotRef1.RefType != ref1Type {
+ t.Errorf("expected ref1 type to be %s, got %s", gotRef1.RefType, ref1Type)
+ }
+ if gotRef1.Locator != ref1Locator {
+ t.Errorf("expected ref1 locator to be %s, got %s", gotRef1.Locator, ref1Locator)
+ }
+ if gotRef1.ExternalRefComment != ref1Comment {
+ t.Errorf("expected ref1 comment to be %s, got %s", gotRef1.ExternalRefComment, ref1Comment)
+ }
+ gotRef2 := parser.pkg.PackageExternalReferences[1]
+ if gotRef2.Category != ref2Category {
+ t.Errorf("expected ref2 category to be %s, got %s", gotRef2.Category, ref2Category)
+ }
+ if gotRef2.RefType != ref2Type {
+ t.Errorf("expected ref2 type to be %s, got %s", gotRef2.RefType, ref2Type)
+ }
+ if gotRef2.Locator != ref2Locator {
+ t.Errorf("expected ref2 locator to be %s, got %s", gotRef2.Locator, ref2Locator)
+ }
+ if gotRef2.ExternalRefComment != ref2Comment {
+ t.Errorf("expected ref2 comment to be %s, got %s", gotRef2.ExternalRefComment, ref2Comment)
+ }
+
+}
+
+func TestParser2_2CanParsePackageSupplierPersonTag(t *testing.T) {
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"},
+ }
+ parser.doc.Packages = append(parser.doc.Packages, parser.pkg)
+
+ // Package Supplier: Person
+ err := parser.parsePairFromPackage2_2("PackageSupplier", "Person: John Doe")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ if parser.pkg.PackageSupplier.Supplier != "John Doe" {
+ t.Errorf("got %v for PackageSupplierPerson", parser.pkg.PackageSupplier.Supplier)
+ }
+}
+
+func TestParser2_2CanParsePackageSupplierOrganizationTag(t *testing.T) {
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"},
+ }
+ parser.doc.Packages = append(parser.doc.Packages, parser.pkg)
+
+ // Package Supplier: Organization
+ err := parser.parsePairFromPackage2_2("PackageSupplier", "Organization: John Doe, Inc.")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ if parser.pkg.PackageSupplier.Supplier != "John Doe, Inc." {
+ t.Errorf("got %v for PackageSupplierOrganization", parser.pkg.PackageSupplier.Supplier)
+ }
+}
+
+func TestParser2_2CanParsePackageSupplierNOASSERTIONTag(t *testing.T) {
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"},
+ }
+ parser.doc.Packages = append(parser.doc.Packages, parser.pkg)
+
+ // Package Supplier: NOASSERTION
+ err := parser.parsePairFromPackage2_2("PackageSupplier", "NOASSERTION")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ if parser.pkg.PackageSupplier.Supplier != "NOASSERTION" {
+ t.Errorf("got value for Supplier, expected NOASSERTION")
+ }
+}
+
+func TestParser2_2CanParsePackageOriginatorPersonTag(t *testing.T) {
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"},
+ }
+ parser.doc.Packages = append(parser.doc.Packages, parser.pkg)
+
+ // Package Originator: Person
+ err := parser.parsePairFromPackage2_2("PackageOriginator", "Person: John Doe")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ if parser.pkg.PackageOriginator.Originator != "John Doe" {
+ t.Errorf("got %v for PackageOriginator", parser.pkg.PackageOriginator.Originator)
+ }
+}
+
+func TestParser2_2CanParsePackageOriginatorOrganizationTag(t *testing.T) {
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"},
+ }
+ parser.doc.Packages = append(parser.doc.Packages, parser.pkg)
+
+ // Package Originator: Organization
+ err := parser.parsePairFromPackage2_2("PackageOriginator", "Organization: John Doe, Inc.")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ if parser.pkg.PackageOriginator.Originator != "John Doe, Inc." {
+ t.Errorf("got %v for PackageOriginator", parser.pkg.PackageOriginator.Originator)
+ }
+}
+
+func TestParser2_2CanParsePackageOriginatorNOASSERTIONTag(t *testing.T) {
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"},
+ }
+ parser.doc.Packages = append(parser.doc.Packages, parser.pkg)
+
+ // Package Originator: NOASSERTION
+ err := parser.parsePairFromPackage2_2("PackageOriginator", "NOASSERTION")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ if parser.pkg.PackageOriginator.Originator != "NOASSERTION" {
+ t.Errorf("got false for PackageOriginatorNOASSERTION")
+ }
+}
+
+func TestParser2_2CanParsePackageVerificationCodeTagWithExcludes(t *testing.T) {
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"},
+ }
+ parser.doc.Packages = append(parser.doc.Packages, parser.pkg)
+
+ // Package Verification Code with excludes parenthetical
+ code := "d6a770ba38583ed4bb4525bd96e50461655d2758"
+ fileName := "./package.spdx"
+ fullCodeValue := "d6a770ba38583ed4bb4525bd96e50461655d2758 (excludes: ./package.spdx)"
+ err := parser.parsePairFromPackage2_2("PackageVerificationCode", fullCodeValue)
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ if parser.pkg.PackageVerificationCode.Value != code {
+ t.Errorf("got %v for PackageVerificationCode", parser.pkg.PackageVerificationCode)
+ }
+ if len(parser.pkg.PackageVerificationCode.ExcludedFiles) != 1 || parser.pkg.PackageVerificationCode.ExcludedFiles[0] != fileName {
+ t.Errorf("got %v for PackageVerificationCodeExcludedFile", parser.pkg.PackageVerificationCode.ExcludedFiles)
+ }
+
+}
+
+func TestParser2_2CanParsePackageVerificationCodeTagWithoutExcludes(t *testing.T) {
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"},
+ }
+ parser.doc.Packages = append(parser.doc.Packages, parser.pkg)
+
+ // Package Verification Code without excludes parenthetical
+ code := "d6a770ba38583ed4bb4525bd96e50461655d2758"
+ err := parser.parsePairFromPackage2_2("PackageVerificationCode", code)
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ if parser.pkg.PackageVerificationCode.Value != code {
+ t.Errorf("got %v for PackageVerificationCode", parser.pkg.PackageVerificationCode)
+ }
+ if len(parser.pkg.PackageVerificationCode.ExcludedFiles) != 0 {
+ t.Errorf("got %v for PackageVerificationCodeExcludedFile", parser.pkg.PackageVerificationCode.ExcludedFiles)
+ }
+
+}
+
+func TestParser2_2PackageExternalRefPointerChangesAfterTags(t *testing.T) {
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"},
+ }
+ parser.doc.Packages = append(parser.doc.Packages, parser.pkg)
+
+ ref1 := "SECURITY cpe23Type cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*"
+ err := parser.parsePairFromPackage2_2("ExternalRef", ref1)
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ if parser.pkgExtRef == nil {
+ t.Errorf("expected non-nil external reference pointer, got nil")
+ }
+
+ // now, a comment; pointer should go away
+ err = parser.parsePairFromPackage2_2("ExternalRefComment", "whatever")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ if parser.pkgExtRef != nil {
+ t.Errorf("expected nil external reference pointer, got non-nil")
+ }
+
+ ref2 := "Other LocationRef-something https://example.com/whatever"
+ err = parser.parsePairFromPackage2_2("ExternalRef", ref2)
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ if parser.pkgExtRef == nil {
+ t.Errorf("expected non-nil external reference pointer, got nil")
+ }
+
+ // and some other random tag makes the pointer go away too
+ err = parser.parsePairFromPackage2_2("PackageSummary", "whatever")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ if parser.pkgExtRef != nil {
+ t.Errorf("expected nil external reference pointer, got non-nil")
+ }
+}
+
+func TestParser2_2PackageCreatesRelationshipInDocument(t *testing.T) {
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"},
+ }
+ parser.doc.Packages = append(parser.doc.Packages, parser.pkg)
+
+ err := parser.parsePair2_2("Relationship", "SPDXRef-blah CONTAINS SPDXRef-blah-whatever")
+ if err != nil {
+ t.Errorf("got error when calling parsePair2_2: %v", err)
+ }
+ if parser.rln == nil {
+ t.Fatalf("parser didn't create and point to Relationship struct")
+ }
+ if parser.rln != parser.doc.Relationships[0] {
+ t.Errorf("pointer to new Relationship doesn't match idx 0 for doc.Relationships[]")
+ }
+}
+
+func TestParser2_2PackageCreatesAnnotationInDocument(t *testing.T) {
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"},
+ }
+ parser.doc.Packages = append(parser.doc.Packages, parser.pkg)
+
+ err := parser.parsePair2_2("Annotator", "Person: John Doe ()")
+ if err != nil {
+ t.Errorf("got error when calling parsePair2_2: %v", err)
+ }
+ if parser.ann == nil {
+ t.Fatalf("parser didn't create and point to Annotation struct")
+ }
+ if parser.ann != parser.doc.Annotations[0] {
+ t.Errorf("pointer to new Annotation doesn't match idx 0 for doc.Annotations[]")
+ }
+}
+
+func TestParser2_2PackageUnknownTagFails(t *testing.T) {
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"},
+ }
+ parser.doc.Packages = append(parser.doc.Packages, parser.pkg)
+
+ err := parser.parsePairFromPackage2_2("blah", "something")
+ if err == nil {
+ t.Errorf("expected error from parsing unknown tag")
+ }
+}
+
+func TestParser2_2FailsIfInvalidSPDXIDInPackageSection(t *testing.T) {
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{},
+ }
+
+ // start with Package Name
+ err := parser.parsePairFromPackage2_2("PackageName", "p1")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ // invalid ID format
+ err = parser.parsePairFromPackage2_2("SPDXID", "whoops")
+ if err == nil {
+ t.Errorf("expected non-nil error, got nil")
+ }
+}
+
+func TestParser2_2FailsIfInvalidPackageSupplierFormat(t *testing.T) {
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{},
+ }
+
+ // start with Package Name
+ err := parser.parsePairFromPackage2_2("PackageName", "p1")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ // invalid supplier format
+ err = parser.parsePairFromPackage2_2("PackageSupplier", "whoops")
+ if err == nil {
+ t.Errorf("expected non-nil error, got nil")
+ }
+}
+
+func TestParser2_2FailsIfUnknownPackageSupplierType(t *testing.T) {
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{},
+ }
+
+ // start with Package Name
+ err := parser.parsePairFromPackage2_2("PackageName", "p1")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ // invalid supplier type
+ err = parser.parsePairFromPackage2_2("PackageSupplier", "whoops: John Doe")
+ if err == nil {
+ t.Errorf("expected non-nil error, got nil")
+ }
+}
+
+func TestParser2_2FailsIfInvalidPackageOriginatorFormat(t *testing.T) {
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{},
+ }
+
+ // start with Package Name
+ err := parser.parsePairFromPackage2_2("PackageName", "p1")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ // invalid originator format
+ err = parser.parsePairFromPackage2_2("PackageOriginator", "whoops")
+ if err == nil {
+ t.Errorf("expected non-nil error, got nil")
+ }
+}
+
+func TestParser2_2FailsIfUnknownPackageOriginatorType(t *testing.T) {
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{},
+ }
+
+ // start with Package Name
+ err := parser.parsePairFromPackage2_2("PackageName", "p1")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ // invalid originator type
+ err = parser.parsePairFromPackage2_2("PackageOriginator", "whoops: John Doe")
+ if err == nil {
+ t.Errorf("expected non-nil error, got nil")
+ }
+}
+
+func TestParser2_2SetsFilesAnalyzedTagsCorrectly(t *testing.T) {
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{},
+ }
+
+ // start with Package Name
+ err := parser.parsePairFromPackage2_2("PackageName", "p1")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ // set tag
+ err = parser.parsePairFromPackage2_2("FilesAnalyzed", "true")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ if parser.pkg.FilesAnalyzed != true {
+ t.Errorf("expected %v, got %v", true, parser.pkg.FilesAnalyzed)
+ }
+ if parser.pkg.IsFilesAnalyzedTagPresent != true {
+ t.Errorf("expected %v, got %v", true, parser.pkg.IsFilesAnalyzedTagPresent)
+ }
+}
+
+func TestParser2_2FailsIfInvalidPackageChecksumFormat(t *testing.T) {
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{},
+ }
+
+ // start with Package Name
+ err := parser.parsePairFromPackage2_2("PackageName", "p1")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ // invalid checksum format
+ err = parser.parsePairFromPackage2_2("PackageChecksum", "whoops")
+ if err == nil {
+ t.Errorf("expected non-nil error, got nil")
+ }
+}
+
+func TestParser2_2FailsIfInvalidPackageChecksumType(t *testing.T) {
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{},
+ }
+
+ // start with Package Name
+ err := parser.parsePairFromPackage2_2("PackageName", "p1")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ // invalid checksum type
+ err = parser.parsePairFromPackage2_2("PackageChecksum", "whoops: blah")
+ if err == nil {
+ t.Errorf("expected non-nil error, got nil")
+ }
+}
+
+func TestParser2_2FailsIfInvalidExternalRefFormat(t *testing.T) {
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{},
+ }
+
+ // start with Package Name
+ err := parser.parsePairFromPackage2_2("PackageName", "p1")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ // invalid external ref format
+ err = parser.parsePairFromPackage2_2("ExternalRef", "whoops")
+ if err == nil {
+ t.Errorf("expected non-nil error, got nil")
+ }
+}
+
+func TestParser2_2FailsIfExternalRefCommentBeforeExternalRef(t *testing.T) {
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{},
+ }
+
+ // start with Package Name
+ err := parser.parsePairFromPackage2_2("PackageName", "p1")
+ if err != nil {
+ t.Errorf("expected nil error, got %v", err)
+ }
+ // external ref comment before external ref
+ err = parser.parsePairFromPackage2_2("ExternalRefComment", "whoops")
+ if err == nil {
+ t.Errorf("expected non-nil error, got nil")
+ }
+}
+
+// ===== Helper function tests =====
+
+func TestCanCheckAndExtractExcludesFilenameAndCode(t *testing.T) {
+ code := "d6a770ba38583ed4bb4525bd96e50461655d2758"
+ fileName := "./package.spdx"
+ fullCodeValue := "d6a770ba38583ed4bb4525bd96e50461655d2758 (excludes: ./package.spdx)"
+
+ gotCode := extractCodeAndExcludes(fullCodeValue)
+ if gotCode.Value != code {
+ t.Errorf("got %v for gotCode", gotCode)
+ }
+ if len(gotCode.ExcludedFiles) != 1 || gotCode.ExcludedFiles[0] != fileName {
+ t.Errorf("got %v for gotFileName", gotCode.ExcludedFiles)
+ }
+}
+
+func TestCanExtractPackageExternalReference(t *testing.T) {
+ ref1 := "SECURITY cpe23Type cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*"
+ category := "SECURITY"
+ refType := "cpe23Type"
+ location := "cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*"
+
+ gotCategory, gotRefType, gotLocation, err := extractPackageExternalReference(ref1)
+ if err != nil {
+ t.Errorf("got non-nil error: %v", err)
+ }
+ if gotCategory != category {
+ t.Errorf("expected category %s, got %s", category, gotCategory)
+ }
+ if gotRefType != refType {
+ t.Errorf("expected refType %s, got %s", refType, gotRefType)
+ }
+ if gotLocation != location {
+ t.Errorf("expected location %s, got %s", location, gotLocation)
+ }
+}
+
+func TestCanExtractPackageExternalReferenceWithExtraWhitespace(t *testing.T) {
+ ref1 := " SECURITY \t cpe23Type cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:* \t "
+ category := "SECURITY"
+ refType := "cpe23Type"
+ location := "cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*"
+
+ gotCategory, gotRefType, gotLocation, err := extractPackageExternalReference(ref1)
+ if err != nil {
+ t.Errorf("got non-nil error: %v", err)
+ }
+ if gotCategory != category {
+ t.Errorf("expected category %s, got %s", category, gotCategory)
+ }
+ if gotRefType != refType {
+ t.Errorf("expected refType %s, got %s", refType, gotRefType)
+ }
+ if gotLocation != location {
+ t.Errorf("expected location %s, got %s", location, gotLocation)
+ }
+}
+
+func TestFailsPackageExternalRefWithInvalidFormat(t *testing.T) {
+ _, _, _, err := extractPackageExternalReference("whoops")
+ if err == nil {
+ t.Errorf("expected non-nil error, got nil")
+ }
+}
+
+func TestParser2_2PackageWithoutSpdxIdentifierThrowsError(t *testing.T) {
+ // More than one package, the previous package doesn't contain an SPDX ID
+ pkgOldName := "p1"
+ parser := tvParser2_2{
+ doc: &v2_2.Document{Packages: []*v2_2.Package{}},
+ st: psPackage2_2,
+ pkg: &v2_2.Package{PackageName: pkgOldName},
+ }
+ pkgOld := parser.pkg
+ parser.doc.Packages = append(parser.doc.Packages, pkgOld)
+ // the Document's Packages should have this one only
+ if parser.doc.Packages[0] != pkgOld {
+ t.Errorf("expected package %v, got %v", pkgOld, parser.doc.Packages[0])
+ }
+ if len(parser.doc.Packages) != 1 {
+ t.Errorf("expected 1 package, got %d", len(parser.doc.Packages))
+ }
+
+ pkgName := "p2"
+ err := parser.parsePair2_2("PackageName", pkgName)
+ if err == nil {
+ t.Errorf("package without SPDX Identifier getting accepted")
+ }
+}