reducer_test.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. package conditions
  2. import (
  3. "testing"
  4. . "github.com/smartystreets/goconvey/convey"
  5. "github.com/grafana/grafana/pkg/components/null"
  6. "github.com/grafana/grafana/pkg/tsdb"
  7. )
  8. func TestSimpleReducer(t *testing.T) {
  9. Convey("Test simple reducer by calculating", t, func() {
  10. Convey("sum", func() {
  11. result := testReducer("sum", 1, 2, 3)
  12. So(result, ShouldEqual, float64(6))
  13. })
  14. Convey("min", func() {
  15. result := testReducer("min", 3, 2, 1)
  16. So(result, ShouldEqual, float64(1))
  17. })
  18. Convey("max", func() {
  19. result := testReducer("max", 1, 2, 3)
  20. So(result, ShouldEqual, float64(3))
  21. })
  22. Convey("count", func() {
  23. result := testReducer("count", 1, 2, 3000)
  24. So(result, ShouldEqual, float64(3))
  25. })
  26. Convey("last", func() {
  27. result := testReducer("last", 1, 2, 3000)
  28. So(result, ShouldEqual, float64(3000))
  29. })
  30. Convey("median odd amount of numbers", func() {
  31. result := testReducer("median", 1, 2, 3000)
  32. So(result, ShouldEqual, float64(2))
  33. })
  34. Convey("median even amount of numbers", func() {
  35. result := testReducer("median", 1, 2, 4, 3000)
  36. So(result, ShouldEqual, float64(3))
  37. })
  38. Convey("median with one values", func() {
  39. result := testReducer("median", 1)
  40. So(result, ShouldEqual, float64(1))
  41. })
  42. Convey("median should ignore null values", func() {
  43. reducer := NewSimpleReducer("median")
  44. series := &tsdb.TimeSeries{
  45. Name: "test time serie",
  46. }
  47. series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFromPtr(nil), 1))
  48. series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFromPtr(nil), 2))
  49. series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFromPtr(nil), 3))
  50. series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFrom(float64(1)), 4))
  51. series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFrom(float64(2)), 5))
  52. series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFrom(float64(3)), 6))
  53. result := reducer.Reduce(series)
  54. So(result.Valid, ShouldEqual, true)
  55. So(result.Float64, ShouldEqual, float64(2))
  56. })
  57. Convey("avg", func() {
  58. result := testReducer("avg", 1, 2, 3)
  59. So(result, ShouldEqual, float64(2))
  60. })
  61. Convey("avg with only nulls", func() {
  62. reducer := NewSimpleReducer("avg")
  63. series := &tsdb.TimeSeries{
  64. Name: "test time serie",
  65. }
  66. series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFromPtr(nil), 1))
  67. So(reducer.Reduce(series).Valid, ShouldEqual, false)
  68. })
  69. Convey("count_non_null", func() {
  70. Convey("with null values and real values", func() {
  71. reducer := NewSimpleReducer("count_non_null")
  72. series := &tsdb.TimeSeries{
  73. Name: "test time serie",
  74. }
  75. series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFromPtr(nil), 1))
  76. series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFromPtr(nil), 2))
  77. series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFrom(3), 3))
  78. series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFrom(3), 4))
  79. So(reducer.Reduce(series).Valid, ShouldEqual, true)
  80. So(reducer.Reduce(series).Float64, ShouldEqual, 2)
  81. })
  82. Convey("with null values", func() {
  83. reducer := NewSimpleReducer("count_non_null")
  84. series := &tsdb.TimeSeries{
  85. Name: "test time serie",
  86. }
  87. series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFromPtr(nil), 1))
  88. series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFromPtr(nil), 2))
  89. So(reducer.Reduce(series).Valid, ShouldEqual, false)
  90. })
  91. })
  92. Convey("avg of number values and null values should ignore nulls", func() {
  93. reducer := NewSimpleReducer("avg")
  94. series := &tsdb.TimeSeries{
  95. Name: "test time serie",
  96. }
  97. series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFrom(3), 1))
  98. series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFromPtr(nil), 2))
  99. series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFromPtr(nil), 3))
  100. series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFrom(3), 4))
  101. So(reducer.Reduce(series).Float64, ShouldEqual, float64(3))
  102. })
  103. Convey("diff one point", func() {
  104. result := testReducer("diff", 30)
  105. So(result, ShouldEqual, float64(0))
  106. })
  107. Convey("diff two points", func() {
  108. result := testReducer("diff", 30, 40)
  109. So(result, ShouldEqual, float64(10))
  110. })
  111. Convey("diff three points", func() {
  112. result := testReducer("diff", 30, 40, 40)
  113. So(result, ShouldEqual, float64(10))
  114. })
  115. Convey("diff with only nulls", func() {
  116. reducer := NewSimpleReducer("diff")
  117. series := &tsdb.TimeSeries{
  118. Name: "test time serie",
  119. }
  120. series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFromPtr(nil), 1))
  121. series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFromPtr(nil), 2))
  122. So(reducer.Reduce(series).Valid, ShouldEqual, false)
  123. })
  124. Convey("percent_diff one point", func() {
  125. result := testReducer("percent_diff", 40)
  126. So(result, ShouldEqual, float64(0))
  127. })
  128. Convey("percent_diff two points", func() {
  129. result := testReducer("percent_diff", 30, 40)
  130. So(result, ShouldEqual, float64(33.33333333333333))
  131. })
  132. Convey("percent_diff three points", func() {
  133. result := testReducer("percent_diff", 30, 40, 40)
  134. So(result, ShouldEqual, float64(33.33333333333333))
  135. })
  136. Convey("percent_diff with only nulls", func() {
  137. reducer := NewSimpleReducer("percent_diff")
  138. series := &tsdb.TimeSeries{
  139. Name: "test time serie",
  140. }
  141. series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFromPtr(nil), 1))
  142. series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFromPtr(nil), 2))
  143. So(reducer.Reduce(series).Valid, ShouldEqual, false)
  144. })
  145. })
  146. }
  147. func testReducer(typ string, datapoints ...float64) float64 {
  148. reducer := NewSimpleReducer(typ)
  149. series := &tsdb.TimeSeries{
  150. Name: "test time serie",
  151. }
  152. for idx := range datapoints {
  153. series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFrom(datapoints[idx]), 1234134))
  154. }
  155. return reducer.Reduce(series).Float64
  156. }