github.com/rohankumardubey/aresdb@v0.0.2-0.20190517170215-e54e3ca06b9c/query/time_filter_test.go (about)

     1  //  Copyright (c) 2017-2018 Uber Technologies, Inc.
     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  
    15  package query
    16  
    17  import (
    18  	"fmt"
    19  	"github.com/onsi/ginkgo"
    20  	. "github.com/onsi/gomega"
    21  	"github.com/uber/aresdb/query/expr"
    22  	"time"
    23  )
    24  
    25  type testCase struct {
    26  	expectedFrom string
    27  	expectedTo   string
    28  	expectedUnit string
    29  	expression   string
    30  }
    31  
    32  var _ = ginkgo.Describe("Test", func() {
    33  	location, _ := time.LoadLocation("America/Los_Angeles")
    34  	now := time.Date(2016, time.March, 15, 21, 24, 26, 0, location)
    35  
    36  	ginkgo.It("Works on empty input", func() {
    37  		from, to, err := parseTimeFilter(TimeFilter{}, time.UTC, now)
    38  		Ω(err).Should(BeNil())
    39  		Ω(from).Should(BeNil())
    40  		Ω(to).Should(BeNil())
    41  	})
    42  
    43  	ginkgo.It("Works", func() {
    44  		testCases := []testCase{
    45  			{expectedFrom: "2016-03-16T00:24:26-04:00", expectedTo: "2016-03-16T00:24:26-04:00", expectedUnit: "s", expression: "now"},
    46  			{expectedFrom: "2016-01-01T00:00:00-05:00", expectedTo: "2017-01-01T00:00:00-05:00", expectedUnit: "y", expression: "this year"},
    47  			{expectedFrom: "2016-01-01T00:00:00-05:00", expectedTo: "2017-01-01T00:00:00-05:00", expectedUnit: "y", expression: "0y"},
    48  			{expectedFrom: "2016-01-01T00:00:00-05:00", expectedTo: "2016-04-01T00:00:00-04:00", expectedUnit: "q", expression: "this quarter"}, // daylight saving begins
    49  			{expectedFrom: "2016-01-01T00:00:00-05:00", expectedTo: "2016-04-01T00:00:00-04:00", expectedUnit: "q", expression: "0q"},           // daylight saving begins
    50  			{expectedFrom: "2016-03-01T00:00:00-05:00", expectedTo: "2016-04-01T00:00:00-04:00", expectedUnit: "M", expression: "this month"},   // daylight saving begins
    51  			{expectedFrom: "2016-03-01T00:00:00-05:00", expectedTo: "2016-04-01T00:00:00-04:00", expectedUnit: "M", expression: "0M"},           // daylight saving begins
    52  			{expectedFrom: "2016-03-14T00:00:00-04:00", expectedTo: "2016-03-21T00:00:00-04:00", expectedUnit: "w", expression: "this week"},
    53  			{expectedFrom: "2016-03-14T00:00:00-04:00", expectedTo: "2016-03-21T00:00:00-04:00", expectedUnit: "w", expression: "0w"},
    54  			{expectedFrom: "2016-03-16T00:00:00-04:00", expectedTo: "2016-03-17T00:00:00-04:00", expectedUnit: "d", expression: "this day"},
    55  			{expectedFrom: "2016-03-16T00:00:00-04:00", expectedTo: "2016-03-17T00:00:00-04:00", expectedUnit: "d", expression: "0d"},
    56  			{expectedFrom: "2016-03-16T00:00:00-04:00", expectedTo: "2016-03-17T00:00:00-04:00", expectedUnit: "d", expression: "today"},
    57  			{expectedFrom: "2016-03-16T00:00:00-04:00", expectedTo: "2016-03-16T01:00:00-04:00", expectedUnit: "h", expression: "this hour"},
    58  			{expectedFrom: "2016-03-16T00:00:00-04:00", expectedTo: "2016-03-16T01:00:00-04:00", expectedUnit: "h", expression: "0h"},
    59  			{expectedFrom: "2016-03-16T00:15:00-04:00", expectedTo: "2016-03-16T00:30:00-04:00", expectedUnit: "15m", expression: "this quarter-hour"},
    60  			{expectedFrom: "2016-03-16T00:24:00-04:00", expectedTo: "2016-03-16T00:25:00-04:00", expectedUnit: "m", expression: "this minute"},
    61  			{expectedFrom: "2016-03-16T00:24:00-04:00", expectedTo: "2016-03-16T00:25:00-04:00", expectedUnit: "m", expression: "0m"},
    62  			{expectedFrom: "2015-01-01T00:00:00-05:00", expectedTo: "2016-01-01T00:00:00-05:00", expectedUnit: "y", expression: "last year"},
    63  			{expectedFrom: "2015-01-01T00:00:00-05:00", expectedTo: "2016-01-01T00:00:00-05:00", expectedUnit: "y", expression: "-1y"},
    64  			{expectedFrom: "2015-10-01T00:00:00-04:00", expectedTo: "2016-01-01T00:00:00-05:00", expectedUnit: "q", expression: "last quarter"}, // daylight saving ends
    65  			{expectedFrom: "2015-10-01T00:00:00-04:00", expectedTo: "2016-01-01T00:00:00-05:00", expectedUnit: "q", expression: "-1q"},          // daylight saving ends
    66  			{expectedFrom: "2016-02-01T00:00:00-05:00", expectedTo: "2016-03-01T00:00:00-05:00", expectedUnit: "M", expression: "last month"},
    67  			{expectedFrom: "2016-02-01T00:00:00-05:00", expectedTo: "2016-03-01T00:00:00-05:00", expectedUnit: "M", expression: "-1M"},
    68  			{expectedFrom: "2016-03-07T00:00:00-05:00", expectedTo: "2016-03-14T00:00:00-04:00", expectedUnit: "w", expression: "last week"}, // daylight saving begins
    69  			{expectedFrom: "2016-03-07T00:00:00-05:00", expectedTo: "2016-03-14T00:00:00-04:00", expectedUnit: "w", expression: "-1w"},       // daylight saving begins
    70  			{expectedFrom: "2016-03-15T00:00:00-04:00", expectedTo: "2016-03-16T00:00:00-04:00", expectedUnit: "d", expression: "last day"},
    71  			{expectedFrom: "2016-03-15T00:00:00-04:00", expectedTo: "2016-03-16T00:00:00-04:00", expectedUnit: "d", expression: "-1d"},
    72  			{expectedFrom: "2016-03-15T00:00:00-04:00", expectedTo: "2016-03-16T00:00:00-04:00", expectedUnit: "d", expression: "yesterday"},
    73  			{expectedFrom: "2016-03-15T23:00:00-04:00", expectedTo: "2016-03-16T00:00:00-04:00", expectedUnit: "h", expression: "last hour"},
    74  			{expectedFrom: "2016-03-15T23:00:00-04:00", expectedTo: "2016-03-16T00:00:00-04:00", expectedUnit: "h", expression: "-1h"},
    75  			{expectedFrom: "2016-03-16T00:00:00-04:00", expectedTo: "2016-03-16T00:15:00-04:00", expectedUnit: "15m", expression: "last quarter-hour"},
    76  			{expectedFrom: "2016-03-16T00:23:00-04:00", expectedTo: "2016-03-16T00:24:00-04:00", expectedUnit: "m", expression: "last minute"},
    77  			{expectedFrom: "2016-03-16T00:23:00-04:00", expectedTo: "2016-03-16T00:24:00-04:00", expectedUnit: "m", expression: "-1m"},
    78  			{expectedFrom: "2014-01-01T00:00:00-05:00", expectedTo: "2015-01-01T00:00:00-05:00", expectedUnit: "y", expression: "2 years ago"},
    79  			{expectedFrom: "2014-01-01T00:00:00-05:00", expectedTo: "2015-01-01T00:00:00-05:00", expectedUnit: "y", expression: "-2y"},
    80  			{expectedFrom: "2015-04-01T00:00:00-04:00", expectedTo: "2015-07-01T00:00:00-04:00", expectedUnit: "q", expression: "3 quarters ago"},
    81  			{expectedFrom: "2015-04-01T00:00:00-04:00", expectedTo: "2015-07-01T00:00:00-04:00", expectedUnit: "q", expression: "-3q"},
    82  			{expectedFrom: "2015-11-01T00:00:00-04:00", expectedTo: "2015-12-01T00:00:00-05:00", expectedUnit: "M", expression: "4 months ago"}, // daylight saving ends
    83  			{expectedFrom: "2015-11-01T00:00:00-04:00", expectedTo: "2015-12-01T00:00:00-05:00", expectedUnit: "M", expression: "-4M"},          // daylight saving ends
    84  			{expectedFrom: "2016-02-08T00:00:00-05:00", expectedTo: "2016-02-15T00:00:00-05:00", expectedUnit: "w", expression: "5 weeks ago"},
    85  			{expectedFrom: "2016-02-08T00:00:00-05:00", expectedTo: "2016-02-15T00:00:00-05:00", expectedUnit: "w", expression: "-5w"},
    86  			{expectedFrom: "2016-03-10T00:00:00-05:00", expectedTo: "2016-03-11T00:00:00-05:00", expectedUnit: "d", expression: "6 days ago"},
    87  			{expectedFrom: "2016-03-10T00:00:00-05:00", expectedTo: "2016-03-11T00:00:00-05:00", expectedUnit: "d", expression: "-6d"},
    88  			{expectedFrom: "2016-03-13T01:00:00-05:00", expectedTo: "2016-03-13T03:00:00-04:00", expectedUnit: "h", expression: "70 hours ago"}, // daylight saving begins
    89  			{expectedFrom: "2016-03-13T01:00:00-05:00", expectedTo: "2016-03-13T03:00:00-04:00", expectedUnit: "h", expression: "-70h"},         // daylight saving begins
    90  			{expectedFrom: "2016-03-15T23:00:00-04:00", expectedTo: "2016-03-15T23:15:00-04:00", expectedUnit: "15m", expression: "5 quarter-hours ago"},
    91  			{expectedFrom: "2016-03-15T23:24:00-04:00", expectedTo: "2016-03-15T23:25:00-04:00", expectedUnit: "m", expression: "60 minutes ago"},
    92  			{expectedFrom: "2016-03-15T23:24:00-04:00", expectedTo: "2016-03-15T23:25:00-04:00", expectedUnit: "m", expression: "-60m"},
    93  			{expectedFrom: "2014-01-01T00:00:00-05:00", expectedTo: "2015-01-01T00:00:00-05:00", expectedUnit: "y", expression: "2014"},
    94  			{expectedFrom: "2014-04-01T00:00:00-04:00", expectedTo: "2014-07-01T00:00:00-04:00", expectedUnit: "q", expression: "2014-Q2"},
    95  			{expectedFrom: "2014-03-01T00:00:00-05:00", expectedTo: "2014-04-01T00:00:00-04:00", expectedUnit: "M", expression: "2014-03"},          // daylight saving begins
    96  			{expectedFrom: "2016-03-13T00:00:00-05:00", expectedTo: "2016-03-14T00:00:00-04:00", expectedUnit: "d", expression: "2016-03-13"},       // daylight saving begins
    97  			{expectedFrom: "2016-03-13T01:00:00-05:00", expectedTo: "2016-03-13T03:00:00-04:00", expectedUnit: "h", expression: "2016-03-13 01"},    // daylight saving begins
    98  			{expectedFrom: "2016-03-13T02:00:00-04:00", expectedTo: "2016-03-13T03:00:00-04:00", expectedUnit: "h", expression: "2016-03-13 02"},    // same hour
    99  			{expectedFrom: "2016-03-13T01:31:00-05:00", expectedTo: "2016-03-13T01:32:00-05:00", expectedUnit: "m", expression: "2016-03-13 01:31"}, // non-sense
   100  			{expectedFrom: "2015-11-01T01:00:00-04:00", expectedTo: "2015-11-01T02:00:00-04:00", expectedUnit: "h", expression: "2015-11-01 01"},    // daylight saving ends, ambiguous
   101  			{expectedFrom: "2015-11-01T02:00:00-05:00", expectedTo: "2015-11-01T03:00:00-05:00", expectedUnit: "h", expression: "2015-11-01 02"},    // daylight saving ends
   102  			{expectedFrom: "2015-11-01T01:31:00-04:00", expectedTo: "2015-11-01T01:32:00-04:00", expectedUnit: "m", expression: "2015-11-01 01:31"}, // daylight saving ends, ambiguous
   103  			{expectedFrom: "2016-06-01T22:00:00-04:00", expectedTo: "2016-06-01T22:00:00-04:00", expectedUnit: "m", expression: "1464832800"},
   104  			{expectedFrom: "2016-06-01T22:00:01-04:00", expectedTo: "2016-06-01T22:00:01-04:00", expectedUnit: "s", expression: "1464832801"},
   105  		}
   106  
   107  		for _, testCase := range testCases {
   108  			loc, _ := time.LoadLocation("America/New_York")
   109  			from, to, err := parseTimeFilter(TimeFilter{
   110  				Column: "request_at",
   111  				From:   testCase.expression,
   112  				To:     testCase.expression,
   113  			}, loc, now)
   114  			Ω(err).Should(BeNil())
   115  
   116  			expectedFrom, err := time.Parse(time.RFC3339, testCase.expectedFrom)
   117  			Ω(err).Should(BeNil())
   118  			Ω(from.Time.UnixNano()).Should(Equal(expectedFrom.UnixNano()))
   119  			Ω(from.Unit).Should(Equal(testCase.expectedUnit))
   120  
   121  			expectedTo, err := time.Parse(time.RFC3339, testCase.expectedTo)
   122  			Ω(err).Should(BeNil())
   123  			Ω(to.Time.UnixNano()).Should(Equal(expectedTo.UnixNano()))
   124  			Ω(to.Unit).Should(Equal(testCase.expectedUnit))
   125  
   126  			fromExpr, toExpr := createTimeFilterExpr(&expr.VarRef{Val: "request_at"}, from, to)
   127  
   128  			Ω(testCase.expression + ": " + fromExpr.String() + " AND " + toExpr.String()).Should(Equal(fmt.Sprintf(
   129  				testCase.expression+": request_at >= %d AND request_at < %d",
   130  				expectedFrom.Unix(), expectedTo.Unix())))
   131  		}
   132  	})
   133  
   134  	ginkgo.It("Works on fixed timezone", func() {
   135  		loc := time.FixedZone("fixed", -(7*60*60 + 30*60))
   136  		from, to, err := parseTimeFilter(TimeFilter{
   137  			Column: "request_at",
   138  			From:   "this year",
   139  			To:     "",
   140  		}, loc, now)
   141  		Ω(err).Should(BeNil())
   142  		fromExpr, toExpr := createTimeFilterExpr(&expr.VarRef{Val: "request_at"}, from, to)
   143  		Ω(fromExpr.String() + " AND " + toExpr.String()).Should(Equal("request_at >= 1451633400 AND request_at < 1458102266"))
   144  
   145  		from, to, err = parseTimeFilter(TimeFilter{
   146  			Column: "request_at",
   147  			From:   "",
   148  			To:     "last year",
   149  		}, loc, now)
   150  		Ω(err).Should(BeNil())
   151  		fromExpr, toExpr = createTimeFilterExpr(&expr.VarRef{Val: "request_at"}, from, to)
   152  		Ω(toExpr.String()).Should(Equal("request_at < 1451633400"))
   153  	})
   154  
   155  	ginkgo.It("Corrects America/Sao_Paulo daylight saving start issue", func() {
   156  		loc, _ := time.LoadLocation("America/Sao_Paulo")
   157  		t := time.Date(2016, 10, 16, 13, 23, 0, 0, loc)
   158  		start, end, _ := applyTimeOffset(t, 0, "d")
   159  		Ω(start.Day()).Should(Equal(16))
   160  		Ω(start.Hour()).Should(Equal(1))
   161  		Ω(end.Day()).Should(Equal(17))
   162  		Ω(end.Hour()).Should(Equal(0))
   163  	})
   164  
   165  	ginkgo.It("Fails on error", func() {
   166  		testCases := []TimeFilter{
   167  			{Column: "request_at", From: "future", To: ""},
   168  			{Column: "request_at", From: "", To: "future"},
   169  			{Column: "request_at", From: "this", To: ""},
   170  			{Column: "request_at", From: "last friday night", To: ""},
   171  			{Column: "request_at", From: "years ago", To: ""},
   172  			{Column: "request_at", From: "N years ago", To: ""},
   173  			{Column: "request_at", From: "-Xd", To: ""},
   174  			{Column: "request_at", From: "2014-01-01 00:00 GMT", To: ""},
   175  			{Column: "request_at", From: "2014-01-01-Haha", To: ""},
   176  			{Column: "request_at", From: "2014-QE", To: ""},
   177  			{Column: "request_at", From: "2014-Q1-earnings", To: ""},
   178  			{Column: "request_at", From: "2014-EF", To: ""},
   179  			{Column: "request_at", From: "2014-03-de", To: ""},
   180  			{Column: "request_at", From: "2014-03 11:23", To: ""},
   181  			{Column: "request_at", From: "2014-03-04 11:23:45", To: ""},
   182  			{Column: "request_at", From: "2014-03-04 hh", To: ""},
   183  			{Column: "request_at", From: "2014-03-04 06:mm", To: ""},
   184  			{Column: "request_at", From: "this century", To: ""},
   185  		}
   186  
   187  		for _, testCase := range testCases {
   188  			_, _, err := parseTimeFilter(testCase, time.UTC, now)
   189  			Ω(err).ShouldNot(BeNil())
   190  		}
   191  	})
   192  })