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