| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473 |
- package es
- import (
- "encoding/json"
- "testing"
- "time"
- "github.com/grafana/grafana/pkg/components/simplejson"
- "github.com/grafana/grafana/pkg/tsdb"
- . "github.com/smartystreets/goconvey/convey"
- )
- func TestSearchRequest(t *testing.T) {
- Convey("Test elasticsearch search request", t, func() {
- timeField := "@timestamp"
- Convey("Given new search request builder for es version 5", func() {
- b := NewSearchRequestBuilder(5, tsdb.Interval{Value: 15 * time.Second, Text: "15s"})
- Convey("When building search request", func() {
- sr, err := b.Build()
- So(err, ShouldBeNil)
- Convey("Should have size of zero", func() {
- So(sr.Size, ShouldEqual, 0)
- })
- Convey("Should have no sorting", func() {
- So(sr.Sort, ShouldHaveLength, 0)
- })
- Convey("When marshal to JSON should generate correct json", func() {
- body, err := json.Marshal(sr)
- So(err, ShouldBeNil)
- json, err := simplejson.NewJson(body)
- So(err, ShouldBeNil)
- So(json.Get("size").MustInt(500), ShouldEqual, 0)
- So(json.Get("sort").Interface(), ShouldBeNil)
- So(json.Get("aggs").Interface(), ShouldBeNil)
- So(json.Get("query").Interface(), ShouldBeNil)
- })
- })
- Convey("When adding size, sort, filters", func() {
- b.Size(200)
- b.SortDesc(timeField, "boolean")
- filters := b.Query().Bool().Filter()
- filters.AddDateRangeFilter(timeField, "$timeTo", "$timeFrom", DateFormatEpochMS)
- filters.AddQueryStringFilter("test", true)
- Convey("When building search request", func() {
- sr, err := b.Build()
- So(err, ShouldBeNil)
- Convey("Should have correct size", func() {
- So(sr.Size, ShouldEqual, 200)
- })
- Convey("Should have correct sorting", func() {
- sort, ok := sr.Sort[timeField].(map[string]string)
- So(ok, ShouldBeTrue)
- So(sort["order"], ShouldEqual, "desc")
- So(sort["unmapped_type"], ShouldEqual, "boolean")
- })
- Convey("Should have range filter", func() {
- f, ok := sr.Query.Bool.Filters[0].(*RangeFilter)
- So(ok, ShouldBeTrue)
- So(f.Gte, ShouldEqual, "$timeFrom")
- So(f.Lte, ShouldEqual, "$timeTo")
- So(f.Format, ShouldEqual, "epoch_millis")
- })
- Convey("Should have query string filter", func() {
- f, ok := sr.Query.Bool.Filters[1].(*QueryStringFilter)
- So(ok, ShouldBeTrue)
- So(f.Query, ShouldEqual, "test")
- So(f.AnalyzeWildcard, ShouldBeTrue)
- })
- Convey("When marshal to JSON should generate correct json", func() {
- body, err := json.Marshal(sr)
- So(err, ShouldBeNil)
- json, err := simplejson.NewJson(body)
- So(err, ShouldBeNil)
- So(json.Get("size").MustInt(0), ShouldEqual, 200)
- sort := json.GetPath("sort", timeField)
- So(sort.Get("order").MustString(), ShouldEqual, "desc")
- So(sort.Get("unmapped_type").MustString(), ShouldEqual, "boolean")
- timeRangeFilter := json.GetPath("query", "bool", "filter").GetIndex(0).Get("range").Get(timeField)
- So(timeRangeFilter.Get("gte").MustString(""), ShouldEqual, "$timeFrom")
- So(timeRangeFilter.Get("lte").MustString(""), ShouldEqual, "$timeTo")
- So(timeRangeFilter.Get("format").MustString(""), ShouldEqual, DateFormatEpochMS)
- queryStringFilter := json.GetPath("query", "bool", "filter").GetIndex(1).Get("query_string")
- So(queryStringFilter.Get("analyze_wildcard").MustBool(false), ShouldEqual, true)
- So(queryStringFilter.Get("query").MustString(""), ShouldEqual, "test")
- })
- })
- })
- Convey("When adding doc value field", func() {
- b.AddDocValueField(timeField)
- Convey("should set correct props", func() {
- So(b.customProps["fields"], ShouldBeNil)
- scriptFields, ok := b.customProps["script_fields"].(map[string]interface{})
- So(ok, ShouldBeTrue)
- So(scriptFields, ShouldHaveLength, 0)
- docValueFields, ok := b.customProps["docvalue_fields"].([]string)
- So(ok, ShouldBeTrue)
- So(docValueFields, ShouldHaveLength, 1)
- So(docValueFields[0], ShouldEqual, timeField)
- })
- Convey("When building search request", func() {
- sr, err := b.Build()
- So(err, ShouldBeNil)
- Convey("When marshal to JSON should generate correct json", func() {
- body, err := json.Marshal(sr)
- So(err, ShouldBeNil)
- json, err := simplejson.NewJson(body)
- So(err, ShouldBeNil)
- scriptFields, err := json.Get("script_fields").Map()
- So(err, ShouldBeNil)
- So(scriptFields, ShouldHaveLength, 0)
- _, err = json.Get("fields").StringArray()
- So(err, ShouldNotBeNil)
- docValueFields, err := json.Get("docvalue_fields").StringArray()
- So(err, ShouldBeNil)
- So(docValueFields, ShouldHaveLength, 1)
- So(docValueFields[0], ShouldEqual, timeField)
- })
- })
- })
- Convey("and adding multiple top level aggs", func() {
- aggBuilder := b.Agg()
- aggBuilder.Terms("1", "@hostname", nil)
- aggBuilder.DateHistogram("2", "@timestamp", nil)
- Convey("When building search request", func() {
- sr, err := b.Build()
- So(err, ShouldBeNil)
- Convey("Should have 2 top level aggs", func() {
- aggs := sr.Aggs
- So(aggs, ShouldHaveLength, 2)
- So(aggs[0].Key, ShouldEqual, "1")
- So(aggs[0].Aggregation.Type, ShouldEqual, "terms")
- So(aggs[1].Key, ShouldEqual, "2")
- So(aggs[1].Aggregation.Type, ShouldEqual, "date_histogram")
- })
- Convey("When marshal to JSON should generate correct json", func() {
- body, err := json.Marshal(sr)
- So(err, ShouldBeNil)
- json, err := simplejson.NewJson(body)
- So(err, ShouldBeNil)
- So(json.Get("aggs").MustMap(), ShouldHaveLength, 2)
- So(json.GetPath("aggs", "1", "terms", "field").MustString(), ShouldEqual, "@hostname")
- So(json.GetPath("aggs", "2", "date_histogram", "field").MustString(), ShouldEqual, "@timestamp")
- })
- })
- })
- Convey("and adding top level agg with child agg", func() {
- aggBuilder := b.Agg()
- aggBuilder.Terms("1", "@hostname", func(a *TermsAggregation, ib AggBuilder) {
- ib.DateHistogram("2", "@timestamp", nil)
- })
- Convey("When building search request", func() {
- sr, err := b.Build()
- So(err, ShouldBeNil)
- Convey("Should have 1 top level agg and one child agg", func() {
- aggs := sr.Aggs
- So(aggs, ShouldHaveLength, 1)
- topAgg := aggs[0]
- So(topAgg.Key, ShouldEqual, "1")
- So(topAgg.Aggregation.Type, ShouldEqual, "terms")
- So(topAgg.Aggregation.Aggs, ShouldHaveLength, 1)
- childAgg := aggs[0].Aggregation.Aggs[0]
- So(childAgg.Key, ShouldEqual, "2")
- So(childAgg.Aggregation.Type, ShouldEqual, "date_histogram")
- })
- Convey("When marshal to JSON should generate correct json", func() {
- body, err := json.Marshal(sr)
- So(err, ShouldBeNil)
- json, err := simplejson.NewJson(body)
- So(err, ShouldBeNil)
- So(json.Get("aggs").MustMap(), ShouldHaveLength, 1)
- firstLevelAgg := json.GetPath("aggs", "1")
- secondLevelAgg := firstLevelAgg.GetPath("aggs", "2")
- So(firstLevelAgg.GetPath("terms", "field").MustString(), ShouldEqual, "@hostname")
- So(secondLevelAgg.GetPath("date_histogram", "field").MustString(), ShouldEqual, "@timestamp")
- })
- })
- })
- Convey("and adding two top level aggs with child agg", func() {
- aggBuilder := b.Agg()
- aggBuilder.Histogram("1", "@hostname", func(a *HistogramAgg, ib AggBuilder) {
- ib.DateHistogram("2", "@timestamp", nil)
- })
- aggBuilder.Filters("3", func(a *FiltersAggregation, ib AggBuilder) {
- ib.Terms("4", "@test", nil)
- })
- Convey("When building search request", func() {
- sr, err := b.Build()
- So(err, ShouldBeNil)
- Convey("Should have 2 top level aggs with one child agg each", func() {
- aggs := sr.Aggs
- So(aggs, ShouldHaveLength, 2)
- topAggOne := aggs[0]
- So(topAggOne.Key, ShouldEqual, "1")
- So(topAggOne.Aggregation.Type, ShouldEqual, "histogram")
- So(topAggOne.Aggregation.Aggs, ShouldHaveLength, 1)
- topAggOnechildAgg := topAggOne.Aggregation.Aggs[0]
- So(topAggOnechildAgg.Key, ShouldEqual, "2")
- So(topAggOnechildAgg.Aggregation.Type, ShouldEqual, "date_histogram")
- topAggTwo := aggs[1]
- So(topAggTwo.Key, ShouldEqual, "3")
- So(topAggTwo.Aggregation.Type, ShouldEqual, "filters")
- So(topAggTwo.Aggregation.Aggs, ShouldHaveLength, 1)
- topAggTwochildAgg := topAggTwo.Aggregation.Aggs[0]
- So(topAggTwochildAgg.Key, ShouldEqual, "4")
- So(topAggTwochildAgg.Aggregation.Type, ShouldEqual, "terms")
- })
- Convey("When marshal to JSON should generate correct json", func() {
- body, err := json.Marshal(sr)
- So(err, ShouldBeNil)
- json, err := simplejson.NewJson(body)
- So(err, ShouldBeNil)
- topAggOne := json.GetPath("aggs", "1")
- So(topAggOne.GetPath("histogram", "field").MustString(), ShouldEqual, "@hostname")
- topAggOnechildAgg := topAggOne.GetPath("aggs", "2")
- So(topAggOnechildAgg.GetPath("date_histogram", "field").MustString(), ShouldEqual, "@timestamp")
- topAggTwo := json.GetPath("aggs", "3")
- topAggTwochildAgg := topAggTwo.GetPath("aggs", "4")
- So(topAggTwo.GetPath("filters").MustArray(), ShouldHaveLength, 0)
- So(topAggTwochildAgg.GetPath("terms", "field").MustString(), ShouldEqual, "@test")
- })
- })
- })
- Convey("and adding top level agg with child agg with child agg", func() {
- aggBuilder := b.Agg()
- aggBuilder.Terms("1", "@hostname", func(a *TermsAggregation, ib AggBuilder) {
- ib.Terms("2", "@app", func(a *TermsAggregation, ib AggBuilder) {
- ib.DateHistogram("3", "@timestamp", nil)
- })
- })
- Convey("When building search request", func() {
- sr, err := b.Build()
- So(err, ShouldBeNil)
- Convey("Should have 1 top level agg with one child having a child", func() {
- aggs := sr.Aggs
- So(aggs, ShouldHaveLength, 1)
- topAgg := aggs[0]
- So(topAgg.Key, ShouldEqual, "1")
- So(topAgg.Aggregation.Type, ShouldEqual, "terms")
- So(topAgg.Aggregation.Aggs, ShouldHaveLength, 1)
- childAgg := topAgg.Aggregation.Aggs[0]
- So(childAgg.Key, ShouldEqual, "2")
- So(childAgg.Aggregation.Type, ShouldEqual, "terms")
- childChildAgg := childAgg.Aggregation.Aggs[0]
- So(childChildAgg.Key, ShouldEqual, "3")
- So(childChildAgg.Aggregation.Type, ShouldEqual, "date_histogram")
- })
- Convey("When marshal to JSON should generate correct json", func() {
- body, err := json.Marshal(sr)
- So(err, ShouldBeNil)
- json, err := simplejson.NewJson(body)
- So(err, ShouldBeNil)
- topAgg := json.GetPath("aggs", "1")
- So(topAgg.GetPath("terms", "field").MustString(), ShouldEqual, "@hostname")
- childAgg := topAgg.GetPath("aggs", "2")
- So(childAgg.GetPath("terms", "field").MustString(), ShouldEqual, "@app")
- childChildAgg := childAgg.GetPath("aggs", "3")
- So(childChildAgg.GetPath("date_histogram", "field").MustString(), ShouldEqual, "@timestamp")
- })
- })
- })
- Convey("and adding bucket and metric aggs", func() {
- aggBuilder := b.Agg()
- aggBuilder.Terms("1", "@hostname", func(a *TermsAggregation, ib AggBuilder) {
- ib.Terms("2", "@app", func(a *TermsAggregation, ib AggBuilder) {
- ib.Metric("4", "avg", "@value", nil)
- ib.DateHistogram("3", "@timestamp", func(a *DateHistogramAgg, ib AggBuilder) {
- ib.Metric("4", "avg", "@value", nil)
- ib.Metric("5", "max", "@value", nil)
- })
- })
- })
- Convey("When building search request", func() {
- sr, err := b.Build()
- So(err, ShouldBeNil)
- Convey("Should have 1 top level agg with one child having a child", func() {
- aggs := sr.Aggs
- So(aggs, ShouldHaveLength, 1)
- topAgg := aggs[0]
- So(topAgg.Key, ShouldEqual, "1")
- So(topAgg.Aggregation.Type, ShouldEqual, "terms")
- So(topAgg.Aggregation.Aggs, ShouldHaveLength, 1)
- childAgg := topAgg.Aggregation.Aggs[0]
- So(childAgg.Key, ShouldEqual, "2")
- So(childAgg.Aggregation.Type, ShouldEqual, "terms")
- childChildOneAgg := childAgg.Aggregation.Aggs[0]
- So(childChildOneAgg.Key, ShouldEqual, "4")
- So(childChildOneAgg.Aggregation.Type, ShouldEqual, "avg")
- childChildTwoAgg := childAgg.Aggregation.Aggs[1]
- So(childChildTwoAgg.Key, ShouldEqual, "3")
- So(childChildTwoAgg.Aggregation.Type, ShouldEqual, "date_histogram")
- childChildTwoChildOneAgg := childChildTwoAgg.Aggregation.Aggs[0]
- So(childChildTwoChildOneAgg.Key, ShouldEqual, "4")
- So(childChildTwoChildOneAgg.Aggregation.Type, ShouldEqual, "avg")
- childChildTwoChildTwoAgg := childChildTwoAgg.Aggregation.Aggs[1]
- So(childChildTwoChildTwoAgg.Key, ShouldEqual, "5")
- So(childChildTwoChildTwoAgg.Aggregation.Type, ShouldEqual, "max")
- })
- Convey("When marshal to JSON should generate correct json", func() {
- body, err := json.Marshal(sr)
- So(err, ShouldBeNil)
- json, err := simplejson.NewJson(body)
- So(err, ShouldBeNil)
- termsAgg := json.GetPath("aggs", "1")
- So(termsAgg.GetPath("terms", "field").MustString(), ShouldEqual, "@hostname")
- termsAggTwo := termsAgg.GetPath("aggs", "2")
- So(termsAggTwo.GetPath("terms", "field").MustString(), ShouldEqual, "@app")
- termsAggTwoAvg := termsAggTwo.GetPath("aggs", "4")
- So(termsAggTwoAvg.GetPath("avg", "field").MustString(), ShouldEqual, "@value")
- dateHistAgg := termsAggTwo.GetPath("aggs", "3")
- So(dateHistAgg.GetPath("date_histogram", "field").MustString(), ShouldEqual, "@timestamp")
- avgAgg := dateHistAgg.GetPath("aggs", "4")
- So(avgAgg.GetPath("avg", "field").MustString(), ShouldEqual, "@value")
- maxAgg := dateHistAgg.GetPath("aggs", "5")
- So(maxAgg.GetPath("max", "field").MustString(), ShouldEqual, "@value")
- })
- })
- })
- })
- Convey("Given new search request builder for es version 2", func() {
- b := NewSearchRequestBuilder(2, tsdb.Interval{Value: 15 * time.Second, Text: "15s"})
- Convey("When adding doc value field", func() {
- b.AddDocValueField(timeField)
- Convey("should set correct props", func() {
- fields, ok := b.customProps["fields"].([]string)
- So(ok, ShouldBeTrue)
- So(fields, ShouldHaveLength, 2)
- So(fields[0], ShouldEqual, "*")
- So(fields[1], ShouldEqual, "_source")
- scriptFields, ok := b.customProps["script_fields"].(map[string]interface{})
- So(ok, ShouldBeTrue)
- So(scriptFields, ShouldHaveLength, 0)
- fieldDataFields, ok := b.customProps["fielddata_fields"].([]string)
- So(ok, ShouldBeTrue)
- So(fieldDataFields, ShouldHaveLength, 1)
- So(fieldDataFields[0], ShouldEqual, timeField)
- })
- Convey("When building search request", func() {
- sr, err := b.Build()
- So(err, ShouldBeNil)
- Convey("When marshal to JSON should generate correct json", func() {
- body, err := json.Marshal(sr)
- So(err, ShouldBeNil)
- json, err := simplejson.NewJson(body)
- So(err, ShouldBeNil)
- scriptFields, err := json.Get("script_fields").Map()
- So(err, ShouldBeNil)
- So(scriptFields, ShouldHaveLength, 0)
- fields, err := json.Get("fields").StringArray()
- So(err, ShouldBeNil)
- So(fields, ShouldHaveLength, 2)
- So(fields[0], ShouldEqual, "*")
- So(fields[1], ShouldEqual, "_source")
- fieldDataFields, err := json.Get("fielddata_fields").StringArray()
- So(err, ShouldBeNil)
- So(fieldDataFields, ShouldHaveLength, 1)
- So(fieldDataFields[0], ShouldEqual, timeField)
- })
- })
- })
- })
- })
- }
- func TestMultiSearchRequest(t *testing.T) {
- Convey("Test elasticsearch multi search request", t, func() {
- Convey("Given new multi search request builder", func() {
- b := NewMultiSearchRequestBuilder(0)
- Convey("When adding one search request", func() {
- b.Search(tsdb.Interval{Value: 15 * time.Second, Text: "15s"})
- Convey("When building search request should contain one search request", func() {
- mr, err := b.Build()
- So(err, ShouldBeNil)
- So(mr.Requests, ShouldHaveLength, 1)
- })
- })
- Convey("When adding two search requests", func() {
- b.Search(tsdb.Interval{Value: 15 * time.Second, Text: "15s"})
- b.Search(tsdb.Interval{Value: 15 * time.Second, Text: "15s"})
- Convey("When building search request should contain two search requests", func() {
- mr, err := b.Build()
- So(err, ShouldBeNil)
- So(mr.Requests, ShouldHaveLength, 2)
- })
- })
- })
- })
- }
|