1// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 2 3package licensediff 4 5import ( 6 "testing" 7 8 "github.com/spdx/tools-golang/spdx/common" 9 "github.com/spdx/tools-golang/spdx/v2_1" 10 "github.com/spdx/tools-golang/spdx/v2_2" 11 "github.com/spdx/tools-golang/spdx/v2_3" 12) 13 14// ===== 2.1 License diff top-level function tests ===== 15func Test2_1DifferCanCreateDiffPairs(t *testing.T) { 16 // create files to be used in diff 17 // f1 will be identical in both 18 f1 := &v2_1.File{ 19 FileName: "/project/file1.txt", 20 FileSPDXIdentifier: common.ElementID("File561"), 21 Checksums: []common.Checksum{{Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", Algorithm: common.SHA1}}, 22 LicenseConcluded: "Apache-2.0", 23 LicenseInfoInFiles: []string{ 24 "LicenseRef-We-will-ignore-LicenseInfoInFiles", 25 }, 26 FileCopyrightText: "We'll ignore copyright values", 27 } 28 29 // f2 will only appear in the first Package 30 f2 := &v2_1.File{ 31 FileName: "/project/file2.txt", 32 FileSPDXIdentifier: common.ElementID("File562"), 33 Checksums: []common.Checksum{{Value: "066c5139bd9a43d15812ec1a1755b08ccf199824", Algorithm: common.SHA1}}, 34 LicenseConcluded: "GPL-2.0-or-later", 35 LicenseInfoInFiles: []string{ 36 "NOASSERTION", 37 }, 38 FileCopyrightText: "NOASSERTION", 39 } 40 41 // f3 will only appear in the second Package 42 f3 := &v2_1.File{ 43 FileName: "/project/file3.txt", 44 FileSPDXIdentifier: common.ElementID("File563"), 45 Checksums: []common.Checksum{{Value: "bd0f4863b15fad2b79b35303af54fcb5baaf7c68", Algorithm: common.SHA1}}, 46 LicenseConcluded: "MPL-2.0", 47 LicenseInfoInFiles: []string{ 48 "NOASSERTION", 49 }, 50 FileCopyrightText: "NOASSERTION", 51 } 52 53 // f4_1 and f4_2 will appear in first and second, 54 // with same name, same hash and different license 55 f4_1 := &v2_1.File{ 56 FileName: "/project/file4.txt", 57 FileSPDXIdentifier: common.ElementID("File564"), 58 Checksums: []common.Checksum{{Value: "bc417a575ceae93435bcb7bfd382ac28cbdaa8b5", Algorithm: common.SHA1}}, 59 LicenseConcluded: "MIT", 60 LicenseInfoInFiles: []string{ 61 "NOASSERTION", 62 }, 63 FileCopyrightText: "NOASSERTION", 64 } 65 f4_2 := &v2_1.File{ 66 FileName: "/project/file4.txt", 67 FileSPDXIdentifier: common.ElementID("File564"), 68 Checksums: []common.Checksum{{Value: "bc417a575ceae93435bcb7bfd382ac28cbdaa8b5", Algorithm: common.SHA1}}, 69 LicenseConcluded: "Apache-2.0 AND MIT", 70 LicenseInfoInFiles: []string{ 71 "NOASSERTION", 72 }, 73 FileCopyrightText: "NOASSERTION", 74 } 75 76 // f5_1 and f5_2 will appear in first and second, 77 // with same name, different hash and same license 78 f5_1 := &v2_1.File{ 79 FileName: "/project/file5.txt", 80 FileSPDXIdentifier: common.ElementID("File565"), 81 Checksums: []common.Checksum{{Value: "ba226db943bbbf455da77afab6f16dbab156d000", Algorithm: common.SHA1}}, 82 LicenseConcluded: "BSD-3-Clause", 83 LicenseInfoInFiles: []string{ 84 "NOASSERTION", 85 }, 86 FileCopyrightText: "NOASSERTION", 87 } 88 f5_2 := &v2_1.File{ 89 FileName: "/project/file5.txt", 90 FileSPDXIdentifier: common.ElementID("File565"), 91 Checksums: []common.Checksum{{Value: "b6e0ec7d085c5699b46f6f8d425413702652874d", Algorithm: common.SHA1}}, 92 LicenseConcluded: "BSD-3-Clause", 93 LicenseInfoInFiles: []string{ 94 "NOASSERTION", 95 }, 96 FileCopyrightText: "NOASSERTION", 97 } 98 99 // f6_1 and f6_2 will appear in first and second, 100 // with same name, different hash and different license 101 f6_1 := &v2_1.File{ 102 FileName: "/project/file6.txt", 103 FileSPDXIdentifier: common.ElementID("File566"), 104 Checksums: []common.Checksum{{Value: "ba226db943bbbf455da77afab6f16dbab156d000", Algorithm: common.SHA1}}, 105 LicenseConcluded: "CC0-1.0", 106 LicenseInfoInFiles: []string{ 107 "NOASSERTION", 108 }, 109 FileCopyrightText: "NOASSERTION", 110 } 111 f6_2 := &v2_1.File{ 112 FileName: "/project/file6.txt", 113 FileSPDXIdentifier: common.ElementID("File566"), 114 Checksums: []common.Checksum{{Value: "b6e0ec7d085c5699b46f6f8d425413702652874d", Algorithm: common.SHA1}}, 115 LicenseConcluded: "Unlicense", 116 LicenseInfoInFiles: []string{ 117 "NOASSERTION", 118 }, 119 FileCopyrightText: "NOASSERTION", 120 } 121 122 // create Packages 123 p1 := &v2_1.Package{ 124 PackageName: "p1", 125 PackageSPDXIdentifier: common.ElementID("p1"), 126 PackageDownloadLocation: "NOASSERTION", 127 FilesAnalyzed: true, 128 IsFilesAnalyzedTagPresent: true, 129 // fake the verification code for present purposes 130 PackageVerificationCode: common.PackageVerificationCode{Value: "abc123abc123"}, 131 PackageLicenseConcluded: "NOASSERTION", 132 PackageLicenseInfoFromFiles: []string{ 133 "NOASSERTION", 134 }, 135 PackageLicenseDeclared: "NOASSERTION", 136 PackageCopyrightText: "NOASSERTION", 137 Files: []*v2_1.File{ 138 f1, 139 f2, 140 f4_1, 141 f5_1, 142 f6_1, 143 }, 144 } 145 p2 := &v2_1.Package{ 146 PackageName: "p2", 147 PackageSPDXIdentifier: common.ElementID("p2"), 148 PackageDownloadLocation: "NOASSERTION", 149 FilesAnalyzed: true, 150 IsFilesAnalyzedTagPresent: true, 151 // fake the verification code for present purposes 152 PackageVerificationCode: common.PackageVerificationCode{Value: "def456def456"}, 153 PackageLicenseConcluded: "NOASSERTION", 154 PackageLicenseInfoFromFiles: []string{ 155 "NOASSERTION", 156 }, 157 PackageLicenseDeclared: "NOASSERTION", 158 PackageCopyrightText: "NOASSERTION", 159 Files: []*v2_1.File{ 160 f1, 161 f3, 162 f4_2, 163 f5_2, 164 f6_2, 165 }, 166 } 167 168 // run the diff between the two packages 169 diffMap, err := MakePairs2_1(p1, p2) 170 if err != nil { 171 t.Fatalf("Expected nil error, got %v", err) 172 } 173 174 // check that the diff results are what we expect 175 // there should be 6 entries, one for each unique filename 176 if len(diffMap) != 6 { 177 t.Fatalf("Expected %d, got %d", 6, len(diffMap)) 178 } 179 180 // check each filename is present, and check its pair 181 // pair 1 -- same in both 182 pair1, ok := diffMap["/project/file1.txt"] 183 if !ok { 184 t.Fatalf("Couldn't get pair1") 185 } 186 if pair1.First != f1.LicenseConcluded { 187 t.Errorf("Expected %s, got %s", f1.LicenseConcluded, pair1.First) 188 } 189 if pair1.Second != f1.LicenseConcluded { 190 t.Errorf("Expected %s, got %s", f2.LicenseConcluded, pair1.Second) 191 } 192 193 // pair 2 -- only in first 194 pair2, ok := diffMap["/project/file2.txt"] 195 if !ok { 196 t.Fatalf("Couldn't get pair2") 197 } 198 if pair2.First != f2.LicenseConcluded { 199 t.Errorf("Expected %s, got %s", f2.LicenseConcluded, pair2.First) 200 } 201 if pair2.Second != "" { 202 t.Errorf("Expected %s, got %s", "", pair2.Second) 203 } 204 205 // pair 3 -- only in second 206 pair3, ok := diffMap["/project/file3.txt"] 207 if !ok { 208 t.Fatalf("Couldn't get pair3") 209 } 210 if pair3.First != "" { 211 t.Errorf("Expected %s, got %s", "", pair3.First) 212 } 213 if pair3.Second != f3.LicenseConcluded { 214 t.Errorf("Expected %s, got %s", f3.LicenseConcluded, pair3.Second) 215 } 216 217 // pair 4 -- in both but different license 218 pair4, ok := diffMap["/project/file4.txt"] 219 if !ok { 220 t.Fatalf("Couldn't get pair4") 221 } 222 if pair4.First != f4_1.LicenseConcluded { 223 t.Errorf("Expected %s, got %s", f4_1.LicenseConcluded, pair4.First) 224 } 225 if pair4.Second != f4_2.LicenseConcluded { 226 t.Errorf("Expected %s, got %s", f4_2.LicenseConcluded, pair4.Second) 227 } 228 229 // pair 5 -- in both but different hash, same license 230 pair5, ok := diffMap["/project/file5.txt"] 231 if !ok { 232 t.Fatalf("Couldn't get pair5") 233 } 234 if pair5.First != f5_1.LicenseConcluded { 235 t.Errorf("Expected %s, got %s", f5_1.LicenseConcluded, pair5.First) 236 } 237 if pair5.Second != f5_2.LicenseConcluded { 238 t.Errorf("Expected %s, got %s", f5_2.LicenseConcluded, pair5.Second) 239 } 240 241 // pair 6 -- in both but different hash, different license 242 pair6, ok := diffMap["/project/file6.txt"] 243 if !ok { 244 t.Fatalf("Couldn't get pair6") 245 } 246 if pair6.First != f6_1.LicenseConcluded { 247 t.Errorf("Expected %s, got %s", f6_1.LicenseConcluded, pair6.First) 248 } 249 if pair6.Second != f6_2.LicenseConcluded { 250 t.Errorf("Expected %s, got %s", f6_2.LicenseConcluded, pair6.Second) 251 } 252} 253 254func Test2_1DifferCanCreateDiffStructuredResults(t *testing.T) { 255 // create files to be used in diff 256 // f1 will be identical in both 257 f1 := &v2_1.File{ 258 FileName: "/project/file1.txt", 259 FileSPDXIdentifier: common.ElementID("File561"), 260 Checksums: []common.Checksum{{Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", Algorithm: common.SHA1}}, 261 LicenseConcluded: "Apache-2.0", 262 LicenseInfoInFiles: []string{ 263 "LicenseRef-We-will-ignore-LicenseInfoInFiles", 264 }, 265 FileCopyrightText: "We'll ignore copyright values", 266 } 267 268 // f2 will only appear in the first Package 269 f2 := &v2_1.File{ 270 FileName: "/project/file2.txt", 271 FileSPDXIdentifier: common.ElementID("File562"), 272 Checksums: []common.Checksum{{Value: "066c5139bd9a43d15812ec1a1755b08ccf199824", Algorithm: common.SHA1}}, 273 LicenseConcluded: "GPL-2.0-or-later", 274 LicenseInfoInFiles: []string{ 275 "NOASSERTION", 276 }, 277 FileCopyrightText: "NOASSERTION", 278 } 279 280 // f3 will only appear in the second Package 281 f3 := &v2_1.File{ 282 FileName: "/project/file3.txt", 283 FileSPDXIdentifier: common.ElementID("File563"), 284 Checksums: []common.Checksum{{Value: "bd0f4863b15fad2b79b35303af54fcb5baaf7c68", Algorithm: common.SHA1}}, 285 LicenseConcluded: "MPL-2.0", 286 LicenseInfoInFiles: []string{ 287 "NOASSERTION", 288 }, 289 FileCopyrightText: "NOASSERTION", 290 } 291 292 // f4_1 and f4_2 will appear in first and second, 293 // with same name, same hash and different license 294 f4_1 := &v2_1.File{ 295 FileName: "/project/file4.txt", 296 FileSPDXIdentifier: common.ElementID("File564"), 297 Checksums: []common.Checksum{{Value: "bc417a575ceae93435bcb7bfd382ac28cbdaa8b5", Algorithm: common.SHA1}}, 298 LicenseConcluded: "MIT", 299 LicenseInfoInFiles: []string{ 300 "NOASSERTION", 301 }, 302 FileCopyrightText: "NOASSERTION", 303 } 304 f4_2 := &v2_1.File{ 305 FileName: "/project/file4.txt", 306 FileSPDXIdentifier: common.ElementID("File564"), 307 Checksums: []common.Checksum{{Value: "bc417a575ceae93435bcb7bfd382ac28cbdaa8b5", Algorithm: common.SHA1}}, 308 LicenseConcluded: "Apache-2.0 AND MIT", 309 LicenseInfoInFiles: []string{ 310 "NOASSERTION", 311 }, 312 FileCopyrightText: "NOASSERTION", 313 } 314 315 // f5_1 and f5_2 will appear in first and second, 316 // with same name, different hash and same license 317 f5_1 := &v2_1.File{ 318 FileName: "/project/file5.txt", 319 FileSPDXIdentifier: common.ElementID("File565"), 320 Checksums: []common.Checksum{{Value: "ba226db943bbbf455da77afab6f16dbab156d000", Algorithm: common.SHA1}}, 321 LicenseConcluded: "BSD-3-Clause", 322 LicenseInfoInFiles: []string{ 323 "NOASSERTION", 324 }, 325 FileCopyrightText: "NOASSERTION", 326 } 327 f5_2 := &v2_1.File{ 328 FileName: "/project/file5.txt", 329 FileSPDXIdentifier: common.ElementID("File565"), 330 Checksums: []common.Checksum{{Value: "b6e0ec7d085c5699b46f6f8d425413702652874d", Algorithm: common.SHA1}}, 331 LicenseConcluded: "BSD-3-Clause", 332 LicenseInfoInFiles: []string{ 333 "NOASSERTION", 334 }, 335 FileCopyrightText: "NOASSERTION", 336 } 337 338 // f6_1 and f6_2 will appear in first and second, 339 // with same name, different hash and different license 340 f6_1 := &v2_1.File{ 341 FileName: "/project/file6.txt", 342 FileSPDXIdentifier: common.ElementID("File566"), 343 Checksums: []common.Checksum{{Value: "ba226db943bbbf455da77afab6f16dbab156d000", Algorithm: common.SHA1}}, 344 LicenseConcluded: "CC0-1.0", 345 LicenseInfoInFiles: []string{ 346 "NOASSERTION", 347 }, 348 FileCopyrightText: "NOASSERTION", 349 } 350 f6_2 := &v2_1.File{ 351 FileName: "/project/file6.txt", 352 FileSPDXIdentifier: common.ElementID("File566"), 353 Checksums: []common.Checksum{{Value: "b6e0ec7d085c5699b46f6f8d425413702652874d", Algorithm: common.SHA1}}, 354 LicenseConcluded: "Unlicense", 355 LicenseInfoInFiles: []string{ 356 "NOASSERTION", 357 }, 358 FileCopyrightText: "NOASSERTION", 359 } 360 361 // create Packages 362 p1 := &v2_1.Package{ 363 PackageName: "p1", 364 PackageSPDXIdentifier: common.ElementID("p1"), 365 PackageDownloadLocation: "NOASSERTION", 366 FilesAnalyzed: true, 367 IsFilesAnalyzedTagPresent: true, 368 // fake the verification code for present purposes 369 PackageVerificationCode: common.PackageVerificationCode{Value: "abc123abc123"}, 370 PackageLicenseConcluded: "NOASSERTION", 371 PackageLicenseInfoFromFiles: []string{ 372 "NOASSERTION", 373 }, 374 PackageLicenseDeclared: "NOASSERTION", 375 PackageCopyrightText: "NOASSERTION", 376 Files: []*v2_1.File{ 377 f1, 378 f2, 379 f4_1, 380 f5_1, 381 f6_1, 382 }, 383 } 384 p2 := &v2_1.Package{ 385 PackageName: "p2", 386 PackageSPDXIdentifier: common.ElementID("p2"), 387 PackageDownloadLocation: "NOASSERTION", 388 FilesAnalyzed: true, 389 IsFilesAnalyzedTagPresent: true, 390 // fake the verification code for present purposes 391 PackageVerificationCode: common.PackageVerificationCode{Value: "def456def456"}, 392 PackageLicenseConcluded: "NOASSERTION", 393 PackageLicenseInfoFromFiles: []string{ 394 "NOASSERTION", 395 }, 396 PackageLicenseDeclared: "NOASSERTION", 397 PackageCopyrightText: "NOASSERTION", 398 Files: []*v2_1.File{ 399 f1, 400 f3, 401 f4_2, 402 f5_2, 403 f6_2, 404 }, 405 } 406 407 // run the diff between the two packages 408 diffMap, err := MakePairs2_1(p1, p2) 409 if err != nil { 410 t.Fatalf("Expected nil error, got %v", err) 411 } 412 413 // now, create the LicenseDiff structured results from the pairs 414 diffResults, err := MakeResults(diffMap) 415 if err != nil { 416 t.Fatalf("Expected nil error, got %v", err) 417 } 418 419 // check that the diff results are the expected lengths 420 if len(diffResults.InBothChanged) != 2 { 421 t.Fatalf("Expected %d, got %d", 2, len(diffResults.InBothChanged)) 422 } 423 if len(diffResults.InBothSame) != 2 { 424 t.Fatalf("Expected %d, got %d", 2, len(diffResults.InBothSame)) 425 } 426 if len(diffResults.InFirstOnly) != 1 { 427 t.Fatalf("Expected %d, got %d", 1, len(diffResults.InFirstOnly)) 428 } 429 if len(diffResults.InSecondOnly) != 1 { 430 t.Fatalf("Expected %d, got %d", 1, len(diffResults.InSecondOnly)) 431 } 432 433 // check each filename is present where it belongs, and check license(s) 434 435 // in both and different license: f4 and f6 436 // filename will map to a LicensePair 437 check4, ok := diffResults.InBothChanged["/project/file4.txt"] 438 if !ok { 439 t.Fatalf("Couldn't get check4") 440 } 441 if check4.First != f4_1.LicenseConcluded { 442 t.Errorf("Expected %s, got %s", f4_1.LicenseConcluded, check4.First) 443 } 444 if check4.Second != f4_2.LicenseConcluded { 445 t.Errorf("Expected %s, got %s", f4_2.LicenseConcluded, check4.Second) 446 } 447 check6, ok := diffResults.InBothChanged["/project/file6.txt"] 448 if !ok { 449 t.Fatalf("Couldn't get check6") 450 } 451 if check6.First != f6_1.LicenseConcluded { 452 t.Errorf("Expected %s, got %s", f6_1.LicenseConcluded, check6.First) 453 } 454 if check6.Second != f6_2.LicenseConcluded { 455 t.Errorf("Expected %s, got %s", f6_2.LicenseConcluded, check6.Second) 456 } 457 458 // in both and same license: f1 and f5 459 // filename will map to a string 460 check1, ok := diffResults.InBothSame["/project/file1.txt"] 461 if !ok { 462 t.Fatalf("Couldn't get check1") 463 } 464 if check1 != f1.LicenseConcluded { 465 t.Errorf("Expected %s, got %s", f1.LicenseConcluded, check1) 466 } 467 check5, ok := diffResults.InBothSame["/project/file5.txt"] 468 if !ok { 469 t.Fatalf("Couldn't get check5") 470 } 471 if check5 != f5_1.LicenseConcluded { 472 t.Errorf("Expected %s, got %s", f5_1.LicenseConcluded, check5) 473 } 474 if check5 != f5_2.LicenseConcluded { 475 t.Errorf("Expected %s, got %s", f5_2.LicenseConcluded, check5) 476 } 477 478 // in first only: f2 479 // filename will map to a string 480 check2, ok := diffResults.InFirstOnly["/project/file2.txt"] 481 if !ok { 482 t.Fatalf("Couldn't get check2") 483 } 484 if check2 != f2.LicenseConcluded { 485 t.Errorf("Expected %s, got %s", f2.LicenseConcluded, check2) 486 } 487 488 // in second only: f3 489 // filename will map to a string 490 check3, ok := diffResults.InSecondOnly["/project/file3.txt"] 491 if !ok { 492 t.Fatalf("Couldn't get check3") 493 } 494 if check3 != f3.LicenseConcluded { 495 t.Errorf("Expected %s, got %s", f3.LicenseConcluded, check2) 496 } 497 498} 499 500// ===== 2.2 License diff top-level function tests ===== 501func Test2_2DifferCanCreateDiffPairs(t *testing.T) { 502 // create files to be used in diff 503 // f1 will be identical in both 504 f1 := &v2_2.File{ 505 FileName: "/project/file1.txt", 506 FileSPDXIdentifier: common.ElementID("File561"), 507 Checksums: []common.Checksum{{ 508 Algorithm: common.SHA1, 509 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 510 }, 511 }, 512 LicenseConcluded: "Apache-2.0", 513 LicenseInfoInFiles: []string{ 514 "LicenseRef-We-will-ignore-LicenseInfoInFiles", 515 }, 516 FileCopyrightText: "We'll ignore copyright values", 517 } 518 519 // f2 will only appear in the first Package 520 f2 := &v2_2.File{ 521 FileName: "/project/file2.txt", 522 FileSPDXIdentifier: common.ElementID("File562"), 523 Checksums: []common.Checksum{{ 524 Algorithm: common.SHA1, 525 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 526 }, 527 }, 528 LicenseConcluded: "GPL-2.0-or-later", 529 LicenseInfoInFiles: []string{ 530 "NOASSERTION", 531 }, 532 FileCopyrightText: "NOASSERTION", 533 } 534 535 // f3 will only appear in the second Package 536 f3 := &v2_2.File{ 537 FileName: "/project/file3.txt", 538 FileSPDXIdentifier: common.ElementID("File563"), 539 Checksums: []common.Checksum{{ 540 Algorithm: common.SHA1, 541 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 542 }, 543 }, 544 LicenseConcluded: "MPL-2.0", 545 LicenseInfoInFiles: []string{ 546 "NOASSERTION", 547 }, 548 FileCopyrightText: "NOASSERTION", 549 } 550 551 // f4_1 and f4_2 will appear in first and second, 552 // with same name, same hash and different license 553 f4_1 := &v2_2.File{ 554 FileName: "/project/file4.txt", 555 FileSPDXIdentifier: common.ElementID("File564"), 556 Checksums: []common.Checksum{{ 557 Algorithm: common.SHA1, 558 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 559 }, 560 }, 561 LicenseConcluded: "MIT", 562 LicenseInfoInFiles: []string{ 563 "NOASSERTION", 564 }, 565 FileCopyrightText: "NOASSERTION", 566 } 567 f4_2 := &v2_2.File{ 568 FileName: "/project/file4.txt", 569 FileSPDXIdentifier: common.ElementID("File564"), 570 Checksums: []common.Checksum{{ 571 Algorithm: common.SHA1, 572 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 573 }, 574 }, 575 LicenseConcluded: "Apache-2.0 AND MIT", 576 LicenseInfoInFiles: []string{ 577 "NOASSERTION", 578 }, 579 FileCopyrightText: "NOASSERTION", 580 } 581 582 // f5_1 and f5_2 will appear in first and second, 583 // with same name, different hash and same license 584 f5_1 := &v2_2.File{ 585 FileName: "/project/file5.txt", 586 FileSPDXIdentifier: common.ElementID("File565"), 587 Checksums: []common.Checksum{{ 588 Algorithm: common.SHA1, 589 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 590 }, 591 }, 592 LicenseConcluded: "BSD-3-Clause", 593 LicenseInfoInFiles: []string{ 594 "NOASSERTION", 595 }, 596 FileCopyrightText: "NOASSERTION", 597 } 598 f5_2 := &v2_2.File{ 599 FileName: "/project/file5.txt", 600 FileSPDXIdentifier: common.ElementID("File565"), 601 Checksums: []common.Checksum{{ 602 Algorithm: common.SHA1, 603 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 604 }, 605 }, 606 LicenseConcluded: "BSD-3-Clause", 607 LicenseInfoInFiles: []string{ 608 "NOASSERTION", 609 }, 610 FileCopyrightText: "NOASSERTION", 611 } 612 613 // f6_1 and f6_2 will appear in first and second, 614 // with same name, different hash and different license 615 f6_1 := &v2_2.File{ 616 FileName: "/project/file6.txt", 617 FileSPDXIdentifier: common.ElementID("File566"), 618 Checksums: []common.Checksum{{ 619 Algorithm: common.SHA1, 620 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 621 }, 622 }, 623 LicenseConcluded: "CC0-1.0", 624 LicenseInfoInFiles: []string{ 625 "NOASSERTION", 626 }, 627 FileCopyrightText: "NOASSERTION", 628 } 629 f6_2 := &v2_2.File{ 630 FileName: "/project/file6.txt", 631 FileSPDXIdentifier: common.ElementID("File566"), 632 Checksums: []common.Checksum{{ 633 Algorithm: common.SHA1, 634 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 635 }, 636 }, 637 LicenseConcluded: "Unlicense", 638 LicenseInfoInFiles: []string{ 639 "NOASSERTION", 640 }, 641 FileCopyrightText: "NOASSERTION", 642 } 643 644 // create Packages 645 p1 := &v2_2.Package{ 646 PackageName: "p1", 647 PackageSPDXIdentifier: common.ElementID("p1"), 648 PackageDownloadLocation: "NOASSERTION", 649 FilesAnalyzed: true, 650 IsFilesAnalyzedTagPresent: true, 651 // fake the verification code for present purposes 652 PackageVerificationCode: common.PackageVerificationCode{Value: "abc123abc123"}, 653 PackageLicenseConcluded: "NOASSERTION", 654 PackageLicenseInfoFromFiles: []string{ 655 "NOASSERTION", 656 }, 657 PackageLicenseDeclared: "NOASSERTION", 658 PackageCopyrightText: "NOASSERTION", 659 Files: []*v2_2.File{ 660 f1, 661 f2, 662 f4_1, 663 f5_1, 664 f6_1, 665 }, 666 } 667 p2 := &v2_2.Package{ 668 PackageName: "p2", 669 PackageSPDXIdentifier: common.ElementID("p2"), 670 PackageDownloadLocation: "NOASSERTION", 671 FilesAnalyzed: true, 672 IsFilesAnalyzedTagPresent: true, 673 // fake the verification code for present purposes 674 PackageVerificationCode: common.PackageVerificationCode{Value: "def456def456"}, 675 PackageLicenseConcluded: "NOASSERTION", 676 PackageLicenseInfoFromFiles: []string{ 677 "NOASSERTION", 678 }, 679 PackageLicenseDeclared: "NOASSERTION", 680 PackageCopyrightText: "NOASSERTION", 681 Files: []*v2_2.File{ 682 f1, 683 f3, 684 f4_2, 685 f5_2, 686 f6_2, 687 }, 688 } 689 690 // run the diff between the two packages 691 diffMap, err := MakePairs2_2(p1, p2) 692 if err != nil { 693 t.Fatalf("Expected nil error, got %v", err) 694 } 695 696 // check that the diff results are what we expect 697 // there should be 6 entries, one for each unique filename 698 if len(diffMap) != 6 { 699 t.Fatalf("Expected %d, got %d", 6, len(diffMap)) 700 } 701 702 // check each filename is present, and check its pair 703 // pair 1 -- same in both 704 pair1, ok := diffMap["/project/file1.txt"] 705 if !ok { 706 t.Fatalf("Couldn't get pair1") 707 } 708 if pair1.First != f1.LicenseConcluded { 709 t.Errorf("Expected %s, got %s", f1.LicenseConcluded, pair1.First) 710 } 711 if pair1.Second != f1.LicenseConcluded { 712 t.Errorf("Expected %s, got %s", f2.LicenseConcluded, pair1.Second) 713 } 714 715 // pair 2 -- only in first 716 pair2, ok := diffMap["/project/file2.txt"] 717 if !ok { 718 t.Fatalf("Couldn't get pair2") 719 } 720 if pair2.First != f2.LicenseConcluded { 721 t.Errorf("Expected %s, got %s", f2.LicenseConcluded, pair2.First) 722 } 723 if pair2.Second != "" { 724 t.Errorf("Expected %s, got %s", "", pair2.Second) 725 } 726 727 // pair 3 -- only in second 728 pair3, ok := diffMap["/project/file3.txt"] 729 if !ok { 730 t.Fatalf("Couldn't get pair3") 731 } 732 if pair3.First != "" { 733 t.Errorf("Expected %s, got %s", "", pair3.First) 734 } 735 if pair3.Second != f3.LicenseConcluded { 736 t.Errorf("Expected %s, got %s", f3.LicenseConcluded, pair3.Second) 737 } 738 739 // pair 4 -- in both but different license 740 pair4, ok := diffMap["/project/file4.txt"] 741 if !ok { 742 t.Fatalf("Couldn't get pair4") 743 } 744 if pair4.First != f4_1.LicenseConcluded { 745 t.Errorf("Expected %s, got %s", f4_1.LicenseConcluded, pair4.First) 746 } 747 if pair4.Second != f4_2.LicenseConcluded { 748 t.Errorf("Expected %s, got %s", f4_2.LicenseConcluded, pair4.Second) 749 } 750 751 // pair 5 -- in both but different hash, same license 752 pair5, ok := diffMap["/project/file5.txt"] 753 if !ok { 754 t.Fatalf("Couldn't get pair5") 755 } 756 if pair5.First != f5_1.LicenseConcluded { 757 t.Errorf("Expected %s, got %s", f5_1.LicenseConcluded, pair5.First) 758 } 759 if pair5.Second != f5_2.LicenseConcluded { 760 t.Errorf("Expected %s, got %s", f5_2.LicenseConcluded, pair5.Second) 761 } 762 763 // pair 6 -- in both but different hash, different license 764 pair6, ok := diffMap["/project/file6.txt"] 765 if !ok { 766 t.Fatalf("Couldn't get pair6") 767 } 768 if pair6.First != f6_1.LicenseConcluded { 769 t.Errorf("Expected %s, got %s", f6_1.LicenseConcluded, pair6.First) 770 } 771 if pair6.Second != f6_2.LicenseConcluded { 772 t.Errorf("Expected %s, got %s", f6_2.LicenseConcluded, pair6.Second) 773 } 774} 775 776func Test2_2DifferCanCreateDiffStructuredResults(t *testing.T) { 777 // create files to be used in diff 778 // f1 will be identical in both 779 f1 := &v2_2.File{ 780 FileName: "/project/file1.txt", 781 FileSPDXIdentifier: common.ElementID("File561"), 782 Checksums: []common.Checksum{{ 783 Algorithm: common.SHA1, 784 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 785 }, 786 }, 787 LicenseConcluded: "Apache-2.0", 788 LicenseInfoInFiles: []string{ 789 "LicenseRef-We-will-ignore-LicenseInfoInFiles", 790 }, 791 FileCopyrightText: "We'll ignore copyright values", 792 } 793 794 // f2 will only appear in the first Package 795 f2 := &v2_2.File{ 796 FileName: "/project/file2.txt", 797 FileSPDXIdentifier: common.ElementID("File562"), 798 Checksums: []common.Checksum{{ 799 Algorithm: common.SHA1, 800 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 801 }, 802 }, 803 LicenseConcluded: "GPL-2.0-or-later", 804 LicenseInfoInFiles: []string{ 805 "NOASSERTION", 806 }, 807 FileCopyrightText: "NOASSERTION", 808 } 809 810 // f3 will only appear in the second Package 811 f3 := &v2_2.File{ 812 FileName: "/project/file3.txt", 813 FileSPDXIdentifier: common.ElementID("File563"), 814 Checksums: []common.Checksum{{ 815 Algorithm: common.SHA1, 816 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 817 }, 818 }, 819 LicenseConcluded: "MPL-2.0", 820 LicenseInfoInFiles: []string{ 821 "NOASSERTION", 822 }, 823 FileCopyrightText: "NOASSERTION", 824 } 825 826 // f4_1 and f4_2 will appear in first and second, 827 // with same name, same hash and different license 828 f4_1 := &v2_2.File{ 829 FileName: "/project/file4.txt", 830 FileSPDXIdentifier: common.ElementID("File564"), 831 Checksums: []common.Checksum{{ 832 Algorithm: common.SHA1, 833 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 834 }, 835 }, 836 LicenseConcluded: "MIT", 837 LicenseInfoInFiles: []string{ 838 "NOASSERTION", 839 }, 840 FileCopyrightText: "NOASSERTION", 841 } 842 f4_2 := &v2_2.File{ 843 FileName: "/project/file4.txt", 844 FileSPDXIdentifier: common.ElementID("File564"), 845 Checksums: []common.Checksum{{ 846 Algorithm: common.SHA1, 847 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 848 }, 849 }, 850 LicenseConcluded: "Apache-2.0 AND MIT", 851 LicenseInfoInFiles: []string{ 852 "NOASSERTION", 853 }, 854 FileCopyrightText: "NOASSERTION", 855 } 856 857 // f5_1 and f5_2 will appear in first and second, 858 // with same name, different hash and same license 859 f5_1 := &v2_2.File{ 860 FileName: "/project/file5.txt", 861 FileSPDXIdentifier: common.ElementID("File565"), 862 LicenseConcluded: "BSD-3-Clause", 863 LicenseInfoInFiles: []string{ 864 "NOASSERTION", 865 }, 866 FileCopyrightText: "NOASSERTION", 867 } 868 f5_2 := &v2_2.File{ 869 FileName: "/project/file5.txt", 870 FileSPDXIdentifier: common.ElementID("File565"), 871 Checksums: []common.Checksum{{ 872 Algorithm: common.SHA1, 873 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 874 }, 875 }, 876 877 LicenseConcluded: "BSD-3-Clause", 878 LicenseInfoInFiles: []string{ 879 "NOASSERTION", 880 }, 881 FileCopyrightText: "NOASSERTION", 882 } 883 884 // f6_1 and f6_2 will appear in first and second, 885 // with same name, different hash and different license 886 f6_1 := &v2_2.File{ 887 FileName: "/project/file6.txt", 888 FileSPDXIdentifier: common.ElementID("File566"), 889 Checksums: []common.Checksum{{ 890 Algorithm: common.SHA1, 891 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 892 }, 893 }, 894 LicenseConcluded: "CC0-1.0", 895 LicenseInfoInFiles: []string{ 896 "NOASSERTION", 897 }, 898 FileCopyrightText: "NOASSERTION", 899 } 900 f6_2 := &v2_2.File{ 901 FileName: "/project/file6.txt", 902 FileSPDXIdentifier: common.ElementID("File566"), 903 Checksums: []common.Checksum{{ 904 Algorithm: common.SHA1, 905 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 906 }, 907 }, 908 LicenseConcluded: "Unlicense", 909 LicenseInfoInFiles: []string{ 910 "NOASSERTION", 911 }, 912 FileCopyrightText: "NOASSERTION", 913 } 914 915 // create Packages 916 p1 := &v2_2.Package{ 917 PackageName: "p1", 918 PackageSPDXIdentifier: common.ElementID("p1"), 919 PackageDownloadLocation: "NOASSERTION", 920 FilesAnalyzed: true, 921 IsFilesAnalyzedTagPresent: true, 922 // fake the verification code for present purposes 923 PackageVerificationCode: common.PackageVerificationCode{Value: "abc123abc123"}, 924 PackageLicenseConcluded: "NOASSERTION", 925 PackageLicenseInfoFromFiles: []string{ 926 "NOASSERTION", 927 }, 928 PackageLicenseDeclared: "NOASSERTION", 929 PackageCopyrightText: "NOASSERTION", 930 Files: []*v2_2.File{ 931 f1, 932 f2, 933 f4_1, 934 f5_1, 935 f6_1, 936 }, 937 } 938 p2 := &v2_2.Package{ 939 PackageName: "p2", 940 PackageSPDXIdentifier: common.ElementID("p2"), 941 PackageDownloadLocation: "NOASSERTION", 942 FilesAnalyzed: true, 943 IsFilesAnalyzedTagPresent: true, 944 // fake the verification code for present purposes 945 PackageVerificationCode: common.PackageVerificationCode{Value: "def456def456"}, 946 PackageLicenseConcluded: "NOASSERTION", 947 PackageLicenseInfoFromFiles: []string{ 948 "NOASSERTION", 949 }, 950 PackageLicenseDeclared: "NOASSERTION", 951 PackageCopyrightText: "NOASSERTION", 952 Files: []*v2_2.File{ 953 f1, 954 f3, 955 f4_2, 956 f5_2, 957 f6_2, 958 }, 959 } 960 961 // run the diff between the two packages 962 diffMap, err := MakePairs2_2(p1, p2) 963 if err != nil { 964 t.Fatalf("Expected nil error, got %v", err) 965 } 966 967 // now, create the LicenseDiff structured results from the pairs 968 diffResults, err := MakeResults(diffMap) 969 if err != nil { 970 t.Fatalf("Expected nil error, got %v", err) 971 } 972 973 // check that the diff results are the expected lengths 974 if len(diffResults.InBothChanged) != 2 { 975 t.Fatalf("Expected %d, got %d", 2, len(diffResults.InBothChanged)) 976 } 977 if len(diffResults.InBothSame) != 2 { 978 t.Fatalf("Expected %d, got %d", 2, len(diffResults.InBothSame)) 979 } 980 if len(diffResults.InFirstOnly) != 1 { 981 t.Fatalf("Expected %d, got %d", 1, len(diffResults.InFirstOnly)) 982 } 983 if len(diffResults.InSecondOnly) != 1 { 984 t.Fatalf("Expected %d, got %d", 1, len(diffResults.InSecondOnly)) 985 } 986 987 // check each filename is present where it belongs, and check license(s) 988 989 // in both and different license: f4 and f6 990 // filename will map to a LicensePair 991 check4, ok := diffResults.InBothChanged["/project/file4.txt"] 992 if !ok { 993 t.Fatalf("Couldn't get check4") 994 } 995 if check4.First != f4_1.LicenseConcluded { 996 t.Errorf("Expected %s, got %s", f4_1.LicenseConcluded, check4.First) 997 } 998 if check4.Second != f4_2.LicenseConcluded { 999 t.Errorf("Expected %s, got %s", f4_2.LicenseConcluded, check4.Second) 1000 } 1001 check6, ok := diffResults.InBothChanged["/project/file6.txt"] 1002 if !ok { 1003 t.Fatalf("Couldn't get check6") 1004 } 1005 if check6.First != f6_1.LicenseConcluded { 1006 t.Errorf("Expected %s, got %s", f6_1.LicenseConcluded, check6.First) 1007 } 1008 if check6.Second != f6_2.LicenseConcluded { 1009 t.Errorf("Expected %s, got %s", f6_2.LicenseConcluded, check6.Second) 1010 } 1011 1012 // in both and same license: f1 and f5 1013 // filename will map to a string 1014 check1, ok := diffResults.InBothSame["/project/file1.txt"] 1015 if !ok { 1016 t.Fatalf("Couldn't get check1") 1017 } 1018 if check1 != f1.LicenseConcluded { 1019 t.Errorf("Expected %s, got %s", f1.LicenseConcluded, check1) 1020 } 1021 check5, ok := diffResults.InBothSame["/project/file5.txt"] 1022 if !ok { 1023 t.Fatalf("Couldn't get check5") 1024 } 1025 if check5 != f5_1.LicenseConcluded { 1026 t.Errorf("Expected %s, got %s", f5_1.LicenseConcluded, check5) 1027 } 1028 if check5 != f5_2.LicenseConcluded { 1029 t.Errorf("Expected %s, got %s", f5_2.LicenseConcluded, check5) 1030 } 1031 1032 // in first only: f2 1033 // filename will map to a string 1034 check2, ok := diffResults.InFirstOnly["/project/file2.txt"] 1035 if !ok { 1036 t.Fatalf("Couldn't get check2") 1037 } 1038 if check2 != f2.LicenseConcluded { 1039 t.Errorf("Expected %s, got %s", f2.LicenseConcluded, check2) 1040 } 1041 1042 // in second only: f3 1043 // filename will map to a string 1044 check3, ok := diffResults.InSecondOnly["/project/file3.txt"] 1045 if !ok { 1046 t.Fatalf("Couldn't get check3") 1047 } 1048 if check3 != f3.LicenseConcluded { 1049 t.Errorf("Expected %s, got %s", f3.LicenseConcluded, check2) 1050 } 1051 1052} 1053 1054// ===== 2.3 License diff top-level function tests ===== 1055func Test2_3DifferCanCreateDiffPairs(t *testing.T) { 1056 // create files to be used in diff 1057 // f1 will be identical in both 1058 f1 := &v2_3.File{ 1059 FileName: "/project/file1.txt", 1060 FileSPDXIdentifier: common.ElementID("File561"), 1061 Checksums: []common.Checksum{{ 1062 Algorithm: common.SHA1, 1063 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 1064 }, 1065 }, 1066 LicenseConcluded: "Apache-2.0", 1067 LicenseInfoInFiles: []string{ 1068 "LicenseRef-We-will-ignore-LicenseInfoInFiles", 1069 }, 1070 FileCopyrightText: "We'll ignore copyright values", 1071 } 1072 1073 // f2 will only appear in the first Package 1074 f2 := &v2_3.File{ 1075 FileName: "/project/file2.txt", 1076 FileSPDXIdentifier: common.ElementID("File562"), 1077 Checksums: []common.Checksum{{ 1078 Algorithm: common.SHA1, 1079 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 1080 }, 1081 }, 1082 LicenseConcluded: "GPL-2.0-or-later", 1083 LicenseInfoInFiles: []string{ 1084 "NOASSERTION", 1085 }, 1086 FileCopyrightText: "NOASSERTION", 1087 } 1088 1089 // f3 will only appear in the second Package 1090 f3 := &v2_3.File{ 1091 FileName: "/project/file3.txt", 1092 FileSPDXIdentifier: common.ElementID("File563"), 1093 Checksums: []common.Checksum{{ 1094 Algorithm: common.SHA1, 1095 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 1096 }, 1097 }, 1098 LicenseConcluded: "MPL-2.0", 1099 LicenseInfoInFiles: []string{ 1100 "NOASSERTION", 1101 }, 1102 FileCopyrightText: "NOASSERTION", 1103 } 1104 1105 // f4_1 and f4_2 will appear in first and second, 1106 // with same name, same hash and different license 1107 f4_1 := &v2_3.File{ 1108 FileName: "/project/file4.txt", 1109 FileSPDXIdentifier: common.ElementID("File564"), 1110 Checksums: []common.Checksum{{ 1111 Algorithm: common.SHA1, 1112 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 1113 }, 1114 }, 1115 LicenseConcluded: "MIT", 1116 LicenseInfoInFiles: []string{ 1117 "NOASSERTION", 1118 }, 1119 FileCopyrightText: "NOASSERTION", 1120 } 1121 f4_2 := &v2_3.File{ 1122 FileName: "/project/file4.txt", 1123 FileSPDXIdentifier: common.ElementID("File564"), 1124 Checksums: []common.Checksum{{ 1125 Algorithm: common.SHA1, 1126 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 1127 }, 1128 }, 1129 LicenseConcluded: "Apache-2.0 AND MIT", 1130 LicenseInfoInFiles: []string{ 1131 "NOASSERTION", 1132 }, 1133 FileCopyrightText: "NOASSERTION", 1134 } 1135 1136 // f5_1 and f5_2 will appear in first and second, 1137 // with same name, different hash and same license 1138 f5_1 := &v2_3.File{ 1139 FileName: "/project/file5.txt", 1140 FileSPDXIdentifier: common.ElementID("File565"), 1141 Checksums: []common.Checksum{{ 1142 Algorithm: common.SHA1, 1143 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 1144 }, 1145 }, 1146 LicenseConcluded: "BSD-3-Clause", 1147 LicenseInfoInFiles: []string{ 1148 "NOASSERTION", 1149 }, 1150 FileCopyrightText: "NOASSERTION", 1151 } 1152 f5_2 := &v2_3.File{ 1153 FileName: "/project/file5.txt", 1154 FileSPDXIdentifier: common.ElementID("File565"), 1155 Checksums: []common.Checksum{{ 1156 Algorithm: common.SHA1, 1157 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 1158 }, 1159 }, 1160 LicenseConcluded: "BSD-3-Clause", 1161 LicenseInfoInFiles: []string{ 1162 "NOASSERTION", 1163 }, 1164 FileCopyrightText: "NOASSERTION", 1165 } 1166 1167 // f6_1 and f6_2 will appear in first and second, 1168 // with same name, different hash and different license 1169 f6_1 := &v2_3.File{ 1170 FileName: "/project/file6.txt", 1171 FileSPDXIdentifier: common.ElementID("File566"), 1172 Checksums: []common.Checksum{{ 1173 Algorithm: common.SHA1, 1174 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 1175 }, 1176 }, 1177 LicenseConcluded: "CC0-1.0", 1178 LicenseInfoInFiles: []string{ 1179 "NOASSERTION", 1180 }, 1181 FileCopyrightText: "NOASSERTION", 1182 } 1183 f6_2 := &v2_3.File{ 1184 FileName: "/project/file6.txt", 1185 FileSPDXIdentifier: common.ElementID("File566"), 1186 Checksums: []common.Checksum{{ 1187 Algorithm: common.SHA1, 1188 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 1189 }, 1190 }, 1191 LicenseConcluded: "Unlicense", 1192 LicenseInfoInFiles: []string{ 1193 "NOASSERTION", 1194 }, 1195 FileCopyrightText: "NOASSERTION", 1196 } 1197 1198 // create Packages 1199 p1 := &v2_3.Package{ 1200 PackageName: "p1", 1201 PackageSPDXIdentifier: common.ElementID("p1"), 1202 PackageDownloadLocation: "NOASSERTION", 1203 FilesAnalyzed: true, 1204 IsFilesAnalyzedTagPresent: true, 1205 // fake the verification code for present purposes 1206 PackageVerificationCode: &common.PackageVerificationCode{Value: "abc123abc123"}, 1207 PackageLicenseConcluded: "NOASSERTION", 1208 PackageLicenseInfoFromFiles: []string{ 1209 "NOASSERTION", 1210 }, 1211 PackageLicenseDeclared: "NOASSERTION", 1212 PackageCopyrightText: "NOASSERTION", 1213 Files: []*v2_3.File{ 1214 f1, 1215 f2, 1216 f4_1, 1217 f5_1, 1218 f6_1, 1219 }, 1220 } 1221 p2 := &v2_3.Package{ 1222 PackageName: "p2", 1223 PackageSPDXIdentifier: common.ElementID("p2"), 1224 PackageDownloadLocation: "NOASSERTION", 1225 FilesAnalyzed: true, 1226 IsFilesAnalyzedTagPresent: true, 1227 // fake the verification code for present purposes 1228 PackageVerificationCode: &common.PackageVerificationCode{Value: "def456def456"}, 1229 PackageLicenseConcluded: "NOASSERTION", 1230 PackageLicenseInfoFromFiles: []string{ 1231 "NOASSERTION", 1232 }, 1233 PackageLicenseDeclared: "NOASSERTION", 1234 PackageCopyrightText: "NOASSERTION", 1235 Files: []*v2_3.File{ 1236 f1, 1237 f3, 1238 f4_2, 1239 f5_2, 1240 f6_2, 1241 }, 1242 } 1243 1244 // run the diff between the two packages 1245 diffMap, err := MakePairs2_3(p1, p2) 1246 if err != nil { 1247 t.Fatalf("Expected nil error, got %v", err) 1248 } 1249 1250 // check that the diff results are what we expect 1251 // there should be 6 entries, one for each unique filename 1252 if len(diffMap) != 6 { 1253 t.Fatalf("Expected %d, got %d", 6, len(diffMap)) 1254 } 1255 1256 // check each filename is present, and check its pair 1257 // pair 1 -- same in both 1258 pair1, ok := diffMap["/project/file1.txt"] 1259 if !ok { 1260 t.Fatalf("Couldn't get pair1") 1261 } 1262 if pair1.First != f1.LicenseConcluded { 1263 t.Errorf("Expected %s, got %s", f1.LicenseConcluded, pair1.First) 1264 } 1265 if pair1.Second != f1.LicenseConcluded { 1266 t.Errorf("Expected %s, got %s", f2.LicenseConcluded, pair1.Second) 1267 } 1268 1269 // pair 2 -- only in first 1270 pair2, ok := diffMap["/project/file2.txt"] 1271 if !ok { 1272 t.Fatalf("Couldn't get pair2") 1273 } 1274 if pair2.First != f2.LicenseConcluded { 1275 t.Errorf("Expected %s, got %s", f2.LicenseConcluded, pair2.First) 1276 } 1277 if pair2.Second != "" { 1278 t.Errorf("Expected %s, got %s", "", pair2.Second) 1279 } 1280 1281 // pair 3 -- only in second 1282 pair3, ok := diffMap["/project/file3.txt"] 1283 if !ok { 1284 t.Fatalf("Couldn't get pair3") 1285 } 1286 if pair3.First != "" { 1287 t.Errorf("Expected %s, got %s", "", pair3.First) 1288 } 1289 if pair3.Second != f3.LicenseConcluded { 1290 t.Errorf("Expected %s, got %s", f3.LicenseConcluded, pair3.Second) 1291 } 1292 1293 // pair 4 -- in both but different license 1294 pair4, ok := diffMap["/project/file4.txt"] 1295 if !ok { 1296 t.Fatalf("Couldn't get pair4") 1297 } 1298 if pair4.First != f4_1.LicenseConcluded { 1299 t.Errorf("Expected %s, got %s", f4_1.LicenseConcluded, pair4.First) 1300 } 1301 if pair4.Second != f4_2.LicenseConcluded { 1302 t.Errorf("Expected %s, got %s", f4_2.LicenseConcluded, pair4.Second) 1303 } 1304 1305 // pair 5 -- in both but different hash, same license 1306 pair5, ok := diffMap["/project/file5.txt"] 1307 if !ok { 1308 t.Fatalf("Couldn't get pair5") 1309 } 1310 if pair5.First != f5_1.LicenseConcluded { 1311 t.Errorf("Expected %s, got %s", f5_1.LicenseConcluded, pair5.First) 1312 } 1313 if pair5.Second != f5_2.LicenseConcluded { 1314 t.Errorf("Expected %s, got %s", f5_2.LicenseConcluded, pair5.Second) 1315 } 1316 1317 // pair 6 -- in both but different hash, different license 1318 pair6, ok := diffMap["/project/file6.txt"] 1319 if !ok { 1320 t.Fatalf("Couldn't get pair6") 1321 } 1322 if pair6.First != f6_1.LicenseConcluded { 1323 t.Errorf("Expected %s, got %s", f6_1.LicenseConcluded, pair6.First) 1324 } 1325 if pair6.Second != f6_2.LicenseConcluded { 1326 t.Errorf("Expected %s, got %s", f6_2.LicenseConcluded, pair6.Second) 1327 } 1328} 1329 1330func Test2_3DifferCanCreateDiffStructuredResults(t *testing.T) { 1331 // create files to be used in diff 1332 // f1 will be identical in both 1333 f1 := &v2_3.File{ 1334 FileName: "/project/file1.txt", 1335 FileSPDXIdentifier: common.ElementID("File561"), 1336 Checksums: []common.Checksum{{ 1337 Algorithm: common.SHA1, 1338 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 1339 }, 1340 }, 1341 LicenseConcluded: "Apache-2.0", 1342 LicenseInfoInFiles: []string{ 1343 "LicenseRef-We-will-ignore-LicenseInfoInFiles", 1344 }, 1345 FileCopyrightText: "We'll ignore copyright values", 1346 } 1347 1348 // f2 will only appear in the first Package 1349 f2 := &v2_3.File{ 1350 FileName: "/project/file2.txt", 1351 FileSPDXIdentifier: common.ElementID("File562"), 1352 Checksums: []common.Checksum{{ 1353 Algorithm: common.SHA1, 1354 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 1355 }, 1356 }, 1357 LicenseConcluded: "GPL-2.0-or-later", 1358 LicenseInfoInFiles: []string{ 1359 "NOASSERTION", 1360 }, 1361 FileCopyrightText: "NOASSERTION", 1362 } 1363 1364 // f3 will only appear in the second Package 1365 f3 := &v2_3.File{ 1366 FileName: "/project/file3.txt", 1367 FileSPDXIdentifier: common.ElementID("File563"), 1368 Checksums: []common.Checksum{{ 1369 Algorithm: common.SHA1, 1370 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 1371 }, 1372 }, 1373 LicenseConcluded: "MPL-2.0", 1374 LicenseInfoInFiles: []string{ 1375 "NOASSERTION", 1376 }, 1377 FileCopyrightText: "NOASSERTION", 1378 } 1379 1380 // f4_1 and f4_2 will appear in first and second, 1381 // with same name, same hash and different license 1382 f4_1 := &v2_3.File{ 1383 FileName: "/project/file4.txt", 1384 FileSPDXIdentifier: common.ElementID("File564"), 1385 Checksums: []common.Checksum{{ 1386 Algorithm: common.SHA1, 1387 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 1388 }, 1389 }, 1390 LicenseConcluded: "MIT", 1391 LicenseInfoInFiles: []string{ 1392 "NOASSERTION", 1393 }, 1394 FileCopyrightText: "NOASSERTION", 1395 } 1396 f4_2 := &v2_3.File{ 1397 FileName: "/project/file4.txt", 1398 FileSPDXIdentifier: common.ElementID("File564"), 1399 Checksums: []common.Checksum{{ 1400 Algorithm: common.SHA1, 1401 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 1402 }, 1403 }, 1404 LicenseConcluded: "Apache-2.0 AND MIT", 1405 LicenseInfoInFiles: []string{ 1406 "NOASSERTION", 1407 }, 1408 FileCopyrightText: "NOASSERTION", 1409 } 1410 1411 // f5_1 and f5_2 will appear in first and second, 1412 // with same name, different hash and same license 1413 f5_1 := &v2_3.File{ 1414 FileName: "/project/file5.txt", 1415 FileSPDXIdentifier: common.ElementID("File565"), 1416 LicenseConcluded: "BSD-3-Clause", 1417 LicenseInfoInFiles: []string{ 1418 "NOASSERTION", 1419 }, 1420 FileCopyrightText: "NOASSERTION", 1421 } 1422 f5_2 := &v2_3.File{ 1423 FileName: "/project/file5.txt", 1424 FileSPDXIdentifier: common.ElementID("File565"), 1425 Checksums: []common.Checksum{{ 1426 Algorithm: common.SHA1, 1427 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 1428 }, 1429 }, 1430 1431 LicenseConcluded: "BSD-3-Clause", 1432 LicenseInfoInFiles: []string{ 1433 "NOASSERTION", 1434 }, 1435 FileCopyrightText: "NOASSERTION", 1436 } 1437 1438 // f6_1 and f6_2 will appear in first and second, 1439 // with same name, different hash and different license 1440 f6_1 := &v2_3.File{ 1441 FileName: "/project/file6.txt", 1442 FileSPDXIdentifier: common.ElementID("File566"), 1443 Checksums: []common.Checksum{{ 1444 Algorithm: common.SHA1, 1445 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 1446 }, 1447 }, 1448 LicenseConcluded: "CC0-1.0", 1449 LicenseInfoInFiles: []string{ 1450 "NOASSERTION", 1451 }, 1452 FileCopyrightText: "NOASSERTION", 1453 } 1454 f6_2 := &v2_3.File{ 1455 FileName: "/project/file6.txt", 1456 FileSPDXIdentifier: common.ElementID("File566"), 1457 Checksums: []common.Checksum{{ 1458 Algorithm: common.SHA1, 1459 Value: "6c92dc8bc462b6889d9b1c0bc16c54d19a2cbdd3", 1460 }, 1461 }, 1462 LicenseConcluded: "Unlicense", 1463 LicenseInfoInFiles: []string{ 1464 "NOASSERTION", 1465 }, 1466 FileCopyrightText: "NOASSERTION", 1467 } 1468 1469 // create Packages 1470 p1 := &v2_3.Package{ 1471 PackageName: "p1", 1472 PackageSPDXIdentifier: common.ElementID("p1"), 1473 PackageDownloadLocation: "NOASSERTION", 1474 FilesAnalyzed: true, 1475 IsFilesAnalyzedTagPresent: true, 1476 // fake the verification code for present purposes 1477 PackageVerificationCode: &common.PackageVerificationCode{Value: "abc123abc123"}, 1478 PackageLicenseConcluded: "NOASSERTION", 1479 PackageLicenseInfoFromFiles: []string{ 1480 "NOASSERTION", 1481 }, 1482 PackageLicenseDeclared: "NOASSERTION", 1483 PackageCopyrightText: "NOASSERTION", 1484 Files: []*v2_3.File{ 1485 f1, 1486 f2, 1487 f4_1, 1488 f5_1, 1489 f6_1, 1490 }, 1491 } 1492 p2 := &v2_3.Package{ 1493 PackageName: "p2", 1494 PackageSPDXIdentifier: common.ElementID("p2"), 1495 PackageDownloadLocation: "NOASSERTION", 1496 FilesAnalyzed: true, 1497 IsFilesAnalyzedTagPresent: true, 1498 // fake the verification code for present purposes 1499 PackageVerificationCode: &common.PackageVerificationCode{Value: "def456def456"}, 1500 PackageLicenseConcluded: "NOASSERTION", 1501 PackageLicenseInfoFromFiles: []string{ 1502 "NOASSERTION", 1503 }, 1504 PackageLicenseDeclared: "NOASSERTION", 1505 PackageCopyrightText: "NOASSERTION", 1506 Files: []*v2_3.File{ 1507 f1, 1508 f3, 1509 f4_2, 1510 f5_2, 1511 f6_2, 1512 }, 1513 } 1514 1515 // run the diff between the two packages 1516 diffMap, err := MakePairs2_3(p1, p2) 1517 if err != nil { 1518 t.Fatalf("Expected nil error, got %v", err) 1519 } 1520 1521 // now, create the LicenseDiff structured results from the pairs 1522 diffResults, err := MakeResults(diffMap) 1523 if err != nil { 1524 t.Fatalf("Expected nil error, got %v", err) 1525 } 1526 1527 // check that the diff results are the expected lengths 1528 if len(diffResults.InBothChanged) != 2 { 1529 t.Fatalf("Expected %d, got %d", 2, len(diffResults.InBothChanged)) 1530 } 1531 if len(diffResults.InBothSame) != 2 { 1532 t.Fatalf("Expected %d, got %d", 2, len(diffResults.InBothSame)) 1533 } 1534 if len(diffResults.InFirstOnly) != 1 { 1535 t.Fatalf("Expected %d, got %d", 1, len(diffResults.InFirstOnly)) 1536 } 1537 if len(diffResults.InSecondOnly) != 1 { 1538 t.Fatalf("Expected %d, got %d", 1, len(diffResults.InSecondOnly)) 1539 } 1540 1541 // check each filename is present where it belongs, and check license(s) 1542 1543 // in both and different license: f4 and f6 1544 // filename will map to a LicensePair 1545 check4, ok := diffResults.InBothChanged["/project/file4.txt"] 1546 if !ok { 1547 t.Fatalf("Couldn't get check4") 1548 } 1549 if check4.First != f4_1.LicenseConcluded { 1550 t.Errorf("Expected %s, got %s", f4_1.LicenseConcluded, check4.First) 1551 } 1552 if check4.Second != f4_2.LicenseConcluded { 1553 t.Errorf("Expected %s, got %s", f4_2.LicenseConcluded, check4.Second) 1554 } 1555 check6, ok := diffResults.InBothChanged["/project/file6.txt"] 1556 if !ok { 1557 t.Fatalf("Couldn't get check6") 1558 } 1559 if check6.First != f6_1.LicenseConcluded { 1560 t.Errorf("Expected %s, got %s", f6_1.LicenseConcluded, check6.First) 1561 } 1562 if check6.Second != f6_2.LicenseConcluded { 1563 t.Errorf("Expected %s, got %s", f6_2.LicenseConcluded, check6.Second) 1564 } 1565 1566 // in both and same license: f1 and f5 1567 // filename will map to a string 1568 check1, ok := diffResults.InBothSame["/project/file1.txt"] 1569 if !ok { 1570 t.Fatalf("Couldn't get check1") 1571 } 1572 if check1 != f1.LicenseConcluded { 1573 t.Errorf("Expected %s, got %s", f1.LicenseConcluded, check1) 1574 } 1575 check5, ok := diffResults.InBothSame["/project/file5.txt"] 1576 if !ok { 1577 t.Fatalf("Couldn't get check5") 1578 } 1579 if check5 != f5_1.LicenseConcluded { 1580 t.Errorf("Expected %s, got %s", f5_1.LicenseConcluded, check5) 1581 } 1582 if check5 != f5_2.LicenseConcluded { 1583 t.Errorf("Expected %s, got %s", f5_2.LicenseConcluded, check5) 1584 } 1585 1586 // in first only: f2 1587 // filename will map to a string 1588 check2, ok := diffResults.InFirstOnly["/project/file2.txt"] 1589 if !ok { 1590 t.Fatalf("Couldn't get check2") 1591 } 1592 if check2 != f2.LicenseConcluded { 1593 t.Errorf("Expected %s, got %s", f2.LicenseConcluded, check2) 1594 } 1595 1596 // in second only: f3 1597 // filename will map to a string 1598 check3, ok := diffResults.InSecondOnly["/project/file3.txt"] 1599 if !ok { 1600 t.Fatalf("Couldn't get check3") 1601 } 1602 if check3 != f3.LicenseConcluded { 1603 t.Errorf("Expected %s, got %s", f3.LicenseConcluded, check2) 1604 } 1605 1606} 1607