1// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 2 3package saver2v1 4 5import ( 6 "bytes" 7 "testing" 8 9 "github.com/spdx/tools-golang/spdx/common" 10 "github.com/spdx/tools-golang/spdx/v2_1" 11) 12 13// ===== Package section Saver tests ===== 14func TestSaver2_1PackageSavesTextCombo1(t *testing.T) { 15 // include package external refs 16 // test Supplier:Organization, Originator:Person 17 // FilesAnalyzed true, IsFilesAnalyzedTagPresent true 18 // PackageVerificationCodeExcludedFile has string 19 20 // NOTE, this is an entirely made up CPE and the format is likely invalid 21 per1 := &v2_1.PackageExternalReference{ 22 Category: "SECURITY", 23 RefType: "cpe22Type", 24 Locator: "cpe:/a:john_doe_inc:p1:0.1.0", 25 ExternalRefComment: "this is an external ref comment #1", 26 } 27 28 // NOTE, this is an entirely made up NPM 29 per2 := &v2_1.PackageExternalReference{ 30 Category: "PACKAGE-MANAGER", 31 RefType: "npm", 32 Locator: "p1@0.1.0", 33 ExternalRefComment: `this is a 34multi-line external ref comment`, 35 } 36 37 per3 := &v2_1.PackageExternalReference{ 38 Category: "OTHER", 39 RefType: "anything", 40 Locator: "anything-without-spaces-can-go-here", 41 // no ExternalRefComment for this one 42 } 43 44 pkg := &v2_1.Package{ 45 PackageName: "p1", 46 PackageSPDXIdentifier: common.ElementID("p1"), 47 PackageVersion: "0.1.0", 48 PackageFileName: "p1-0.1.0-master.tar.gz", 49 PackageSupplier: &common.Supplier{SupplierType: "Organization", Supplier: "John Doe, Inc."}, 50 PackageOriginator: &common.Originator{Originator: "John Doe", OriginatorType: "Person"}, 51 PackageDownloadLocation: "http://example.com/p1/p1-0.1.0-master.tar.gz", 52 FilesAnalyzed: true, 53 IsFilesAnalyzedTagPresent: true, 54 PackageVerificationCode: common.PackageVerificationCode{ 55 Value: "0123456789abcdef0123456789abcdef01234567", 56 ExcludedFiles: []string{"p1-0.1.0.spdx"}, 57 }, 58 PackageChecksums: []common.Checksum{ 59 { 60 Algorithm: common.SHA1, 61 Value: "85ed0817af83a24ad8da68c2b5094de69833983c", 62 }, 63 { 64 Algorithm: common.SHA256, 65 Value: "11b6d3ee554eedf79299905a98f9b9a04e498210b59f15094c916c91d150efcd", 66 }, 67 { 68 Algorithm: common.MD5, 69 Value: "624c1abb3664f4b35547e7c73864ad24", 70 }, 71 }, 72 PackageHomePage: "http://example.com/p1", 73 PackageSourceInfo: "this is a source comment", 74 PackageLicenseConcluded: "GPL-2.0-or-later", 75 PackageLicenseInfoFromFiles: []string{ 76 "Apache-1.1", 77 "Apache-2.0", 78 "GPL-2.0-or-later", 79 }, 80 PackageLicenseDeclared: "Apache-2.0 OR GPL-2.0-or-later", 81 PackageLicenseComments: "this is a license comment(s)", 82 PackageCopyrightText: "Copyright (c) John Doe, Inc.", 83 PackageSummary: "this is a summary comment", 84 PackageDescription: "this is a description comment", 85 PackageComment: "this is a comment comment", 86 PackageExternalReferences: []*v2_1.PackageExternalReference{ 87 per1, 88 per2, 89 per3, 90 }, 91 } 92 93 // what we want to get, as a buffer of bytes 94 want := bytes.NewBufferString(`PackageName: p1 95SPDXID: SPDXRef-p1 96PackageVersion: 0.1.0 97PackageFileName: p1-0.1.0-master.tar.gz 98PackageSupplier: Organization: John Doe, Inc. 99PackageOriginator: Person: John Doe 100PackageDownloadLocation: http://example.com/p1/p1-0.1.0-master.tar.gz 101FilesAnalyzed: true 102PackageVerificationCode: 0123456789abcdef0123456789abcdef01234567 (excludes: p1-0.1.0.spdx) 103PackageChecksum: SHA1: 85ed0817af83a24ad8da68c2b5094de69833983c 104PackageChecksum: SHA256: 11b6d3ee554eedf79299905a98f9b9a04e498210b59f15094c916c91d150efcd 105PackageChecksum: MD5: 624c1abb3664f4b35547e7c73864ad24 106PackageHomePage: http://example.com/p1 107PackageSourceInfo: this is a source comment 108PackageLicenseConcluded: GPL-2.0-or-later 109PackageLicenseInfoFromFiles: Apache-1.1 110PackageLicenseInfoFromFiles: Apache-2.0 111PackageLicenseInfoFromFiles: GPL-2.0-or-later 112PackageLicenseDeclared: Apache-2.0 OR GPL-2.0-or-later 113PackageLicenseComments: this is a license comment(s) 114PackageCopyrightText: Copyright (c) John Doe, Inc. 115PackageSummary: this is a summary comment 116PackageDescription: this is a description comment 117PackageComment: this is a comment comment 118ExternalRef: SECURITY cpe22Type cpe:/a:john_doe_inc:p1:0.1.0 119ExternalRefComment: this is an external ref comment #1 120ExternalRef: PACKAGE-MANAGER npm p1@0.1.0 121ExternalRefComment: <text>this is a 122multi-line external ref comment</text> 123ExternalRef: OTHER anything anything-without-spaces-can-go-here 124 125`) 126 127 // render as buffer of bytes 128 var got bytes.Buffer 129 err := renderPackage2_1(pkg, &got) 130 if err != nil { 131 t.Errorf("Expected nil error, got %v", err) 132 } 133 134 // check that they match 135 c := bytes.Compare(want.Bytes(), got.Bytes()) 136 if c != 0 { 137 t.Errorf("Expected %v, got %v", want.String(), got.String()) 138 } 139} 140 141func TestSaver2_1PackageSavesTextCombo2(t *testing.T) { 142 // no package external refs 143 // test Supplier:NOASSERTION, Originator:Organization 144 // FilesAnalyzed true, IsFilesAnalyzedTagPresent false 145 // PackageVerificationCodeExcludedFile is empty 146 147 pkg := &v2_1.Package{ 148 PackageName: "p1", 149 PackageSPDXIdentifier: common.ElementID("p1"), 150 PackageVersion: "0.1.0", 151 PackageFileName: "p1-0.1.0-master.tar.gz", 152 PackageSupplier: &common.Supplier{Supplier: "NOASSERTION"}, 153 PackageOriginator: &common.Originator{OriginatorType: "Organization", Originator: "John Doe, Inc."}, 154 PackageDownloadLocation: "http://example.com/p1/p1-0.1.0-master.tar.gz", 155 FilesAnalyzed: true, 156 IsFilesAnalyzedTagPresent: false, 157 PackageVerificationCode: common.PackageVerificationCode{Value: "0123456789abcdef0123456789abcdef01234567"}, 158 PackageChecksums: []common.Checksum{ 159 { 160 Algorithm: common.SHA1, 161 Value: "85ed0817af83a24ad8da68c2b5094de69833983c", 162 }, 163 { 164 Algorithm: common.SHA256, 165 Value: "11b6d3ee554eedf79299905a98f9b9a04e498210b59f15094c916c91d150efcd", 166 }, 167 { 168 Algorithm: common.MD5, 169 Value: "624c1abb3664f4b35547e7c73864ad24", 170 }, 171 }, 172 PackageHomePage: "http://example.com/p1", 173 PackageSourceInfo: "this is a source comment", 174 PackageLicenseConcluded: "GPL-2.0-or-later", 175 PackageLicenseInfoFromFiles: []string{ 176 "Apache-1.1", 177 "Apache-2.0", 178 "GPL-2.0-or-later", 179 }, 180 PackageLicenseDeclared: "Apache-2.0 OR GPL-2.0-or-later", 181 PackageLicenseComments: "this is a license comment(s)", 182 PackageCopyrightText: "Copyright (c) John Doe, Inc.", 183 PackageSummary: "this is a summary comment", 184 PackageDescription: "this is a description comment", 185 PackageComment: "this is a comment comment", 186 } 187 188 // what we want to get, as a buffer of bytes 189 want := bytes.NewBufferString(`PackageName: p1 190SPDXID: SPDXRef-p1 191PackageVersion: 0.1.0 192PackageFileName: p1-0.1.0-master.tar.gz 193PackageSupplier: NOASSERTION 194PackageOriginator: Organization: John Doe, Inc. 195PackageDownloadLocation: http://example.com/p1/p1-0.1.0-master.tar.gz 196PackageVerificationCode: 0123456789abcdef0123456789abcdef01234567 197PackageChecksum: SHA1: 85ed0817af83a24ad8da68c2b5094de69833983c 198PackageChecksum: SHA256: 11b6d3ee554eedf79299905a98f9b9a04e498210b59f15094c916c91d150efcd 199PackageChecksum: MD5: 624c1abb3664f4b35547e7c73864ad24 200PackageHomePage: http://example.com/p1 201PackageSourceInfo: this is a source comment 202PackageLicenseConcluded: GPL-2.0-or-later 203PackageLicenseInfoFromFiles: Apache-1.1 204PackageLicenseInfoFromFiles: Apache-2.0 205PackageLicenseInfoFromFiles: GPL-2.0-or-later 206PackageLicenseDeclared: Apache-2.0 OR GPL-2.0-or-later 207PackageLicenseComments: this is a license comment(s) 208PackageCopyrightText: Copyright (c) John Doe, Inc. 209PackageSummary: this is a summary comment 210PackageDescription: this is a description comment 211PackageComment: this is a comment comment 212 213`) 214 215 // render as buffer of bytes 216 var got bytes.Buffer 217 err := renderPackage2_1(pkg, &got) 218 if err != nil { 219 t.Errorf("Expected nil error, got %v", err) 220 } 221 222 // check that they match 223 c := bytes.Compare(want.Bytes(), got.Bytes()) 224 if c != 0 { 225 t.Errorf("Expected %v, got %v", want.String(), got.String()) 226 } 227} 228 229func TestSaver2_1PackageSavesTextCombo3(t *testing.T) { 230 // no package external refs 231 // test Supplier:Person, Originator:NOASSERTION 232 // FilesAnalyzed false, IsFilesAnalyzedTagPresent true 233 // PackageVerificationCodeExcludedFile is empty 234 235 pkg := &v2_1.Package{ 236 PackageName: "p1", 237 PackageSPDXIdentifier: common.ElementID("p1"), 238 PackageVersion: "0.1.0", 239 PackageFileName: "p1-0.1.0-master.tar.gz", 240 PackageSupplier: &common.Supplier{Supplier: "John Doe", SupplierType: "Person"}, 241 PackageOriginator: &common.Originator{Originator: "NOASSERTION"}, 242 PackageDownloadLocation: "http://example.com/p1/p1-0.1.0-master.tar.gz", 243 FilesAnalyzed: false, 244 IsFilesAnalyzedTagPresent: true, 245 // NOTE that verification code MUST be omitted from output 246 // since FilesAnalyzed is false 247 PackageVerificationCode: common.PackageVerificationCode{Value: "0123456789abcdef0123456789abcdef01234567"}, 248 PackageChecksums: []common.Checksum{ 249 { 250 Algorithm: common.SHA1, 251 Value: "85ed0817af83a24ad8da68c2b5094de69833983c", 252 }, 253 { 254 Algorithm: common.SHA256, 255 Value: "11b6d3ee554eedf79299905a98f9b9a04e498210b59f15094c916c91d150efcd", 256 }, 257 { 258 Algorithm: common.MD5, 259 Value: "624c1abb3664f4b35547e7c73864ad24", 260 }, 261 }, 262 PackageHomePage: "http://example.com/p1", 263 PackageSourceInfo: "this is a source comment", 264 PackageLicenseConcluded: "GPL-2.0-or-later", 265 // NOTE that license info from files MUST be omitted from output 266 // since FilesAnalyzed is false 267 PackageLicenseInfoFromFiles: []string{ 268 "Apache-1.1", 269 "Apache-2.0", 270 "GPL-2.0-or-later", 271 }, 272 PackageLicenseDeclared: "Apache-2.0 OR GPL-2.0-or-later", 273 PackageLicenseComments: "this is a license comment(s)", 274 PackageCopyrightText: "Copyright (c) John Doe, Inc.", 275 PackageSummary: "this is a summary comment", 276 PackageDescription: "this is a description comment", 277 PackageComment: "this is a comment comment", 278 } 279 280 // what we want to get, as a buffer of bytes 281 want := bytes.NewBufferString(`PackageName: p1 282SPDXID: SPDXRef-p1 283PackageVersion: 0.1.0 284PackageFileName: p1-0.1.0-master.tar.gz 285PackageSupplier: Person: John Doe 286PackageOriginator: NOASSERTION 287PackageDownloadLocation: http://example.com/p1/p1-0.1.0-master.tar.gz 288FilesAnalyzed: false 289PackageChecksum: SHA1: 85ed0817af83a24ad8da68c2b5094de69833983c 290PackageChecksum: SHA256: 11b6d3ee554eedf79299905a98f9b9a04e498210b59f15094c916c91d150efcd 291PackageChecksum: MD5: 624c1abb3664f4b35547e7c73864ad24 292PackageHomePage: http://example.com/p1 293PackageSourceInfo: this is a source comment 294PackageLicenseConcluded: GPL-2.0-or-later 295PackageLicenseDeclared: Apache-2.0 OR GPL-2.0-or-later 296PackageLicenseComments: this is a license comment(s) 297PackageCopyrightText: Copyright (c) John Doe, Inc. 298PackageSummary: this is a summary comment 299PackageDescription: this is a description comment 300PackageComment: this is a comment comment 301 302`) 303 304 // render as buffer of bytes 305 var got bytes.Buffer 306 err := renderPackage2_1(pkg, &got) 307 if err != nil { 308 t.Errorf("Expected nil error, got %v", err) 309 } 310 311 // check that they match 312 c := bytes.Compare(want.Bytes(), got.Bytes()) 313 if c != 0 { 314 t.Errorf("Expected %v, got %v", want.String(), got.String()) 315 } 316} 317 318func TestSaver2_1PackageSaveOmitsOptionalFieldsIfEmpty(t *testing.T) { 319 pkg := &v2_1.Package{ 320 PackageName: "p1", 321 PackageSPDXIdentifier: common.ElementID("p1"), 322 PackageDownloadLocation: "http://example.com/p1/p1-0.1.0-master.tar.gz", 323 FilesAnalyzed: false, 324 IsFilesAnalyzedTagPresent: true, 325 // NOTE that verification code MUST be omitted from output, 326 // even if present in model, since FilesAnalyzed is false 327 PackageLicenseConcluded: "GPL-2.0-or-later", 328 // NOTE that license info from files MUST be omitted from output 329 // even if present in model, since FilesAnalyzed is false 330 PackageLicenseInfoFromFiles: []string{ 331 "Apache-1.1", 332 "Apache-2.0", 333 "GPL-2.0-or-later", 334 }, 335 PackageLicenseDeclared: "Apache-2.0 OR GPL-2.0-or-later", 336 PackageCopyrightText: "Copyright (c) John Doe, Inc.", 337 } 338 339 // what we want to get, as a buffer of bytes 340 want := bytes.NewBufferString(`PackageName: p1 341SPDXID: SPDXRef-p1 342PackageDownloadLocation: http://example.com/p1/p1-0.1.0-master.tar.gz 343FilesAnalyzed: false 344PackageLicenseConcluded: GPL-2.0-or-later 345PackageLicenseDeclared: Apache-2.0 OR GPL-2.0-or-later 346PackageCopyrightText: Copyright (c) John Doe, Inc. 347 348`) 349 350 // render as buffer of bytes 351 var got bytes.Buffer 352 err := renderPackage2_1(pkg, &got) 353 if err != nil { 354 t.Errorf("Expected nil error, got %v", err) 355 } 356 357 // check that they match 358 c := bytes.Compare(want.Bytes(), got.Bytes()) 359 if c != 0 { 360 t.Errorf("Expected %v, got %v", want.String(), got.String()) 361 } 362} 363 364func TestSaver2_1PackageSavesFilesIfPresent(t *testing.T) { 365 f1 := &v2_1.File{ 366 FileName: "/tmp/whatever1.txt", 367 FileSPDXIdentifier: common.ElementID("File1231"), 368 Checksums: []common.Checksum{ 369 { 370 Algorithm: common.SHA1, 371 Value: "85ed0817af83a24ad8da68c2b5094de69833983c", 372 }, 373 }, 374 LicenseConcluded: "Apache-2.0", 375 LicenseInfoInFiles: []string{"Apache-2.0"}, 376 FileCopyrightText: "Copyright (c) Jane Doe", 377 } 378 379 f2 := &v2_1.File{ 380 FileName: "/tmp/whatever2.txt", 381 FileSPDXIdentifier: common.ElementID("File1232"), 382 Checksums: []common.Checksum{ 383 { 384 Algorithm: common.SHA1, 385 Value: "85ed0817af83a24ad8da68c2b5094de69833983d", 386 }, 387 }, 388 LicenseConcluded: "MIT", 389 LicenseInfoInFiles: []string{"MIT"}, 390 FileCopyrightText: "Copyright (c) John Doe", 391 } 392 393 pkg := &v2_1.Package{ 394 PackageName: "p1", 395 PackageSPDXIdentifier: common.ElementID("p1"), 396 PackageDownloadLocation: "http://example.com/p1/p1-0.1.0-master.tar.gz", 397 FilesAnalyzed: false, 398 IsFilesAnalyzedTagPresent: true, 399 // NOTE that verification code MUST be omitted from output, 400 // even if present in model, since FilesAnalyzed is false 401 PackageLicenseConcluded: "GPL-2.0-or-later", 402 // NOTE that license info from files MUST be omitted from output 403 // even if present in model, since FilesAnalyzed is false 404 PackageLicenseInfoFromFiles: []string{ 405 "Apache-1.1", 406 "Apache-2.0", 407 "GPL-2.0-or-later", 408 }, 409 PackageLicenseDeclared: "Apache-2.0 OR GPL-2.0-or-later", 410 PackageCopyrightText: "Copyright (c) John Doe, Inc.", 411 Files: []*v2_1.File{ 412 f1, 413 f2, 414 }, 415 } 416 417 // what we want to get, as a buffer of bytes 418 want := bytes.NewBufferString(`PackageName: p1 419SPDXID: SPDXRef-p1 420PackageDownloadLocation: http://example.com/p1/p1-0.1.0-master.tar.gz 421FilesAnalyzed: false 422PackageLicenseConcluded: GPL-2.0-or-later 423PackageLicenseDeclared: Apache-2.0 OR GPL-2.0-or-later 424PackageCopyrightText: Copyright (c) John Doe, Inc. 425 426FileName: /tmp/whatever1.txt 427SPDXID: SPDXRef-File1231 428FileChecksum: SHA1: 85ed0817af83a24ad8da68c2b5094de69833983c 429LicenseConcluded: Apache-2.0 430LicenseInfoInFile: Apache-2.0 431FileCopyrightText: Copyright (c) Jane Doe 432 433FileName: /tmp/whatever2.txt 434SPDXID: SPDXRef-File1232 435FileChecksum: SHA1: 85ed0817af83a24ad8da68c2b5094de69833983d 436LicenseConcluded: MIT 437LicenseInfoInFile: MIT 438FileCopyrightText: Copyright (c) John Doe 439 440`) 441 442 // render as buffer of bytes 443 var got bytes.Buffer 444 err := renderPackage2_1(pkg, &got) 445 if err != nil { 446 t.Errorf("Expected nil error, got %v", err) 447 } 448 449 // check that they match 450 c := bytes.Compare(want.Bytes(), got.Bytes()) 451 if c != 0 { 452 t.Errorf("Expected %v, got %v", want.String(), got.String()) 453 } 454} 455 456func TestSaver2_1PackageWrapsCopyrightMultiLine(t *testing.T) { 457 pkg := &v2_1.Package{ 458 PackageName: "p1", 459 PackageSPDXIdentifier: common.ElementID("p1"), 460 PackageDownloadLocation: "http://example.com/p1/p1-0.1.0-master.tar.gz", 461 FilesAnalyzed: false, 462 IsFilesAnalyzedTagPresent: true, 463 PackageLicenseConcluded: "GPL-2.0-or-later", 464 PackageLicenseInfoFromFiles: []string{ 465 "Apache-1.1", 466 "Apache-2.0", 467 "GPL-2.0-or-later", 468 }, 469 PackageLicenseDeclared: "Apache-2.0 OR GPL-2.0-or-later", 470 PackageCopyrightText: `Copyright (c) John Doe, Inc. 471Copyright Jane Doe`, 472 } 473 474 // what we want to get, as a buffer of bytes 475 want := bytes.NewBufferString(`PackageName: p1 476SPDXID: SPDXRef-p1 477PackageDownloadLocation: http://example.com/p1/p1-0.1.0-master.tar.gz 478FilesAnalyzed: false 479PackageLicenseConcluded: GPL-2.0-or-later 480PackageLicenseDeclared: Apache-2.0 OR GPL-2.0-or-later 481PackageCopyrightText: <text>Copyright (c) John Doe, Inc. 482Copyright Jane Doe</text> 483 484`) 485 486 // render as buffer of bytes 487 var got bytes.Buffer 488 err := renderPackage2_1(pkg, &got) 489 if err != nil { 490 t.Errorf("Expected nil error, got %v", err) 491 } 492 493 // check that they match 494 c := bytes.Compare(want.Bytes(), got.Bytes()) 495 if c != 0 { 496 t.Errorf("Expected %v, got %v", want.String(), got.String()) 497 } 498} 499