package integration import ( "encoding/json" "fmt" "math" "net/http" "time" influxdb "github.com/influxdb/influxdb/client" "github.com/influxdb/influxdb/engine" . "github.com/influxdb/influxdb/integration/helpers" . "launchpad.net/gocheck" ) type DataTestSuite struct { server *Server client *DataTestClient dbname string } var _ = Suite(&DataTestSuite{}) func (self *DataTestSuite) SetUpSuite(c *C) { self.dbname = "testdb" self.server = NewServer("integration/test_config_single.toml", c) // make sure the tests don't use an idle connection, otherwise the // server will close it http.DefaultTransport.(*http.Transport).CloseIdleConnections() } func (self *DataTestSuite) TearDownSuite(c *C) { if self.server == nil { return } self.server.Stop() } func (self *DataTestSuite) SetUpTest(c *C) { self.client = &DataTestClient{} self.client.CreateDatabase(self.dbname, c) self.client.SetDB(self.dbname) } func (self *DataTestSuite) TearDownTest(c *C) { self.client.DeleteDatabase(self.dbname, c) self.client = nil } type Fun func(client Client) // issue #518 func (self *DataTestSuite) TestInfiniteValues(c *C) { // make sure we exceed the pointBatchSize, so we force a yield to // the filtering engine data := ` [ { "points": [ [1399590718, 0.0], [1399590718, 0.0] ], "name": "test_infinite_values", "columns": ["time", "value"] } ]` self.client.WriteJsonData(data, c, influxdb.Second) serieses := self.client.RunQuery("select derivative(value) from test_infinite_values", c, "m") c.Assert(serieses, HasLen, 1) maps := ToMap(serieses[0]) c.Assert(maps, HasLen, 1) c.Assert(maps[0]["derivative"], IsNil) } // test large integer values func (self *DataTestSuite) TestLargeIntegerValues(c *C) { // make sure we exceed the pointBatchSize, so we force a yield to // the filtering engine i := int64(math.MaxInt64) data := fmt.Sprintf(` [ { "points": [ [%d] ], "name": "test_large_integer_values", "columns": ["value"] } ]`, i) self.client.WriteJsonData(data, c, influxdb.Second) serieses := self.client.RunQueryWithNumbers("select * from test_large_integer_values", c, "m") c.Assert(serieses, HasLen, 1) maps := ToMap(serieses[0]) c.Assert(maps, HasLen, 1) n := maps[0]["value"] actual, err := n.(json.Number).Int64() c.Assert(err, IsNil) c.Assert(actual, Equals, i) } // Postive case of derivative function func (self *DataTestSuite) TestDerivativeValues(c *C) { // make sure we exceed the pointBatchSize, so we force a yield to // the filtering engine data := ` [ { "points": [ [1399590718, 10.0], [1399590719, 20.0] ], "name": "test_derivative_values", "columns": ["time", "value"] } ]` self.client.WriteJsonData(data, c, influxdb.Second) serieses := self.client.RunQuery("select derivative(value) from test_derivative_values", c, "m") c.Assert(serieses, HasLen, 1) maps := ToMap(serieses[0]) c.Assert(maps, HasLen, 1) c.Assert(maps[0]["derivative"], Equals, 10.0) } // Simple case of difference function func (self *DataTestSuite) TestDifferenceValues(c *C) { // make sure we exceed the pointBatchSize, so we force a yield to // the filtering engine data := ` [ { "points": [ [1399590718, 10.0], [1399590719, 20.0], [1399590720, 30.0] ], "name": "test_difference_values", "columns": ["time", "value"] } ]` self.client.WriteJsonData(data, c, influxdb.Second) serieses := self.client.RunQuery("select difference(value) from test_difference_values order asc", c, "m") c.Assert(serieses, HasLen, 1) maps := ToMap(serieses[0]) c.Assert(maps, HasLen, 1) c.Assert(maps[0]["difference"], Equals, 20.0) } // issue #426 func (self *DataTestSuite) TestFillingEntireRange(c *C) { data := ` [ { "name": "test_filling_range", "columns": ["value"], "points": [ [1] ] } ]` self.client.WriteJsonData(data, c, influxdb.Millisecond) serieses := self.client.RunQuery("select sum(value) from test_filling_range where time > now() - 1d group by time(1h) fill(0)", c, "m") c.Assert(serieses, HasLen, 1) maps := ToMap(serieses[0]) c.Assert(maps, HasLen, 25) c.Assert(maps[0]["sum"], Equals, 1.0) for i := 1; i < len(maps); i++ { c.Assert(maps[i]["sum"], Equals, 0.0) } } func (self *DataTestSuite) TestModeWithInt(c *C) { data := ` [ { "name": "test_mode", "columns": ["value"], "points": [ [1], [2], [2], [3], [4] ] } ]` self.client.WriteJsonData(data, c, influxdb.Millisecond) serieses := self.client.RunQuery("select mode(value) from test_mode", c, "m") c.Assert(serieses, HasLen, 1) maps := ToMap(serieses[0]) c.Assert(maps, HasLen, 1) c.Assert(maps[0]["mode"], Equals, 2.0) } func (self *DataTestSuite) TestModeWithString(c *C) { data := ` [ { "name": "test_mode_string", "columns": ["value"], "points": [ ["one"], ["two"], ["two"], ["two"], ["three"] ] } ]` self.client.WriteJsonData(data, c, influxdb.Millisecond) serieses := self.client.RunQuery("select mode(value) from test_mode_string", c, "m") c.Assert(serieses, HasLen, 1) maps := ToMap(serieses[0]) c.Assert(maps, HasLen, 1) c.Assert(maps[0]["mode"], Equals, "two") } func (self *DataTestSuite) TestModeWithNils(c *C) { data := ` [ { "name": "test_mode_nils", "columns": ["value", "value2"], "points": [ [1, "one"], [1, null], [1, null], [1, null], [1, "three"] ] } ]` self.client.WriteJsonData(data, c, influxdb.Millisecond) serieses := self.client.RunQuery("select mode(value) as m1, mode(value2) as m2 from test_mode_nils", c, "m") c.Assert(serieses, HasLen, 1) maps := ToMap(serieses[0]) c.Assert(maps, HasLen, 1) c.Assert(maps[0]["m2"], Equals, nil) } func (self *DataTestSuite) TestMergingOldData(c *C) { data := ` [ { "name": "test_merge_1", "columns": ["time", "value"], "points": [ [315532800000, "a value"] ] }, { "name": "test_merge_2", "columns": ["time", "value"], "points": [ [1401321600000, "another value"] ] } ]` self.client.WriteJsonData(data, c, influxdb.Millisecond) serieses := self.client.RunQuery("select * from test_merge_1 merge test_merge_2", c, "m") c.Assert(serieses, HasLen, 1) maps := ToMap(serieses[0]) c.Assert(maps, HasLen, 2) serieses = self.client.RunQuery("select * from test_merge_1 merge test_merge_2 where time > '1980-01-01' and time < '1980-01-04'", c, "m") c.Assert(serieses, HasLen, 1) maps = ToMap(serieses[0]) c.Assert(maps, HasLen, 1) c.Assert(maps[0]["value"], Equals, "a value") } // Difference function combined with group by func (self *DataTestSuite) TestDifferenceGroupValues(c *C) { data := ` [ { "points": [ [1399590700, 0.0], [1399590710, 10.0], [1399590720, 20.0], [1399590730, 40.0], [1399590740, 80.0], [1399590750, 160.0] ], "name": "test_difference_group_values", "columns": ["time", "value"] } ]` self.client.WriteJsonData(data, c, influxdb.Second) serieses := self.client.RunQuery("select difference(value) from test_difference_group_values group by time(20s) order asc", c, "m") c.Assert(serieses, HasLen, 1) maps := ToMap(serieses[0]) c.Assert(maps, HasLen, 3) c.Assert(maps[0]["difference"], Equals, 10.0) c.Assert(maps[1]["difference"], Equals, 20.0) c.Assert(maps[2]["difference"], Equals, 80.0) } // issue 578 func (self *DataTestSuite) TestParanthesesAlias(c *C) { data := ` [ { "points": [ [ 0.0, 1.0] ], "name": "test_parantheses_aliasing", "columns": ["value", "one"] } ]` self.client.WriteJsonData(data, c, influxdb.Second) serieses := self.client.RunQuery("select (value + one) as value_plus_one from test_parantheses_aliasing", c, "m") c.Assert(serieses, HasLen, 1) maps := ToMap(serieses[0]) c.Assert(maps, HasLen, 1) c.Assert(maps[0]["value_plus_one"], Equals, 1.0) } // Difference and group by function using a time where clause with an interval which is equal to the time of the points // FIXME: This test still fails. For this case the group by function should include points with the end time for each bucket. //func (self *DataTestSuite) TestDifferenceGroupSameTimeValues(c *C) { // // make sure we exceed the pointBatchSize, so we force a yield to // // the filtering engine // data := ` //[ // { // "points": [ // [1399590700, 0.0], // [1399590710, 10.0], // [1399590720, 20.0], // [1399590730, 40.0], // [1399590740, 80.0], // [1399590750, 160.0] // ], // "name": "test_difference_group_same_time_values", // "columns": ["time", "value"] // } //]` // self.client.WriteJsonData(data, c, influxdb.Second) // serieses := self.client.RunQuery("select range(value) from test_difference_group_same_time_values group by time(10s) order asc", c, "m") // c.Assert(serieses, HasLen, 1) // maps := ToMap(serieses[0]) // c.Assert(maps, HasLen, 6) // c.Assert(maps[0]["difference"], Equals, 10.0) // c.Assert(maps[1]["difference"], Equals, 10.0) // c.Assert(maps[2]["difference"], Equals, 20.0) // c.Assert(maps[3]["difference"], Equals, 40.0) // c.Assert(maps[4]["difference"], Equals, 80.0) //} // issue #512 func (self *DataTestSuite) TestGroupByNullValues(c *C) { // make sure we exceed the pointBatchSize, so we force a yield to // the filtering engine data := ` [ { "points": [ ["one", null], ["one", 1], ["one", null] ], "name": "test_null_groups", "columns": ["column0", "column1"] } ]` self.client.WriteJsonData(data, c, influxdb.Second) serieses := self.client.RunQuery("select count(column0) from test_null_groups group by column1", c, "m") c.Assert(serieses, HasLen, 1) maps := ToMap(serieses[0]) c.Assert(maps, HasLen, 2) c.Assert(maps[0]["count"], Equals, 1.0) // this is an implementation detail, but nulls come last in the // trie c.Assert(maps[1]["count"], Equals, 2.0) } // issue #389 func (self *DataTestSuite) TestFilteringShouldNotStopIfAllPointsDontMatch(c *C) { // make sure we exceed the pointBatchSize, so we force a yield to // the filtering engine numberOfPoints := 1000000 serieses := CreatePointsFromFunc("test_filtering_shouldnt_stop", 1, numberOfPoints, func(i int) float64 { return float64(numberOfPoints - i) }) series := serieses[0] series.Columns = append(series.Columns, "time") points := series.Points series.Points = nil now := time.Now() for idx, point := range points { point = append(point, float64(now.Add(time.Duration(-idx)*time.Second).Unix())) series.Points = append(series.Points, point) } self.client.WriteData([]*influxdb.Series{series}, c, influxdb.Second) result := self.client.RunQuery("select column0 from test_filtering_shouldnt_stop where column0 < 10", c, "m") c.Assert(result, HasLen, 1) } // issue #413 func (self *DataTestSuite) TestSmallGroupByIntervals(c *C) { serieses := CreatePoints("test_small_group_by", 1, 1) self.client.WriteData(serieses, c) serieses = self.client.RunQuery("select count(column0) from test_small_group_by group by time(10)", c, "m") c.Assert(serieses, HasLen, 1) c.Assert(serieses[0].Points, HasLen, 1) c.Assert(serieses[0].Points[0], HasLen, 2) c.Assert(serieses[0].Points[0][1], Equals, 1.0) } // issue #524 func (self *DataTestSuite) TestWhereAndArithmetic(c *C) { i := 0 serieses := CreatePointsFromFunc("foo", 2, 2, func(_ int) float64 { i++; return float64(i) }) self.client.WriteData(serieses, c) serieses = self.client.RunQuery("select column1 / 2 from foo where column0 > 1", c, "m") c.Assert(serieses, HasLen, 1) maps := ToMap(serieses[0]) c.Assert(maps, HasLen, 1) c.Assert(maps[0]["expr0"], Equals, 2.0) } // issue #524 func (self *DataTestSuite) TestJoinAndArithmetic(c *C) { t1 := time.Now().Truncate(time.Hour).Add(-4 * time.Hour) t2 := t1.Add(time.Hour) t3 := t2.Add(time.Hour) t4 := t3.Add(time.Hour) data := fmt.Sprintf(`[ { "name":"foo", "columns":["time", "val"], "points":[[%d, 1],[%d, 2]] }, { "name":"bar", "columns":["time", "val"], "points":[[%d, 3],[%d, 4]] }]`, t1.Unix(), t3.Unix(), t2.Unix(), t4.Unix()) self.client.WriteJsonData(data, c, "s") serieses := self.client.RunQuery("select foo.val + bar.val from foo inner join bar where bar.val <> 3", c, "m") c.Assert(serieses, HasLen, 1) maps := ToMap(serieses[0]) c.Assert(maps, HasLen, 1) c.Assert(maps[0]["expr0"], Equals, 6.0) } // issue #652 func (self *DataTestSuite) TestJoinWithInvalidFilteringShouldReturnMeaningfulError(c *C) { t1 := time.Now().Truncate(time.Hour).Add(-4 * time.Hour) t2 := t1.Add(time.Hour) t3 := t2.Add(time.Hour) t4 := t3.Add(time.Hour) data := fmt.Sprintf(`[ { "name":"foo", "columns":["time", "val"], "points":[[%d, 1],[%d, 2]] }, { "name":"bar", "columns":["time", "val"], "points":[[%d, 3],[%d, 4]] }]`, t1.Unix(), t3.Unix(), t2.Unix(), t4.Unix()) self.client.WriteJsonData(data, c, "s") self.client.RunInvalidQuery("select foo.val + bar.val from foo inner join bar where val <> 3", c, "m") } // issue #768 func (self *DataTestSuite) TestMinusOperatorWithoutSpace(c *C) { data := ` [{ "points": [ [2, 3] ], "name": "test_minus_operator", "columns": ["val1", "val2"] }]` self.client.WriteJsonData(data, c) serieses := self.client.RunQuery("select val2-val1 from test_minus_operator ", c, "m") c.Assert(serieses, HasLen, 1) maps := ToMap(serieses[0]) c.Assert(maps, HasLen, 1) c.Assert(maps[0]["expr0"], Equals, 1.0) } // issue #540 func (self *DataTestSuite) TestRegexMatching(c *C) { serieses := CreatePoints("cpu.1", 1, 1) self.client.WriteData(serieses, c) serieses = CreatePoints("cpu-2", 1, 1) self.client.WriteData(serieses, c) serieses = self.client.RunQuery("select * from /cpu\\..*/ limit 1", c, "m") c.Assert(serieses, HasLen, 1) c.Assert(serieses[0].Name, Equals, "cpu.1") } // issue #112 func (self *DataTestSuite) TestSelectFromMultipleSeries(c *C) { serieses := CreatePoints("cpu1.load_one", 1, 5) self.client.WriteData(serieses, c) serieses = CreatePoints("cpu2.load_one", 1, 3) self.client.WriteData(serieses, c) results := self.client.RunQuery("select * from cpu1.load_one, cpu2.load_one", c, "m") series := map[string][]map[string]interface{}{} for _, s := range results { series[s.Name] = ToMap(s) } c.Assert(series, HasLen, 2) c.Assert(series["cpu1.load_one"], HasLen, 5) c.Assert(series["cpu2.load_one"], HasLen, 3) } func (self *DataTestSuite) TestSelectFromMultipleSeriesWithLimit(c *C) { i := 0.0 serieses := CreatePointsFromFunc("cpu1.load_one", 1, 5, func(_ int) float64 { i++; return i }) self.client.WriteData(serieses, c) serieses = CreatePointsFromFunc("cpu2.load_one", 1, 3, func(_ int) float64 { i++; return i }) self.client.WriteData(serieses, c) results := self.client.RunQuery("select * from cpu1.load_one, cpu2.load_one limit 2", c, "m") series := map[string][]map[string]interface{}{} for _, s := range results { series[s.Name] = ToMap(s) } c.Assert(series, HasLen, 2) c.Assert(series["cpu1.load_one"], HasLen, 2) c.Assert(series["cpu2.load_one"], HasLen, 2) c.Assert(series["cpu1.load_one"][0]["column0"], Equals, float64(5.0)) c.Assert(series["cpu1.load_one"][1]["column0"], Equals, float64(4.0)) c.Assert(series["cpu2.load_one"][0]["column0"], Equals, float64(8.0)) c.Assert(series["cpu2.load_one"][1]["column0"], Equals, float64(7.0)) } // issue #392 func (self *DataTestSuite) TestDifferentColumnsAcrossShards(c *C) { i := 0.0 serieses := CreatePointsFromFunc("test_different_columns_across_shards", 1, 1, func(_ int) float64 { i++; return i }) now := time.Now().Truncate(24 * time.Hour) serieses[0].Columns = []string{"column0", "time"} serieses[0].Points[0] = append(serieses[0].Points[0], now.Unix()) self.client.WriteData(serieses, c, "s") serieses = CreatePointsFromFunc("test_different_columns_across_shards", 2, 1, func(_ int) float64 { i++; return i }) serieses[0].Columns = []string{"column0", "column1", "time"} serieses[0].Points[0] = append(serieses[0].Points[0], now.Add(-8*24*time.Hour).Unix()) self.client.WriteData(serieses, c, "s") serieses = self.client.RunQuery("select * from test_different_columns_across_shards", c, "s") c.Assert(serieses, HasLen, 1) maps := ToMap(serieses[0]) c.Assert(maps[0]["column0"], Equals, 1.0) c.Assert(maps[0]["column1"], IsNil) c.Assert(maps[1]["column0"], Equals, 2.0) c.Assert(maps[1]["column1"], Equals, 3.0) } // issue #392 func (self *DataTestSuite) TestDifferentColumnsAcrossShards2(c *C) { i := 0.0 serieses := CreatePointsFromFunc("test_different_columns_across_shards_2", 1, 1, func(_ int) float64 { i++; return i }) now := time.Now().Truncate(24 * time.Hour) serieses[0].Columns = []string{"column1", "time"} serieses[0].Points[0] = append(serieses[0].Points[0], now.Add(-13*24*time.Hour).Unix()) self.client.WriteData(serieses, c, "s") serieses = CreatePointsFromFunc("test_different_columns_across_shards_2", 2, 1, func(_ int) float64 { i++; return i }) serieses[0].Columns = []string{"column1", "column0", "time"} serieses[0].Points[0] = append(serieses[0].Points[0], now.Unix()) self.client.WriteData(serieses, c, "s") serieses = self.client.RunQuery("select * from test_different_columns_across_shards_2", c, "s") c.Assert(serieses, HasLen, 1) maps := ToMap(serieses[0]) c.Assert(maps[0]["column0"], Equals, 3.0) c.Assert(maps[0]["column1"], Equals, 2.0) c.Assert(maps[1]["column0"], IsNil) c.Assert(maps[1]["column1"], Equals, 1.0) } // issue #455 func (self *DataTestSuite) TestNullValuesInComparison(c *C) { series := []*influxdb.Series{ { Name: "foo", Columns: []string{"foo", "bar"}, Points: [][]interface{}{ {1, 2}, {2, nil}, }, }, } self.client.WriteData(series, c, "s") serieses := self.client.RunQuery("select * from foo where bar < 10", c, "s") c.Assert(serieses, HasLen, 1) maps := ToMap(serieses[0]) c.Assert(maps, HasLen, 1) c.Assert(maps[0]["bar"], Equals, 2.0) } // issue #462 (wasn't an issue, added for regression testing only) func (self *DataTestSuite) TestRegexWithDollarSign(c *C) { data := ` [ { "points": [ ["one", 1] ], "name": "test.negative.in.where.clause.1", "columns": ["val_1", "val_2"] }, { "points": [ ["two", 2] ], "name": "test.negative.in.where.clause.1.2", "columns": ["val_1", "val_2"] }, { "points": [ ["three", 3] ], "name": "test.negative.in.where.clause.a", "columns": ["val_1", "val_2"] } ]` self.client.WriteJsonData(data, c) series := self.client.RunQuery(`select * from /test\.negative\.in\.where\.clause\.\d$/ limit 1`, c, "m") c.Assert(series, HasLen, 1) c.Assert(series[0].Name, Equals, "test.negative.in.where.clause.1") c.Assert(series[0].Columns, HasLen, 4) maps := ToMap(series[0]) c.Assert(maps, HasLen, 1) c.Assert(maps[0]["val_1"], Equals, "one") c.Assert(maps[0]["val_2"], Equals, 1.0) } // https://groups.google.com/forum/#!searchin/influxdb/INT_VALUE%7Csort:relevance%7Cspell:false/influxdb/9bQAuWUnDf4/cp0vtmEe65oJ func (self *DataTestSuite) TestNegativeNumbersInWhereClause(c *C) { data := ` [{ "points": [ ["one", -1], ["two", 3] ], "name": "test_negative_in_where_clause", "columns": ["val_1", "val_2"] }]` self.client.WriteJsonData(data, c) series := self.client.RunQuery("select * from test_negative_in_where_clause where val_2 = -1 limit 1", c, "m") c.Assert(series, HasLen, 1) c.Assert(series[0].Name, Equals, "test_negative_in_where_clause") c.Assert(series[0].Columns, HasLen, 4) // 6 columns plus the time column maps := ToMap(series[0]) c.Assert(maps, HasLen, 1) c.Assert(maps[0]["val_2"], Equals, -1.0) c.Assert(maps[0]["val_1"], Equals, "one") } func (self *DataTestSuite) TestDistinctWithLimit(c *C) { data := CreatePoints("test_count_distinct_limit", 1, 1000) self.client.WriteData(data, c) series := self.client.RunQuery("select distinct(column0) from test_count_distinct_limit limit 10", c, "m") c.Assert(series, HasLen, 1) c.Assert(series[0].Columns, HasLen, 2) // 6 columns plus the time column c.Assert(series[0].Points, HasLen, 10) } func (self *DataTestSuite) TestInsensitiveRegexMatching(c *C) { data := `[{"name":"foo","columns":["value"],"points":[["Paul"]]}]` self.client.WriteJsonData(data, c) series := self.client.RunQuery("select * from foo where value =~ /paul/i", c, "m") c.Assert(series, HasLen, 1) c.Assert(series[0].Name, Equals, "foo") maps := ToMap(series[0]) c.Assert(maps, HasLen, 1) c.Assert(maps[0]["value"], Equals, "Paul") } func (self *DataTestSuite) TestDifferentColumnsInOnePost(c *C) { data := `[{"name":"foo","columns":["val0", "val1"],"points":[["a", 1]]},{"name":"foo","columns":["val0"],"points":[["b"]]}]` self.client.WriteJsonData(data, c) for v0, v1 := range map[string]interface{}{"a": 1.0, "b": nil} { series := self.client.RunQuery(fmt.Sprintf("select * from foo where val0 = '%s'", v0), c, "m") c.Assert(series, HasLen, 1) c.Assert(series[0].Name, Equals, "foo") maps := ToMap(series[0]) c.Assert(maps, HasLen, 1) c.Assert(maps[0]["val1"], Equals, v1) } } func (self *DataTestSuite) TestFillWithCountDistinct(c *C) { t1 := time.Now() t2 := t1.Add(-2 * time.Hour) data := fmt.Sprintf(`[{"name":"foo","columns":["time", "val0"],"points":[[%d, "a"],[%d, "b"]]}]`, t1.Unix(), t2.Unix()) self.client.WriteJsonData(data, c, "s") series := self.client.RunQuery("select count(distinct(val0)) from foo group by time(1h) fill(0)", c, "m") c.Assert(series, HasLen, 1) maps := ToMap(series[0]) c.Assert(maps, HasLen, 3) c.Assert(maps[0]["count"], Equals, 1.0) c.Assert(maps[1]["count"], Equals, 0.0) c.Assert(maps[2]["count"], Equals, 1.0) } func (self *DataTestSuite) TestMedians(c *C) { for i := 0; i < 3; i++ { self.client.WriteJsonData(fmt.Sprintf(` [ { "name": "test_medians", "columns": ["cpu", "host"], "points": [[%d, "hosta"], [%d, "hostb"]] } ] `, 60+i*10, 70+i*10), c) } data := self.client.RunQuery("select median(cpu) from test_medians group by host;", c, "m") c.Assert(data[0].Name, Equals, "test_medians") c.Assert(data[0].Columns, HasLen, 3) c.Assert(data[0].Points, HasLen, 2) medians := map[float64]string{} for _, point := range data[0].Points { medians[point[1].(float64)] = point[2].(string) } c.Assert(medians, DeepEquals, map[float64]string{70.0: "hosta", 80.0: "hostb"}) } // issue #34 func (self *DataTestSuite) TestAscendingQueries(c *C) { now := time.Now().Truncate(time.Hour) series := &influxdb.Series{ Name: "test_ascending", Columns: []string{"host", "time"}, Points: [][]interface{}{ {"hosta", now.Add(-4 * time.Second).Unix()}, }, } self.client.WriteData([]*influxdb.Series{series}, c, "s") series = &influxdb.Series{ Name: "test_ascending", Columns: []string{"host", "time", "cpu"}, Points: [][]interface{}{ {"hosta", now.Add(-time.Second).Unix(), 60}, {"hostb", now.Add(-time.Second).Unix(), 70}, }, } self.client.WriteData([]*influxdb.Series{series}, c, "s") data := self.client.RunQuery("select host, cpu from test_ascending order asc", c, "s") c.Assert(data, HasLen, 1) c.Assert(data[0].Name, Equals, "test_ascending") c.Assert(data[0].Columns, HasLen, 4) c.Assert(data[0].Points, HasLen, 3) maps := ToMap(data[0]) for i := 1; i < 3; i++ { c.Assert(maps[i]["cpu"], NotNil) } } func (self *DataTestSuite) TestFilterWithInvalidCondition(c *C) { data := CreatePoints("test_invalid_where_condition", 1, 1) self.client.WriteData(data, c) self.client.RunInvalidQuery("select * from test_invalid_where_condition where column0 > 0.1s", c, "m") } // issue #55 func (self *DataTestSuite) TestFilterWithLimit(c *C) { now := time.Now().Truncate(time.Hour) series := &influxdb.Series{ Name: "test_ascending", Columns: []string{"host", "time", "cpu"}, Points: [][]interface{}{ {"hosta", now.Add(-time.Second).Unix(), 60}, {"hostb", now.Add(-time.Second).Unix(), 70}, {"hosta", now.Add(-2 * time.Second).Unix(), 70}, {"hostb", now.Add(-2 * time.Second).Unix(), 80}, }, } self.client.WriteData([]*influxdb.Series{series}, c) data := self.client.RunQuery("select host, cpu from test_ascending where host = 'hostb' order asc limit 1", c, "m") c.Assert(data, HasLen, 1) maps := ToMap(data[0]) c.Assert(maps, HasLen, 1) c.Assert(maps[0]["cpu"], Equals, 80.0) } // issue #81 func (self *DataTestSuite) TestFilterWithInClause(c *C) { series := &influxdb.Series{ Name: "test_in_clause", Columns: []string{"host", "cpu"}, Points: [][]interface{}{ {"hosta", 60}, {"hostb", 70}, }, } self.client.WriteData([]*influxdb.Series{series}, c) data := self.client.RunQuery("select host, cpu from test_in_clause where host in ('hostb')", c, "m") c.Assert(data, HasLen, 1) maps := ToMap(data[0]) c.Assert(maps, HasLen, 1) c.Assert(maps[0]["host"], Equals, "hostb") } // issue #85 // querying a time series shouldn't add non existing columns func (self *DataTestSuite) TestIssue85(c *C) { data := CreatePoints("test_issue_85", 1, 1) self.client.WriteData(data, c) _ = self.client.RunInvalidQuery("select new_column from test_issue_85", c, "m") data = self.client.RunQuery("select * from test_issue_85", c, "m") c.Assert(data, HasLen, 1) c.Assert(data[0].Columns, HasLen, 3) } // issue #92 // grouping my multiple columns fails // Assuming the following sample data // // time | fr | to | app | kb // ----------------------------------------------------- // now() - 1hr | home | office | ssl | 10 // now() - 1hr | home | office | ssl | 20 // now() - 1hr | home | internet | http | 30 // now() - 1hr | home | office | http | 40 // now() | home | internet | skype | 50 // now() | home | office | lotus | 60 // now() | home | internet | skype | 70 // // the query `select sum(kb) from test group by time(1h), to, app` // will cause an index out of range func (self *DataTestSuite) TestIssue92(c *C) { hourAgo := time.Now().Add(-1 * time.Hour).Unix() now := time.Now().Unix() self.client.WriteJsonData(fmt.Sprintf(` [ { "name": "test_issue_92", "columns": ["time", "fr", "to", "app", "kb"], "points": [ [%d, "home", "office", "ssl", 10], [%d, "home", "office", "ssl", 20], [%d, "home", "internet", "http", 30], [%d, "home", "office", "http", 40], [%d, "home", "internet", "skype", 50], [%d, "home", "office", "lotus", 60], [%d, "home", "internet", "skype", 70] ] } ] `, hourAgo, hourAgo, hourAgo, hourAgo, now, now, now), c, "s") data := self.client.RunQuery("select sum(kb) from test_issue_92 group by time(1h), to, app", c, "m") c.Assert(data, HasLen, 1) points := ToMap(data[0]) // use a map since the order isn't guaranteed sumToPointsMap := map[float64][]map[string]interface{}{} for _, point := range points { sum := point["sum"].(float64) sumToPointsMap[sum] = append(sumToPointsMap[sum], point) } c.Assert(sumToPointsMap[120.0], HasLen, 1) c.Assert(sumToPointsMap[120.0][0]["to"], Equals, "internet") c.Assert(sumToPointsMap[120.0][0]["app"], Equals, "skype") c.Assert(sumToPointsMap[60.0], HasLen, 1) c.Assert(sumToPointsMap[40.0], HasLen, 1) c.Assert(sumToPointsMap[30.0], HasLen, 2) } // issue #89 // Group by combined with where clause doesn't work // // a | b | c // --------- // x | y | 10 // x | y | 20 // y | z | 30 // x | z | 40 // // `select sum(c) from test group by b where a = 'x'` should return the following: // // time | sum | b // -------------- // tttt | 30 | y // tttt | 40 | z func (self *DataTestSuite) TestIssue89(c *C) { self.client.WriteJsonData(` [ { "name": "test_issue_89", "columns": ["a", "b", "c"], "points": [ ["x", "y", 10], ["x", "y", 20], ["y", "z", 30], ["x", "z", 40] ] } ]`, c) data := self.client.RunQuery("select sum(c) from test_issue_89 group by b where a = 'x'", c, "m") c.Assert(data, HasLen, 1) points := ToMap(data[0]) c.Assert(points, HasLen, 2) sums := map[string]float64{} for _, p := range points { sums[p["b"].(string)] = p["sum"].(float64) } c.Assert(sums, DeepEquals, map[string]float64{"y": 30.0, "z": 40.0}) } // issue #306 func (self *DataTestSuite) TestNegativeTimeInterval(c *C) { self.client.WriteJsonData(` [ { "name": "test_negative_interval", "columns": ["cpu", "host", "time"], "points": [[60, "hosta", -1], [70, "hostb", -2]] } ] `, c) data := self.client.RunQuery("select count(cpu) from test_negative_interval", c, "m") c.Assert(data, HasLen, 1) c.Assert(data[0].Name, Equals, "test_negative_interval") c.Assert(data[0].Columns, HasLen, 2) c.Assert(data[0].Points, HasLen, 1) // count should be 3 c.Assert(data[0].Points[0][1], Equals, 2.0) } // issue #306 func (self *DataTestSuite) TestShardBoundaries(c *C) { d := ` [ { "name": "test_end_time_of_shard_is_exclusive", "columns": ["cpu", "host", "time"], "points": [[60, "hosta", -1], [70, "hostb", 0]] } ] ` self.client.WriteJsonData(d, c, "s") for _, query := range []string{ "select count(cpu) from test_end_time_of_shard_is_exclusive where time > 0s", "select count(cpu) from test_end_time_of_shard_is_exclusive where time < 0s", } { fmt.Printf("Running query: %s\n", query) data := self.client.RunQuery(query, c, "s") c.Assert(data, HasLen, 1) c.Assert(data[0].Name, Equals, "test_end_time_of_shard_is_exclusive") c.Assert(data[0].Columns, HasLen, 2) c.Assert(data[0].Points, HasLen, 1) c.Assert(data[0].Points[0][1], Equals, 1.0) } } // make sure aggregation when happen locally at the shard level don't // get repeated at the coordinator level, otherwise unexpected // behavior will happen func (self *DataTestSuite) TestCountWithGroupByTimeAndLimit(c *C) { data := CreatePoints("test_count_with_groupby_and_limit", 1, 2) self.client.WriteData(data, c) data = self.client.RunQuery("select count(column0) from test_count_with_groupby_and_limit group by time(5m) limit 10", c, "m") c.Assert(data, HasLen, 1) c.Assert(data[0].Name, Equals, "test_count_with_groupby_and_limit") c.Assert(data[0].Columns, HasLen, 2) c.Assert(data[0].Points, HasLen, 1) c.Assert(data[0].Points[0][1], Equals, 2.0) } func (self *DataTestSuite) TestWhereQuery(c *C) { data := `[{"points": [[4], [10], [5]], "name": "test_where_query", "columns": ["value"]}]` self.client.WriteJsonData(data, c) collection := self.client.RunQuery("select * from test_where_query where value < 6", c) c.Assert(collection, HasLen, 1) maps := ToMap(collection[0]) c.Assert(maps, HasLen, 2) c.Assert(maps[0]["value"], Equals, 5.0) c.Assert(maps[1]["value"], Equals, 4.0) } func (self *DataTestSuite) TestCountWithGroupBy(c *C) { series := &influxdb.Series{ Name: "test_count", Columns: []string{"host"}, } for i := 0; i < 20; i++ { series.Points = append(series.Points, []interface{}{"hosta"}) series.Points = append(series.Points, []interface{}{"hostb"}) } self.client.WriteData([]*influxdb.Series{series}, c) data := self.client.RunQuery("select count(host) from test_count group by host limit 10", c, "m") c.Assert(data, HasLen, 1) maps := ToMap(data[0]) c.Assert(maps[0]["count"], Equals, 20.0) } func (self *DataTestSuite) TestCountWithAlias(c *C) { // generate 10 points to make sure the aggregation will be calculated now := time.Now().Truncate(time.Hour) data := CreatePoints("test_aliasing", 1, 2) data[0].Columns = append(data[0].Columns, "time") data[0].Points[0] = append(data[0].Points[0], now.Unix()) data[0].Points[1] = append(data[0].Points[1], now.Add(-time.Second).Unix()) self.client.WriteData(data, c) for _, name := range engine.GetRegisteredAggregators() { query := fmt.Sprintf("select %s(column0) as some_alias from test_aliasing", name) if name == "percentile" { query = "select percentile(column0, 90) as some_alias from test_aliasing" } else if name == "top" || name == "bottom" { query = fmt.Sprintf("select %s(column0, 10) as some_alias from test_aliasing", name) } fmt.Printf("query: %s\n", query) data := self.client.RunQuery(query, c, "m") c.Assert(data, HasLen, 1) c.Assert(data[0].Name, Equals, "test_aliasing") if name == "histogram" { c.Assert(data[0].Columns, DeepEquals, []string{"time", "some_alias_bucket_start", "some_alias_count"}) continue } c.Assert(data[0].Columns, DeepEquals, []string{"time", "some_alias"}) } } // test for issue #30 func (self *DataTestSuite) TestHttpPostWithTime(c *C) { now := time.Now().Add(-10 * 24 * time.Hour) data := CreatePoints("test_post_with_time", 1, 1) data[0].Columns = append(data[0].Columns, "time") data[0].Points[0] = append(data[0].Points[0], now.Unix()) self.client.WriteData(data, c, "s") data = self.client.RunQuery("select * from test_post_with_time where time > now() - 20d", c, "m") c.Assert(data, HasLen, 1) c.Assert(data[0].Columns, HasLen, 3) c.Assert(data[0].Points, HasLen, 1) } // test limit when getting data from multiple shards func (self *DataTestSuite) TestLimitMultipleShards(c *C) { self.client.WriteJsonData(` [ { "name": "test_limit_with_multiple_shards", "columns": ["time", "a"], "points":[ [1393577978000, 1], [1383577978000, 2], [1373577978000, 2], [1363577978000, 2], [1353577978000, 2], [1343577978000, 2], [1333577978000, 2], [1323577978000, 2], [1313577978000, 2] ] } ]`, c, "m") data := self.client.RunQuery("select * from test_limit_with_multiple_shards limit 1", c, "m") c.Assert(data, HasLen, 1) c.Assert(data[0].Points, HasLen, 1) } // test for issue #106 func (self *DataTestSuite) TestIssue106(c *C) { data := CreatePoints("test_issue_106", 1, 1) self.client.WriteData(data, c) data = self.client.RunQuery("select derivative(column0) from test_issue_106", c, "m") c.Assert(data, HasLen, 0) } func (self *DataTestSuite) TestIssue105(c *C) { self.client.WriteJsonData(` [ { "name": "test_issue_105", "columns": ["time", "a", "b"], "points":[ [1386262529794, 2, 1], [1386262529794, 2, null] ] } ]`, c, "m") data := self.client.RunQuery("select a, b from test_issue_105 where b > 0", c, "m") c.Assert(data, HasLen, 1) maps := ToMap(data[0]) c.Assert(maps, HasLen, 1) c.Assert(maps[0]["b"], Equals, 1.0) } func (self *DataTestSuite) TestWhereConditionWithExpression(c *C) { self.client.WriteJsonData(` [ { "name": "test_where_expression", "columns": ["time", "a", "b"], "points":[ [1386262529794, 2, 1], [1386262529794, 2, 0] ] } ]`, c, "m") data := self.client.RunQuery("select a, b from test_where_expression where a + b >= 3", c, "m") c.Assert(data, HasLen, 1) maps := ToMap(data[0]) c.Assert(maps, HasLen, 1) c.Assert(maps[0]["b"], Equals, 1.0) } // issue #740 and #781 func (self *DataTestSuite) TestJoiningDifferentFields(c *C) { // TODO: why do we get a different error if we remove all but the first values self.client.WriteJsonData(` [ { "name" : "totalThreads", "columns" : ["time", "value", "hostname"], "points" : [ [1405364100, 16, "serverA"], [1405364105, 20, "serverB"], [1405364115, 16, "serverA"], [1405364120, 20, "serverB"], [1405364130, 18, "serverA"], [1405364135, 15, "serverB"], [1405364145, 19, "serverA"], [1405364150, 16, "serverB"] ] }, { "name" : "idleThreads", "columns" : ["time", "value", "hostname"], "points" : [ [1405364100, 12, "serverA"], [1405364105, 9, "serverB"], [1405364115, 13, "serverA"], [1405364120, 12, "serverB"], [1405364130, 8, "serverA"], [1405364135, 13, "serverB"], [1405364145, 2, "serverA"], [1405364150, 13, "serverB"] ] } ] `, c, "ms") data := self.client.RunQuery("SELECT total.hostname, total.value - idle.value FROM totalThreads AS total INNER JOIN idleThreads AS idle GROUP BY time(15s);", c, "m") c.Assert(data, HasLen, 1) maps := ToMap(data[0]) expectedValues := []float64{3, 17, 2, 10, 8, 3, 11, 4} for i, m := range maps { c.Assert(m["expr1"], Equals, expectedValues[i]) } } func (self *DataTestSuite) TestAggregateWithExpression(c *C) { self.client.WriteJsonData(` [ { "name": "test_aggregate_expression", "columns": ["time", "a", "b"], "points":[ [1386262529794, 1, 1], [1386262529794, 2, 2] ] } ]`, c, "m") data := self.client.RunQuery("select mean(a + b) from test_aggregate_expression", c, "m") c.Assert(data, HasLen, 1) maps := ToMap(data[0]) c.Assert(maps, HasLen, 1) c.Assert(maps[0]["mean"], Equals, 3.0) } func (self *DataTestSuite) verifyWrite(seriesName string, value interface{}, c *C) { series := CreatePoints("foo", 1, 1) series[0].Columns = append(series[0].Columns, "time", "sequence_number") now := time.Now().Truncate(time.Hour) series[0].Points[0] = append(series[0].Points[0], 1.0, now.Unix()) self.client.WriteData(series, c, "s") series[0].Points[0][0] = value self.client.WriteData(series, c, "s") data := self.client.RunQuery("select * from foo", c, "m") if value == nil { c.Assert(data, HasLen, 0) return } c.Assert(data, HasLen, 1) maps := ToMap(data[0]) c.Assert(maps[0]["column0"], Equals, value) } func (self *DataTestSuite) TestUpdatePoint(c *C) { self.verifyWrite("test_updating_point", 1.0, c) } func (self *DataTestSuite) TestDeletePoint(c *C) { self.verifyWrite("test_deleting_point", nil, c) } func (self *DataTestSuite) TestInvalidDeleteQuery(c *C) { data := CreatePoints("test_invalid_delete_query", 1, 1) self.client.WriteData(data, c) _ = self.client.RunInvalidQuery("delete from test_invalid_delete_query where foo = 'bar'", c, "m") data = self.client.RunQuery("select * from test_invalid_delete_query", c, "m") c.Assert(data, HasLen, 1) c.Assert(data[0].Points, HasLen, 1) } func (self *DataTestSuite) TestReadingWhenColumnHasDot(c *C) { self.client.WriteJsonData(` [ { "name": "test_column_names_with_dots", "columns": ["first.name", "last.name"], "points": [["paul", "dix"], ["john", "shahid"]] } ]`, c) for name, expected := range map[string]map[string]bool{ "first.name": {"paul": true, "john": true}, "last.name": {"dix": true, "shahid": true}, } { q := fmt.Sprintf("select %s from test_column_names_with_dots", name) data := self.client.RunQuery(q, c, "m") c.Assert(data, HasLen, 1) c.Assert(data[0].Columns, HasLen, 3) // time, sequence number and the requested columns c.Assert(data[0].Columns[2], Equals, name) names := map[string]bool{} for _, p := range data[0].Points { names[p[2].(string)] = true } c.Assert(names, DeepEquals, expected) } } func (self *DataTestSuite) TestSinglePointSelect(c *C) { data := CreatePoints("test_single_points", 1, 2) self.client.WriteData(data, c) query := "select * from test_single_points;" data = self.client.RunQuery(query, c, "u") c.Assert(data[0].Points, HasLen, 2) c.Assert(data, HasLen, 1) expected := ToMap(data[0]) c.Assert(expected, HasLen, 2) for _, point := range expected { query := fmt.Sprintf("select * from test_single_points where time = %.0fu and sequence_number = %0.f;", point["time"], point["sequence_number"]) data := self.client.RunQuery(query, c, "u") c.Assert(data, HasLen, 1) maps := ToMap(data[0]) c.Assert(maps, HasLen, 1) actual := maps[0] c.Assert(actual, HasLen, 3) c.Assert(actual["time"], Equals, point["time"]) } } func (self *DataTestSuite) TestSinglePointSelectWithNullValues(c *C) { self.client.WriteJsonData(` [ { "name": "test_single_points_with_nulls", "columns": ["name", "age"], "points": [["paul", 50],["john", null]] } ]`, c) query := "select * from test_single_points_with_nulls where name='john';" data := self.client.RunQuery(query, c, "u") c.Assert(data, HasLen, 1) maps := ToMap(data[0]) for _, m := range maps { query := fmt.Sprintf("select * from test_single_points_with_nulls where time = %.0fu and sequence_number = %0.f;", m["time"], m["sequence_number"]) data := self.client.RunQuery(query, c, "u") c.Assert(data, HasLen, 1) actualMaps := ToMap(data[0]) c.Assert(actualMaps, HasLen, 1) c.Assert(actualMaps[0]["name"], Equals, maps[0]["name"]) } } func (self *DataTestSuite) TestBooleanColumnsWorkWithWhereQuery(c *C) { self.client.WriteJsonData(` [ { "name": "test_boolean_columns_where", "columns": ["a"], "points":[[true], [false], [true]] } ]`, c) data := self.client.RunQuery("select count(a) from test_boolean_columns_where where a = true", c, "m") c.Assert(data, HasLen, 1) c.Assert(data[0].Points, HasLen, 1) c.Assert(data[0].Points[0][1], Equals, 2.0) } func (self *DataTestSuite) TestColumnsWithOnlySomeValuesWorkWithWhereQuery(c *C) { self.client.WriteJsonData(` [ { "name": "test_missing_column_values", "columns": ["a", "b"], "points":[["a", "b"]] } ]`, c) self.client.WriteJsonData(` [ { "name": "test_missing_column_values", "columns": ["a", "b", "c"], "points":[["a", "b", "c"]] } ]`, c) data := self.client.RunQuery("select * from test_missing_column_values where c = 'c'", c, "m") c.Assert(data, HasLen, 1) c.Assert(data[0].Points, HasLen, 1) } func (self *DataTestSuite) TestSeriesListing(c *C) { self.client.WriteJsonData(` [ { "name": "test_series_listing", "columns": ["cpu", "host"], "points": [[99.2, "hosta"], [55.6, "hostb"]] } ] `, c) data := self.client.RunQuery("list series", c, "m") c.Assert(data, HasLen, 1) maps := ToMap(data[0]) names := map[string]bool{} for _, m := range maps { names[m["name"].(string)] = true } c.Assert(names["test_series_listing"], Equals, true) } func (self *DataTestSuite) TestArithmeticOperations(c *C) { queries := map[string][9]float64{ "select input + output from test_arithmetic_3.0;": {1, 2, 3, 4, 5, 9, 6, 7, 13}, "select input - output from \"test_arithmetic_-1.0\";": {1, 2, -1, 4, 5, -1, 6, 7, -1}, "select input * output from test_arithmetic_2.0;": {1, 2, 2, 4, 5, 20, 6, 7, 42}, "select 1.0 * input / output from test_arithmetic_0.5;": {1, 2, 0.5, 4, 5, 0.8, 6, 8, 0.75}, } for query, values := range queries { fmt.Printf("Running query %s\n", query) for i := 0; i < 3; i++ { data := fmt.Sprintf(` [ { "name": "test_arithmetic_%.1f", "columns": ["input", "output"], "points": [[%f, %f]] } ] `, values[2], values[3*i], values[3*i+1]) self.client.WriteJsonData(data, c) } } for query, values := range queries { data := self.client.RunQuery(query, c, "m") c.Assert(data, HasLen, 1) c.Assert(data[0].Columns, HasLen, 3) c.Assert(data[0].Points, HasLen, 3) for i, p := range data[0].Points { idx := 2 - i c.Assert(p[2], Equals, values[3*idx+2]) } } } // issue #437 func (self *DataTestSuite) TestConstantsInArithmeticQueries(c *C) { data := `[{"points": [[1]], "name": "test_constants", "columns": ["value"]}]` self.client.WriteJsonData(data, c) for _, query := range []string{ "select -1 * value from test_constants", "select -1.0 * value from test_constants", } { collection := self.client.RunQuery(query, c) c.Assert(collection, HasLen, 1) maps := ToMap(collection[0]) c.Assert(maps, HasLen, 1) c.Assert(maps[0]["expr0"], Equals, -1.0) } } func (self *DataTestSuite) TestCountQueryOnSingleShard(c *C) { data := `[{"points": [[4], [10], [5]], "name": "test_count_query_single_shard", "columns": ["value"]}]` self.client.WriteJsonData(data, c) t := time.Now().Add(-time.Minute) data = fmt.Sprintf(`[{"points": [[2, %d]], "name": "test_count_query_single_shard", "columns": ["value", "time"]}]`, t.Unix()) self.client.WriteJsonData(data, c, "s") collection := self.client.RunQuery("select count(value) from test_count_query_single_shard group by time(1m)", c) c.Assert(collection, HasLen, 1) maps := ToMap(collection[0]) c.Assert(maps, HasLen, 2) c.Assert(maps[0]["count"], Equals, 3.0) c.Assert(maps[1]["count"], Equals, 1.0) } // issue #714 func (self *DataTestSuite) TestWhereClauseWithFunction(c *C) { serieses := CreatePoints("test_where_clause_with_function", 1, 1) self.client.WriteData(serieses, c) self.client.RunInvalidQuery("select column0 from test_where_clause_with_function where empty(column0)", c) //FIXME: Why doesn't this test have asserts? } func (self *DataTestSuite) TestGroupByDay(c *C) { data := `[{"points": [[4], [10], [5]], "name": "test_group_by_day", "columns": ["value"]}]` self.client.WriteJsonData(data, c) t := time.Now().Add(-24 * time.Hour).Unix() data = fmt.Sprintf(`[{"points": [[2, %d]], "name": "test_group_by_day", "columns": ["value", "time"]}]`, t) self.client.WriteJsonData(data, c, "s") collection := self.client.RunQuery("select count(value) from test_group_by_day group by time(1d)", c) c.Assert(collection, HasLen, 1) maps := ToMap(collection[0]) c.Assert(maps, HasLen, 2) c.Assert(maps[0]["count"], Equals, 3.0) c.Assert(maps[1]["count"], Equals, 1.0) } func (self *DataTestSuite) TestLimitQueryOnSingleShard(c *C) { data := `[{"points": [[4], [10], [5]], "name": "test_limit_query_single_shard", "columns": ["value"]}]` self.client.WriteJsonData(data, c) collection := self.client.RunQuery("select * from test_limit_query_single_shard limit 2", c) c.Assert(collection, HasLen, 1) maps := ToMap(collection[0]) c.Assert(maps, HasLen, 2) c.Assert(maps[0]["value"], Equals, 5.0) c.Assert(maps[1]["value"], Equals, 10.0) } func (self *DataTestSuite) TestQueryAgainstMultipleShards(c *C) { data := `[{"points": [[4], [10], [5]], "name": "test_query_against_multiple_shards", "columns": ["value"]}]` self.client.WriteJsonData(data, c) t := time.Now().Add(-14 * 24 * time.Hour).Unix() data = fmt.Sprintf(`[{"points": [[2, %d]], "name": "test_query_against_multiple_shards", "columns": ["value", "time"]}]`, t) self.client.WriteJsonData(data, c, "s") collection := self.client.RunQuery("select count(value) from test_query_against_multiple_shards group by time(1h)", c) c.Assert(collection, HasLen, 1) maps := ToMap(collection[0]) c.Assert(maps, HasLen, 2) c.Assert(maps[0]["count"], Equals, 3.0) c.Assert(maps[1]["count"], Equals, 1.0) } func (self *DataTestSuite) TestQueryAscendingAgainstMultipleShards(c *C) { data := `[{"points": [[4], [10]], "name": "test_ascending_against_multiple_shards", "columns": ["value"]}]` self.client.WriteJsonData(data, c) t := time.Now().Add(-14 * 24 * time.Hour).Unix() data = fmt.Sprintf(`[{"points": [[2, %d]], "name": "test_ascending_against_multiple_shards", "columns": ["value", "time"]}]`, t) self.client.WriteJsonData(data, c, "s") collection := self.client.RunQuery("select * from test_ascending_against_multiple_shards order asc", c) c.Assert(collection, HasLen, 1) maps := ToMap(collection[0]) c.Assert(maps, HasLen, 3) c.Assert(maps[0]["value"], Equals, 2.0) c.Assert(maps[1]["value"], Equals, 4.0) c.Assert(maps[2]["value"], Equals, 10.0) } func (self *DataTestSuite) TestBigGroupByQueryAgainstMultipleShards(c *C) { duration := int64(30 * 24 * time.Hour) first := time.Unix(time.Now().Unix()/duration*duration, 0).Add(7 * 24 * time.Hour) data := fmt.Sprintf( `[{"points": [[4, %d], [10, %d]], "name": "test_multiple_shards_big_group_by", "columns": ["value", "time"]}]`, first.Unix(), first.Unix()) self.client.WriteJsonData(data, c) t := first.Add(7 * 24 * time.Hour).Unix() data = fmt.Sprintf(`[{"points": [[2, %d]], "name": "test_multiple_shards_big_group_by", "columns": ["value", "time"]}]`, t) self.client.WriteJsonData(data, c, "s") collection := self.client.RunQuery("select count(value) from test_multiple_shards_big_group_by group by time(30d)", c) c.Assert(collection, HasLen, 1) maps := ToMap(collection[0]) c.Assert(maps, HasLen, 1) c.Assert(maps[0]["count"], Equals, 3.0) } func (self *DataTestSuite) TestWriteSplitToMultipleShards(c *C) { data := `[ {"points": [[4], [10]], "name": "test_write_multiple_shards", "columns": ["value"]}, {"points": [["asdf"]], "name": "Test_write_multiple_shards", "columns": ["thing"]}]` self.client.WriteJsonData(data, c) collection := self.client.RunQuery("select count(value) from test_write_multiple_shards", c) c.Assert(collection, HasLen, 1) maps := ToMap(collection[0]) c.Assert(maps, HasLen, 1) c.Assert(maps[0]["count"], Equals, 2.0) collection = self.client.RunQuery("select * from Test_write_multiple_shards", c) c.Assert(collection, HasLen, 1) maps = ToMap(collection[0]) c.Assert(maps, HasLen, 1) c.Assert(maps[0]["thing"], Equals, "asdf") } func (self *DataTestSuite) TestCountDistinctWithNullValues(c *C) { data := `[{"name":"test_null_with_distinct","columns":["column"],"points":[["value1"], [null], ["value2"], ["value1"], [null]]}]` self.client.WriteJsonData(data, c) collection := self.client.RunQuery("select count(distinct(column)) from test_null_with_distinct group by time(1m)", c) c.Assert(collection, HasLen, 1) maps := ToMap(collection[0]) c.Assert(maps, HasLen, 1) c.Assert(maps[0]["count"], Equals, 2.0) } // issue #147 func (self *DataTestSuite) TestExtraSequenceNumberColumns(c *C) { data := ` [{ "points": [ ["foo", 1390852524, 1234] ], "name": "test_extra_sequence_number_column", "columns": ["val_1", "time", "sequence_number"] }]` self.client.WriteJsonData(data, c) collection := self.client.RunQuery("select * from test_extra_sequence_number_column", c) c.Assert(collection, HasLen, 1) maps := ToMap(collection[0]) c.Assert(maps, HasLen, 1) c.Assert(maps[0]["sequence_number"], Equals, 1234.0) } // issue #206 func (self *DataTestSuite) TestUnicodeSupport(c *C) { data := ` [{ "points": [ ["山田太郎", "中文", "⚑"] ], "name": "test_unicode", "columns": ["val_1", "val_2", "val_3"] }]` self.client.WriteJsonData(data, c) collection := self.client.RunQuery("select * from test_unicode", c) c.Assert(collection, HasLen, 1) maps := ToMap(collection[0]) c.Assert(maps[0]["val_1"], Equals, "山田太郎") c.Assert(maps[0]["val_2"], Equals, "中文") c.Assert(maps[0]["val_3"], Equals, "⚑") } func (self *DataTestSuite) TestSelectingTimeColumn(c *C) { data := `[{ "name": "selecting_time_column", "columns": ["val1"], "points": [[1]] }]` self.client.WriteJsonData(data, c) collection := self.client.RunQuery("select val1, time from selecting_time_column", c) c.Assert(collection, HasLen, 1) c.Assert(collection[0].Columns, HasLen, 3) c.Assert(collection[0].Points, HasLen, 1) } // For issue #130 https://github.com/influxdb/influxdb/issues/130 func (self *DataTestSuite) TestColumnNamesReturnInDistributedQuery(c *C) { data := `[{ "name": "cluster_query_with_columns", "columns": ["col1"], "points": [[1], [2]] }]` self.client.WriteJsonData(data, c) collection := self.client.RunQuery("select * from cluster_query_with_columns", c) c.Assert(collection, HasLen, 1) maps := ToMap(collection[0]) set := map[float64]bool{} for idx := range maps { set[maps[idx]["col1"].(float64)] = true } c.Assert(set, DeepEquals, map[float64]bool{1: true, 2: true}) } func (self *DataTestSuite) TestLimitWithRegex(c *C) { batchSize := []int{100, 1000} // run the test once with less than POINT_BATCH_SIZE points and once // with more than POINT_BATCH_SIZE points series := []*influxdb.Series{} for _, numberOfPoints := range batchSize { for i := 0; i < 100; i++ { series = append(series, CreatePointsFromFunc(fmt.Sprintf("limit_with_regex_%d_%d", numberOfPoints, i), 1, numberOfPoints, func(i int) float64 { return float64(i) }, )...) } } self.client.WriteData(series, c) for _, numberOfPoints := range batchSize { query := fmt.Sprintf("select * from /.*limit_with_regex_%d.*/ limit 1", numberOfPoints) collection := self.client.RunQuery(query, c) // make sure all series get back 1 point only series := map[string][]map[string]interface{}{} for _, s := range collection { series[s.Name] = ToMap(s) } for i := 0; i < 100; i++ { table := fmt.Sprintf("limit_with_regex_%d_%d", numberOfPoints, i) c.Assert(series[table], HasLen, 1) c.Assert(series[table][0]["column0"], Equals, float64(numberOfPoints-1)) } } } // For issue #131 https://github.com/influxdb/influxdb/issues/131 func (self *DataTestSuite) TestSelectFromRegexInCluster(c *C) { data := `[{ "name": "cluster_regex_query", "columns": ["col1", "col2"], "points": [[1, "foo"], [23, "bar"]] },{ "name": "cluster_regex_query_2", "columns": ["blah"], "points": [[true]] },{ "name": "cluster_regex_query_3", "columns": ["foobar"], "points": [["asdf"]] }]` self.client.WriteJsonData(data, c) collection := self.client.RunQuery("select * from /.*/ limit 1", c) c.Assert(collection, HasLen, 3) series := map[string][]map[string]interface{}{} for _, s := range collection { series[s.Name] = ToMap(s) } c.Assert(series["cluster_regex_query"], HasLen, 1) c.Assert(series["cluster_regex_query"][0]["col1"], Equals, 23.0) c.Assert(series["cluster_regex_query"][0]["col2"], Equals, "bar") c.Assert(series["cluster_regex_query_2"], HasLen, 1) c.Assert(series["cluster_regex_query_2"][0]["blah"], Equals, true) c.Assert(series["cluster_regex_query_3"], HasLen, 1) c.Assert(series["cluster_regex_query_3"][0]["foobar"], Equals, "asdf") } func (self *DataTestSuite) TestListSeries(c *C) { data := `[ {"points": [[1]], "name": "cluster_query", "columns": ["value"]}, {"points": [[2]], "name": "another_query", "columns": ["value"]} ]` self.client.WriteJsonData(data, c, "s") collection := self.client.RunQuery("list series", c) c.Assert(collection, HasLen, 1) maps := ToMap(collection[0]) names := map[string]bool{} for _, m := range maps { names[m["name"].(string)] = true } c.Assert(names["cluster_query"], Equals, true) c.Assert(names["another_query"], Equals, true) } // For issue #267 - allow all characters in series name - https://github.com/influxdb/influxdb/issues/267 func (self *DataTestSuite) TestSeriesNameWithWeirdCharacters(c *C) { data := `[ { "name": "/blah ( ) ; : ! @ # $ \n \t,foo\"=bar/baz", "columns": ["value"], "points": [[1]] } ]` self.client.WriteJsonData(data, c, "s") result := self.client.RunQuery("select value from \"/blah ( ) ; : ! @ # $ \n \t,foo\\\"=bar/baz\"", c) c.Assert(result, HasLen, 1) c.Assert(result[0].Points, HasLen, 1) c.Assert(result[0].Name, Equals, "/blah ( ) ; : ! @ # $ \n \t,foo\"=bar/baz") } // For issue #466 - allow all characters in column names - https://github.com/influxdb/influxdb/issues/267 func (self *DataTestSuite) TestColumnNameWithWeirdCharacters(c *C) { data := `[ { "name": "foo", "columns": ["baz.-239(*@&#$!#)(* #$@"], "points": [[1]] } ]` self.client.WriteJsonData(data, c, "s") result := self.client.RunQuery(`select "baz.-239(*@&#$!#)(* #$@" from foo`, c) c.Assert(result, HasLen, 1) c.Assert(result[0].Points, HasLen, 1) c.Assert(result[0].Name, Equals, "foo") c.Assert(result[0].Columns, HasLen, 3) c.Assert(result[0].Columns[2], Equals, `baz.-239(*@&#$!#)(* #$@`) } // For issue #551 - add aggregate function top and bottom - https://github.com/influxdb/influxdb/issues/551 func (self *DataTestSuite) TestTop(c *C) { for i := 0; i < 3; i++ { self.client.WriteJsonData(fmt.Sprintf(` [ { "name": "test_top", "columns": ["cpu", "host"], "points": [[%d, "hosta"], [%d, "hostb"]] } ] `, 60+i*10, 70+i*10), c) } data := self.client.RunQuery("select top(cpu, 5) from test_top;", c, "m") c.Assert(data[0].Name, Equals, "test_top") c.Assert(data[0].Columns, HasLen, 2) c.Assert(data[0].Points, HasLen, 5) tops := []float64{} for _, point := range data[0].Points { tops = append(tops, point[1].(float64)) } c.Assert(tops, DeepEquals, []float64{90, 80, 80, 70, 70}) } func (self *DataTestSuite) TestTopWithStringColumn(c *C) { for i := 0; i < 3; i++ { self.client.WriteJsonData(fmt.Sprintf(` [ { "name": "test_top", "columns": ["cpu", "host"], "points": [[%d, "hosta"], [%d, "hostb"]] } ] `, 60+i*10, 70+i*10), c) } data := self.client.RunQuery("select top(host, 5) from test_top;", c, "m") c.Assert(data[0].Name, Equals, "test_top") c.Assert(data[0].Columns, HasLen, 2) c.Assert(data[0].Points, HasLen, 5) tops := []string{} for _, point := range data[0].Points { tops = append(tops, point[1].(string)) } c.Assert(tops, DeepEquals, []string{"hostb", "hostb", "hostb", "hosta", "hosta"}) } func (self *DataTestSuite) TestTopWithGroupBy(c *C) { for i := 0; i < 3; i++ { self.client.WriteJsonData(fmt.Sprintf(` [ { "name": "test_top", "columns": ["cpu", "host"], "points": [[%d, "hosta"], [%d, "hostb"]] } ] `, 60+i*10, 70+i*10), c) } data := self.client.RunQuery("select top(cpu, 2), host from test_top group by host;", c, "m") c.Assert(data[0].Name, Equals, "test_top") c.Assert(data[0].Columns, HasLen, 3) c.Assert(data[0].Points, HasLen, 4) type tmp struct { cpu float64 host string } tops := []tmp{} for _, point := range data[0].Points { tops = append(tops, tmp{point[1].(float64), point[2].(string)}) } c.Assert(tops, DeepEquals, []tmp{{80, "hosta"}, {70, "hosta"}, {90, "hostb"}, {80, "hostb"}}) } func (self *DataTestSuite) TestTopWithMultipleGroupBy(c *C) { for i := 0; i < 3; i++ { self.client.WriteJsonData(fmt.Sprintf(` [ { "name": "test_top", "columns": ["time", "cpu", "host"], "points": [[%d, %d, "hosta"], [%d, %d, "hostb"]] } ] `, 1400504400+i*60, 60+i*10, 1400504400+i*60, 70+i*10), c, "s") } data := self.client.RunQuery("select top(cpu, 2), host from test_top group by time(1d), host;", c, "m") c.Assert(data[0].Name, Equals, "test_top") c.Assert(data[0].Columns, HasLen, 3) type tmp struct { // TODO(chobie): add time column cpu float64 host string } tops := []tmp{} for _, point := range data[0].Points { tops = append(tops, tmp{point[1].(float64), point[2].(string)}) } c.Assert(tops, DeepEquals, []tmp{{80, "hosta"}, {70, "hosta"}, {90, "hostb"}, {80, "hostb"}}) } func (self *DataTestSuite) TestTopWithLessResult(c *C) { for i := 0; i < 5; i++ { self.client.WriteJsonData(fmt.Sprintf(` [ { "name": "test_top", "columns": ["cpu", "host"], "points": [[%d, "hosta"], [%d, "hostb"]] } ] `, 40+i*10, 50+i*10), c) } data := self.client.RunQuery("select top(cpu, 20) from test_top;", c, "m") c.Assert(data[0].Name, Equals, "test_top") c.Assert(data[0].Columns, HasLen, 2) // top collects result as possible c.Assert(data[0].Points, HasLen, 10) tops := []float64{} for _, point := range data[0].Points { tops = append(tops, point[1].(float64)) } c.Assert(tops, DeepEquals, []float64{90, 80, 80, 70, 70, 60, 60, 50, 50, 40}) } func (self *DataTestSuite) TestBottom(c *C) { for i := 0; i < 3; i++ { self.client.WriteJsonData(fmt.Sprintf(` [ { "name": "test_bottom", "columns": ["cpu", "host"], "points": [[%d, "hosta"], [%d, "hostb"]] } ] `, 60+i*10, 70+i*10), c) } data := self.client.RunQuery("select bottom(cpu, 5) from test_bottom;", c, "m") c.Assert(data[0].Name, Equals, "test_bottom") c.Assert(data[0].Columns, HasLen, 2) c.Assert(data[0].Points, HasLen, 5) tops := []float64{} for _, point := range data[0].Points { tops = append(tops, point[1].(float64)) } c.Assert(tops, DeepEquals, []float64{60, 70, 70, 80, 80}) } func (self *DataTestSuite) TestBottomWithStringColumn(c *C) { for i := 0; i < 3; i++ { self.client.WriteJsonData(fmt.Sprintf(` [ { "name": "test_bottom", "columns": ["cpu", "host"], "points": [[%d, "hosta"], [%d, "hostb"]] } ] `, 60+i*10, 70+i*10), c) } data := self.client.RunQuery("select bottom(host, 5) from test_bottom;", c, "m") c.Assert(data[0].Name, Equals, "test_bottom") c.Assert(data[0].Columns, HasLen, 2) c.Assert(data[0].Points, HasLen, 5) tops := []string{} for _, point := range data[0].Points { tops = append(tops, point[1].(string)) } c.Assert(tops, DeepEquals, []string{"hosta", "hosta", "hosta", "hostb", "hostb"}) } func (self *DataTestSuite) TestBottomWithGroupBy(c *C) { for i := 0; i < 3; i++ { self.client.WriteJsonData(fmt.Sprintf(` [ { "name": "test_bottom", "columns": ["cpu", "host"], "points": [[%d, "hosta"], [%d, "hostb"]] } ] `, 60+i*10, 70+i*10), c) } data := self.client.RunQuery("select bottom(cpu, 2), host from test_bottom group by host;", c, "m") c.Assert(data[0].Name, Equals, "test_bottom") c.Assert(data[0].Columns, HasLen, 3) type tmp struct { cpu float64 host string } tops := []tmp{} for _, point := range data[0].Points { tops = append(tops, tmp{point[1].(float64), point[2].(string)}) } c.Assert(tops, DeepEquals, []tmp{{60, "hosta"}, {70, "hosta"}, {70, "hostb"}, {80, "hostb"}}) } func (self *DataTestSuite) TestBottomWithLessResult(c *C) { for i := 0; i < 5; i++ { self.client.WriteJsonData(fmt.Sprintf(` [ { "name": "test_bottom", "columns": ["cpu", "host"], "points": [[%d, "hosta"], [%d, "hostb"]] } ] `, 40+i*10, 50+i*10), c) } data := self.client.RunQuery("select bottom(cpu, 20) from test_bottom;", c, "m") c.Assert(data[0].Name, Equals, "test_bottom") c.Assert(data[0].Columns, HasLen, 2) // bottom collects result as possible c.Assert(data[0].Points, HasLen, 10) bottoms := []float64{} for _, point := range data[0].Points { bottoms = append(bottoms, point[1].(float64)) } c.Assert(bottoms, DeepEquals, []float64{40, 50, 50, 60, 60, 70, 70, 80, 80, 90}) } func (self *DataTestSuite) TestBottomWithMultipleGroupBy(c *C) { for i := 0; i < 3; i++ { self.client.WriteJsonData(fmt.Sprintf(` [ { "name": "test_bottom", "columns": ["time", "cpu", "host"], "points": [[%d, %d, "hosta"], [%d, %d, "hostb"]] } ] `, 1400504400+i*60, 60+i*10, 1400504400+i*60, 70+i*10), c) } data := self.client.RunQuery("select bottom(cpu, 2), host from test_bottom group by time(1d), host;", c, "m") c.Assert(data[0].Name, Equals, "test_bottom") c.Assert(data[0].Columns, HasLen, 3) type tmp struct { // TODO(chobie): add time column cpu float64 host string } tops := []tmp{} for _, point := range data[0].Points { tops = append(tops, tmp{point[1].(float64), point[2].(string)}) } c.Assert(tops, DeepEquals, []tmp{{60, "hosta"}, {70, "hosta"}, {70, "hostb"}, {80, "hostb"}}) } // issue #557 func (self *DataTestSuite) TestGroupByYear(c *C) { data := `[{"points": [[4], [10], [5]], "name": "test_group_by_day", "columns": ["value"]}]` self.client.WriteJsonData(data, c) t := time.Now().Truncate(time.Hour).Add(-24 * 365 * time.Hour).Unix() data = fmt.Sprintf(`[{"points": [[2, %d]], "name": "test_group_by_day", "columns": ["value", "time"]}]`, t) self.client.WriteJsonData(data, c, "s") collection := self.client.RunQuery("select count(value) from test_group_by_day group by time(1y)", c) c.Assert(collection, HasLen, 1) maps := ToMap(collection[0]) c.Assert(maps, HasLen, 2) c.Assert(maps[0]["count"], Equals, 3.0) c.Assert(maps[1]["count"], Equals, 1.0) } // Issue #713 // Test various fill options func (self *DataTestSuite) TestMeanAggregateFillWithZero(c *C) { data := ` [ { "points": [ [1304378375, 10.0], [1304378380, 20.0], [1304378400, 60.0] ], "name": "test_fill_zero", "columns": ["time", "value"] } ]` self.client.WriteJsonData(data, c, influxdb.Second) queries := map[string]interface{}{ "select mean(value) from test_fill_zero group by time(10s)": math.Inf(1), "select mean(value) from test_fill_zero group by time(10s) fill(0)": 0.0, "select mean(value) from test_fill_zero group by time(10s) fill(-42)": -42.0, "select mean(value) from test_fill_zero group by time(10s) fill(42)": 42.0, "select mean(value) from test_fill_zero group by time(10s) fill(null)": nil, } for query, expectedValue := range queries { serieses := self.client.RunQuery(query, c) c.Assert(serieses, HasLen, 1) maps := ToMap(serieses[0]) c.Assert(maps[0], DeepEquals, map[string]interface{}{"time": 1304378400000.0, "mean": 60.0}) v, ok := expectedValue.(float64) // we assign math.Inf for the no fill() case if ok && math.IsInf(v, 1) { c.Assert(maps[1], DeepEquals, map[string]interface{}{"time": 1304378380000.0, "mean": 20.0}) c.Assert(maps[2], DeepEquals, map[string]interface{}{"time": 1304378370000.0, "mean": 10.0}) continue } c.Assert(maps[1], DeepEquals, map[string]interface{}{"time": 1304378390000.0, "mean": expectedValue}) c.Assert(maps[2], DeepEquals, map[string]interface{}{"time": 1304378380000.0, "mean": 20.0}) c.Assert(maps[3], DeepEquals, map[string]interface{}{"time": 1304378370000.0, "mean": 10.0}) } } // issue #669 func HistogramHelper(c *C, client Client, query string, expected map[float64]float64) { //Test basic histogram collection := client.RunQuery(query, c) c.Assert(collection, HasLen, 1) maps := ToMap(collection[0]) actual := make(map[float64]float64, len(maps)) for key := range maps { c.Logf(fmt.Sprintf(`%d: bucket_start: %f count: %f`, key, maps[key]["bucket_start"], maps[key]["count"])) actual[maps[key]["bucket_start"].(float64)] = maps[key]["count"].(float64) } c.Assert(actual, HasLen, len(expected)) for bucket, count := range expected { c.Assert(actual[bucket], Equals, count) } } func (self *DataTestSuite) TestHistogram(c *C) { c.Logf("Running Histogram test") data := `[{"points": [[-3], [-2], [-1], [0], [1], [2], [3]], "name": "test_histogram", "columns": ["value"]}]` self.client.WriteJsonData(data, c) //Test basic histogram expected := make(map[float64]float64, 7) expected[-3.0] = 1.0 expected[-2.0] = 1.0 expected[-1.0] = 1.0 expected[0.0] = 1.0 expected[1.0] = 1.0 expected[2.0] = 1.0 expected[3.0] = 1.0 HistogramHelper(c, self.client, "select Histogram(value, 1.0) from test_histogram", expected) // Test specifying start and stop HistogramHelper(c, self.client, "select Histogram(value, 1.0, -3, 3) from test_histogram", expected) // Test specifying start and stop outside domain of data expected = make(map[float64]float64, 21) expected[-10.0] = 0.0 expected[-9.0] = 0.0 expected[-8.0] = 0.0 expected[-7.0] = 0.0 expected[-6.0] = 0.0 expected[-5.0] = 0.0 expected[-4.0] = 0.0 expected[-3.0] = 1.0 expected[-2.0] = 1.0 expected[-1.0] = 1.0 expected[0.0] = 1.0 expected[1.0] = 1.0 expected[2.0] = 1.0 expected[3.0] = 1.0 expected[4.0] = 0.0 expected[5.0] = 0.0 expected[6.0] = 0.0 expected[7.0] = 0.0 expected[8.0] = 0.0 expected[9.0] = 0.0 expected[10.0] = 0.0 HistogramHelper(c, self.client, "select Histogram(value, 1.0, -10, 10) from test_histogram", expected) // Test specifying start and stop inside domain of data expected = make(map[float64]float64, 2) expected[-1.0] = 1.0 expected[0.0] = 1.0 HistogramHelper(c, self.client, "select Histogram(value, 1.0, -1, 0) from test_histogram", expected) // Test specifying step and start that don't align with 0 expected = make(map[float64]float64, 4) expected[-3.0] = 2.0 expected[-1.0] = 2.0 expected[1.0] = 2.0 expected[3.0] = 1.0 HistogramHelper(c, self.client, "select Histogram(value, 2.0, -3) from test_histogram", expected) HistogramHelper(c, self.client, "select Histogram(value, 2.0, -3, 3) from test_histogram", expected) // Test specifying step, start and stop that don't align with 0 inside the domain expected = make(map[float64]float64, 3) expected[-3.0] = 2.0 expected[-1.0] = 2.0 expected[1.0] = 2.0 HistogramHelper(c, self.client, "select Histogram(value, 2.0, -3, 1) from test_histogram", expected) // Test specifying step and start that don't align with stop expected = make(map[float64]float64, 2) expected[-1.0] = 2.0 expected[1.0] = 2.0 HistogramHelper(c, self.client, "select Histogram(value, 2.0, -1, 2) from test_histogram", expected) } // code that's common to many of the folling Test*AggregateFillWith* tests func (self *DataTestSuite) tstAggregateFill(aggregate, fill string, aggArgs []interface{}, expVals []interface{}, c *C) { data := ` [ { "points": [ [300000, 30.0], [120000, 20.0], [60000, 10.0] ], "name": "data", "columns": ["time", "value"] } ]` self.client.WriteJsonData(data, c, influxdb.Millisecond) series := self.client.RunQuery(fmtFillQuery(aggregate, aggArgs, "data", fill), c) c.Assert(len(series), Equals, 1) maps := ToMap(series[0]) c.Assert(len(maps), Equals, len(expVals)) fmt.Println(maps) c.Assert(maps[0], DeepEquals, map[string]interface{}{"time": 300000.0, aggregate: expVals[0]}) c.Assert(maps[1], DeepEquals, map[string]interface{}{"time": 240000.0, aggregate: expVals[1]}) c.Assert(maps[2], DeepEquals, map[string]interface{}{"time": 180000.0, aggregate: expVals[2]}) c.Assert(maps[3], DeepEquals, map[string]interface{}{"time": 120000.0, aggregate: expVals[3]}) c.Assert(maps[4], DeepEquals, map[string]interface{}{"time": 60000.0, aggregate: expVals[4]}) } func fmtFillQuery(aggregate string, aggArgs []interface{}, series, fill string) string { args := "value" for _, arg := range aggArgs { args = fmt.Sprintf("%s, %v", args, arg) } return fmt.Sprintf("select %s(%s) from %s group by time(60s) fill(%s) where time > 60s and time < 320s", aggregate, args, series, fill) } var emptyAggArgs []interface{} // count aggregate filling with null func (self *DataTestSuite) TestCountAggregateFillWithNull(c *C) { self.tstAggregateFill("count", "null", emptyAggArgs, []interface{}{1.0, nil, nil, 1.0, 1.0}, c) } // count aggregate filling with 0 func (self *DataTestSuite) TestCountAggregateFillWith0(c *C) { self.tstAggregateFill("count", "0", emptyAggArgs, []interface{}{1.0, 0.0, 0.0, 1.0, 1.0}, c) } // min aggregate filling with null func (self *DataTestSuite) TestMinAggregateFillWithNull(c *C) { self.tstAggregateFill("min", "null", emptyAggArgs, []interface{}{30.0, nil, nil, 20.0, 10.0}, c) } // min aggregate filling with 0 func (self *DataTestSuite) TestMinAggregateFillWith0(c *C) { self.tstAggregateFill("min", "0", emptyAggArgs, []interface{}{30.0, 0.0, 0.0, 20.0, 10.0}, c) } // max aggregate filling with null func (self *DataTestSuite) TestMaxAggregateFillWithNull(c *C) { self.tstAggregateFill("max", "null", emptyAggArgs, []interface{}{30.0, nil, nil, 20.0, 10.0}, c) } // max aggregate filling with 0 func (self *DataTestSuite) TestMaxAggregateFillWith0(c *C) { self.tstAggregateFill("max", "0", emptyAggArgs, []interface{}{30.0, 0.0, 0.0, 20.0, 10.0}, c) } // mode aggregate filling with null func (self *DataTestSuite) TestModeAggregateFillWithNull(c *C) { self.tstAggregateFill("mode", "null", emptyAggArgs, []interface{}{30.0, nil, nil, 20.0, 10.0}, c) } // mode aggregate filling with 0 func (self *DataTestSuite) TestModeAggregateFillWith0(c *C) { self.tstAggregateFill("mode", "0", emptyAggArgs, []interface{}{30.0, 0.0, 0.0, 20.0, 10.0}, c) } // median aggregate filling with null func (self *DataTestSuite) TestMedianAggregateFillWithNull(c *C) { self.tstAggregateFill("median", "null", emptyAggArgs, []interface{}{30.0, nil, nil, 20.0, 10.0}, c) } // median aggregate filling with 0 func (self *DataTestSuite) TestMedianAggregateFillWith0(c *C) { self.tstAggregateFill("median", "0", emptyAggArgs, []interface{}{30.0, 0.0, 0.0, 20.0, 10.0}, c) } // distinct aggregate filling with null func (self *DataTestSuite) TestDistinctAggregateFillWithNull(c *C) { self.tstAggregateFill("distinct", "null", emptyAggArgs, []interface{}{30.0, nil, nil, 20.0, 10.0}, c) } // distinct aggregate filling with 0 func (self *DataTestSuite) TestDistinctAggregateFillWith0(c *C) { self.tstAggregateFill("distinct", "0", emptyAggArgs, []interface{}{30.0, 0.0, 0.0, 20.0, 10.0}, c) } // percentile aggregate filling with null func (self *DataTestSuite) TestPercentileAggregateFillWithNull(c *C) { self.tstAggregateFill("percentile", "null", []interface{}{10}, []interface{}{0.0, nil, nil, 0.0, 0.0}, c) } // percentile aggregate filling with 0 func (self *DataTestSuite) TestPercentileAggregateFillWith0(c *C) { self.tstAggregateFill("percentile", "0", []interface{}{10}, []interface{}{0.0, 0.0, 0.0, 0.0, 0.0}, c) } // sum aggregate filling with null func (self *DataTestSuite) TestSumAggregateFillWithNull(c *C) { self.tstAggregateFill("sum", "null", emptyAggArgs, []interface{}{30.0, nil, nil, 20.0, 10.0}, c) } // sum aggregate filling with 0 func (self *DataTestSuite) TestSumAggregateFillWith0(c *C) { self.tstAggregateFill("sum", "0", emptyAggArgs, []interface{}{30.0, 0.0, 0.0, 20.0, 10.0}, c) } // stddev aggregate filling with null func (self *DataTestSuite) TestStddevAggregateFillWithNull(c *C) { self.tstAggregateFill("stddev", "null", emptyAggArgs, []interface{}{0.0, nil, nil, 0.0, 0.0}, c) } // stddev aggregate filling with 0 func (self *DataTestSuite) TestStddevAggregateFillWith0(c *C) { self.tstAggregateFill("stddev", "0", emptyAggArgs, []interface{}{0.0, 0.0, 0.0, 0.0, 0.0}, c) } // first aggregate filling with null func (self *DataTestSuite) TestFirstAggregateFillWithNull(c *C) { self.tstAggregateFill("first", "null", emptyAggArgs, []interface{}{30.0, nil, nil, 20.0, 10.0}, c) } // first aggregate filling with 0 func (self *DataTestSuite) TestFirstAggregateFillWith0(c *C) { self.tstAggregateFill("first", "0", emptyAggArgs, []interface{}{30.0, 0.0, 0.0, 20.0, 10.0}, c) } // last aggregate filling with null func (self *DataTestSuite) TestLastAggregateFillWithNull(c *C) { self.tstAggregateFill("last", "null", emptyAggArgs, []interface{}{30.0, nil, nil, 20.0, 10.0}, c) } // last aggregate filling with 0 func (self *DataTestSuite) TestLastAggregateFillWith0(c *C) { self.tstAggregateFill("last", "0", emptyAggArgs, []interface{}{30.0, 0.0, 0.0, 20.0, 10.0}, c) } // top 1 aggregate filling with null func (self *DataTestSuite) TestTop1AggregateFillWithNull(c *C) { self.tstAggregateFill("top", "null", []interface{}{1}, []interface{}{30.0, nil, nil, 20.0, 10.0}, c) } // top 1 aggregate filling with 0 func (self *DataTestSuite) TestTop1AggregateFillWith0(c *C) { self.tstAggregateFill("top", "0", []interface{}{1}, []interface{}{30.0, 0.0, 0.0, 20.0, 10.0}, c) } // top 10 aggregate filling with null func (self *DataTestSuite) TestTop10AggregateFillWithNull(c *C) { self.tstAggregateFill("top", "null", []interface{}{10}, []interface{}{30.0, nil, nil, 20.0, 10.0}, c) } // top 10 aggregate filling with 0 func (self *DataTestSuite) TestTop10AggregateFillWith0(c *C) { self.tstAggregateFill("top", "0", []interface{}{10}, []interface{}{30.0, 0.0, 0.0, 20.0, 10.0}, c) } // bottom 1 aggregate filling with null func (self *DataTestSuite) TestBottom1AggregateFillWithNull(c *C) { self.tstAggregateFill("bottom", "null", []interface{}{1}, []interface{}{30.0, nil, nil, 20.0, 10.0}, c) } // bottom 1 aggregate filling with 0 func (self *DataTestSuite) TestBottom1AggregateFillWith0(c *C) { self.tstAggregateFill("bottom", "0", []interface{}{1}, []interface{}{30.0, 0.0, 0.0, 20.0, 10.0}, c) } // bottom 10 aggregate filling with null func (self *DataTestSuite) TestBottom10AggregateFillWithNull(c *C) { self.tstAggregateFill("bottom", "null", []interface{}{10}, []interface{}{30.0, nil, nil, 20.0, 10.0}, c) } // bottom 10 aggregate filling with 0 func (self *DataTestSuite) TestBottom10AggregateFillWith0(c *C) { self.tstAggregateFill("bottom", "0", []interface{}{10}, []interface{}{30.0, 0.0, 0.0, 20.0, 10.0}, c) } var testData = ` [ { "points": [ [300000, 30.0], [120000, 20.0], [60000, 10.0], [310000, 15.0] ], "name": "data", "columns": ["time", "value"] } ]` func (self *DataTestSuite) tstAggregateFill2(aggregate, fill string, aggArgs []interface{}, expVals []interface{}, c *C) { self.client.WriteJsonData(testData, c, influxdb.Millisecond) series := self.client.RunQuery(fmtFillQuery(aggregate, aggArgs, "data", fill), c) c.Assert(len(series), Equals, 1) maps := ToMap(series[0]) c.Assert(maps[0], DeepEquals, map[string]interface{}{"time": 300000.0, aggregate: expVals[0]}) c.Assert(maps[1], DeepEquals, map[string]interface{}{"time": 240000.0, aggregate: expVals[1]}) c.Assert(maps[2], DeepEquals, map[string]interface{}{"time": 180000.0, aggregate: expVals[2]}) } // derivative aggregate filling with null func (self *DataTestSuite) TestDerivativeAggregateFillWithNull(c *C) { self.tstAggregateFill2("derivative", "null", emptyAggArgs, []interface{}{-1.5, nil, nil}, c) } // derivative aggregate filling with 0 func (self *DataTestSuite) TestDerivativeAggregateFillWith0(c *C) { self.tstAggregateFill2("derivative", "0", emptyAggArgs, []interface{}{-1.5, 0.0, 0.0}, c) } // difference aggregate filling with null func (self *DataTestSuite) TestDifferenceAggregateFillWithNull(c *C) { self.tstAggregateFill2("difference", "null", emptyAggArgs, []interface{}{15.0, nil, nil}, c) } // difference aggregate filling with 0 func (self *DataTestSuite) TestDifferenceAggregateFillWith0(c *C) { self.tstAggregateFill2("difference", "0", emptyAggArgs, []interface{}{15.0, 0.0, 0.0}, c) } // histogram aggregate filling with null func (self *DataTestSuite) TestHistogramAggregateFillWithNull(c *C) { self.client.WriteJsonData(testData, c, influxdb.Millisecond) series := self.client.RunQuery(fmtFillQuery("histogram", []interface{}{}, "data", "null"), c) c.Assert(len(series), Equals, 1) maps := ToMap(series[0]) c.Assert(len(maps), Equals, 6) // FIXME: Can't test return values because the order of the returned data is randomized. // Add some asserts here once engine/aggregator_operators.go // func(self *HistogramAggregator) GetValues(...) is modified to sort data. } // histogram aggregate filling with 0 func (self *DataTestSuite) TestHistogramAggregateFillWith0(c *C) { self.client.WriteJsonData(testData, c, influxdb.Millisecond) series := self.client.RunQuery(fmtFillQuery("histogram", []interface{}{}, "data", "0"), c) c.Assert(len(series), Equals, 1) maps := ToMap(series[0]) c.Assert(len(maps), Equals, 6) // FIXME: Can't test return values because the order of the returned data is randomized. // Add some asserts here once engine/aggregator_operators.go // func(self *HistogramAggregator) GetValues(...) is modified to sort data. }