1// Copyright 2021 Google LLC 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package compliance 16 17import ( 18 "bytes" 19 "fmt" 20 "os" 21 "strings" 22 "testing" 23) 24 25func TestMain(m *testing.M) { 26 // Change into the cmd directory before running the tests 27 // so they can find the testdata directory. 28 if err := os.Chdir("cmd"); err != nil { 29 fmt.Printf("failed to change to testdata directory: %s\n", err) 30 os.Exit(1) 31 } 32 os.Exit(m.Run()) 33} 34 35func TestWalkResolutionsForCondition(t *testing.T) { 36 tests := []struct { 37 name string 38 condition LicenseConditionSet 39 roots []string 40 edges []annotated 41 expectedResolutions []res 42 }{ 43 { 44 name: "firstparty", 45 condition: ImpliesNotice, 46 roots: []string{"apacheBin.meta_lic"}, 47 edges: []annotated{ 48 {"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"static"}}, 49 }, 50 expectedResolutions: []res{ 51 {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"}, 52 {"apacheBin.meta_lic", "apacheLib.meta_lic", "notice"}, 53 }, 54 }, 55 { 56 name: "notice", 57 condition: ImpliesNotice, 58 roots: []string{"mitBin.meta_lic"}, 59 edges: []annotated{ 60 {"mitBin.meta_lic", "mitLib.meta_lic", []string{"static"}}, 61 }, 62 expectedResolutions: []res{ 63 {"mitBin.meta_lic", "mitBin.meta_lic", "notice"}, 64 {"mitBin.meta_lic", "mitLib.meta_lic", "notice"}, 65 }, 66 }, 67 { 68 name: "fponlgplnotice", 69 condition: ImpliesNotice, 70 roots: []string{"apacheBin.meta_lic"}, 71 edges: []annotated{ 72 {"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"static"}}, 73 }, 74 expectedResolutions: []res{ 75 {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice|restricted_if_statically_linked"}, 76 {"apacheBin.meta_lic", "lgplLib.meta_lic", "restricted_if_statically_linked"}, 77 }, 78 }, 79 { 80 name: "fponlgpldynamicnotice", 81 condition: ImpliesNotice, 82 roots: []string{"apacheBin.meta_lic"}, 83 edges: []annotated{ 84 {"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"dynamic"}}, 85 }, 86 expectedResolutions: []res{ 87 {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"}, 88 }, 89 }, 90 { 91 name: "independentmodulenotice", 92 condition: ImpliesNotice, 93 roots: []string{"apacheBin.meta_lic"}, 94 edges: []annotated{ 95 {"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}}, 96 }, 97 expectedResolutions: []res{ 98 {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"}, 99 }, 100 }, 101 { 102 name: "independentmodulerestricted", 103 condition: ImpliesRestricted, 104 roots: []string{"apacheBin.meta_lic"}, 105 edges: []annotated{ 106 {"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}}, 107 }, 108 expectedResolutions: []res{}, 109 }, 110 { 111 name: "independentmodulestaticnotice", 112 condition: ImpliesNotice, 113 roots: []string{"apacheBin.meta_lic"}, 114 edges: []annotated{ 115 {"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"static"}}, 116 }, 117 expectedResolutions: []res{ 118 {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"}, 119 {"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", "permissive"}, 120 }, 121 }, 122 { 123 name: "independentmodulestaticrestricted", 124 condition: ImpliesRestricted, 125 roots: []string{"apacheBin.meta_lic"}, 126 edges: []annotated{ 127 {"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"static"}}, 128 }, 129 expectedResolutions: []res{}, 130 }, 131 { 132 name: "dependentmodulenotice", 133 condition: ImpliesNotice, 134 roots: []string{"dependentModule.meta_lic"}, 135 edges: []annotated{ 136 {"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}}, 137 }, 138 expectedResolutions: []res{ 139 {"dependentModule.meta_lic", "dependentModule.meta_lic", "notice"}, 140 }, 141 }, 142 { 143 name: "dependentmodulerestricted", 144 condition: ImpliesRestricted, 145 roots: []string{"dependentModule.meta_lic"}, 146 edges: []annotated{ 147 {"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}}, 148 }, 149 expectedResolutions: []res{}, 150 }, 151 { 152 name: "lgplonfpnotice", 153 condition: ImpliesNotice, 154 roots: []string{"lgplBin.meta_lic"}, 155 edges: []annotated{ 156 {"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}}, 157 }, 158 expectedResolutions: []res{ 159 {"lgplBin.meta_lic", "lgplBin.meta_lic", "restricted_if_statically_linked"}, 160 {"lgplBin.meta_lic", "apacheLib.meta_lic", "notice|restricted_if_statically_linked"}, 161 }, 162 }, 163 { 164 name: "lgplonfprestricted", 165 condition: ImpliesRestricted, 166 roots: []string{"lgplBin.meta_lic"}, 167 edges: []annotated{ 168 {"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}}, 169 }, 170 expectedResolutions: []res{ 171 {"lgplBin.meta_lic", "lgplBin.meta_lic", "restricted_if_statically_linked"}, 172 {"lgplBin.meta_lic", "apacheLib.meta_lic", "restricted_if_statically_linked"}, 173 }, 174 }, 175 { 176 name: "lgplonfpdynamicnotice", 177 condition: ImpliesNotice, 178 roots: []string{"lgplBin.meta_lic"}, 179 edges: []annotated{ 180 {"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}}, 181 }, 182 expectedResolutions: []res{ 183 {"lgplBin.meta_lic", "lgplBin.meta_lic", "restricted_if_statically_linked"}, 184 }, 185 }, 186 { 187 name: "lgplonfpdynamicrestricted", 188 condition: ImpliesRestricted, 189 roots: []string{"lgplBin.meta_lic"}, 190 edges: []annotated{ 191 {"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}}, 192 }, 193 expectedResolutions: []res{ 194 {"lgplBin.meta_lic", "lgplBin.meta_lic", "restricted_if_statically_linked"}, 195 }, 196 }, 197 { 198 name: "gplonfpnotice", 199 condition: ImpliesNotice, 200 roots: []string{"gplBin.meta_lic"}, 201 edges: []annotated{ 202 {"gplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}}, 203 }, 204 expectedResolutions: []res{ 205 {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"}, 206 {"gplBin.meta_lic", "apacheLib.meta_lic", "notice|restricted"}, 207 }, 208 }, 209 { 210 name: "gplonfprestricted", 211 condition: ImpliesRestricted, 212 roots: []string{"gplBin.meta_lic"}, 213 edges: []annotated{ 214 {"gplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}}, 215 }, 216 expectedResolutions: []res{ 217 {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"}, 218 {"gplBin.meta_lic", "apacheLib.meta_lic", "restricted"}, 219 }, 220 }, 221 { 222 name: "gplcontainernotice", 223 condition: ImpliesNotice, 224 roots: []string{"gplContainer.meta_lic"}, 225 edges: []annotated{ 226 {"gplContainer.meta_lic", "apacheLib.meta_lic", []string{"static"}}, 227 }, 228 expectedResolutions: []res{ 229 {"gplContainer.meta_lic", "gplContainer.meta_lic", "restricted"}, 230 {"gplContainer.meta_lic", "apacheLib.meta_lic", "notice|restricted"}, 231 {"apacheLib.meta_lic", "apacheLib.meta_lic", "notice|restricted"}, 232 }, 233 }, 234 { 235 name: "gplcontainerrestricted", 236 condition: ImpliesRestricted, 237 roots: []string{"gplContainer.meta_lic"}, 238 edges: []annotated{ 239 {"gplContainer.meta_lic", "apacheLib.meta_lic", []string{"static"}}, 240 }, 241 expectedResolutions: []res{ 242 {"gplContainer.meta_lic", "gplContainer.meta_lic", "restricted"}, 243 {"gplContainer.meta_lic", "apacheLib.meta_lic", "restricted"}, 244 {"apacheLib.meta_lic", "apacheLib.meta_lic", "restricted"}, 245 }, 246 }, 247 { 248 name: "gploncontainernotice", 249 condition: ImpliesNotice, 250 roots: []string{"apacheContainer.meta_lic"}, 251 edges: []annotated{ 252 {"apacheContainer.meta_lic", "apacheLib.meta_lic", []string{"static"}}, 253 {"apacheContainer.meta_lic", "gplLib.meta_lic", []string{"static"}}, 254 }, 255 expectedResolutions: []res{ 256 {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice|restricted"}, 257 {"apacheContainer.meta_lic", "apacheLib.meta_lic", "notice"}, 258 {"apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"}, 259 {"apacheLib.meta_lic", "apacheLib.meta_lic", "notice"}, 260 {"gplLib.meta_lic", "gplLib.meta_lic", "restricted"}, 261 }, 262 }, 263 { 264 name: "gploncontainerrestricted", 265 condition: ImpliesRestricted, 266 roots: []string{"apacheContainer.meta_lic"}, 267 edges: []annotated{ 268 {"apacheContainer.meta_lic", "apacheLib.meta_lic", []string{"static"}}, 269 {"apacheContainer.meta_lic", "gplLib.meta_lic", []string{"static"}}, 270 }, 271 expectedResolutions: []res{ 272 {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "restricted"}, 273 {"apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"}, 274 {"gplLib.meta_lic", "gplLib.meta_lic", "restricted"}, 275 }, 276 }, 277 { 278 name: "gplonbinnotice", 279 condition: ImpliesNotice, 280 roots: []string{"apacheBin.meta_lic"}, 281 edges: []annotated{ 282 {"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"static"}}, 283 {"apacheBin.meta_lic", "gplLib.meta_lic", []string{"static"}}, 284 }, 285 expectedResolutions: []res{ 286 {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice|restricted"}, 287 {"apacheBin.meta_lic", "apacheLib.meta_lic", "notice|restricted"}, 288 {"apacheBin.meta_lic", "gplLib.meta_lic", "restricted"}, 289 }, 290 }, 291 { 292 name: "gplonbinrestricted", 293 condition: ImpliesRestricted, 294 roots: []string{"apacheBin.meta_lic"}, 295 edges: []annotated{ 296 {"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"static"}}, 297 {"apacheBin.meta_lic", "gplLib.meta_lic", []string{"static"}}, 298 }, 299 expectedResolutions: []res{ 300 {"apacheBin.meta_lic", "apacheBin.meta_lic", "restricted"}, 301 {"apacheBin.meta_lic", "apacheLib.meta_lic", "restricted"}, 302 {"apacheBin.meta_lic", "gplLib.meta_lic", "restricted"}, 303 }, 304 }, 305 { 306 name: "gplonfpdynamicnotice", 307 condition: ImpliesNotice, 308 roots: []string{"gplBin.meta_lic"}, 309 edges: []annotated{ 310 {"gplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}}, 311 }, 312 expectedResolutions: []res{ 313 {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"}, 314 }, 315 }, 316 { 317 name: "gplonfpdynamicrestricted", 318 condition: ImpliesRestricted, 319 roots: []string{"gplBin.meta_lic"}, 320 edges: []annotated{ 321 {"gplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}}, 322 }, 323 expectedResolutions: []res{ 324 {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"}, 325 }, 326 }, 327 { 328 name: "gplonfpdynamicrestrictedshipped", 329 condition: ImpliesRestricted, 330 roots: []string{"gplBin.meta_lic", "apacheLib.meta_lic"}, 331 edges: []annotated{ 332 {"gplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}}, 333 }, 334 expectedResolutions: []res{ 335 {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"}, 336 {"gplBin.meta_lic", "apacheLib.meta_lic", "restricted"}, 337 {"apacheLib.meta_lic", "apacheLib.meta_lic", "restricted"}, 338 }, 339 }, 340 { 341 name: "independentmodulereversenotice", 342 condition: ImpliesNotice, 343 roots: []string{"gplWithClasspathException.meta_lic"}, 344 edges: []annotated{ 345 {"gplWithClasspathException.meta_lic", "apacheBin.meta_lic", []string{"dynamic"}}, 346 }, 347 expectedResolutions: []res{ 348 {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "permissive"}, 349 }, 350 }, 351 { 352 name: "independentmodulereverserestricted", 353 condition: ImpliesRestricted, 354 roots: []string{"gplWithClasspathException.meta_lic"}, 355 edges: []annotated{ 356 {"gplWithClasspathException.meta_lic", "apacheBin.meta_lic", []string{"dynamic"}}, 357 }, 358 expectedResolutions: []res{}, 359 }, 360 { 361 name: "independentmodulereverserestrictedshipped", 362 condition: ImpliesRestricted, 363 roots: []string{"gplWithClasspathException.meta_lic", "apacheBin.meta_lic"}, 364 edges: []annotated{ 365 {"gplWithClasspathException.meta_lic", "apacheBin.meta_lic", []string{"dynamic"}}, 366 }, 367 expectedResolutions: []res{}, 368 }, 369 { 370 name: "independentmodulereversestaticnotice", 371 condition: ImpliesNotice, 372 roots: []string{"gplWithClasspathException.meta_lic"}, 373 edges: []annotated{ 374 {"gplWithClasspathException.meta_lic", "apacheBin.meta_lic", []string{"static"}}, 375 }, 376 expectedResolutions: []res{ 377 {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "permissive"}, 378 {"gplWithClasspathException.meta_lic", "apacheBin.meta_lic", "notice"}, 379 }, 380 }, 381 { 382 name: "independentmodulereversestaticrestricted", 383 condition: ImpliesRestricted, 384 roots: []string{"gplWithClasspathException.meta_lic"}, 385 edges: []annotated{ 386 {"gplWithClasspathException.meta_lic", "apacheBin.meta_lic", []string{"static"}}, 387 }, 388 expectedResolutions: []res{}, 389 }, 390 { 391 name: "dependentmodulereversenotice", 392 condition: ImpliesNotice, 393 roots: []string{"gplWithClasspathException.meta_lic"}, 394 edges: []annotated{ 395 {"gplWithClasspathException.meta_lic", "dependentModule.meta_lic", []string{"dynamic"}}, 396 }, 397 expectedResolutions: []res{ 398 {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "permissive"}, 399 }, 400 }, 401 { 402 name: "dependentmodulereverserestricted", 403 condition: ImpliesRestricted, 404 roots: []string{"gplWithClasspathException.meta_lic"}, 405 edges: []annotated{ 406 {"gplWithClasspathException.meta_lic", "dependentModule.meta_lic", []string{"dynamic"}}, 407 }, 408 expectedResolutions: []res{}, 409 }, 410 { 411 name: "dependentmodulereverserestrictedshipped", 412 condition: ImpliesRestricted, 413 roots: []string{"gplWithClasspathException.meta_lic", "dependentModule.meta_lic"}, 414 edges: []annotated{ 415 {"gplWithClasspathException.meta_lic", "dependentModule.meta_lic", []string{"dynamic"}}, 416 }, 417 expectedResolutions: []res{}, 418 }, 419 { 420 name: "ponrnotice", 421 condition: ImpliesNotice, 422 roots: []string{"proprietary.meta_lic"}, 423 edges: []annotated{ 424 {"proprietary.meta_lic", "gplLib.meta_lic", []string{"static"}}, 425 }, 426 expectedResolutions: []res{ 427 {"proprietary.meta_lic", "proprietary.meta_lic", "restricted|proprietary"}, 428 {"proprietary.meta_lic", "gplLib.meta_lic", "restricted"}, 429 }, 430 }, 431 { 432 name: "ponrrestricted", 433 condition: ImpliesRestricted, 434 roots: []string{"proprietary.meta_lic"}, 435 edges: []annotated{ 436 {"proprietary.meta_lic", "gplLib.meta_lic", []string{"static"}}, 437 }, 438 expectedResolutions: []res{ 439 {"proprietary.meta_lic", "gplLib.meta_lic", "restricted"}, 440 {"proprietary.meta_lic", "proprietary.meta_lic", "restricted"}, 441 }, 442 }, 443 { 444 name: "ponrproprietary", 445 condition: ImpliesProprietary, 446 roots: []string{"proprietary.meta_lic"}, 447 edges: []annotated{ 448 {"proprietary.meta_lic", "gplLib.meta_lic", []string{"static"}}, 449 }, 450 expectedResolutions: []res{ 451 {"proprietary.meta_lic", "proprietary.meta_lic", "proprietary"}, 452 }, 453 }, 454 { 455 name: "ronpnotice", 456 condition: ImpliesNotice, 457 roots: []string{"gplBin.meta_lic"}, 458 edges: []annotated{ 459 {"gplBin.meta_lic", "proprietary.meta_lic", []string{"static"}}, 460 }, 461 expectedResolutions: []res{ 462 {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"}, 463 {"gplBin.meta_lic", "proprietary.meta_lic", "restricted|proprietary"}, 464 }, 465 }, 466 { 467 name: "ronprestricted", 468 condition: ImpliesRestricted, 469 roots: []string{"gplBin.meta_lic"}, 470 edges: []annotated{ 471 {"gplBin.meta_lic", "proprietary.meta_lic", []string{"static"}}, 472 }, 473 expectedResolutions: []res{ 474 {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"}, 475 {"gplBin.meta_lic", "proprietary.meta_lic", "restricted"}, 476 }, 477 }, 478 { 479 name: "ronpproprietary", 480 condition: ImpliesProprietary, 481 roots: []string{"gplBin.meta_lic"}, 482 edges: []annotated{ 483 {"gplBin.meta_lic", "proprietary.meta_lic", []string{"static"}}, 484 }, 485 expectedResolutions: []res{ 486 {"gplBin.meta_lic", "proprietary.meta_lic", "proprietary"}, 487 }, 488 }, 489 { 490 name: "noticeonb_e_onotice", 491 condition: ImpliesNotice, 492 roots: []string{"mitBin.meta_lic"}, 493 edges: []annotated{ 494 {"mitBin.meta_lic", "by_exception.meta_lic", []string{"static"}}, 495 }, 496 expectedResolutions: []res{ 497 {"mitBin.meta_lic", "mitBin.meta_lic", "notice"}, 498 {"mitBin.meta_lic", "by_exception.meta_lic", "by_exception_only"}, 499 }, 500 }, 501 { 502 name: "noticeonb_e_orestricted", 503 condition: ImpliesRestricted, 504 roots: []string{"mitBin.meta_lic"}, 505 edges: []annotated{ 506 {"mitBin.meta_lic", "by_exception.meta_lic", []string{"static"}}, 507 }, 508 expectedResolutions: []res{}, 509 }, 510 { 511 name: "noticeonb_e_ob_e_o", 512 condition: ImpliesByExceptionOnly, 513 roots: []string{"mitBin.meta_lic"}, 514 edges: []annotated{ 515 {"mitBin.meta_lic", "by_exception.meta_lic", []string{"static"}}, 516 }, 517 expectedResolutions: []res{ 518 {"mitBin.meta_lic", "by_exception.meta_lic", "by_exception_only"}, 519 }, 520 }, 521 { 522 name: "b_e_oonnoticenotice", 523 condition: ImpliesNotice, 524 roots: []string{"by_exception.meta_lic"}, 525 edges: []annotated{ 526 {"by_exception.meta_lic", "mitLib.meta_lic", []string{"static"}}, 527 }, 528 expectedResolutions: []res{ 529 {"by_exception.meta_lic", "by_exception.meta_lic", "by_exception_only"}, 530 {"by_exception.meta_lic", "mitLib.meta_lic", "notice"}, 531 }, 532 }, 533 { 534 name: "b_e_oonnoticerestricted", 535 condition: ImpliesRestricted, 536 roots: []string{"by_exception.meta_lic"}, 537 edges: []annotated{ 538 {"by_exception.meta_lic", "mitLib.meta_lic", []string{"static"}}, 539 }, 540 expectedResolutions: []res{}, 541 }, 542 { 543 name: "b_e_oonnoticeb_e_o", 544 condition: ImpliesByExceptionOnly, 545 roots: []string{"by_exception.meta_lic"}, 546 edges: []annotated{ 547 {"by_exception.meta_lic", "mitLib.meta_lic", []string{"static"}}, 548 }, 549 expectedResolutions: []res{ 550 {"by_exception.meta_lic", "by_exception.meta_lic", "by_exception_only"}, 551 }, 552 }, 553 { 554 name: "noticeonrecipnotice", 555 condition: ImpliesNotice, 556 roots: []string{"mitBin.meta_lic"}, 557 edges: []annotated{ 558 {"mitBin.meta_lic", "mplLib.meta_lic", []string{"static"}}, 559 }, 560 expectedResolutions: []res{ 561 {"mitBin.meta_lic", "mitBin.meta_lic", "notice"}, 562 {"mitBin.meta_lic", "mplLib.meta_lic", "reciprocal"}, 563 }, 564 }, 565 { 566 name: "noticeonreciprecip", 567 condition: ImpliesReciprocal, 568 roots: []string{"mitBin.meta_lic"}, 569 edges: []annotated{ 570 {"mitBin.meta_lic", "mplLib.meta_lic", []string{"static"}}, 571 }, 572 expectedResolutions: []res{ 573 {"mitBin.meta_lic", "mplLib.meta_lic", "reciprocal"}, 574 }, 575 }, 576 { 577 name: "reciponnoticenotice", 578 condition: ImpliesNotice, 579 roots: []string{"mplBin.meta_lic"}, 580 edges: []annotated{ 581 {"mplBin.meta_lic", "mitLib.meta_lic", []string{"static"}}, 582 }, 583 expectedResolutions: []res{ 584 {"mplBin.meta_lic", "mplBin.meta_lic", "reciprocal"}, 585 {"mplBin.meta_lic", "mitLib.meta_lic", "notice"}, 586 }, 587 }, 588 { 589 name: "reciponnoticerecip", 590 condition: ImpliesReciprocal, 591 roots: []string{"mplBin.meta_lic"}, 592 edges: []annotated{ 593 {"mplBin.meta_lic", "mitLib.meta_lic", []string{"static"}}, 594 }, 595 expectedResolutions: []res{ 596 {"mplBin.meta_lic", "mplBin.meta_lic", "reciprocal"}, 597 }, 598 }, 599 } 600 for _, tt := range tests { 601 t.Run(tt.name, func(t *testing.T) { 602 stderr := &bytes.Buffer{} 603 lg, err := toGraph(stderr, tt.roots, tt.edges) 604 if err != nil { 605 t.Errorf("unexpected test data error: got %s, want no error", err) 606 return 607 } 608 expectedRs := toResolutionSet(lg, tt.expectedResolutions) 609 ResolveTopDownConditions(lg) 610 actualRs := WalkResolutionsForCondition(lg, tt.condition) 611 checkResolves(actualRs, expectedRs, t) 612 }) 613 } 614} 615 616func TestWalkActionsForCondition(t *testing.T) { 617 tests := []struct { 618 name string 619 condition LicenseConditionSet 620 roots []string 621 edges []annotated 622 expectedActions []act 623 }{ 624 { 625 name: "firstparty", 626 condition: ImpliesNotice, 627 roots: []string{"apacheBin.meta_lic"}, 628 edges: []annotated{ 629 {"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"static"}}, 630 }, 631 expectedActions: []act{ 632 {"apacheBin.meta_lic", "notice"}, 633 {"apacheLib.meta_lic", "notice"}, 634 }, 635 }, 636 { 637 name: "notice", 638 condition: ImpliesNotice, 639 roots: []string{"mitBin.meta_lic"}, 640 edges: []annotated{ 641 {"mitBin.meta_lic", "mitLib.meta_lic", []string{"static"}}, 642 }, 643 expectedActions: []act{ 644 {"mitBin.meta_lic", "notice"}, 645 {"mitLib.meta_lic", "notice"}, 646 }, 647 }, 648 { 649 name: "fponlgplnotice", 650 condition: ImpliesNotice, 651 roots: []string{"apacheBin.meta_lic"}, 652 edges: []annotated{ 653 {"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"static"}}, 654 }, 655 expectedActions: []act{ 656 {"apacheBin.meta_lic", "notice"}, 657 {"lgplLib.meta_lic", "restricted_if_statically_linked"}, 658 }, 659 }, 660 { 661 name: "fponlgpldynamicnotice", 662 condition: ImpliesNotice, 663 roots: []string{"apacheBin.meta_lic"}, 664 edges: []annotated{ 665 {"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"dynamic"}}, 666 }, 667 expectedActions: []act{ 668 {"apacheBin.meta_lic", "notice"}, 669 }, 670 }, 671 { 672 name: "independentmodulenotice", 673 condition: ImpliesNotice, 674 roots: []string{"apacheBin.meta_lic"}, 675 edges: []annotated{ 676 {"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}}, 677 }, 678 expectedActions: []act{ 679 {"apacheBin.meta_lic", "notice"}, 680 }, 681 }, 682 { 683 name: "independentmodulerestricted", 684 condition: ImpliesRestricted, 685 roots: []string{"apacheBin.meta_lic"}, 686 edges: []annotated{ 687 {"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}}, 688 }, 689 expectedActions: []act{}, 690 }, 691 { 692 name: "independentmodulestaticnotice", 693 condition: ImpliesNotice, 694 roots: []string{"apacheBin.meta_lic"}, 695 edges: []annotated{ 696 {"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"static"}}, 697 }, 698 expectedActions: []act{ 699 {"apacheBin.meta_lic", "notice"}, 700 {"gplWithClasspathException.meta_lic", "permissive"}, 701 }, 702 }, 703 { 704 name: "independentmodulestaticrestricted", 705 condition: ImpliesRestricted, 706 roots: []string{"apacheBin.meta_lic"}, 707 edges: []annotated{ 708 {"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"static"}}, 709 }, 710 expectedActions: []act{}, 711 }, 712 { 713 name: "dependentmodulenotice", 714 condition: ImpliesNotice, 715 roots: []string{"dependentModule.meta_lic"}, 716 edges: []annotated{ 717 {"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}}, 718 }, 719 expectedActions: []act{ 720 {"dependentModule.meta_lic", "notice"}, 721 }, 722 }, 723 { 724 name: "dependentmodulerestricted", 725 condition: ImpliesRestricted, 726 roots: []string{"dependentModule.meta_lic"}, 727 edges: []annotated{ 728 {"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}}, 729 }, 730 expectedActions: []act{}, 731 }, 732 { 733 name: "lgplonfpnotice", 734 condition: ImpliesNotice, 735 roots: []string{"lgplBin.meta_lic"}, 736 edges: []annotated{ 737 {"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}}, 738 }, 739 expectedActions: []act{ 740 {"lgplBin.meta_lic", "restricted_if_statically_linked"}, 741 {"apacheLib.meta_lic", "notice|restricted_if_statically_linked"}, 742 }, 743 }, 744 { 745 name: "lgplonfprestricted", 746 condition: ImpliesRestricted, 747 roots: []string{"lgplBin.meta_lic"}, 748 edges: []annotated{ 749 {"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}}, 750 }, 751 expectedActions: []act{ 752 {"lgplBin.meta_lic", "restricted_if_statically_linked"}, 753 {"apacheLib.meta_lic", "restricted_if_statically_linked"}, 754 }, 755 }, 756 { 757 name: "lgplonfpdynamicnotice", 758 condition: ImpliesNotice, 759 roots: []string{"lgplBin.meta_lic"}, 760 edges: []annotated{ 761 {"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}}, 762 }, 763 expectedActions: []act{ 764 {"lgplBin.meta_lic", "restricted_if_statically_linked"}, 765 }, 766 }, 767 { 768 name: "lgplonfpdynamicrestricted", 769 condition: ImpliesRestricted, 770 roots: []string{"lgplBin.meta_lic"}, 771 edges: []annotated{ 772 {"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}}, 773 }, 774 expectedActions: []act{ 775 {"lgplBin.meta_lic", "restricted_if_statically_linked"}, 776 }, 777 }, 778 { 779 name: "gplonfpnotice", 780 condition: ImpliesNotice, 781 roots: []string{"gplBin.meta_lic"}, 782 edges: []annotated{ 783 {"gplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}}, 784 }, 785 expectedActions: []act{ 786 {"gplBin.meta_lic", "restricted"}, 787 {"apacheLib.meta_lic", "notice|restricted"}, 788 }, 789 }, 790 { 791 name: "gplonfprestricted", 792 condition: ImpliesRestricted, 793 roots: []string{"gplBin.meta_lic"}, 794 edges: []annotated{ 795 {"gplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}}, 796 }, 797 expectedActions: []act{ 798 {"gplBin.meta_lic", "restricted"}, 799 {"apacheLib.meta_lic", "restricted"}, 800 }, 801 }, 802 { 803 name: "gplcontainernotice", 804 condition: ImpliesNotice, 805 roots: []string{"gplContainer.meta_lic"}, 806 edges: []annotated{ 807 {"gplContainer.meta_lic", "apacheLib.meta_lic", []string{"static"}}, 808 }, 809 expectedActions: []act{ 810 {"gplContainer.meta_lic", "restricted"}, 811 {"apacheLib.meta_lic", "notice|restricted"}, 812 }, 813 }, 814 { 815 name: "gplcontainerrestricted", 816 condition: ImpliesRestricted, 817 roots: []string{"gplContainer.meta_lic"}, 818 edges: []annotated{ 819 {"gplContainer.meta_lic", "apacheLib.meta_lic", []string{"static"}}, 820 }, 821 expectedActions: []act{ 822 {"gplContainer.meta_lic", "restricted"}, 823 {"apacheLib.meta_lic", "restricted"}, 824 }, 825 }, 826 { 827 name: "gploncontainernotice", 828 condition: ImpliesNotice, 829 roots: []string{"apacheContainer.meta_lic"}, 830 edges: []annotated{ 831 {"apacheContainer.meta_lic", "apacheLib.meta_lic", []string{"static"}}, 832 {"apacheContainer.meta_lic", "gplLib.meta_lic", []string{"static"}}, 833 }, 834 expectedActions: []act{ 835 {"apacheContainer.meta_lic", "notice|restricted"}, 836 {"apacheLib.meta_lic", "notice"}, 837 {"gplLib.meta_lic", "restricted"}, 838 }, 839 }, 840 { 841 name: "gploncontainerrestricted", 842 condition: ImpliesRestricted, 843 roots: []string{"apacheContainer.meta_lic"}, 844 edges: []annotated{ 845 {"apacheContainer.meta_lic", "apacheLib.meta_lic", []string{"static"}}, 846 {"apacheContainer.meta_lic", "gplLib.meta_lic", []string{"static"}}, 847 }, 848 expectedActions: []act{ 849 {"apacheContainer.meta_lic", "restricted"}, 850 {"gplLib.meta_lic", "restricted"}, 851 }, 852 }, 853 { 854 name: "gplonbinnotice", 855 condition: ImpliesNotice, 856 roots: []string{"apacheBin.meta_lic"}, 857 edges: []annotated{ 858 {"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"static"}}, 859 {"apacheBin.meta_lic", "gplLib.meta_lic", []string{"static"}}, 860 }, 861 expectedActions: []act{ 862 {"apacheBin.meta_lic", "notice|restricted"}, 863 {"apacheLib.meta_lic", "notice|restricted"}, 864 {"gplLib.meta_lic", "restricted"}, 865 }, 866 }, 867 { 868 name: "gplonbinrestricted", 869 condition: ImpliesRestricted, 870 roots: []string{"apacheBin.meta_lic"}, 871 edges: []annotated{ 872 {"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"static"}}, 873 {"apacheBin.meta_lic", "gplLib.meta_lic", []string{"static"}}, 874 }, 875 expectedActions: []act{ 876 {"apacheBin.meta_lic", "restricted"}, 877 {"apacheLib.meta_lic", "restricted"}, 878 {"gplLib.meta_lic", "restricted"}, 879 }, 880 }, 881 { 882 name: "gplonfpdynamicnotice", 883 condition: ImpliesNotice, 884 roots: []string{"gplBin.meta_lic"}, 885 edges: []annotated{ 886 {"gplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}}, 887 }, 888 expectedActions: []act{ 889 {"gplBin.meta_lic", "restricted"}, 890 }, 891 }, 892 { 893 name: "gplonfpdynamicrestricted", 894 condition: ImpliesRestricted, 895 roots: []string{"gplBin.meta_lic"}, 896 edges: []annotated{ 897 {"gplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}}, 898 }, 899 expectedActions: []act{ 900 {"gplBin.meta_lic", "restricted"}, 901 }, 902 }, 903 { 904 name: "gplonfpdynamicrestrictedshipped", 905 condition: ImpliesRestricted, 906 roots: []string{"gplBin.meta_lic", "apacheLib.meta_lic"}, 907 edges: []annotated{ 908 {"gplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}}, 909 }, 910 expectedActions: []act{ 911 {"gplBin.meta_lic", "restricted"}, 912 {"apacheLib.meta_lic", "restricted"}, 913 }, 914 }, 915 { 916 name: "independentmodulereversenotice", 917 condition: ImpliesNotice, 918 roots: []string{"gplWithClasspathException.meta_lic"}, 919 edges: []annotated{ 920 {"gplWithClasspathException.meta_lic", "apacheBin.meta_lic", []string{"dynamic"}}, 921 }, 922 expectedActions: []act{ 923 {"gplWithClasspathException.meta_lic", "permissive"}, 924 }, 925 }, 926 { 927 name: "independentmodulereverserestricted", 928 condition: ImpliesRestricted, 929 roots: []string{"gplWithClasspathException.meta_lic"}, 930 edges: []annotated{ 931 {"gplWithClasspathException.meta_lic", "apacheBin.meta_lic", []string{"dynamic"}}, 932 }, 933 expectedActions: []act{}, 934 }, 935 { 936 name: "independentmodulereverserestrictedshipped", 937 condition: ImpliesRestricted, 938 roots: []string{"gplWithClasspathException.meta_lic", "apacheBin.meta_lic"}, 939 edges: []annotated{ 940 {"gplWithClasspathException.meta_lic", "apacheBin.meta_lic", []string{"dynamic"}}, 941 }, 942 expectedActions: []act{}, 943 }, 944 { 945 name: "independentmodulereversestaticnotice", 946 condition: ImpliesNotice, 947 roots: []string{"gplWithClasspathException.meta_lic"}, 948 edges: []annotated{ 949 {"gplWithClasspathException.meta_lic", "apacheBin.meta_lic", []string{"static"}}, 950 }, 951 expectedActions: []act{ 952 {"gplWithClasspathException.meta_lic", "permissive"}, 953 {"apacheBin.meta_lic", "notice"}, 954 }, 955 }, 956 { 957 name: "independentmodulereversestaticrestricted", 958 condition: ImpliesRestricted, 959 roots: []string{"gplWithClasspathException.meta_lic"}, 960 edges: []annotated{ 961 {"gplWithClasspathException.meta_lic", "apacheBin.meta_lic", []string{"static"}}, 962 }, 963 expectedActions: []act{}, 964 }, 965 { 966 name: "dependentmodulereversenotice", 967 condition: ImpliesNotice, 968 roots: []string{"gplWithClasspathException.meta_lic"}, 969 edges: []annotated{ 970 {"gplWithClasspathException.meta_lic", "dependentModule.meta_lic", []string{"dynamic"}}, 971 }, 972 expectedActions: []act{ 973 {"gplWithClasspathException.meta_lic", "permissive"}, 974 }, 975 }, 976 { 977 name: "dependentmodulereverserestricted", 978 condition: ImpliesRestricted, 979 roots: []string{"gplWithClasspathException.meta_lic"}, 980 edges: []annotated{ 981 {"gplWithClasspathException.meta_lic", "dependentModule.meta_lic", []string{"dynamic"}}, 982 }, 983 expectedActions: []act{}, 984 }, 985 { 986 name: "dependentmodulereverserestrictedshipped", 987 condition: ImpliesRestricted, 988 roots: []string{"gplWithClasspathException.meta_lic", "dependentModule.meta_lic"}, 989 edges: []annotated{ 990 {"gplWithClasspathException.meta_lic", "dependentModule.meta_lic", []string{"dynamic"}}, 991 }, 992 expectedActions: []act{}, 993 }, 994 { 995 name: "ponrnotice", 996 condition: ImpliesNotice, 997 roots: []string{"proprietary.meta_lic"}, 998 edges: []annotated{ 999 {"proprietary.meta_lic", "gplLib.meta_lic", []string{"static"}}, 1000 }, 1001 expectedActions: []act{ 1002 {"proprietary.meta_lic", "restricted|proprietary"}, 1003 {"gplLib.meta_lic", "restricted"}, 1004 }, 1005 }, 1006 { 1007 name: "ponrrestricted", 1008 condition: ImpliesRestricted, 1009 roots: []string{"proprietary.meta_lic"}, 1010 edges: []annotated{ 1011 {"proprietary.meta_lic", "gplLib.meta_lic", []string{"static"}}, 1012 }, 1013 expectedActions: []act{ 1014 {"gplLib.meta_lic", "restricted"}, 1015 {"proprietary.meta_lic", "restricted"}, 1016 }, 1017 }, 1018 { 1019 name: "ponrproprietary", 1020 condition: ImpliesProprietary, 1021 roots: []string{"proprietary.meta_lic"}, 1022 edges: []annotated{ 1023 {"proprietary.meta_lic", "gplLib.meta_lic", []string{"static"}}, 1024 }, 1025 expectedActions: []act{ 1026 {"proprietary.meta_lic", "proprietary"}, 1027 }, 1028 }, 1029 { 1030 name: "ronpnotice", 1031 condition: ImpliesNotice, 1032 roots: []string{"gplBin.meta_lic"}, 1033 edges: []annotated{ 1034 {"gplBin.meta_lic", "proprietary.meta_lic", []string{"static"}}, 1035 }, 1036 expectedActions: []act{ 1037 {"gplBin.meta_lic", "restricted"}, 1038 {"proprietary.meta_lic", "restricted|proprietary"}, 1039 }, 1040 }, 1041 { 1042 name: "ronprestricted", 1043 condition: ImpliesRestricted, 1044 roots: []string{"gplBin.meta_lic"}, 1045 edges: []annotated{ 1046 {"gplBin.meta_lic", "proprietary.meta_lic", []string{"static"}}, 1047 }, 1048 expectedActions: []act{ 1049 {"gplBin.meta_lic", "restricted"}, 1050 {"proprietary.meta_lic", "restricted"}, 1051 }, 1052 }, 1053 { 1054 name: "ronpproprietary", 1055 condition: ImpliesProprietary, 1056 roots: []string{"gplBin.meta_lic"}, 1057 edges: []annotated{ 1058 {"gplBin.meta_lic", "proprietary.meta_lic", []string{"static"}}, 1059 }, 1060 expectedActions: []act{ 1061 {"proprietary.meta_lic", "proprietary"}, 1062 }, 1063 }, 1064 { 1065 name: "noticeonb_e_onotice", 1066 condition: ImpliesNotice, 1067 roots: []string{"mitBin.meta_lic"}, 1068 edges: []annotated{ 1069 {"mitBin.meta_lic", "by_exception.meta_lic", []string{"static"}}, 1070 }, 1071 expectedActions: []act{ 1072 {"mitBin.meta_lic", "notice"}, 1073 {"by_exception.meta_lic", "by_exception_only"}, 1074 }, 1075 }, 1076 { 1077 name: "noticeonb_e_orestricted", 1078 condition: ImpliesRestricted, 1079 roots: []string{"mitBin.meta_lic"}, 1080 edges: []annotated{ 1081 {"mitBin.meta_lic", "by_exception.meta_lic", []string{"static"}}, 1082 }, 1083 expectedActions: []act{}, 1084 }, 1085 { 1086 name: "noticeonb_e_ob_e_o", 1087 condition: ImpliesByExceptionOnly, 1088 roots: []string{"mitBin.meta_lic"}, 1089 edges: []annotated{ 1090 {"mitBin.meta_lic", "by_exception.meta_lic", []string{"static"}}, 1091 }, 1092 expectedActions: []act{ 1093 {"by_exception.meta_lic", "by_exception_only"}, 1094 }, 1095 }, 1096 { 1097 name: "b_e_oonnoticenotice", 1098 condition: ImpliesNotice, 1099 roots: []string{"by_exception.meta_lic"}, 1100 edges: []annotated{ 1101 {"by_exception.meta_lic", "mitLib.meta_lic", []string{"static"}}, 1102 }, 1103 expectedActions: []act{ 1104 {"by_exception.meta_lic", "by_exception_only"}, 1105 {"mitLib.meta_lic", "notice"}, 1106 }, 1107 }, 1108 { 1109 name: "b_e_oonnoticerestricted", 1110 condition: ImpliesRestricted, 1111 roots: []string{"by_exception.meta_lic"}, 1112 edges: []annotated{ 1113 {"by_exception.meta_lic", "mitLib.meta_lic", []string{"static"}}, 1114 }, 1115 expectedActions: []act{}, 1116 }, 1117 { 1118 name: "b_e_oonnoticeb_e_o", 1119 condition: ImpliesByExceptionOnly, 1120 roots: []string{"by_exception.meta_lic"}, 1121 edges: []annotated{ 1122 {"by_exception.meta_lic", "mitLib.meta_lic", []string{"static"}}, 1123 }, 1124 expectedActions: []act{ 1125 {"by_exception.meta_lic", "by_exception_only"}, 1126 }, 1127 }, 1128 { 1129 name: "noticeonrecipnotice", 1130 condition: ImpliesNotice, 1131 roots: []string{"mitBin.meta_lic"}, 1132 edges: []annotated{ 1133 {"mitBin.meta_lic", "mplLib.meta_lic", []string{"static"}}, 1134 }, 1135 expectedActions: []act{ 1136 {"mitBin.meta_lic", "notice"}, 1137 {"mplLib.meta_lic", "reciprocal"}, 1138 }, 1139 }, 1140 { 1141 name: "noticeonreciprecip", 1142 condition: ImpliesReciprocal, 1143 roots: []string{"mitBin.meta_lic"}, 1144 edges: []annotated{ 1145 {"mitBin.meta_lic", "mplLib.meta_lic", []string{"static"}}, 1146 }, 1147 expectedActions: []act{ 1148 {"mplLib.meta_lic", "reciprocal"}, 1149 }, 1150 }, 1151 { 1152 name: "reciponnoticenotice", 1153 condition: ImpliesNotice, 1154 roots: []string{"mplBin.meta_lic"}, 1155 edges: []annotated{ 1156 {"mplBin.meta_lic", "mitLib.meta_lic", []string{"static"}}, 1157 }, 1158 expectedActions: []act{ 1159 {"mplBin.meta_lic", "reciprocal"}, 1160 {"mitLib.meta_lic", "notice"}, 1161 }, 1162 }, 1163 { 1164 name: "reciponnoticerecip", 1165 condition: ImpliesReciprocal, 1166 roots: []string{"mplBin.meta_lic"}, 1167 edges: []annotated{ 1168 {"mplBin.meta_lic", "mitLib.meta_lic", []string{"static"}}, 1169 }, 1170 expectedActions: []act{ 1171 {"mplBin.meta_lic", "reciprocal"}, 1172 }, 1173 }, 1174 { 1175 name: "regress-walk-twice", 1176 condition: ImpliesShared, 1177 roots: []string{"mitBin.meta_lic", "apacheBin.meta_lic", "gplLib.meta_lic"}, 1178 edges: []annotated{ 1179 {"apacheBin.meta_lic", "mitLib.meta_lic", []string{"dynamic"}}, 1180 {"apacheBin.meta_lic", "gplLib.meta_lic", []string{"dynamic"}}, 1181 {"mitBin.meta_lic", "mitLib.meta_lic", []string{"static"}}, 1182 {"mitBin.meta_lic", "lgplLib.meta_lic", []string{"static"}}, 1183 }, 1184 expectedActions: []act{ 1185 {"apacheBin.meta_lic", "restricted"}, 1186 {"mitLib.meta_lic", "restricted|restricted_if_statically_linked"}, 1187 {"gplLib.meta_lic", "restricted"}, 1188 {"mitBin.meta_lic", "restricted_if_statically_linked"}, 1189 {"lgplLib.meta_lic", "restricted_if_statically_linked"}, 1190 }, 1191 }, 1192 } 1193 for _, tt := range tests { 1194 t.Run(tt.name, func(t *testing.T) { 1195 stderr := &bytes.Buffer{} 1196 lg, err := toGraph(stderr, tt.roots, tt.edges) 1197 if err != nil { 1198 t.Errorf("unexpected test data error: got %s, want no error", err) 1199 return 1200 } 1201 expectedAs := toActionSet(lg, tt.expectedActions) 1202 ResolveTopDownConditions(lg) 1203 actualAs := WalkActionsForCondition(lg, tt.condition) 1204 checkResolvesActions(lg, actualAs, expectedAs, t) 1205 }) 1206 } 1207} 1208 1209func TestWalkTopDownBreadthFirst(t *testing.T) { 1210 tests := []struct { 1211 name string 1212 roots []string 1213 edges []annotated 1214 expectedResult []string 1215 }{ 1216 { 1217 name: "bin/bin1", 1218 roots: []string{"bin/bin1.meta_lic"}, 1219 expectedResult: []string{ 1220 "testdata/notice/bin/bin1.meta_lic", 1221 "testdata/notice/lib/liba.so.meta_lic", 1222 "testdata/notice/lib/libc.a.meta_lic", 1223 }, 1224 }, 1225 { 1226 name: "bin/bin2", 1227 roots: []string{"bin/bin2.meta_lic"}, 1228 expectedResult: []string{ 1229 "testdata/notice/bin/bin2.meta_lic", 1230 "testdata/notice/lib/libb.so.meta_lic", 1231 "testdata/notice/lib/libd.so.meta_lic", 1232 }, 1233 }, 1234 { 1235 name: "bin/bin3", 1236 roots: []string{"bin/bin3.meta_lic"}, 1237 expectedResult: []string{ 1238 "testdata/notice/bin/bin3.meta_lic", 1239 }, 1240 }, 1241 { 1242 name: "lib/liba.so", 1243 roots: []string{"lib/liba.so.meta_lic"}, 1244 expectedResult: []string{ 1245 "testdata/notice/lib/liba.so.meta_lic", 1246 }, 1247 }, 1248 { 1249 name: "lib/libb.so", 1250 roots: []string{"lib/libb.so.meta_lic"}, 1251 expectedResult: []string{ 1252 "testdata/notice/lib/libb.so.meta_lic", 1253 }, 1254 }, 1255 { 1256 name: "lib/libc.so", 1257 roots: []string{"lib/libc.a.meta_lic"}, 1258 expectedResult: []string{ 1259 "testdata/notice/lib/libc.a.meta_lic", 1260 }, 1261 }, 1262 { 1263 name: "lib/libd.so", 1264 roots: []string{"lib/libd.so.meta_lic"}, 1265 expectedResult: []string{ 1266 "testdata/notice/lib/libd.so.meta_lic", 1267 }, 1268 }, 1269 { 1270 name: "highest.apex", 1271 roots: []string{"highest.apex.meta_lic"}, 1272 expectedResult: []string{ 1273 "testdata/notice/highest.apex.meta_lic", 1274 "testdata/notice/bin/bin1.meta_lic", 1275 "testdata/notice/bin/bin2.meta_lic", 1276 "testdata/notice/lib/liba.so.meta_lic", 1277 "testdata/notice/lib/libb.so.meta_lic", 1278 "testdata/notice/lib/liba.so.meta_lic", 1279 "testdata/notice/lib/libc.a.meta_lic", 1280 "testdata/notice/lib/libb.so.meta_lic", 1281 "testdata/notice/lib/libd.so.meta_lic", 1282 }, 1283 }, 1284 { 1285 name: "container.zip", 1286 roots: []string{"container.zip.meta_lic"}, 1287 expectedResult: []string{ 1288 "testdata/notice/container.zip.meta_lic", 1289 "testdata/notice/bin/bin1.meta_lic", 1290 "testdata/notice/bin/bin2.meta_lic", 1291 "testdata/notice/lib/liba.so.meta_lic", 1292 "testdata/notice/lib/libb.so.meta_lic", 1293 "testdata/notice/lib/liba.so.meta_lic", 1294 "testdata/notice/lib/libc.a.meta_lic", 1295 "testdata/notice/lib/libb.so.meta_lic", 1296 "testdata/notice/lib/libd.so.meta_lic", 1297 }, 1298 }, 1299 { 1300 name: "application", 1301 roots: []string{"application.meta_lic"}, 1302 expectedResult: []string{ 1303 "testdata/notice/application.meta_lic", 1304 "testdata/notice/bin/bin3.meta_lic", 1305 "testdata/notice/lib/liba.so.meta_lic", 1306 "testdata/notice/lib/libb.so.meta_lic", 1307 }, 1308 }, 1309 { 1310 name: "bin/bin1&lib/liba", 1311 roots: []string{"bin/bin1.meta_lic","lib/liba.so.meta_lic"}, 1312 expectedResult: []string{ 1313 "testdata/notice/bin/bin1.meta_lic", 1314 "testdata/notice/lib/liba.so.meta_lic", 1315 "testdata/notice/lib/liba.so.meta_lic", 1316 "testdata/notice/lib/libc.a.meta_lic", 1317 }, 1318 }, 1319 { 1320 name: "bin/bin2&lib/libd", 1321 roots: []string{"bin/bin2.meta_lic", "lib/libd.so.meta_lic"}, 1322 expectedResult: []string{ 1323 "testdata/notice/bin/bin2.meta_lic", 1324 "testdata/notice/lib/libd.so.meta_lic", 1325 "testdata/notice/lib/libb.so.meta_lic", 1326 "testdata/notice/lib/libd.so.meta_lic", 1327 }, 1328 }, 1329 { 1330 name: "application&bin/bin3", 1331 roots: []string{"application.meta_lic", "bin/bin3.meta_lic"}, 1332 expectedResult: []string{ 1333 "testdata/notice/application.meta_lic", 1334 "testdata/notice/bin/bin3.meta_lic", 1335 "testdata/notice/bin/bin3.meta_lic", 1336 "testdata/notice/lib/liba.so.meta_lic", 1337 "testdata/notice/lib/libb.so.meta_lic", 1338 }, 1339 }, 1340 { 1341 name: "highest.apex&container.zip", 1342 roots: []string{"highest.apex.meta_lic", "container.zip.meta_lic"}, 1343 expectedResult: []string{ 1344 "testdata/notice/highest.apex.meta_lic", 1345 "testdata/notice/container.zip.meta_lic", 1346 "testdata/notice/bin/bin1.meta_lic", 1347 "testdata/notice/bin/bin2.meta_lic", 1348 "testdata/notice/lib/liba.so.meta_lic", 1349 "testdata/notice/lib/libb.so.meta_lic", 1350 "testdata/notice/lib/liba.so.meta_lic", 1351 "testdata/notice/lib/libc.a.meta_lic", 1352 "testdata/notice/lib/libb.so.meta_lic", 1353 "testdata/notice/lib/libd.so.meta_lic", 1354 "testdata/notice/bin/bin1.meta_lic", 1355 "testdata/notice/bin/bin2.meta_lic", 1356 "testdata/notice/lib/liba.so.meta_lic", 1357 "testdata/notice/lib/libb.so.meta_lic", 1358 "testdata/notice/lib/liba.so.meta_lic", 1359 "testdata/notice/lib/libc.a.meta_lic", 1360 "testdata/notice/lib/libb.so.meta_lic", 1361 "testdata/notice/lib/libd.so.meta_lic", 1362 }, 1363 }, 1364 } 1365 1366 for _, tt := range tests { 1367 t.Run(tt.name, func(t *testing.T) { 1368 stderr := &bytes.Buffer{} 1369 actualOut := &bytes.Buffer{} 1370 1371 rootFiles := make([]string, 0, len(tt.roots)) 1372 for _, r := range tt.roots { 1373 rootFiles = append(rootFiles, "testdata/notice/"+r) 1374 } 1375 1376 lg, err := ReadLicenseGraph(GetFS(""), stderr, rootFiles) 1377 1378 if err != nil { 1379 t.Errorf("unexpected test data error: got %s, want no error", err) 1380 return 1381 } 1382 1383 expectedRst := tt.expectedResult 1384 1385 WalkTopDownBreadthFirst(nil, lg, func(lg *LicenseGraph, tn *TargetNode, path TargetEdgePath) bool { 1386 fmt.Fprintln(actualOut, tn.Name()) 1387 return true 1388 }) 1389 1390 actualRst := strings.Split(actualOut.String(), "\n") 1391 1392 if len(actualRst) > 0 { 1393 actualRst = actualRst[:len(actualRst)-1] 1394 } 1395 1396 t.Logf("actual nodes visited: %s", actualOut.String()) 1397 t.Logf("expected nodes visited: %s", strings.Join(expectedRst, "\n")) 1398 1399 if len(actualRst) != len(expectedRst) { 1400 t.Errorf("WalkTopDownBreadthFirst: number of visited nodes is different: got %d, want %d", len(actualRst), len(expectedRst)) 1401 } 1402 1403 for i := 0; i < len(actualRst) && i < len(expectedRst); i++ { 1404 if actualRst[i] != expectedRst[i] { 1405 t.Errorf("WalkTopDownBreadthFirst: lines differ at index %d: got %q, want %q", i, actualRst[i], expectedRst[i]) 1406 break 1407 } 1408 } 1409 1410 if len(actualRst) < len(expectedRst) { 1411 t.Errorf("WalkTopDownBreadthFirst: extra lines at %d: got %q, want nothing", len(actualRst), expectedRst[len(actualRst)]) 1412 } 1413 1414 if len(expectedRst) < len(actualRst) { 1415 t.Errorf("WalkTopDownBreadthFirst: missing lines at %d: got nothing, want %q", len(expectedRst), actualRst[len(expectedRst)]) 1416 } 1417 }) 1418 } 1419} 1420 1421func TestWalkTopDownBreadthFirstWithoutDuplicates(t *testing.T) { 1422 tests := []struct { 1423 name string 1424 roots []string 1425 edges []annotated 1426 expectedResult []string 1427 }{ 1428 { 1429 name: "bin/bin1", 1430 roots: []string{"bin/bin1.meta_lic"}, 1431 expectedResult: []string{ 1432 "testdata/notice/bin/bin1.meta_lic", 1433 "testdata/notice/lib/liba.so.meta_lic", 1434 "testdata/notice/lib/libc.a.meta_lic", 1435 }, 1436 }, 1437 { 1438 name: "bin/bin2", 1439 roots: []string{"bin/bin2.meta_lic"}, 1440 expectedResult: []string{ 1441 "testdata/notice/bin/bin2.meta_lic", 1442 "testdata/notice/lib/libb.so.meta_lic", 1443 "testdata/notice/lib/libd.so.meta_lic", 1444 }, 1445 }, 1446 { 1447 name: "bin/bin3", 1448 roots: []string{"bin/bin3.meta_lic"}, 1449 expectedResult: []string{ 1450 "testdata/notice/bin/bin3.meta_lic", 1451 }, 1452 }, 1453 { 1454 name: "lib/liba.so", 1455 roots: []string{"lib/liba.so.meta_lic"}, 1456 expectedResult: []string{ 1457 "testdata/notice/lib/liba.so.meta_lic", 1458 }, 1459 }, 1460 { 1461 name: "lib/libb.so", 1462 roots: []string{"lib/libb.so.meta_lic"}, 1463 expectedResult: []string{ 1464 "testdata/notice/lib/libb.so.meta_lic", 1465 }, 1466 }, 1467 { 1468 name: "lib/libc.so", 1469 roots: []string{"lib/libc.a.meta_lic"}, 1470 expectedResult: []string{ 1471 "testdata/notice/lib/libc.a.meta_lic", 1472 }, 1473 }, 1474 { 1475 name: "lib/libd.so", 1476 roots: []string{"lib/libd.so.meta_lic"}, 1477 expectedResult: []string{ 1478 "testdata/notice/lib/libd.so.meta_lic", 1479 }, 1480 }, 1481 { 1482 name: "highest.apex", 1483 roots: []string{"highest.apex.meta_lic"}, 1484 expectedResult: []string{ 1485 "testdata/notice/highest.apex.meta_lic", 1486 "testdata/notice/bin/bin1.meta_lic", 1487 "testdata/notice/bin/bin2.meta_lic", 1488 "testdata/notice/lib/liba.so.meta_lic", 1489 "testdata/notice/lib/libb.so.meta_lic", 1490 "testdata/notice/lib/libc.a.meta_lic", 1491 "testdata/notice/lib/libd.so.meta_lic", 1492 }, 1493 }, 1494 { 1495 name: "container.zip", 1496 roots: []string{"container.zip.meta_lic"}, 1497 expectedResult: []string{ 1498 "testdata/notice/container.zip.meta_lic", 1499 "testdata/notice/bin/bin1.meta_lic", 1500 "testdata/notice/bin/bin2.meta_lic", 1501 "testdata/notice/lib/liba.so.meta_lic", 1502 "testdata/notice/lib/libb.so.meta_lic", 1503 "testdata/notice/lib/libc.a.meta_lic", 1504 "testdata/notice/lib/libd.so.meta_lic", 1505 }, 1506 }, 1507 { 1508 name: "application", 1509 roots: []string{"application.meta_lic"}, 1510 expectedResult: []string{ 1511 "testdata/notice/application.meta_lic", 1512 "testdata/notice/bin/bin3.meta_lic", 1513 "testdata/notice/lib/liba.so.meta_lic", 1514 "testdata/notice/lib/libb.so.meta_lic", 1515 }, 1516 }, 1517 { 1518 name: "bin/bin1&lib/liba", 1519 roots: []string{"bin/bin1.meta_lic", "lib/liba.so.meta_lic"}, 1520 expectedResult: []string{ 1521 "testdata/notice/bin/bin1.meta_lic", 1522 "testdata/notice/lib/liba.so.meta_lic", 1523 "testdata/notice/lib/libc.a.meta_lic", 1524 }, 1525 }, 1526 { 1527 name: "bin/bin2&lib/libd", 1528 roots: []string{"bin/bin2.meta_lic", "lib/libd.so.meta_lic"}, 1529 expectedResult: []string{ 1530 "testdata/notice/bin/bin2.meta_lic", 1531 "testdata/notice/lib/libd.so.meta_lic", 1532 "testdata/notice/lib/libb.so.meta_lic", 1533 }, 1534 }, 1535 { 1536 name: "application&bin/bin3", 1537 roots: []string{"application.meta_lic", "bin/bin3.meta_lic"}, 1538 expectedResult: []string{ 1539 "testdata/notice/application.meta_lic", 1540 "testdata/notice/bin/bin3.meta_lic", 1541 "testdata/notice/lib/liba.so.meta_lic", 1542 "testdata/notice/lib/libb.so.meta_lic", 1543 }, 1544 }, 1545 { 1546 name: "highest.apex&container.zip", 1547 roots: []string{"highest.apex.meta_lic", "container.zip.meta_lic"}, 1548 expectedResult: []string{ 1549 "testdata/notice/highest.apex.meta_lic", 1550 "testdata/notice/container.zip.meta_lic", 1551 "testdata/notice/bin/bin1.meta_lic", 1552 "testdata/notice/bin/bin2.meta_lic", 1553 "testdata/notice/lib/liba.so.meta_lic", 1554 "testdata/notice/lib/libb.so.meta_lic", 1555 "testdata/notice/lib/libc.a.meta_lic", 1556 "testdata/notice/lib/libd.so.meta_lic", 1557 }, 1558 }, 1559 } 1560 1561 for _, tt := range tests { 1562 t.Run(tt.name, func(t *testing.T) { 1563 stderr := &bytes.Buffer{} 1564 actualOut := &bytes.Buffer{} 1565 1566 rootFiles := make([]string, 0, len(tt.roots)) 1567 for _, r := range tt.roots { 1568 rootFiles = append(rootFiles, "testdata/notice/"+r) 1569 } 1570 1571 lg, err := ReadLicenseGraph(GetFS(""), stderr, rootFiles) 1572 1573 if err != nil { 1574 t.Errorf("unexpected test data error: got %s, want no error", err) 1575 return 1576 } 1577 1578 expectedRst := tt.expectedResult 1579 1580 //Keeping track of the visited nodes 1581 //Only add to actualOut if not visited 1582 visitedNodes := make(map[string]struct{}) 1583 WalkTopDownBreadthFirst(nil, lg, func(lg *LicenseGraph, tn *TargetNode, path TargetEdgePath) bool { 1584 if _, alreadyVisited := visitedNodes[tn.Name()]; alreadyVisited { 1585 return false 1586 } 1587 fmt.Fprintln(actualOut, tn.Name()) 1588 visitedNodes[tn.Name()] = struct{}{} 1589 return true 1590 }) 1591 1592 actualRst := strings.Split(actualOut.String(), "\n") 1593 1594 if len(actualRst) > 0 { 1595 actualRst = actualRst[:len(actualRst)-1] 1596 } 1597 1598 t.Logf("actual nodes visited: %s", actualOut.String()) 1599 t.Logf("expected nodes visited: %s", strings.Join(expectedRst, "\n")) 1600 1601 if len(actualRst) != len(expectedRst) { 1602 t.Errorf("WalkTopDownBreadthFirst: number of visited nodes is different: got %d, want %d", len(actualRst), len(expectedRst)) 1603 } 1604 1605 for i := 0; i < len(actualRst) && i < len(expectedRst); i++ { 1606 if actualRst[i] != expectedRst[i] { 1607 t.Errorf("WalkTopDownBreadthFirst: lines differ at index %d: got %q, want %q", i, actualRst[i], expectedRst[i]) 1608 break 1609 } 1610 } 1611 1612 if len(actualRst) < len(expectedRst) { 1613 t.Errorf("WalkTopDownBreadthFirst: extra lines at %d: got %q, want nothing", len(actualRst), expectedRst[len(actualRst)]) 1614 } 1615 1616 if len(expectedRst) < len(actualRst) { 1617 t.Errorf("WalkTopDownBreadthFirst: missing lines at %d: got nothing, want %q", len(expectedRst), actualRst[len(expectedRst)]) 1618 } 1619 }) 1620 } 1621} 1622