tsdb_test.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. package tsdb
  2. import (
  3. "testing"
  4. "time"
  5. . "github.com/smartystreets/goconvey/convey"
  6. )
  7. func TestMetricQuery(t *testing.T) {
  8. Convey("When batches groups for query", t, func() {
  9. Convey("Given 3 queries for 2 data sources", func() {
  10. request := &Request{
  11. Queries: QuerySlice{
  12. {RefId: "A", Query: "asd", DataSource: &DataSourceInfo{Id: 1}},
  13. {RefId: "B", Query: "asd", DataSource: &DataSourceInfo{Id: 1}},
  14. {RefId: "C", Query: "asd", DataSource: &DataSourceInfo{Id: 2}},
  15. },
  16. }
  17. batches, err := getBatches(request)
  18. So(err, ShouldBeNil)
  19. Convey("Should group into two batches", func() {
  20. So(len(batches), ShouldEqual, 2)
  21. })
  22. })
  23. Convey("Given query 2 depends on query 1", func() {
  24. request := &Request{
  25. Queries: QuerySlice{
  26. {RefId: "A", Query: "asd", DataSource: &DataSourceInfo{Id: 1}},
  27. {RefId: "B", Query: "asd", DataSource: &DataSourceInfo{Id: 2}},
  28. {RefId: "C", Query: "#A / #B", DataSource: &DataSourceInfo{Id: 3}, Depends: []string{"A", "B"}},
  29. },
  30. }
  31. batches, err := getBatches(request)
  32. So(err, ShouldBeNil)
  33. Convey("Should return three batch groups", func() {
  34. So(len(batches), ShouldEqual, 3)
  35. })
  36. Convey("Group 3 should have group 1 and 2 as dependencies", func() {
  37. So(batches[2].Depends["A"], ShouldEqual, true)
  38. So(batches[2].Depends["B"], ShouldEqual, true)
  39. })
  40. })
  41. })
  42. Convey("When executing request with one query", t, func() {
  43. req := &Request{
  44. Queries: QuerySlice{
  45. {RefId: "A", Query: "asd", DataSource: &DataSourceInfo{Id: 1, PluginId: "test"}},
  46. },
  47. }
  48. fakeExecutor := registerFakeExecutor()
  49. fakeExecutor.Return("A", TimeSeriesSlice{&TimeSeries{Name: "argh"}})
  50. res, err := HandleRequest(req)
  51. So(err, ShouldBeNil)
  52. Convey("Should return query results", func() {
  53. So(res.Results["A"].Series, ShouldNotBeEmpty)
  54. So(res.Results["A"].Series[0].Name, ShouldEqual, "argh")
  55. })
  56. })
  57. Convey("When executing one request with two queries from same data source", t, func() {
  58. req := &Request{
  59. Queries: QuerySlice{
  60. {RefId: "A", Query: "asd", DataSource: &DataSourceInfo{Id: 1, PluginId: "test"}},
  61. {RefId: "B", Query: "asd", DataSource: &DataSourceInfo{Id: 1, PluginId: "test"}},
  62. },
  63. }
  64. fakeExecutor := registerFakeExecutor()
  65. fakeExecutor.Return("A", TimeSeriesSlice{&TimeSeries{Name: "argh"}})
  66. fakeExecutor.Return("B", TimeSeriesSlice{&TimeSeries{Name: "barg"}})
  67. res, err := HandleRequest(req)
  68. So(err, ShouldBeNil)
  69. Convey("Should return query results", func() {
  70. So(len(res.Results), ShouldEqual, 2)
  71. So(res.Results["B"].Series[0].Name, ShouldEqual, "barg")
  72. })
  73. Convey("Should have been batched in one request", func() {
  74. So(len(res.BatchTimings), ShouldEqual, 1)
  75. })
  76. })
  77. Convey("When executing one request with three queries from different datasources", t, func() {
  78. req := &Request{
  79. Queries: QuerySlice{
  80. {RefId: "A", Query: "asd", DataSource: &DataSourceInfo{Id: 1, PluginId: "test"}},
  81. {RefId: "B", Query: "asd", DataSource: &DataSourceInfo{Id: 1, PluginId: "test"}},
  82. {RefId: "C", Query: "asd", DataSource: &DataSourceInfo{Id: 2, PluginId: "test"}},
  83. },
  84. }
  85. res, err := HandleRequest(req)
  86. So(err, ShouldBeNil)
  87. Convey("Should have been batched in two requests", func() {
  88. So(len(res.BatchTimings), ShouldEqual, 2)
  89. })
  90. })
  91. Convey("When query uses data source of unknown type", t, func() {
  92. req := &Request{
  93. Queries: QuerySlice{
  94. {RefId: "A", Query: "asd", DataSource: &DataSourceInfo{Id: 1, PluginId: "asdasdas"}},
  95. },
  96. }
  97. _, err := HandleRequest(req)
  98. So(err, ShouldNotBeNil)
  99. })
  100. Convey("When executing request that depend on other query", t, func() {
  101. req := &Request{
  102. Queries: QuerySlice{
  103. {
  104. RefId: "A", Query: "asd", DataSource: &DataSourceInfo{Id: 1, PluginId: "test"},
  105. },
  106. {
  107. RefId: "B", Query: "#A / 2", DataSource: &DataSourceInfo{Id: 2, PluginId: "test"}, Depends: []string{"A"},
  108. },
  109. },
  110. }
  111. fakeExecutor := registerFakeExecutor()
  112. fakeExecutor.HandleQuery("A", func(c *QueryContext) *QueryResult {
  113. time.Sleep(10 * time.Millisecond)
  114. return &QueryResult{
  115. Series: TimeSeriesSlice{
  116. &TimeSeries{Name: "Ares"},
  117. }}
  118. })
  119. fakeExecutor.HandleQuery("B", func(c *QueryContext) *QueryResult {
  120. return &QueryResult{
  121. Series: TimeSeriesSlice{
  122. &TimeSeries{Name: "Bres+" + c.Results["A"].Series[0].Name},
  123. }}
  124. })
  125. res, err := HandleRequest(req)
  126. So(err, ShouldBeNil)
  127. Convey("Should have been batched in two requests", func() {
  128. So(len(res.BatchTimings), ShouldEqual, 2)
  129. })
  130. Convey("Query B should have access to Query A results", func() {
  131. So(res.Results["B"].Series[0].Name, ShouldEqual, "Bres+Ares")
  132. })
  133. })
  134. }
  135. func registerFakeExecutor() *FakeExecutor {
  136. executor := NewFakeExecutor(nil)
  137. RegisterExecutor("test", func(dsInfo *DataSourceInfo) Executor {
  138. return executor
  139. })
  140. return executor
  141. }