github.com/go-graphite/carbonapi@v0.17.0/pkg/parser/parser_test.go (about) 1 package parser 2 3 import ( 4 "testing" 5 6 "github.com/stretchr/testify/assert" 7 ) 8 9 func TestSkipWhitespace(t *testing.T) { 10 testCases := []struct{ in, expected string }{ 11 { 12 in: " ", 13 expected: "", 14 }, 15 { 16 in: " foo", 17 expected: "foo", 18 }, 19 { 20 in: " foo ", 21 expected: "foo ", 22 }, 23 { 24 in: "\nfoo", 25 expected: "foo", 26 }, 27 { 28 in: "\tfoo", 29 expected: "foo", 30 }, 31 } 32 33 for _, tc := range testCases { 34 t.Run(tc.in, func(t *testing.T) { 35 out := skipWhitespace(tc.in) 36 assert.Equal(t, tc.expected, out) 37 }) 38 } 39 } 40 41 func TestParseExpr(t *testing.T) { 42 tests := []struct { 43 s string 44 e *expr 45 }{ 46 {"metric=", 47 &expr{target: "metric="}, 48 }, 49 {"metric", 50 &expr{target: "metric"}, 51 }, 52 { 53 "metric.foo", 54 &expr{target: "metric.foo"}, 55 }, 56 {"metric.*.foo", 57 &expr{target: "metric.*.foo"}, 58 }, 59 { 60 "func(metric)", 61 &expr{ 62 target: "func", 63 etype: EtFunc, 64 args: []*expr{{target: "metric"}}, 65 argString: "metric", 66 }, 67 }, 68 { 69 "func(metric1,metric2,metric3)", 70 &expr{ 71 target: "func", 72 etype: EtFunc, 73 args: []*expr{ 74 {target: "metric1"}, 75 {target: "metric2"}, 76 {target: "metric3"}}, 77 argString: "metric1,metric2,metric3", 78 }, 79 }, 80 { 81 "func1(metric1,func2(metricA, metricB),metric3)", 82 &expr{ 83 target: "func1", 84 etype: EtFunc, 85 args: []*expr{ 86 {target: "metric1"}, 87 {target: "func2", 88 etype: EtFunc, 89 args: []*expr{{target: "metricA"}, {target: "metricB"}}, 90 argString: "metricA, metricB", 91 }, 92 {target: "metric3"}}, 93 argString: "metric1,func2(metricA, metricB),metric3", 94 }, 95 }, 96 97 { 98 "3", 99 &expr{val: 3, etype: EtConst, valStr: "3"}, 100 }, 101 { 102 "3.1", 103 &expr{val: 3.1, etype: EtConst, valStr: "3.1"}, 104 }, 105 { 106 "func1(metric1, 3, 1e2, 2e-3)", 107 &expr{ 108 target: "func1", 109 etype: EtFunc, 110 args: []*expr{ 111 {target: "metric1"}, 112 {val: 3, etype: EtConst, valStr: "3"}, 113 {val: 100, etype: EtConst, valStr: "1e2"}, 114 {val: 0.002, etype: EtConst, valStr: "2e-3"}, 115 }, 116 argString: "metric1, 3, 1e2, 2e-3", 117 }, 118 }, 119 { 120 "func1(metric1, 'stringconst')", 121 &expr{ 122 target: "func1", 123 etype: EtFunc, 124 args: []*expr{ 125 {target: "metric1"}, 126 {valStr: "stringconst", etype: EtString}, 127 }, 128 argString: "metric1, 'stringconst'", 129 }, 130 }, 131 { 132 `func1(metric1, "stringconst")`, 133 &expr{ 134 target: "func1", 135 etype: EtFunc, 136 args: []*expr{ 137 {target: "metric1"}, 138 {valStr: "stringconst", etype: EtString}, 139 }, 140 argString: `metric1, "stringconst"`, 141 }, 142 }, 143 { 144 "func1(metric1, -3)", 145 &expr{ 146 target: "func1", 147 etype: EtFunc, 148 args: []*expr{ 149 {target: "metric1"}, 150 {val: -3, etype: EtConst, valStr: "-3"}, 151 }, 152 argString: "metric1, -3", 153 }, 154 }, 155 156 { 157 "func1(metric1, -3 , 'foo' )", 158 &expr{ 159 target: "func1", 160 etype: EtFunc, 161 args: []*expr{ 162 {target: "metric1"}, 163 {val: -3, etype: EtConst, valStr: "-3"}, 164 {valStr: "foo", etype: EtString}, 165 }, 166 argString: "metric1, -3 , 'foo' ", 167 }, 168 }, 169 170 { 171 "func(metric, key='value')", 172 &expr{ 173 target: "func", 174 etype: EtFunc, 175 args: []*expr{ 176 {target: "metric"}, 177 }, 178 namedArgs: map[string]*expr{ 179 "key": {etype: EtString, valStr: "value"}, 180 }, 181 argString: "metric, key='value'", 182 }, 183 }, 184 { 185 "func(metric, key=true)", 186 &expr{ 187 target: "func", 188 etype: EtFunc, 189 args: []*expr{ 190 {target: "metric"}, 191 }, 192 namedArgs: map[string]*expr{ 193 "key": {etype: EtBool, target: "true", valStr: "true"}, 194 }, 195 argString: "metric, key=true", 196 }, 197 }, 198 { 199 "func(metric, key=1)", 200 &expr{ 201 target: "func", 202 etype: EtFunc, 203 args: []*expr{ 204 {target: "metric"}, 205 }, 206 namedArgs: map[string]*expr{ 207 "key": {etype: EtConst, val: 1, valStr: "1"}, 208 }, 209 argString: "metric, key=1", 210 }, 211 }, 212 { 213 "func(metric, key=0.1)", 214 &expr{ 215 target: "func", 216 etype: EtFunc, 217 args: []*expr{ 218 {target: "metric"}, 219 }, 220 namedArgs: map[string]*expr{ 221 "key": {etype: EtConst, val: 0.1, valStr: "0.1"}, 222 }, 223 argString: "metric, key=0.1", 224 }, 225 }, 226 227 { 228 "func(metric, 1, key='value')", 229 &expr{ 230 target: "func", 231 etype: EtFunc, 232 args: []*expr{ 233 {target: "metric"}, 234 {etype: EtConst, val: 1, valStr: "1"}, 235 }, 236 namedArgs: map[string]*expr{ 237 "key": {etype: EtString, valStr: "value"}, 238 }, 239 argString: "metric, 1, key='value'", 240 }, 241 }, 242 { 243 "func(metric, key='value', 1)", 244 &expr{ 245 target: "func", 246 etype: EtFunc, 247 args: []*expr{ 248 {target: "metric"}, 249 {etype: EtConst, val: 1, valStr: "1"}, 250 }, 251 namedArgs: map[string]*expr{ 252 "key": {etype: EtString, valStr: "value"}, 253 }, 254 argString: "metric, key='value', 1", 255 }, 256 }, 257 { 258 "func(metric, key1='value1', key2='value2')", 259 &expr{ 260 target: "func", 261 etype: EtFunc, 262 args: []*expr{ 263 {target: "metric"}, 264 }, 265 namedArgs: map[string]*expr{ 266 "key1": {etype: EtString, valStr: "value1"}, 267 "key2": {etype: EtString, valStr: "value2"}, 268 }, 269 argString: "metric, key1='value1', key2='value2'", 270 }, 271 }, 272 { 273 "func(metric, key2='value2', key1='value1')", 274 &expr{ 275 target: "func", 276 etype: EtFunc, 277 args: []*expr{ 278 {target: "metric"}, 279 }, 280 namedArgs: map[string]*expr{ 281 "key2": {etype: EtString, valStr: "value2"}, 282 "key1": {etype: EtString, valStr: "value1"}, 283 }, 284 argString: "metric, key2='value2', key1='value1'", 285 }, 286 }, 287 288 { 289 `foo.{bar,baz}.qux`, 290 &expr{ 291 target: "foo.{bar,baz}.qux", 292 etype: EtName, 293 }, 294 }, 295 { 296 `foo.b[0-9].qux`, 297 &expr{ 298 target: "foo.b[0-9].qux", 299 etype: EtName, 300 }, 301 }, 302 { 303 `virt.v1.*.text-match:<foo.bar.qux>`, 304 &expr{ 305 target: "virt.v1.*.text-match:<foo.bar.qux>", 306 etype: EtName, 307 }, 308 }, 309 { 310 "func2(metricA, metricB)|func1(metric1,metric3)", 311 &expr{ 312 target: "func1", 313 etype: EtFunc, 314 args: []*expr{ 315 {target: "func2", 316 etype: EtFunc, 317 args: []*expr{{target: "metricA"}, {target: "metricB"}}, 318 argString: "metricA, metricB", 319 }, 320 {target: "metric1"}, 321 {target: "metric3"}}, 322 argString: "func2(metricA, metricB),metric1,metric3", 323 }, 324 }, 325 { 326 `movingAverage(company.server*.applicationInstance.requestsHandled|aliasByNode(1),"5min")`, 327 &expr{ 328 target: "movingAverage", 329 etype: EtFunc, 330 args: []*expr{ 331 {target: "aliasByNode", 332 etype: EtFunc, 333 args: []*expr{ 334 {target: "company.server*.applicationInstance.requestsHandled"}, 335 {val: 1, etype: EtConst, valStr: "1"}, 336 }, 337 argString: "company.server*.applicationInstance.requestsHandled,1", 338 }, 339 {etype: EtString, valStr: "5min"}, 340 }, 341 argString: `aliasByNode(company.server*.applicationInstance.requestsHandled,1),"5min"`, 342 }, 343 }, 344 { 345 `aliasByNode(company.server*.applicationInstance.requestsHandled,1)|movingAverage("5min")`, 346 &expr{ 347 target: "movingAverage", 348 etype: EtFunc, 349 args: []*expr{ 350 {target: "aliasByNode", 351 etype: EtFunc, 352 args: []*expr{ 353 {target: "company.server*.applicationInstance.requestsHandled"}, 354 {val: 1, etype: EtConst, valStr: "1"}, 355 }, 356 argString: "company.server*.applicationInstance.requestsHandled,1", 357 }, 358 {etype: EtString, valStr: "5min"}, 359 }, 360 argString: `aliasByNode(company.server*.applicationInstance.requestsHandled,1),"5min"`, 361 }, 362 }, 363 { 364 `company.server*.applicationInstance.requestsHandled|aliasByNode(1)|movingAverage("5min")`, 365 &expr{ 366 target: "movingAverage", 367 etype: EtFunc, 368 args: []*expr{ 369 {target: "aliasByNode", 370 etype: EtFunc, 371 args: []*expr{ 372 {target: "company.server*.applicationInstance.requestsHandled"}, 373 {val: 1, etype: EtConst, valStr: "1"}, 374 }, 375 argString: "company.server*.applicationInstance.requestsHandled,1", 376 }, 377 {etype: EtString, valStr: "5min"}, 378 }, 379 argString: `aliasByNode(company.server*.applicationInstance.requestsHandled,1),"5min"`, 380 }, 381 }, 382 { 383 `company.server*.applicationInstance.requestsHandled|keepLastValue()`, 384 &expr{ 385 target: "keepLastValue", 386 etype: EtFunc, 387 args: []*expr{ 388 {target: "company.server*.applicationInstance.requestsHandled"}, 389 }, 390 argString: `company.server*.applicationInstance.requestsHandled`, 391 }, 392 }, 393 {"hello&world", 394 &expr{target: "hello&world"}, 395 }, 396 { 397 "foo.bar\n.baz\t", 398 &expr{ 399 target: "foo.bar", 400 etype: EtName, 401 }, 402 }, 403 { 404 "absolute( baz )\n", 405 &expr{ 406 target: "absolute", 407 etype: EtFunc, 408 args: []*expr{ 409 {target: "baz"}, 410 }, 411 argString: " baz ", 412 }, 413 }, 414 { 415 "func1(\"example blah\")", 416 &expr{ 417 target: "func1", 418 etype: EtFunc, 419 args: []*expr{ 420 { 421 etype: EtString, 422 valStr: "example blah", 423 }, 424 }, 425 argString: "\"example blah\"", 426 }, 427 }, 428 { 429 "foobar(\n)", 430 &expr{ 431 target: "foobar", 432 etype: EtFunc, 433 }, 434 }, 435 { 436 "foobar(asdf,\n\tzxcv,\n\tqwer\n)", 437 &expr{ 438 target: "foobar", 439 etype: EtFunc, 440 args: []*expr{ 441 {target: "asdf"}, 442 {target: "zxcv"}, 443 {target: "qwer"}, 444 }, 445 argString: "asdf,\n\tzxcv,\n\tqwer\n", 446 }, 447 }, 448 { 449 "func1(foo.bar)\n| func2(foo.baz)|\n func3(\n\tfunc4(asdf.zxcv.qwer)\n)", 450 &expr{ 451 target: "func3", 452 etype: EtFunc, 453 args: []*expr{ 454 { 455 target: "func2", 456 etype: EtFunc, 457 args: []*expr{ 458 { 459 target: "func1", 460 etype: EtFunc, 461 args: []*expr{ 462 {target: "foo.bar"}, 463 }, 464 argString: "foo.bar", 465 }, 466 {target: "foo.baz"}, 467 }, 468 argString: "func1(foo.bar),foo.baz", 469 }, 470 { 471 target: "func4", 472 etype: EtFunc, 473 args: []*expr{ 474 {target: "asdf.zxcv.qwer"}, 475 }, 476 argString: "asdf.zxcv.qwer", 477 }, 478 }, 479 argString: "func2(func1(foo.bar),foo.baz),func4(asdf.zxcv.qwer)", 480 }, 481 }, 482 } 483 484 for _, tt := range tests { 485 t.Run(tt.s, func(t *testing.T) { 486 assert := assert.New(t) 487 488 e, _, err := ParseExpr(tt.s) 489 if assert.NoError(err) { 490 assert.Equal(tt.e, e, tt.s) 491 } 492 }) 493 } 494 } 495 496 func TestDoGetBoolVar(t *testing.T) { 497 tests := []struct { 498 s string 499 e *expr 500 r bool 501 }{ 502 { 503 "1 is true", 504 &expr{val: 1, etype: EtConst, valStr: "1"}, 505 true, 506 }, 507 { 508 "true is true", 509 &expr{etype: EtString, valStr: "true"}, 510 true, 511 }, 512 { 513 "True is true", 514 &expr{etype: EtString, valStr: "True"}, 515 true, 516 }, 517 { 518 "0 is false", 519 &expr{val: 0, etype: EtConst, valStr: "0"}, 520 false, 521 }, 522 { 523 "False is false", 524 &expr{etype: EtString, valStr: "False"}, 525 false, 526 }, 527 { 528 "false is false", 529 &expr{etype: EtString, valStr: "false"}, 530 false, 531 }, 532 } 533 for _, tt := range tests { 534 t.Run(tt.s, func(t *testing.T) { 535 assert := assert.New(t) 536 537 r, err := tt.e.doGetBoolArg() 538 if assert.NoError(err) { 539 assert.Equal(tt.r, r, tt.s) 540 } 541 }) 542 } 543 } 544 545 func TestGetIntervalNamedOrPosArgDefault(t *testing.T) { 546 e, _, err := ParseExpr("func(metric, key='1min')") 547 assert.NoError(t, err) 548 549 val, err := e.GetIntervalNamedOrPosArgDefault("key", 1, -1, 0) 550 assert.NoError(t, err) 551 assert.Equal(t, int64(-60), val) 552 } 553 554 func TestDoGetFloatArg(t *testing.T) { 555 tests := []struct { 556 s string 557 e *expr 558 r float64 559 }{ 560 { 561 "parse float", 562 &expr{val: 1.0, etype: EtConst, valStr: "1.0"}, 563 1.0, 564 }, 565 { 566 "parse string to float", 567 &expr{etype: EtString, valStr: "1.0"}, 568 1.0, 569 }, 570 } 571 for _, tt := range tests { 572 t.Run(tt.s, func(t *testing.T) { 573 assert := assert.New(t) 574 575 r, err := tt.e.doGetFloatArg() 576 if assert.NoError(err) { 577 assert.Equal(tt.r, r, tt.s) 578 } 579 }) 580 } 581 } 582 583 func TestDoGetIntArg(t *testing.T) { 584 tests := []struct { 585 s string 586 e *expr 587 r int 588 }{ 589 { 590 "parse int", 591 &expr{val: 5, etype: EtConst, valStr: "5"}, 592 5, 593 }, 594 { 595 "parse string to int", 596 &expr{etype: EtString, valStr: "1"}, 597 1, 598 }, 599 } 600 for _, tt := range tests { 601 t.Run(tt.s, func(t *testing.T) { 602 assert := assert.New(t) 603 604 r, err := tt.e.doGetIntArg() 605 if assert.NoError(err) { 606 assert.Equal(tt.r, r, tt.s) 607 } 608 }) 609 } 610 } 611 612 func TestDoGetIntOrInf(t *testing.T) { 613 tests := []struct { 614 s string 615 e *expr 616 r IntOrInf 617 }{ 618 { 619 "parse int", 620 &expr{val: 5, etype: EtConst, valStr: "5"}, 621 IntOrInf{IntVal: 5}, 622 }, 623 { 624 "parse string to int", 625 &expr{etype: EtString, valStr: "1"}, 626 IntOrInf{IntVal: 1}, 627 }, 628 { 629 "parse inf", 630 &expr{etype: EtName, target: "inf"}, 631 IntOrInf{IsInf: true}, 632 }, 633 { 634 "parse capitalized inf", 635 &expr{etype: EtName, target: "INF"}, 636 IntOrInf{IsInf: true}, 637 }, 638 { 639 "parse string to inf", 640 &expr{etype: EtString, valStr: "inf"}, 641 IntOrInf{IsInf: true}, 642 }, 643 } 644 for _, tt := range tests { 645 t.Run(tt.s, func(t *testing.T) { 646 assert := assert.New(t) 647 648 r, err := tt.e.doGetIntOrInfArg() 649 if assert.NoError(err) { 650 assert.Equal(tt.r, r, tt.s) 651 } 652 }) 653 } 654 } 655 656 func TestMetrics(t *testing.T) { 657 tests := []struct { 658 s string 659 e *expr 660 from int64 661 to int64 662 expected []MetricRequest 663 }{ 664 { 665 "hitcount(metric1, '1h', true)", 666 &expr{ 667 target: "hitcount", 668 etype: EtFunc, 669 args: []*expr{ 670 {target: "metric1"}, 671 {valStr: "1h", etype: EtString}, 672 {valStr: "true", etype: EtBool}, 673 }, 674 argString: "metric1, '1h', true", 675 }, 676 1410346740, 677 1410346865, 678 []MetricRequest{ 679 { 680 Metric: "metric1", 681 From: 1410343200, 682 Until: 1410346865, 683 }, 684 }, 685 }, 686 { 687 "hitcount(metric1, '1h', alignToInterval=True)", 688 &expr{ 689 target: "hitcount", 690 etype: EtFunc, 691 args: []*expr{ 692 {target: "metric1"}, 693 {valStr: "1h", etype: EtString}, 694 }, 695 namedArgs: map[string]*expr{ 696 "alignToInterval": { 697 target: "true", 698 etype: EtBool, 699 valStr: "true", 700 }, 701 }, 702 argString: "metric1, '1h', alignToInterval=True", 703 }, 704 1410346740, 705 1410346865, 706 []MetricRequest{ 707 { 708 Metric: "metric1", 709 From: 1410343200, 710 Until: 1410346865, 711 }, 712 }, 713 }, 714 { 715 "hitcount(metric1, '1h')", 716 &expr{ 717 target: "hitcount", 718 etype: EtFunc, 719 args: []*expr{ 720 {target: "metric1"}, 721 {valStr: "1h", etype: EtString}, 722 }, 723 argString: "metric1, '1h'", 724 }, 725 1410346740, 726 1410346865, 727 []MetricRequest{ 728 { 729 Metric: "metric1", 730 From: 1410346740, 731 Until: 1410346865, 732 }, 733 }, 734 }, 735 { 736 "hitcount(timeShift(metric1, '-1h'),'1h')", 737 &expr{ 738 target: "hitcount", 739 etype: EtFunc, 740 args: []*expr{ 741 { 742 target: "timeShift", 743 etype: EtFunc, 744 args: []*expr{ 745 {target: "metric1"}, 746 {valStr: "-1h", etype: EtString}, 747 }, 748 argString: "metric1, '-1h'", 749 }, 750 {valStr: "1h", etype: EtString}, 751 {valStr: "true", etype: EtBool}, 752 }, 753 argString: "timeShift(metric1, '-1h'),'1h'", 754 }, 755 1410346740, 756 1410346865, 757 []MetricRequest{ 758 { 759 Metric: "metric1", 760 From: 1410339600, 761 Until: 1410343265, 762 }, 763 }, 764 }, 765 { 766 "holtWintersAberration(metric1)", 767 &expr{ 768 target: "holtWintersAberration", 769 etype: EtFunc, 770 args: []*expr{ 771 {target: "metric1"}, 772 }, 773 argString: "metric1", 774 }, 775 1410346740, 776 1410346865, 777 []MetricRequest{ 778 { 779 Metric: "metric1", 780 From: 1410346740, 781 Until: 1410346865, 782 }, 783 { 784 Metric: "metric1", 785 From: 1409741940, 786 Until: 1410346865, 787 }, 788 }, 789 }, 790 { 791 "holtWintersAberration(metric1,3,'6d')", 792 &expr{ 793 target: "holtWintersAberration", 794 etype: EtFunc, 795 args: []*expr{ 796 {target: "metric1"}, 797 {valStr: "3", etype: EtConst}, 798 {valStr: "6d", etype: EtString}, 799 }, 800 argString: "metric1, 3, '6d'", 801 }, 802 1410346740, 803 1410346865, 804 []MetricRequest{ 805 { 806 Metric: "metric1", 807 From: 1410346740, 808 Until: 1410346865, 809 }, 810 { 811 Metric: "metric1", 812 From: 1409828340, 813 Until: 1410346865, 814 }, 815 }, 816 }, 817 { 818 "holtWintersConfidenceBands(metric1)", 819 &expr{ 820 target: "holtWintersConfidenceBands", 821 etype: EtFunc, 822 args: []*expr{ 823 {target: "metric1"}, 824 }, 825 argString: "metric1", 826 }, 827 1410346740, 828 1410346865, 829 []MetricRequest{ 830 { 831 Metric: "metric1", 832 From: 1409741940, 833 Until: 1410346865, 834 }, 835 }, 836 }, 837 { 838 "holtWintersConfidenceBands(metric1, 4, '1d')", 839 &expr{ 840 target: "holtWintersConfidenceBands", 841 etype: EtFunc, 842 args: []*expr{ 843 {target: "metric1"}, 844 {valStr: "4", etype: EtConst}, 845 {valStr: "1d", etype: EtString}, 846 }, 847 argString: "metric1, 4, '1d'", 848 }, 849 1410346740, 850 1410346865, 851 []MetricRequest{ 852 { 853 Metric: "metric1", 854 From: 1410260340, 855 Until: 1410346865, 856 }, 857 }, 858 }, 859 { 860 "holtWintersConfidenceBands(metric1, 4, bootstrapInterval='3d')", 861 &expr{ 862 target: "holtWintersConfidenceBands", 863 etype: EtFunc, 864 args: []*expr{ 865 {target: "metric1"}, 866 {valStr: "4", etype: EtConst}, 867 }, 868 namedArgs: map[string]*expr{ 869 "bootstrapInterval": {etype: EtString, valStr: "3d"}, 870 }, 871 argString: "metric1, 4, '3d'", 872 }, 873 1410346740, 874 1410346865, 875 []MetricRequest{ 876 { 877 Metric: "metric1", 878 From: 1410087540, 879 Until: 1410346865, 880 }, 881 }, 882 }, 883 { 884 "holtWintersForecast(metric1,'1d')", 885 &expr{ 886 target: "holtWintersConfidenceBands", 887 etype: EtFunc, 888 args: []*expr{ 889 {target: "metric1"}, 890 }, 891 argString: "metric1", 892 }, 893 1410346740, 894 1410346865, 895 []MetricRequest{ 896 { 897 Metric: "metric1", 898 From: 1409741940, 899 Until: 1410346865, 900 }, 901 }, 902 }, 903 { 904 "smartSummarize(metric1, '1h', 'sum', 'seconds')", 905 &expr{ 906 target: "smartSummarize", 907 etype: EtFunc, 908 args: []*expr{ 909 {target: "metric1"}, 910 {valStr: "1h", etype: EtString}, 911 {valStr: "sum", etype: EtString}, 912 {valStr: "seconds", etype: EtString}, 913 }, 914 argString: "metric1, '1h', 'sum', 'seconds'", 915 }, 916 1410346740, 917 1410346865, 918 []MetricRequest{ 919 { 920 Metric: "metric1", 921 From: 1410346740, 922 Until: 1410346865, 923 }, 924 }, 925 }, 926 { 927 "smartSummarize(metric1, '1h', 'sum', '1minutes')", 928 &expr{ 929 target: "smartSummarize", 930 etype: EtFunc, 931 args: []*expr{ 932 {target: "metric1"}, 933 {valStr: "1h", etype: EtString}, 934 {valStr: "sum", etype: EtString}, 935 {valStr: "1minutes", etype: EtString}, 936 }, 937 argString: "metric1, '1h', 'sum', '1minutes'", 938 }, 939 1410346745, 940 1410346865, 941 []MetricRequest{ 942 { 943 Metric: "metric1", 944 From: 1410346740, 945 Until: 1410346865, 946 }, 947 }, 948 }, 949 { 950 "smartSummarize(metric1, '1h', 'sum', 'hours')", 951 &expr{ 952 target: "smartSummarize", 953 etype: EtFunc, 954 args: []*expr{ 955 {target: "metric1"}, 956 {valStr: "1h", etype: EtString}, 957 {valStr: "sum", etype: EtString}, 958 {valStr: "hours", etype: EtString}, 959 }, 960 argString: "metric1, '1h', 'sum', 'hours'", 961 }, 962 1410346740, 963 1410346865, 964 []MetricRequest{ 965 { 966 Metric: "metric1", 967 From: 1410343200, 968 Until: 1410346865, 969 }, 970 }, 971 }, 972 { 973 "smartSummarize(metric1, '1h', 'sum', 'days')", 974 &expr{ 975 target: "smartSummarize", 976 etype: EtFunc, 977 args: []*expr{ 978 {target: "metric1"}, 979 {valStr: "1h", etype: EtString}, 980 {valStr: "sum", etype: EtString}, 981 {valStr: "days", etype: EtString}, 982 }, 983 argString: "metric1, '1h', 'sum', 'days'", 984 }, 985 1410346740, 986 1410346865, 987 []MetricRequest{ 988 { 989 Metric: "metric1", 990 From: 1410307200, 991 Until: 1410346865, 992 }, 993 }, 994 }, 995 { 996 "smartSummarize(metric1, '1hours','sum','weeks5')", 997 &expr{ 998 target: "smartSummarize", 999 etype: EtFunc, 1000 args: []*expr{ 1001 {target: "metric1"}, 1002 {valStr: "1h", etype: EtString}, 1003 {valStr: "sum", etype: EtString}, 1004 {valStr: "weeks5", etype: EtString}, 1005 }, 1006 argString: "metric1, '1h', 'sum', 'weeks5'", 1007 }, 1008 1410346740, 1009 1410346865, 1010 []MetricRequest{ 1011 { 1012 Metric: "metric1", 1013 From: 1409875200, 1014 Until: 1410346865, 1015 }, 1016 }, 1017 }, 1018 { 1019 "smartSummarize(metric1, '1hours','sum','months')", 1020 &expr{ 1021 target: "smartSummarize", 1022 etype: EtFunc, 1023 args: []*expr{ 1024 {target: "metric1"}, 1025 {valStr: "1h", etype: EtString}, 1026 {valStr: "sum", etype: EtString}, 1027 {valStr: "months", etype: EtString}, 1028 }, 1029 argString: "metric1, '1h', 'sum', 'months'", 1030 }, 1031 1410346740, 1032 1410346865, 1033 []MetricRequest{ 1034 { 1035 Metric: "metric1", 1036 From: 1409529600, 1037 Until: 1410346865, 1038 }, 1039 }, 1040 }, 1041 { 1042 "smartSummarize(metric1, '1hours','sum','y')", 1043 &expr{ 1044 target: "smartSummarize", 1045 etype: EtFunc, 1046 args: []*expr{ 1047 {target: "metric1"}, 1048 {valStr: "1h", etype: EtString}, 1049 {valStr: "sum", etype: EtString}, 1050 {valStr: "years", etype: EtString}, 1051 }, 1052 argString: "metric1, '1h', 'sum', 'years'", 1053 }, 1054 1410346740, 1055 1410346865, 1056 []MetricRequest{ 1057 { 1058 Metric: "metric1", 1059 From: 1388534400, 1060 Until: 1410346865, 1061 }, 1062 }, 1063 }, 1064 } 1065 for _, tt := range tests { 1066 t.Run(tt.s, func(t *testing.T) { 1067 1068 r := tt.e.Metrics(tt.from, tt.to) 1069 assert.Equal(t, tt.expected, r) 1070 }) 1071 } 1072 }