gitee.com/leisunstar/runtime@v0.0.0-20200521203717-5cef3e7b53f9/pkg/katatestutils/constraints_test.go (about) 1 // Copyright (c) 2019 Intel Corporation 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 // 5 6 package katatestutils 7 8 import ( 9 "errors" 10 "fmt" 11 "io/ioutil" 12 "os" 13 "os/exec" 14 "path/filepath" 15 "strconv" 16 "strings" 17 "testing" 18 19 "github.com/blang/semver" 20 "github.com/stretchr/testify/assert" 21 ) 22 23 const ( 24 testFileMode = os.FileMode(0640) 25 invalidOperator = 1234 26 27 skipUnknownDistroName = "skipping test as cannot determine distro name" 28 ) 29 30 type testDataUID struct { 31 uid int 32 op Operator 33 c Constraints 34 } 35 36 type testDataDistro struct { 37 distro string 38 op Operator 39 c Constraints 40 } 41 42 var distros = []string{ 43 "centos", 44 "clear-linux-os", 45 "debian", 46 "fedora", 47 "opensuse", 48 "rhel", 49 "sles", 50 "ubuntu", 51 } 52 53 var thisUID = os.Getuid() 54 var rootUID = 0 55 56 // name and version of current distro and kernel version of system tests are 57 // running on 58 var distroName string 59 var distroVersion string 60 var kernelVersion string 61 62 // error saved when attempting to determine distro name+version and kernel 63 // version. 64 var getDistroErr error 65 var getKernelErr error 66 67 // true if running as root 68 var root = thisUID == rootUID 69 70 var uidEqualsRootData = testDataUID{ 71 uid: rootUID, 72 op: eqOperator, 73 c: Constraints{ 74 Operator: eqOperator, 75 UID: rootUID, 76 UIDSet: true, 77 }, 78 } 79 80 var uidNotEqualsRootData = testDataUID{ 81 uid: rootUID, 82 op: neOperator, 83 c: Constraints{ 84 Operator: neOperator, 85 UID: rootUID, 86 UIDSet: true, 87 }, 88 } 89 90 var distroEqualsCurrentData testDataDistro 91 var distroNotEqualsCurrentData testDataDistro 92 93 func init() { 94 distroName, distroVersion, getDistroErr = testGetDistro() 95 kernelVersion, getKernelErr = testGetKernelVersion() 96 97 distroEqualsCurrentData = testDataDistro{ 98 distro: distroName, 99 op: eqOperator, 100 c: Constraints{ 101 DistroName: distroName, 102 Operator: eqOperator, 103 }, 104 } 105 106 distroNotEqualsCurrentData = testDataDistro{ 107 distro: distroName, 108 op: neOperator, 109 c: Constraints{ 110 DistroName: distroName, 111 Operator: neOperator, 112 }, 113 } 114 } 115 116 func fileExists(path string) bool { 117 if _, err := os.Stat(path); os.IsNotExist(err) { 118 return false 119 } 120 121 return true 122 } 123 124 // getAnotherDistro returns a distro name not equal to the one specified. 125 func getAnotherDistro(distro string) string { 126 for _, d := range distros { 127 if d != distro { 128 return d 129 } 130 } 131 132 panic(fmt.Sprintf("failed to find a distro different to %s", distro)) 133 } 134 135 func checkUIDConstraints(assert *assert.Assertions, a, b Constraints, desc string) { 136 msg := fmt.Sprintf("%s: a: %+v, b: %+v", desc, a, b) 137 138 assert.Equal(a.UID, b.UID, msg) 139 assert.Equal(a.Operator, b.Operator, msg) 140 assert.Equal(a.UIDSet, b.UIDSet, msg) 141 } 142 143 func checkDistroConstraints(assert *assert.Assertions, a, b Constraints, desc string) { 144 msg := fmt.Sprintf("%s: a: %+v, b: %+v", desc, a, b) 145 146 assert.Equal(a.DistroName, b.DistroName, msg) 147 assert.Equal(a.Operator, b.Operator, msg) 148 } 149 150 func checkKernelConstraint(assert *assert.Assertions, f Constraint, version string, op Operator, msg string) { 151 c := Constraints{} 152 153 f(&c) 154 155 assert.Equal(c.KernelVersion, version, msg) 156 assert.Equal(c.Operator, op, msg) 157 } 158 159 // runCommand runs a command and returns its output 160 func runCommand(args ...string) ([]string, error) { 161 cmd := exec.Command(args[0], args[1:]...) 162 bytes, err := cmd.Output() 163 if err != nil { 164 return []string{}, err 165 } 166 167 output := strings.Split(string(bytes), "\n") 168 169 return output, nil 170 } 171 172 // semverBumpVersion takes an existing semantic version and increments one or 173 // more parts of it, returning the new version number as a string. 174 func semverBumpVersion(ver semver.Version, bumpMajor, bumpMinor, bumpPatch bool) (string, error) { 175 if bumpMajor { 176 err := ver.IncrementMajor() 177 if err != nil { 178 return "", err 179 } 180 } 181 182 if bumpMinor { 183 err := ver.IncrementMinor() 184 if err != nil { 185 return "", err 186 } 187 } 188 189 if bumpPatch { 190 err := ver.IncrementPatch() 191 if err != nil { 192 return "", err 193 } 194 } 195 196 return ver.String(), nil 197 } 198 199 // changeVersion modifies the specified version and returns the 200 // string representation. If decrement is true the returned version is smaller 201 // than the specified version, else it is larger. 202 func changeVersion(version string, decrement bool) (string, error) { 203 operand := int64(1) 204 205 if decrement { 206 operand = -1 207 } 208 209 // Is it an integer? 210 intResult, err := strconv.ParseUint(version, 10, 0) 211 if err == nil { 212 if intResult == 0 && decrement { 213 return "", fmt.Errorf("cannot decrement integer version with value zero") 214 } 215 216 return fmt.Sprintf("%d", uint64(int64(intResult)+operand)), nil 217 } 218 219 // Is it a float? 220 floatResult, err := strconv.ParseFloat(version, 32) 221 if err == nil { 222 if int(floatResult) == 0 && decrement { 223 return "", fmt.Errorf("cannot decrement integer part of floating point version with value zero: %v", version) 224 } 225 226 return fmt.Sprintf("%f", floatResult+float64(operand)), nil 227 } 228 229 // Not an int nor a float, so it must be a semantic version 230 ver, err := semver.Make(version) 231 if err != nil { 232 // but if not, bail as we've run out of options 233 return "", err 234 } 235 236 if decrement { 237 // the semver package only provides increment operations, so 238 // handle decrement ourselves. 239 major := ver.Major 240 241 if major == 0 { 242 return "", fmt.Errorf("cannot decrement semver with zero major version: %+v", version) 243 } 244 245 major-- 246 247 ver.Major = major 248 } else { 249 err = ver.IncrementMajor() 250 if err != nil { 251 return "", err 252 } 253 } 254 255 return ver.String(), nil 256 } 257 258 func incrementVersion(version string) (string, error) { 259 return changeVersion(version, false) 260 } 261 262 func decrementVersion(version string) (string, error) { 263 return changeVersion(version, true) 264 } 265 266 // testGetDistro is an alternative implementation of getDistroDetails() used 267 // for testing. 268 func testGetDistro() (name, version string, err error) { 269 files := []string{"/etc/os-release", "/usr/lib/os-release"} 270 271 for _, file := range files { 272 if !fileExists(file) { 273 continue 274 } 275 276 output, err := runCommand("grep", "^ID=", file) 277 if err != nil { 278 return "", "", err 279 } 280 281 line := output[0] 282 fields := strings.Split(line, "=") 283 if name == "" { 284 name = strings.Trim(fields[1], `"`) 285 name = strings.ToLower(name) 286 } 287 288 output, err = runCommand("grep", "^VERSION_ID=", file) 289 if err != nil { 290 return "", "", err 291 } 292 293 line = output[0] 294 fields = strings.Split(line, "=") 295 if version == "" { 296 version = strings.Trim(fields[1], `"`) 297 version = strings.ToLower(version) 298 } 299 } 300 301 if name != "" && version != "" { 302 return name, version, nil 303 } 304 305 if name == "" { 306 return "", "", errUnknownDistroName 307 } 308 309 if version == "" { 310 return "", "", errUnknownDistroVersion 311 } 312 313 return "", "", errors.New("BUG: something bad happened") 314 } 315 316 func testGetKernelVersion() (version string, err error) { 317 const file = "/proc/version" 318 319 bytes, err := ioutil.ReadFile(file) 320 if err != nil { 321 return "", err 322 } 323 324 line := string(bytes) 325 fields := strings.Fields(line) 326 327 const minFields = 3 328 329 count := len(fields) 330 331 if count < minFields { 332 return "", fmt.Errorf("expected atleast %d fields in file %q, got %d", 333 minFields, file, count) 334 } 335 336 version = fixKernelVersion(fields[2]) 337 338 return version, nil 339 } 340 341 func TestOperatorString(t *testing.T) { 342 assert := assert.New(t) 343 344 type testData struct { 345 op Operator 346 value string 347 } 348 349 data := []testData{ 350 {eqOperator, "=="}, 351 {neOperator, "!="}, 352 } 353 354 for i, d := range data { 355 value := d.op.String() 356 357 assert.Equal(value, d.value, "test[%d]: %+v", i, d) 358 } 359 } 360 361 func TestNewTestConstraint(t *testing.T) { 362 if getDistroErr != nil { 363 t.Skipf("skipping as unable to determine distro name/version: %v", 364 getDistroErr) 365 } 366 367 if getKernelErr != nil { 368 t.Skipf("skipping as unable to determine kernel version: %v", 369 getKernelErr) 370 } 371 372 assert := assert.New(t) 373 374 for i, debug := range []bool{true, false} { 375 c := NewTestConstraint(debug) 376 377 msg := fmt.Sprintf("test[%d]: debug: %v, constraint: %+v", i, debug, c) 378 379 assert.Equal(debug, c.Debug, msg) 380 381 assert.Equal(distroName, c.DistroName, msg) 382 assert.Equal(distroVersion, c.DistroVersion, msg) 383 assert.Equal(kernelVersion, c.KernelVersion, msg) 384 assert.Equal(thisUID, c.ActualEUID) 385 386 toCheck := []string{ 387 distroName, 388 distroVersion, 389 kernelVersion, 390 c.DistroName, 391 c.DistroVersion, 392 c.KernelVersion, 393 } 394 395 for _, str := range toCheck { 396 assert.NotNil(str, msg) 397 } 398 } 399 } 400 401 func TestGetFileContents(t *testing.T) { 402 assert := assert.New(t) 403 404 type testData struct { 405 contents string 406 } 407 408 data := []testData{ 409 {""}, 410 {" "}, 411 {"\n"}, 412 {"\n\n"}, 413 {"\n\n\n"}, 414 {"foo"}, 415 {"foo\nbar"}, 416 } 417 418 dir, err := ioutil.TempDir("", "") 419 assert.NoError(err) 420 defer os.RemoveAll(dir) 421 422 file := filepath.Join(dir, "foo") 423 424 // file doesn't exist 425 _, err = getFileContents(file) 426 assert.Error(err) 427 428 for _, d := range data { 429 // create the file 430 err = ioutil.WriteFile(file, []byte(d.contents), testFileMode) 431 assert.NoError(err) 432 defer os.Remove(file) 433 434 contents, err := getFileContents(file) 435 assert.NoError(err) 436 assert.Equal(contents, d.contents) 437 } 438 } 439 440 func TestGetDistroDetails(t *testing.T) { 441 assert := assert.New(t) 442 443 if getDistroErr == errUnknownDistroName { 444 t.Skip(skipUnknownDistroName) 445 } 446 447 assert.NoError(getDistroErr) 448 assert.NotNil(distroName) 449 assert.NotNil(distroVersion) 450 451 name, version, err := getDistroDetails() 452 assert.NoError(err) 453 assert.NotNil(name) 454 assert.NotNil(version) 455 456 assert.Equal(name, distroName) 457 assert.Equal(version, distroVersion) 458 } 459 460 func TestGetKernelVersion(t *testing.T) { 461 assert := assert.New(t) 462 463 assert.NoError(getKernelErr) 464 assert.NotNil(kernelVersion) 465 466 version, err := getKernelVersion() 467 assert.NoError(err) 468 assert.NotNil(version) 469 470 assert.Equal(version, kernelVersion) 471 } 472 473 func TestConstraintHandleDistroName(t *testing.T) { 474 assert := assert.New(t) 475 476 type testData struct { 477 distro string 478 op Operator 479 result Result 480 expectError bool 481 } 482 483 distroName, _, err := testGetDistro() 484 if err != nil && err == errUnknownDistroName { 485 t.Skip(skipUnknownDistroName) 486 } 487 488 // Look for the first distro that is not the same as the distro this 489 // test is currently running on. 490 differentDistro := getAnotherDistro(distroName) 491 492 data := []testData{ 493 {"", eqOperator, Result{}, true}, 494 {"", neOperator, Result{}, true}, 495 {"", invalidOperator, Result{}, true}, 496 {distroName, invalidOperator, Result{}, true}, 497 {distroName, invalidOperator, Result{}, true}, 498 499 { 500 distroName, 501 eqOperator, 502 Result{ 503 Description: distroName, 504 Success: true, 505 }, 506 false, 507 }, 508 { 509 distroName, 510 neOperator, 511 Result{ 512 Description: distroName, 513 Success: false, 514 }, 515 false, 516 }, 517 { 518 differentDistro, 519 eqOperator, 520 Result{ 521 Description: differentDistro, 522 Success: false, 523 }, 524 false, 525 }, 526 527 { 528 differentDistro, 529 neOperator, 530 Result{ 531 Description: differentDistro, 532 Success: true, 533 }, 534 false, 535 }, 536 } 537 538 for _, debug := range []bool{true, false} { 539 tc := NewTestConstraint(debug) 540 541 for i, d := range data { 542 result, err := tc.handleDistroName(d.distro, d.op) 543 544 msg := fmt.Sprintf("test[%d]: %+v, result: %+v", i, d, result) 545 546 if d.expectError { 547 assert.Error(err, msg) 548 continue 549 550 } 551 552 assert.NoError(err, msg) 553 assert.Equal(result.Success, d.result.Success, msg) 554 assert.NotNil(result.Description, msg) 555 } 556 } 557 } 558 559 func TestConstraintHandleDistroVersion(t *testing.T) { 560 assert := assert.New(t) 561 562 assert.NotNil(distroVersion) 563 564 // Generate a new distro version for testing purposes. Since we don't 565 // know the format of this particular distros versioning scheme, we 566 // need to calculate it. 567 higherVersion, err := incrementVersion(distroVersion) 568 assert.NoError(err) 569 assert.NotEqual(distroVersion, higherVersion) 570 571 type testData struct { 572 version string 573 op Operator 574 result Result 575 expectError bool 576 } 577 578 data := []testData{ 579 {"", eqOperator, Result{}, true}, 580 {"", geOperator, Result{}, true}, 581 {"", gtOperator, Result{}, true}, 582 {"", leOperator, Result{}, true}, 583 {"", ltOperator, Result{}, true}, 584 {"", neOperator, Result{}, true}, 585 586 {distroVersion, eqOperator, Result{Success: true}, false}, 587 {higherVersion, eqOperator, Result{Success: false}, false}, 588 589 {distroVersion, gtOperator, Result{Success: false}, false}, 590 {higherVersion, gtOperator, Result{Success: false}, false}, 591 592 {distroVersion, geOperator, Result{Success: true}, false}, 593 {higherVersion, geOperator, Result{Success: false}, false}, 594 595 {distroVersion, ltOperator, Result{Success: false}, false}, 596 {higherVersion, ltOperator, Result{Success: true}, false}, 597 598 {distroVersion, leOperator, Result{Success: true}, false}, 599 {higherVersion, leOperator, Result{Success: true}, false}, 600 601 {distroVersion, neOperator, Result{Success: false}, false}, 602 {higherVersion, neOperator, Result{Success: true}, false}, 603 } 604 605 for _, debug := range []bool{true, false} { 606 tc := NewTestConstraint(debug) 607 608 for i, d := range data { 609 result, err := tc.handleDistroVersion(d.version, d.op) 610 611 msg := fmt.Sprintf("test[%d]: %+v, result: %+v", i, d, result) 612 613 if d.expectError { 614 assert.Error(err, msg) 615 continue 616 } 617 618 assert.Equal(d.result.Success, result.Success, msg) 619 } 620 } 621 } 622 623 func TestConstraintHandleVersionType(t *testing.T) { 624 assert := assert.New(t) 625 626 type testData struct { 627 versionName string 628 currentVersion string 629 op Operator 630 newVersion string 631 result Result 632 expectError bool 633 } 634 635 data := []testData{ 636 //---------- 637 638 {"", "", eqOperator, "", Result{}, true}, 639 640 {"name", "foo", eqOperator, "", Result{}, true}, 641 {"name", "", eqOperator, "foo", Result{}, true}, 642 {"name", "1", eqOperator, "", Result{}, true}, 643 {"name", "", eqOperator, "1", Result{}, true}, 644 645 {"name", "1", eqOperator, "1", Result{Success: true}, false}, 646 {"name", "1", eqOperator, "2", Result{Success: false}, false}, 647 {"name", "2", eqOperator, "1", Result{Success: false}, false}, 648 649 {"name", "3.141", eqOperator, "3.141", Result{Success: true}, false}, 650 {"name", "4.141", eqOperator, "3.141", Result{Success: false}, false}, 651 {"name", "3.141", eqOperator, "4.141", Result{Success: false}, false}, 652 653 {"name", "3.1.4-1", eqOperator, "3.1.4-1", Result{Success: true}, false}, 654 {"name", "3.1.4-1", eqOperator, "4.1.4-1", Result{Success: false}, false}, 655 {"name", "4.1.4-1", eqOperator, "3.1.4-1", Result{Success: false}, false}, 656 657 //---------- 658 659 {"", "", ltOperator, "", Result{}, true}, 660 661 {"name", "foo", ltOperator, "", Result{}, true}, 662 {"name", "", ltOperator, "foo", Result{}, true}, 663 {"name", "1", ltOperator, "", Result{}, true}, 664 {"name", "", ltOperator, "1", Result{}, true}, 665 666 {"name", "1", ltOperator, "2", Result{Success: true}, false}, 667 {"name", "2", ltOperator, "1", Result{Success: false}, false}, 668 {"name", "1", ltOperator, "1", Result{Success: false}, false}, 669 670 {"name", "1.3", ltOperator, "2.3", Result{Success: true}, false}, 671 {"name", "2.3", ltOperator, "1.3", Result{Success: false}, false}, 672 {"name", "1.3", ltOperator, "1.3", Result{Success: false}, false}, 673 674 {"name", "3.1.4", ltOperator, "3.1.5", Result{Success: true}, false}, 675 {"name", "3.1.5", ltOperator, "3.1.4", Result{Success: false}, false}, 676 {"name", "3.1.4", ltOperator, "3.1.4", Result{Success: false}, false}, 677 678 //---------- 679 680 {"", "", leOperator, "", Result{}, true}, 681 682 {"name", "foo", leOperator, "", Result{}, true}, 683 {"name", "", leOperator, "foo", Result{}, true}, 684 {"name", "1", leOperator, "", Result{}, true}, 685 {"name", "", leOperator, "1", Result{}, true}, 686 687 {"name", "1", leOperator, "2", Result{Success: true}, false}, 688 {"name", "2", leOperator, "1", Result{Success: false}, false}, 689 {"name", "1", leOperator, "1", Result{Success: true}, false}, 690 691 {"name", "1.3", leOperator, "2.3", Result{Success: true}, false}, 692 {"name", "2.3", leOperator, "1.3", Result{Success: false}, false}, 693 {"name", "1.3", leOperator, "1.3", Result{Success: true}, false}, 694 695 {"name", "3.1.4", leOperator, "3.1.5", Result{Success: true}, false}, 696 {"name", "3.1.5", leOperator, "3.1.4", Result{Success: false}, false}, 697 {"name", "3.1.4", leOperator, "3.1.4", Result{Success: true}, false}, 698 699 //---------- 700 701 {"", "", gtOperator, "", Result{}, true}, 702 703 {"name", "foo", gtOperator, "", Result{}, true}, 704 {"name", "", gtOperator, "foo", Result{}, true}, 705 {"name", "1", gtOperator, "", Result{}, true}, 706 {"name", "", gtOperator, "1", Result{}, true}, 707 708 {"name", "1", gtOperator, "2", Result{Success: false}, false}, 709 {"name", "2", gtOperator, "1", Result{Success: true}, false}, 710 {"name", "1", gtOperator, "1", Result{Success: false}, false}, 711 712 {"name", "1.3", gtOperator, "2.3", Result{Success: false}, false}, 713 {"name", "2.3", gtOperator, "1.3", Result{Success: true}, false}, 714 {"name", "1.3", gtOperator, "1.3", Result{Success: false}, false}, 715 716 {"name", "3.1.4", gtOperator, "3.1.5", Result{Success: false}, false}, 717 {"name", "3.1.5", gtOperator, "3.1.4", Result{Success: true}, false}, 718 {"name", "3.1.4", gtOperator, "3.1.4", Result{Success: false}, false}, 719 720 //---------- 721 722 {"", "", geOperator, "", Result{}, true}, 723 724 {"name", "foo", geOperator, "", Result{}, true}, 725 {"name", "", geOperator, "foo", Result{}, true}, 726 {"name", "1", geOperator, "", Result{}, true}, 727 {"name", "", geOperator, "1", Result{}, true}, 728 729 {"name", "1", geOperator, "2", Result{Success: false}, false}, 730 {"name", "2", geOperator, "1", Result{Success: true}, false}, 731 {"name", "1", geOperator, "1", Result{Success: true}, false}, 732 733 {"name", "1.3", geOperator, "2.3", Result{Success: false}, false}, 734 {"name", "2.3", geOperator, "1.3", Result{Success: true}, false}, 735 {"name", "1.3", geOperator, "1.3", Result{Success: true}, false}, 736 737 {"name", "3.1.4", geOperator, "3.1.5", Result{Success: false}, false}, 738 {"name", "3.1.5", geOperator, "3.1.4", Result{Success: true}, false}, 739 {"name", "3.1.4", geOperator, "3.1.4", Result{Success: true}, false}, 740 741 //---------- 742 743 {"", "", neOperator, "", Result{}, true}, 744 745 {"name", "foo", neOperator, "", Result{}, true}, 746 {"name", "", neOperator, "foo", Result{}, true}, 747 {"name", "1", neOperator, "", Result{}, true}, 748 {"name", "", neOperator, "1", Result{}, true}, 749 750 {"name", "1", neOperator, "2", Result{Success: true}, false}, 751 {"name", "2", neOperator, "1", Result{Success: true}, false}, 752 {"name", "1", neOperator, "1", Result{Success: false}, false}, 753 754 {"name", "1.3", neOperator, "2.3", Result{Success: true}, false}, 755 {"name", "2.3", neOperator, "1.3", Result{Success: true}, false}, 756 {"name", "1.3", neOperator, "1.3", Result{Success: false}, false}, 757 758 {"name", "3.1.4", neOperator, "3.1.5", Result{Success: true}, false}, 759 {"name", "3.1.5", neOperator, "3.1.4", Result{Success: true}, false}, 760 {"name", "3.1.4", neOperator, "3.1.4", Result{Success: false}, false}, 761 762 //---------- 763 } 764 765 for i, d := range data { 766 result, err := handleVersionType(d.versionName, d.currentVersion, d.op, d.newVersion) 767 768 msg := fmt.Sprintf("test[%d]: %+v, result: %+v", i, d, result) 769 770 if d.expectError { 771 assert.Error(err, msg) 772 continue 773 } 774 775 assert.Equal(d.result.Success, result.Success, msg) 776 } 777 } 778 779 func TestConstraintHandleKernelVersion(t *testing.T) { 780 assert := assert.New(t) 781 782 ver, err := semver.Make(kernelVersion) 783 assert.NoError(err) 784 785 newerMajor, err := semverBumpVersion(ver, true, false, false) 786 assert.NoError(err) 787 788 newerMinor, err := semverBumpVersion(ver, false, true, false) 789 assert.NoError(err) 790 791 newerPatch, err := semverBumpVersion(ver, false, false, true) 792 assert.NoError(err) 793 794 type testData struct { 795 version string 796 op Operator 797 result Result 798 expectError bool 799 } 800 801 data := []testData{ 802 {"", eqOperator, Result{}, true}, 803 {"", geOperator, Result{}, true}, 804 {"", gtOperator, Result{}, true}, 805 {"", leOperator, Result{}, true}, 806 {"", ltOperator, Result{}, true}, 807 {"", neOperator, Result{}, true}, 808 809 {kernelVersion, eqOperator, Result{Success: true}, false}, 810 {kernelVersion, neOperator, Result{Success: false}, false}, 811 812 {newerMajor, eqOperator, Result{Success: false}, false}, 813 {newerMajor, geOperator, Result{Success: false}, false}, 814 {newerMajor, gtOperator, Result{Success: false}, false}, 815 {newerMajor, ltOperator, Result{Success: true}, false}, 816 {newerMajor, leOperator, Result{Success: true}, false}, 817 {newerMajor, neOperator, Result{Success: true}, false}, 818 819 {newerMinor, eqOperator, Result{Success: false}, false}, 820 {newerMinor, geOperator, Result{Success: false}, false}, 821 {newerMinor, gtOperator, Result{Success: false}, false}, 822 {newerMinor, ltOperator, Result{Success: true}, false}, 823 {newerMinor, leOperator, Result{Success: true}, false}, 824 {newerMinor, neOperator, Result{Success: true}, false}, 825 826 {newerPatch, eqOperator, Result{Success: false}, false}, 827 {newerPatch, geOperator, Result{Success: false}, false}, 828 {newerPatch, gtOperator, Result{Success: false}, false}, 829 {newerPatch, ltOperator, Result{Success: true}, false}, 830 {newerPatch, leOperator, Result{Success: true}, false}, 831 {newerPatch, neOperator, Result{Success: true}, false}, 832 } 833 834 for _, debug := range []bool{true, false} { 835 tc := NewTestConstraint(debug) 836 837 for i, d := range data { 838 result, err := tc.handleKernelVersion(d.version, d.op) 839 840 msg := fmt.Sprintf("test[%d]: %+v, result: %+v", i, d, result) 841 842 if d.expectError { 843 assert.Error(err, msg) 844 continue 845 } 846 847 assert.Equal(d.result.Success, result.Success, msg) 848 } 849 } 850 } 851 852 func TestConstraintHandleUID(t *testing.T) { 853 assert := assert.New(t) 854 855 type testData struct { 856 uid int 857 op Operator 858 result Result 859 expectError bool 860 } 861 862 data := []testData{ 863 {-1, eqOperator, Result{}, true}, 864 {-1, neOperator, Result{}, true}, 865 {-2, eqOperator, Result{}, true}, 866 {-2, neOperator, Result{}, true}, 867 {rootUID, invalidOperator, Result{}, true}, 868 {thisUID, invalidOperator, Result{}, true}, 869 870 {rootUID, eqOperator, Result{Success: root}, false}, 871 {rootUID, neOperator, Result{Success: !root}, false}, 872 873 {thisUID, eqOperator, Result{Success: true}, false}, 874 {thisUID, neOperator, Result{Success: false}, false}, 875 } 876 877 for _, debug := range []bool{true, false} { 878 tc := NewTestConstraint(debug) 879 880 for i, d := range data { 881 result, err := tc.handleUID(d.uid, d.op) 882 883 msg := fmt.Sprintf("test[%d]: %+v, result: %+v", i, d, result) 884 885 if d.expectError { 886 assert.Error(err, msg) 887 continue 888 } 889 890 assert.NoError(err, msg) 891 assert.Equal(result.Success, d.result.Success, msg) 892 assert.NotNil(result.Description, msg) 893 } 894 } 895 } 896 897 func TestConstraintHandleResults(t *testing.T) { 898 assert := assert.New(t) 899 900 type testData struct { 901 result Result 902 err error 903 } 904 905 data := []testData{ 906 {Result{}, errors.New("foo")}, 907 908 {Result{Success: true}, nil}, 909 {Result{Success: false}, nil}, 910 } 911 912 for _, debug := range []bool{true, false} { 913 tc := NewTestConstraint(debug) 914 915 for i, d := range data { 916 tc.Passed = nil 917 tc.Failed = nil 918 919 msg := fmt.Sprintf("test[%d]: %+v", i, d) 920 921 if d.err != nil { 922 assert.Panics(func() { 923 tc.handleResults(d.result, d.err) 924 }, msg) 925 continue 926 } 927 928 tc.handleResults(d.result, d.err) 929 930 passedLen := len(tc.Passed) 931 failedLen := len(tc.Failed) 932 933 var expectedPassedLen int 934 var expectedFailedLen int 935 936 if d.result.Success { 937 expectedPassedLen = 1 938 expectedFailedLen = 0 939 } else { 940 expectedPassedLen = 0 941 expectedFailedLen = 1 942 } 943 944 assert.Equal(passedLen, expectedPassedLen, msg) 945 assert.Equal(failedLen, expectedFailedLen, msg) 946 } 947 } 948 } 949 950 func TestNeedUID(t *testing.T) { 951 assert := assert.New(t) 952 953 data := []testDataUID{ 954 uidEqualsRootData, 955 uidNotEqualsRootData, 956 {thisUID, eqOperator, Constraints{ 957 Operator: eqOperator, 958 UID: thisUID, 959 UIDSet: true}, 960 }, 961 } 962 963 for i, d := range data { 964 c := Constraints{} 965 966 f := NeedUID(d.uid, d.op) 967 f(&c) 968 969 desc := fmt.Sprintf("test[%d]: %+v", i, d) 970 checkUIDConstraints(assert, c, d.c, desc) 971 } 972 } 973 974 func TestNeedRoot(t *testing.T) { 975 assert := assert.New(t) 976 977 c := Constraints{} 978 979 f := NeedRoot() 980 f(&c) 981 982 checkUIDConstraints(assert, c, uidEqualsRootData.c, "TestNeedRoot") 983 } 984 985 func TestNeedNonRoot(t *testing.T) { 986 assert := assert.New(t) 987 988 c := Constraints{} 989 990 f := NeedNonRoot() 991 f(&c) 992 993 checkUIDConstraints(assert, c, uidNotEqualsRootData.c, "TestNeedNonRoot") 994 } 995 996 func TestNeedDistroWithOp(t *testing.T) { 997 assert := assert.New(t) 998 999 if getDistroErr == errUnknownDistroName { 1000 t.Skip(skipUnknownDistroName) 1001 } 1002 1003 data := []testDataDistro{ 1004 distroEqualsCurrentData, 1005 distroNotEqualsCurrentData, 1006 1007 // check name provided is lower-cased 1008 { 1009 strings.ToUpper(distroName), 1010 eqOperator, 1011 Constraints{ 1012 DistroName: distroName, 1013 Operator: eqOperator, 1014 }, 1015 }, 1016 } 1017 1018 for i, d := range data { 1019 1020 c := Constraints{} 1021 1022 f := NeedDistroWithOp(d.distro, d.op) 1023 f(&c) 1024 1025 desc := fmt.Sprintf("test[%d]: %+v, constraints: %+v", i, d, c) 1026 checkDistroConstraints(assert, d.c, c, desc) 1027 } 1028 } 1029 1030 func TestNeedDistroEquals(t *testing.T) { 1031 assert := assert.New(t) 1032 1033 c := Constraints{} 1034 1035 f := NeedDistroEquals(distroName) 1036 f(&c) 1037 1038 checkDistroConstraints(assert, c, distroEqualsCurrentData.c, "TestNeedDistroEquals") 1039 } 1040 1041 func TestNeedDistroNotEquals(t *testing.T) { 1042 assert := assert.New(t) 1043 1044 c := Constraints{} 1045 1046 f := NeedDistroNotEquals(distroName) 1047 f(&c) 1048 1049 checkDistroConstraints(assert, c, distroNotEqualsCurrentData.c, "TestNeedDistroNotEquals") 1050 } 1051 1052 func TestWithIssue(t *testing.T) { 1053 assert := assert.New(t) 1054 1055 c := Constraints{} 1056 1057 issue := "issue" 1058 1059 f := WithIssue(issue) 1060 f(&c) 1061 1062 assert.Equal(c.Issue, issue) 1063 } 1064 1065 func TestNeedKernelVersionWithOp(t *testing.T) { 1066 assert := assert.New(t) 1067 1068 type testData struct { 1069 version string 1070 op Operator 1071 } 1072 1073 version := "version" 1074 1075 data := []testData{ 1076 {version, eqOperator}, 1077 {version, geOperator}, 1078 {version, gtOperator}, 1079 {version, leOperator}, 1080 {version, ltOperator}, 1081 {version, neOperator}, 1082 } 1083 1084 for i, d := range data { 1085 msg := fmt.Sprintf("test[%d]: %+v", i, d) 1086 1087 c := NeedKernelVersionWithOp(d.version, d.op) 1088 1089 checkKernelConstraint(assert, c, d.version, d.op, msg) 1090 } 1091 } 1092 1093 func TestNeedKernelVersion(t *testing.T) { 1094 assert := assert.New(t) 1095 1096 version := "version" 1097 f := NeedKernelVersion(version) 1098 checkKernelConstraint(assert, f, version, eqOperator, "TestNeedKernelVersion") 1099 } 1100 1101 func TestNeedKernelVersionEquals(t *testing.T) { 1102 assert := assert.New(t) 1103 1104 version := "version" 1105 f := NeedKernelVersionEquals(version) 1106 checkKernelConstraint(assert, f, version, eqOperator, "TestNeedKernelVersionEquals") 1107 } 1108 1109 func TestNeedKernelVersionLE(t *testing.T) { 1110 assert := assert.New(t) 1111 1112 version := "version" 1113 f := NeedKernelVersionLE(version) 1114 checkKernelConstraint(assert, f, version, leOperator, "TestNeedKernelVersionLE") 1115 } 1116 1117 func TestNeedKernelVersionLT(t *testing.T) { 1118 assert := assert.New(t) 1119 1120 version := "version" 1121 f := NeedKernelVersionLT(version) 1122 checkKernelConstraint(assert, f, version, ltOperator, "TestNeedKernelVersionLT") 1123 } 1124 1125 func TestNeedKernelVersionGE(t *testing.T) { 1126 assert := assert.New(t) 1127 1128 version := "version" 1129 f := NeedKernelVersionGE(version) 1130 checkKernelConstraint(assert, f, version, geOperator, "TestNeedKernelVersionGE") 1131 } 1132 1133 func TestNeedKernelVersionGT(t *testing.T) { 1134 assert := assert.New(t) 1135 1136 version := "version" 1137 f := NeedKernelVersionGT(version) 1138 checkKernelConstraint(assert, f, version, gtOperator, "TestNeedKernelVersionGT") 1139 } 1140 1141 func TestConstraintNotValid(t *testing.T) { 1142 assert := assert.New(t) 1143 1144 for _, debug := range []bool{true, false} { 1145 tc := NewTestConstraint(debug) 1146 1147 // Ensure no params is an error 1148 assert.Panics(func() { 1149 _ = tc.NotValid() 1150 }) 1151 1152 // Test specification of a single constraint 1153 if root { 1154 result := tc.NotValid(NeedRoot()) 1155 assert.False(result) 1156 1157 result = tc.NotValid(NeedNonRoot()) 1158 assert.True(result) 1159 } else { 1160 result := tc.NotValid(NeedRoot()) 1161 assert.True(result) 1162 1163 result = tc.NotValid(NeedNonRoot()) 1164 assert.False(result) 1165 } 1166 1167 // Now test specification of multiple constraints 1168 if root { 1169 result := tc.NotValid(NeedRoot(), NeedDistro(distroName)) 1170 assert.False(result) 1171 1172 result = tc.NotValid(NeedNonRoot(), NeedDistro(distroName)) 1173 assert.True(result) 1174 } else { 1175 result := tc.NotValid(NeedRoot(), NeedDistro(distroName)) 1176 assert.True(result) 1177 1178 result = tc.NotValid(NeedNonRoot(), NeedDistro(distroName)) 1179 assert.False(result) 1180 } 1181 } 1182 1183 } 1184 1185 func TestConstraintNotValidKernelVersion(t *testing.T) { 1186 assert := assert.New(t) 1187 1188 assert.NotNil(kernelVersion) 1189 1190 // Generate new kernel versions for testing purposes based on the 1191 // current kernel version. 1192 higherVersion, err := incrementVersion(kernelVersion) 1193 assert.NoError(err) 1194 assert.NotEqual(kernelVersion, higherVersion) 1195 1196 lowerVersion, err := decrementVersion(kernelVersion) 1197 assert.NoError(err) 1198 assert.NotEqual(kernelVersion, lowerVersion) 1199 1200 // Antique kernel version numbers. 1201 // 1202 // Note: Not all are actually real kernel releases - we're just trying 1203 // to do a thorough test. 1204 lowKernelVersions := []string{ 1205 "0.0.0", 1206 "0.0.1", 1207 "1.0.0", 1208 "1.0.6-1.1.0", 1209 "2.0.0", 1210 "2.6.0", 1211 lowerVersion, 1212 } 1213 1214 // Host kernel is expected to be newer than all the low kernel versions 1215 for _, debug := range []bool{true, false} { 1216 tc := NewTestConstraint(debug) 1217 1218 for _, ver := range lowKernelVersions { 1219 result := tc.NotValid(NeedKernelVersionEquals(ver)) 1220 assert.True(result) 1221 1222 result = tc.NotValid(NeedKernelVersionLE(ver)) 1223 assert.True(result) 1224 1225 result = tc.NotValid(NeedKernelVersionLT(ver)) 1226 assert.True(result) 1227 1228 result = tc.NotValid(NeedKernelVersionGT(ver)) 1229 assert.False(result) 1230 1231 result = tc.NotValid(NeedKernelVersionGE(ver)) 1232 assert.False(result) 1233 1234 result = tc.NotValid(NeedKernelVersionNotEquals(ver)) 1235 assert.False(result) 1236 } 1237 } 1238 1239 // Ridiculously high kernel version numbers. The host kernel is 1240 // expected to never reach these values. 1241 highKernelVersions := []string{ 1242 higherVersion, 1243 "999.0.0", 1244 "999.0.999", 1245 "999.999.999", 1246 "1024.0.0", 1247 } 1248 1249 for _, debug := range []bool{true, false} { 1250 tc := NewTestConstraint(debug) 1251 1252 for _, ver := range highKernelVersions { 1253 result := tc.NotValid(NeedKernelVersionEquals(ver)) 1254 assert.True(result) 1255 1256 result = tc.NotValid(NeedKernelVersionGE(ver)) 1257 assert.True(result) 1258 1259 result = tc.NotValid(NeedKernelVersionGT(ver)) 1260 assert.True(result) 1261 1262 result = tc.NotValid(NeedKernelVersionLE(ver)) 1263 assert.False(result) 1264 1265 result = tc.NotValid(NeedKernelVersionLT(ver)) 1266 assert.False(result) 1267 1268 result = tc.NotValid(NeedKernelVersionNotEquals(ver)) 1269 assert.False(result) 1270 } 1271 } 1272 } 1273 1274 func TestConstraintNotValidDistroVersion(t *testing.T) { 1275 assert := assert.New(t) 1276 1277 assert.NotNil(distroVersion) 1278 1279 // Generate new distro versions for testing purposes based on the 1280 // current kernel version. 1281 higherVersion, err := incrementVersion(distroVersion) 1282 assert.NoError(err) 1283 assert.NotEqual(distroVersion, higherVersion) 1284 1285 lowerVersion, err := decrementVersion(distroVersion) 1286 assert.NoError(err) 1287 assert.NotEqual(distroVersion, lowerVersion) 1288 1289 for _, debug := range []bool{true, false} { 1290 tc := NewTestConstraint(debug) 1291 1292 result := tc.NotValid(NeedDistroVersionEquals(higherVersion)) 1293 assert.True(result) 1294 1295 result = tc.NotValid(NeedDistroVersionEquals(distroVersion)) 1296 assert.False(result) 1297 1298 result = tc.NotValid(NeedDistroVersionLE(higherVersion)) 1299 assert.False(result) 1300 1301 result = tc.NotValid(NeedDistroVersionLE(distroVersion)) 1302 assert.False(result) 1303 1304 result = tc.NotValid(NeedDistroVersionLT(higherVersion)) 1305 assert.False(result) 1306 1307 result = tc.NotValid(NeedDistroVersionLT(distroVersion)) 1308 assert.True(result) 1309 1310 result = tc.NotValid(NeedDistroVersionGE(higherVersion)) 1311 assert.True(result) 1312 1313 result = tc.NotValid(NeedDistroVersionGE(distroVersion)) 1314 assert.False(result) 1315 1316 result = tc.NotValid(NeedDistroVersionGT(higherVersion)) 1317 assert.True(result) 1318 1319 result = tc.NotValid(NeedDistroVersionGT(distroVersion)) 1320 assert.True(result) 1321 1322 result = tc.NotValid(NeedDistroVersionNotEquals(higherVersion)) 1323 assert.False(result) 1324 1325 result = tc.NotValid(NeedDistroVersionNotEquals(distroVersion)) 1326 assert.True(result) 1327 } 1328 } 1329 1330 func TestConstraintConstraintValid(t *testing.T) { 1331 assert := assert.New(t) 1332 1333 type testData struct { 1334 fn Constraint 1335 valid bool 1336 expected TestConstraint 1337 } 1338 1339 issue := "issue" 1340 1341 data := []testData{ 1342 { 1343 WithIssue(issue), 1344 true, 1345 TestConstraint{Issue: issue}, 1346 }, 1347 1348 { 1349 NeedDistroWithOp(distroName, eqOperator), 1350 true, 1351 TestConstraint{ 1352 Passed: []Result{ 1353 {Success: true}, 1354 }, 1355 }, 1356 }, 1357 { 1358 NeedDistroWithOp(distroName, neOperator), 1359 false, 1360 TestConstraint{ 1361 Failed: []Result{ 1362 {Success: false}, 1363 }, 1364 }, 1365 }, 1366 { 1367 NeedDistroWithOp(getAnotherDistro(distroName), eqOperator), 1368 false, 1369 TestConstraint{ 1370 Failed: []Result{ 1371 {Success: false}, 1372 }, 1373 }, 1374 }, 1375 { 1376 NeedDistroWithOp(getAnotherDistro(distroName), neOperator), 1377 true, 1378 TestConstraint{ 1379 Failed: []Result{ 1380 {Success: true}, 1381 }, 1382 }, 1383 }, 1384 1385 { 1386 NeedDistroEquals(distroName), 1387 true, 1388 TestConstraint{ 1389 Passed: []Result{ 1390 {Success: true}, 1391 }, 1392 }, 1393 }, 1394 { 1395 NeedDistroEquals(getAnotherDistro(distroName)), 1396 false, 1397 TestConstraint{ 1398 Failed: []Result{ 1399 {Success: false}, 1400 }, 1401 }, 1402 }, 1403 1404 { 1405 NeedDistroNotEquals(getAnotherDistro(distroName)), 1406 true, 1407 TestConstraint{ 1408 Passed: []Result{ 1409 {Success: true}, 1410 }, 1411 }, 1412 }, 1413 { 1414 NeedDistroNotEquals(distroName), 1415 false, 1416 TestConstraint{ 1417 Failed: []Result{ 1418 {Success: false}, 1419 }, 1420 }, 1421 }, 1422 1423 { 1424 NeedDistro(distroName), 1425 true, 1426 TestConstraint{ 1427 Passed: []Result{ 1428 {Success: true}, 1429 }, 1430 }, 1431 }, 1432 { 1433 NeedDistro(getAnotherDistro(distroName)), 1434 false, 1435 TestConstraint{ 1436 Failed: []Result{ 1437 {Success: false}, 1438 }, 1439 }, 1440 }, 1441 } 1442 1443 if root { 1444 td := testData{ 1445 fn: NeedRoot(), 1446 valid: true, 1447 expected: TestConstraint{ 1448 Passed: []Result{ 1449 {Success: true}, 1450 }, 1451 }, 1452 } 1453 1454 data = append(data, td) 1455 1456 td = testData{ 1457 fn: NeedNonRoot(), 1458 valid: false, 1459 expected: TestConstraint{ 1460 Failed: []Result{ 1461 {Success: false}, 1462 }, 1463 }, 1464 } 1465 1466 data = append(data, td) 1467 } else { 1468 td := testData{ 1469 fn: NeedRoot(), 1470 valid: false, 1471 expected: TestConstraint{ 1472 Failed: []Result{ 1473 {Success: false}, 1474 }, 1475 }, 1476 } 1477 1478 data = append(data, td) 1479 1480 td = testData{ 1481 fn: NeedNonRoot(), 1482 valid: true, 1483 expected: TestConstraint{ 1484 Passed: []Result{ 1485 {Success: true}, 1486 }, 1487 }, 1488 } 1489 1490 data = append(data, td) 1491 } 1492 1493 for _, debug := range []bool{true, false} { 1494 for i, d := range data { 1495 tc := NewTestConstraint(debug) 1496 1497 result := tc.constraintValid(d.fn) 1498 1499 msg := fmt.Sprintf("test[%d]: %+v, result: %v", i, d, result) 1500 1501 if d.expected.Issue != "" { 1502 assert.Equal(tc.Issue, d.expected.Issue, msg) 1503 } 1504 1505 if d.valid { 1506 assert.True(result, msg) 1507 1508 if len(d.expected.Passed) != 0 { 1509 assert.Equal(d.expected.Passed[0].Success, tc.Passed[0].Success, msg) 1510 } 1511 } else { 1512 assert.False(result, msg) 1513 1514 if len(d.expected.Failed) != 0 { 1515 assert.Equal(d.expected.Failed[0].Success, tc.Failed[0].Success, msg) 1516 } 1517 } 1518 } 1519 } 1520 } 1521 1522 func TestEvalIntVersion(t *testing.T) { 1523 assert := assert.New(t) 1524 1525 type testData struct { 1526 currentVer string 1527 op Operator 1528 newVer string 1529 expectSuccess bool 1530 expectError bool 1531 } 1532 1533 data := []testData{ 1534 //---------- 1535 1536 {"", eqOperator, "", false, true}, 1537 {"", eqOperator, "1", false, true}, 1538 {"1", eqOperator, "", false, true}, 1539 1540 {"foo", eqOperator, "", false, true}, 1541 {"", eqOperator, "foo", false, true}, 1542 {"foo", eqOperator, "1", false, true}, 1543 {"1", eqOperator, "foo", false, true}, 1544 1545 {"1", eqOperator, "1", true, false}, 1546 {"1", eqOperator, "2", false, false}, 1547 1548 //---------- 1549 1550 {"", geOperator, "", false, true}, 1551 {"foo", geOperator, "", false, true}, 1552 {"", geOperator, "foo", false, true}, 1553 {"1", geOperator, "", false, true}, 1554 {"", geOperator, "1", false, true}, 1555 1556 {"1", geOperator, "2", false, false}, 1557 {"2", geOperator, "1", true, false}, 1558 {"2", geOperator, "2", true, false}, 1559 1560 //---------- 1561 1562 {"", gtOperator, "", false, true}, 1563 {"foo", gtOperator, "", false, true}, 1564 {"", gtOperator, "foo", false, true}, 1565 {"1", gtOperator, "", false, true}, 1566 {"", gtOperator, "1", false, true}, 1567 1568 {"2", gtOperator, "1", true, false}, 1569 {"1", gtOperator, "2", false, false}, 1570 {"1", gtOperator, "1", false, false}, 1571 1572 //---------- 1573 1574 {"", leOperator, "", false, true}, 1575 {"foo", leOperator, "", false, true}, 1576 {"", leOperator, "foo", false, true}, 1577 {"1", leOperator, "", false, true}, 1578 {"", leOperator, "1", false, true}, 1579 1580 {"2", leOperator, "1", false, false}, 1581 {"1", leOperator, "2", true, false}, 1582 {"1", leOperator, "1", true, false}, 1583 1584 //---------- 1585 1586 {"", ltOperator, "", false, true}, 1587 {"foo", ltOperator, "", false, true}, 1588 {"", ltOperator, "foo", false, true}, 1589 {"1", ltOperator, "", false, true}, 1590 {"", ltOperator, "1", false, true}, 1591 1592 {"1", ltOperator, "2", true, false}, 1593 {"2", ltOperator, "1", false, false}, 1594 {"1", ltOperator, "1", false, false}, 1595 1596 //---------- 1597 1598 {"", neOperator, "", false, true}, 1599 {"foo", neOperator, "", false, true}, 1600 {"", neOperator, "foo", false, true}, 1601 {"1", neOperator, "", false, true}, 1602 {"", neOperator, "1", false, true}, 1603 1604 {"2", neOperator, "2", false, false}, 1605 {"1", neOperator, "2", true, false}, 1606 {"2", neOperator, "1", true, false}, 1607 } 1608 1609 for i, d := range data { 1610 success, err := evalIntVersion(d.currentVer, d.op, d.newVer) 1611 1612 msg := fmt.Sprintf("test[%d]: %+v, success: %v", i, d, success) 1613 1614 if d.expectError { 1615 assert.Error(err, msg) 1616 continue 1617 } 1618 1619 if d.expectSuccess { 1620 assert.True(success, msg) 1621 } else { 1622 assert.False(success, msg) 1623 } 1624 } 1625 } 1626 1627 func TestEvalFloatVersion(t *testing.T) { 1628 assert := assert.New(t) 1629 1630 type testData struct { 1631 currentVer string 1632 op Operator 1633 newVer string 1634 expectSuccess bool 1635 expectError bool 1636 } 1637 1638 data := []testData{ 1639 //---------- 1640 1641 {"", eqOperator, "", false, true}, 1642 {"foo", eqOperator, "", false, true}, 1643 {"", eqOperator, "foo", false, true}, 1644 {"foo", eqOperator, "1", false, true}, 1645 {"1", eqOperator, "foo", false, true}, 1646 1647 {"1", eqOperator, "1", true, false}, 1648 {"1", eqOperator, "2", false, false}, 1649 1650 {"1.1", eqOperator, "1.1", true, false}, 1651 {"1.1", eqOperator, "2.1", false, false}, 1652 1653 //---------- 1654 1655 {"", geOperator, "", false, true}, 1656 {"foo", geOperator, "", false, true}, 1657 {"", geOperator, "foo", false, true}, 1658 1659 {"1", geOperator, "2", false, false}, 1660 {"2", geOperator, "1", true, false}, 1661 {"2", geOperator, "2", true, false}, 1662 1663 {"1.1", geOperator, "2.1", false, false}, 1664 {"2.1", geOperator, "1.1", true, false}, 1665 {"2.1", geOperator, "2.1", true, false}, 1666 1667 //---------- 1668 1669 {"", gtOperator, "", false, true}, 1670 {"foo", gtOperator, "", false, true}, 1671 {"", gtOperator, "foo", false, true}, 1672 1673 {"2", gtOperator, "1", true, false}, 1674 {"1", gtOperator, "2", false, false}, 1675 {"1", gtOperator, "1", false, false}, 1676 1677 {"2.1", gtOperator, "1.1", true, false}, 1678 {"1.1", gtOperator, "2.1", false, false}, 1679 {"1.1", gtOperator, "1.1", false, false}, 1680 1681 //---------- 1682 1683 {"", leOperator, "", false, true}, 1684 {"foo", leOperator, "", false, true}, 1685 {"", leOperator, "foo", false, true}, 1686 1687 {"2", leOperator, "1", false, false}, 1688 {"1", leOperator, "2", true, false}, 1689 {"1", leOperator, "1", true, false}, 1690 1691 {"2.1", leOperator, "1.1", false, false}, 1692 {"1.1", leOperator, "2.1", true, false}, 1693 {"1.1", leOperator, "1.1", true, false}, 1694 1695 //---------- 1696 1697 {"", ltOperator, "", false, true}, 1698 {"foo", ltOperator, "", false, true}, 1699 {"", ltOperator, "foo", false, true}, 1700 1701 {"1", ltOperator, "2", true, false}, 1702 {"2", ltOperator, "1", false, false}, 1703 {"1", ltOperator, "1", false, false}, 1704 1705 {"1.1", ltOperator, "2.1", true, false}, 1706 {"2.1", ltOperator, "1.1", false, false}, 1707 {"1.1", ltOperator, "1.1", false, false}, 1708 1709 //---------- 1710 1711 {"", neOperator, "", false, true}, 1712 {"foo", neOperator, "", false, true}, 1713 {"", neOperator, "foo", false, true}, 1714 1715 {"2", neOperator, "2", false, false}, 1716 {"1", neOperator, "2", true, false}, 1717 {"2", neOperator, "1", true, false}, 1718 1719 {"2.1", neOperator, "2.1", false, false}, 1720 {"1.1", neOperator, "2.1", true, false}, 1721 {"2.1", neOperator, "1.1", true, false}, 1722 } 1723 1724 for i, d := range data { 1725 success, err := evalFloatVersion(d.currentVer, d.op, d.newVer) 1726 1727 msg := fmt.Sprintf("test[%d]: %+v, success: %v", i, d, success) 1728 1729 if d.expectError { 1730 assert.Error(err, msg) 1731 continue 1732 } 1733 1734 if d.expectSuccess { 1735 assert.True(success, msg) 1736 } else { 1737 assert.False(success, msg) 1738 } 1739 } 1740 } 1741 1742 func TestEvalSemverVersion(t *testing.T) { 1743 assert := assert.New(t) 1744 1745 type testData struct { 1746 currentVer string 1747 op Operator 1748 newVer string 1749 expectSuccess bool 1750 expectError bool 1751 } 1752 1753 data := []testData{ 1754 //---------- 1755 1756 {"", eqOperator, "", false, true}, 1757 {"foo", eqOperator, "", false, true}, 1758 {"", eqOperator, "foo", false, true}, 1759 {"foo", eqOperator, "1", false, true}, 1760 {"1", eqOperator, "foo", false, true}, 1761 1762 {"1.1.1", eqOperator, "1.1.1", true, false}, 1763 {"1.1.1", eqOperator, "2.2.2", false, false}, 1764 1765 //---------- 1766 1767 {"", geOperator, "", false, true}, 1768 {"foo", geOperator, "", false, true}, 1769 {"", geOperator, "foo", false, true}, 1770 1771 {"1.1.1", geOperator, "2.2.2", false, false}, 1772 {"2.2.2", geOperator, "1.1.1", true, false}, 1773 {"2.2.2", geOperator, "2.2.2", true, false}, 1774 1775 //---------- 1776 1777 {"", gtOperator, "", false, true}, 1778 {"foo", gtOperator, "", false, true}, 1779 {"", gtOperator, "foo", false, true}, 1780 1781 {"2.2.2", gtOperator, "1.1.1", true, false}, 1782 {"1.1.1", gtOperator, "2.2.2", false, false}, 1783 {"1.1.1", gtOperator, "1.1.1", false, false}, 1784 1785 //---------- 1786 1787 {"", leOperator, "", false, true}, 1788 {"foo", leOperator, "", false, true}, 1789 {"", leOperator, "foo", false, true}, 1790 1791 {"2.2.2", leOperator, "1.1.1", false, false}, 1792 {"1.1.1", leOperator, "2.2.2", true, false}, 1793 {"1.1.1", leOperator, "1.1.1", true, false}, 1794 1795 //---------- 1796 1797 {"", ltOperator, "", false, true}, 1798 {"foo", ltOperator, "", false, true}, 1799 {"", ltOperator, "foo", false, true}, 1800 1801 {"1.1.1", ltOperator, "2.2.2", true, false}, 1802 {"2.2.2", ltOperator, "1.1.1", false, false}, 1803 {"1.1.1", ltOperator, "1.1.1", false, false}, 1804 1805 //---------- 1806 1807 {"", neOperator, "", false, true}, 1808 {"foo", neOperator, "", false, true}, 1809 {"", neOperator, "foo", false, true}, 1810 1811 {"2.2.2", neOperator, "2.2.2", false, false}, 1812 {"1.1.1", neOperator, "2.2.2", true, false}, 1813 {"2.2.2", neOperator, "1.1.1", true, false}, 1814 } 1815 1816 for i, d := range data { 1817 success, err := evalSemverVersion(d.currentVer, d.op, d.newVer) 1818 1819 msg := fmt.Sprintf("test[%d]: %+v, success: %v", i, d, success) 1820 1821 if d.expectError { 1822 assert.Error(err, msg) 1823 continue 1824 } 1825 1826 if d.expectSuccess { 1827 assert.True(success, msg) 1828 } else { 1829 assert.False(success, msg) 1830 } 1831 } 1832 }