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