sql_engine_test.go 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. package tsdb
  2. import (
  3. "testing"
  4. "time"
  5. "github.com/grafana/grafana/pkg/components/null"
  6. "github.com/grafana/grafana/pkg/components/simplejson"
  7. "github.com/grafana/grafana/pkg/models"
  8. . "github.com/smartystreets/goconvey/convey"
  9. )
  10. func TestSqlEngine(t *testing.T) {
  11. Convey("SqlEngine", t, func() {
  12. dt := time.Date(2018, 3, 14, 21, 20, 6, int(527345*time.Microsecond), time.UTC)
  13. earlyDt := time.Date(1970, 3, 14, 21, 20, 6, int(527345*time.Microsecond), time.UTC)
  14. Convey("Given a time range between 2018-04-12 00:00 and 2018-04-12 00:05", func() {
  15. from := time.Date(2018, 4, 12, 18, 0, 0, 0, time.UTC)
  16. to := from.Add(5 * time.Minute)
  17. timeRange := NewFakeTimeRange("5m", "now", to)
  18. query := &Query{DataSource: &models.DataSource{}, Model: simplejson.New()}
  19. Convey("interpolate $__interval", func() {
  20. sql, err := Interpolate(query, timeRange, "select $__interval ")
  21. So(err, ShouldBeNil)
  22. So(sql, ShouldEqual, "select 1m ")
  23. })
  24. Convey("interpolate $__interval in $__timeGroup", func() {
  25. sql, err := Interpolate(query, timeRange, "select $__timeGroupAlias(time,$__interval)")
  26. So(err, ShouldBeNil)
  27. So(sql, ShouldEqual, "select $__timeGroupAlias(time,1m)")
  28. })
  29. Convey("interpolate $__interval_ms", func() {
  30. sql, err := Interpolate(query, timeRange, "select $__interval_ms ")
  31. So(err, ShouldBeNil)
  32. So(sql, ShouldEqual, "select 60000 ")
  33. })
  34. })
  35. Convey("Given row values with time.Time as time columns", func() {
  36. var nilPointer *time.Time
  37. fixtures := make([]interface{}, 5)
  38. fixtures[0] = dt
  39. fixtures[1] = &dt
  40. fixtures[2] = earlyDt
  41. fixtures[3] = &earlyDt
  42. fixtures[4] = nilPointer
  43. for i := range fixtures {
  44. ConvertSqlTimeColumnToEpochMs(fixtures, i)
  45. }
  46. Convey("When converting them should return epoch time with millisecond precision ", func() {
  47. expected := float64(dt.UnixNano()) / float64(time.Millisecond)
  48. expectedEarly := float64(earlyDt.UnixNano()) / float64(time.Millisecond)
  49. So(fixtures[0].(float64), ShouldEqual, expected)
  50. So(fixtures[1].(float64), ShouldEqual, expected)
  51. So(fixtures[2].(float64), ShouldEqual, expectedEarly)
  52. So(fixtures[3].(float64), ShouldEqual, expectedEarly)
  53. So(fixtures[4], ShouldBeNil)
  54. })
  55. })
  56. Convey("Given row values with int64 as time columns", func() {
  57. tSeconds := dt.Unix()
  58. tMilliseconds := dt.UnixNano() / 1e6
  59. tNanoSeconds := dt.UnixNano()
  60. var nilPointer *int64
  61. fixtures := make([]interface{}, 7)
  62. fixtures[0] = tSeconds
  63. fixtures[1] = &tSeconds
  64. fixtures[2] = tMilliseconds
  65. fixtures[3] = &tMilliseconds
  66. fixtures[4] = tNanoSeconds
  67. fixtures[5] = &tNanoSeconds
  68. fixtures[6] = nilPointer
  69. for i := range fixtures {
  70. ConvertSqlTimeColumnToEpochMs(fixtures, i)
  71. }
  72. Convey("When converting them should return epoch time with millisecond precision ", func() {
  73. So(fixtures[0].(int64), ShouldEqual, tSeconds*1e3)
  74. So(fixtures[1].(int64), ShouldEqual, tSeconds*1e3)
  75. So(fixtures[2].(int64), ShouldEqual, tMilliseconds)
  76. So(fixtures[3].(int64), ShouldEqual, tMilliseconds)
  77. So(fixtures[4].(int64), ShouldEqual, tMilliseconds)
  78. So(fixtures[5].(int64), ShouldEqual, tMilliseconds)
  79. So(fixtures[6], ShouldBeNil)
  80. })
  81. })
  82. Convey("Given row values with uin64 as time columns", func() {
  83. tSeconds := uint64(dt.Unix())
  84. tMilliseconds := uint64(dt.UnixNano() / 1e6)
  85. tNanoSeconds := uint64(dt.UnixNano())
  86. var nilPointer *uint64
  87. fixtures := make([]interface{}, 7)
  88. fixtures[0] = tSeconds
  89. fixtures[1] = &tSeconds
  90. fixtures[2] = tMilliseconds
  91. fixtures[3] = &tMilliseconds
  92. fixtures[4] = tNanoSeconds
  93. fixtures[5] = &tNanoSeconds
  94. fixtures[6] = nilPointer
  95. for i := range fixtures {
  96. ConvertSqlTimeColumnToEpochMs(fixtures, i)
  97. }
  98. Convey("When converting them should return epoch time with millisecond precision ", func() {
  99. So(fixtures[0].(int64), ShouldEqual, tSeconds*1e3)
  100. So(fixtures[1].(int64), ShouldEqual, tSeconds*1e3)
  101. So(fixtures[2].(int64), ShouldEqual, tMilliseconds)
  102. So(fixtures[3].(int64), ShouldEqual, tMilliseconds)
  103. So(fixtures[4].(int64), ShouldEqual, tMilliseconds)
  104. So(fixtures[5].(int64), ShouldEqual, tMilliseconds)
  105. So(fixtures[6], ShouldBeNil)
  106. })
  107. })
  108. Convey("Given row values with int32 as time columns", func() {
  109. tSeconds := int32(dt.Unix())
  110. var nilInt *int32
  111. fixtures := make([]interface{}, 3)
  112. fixtures[0] = tSeconds
  113. fixtures[1] = &tSeconds
  114. fixtures[2] = nilInt
  115. for i := range fixtures {
  116. ConvertSqlTimeColumnToEpochMs(fixtures, i)
  117. }
  118. Convey("When converting them should return epoch time with millisecond precision ", func() {
  119. So(fixtures[0].(int64), ShouldEqual, dt.Unix()*1e3)
  120. So(fixtures[1].(int64), ShouldEqual, dt.Unix()*1e3)
  121. So(fixtures[2], ShouldBeNil)
  122. })
  123. })
  124. Convey("Given row values with uint32 as time columns", func() {
  125. tSeconds := uint32(dt.Unix())
  126. var nilInt *uint32
  127. fixtures := make([]interface{}, 3)
  128. fixtures[0] = tSeconds
  129. fixtures[1] = &tSeconds
  130. fixtures[2] = nilInt
  131. for i := range fixtures {
  132. ConvertSqlTimeColumnToEpochMs(fixtures, i)
  133. }
  134. Convey("When converting them should return epoch time with millisecond precision ", func() {
  135. So(fixtures[0].(int64), ShouldEqual, dt.Unix()*1e3)
  136. So(fixtures[1].(int64), ShouldEqual, dt.Unix()*1e3)
  137. So(fixtures[2], ShouldBeNil)
  138. })
  139. })
  140. Convey("Given row values with float64 as time columns", func() {
  141. tSeconds := float64(dt.UnixNano()) / float64(time.Second)
  142. tMilliseconds := float64(dt.UnixNano()) / float64(time.Millisecond)
  143. tNanoSeconds := float64(dt.UnixNano())
  144. var nilPointer *float64
  145. fixtures := make([]interface{}, 7)
  146. fixtures[0] = tSeconds
  147. fixtures[1] = &tSeconds
  148. fixtures[2] = tMilliseconds
  149. fixtures[3] = &tMilliseconds
  150. fixtures[4] = tNanoSeconds
  151. fixtures[5] = &tNanoSeconds
  152. fixtures[6] = nilPointer
  153. for i := range fixtures {
  154. ConvertSqlTimeColumnToEpochMs(fixtures, i)
  155. }
  156. Convey("When converting them should return epoch time with millisecond precision ", func() {
  157. So(fixtures[0].(float64), ShouldEqual, tMilliseconds)
  158. So(fixtures[1].(float64), ShouldEqual, tMilliseconds)
  159. So(fixtures[2].(float64), ShouldEqual, tMilliseconds)
  160. So(fixtures[3].(float64), ShouldEqual, tMilliseconds)
  161. So(fixtures[4].(float64), ShouldEqual, tMilliseconds)
  162. So(fixtures[5].(float64), ShouldEqual, tMilliseconds)
  163. So(fixtures[6], ShouldBeNil)
  164. })
  165. })
  166. Convey("Given row values with float32 as time columns", func() {
  167. tSeconds := float32(dt.Unix())
  168. var nilInt *float32
  169. fixtures := make([]interface{}, 3)
  170. fixtures[0] = tSeconds
  171. fixtures[1] = &tSeconds
  172. fixtures[2] = nilInt
  173. for i := range fixtures {
  174. ConvertSqlTimeColumnToEpochMs(fixtures, i)
  175. }
  176. Convey("When converting them should return epoch time with millisecond precision ", func() {
  177. So(fixtures[0].(float64), ShouldEqual, float32(dt.Unix()*1e3))
  178. So(fixtures[1].(float64), ShouldEqual, float32(dt.Unix()*1e3))
  179. So(fixtures[2], ShouldBeNil)
  180. })
  181. })
  182. Convey("Given row with value columns", func() {
  183. intValue := 1
  184. int64Value := int64(1)
  185. int32Value := int32(1)
  186. int16Value := int16(1)
  187. int8Value := int8(1)
  188. float64Value := float64(1)
  189. float32Value := float32(1)
  190. uintValue := uint(1)
  191. uint64Value := uint64(1)
  192. uint32Value := uint32(1)
  193. uint16Value := uint16(1)
  194. uint8Value := uint8(1)
  195. fixtures := make([]interface{}, 24)
  196. fixtures[0] = intValue
  197. fixtures[1] = &intValue
  198. fixtures[2] = int64Value
  199. fixtures[3] = &int64Value
  200. fixtures[4] = int32Value
  201. fixtures[5] = &int32Value
  202. fixtures[6] = int16Value
  203. fixtures[7] = &int16Value
  204. fixtures[8] = int8Value
  205. fixtures[9] = &int8Value
  206. fixtures[10] = float64Value
  207. fixtures[11] = &float64Value
  208. fixtures[12] = float32Value
  209. fixtures[13] = &float32Value
  210. fixtures[14] = uintValue
  211. fixtures[15] = &uintValue
  212. fixtures[16] = uint64Value
  213. fixtures[17] = &uint64Value
  214. fixtures[18] = uint32Value
  215. fixtures[19] = &uint32Value
  216. fixtures[20] = uint16Value
  217. fixtures[21] = &uint16Value
  218. fixtures[22] = uint8Value
  219. fixtures[23] = &uint8Value
  220. var intNilPointer *int
  221. var int64NilPointer *int64
  222. var int32NilPointer *int32
  223. var int16NilPointer *int16
  224. var int8NilPointer *int8
  225. var float64NilPointer *float64
  226. var float32NilPointer *float32
  227. var uintNilPointer *uint
  228. var uint64NilPointer *uint64
  229. var uint32NilPointer *uint32
  230. var uint16NilPointer *uint16
  231. var uint8NilPointer *uint8
  232. nilPointerFixtures := make([]interface{}, 12)
  233. nilPointerFixtures[0] = intNilPointer
  234. nilPointerFixtures[1] = int64NilPointer
  235. nilPointerFixtures[2] = int32NilPointer
  236. nilPointerFixtures[3] = int16NilPointer
  237. nilPointerFixtures[4] = int8NilPointer
  238. nilPointerFixtures[5] = float64NilPointer
  239. nilPointerFixtures[6] = float32NilPointer
  240. nilPointerFixtures[7] = uintNilPointer
  241. nilPointerFixtures[8] = uint64NilPointer
  242. nilPointerFixtures[9] = uint32NilPointer
  243. nilPointerFixtures[10] = uint16NilPointer
  244. nilPointerFixtures[11] = uint8NilPointer
  245. Convey("When converting values to float should return expected value", func() {
  246. for _, f := range fixtures {
  247. value, _ := ConvertSqlValueColumnToFloat("col", f)
  248. if !value.Valid {
  249. t.Fatalf("Failed to convert %T value, expected a valid float value", f)
  250. }
  251. if value.Float64 != null.FloatFrom(1).Float64 {
  252. t.Fatalf("Failed to convert %T value, expected a float value of 1.000, but got %v", f, value)
  253. }
  254. }
  255. })
  256. Convey("When converting nil pointer values to float should return expected value", func() {
  257. for _, f := range nilPointerFixtures {
  258. value, err := ConvertSqlValueColumnToFloat("col", f)
  259. if err != nil {
  260. t.Fatalf("Failed to convert %T value, expected a non nil error, but got %v", f, err)
  261. }
  262. if value.Valid {
  263. t.Fatalf("Failed to convert %T value, expected an invalid float value", f)
  264. }
  265. }
  266. })
  267. })
  268. })
  269. }