github.com/ferranbt/nomad@v0.9.3-0.20190607002617-85c449b7667c/plugins/shared/structs/attribute_test.go (about) 1 package structs 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/hashicorp/nomad/helper" 8 "github.com/stretchr/testify/require" 9 ) 10 11 func TestAttribute_Validate(t *testing.T) { 12 cases := []struct { 13 Input *Attribute 14 Fail bool 15 }{ 16 { 17 Input: &Attribute{ 18 Bool: helper.BoolToPtr(true), 19 }, 20 }, 21 { 22 Input: &Attribute{ 23 String: helper.StringToPtr("foo"), 24 }, 25 }, 26 { 27 Input: &Attribute{ 28 Int: helper.Int64ToPtr(123), 29 }, 30 }, 31 { 32 Input: &Attribute{ 33 Float: helper.Float64ToPtr(123.2), 34 }, 35 }, 36 { 37 Input: &Attribute{ 38 Bool: helper.BoolToPtr(true), 39 Unit: "MB", 40 }, 41 Fail: true, 42 }, 43 { 44 Input: &Attribute{ 45 String: helper.StringToPtr("foo"), 46 Unit: "MB", 47 }, 48 Fail: true, 49 }, 50 { 51 Input: &Attribute{ 52 Int: helper.Int64ToPtr(123), 53 Unit: "lolNO", 54 }, 55 Fail: true, 56 }, 57 { 58 Input: &Attribute{ 59 Float: helper.Float64ToPtr(123.2), 60 Unit: "lolNO", 61 }, 62 Fail: true, 63 }, 64 { 65 Input: &Attribute{ 66 Int: helper.Int64ToPtr(123), 67 Float: helper.Float64ToPtr(123.2), 68 Unit: "mW", 69 }, 70 Fail: true, 71 }, 72 } 73 74 for _, c := range cases { 75 t.Run(c.Input.GoString(), func(t *testing.T) { 76 if err := c.Input.Validate(); err != nil && !c.Fail { 77 require.NoError(t, err) 78 } 79 }) 80 } 81 } 82 83 type compareTestCase struct { 84 A *Attribute 85 B *Attribute 86 Expected int 87 NotComparable bool 88 } 89 90 func TestAttribute_Compare_Bool(t *testing.T) { 91 cases := []*compareTestCase{ 92 { 93 A: &Attribute{ 94 Bool: helper.BoolToPtr(true), 95 }, 96 B: &Attribute{ 97 Bool: helper.BoolToPtr(true), 98 }, 99 Expected: 0, 100 }, 101 { 102 A: &Attribute{ 103 Bool: helper.BoolToPtr(true), 104 }, 105 B: &Attribute{ 106 Bool: helper.BoolToPtr(false), 107 }, 108 Expected: 1, 109 }, 110 { 111 A: &Attribute{ 112 Bool: helper.BoolToPtr(true), 113 }, 114 B: &Attribute{ 115 String: helper.StringToPtr("foo"), 116 }, 117 NotComparable: true, 118 }, 119 { 120 A: &Attribute{ 121 Bool: helper.BoolToPtr(true), 122 }, 123 B: &Attribute{ 124 Int: helper.Int64ToPtr(123), 125 }, 126 NotComparable: true, 127 }, 128 { 129 A: &Attribute{ 130 Bool: helper.BoolToPtr(true), 131 }, 132 B: &Attribute{ 133 Float: helper.Float64ToPtr(123.2), 134 }, 135 NotComparable: true, 136 }, 137 } 138 testComparison(t, cases) 139 } 140 141 func TestAttribute_Compare_String(t *testing.T) { 142 cases := []*compareTestCase{ 143 { 144 A: &Attribute{ 145 String: helper.StringToPtr("a"), 146 }, 147 B: &Attribute{ 148 String: helper.StringToPtr("b"), 149 }, 150 Expected: -1, 151 }, 152 { 153 A: &Attribute{ 154 String: helper.StringToPtr("hello"), 155 }, 156 B: &Attribute{ 157 String: helper.StringToPtr("hello"), 158 }, 159 Expected: 0, 160 }, 161 { 162 A: &Attribute{ 163 String: helper.StringToPtr("b"), 164 }, 165 B: &Attribute{ 166 String: helper.StringToPtr("a"), 167 }, 168 Expected: 1, 169 }, 170 { 171 A: &Attribute{ 172 String: helper.StringToPtr("hello"), 173 }, 174 B: &Attribute{ 175 Bool: helper.BoolToPtr(true), 176 }, 177 NotComparable: true, 178 }, 179 { 180 A: &Attribute{ 181 String: helper.StringToPtr("hello"), 182 }, 183 B: &Attribute{ 184 Int: helper.Int64ToPtr(123), 185 }, 186 NotComparable: true, 187 }, 188 { 189 A: &Attribute{ 190 String: helper.StringToPtr("hello"), 191 }, 192 B: &Attribute{ 193 Float: helper.Float64ToPtr(123.2), 194 }, 195 NotComparable: true, 196 }, 197 } 198 testComparison(t, cases) 199 } 200 201 func TestAttribute_Compare_Float(t *testing.T) { 202 cases := []*compareTestCase{ 203 { 204 A: &Attribute{ 205 Float: helper.Float64ToPtr(101.5), 206 }, 207 B: &Attribute{ 208 Float: helper.Float64ToPtr(100001.5), 209 }, 210 Expected: -1, 211 }, 212 { 213 A: &Attribute{ 214 Float: helper.Float64ToPtr(100001.5), 215 }, 216 B: &Attribute{ 217 Float: helper.Float64ToPtr(100001.5), 218 }, 219 Expected: 0, 220 }, 221 { 222 A: &Attribute{ 223 Float: helper.Float64ToPtr(999999999.5), 224 }, 225 B: &Attribute{ 226 Float: helper.Float64ToPtr(101.5), 227 }, 228 Expected: 1, 229 }, 230 { 231 A: &Attribute{ 232 Float: helper.Float64ToPtr(101.5), 233 }, 234 B: &Attribute{ 235 Bool: helper.BoolToPtr(true), 236 }, 237 NotComparable: true, 238 }, 239 { 240 A: &Attribute{ 241 Float: helper.Float64ToPtr(101.5), 242 }, 243 B: &Attribute{ 244 String: helper.StringToPtr("hello"), 245 }, 246 NotComparable: true, 247 }, 248 } 249 testComparison(t, cases) 250 } 251 252 func TestAttribute_Compare_Int(t *testing.T) { 253 cases := []*compareTestCase{ 254 { 255 A: &Attribute{ 256 Int: helper.Int64ToPtr(3), 257 }, 258 B: &Attribute{ 259 Int: helper.Int64ToPtr(10), 260 }, 261 Expected: -1, 262 }, 263 { 264 A: &Attribute{ 265 Int: helper.Int64ToPtr(10), 266 }, 267 B: &Attribute{ 268 Int: helper.Int64ToPtr(10), 269 }, 270 Expected: 0, 271 }, 272 { 273 A: &Attribute{ 274 Int: helper.Int64ToPtr(100), 275 }, 276 B: &Attribute{ 277 Int: helper.Int64ToPtr(10), 278 }, 279 Expected: 1, 280 }, 281 { 282 A: &Attribute{ 283 Int: helper.Int64ToPtr(10), 284 }, 285 B: &Attribute{ 286 Bool: helper.BoolToPtr(true), 287 }, 288 NotComparable: true, 289 }, 290 { 291 A: &Attribute{ 292 Int: helper.Int64ToPtr(10), 293 }, 294 B: &Attribute{ 295 String: helper.StringToPtr("hello"), 296 }, 297 NotComparable: true, 298 }, 299 } 300 testComparison(t, cases) 301 } 302 303 func TestAttribute_Compare_Int_With_Units(t *testing.T) { 304 cases := []*compareTestCase{ 305 { 306 A: &Attribute{ 307 Int: helper.Int64ToPtr(3), 308 Unit: "MB", 309 }, 310 B: &Attribute{ 311 Int: helper.Int64ToPtr(10), 312 Unit: "MB", 313 }, 314 Expected: -1, 315 }, 316 { 317 A: &Attribute{ 318 Int: helper.Int64ToPtr(10), 319 Unit: "MB", 320 }, 321 B: &Attribute{ 322 Int: helper.Int64ToPtr(10), 323 Unit: "MB", 324 }, 325 Expected: 0, 326 }, 327 { 328 A: &Attribute{ 329 Int: helper.Int64ToPtr(100), 330 Unit: "MB", 331 }, 332 B: &Attribute{ 333 Int: helper.Int64ToPtr(10), 334 Unit: "MB", 335 }, 336 Expected: 1, 337 }, 338 { 339 A: &Attribute{ 340 Int: helper.Int64ToPtr(3), 341 Unit: "GB", 342 }, 343 B: &Attribute{ 344 Int: helper.Int64ToPtr(3), 345 Unit: "MB", 346 }, 347 Expected: 1, 348 }, 349 { 350 A: &Attribute{ 351 Int: helper.Int64ToPtr(1), 352 Unit: "GiB", 353 }, 354 B: &Attribute{ 355 Int: helper.Int64ToPtr(1024), 356 Unit: "MiB", 357 }, 358 Expected: 0, 359 }, 360 { 361 A: &Attribute{ 362 Int: helper.Int64ToPtr(1), 363 Unit: "GiB", 364 }, 365 B: &Attribute{ 366 Int: helper.Int64ToPtr(1025), 367 Unit: "MiB", 368 }, 369 Expected: -1, 370 }, 371 { 372 A: &Attribute{ 373 Int: helper.Int64ToPtr(1000), 374 Unit: "mW", 375 }, 376 B: &Attribute{ 377 Int: helper.Int64ToPtr(1), 378 Unit: "W", 379 }, 380 Expected: 0, 381 }, 382 } 383 testComparison(t, cases) 384 } 385 386 func TestAttribute_Compare_Float_With_Units(t *testing.T) { 387 cases := []*compareTestCase{ 388 { 389 A: &Attribute{ 390 Float: helper.Float64ToPtr(3.0), 391 Unit: "MB", 392 }, 393 B: &Attribute{ 394 Float: helper.Float64ToPtr(10.0), 395 Unit: "MB", 396 }, 397 Expected: -1, 398 }, 399 { 400 A: &Attribute{ 401 Float: helper.Float64ToPtr(10.0), 402 Unit: "MB", 403 }, 404 B: &Attribute{ 405 Float: helper.Float64ToPtr(10.0), 406 Unit: "MB", 407 }, 408 Expected: 0, 409 }, 410 { 411 A: &Attribute{ 412 Float: helper.Float64ToPtr(100.0), 413 Unit: "MB", 414 }, 415 B: &Attribute{ 416 Float: helper.Float64ToPtr(10.0), 417 Unit: "MB", 418 }, 419 Expected: 1, 420 }, 421 { 422 A: &Attribute{ 423 Float: helper.Float64ToPtr(3.0), 424 Unit: "GB", 425 }, 426 B: &Attribute{ 427 Float: helper.Float64ToPtr(3.0), 428 Unit: "MB", 429 }, 430 Expected: 1, 431 }, 432 { 433 A: &Attribute{ 434 Float: helper.Float64ToPtr(1.0), 435 Unit: "GiB", 436 }, 437 B: &Attribute{ 438 Float: helper.Float64ToPtr(1024.0), 439 Unit: "MiB", 440 }, 441 Expected: 0, 442 }, 443 { 444 A: &Attribute{ 445 Float: helper.Float64ToPtr(1.0), 446 Unit: "GiB", 447 }, 448 B: &Attribute{ 449 Float: helper.Float64ToPtr(1025.0), 450 Unit: "MiB", 451 }, 452 Expected: -1, 453 }, 454 { 455 A: &Attribute{ 456 Float: helper.Float64ToPtr(1000.0), 457 Unit: "mW", 458 }, 459 B: &Attribute{ 460 Float: helper.Float64ToPtr(1.0), 461 Unit: "W", 462 }, 463 Expected: 0, 464 }, 465 { 466 A: &Attribute{ 467 Float: helper.Float64ToPtr(1.5), 468 Unit: "GiB", 469 }, 470 B: &Attribute{ 471 Float: helper.Float64ToPtr(1400.0), 472 Unit: "MiB", 473 }, 474 Expected: 1, 475 }, 476 } 477 testComparison(t, cases) 478 } 479 480 func TestAttribute_Compare_IntToFloat(t *testing.T) { 481 cases := []*compareTestCase{ 482 { 483 A: &Attribute{ 484 Int: helper.Int64ToPtr(3), 485 }, 486 B: &Attribute{ 487 Float: helper.Float64ToPtr(10.0), 488 }, 489 Expected: -1, 490 }, 491 { 492 A: &Attribute{ 493 Int: helper.Int64ToPtr(10), 494 }, 495 B: &Attribute{ 496 Float: helper.Float64ToPtr(10.0), 497 }, 498 Expected: 0, 499 }, 500 { 501 A: &Attribute{ 502 Int: helper.Int64ToPtr(10), 503 }, 504 B: &Attribute{ 505 Float: helper.Float64ToPtr(10.1), 506 }, 507 Expected: -1, 508 }, 509 { 510 A: &Attribute{ 511 Int: helper.Int64ToPtr(100), 512 }, 513 B: &Attribute{ 514 Float: helper.Float64ToPtr(10.0), 515 }, 516 Expected: 1, 517 }, 518 { 519 A: &Attribute{ 520 Int: helper.Int64ToPtr(100), 521 }, 522 B: &Attribute{ 523 Float: helper.Float64ToPtr(100.00001), 524 }, 525 Expected: -1, 526 }, 527 } 528 testComparison(t, cases) 529 } 530 531 func testComparison(t *testing.T, cases []*compareTestCase) { 532 for _, c := range cases { 533 t.Run(fmt.Sprintf("%#v vs %#v", c.A, c.B), func(t *testing.T) { 534 v, ok := c.A.Compare(c.B) 535 if !ok && !c.NotComparable { 536 t.Fatal("should be comparable") 537 } else if ok { 538 require.Equal(t, c.Expected, v) 539 } 540 }) 541 } 542 } 543 544 func TestAttribute_ParseAndValidate(t *testing.T) { 545 cases := []struct { 546 Input string 547 Expected *Attribute 548 }{ 549 { 550 Input: "true", 551 Expected: &Attribute{ 552 Bool: helper.BoolToPtr(true), 553 }, 554 }, 555 { 556 Input: "false", 557 Expected: &Attribute{ 558 Bool: helper.BoolToPtr(false), 559 }, 560 }, 561 { 562 Input: "1", 563 Expected: &Attribute{ 564 Int: helper.Int64ToPtr(1), 565 }, 566 }, 567 { 568 Input: "100", 569 Expected: &Attribute{ 570 Int: helper.Int64ToPtr(100), 571 }, 572 }, 573 { 574 Input: "-100", 575 Expected: &Attribute{ 576 Int: helper.Int64ToPtr(-100), 577 }, 578 }, 579 { 580 Input: "-1.0", 581 Expected: &Attribute{ 582 Float: helper.Float64ToPtr(-1.0), 583 }, 584 }, 585 { 586 Input: "-100.25", 587 Expected: &Attribute{ 588 Float: helper.Float64ToPtr(-100.25), 589 }, 590 }, 591 { 592 Input: "1.01", 593 Expected: &Attribute{ 594 Float: helper.Float64ToPtr(1.01), 595 }, 596 }, 597 { 598 Input: "100.25", 599 Expected: &Attribute{ 600 Float: helper.Float64ToPtr(100.25), 601 }, 602 }, 603 { 604 Input: "foobar", 605 Expected: &Attribute{ 606 String: helper.StringToPtr("foobar"), 607 }, 608 }, 609 { 610 Input: "foo123bar", 611 Expected: &Attribute{ 612 String: helper.StringToPtr("foo123bar"), 613 }, 614 }, 615 { 616 Input: "100MB", 617 Expected: &Attribute{ 618 Int: helper.Int64ToPtr(100), 619 Unit: "MB", 620 }, 621 }, 622 { 623 Input: "-100MHz", 624 Expected: &Attribute{ 625 Int: helper.Int64ToPtr(-100), 626 Unit: "MHz", 627 }, 628 }, 629 { 630 Input: "-1.0MB/s", 631 Expected: &Attribute{ 632 Float: helper.Float64ToPtr(-1.0), 633 Unit: "MB/s", 634 }, 635 }, 636 { 637 Input: "-100.25GiB/s", 638 Expected: &Attribute{ 639 Float: helper.Float64ToPtr(-100.25), 640 Unit: "GiB/s", 641 }, 642 }, 643 { 644 Input: "1.01TB", 645 Expected: &Attribute{ 646 Float: helper.Float64ToPtr(1.01), 647 Unit: "TB", 648 }, 649 }, 650 { 651 Input: "100.25mW", 652 Expected: &Attribute{ 653 Float: helper.Float64ToPtr(100.25), 654 Unit: "mW", 655 }, 656 }, 657 } 658 659 for _, c := range cases { 660 t.Run(c.Input, func(t *testing.T) { 661 a := ParseAttribute(c.Input) 662 require.Equal(t, c.Expected, a) 663 require.NoError(t, a.Validate()) 664 }) 665 } 666 } 667 668 func BenchmarkParse(b *testing.B) { 669 cases := []string{ 670 "true", 671 "false", 672 "100", 673 "-100", 674 "-1.0", 675 "-100.25", 676 "1.01", 677 "100.25", 678 "foobar", 679 "foo123bar", 680 "100MB", 681 "-100MHz", 682 "-1.0MB/s", 683 "-100.25GiB/s", 684 "1.01TB", 685 "100.25mW", 686 } 687 688 for n := 0; n < b.N; n++ { 689 for _, c := range cases { 690 ParseAttribute(c) 691 } 692 } 693 }