reducer_test.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package conditions
  15. import (
  16. "testing"
  17. . "github.com/smartystreets/goconvey/convey"
  18. "yunion.io/x/onecloud/pkg/apis/monitor"
  19. )
  20. func TestSimpleReducer(t *testing.T) {
  21. Convey("Test simple reducer by calculating", t, func() {
  22. Convey("sum", func() {
  23. result := testReducer("sum", 1, 2, 3)
  24. So(result, ShouldEqual, float64(6))
  25. })
  26. Convey("min", func() {
  27. result := testReducer("min", 3, 2, 1)
  28. So(result, ShouldEqual, float64(1))
  29. })
  30. Convey("max", func() {
  31. result := testReducer("max", 1, 2, 3)
  32. So(result, ShouldEqual, float64(3))
  33. })
  34. Convey("count", func() {
  35. result := testReducer("count", 1, 2, 3000)
  36. So(result, ShouldEqual, float64(3))
  37. })
  38. Convey("last", func() {
  39. result := testReducer("last", 1, 2, 3000)
  40. So(result, ShouldEqual, float64(3000))
  41. })
  42. Convey("median odd amount of numbers", func() {
  43. result := testReducer("median", 1, 2, 3000)
  44. So(result, ShouldEqual, float64(2))
  45. })
  46. Convey("median even amount of numbers", func() {
  47. result := testReducer("median", 1, 2, 4, 3000)
  48. So(result, ShouldEqual, float64(3))
  49. })
  50. Convey("median with one values", func() {
  51. result := testReducer("median", 1)
  52. So(result, ShouldEqual, float64(1))
  53. })
  54. Convey("median should ignore null values", func() {
  55. reducer := newSimpleReducerByType("median")
  56. series := &monitor.TimeSeries{
  57. Name: "test time series",
  58. }
  59. series.Points = append(series.Points, monitor.NewTimePoint(nil, 1))
  60. series.Points = append(series.Points, monitor.NewTimePoint(nil, 2))
  61. series.Points = append(series.Points, monitor.NewTimePoint(nil, 3))
  62. series.Points = append(series.Points, monitor.NewTimePointByVal(1, 4))
  63. series.Points = append(series.Points, monitor.NewTimePointByVal(2, 5))
  64. series.Points = append(series.Points, monitor.NewTimePointByVal(3, 6))
  65. result, _ := reducer.Reduce(series)
  66. So(result, ShouldNotBeNil)
  67. So(*result, ShouldEqual, 2)
  68. })
  69. Convey("avg", func() {
  70. result := testReducer("avg", 1, 2, 3)
  71. So(result, ShouldEqual, float64(2))
  72. })
  73. Convey("count_non_null", func() {
  74. Convey("with null values and real values", func() {
  75. reducer := newSimpleReducerByType("count_non_null")
  76. series := &monitor.TimeSeries{
  77. Name: "test time series",
  78. }
  79. series.Points = append(series.Points, monitor.NewTimePoint(nil, 1))
  80. series.Points = append(series.Points, monitor.NewTimePoint(nil, 2))
  81. series.Points = append(series.Points, monitor.NewTimePointByVal(3, 3))
  82. series.Points = append(series.Points, monitor.NewTimePointByVal(4, 4))
  83. reduce, _ := reducer.Reduce(series)
  84. So(reduce, ShouldNotBeNil)
  85. So(*reduce, ShouldEqual, 2)
  86. })
  87. Convey("with null values", func() {
  88. reducer := newSimpleReducerByType("count_non_null")
  89. series := &monitor.TimeSeries{
  90. Name: "test time series",
  91. }
  92. series.Points = append(series.Points, monitor.NewTimePoint(nil, 1))
  93. series.Points = append(series.Points, monitor.NewTimePoint(nil, 2))
  94. reduce, _ := reducer.Reduce(series)
  95. So(reduce, ShouldBeNil)
  96. })
  97. })
  98. Convey("avg of number values and null values should ignore nulls", func() {
  99. reduer := newSimpleReducerByType("avg")
  100. series := &monitor.TimeSeries{
  101. Name: "test time series",
  102. }
  103. series.Points = append(series.Points, monitor.NewTimePoint(nil, 1))
  104. series.Points = append(series.Points, monitor.NewTimePoint(nil, 2))
  105. series.Points = append(series.Points, monitor.NewTimePoint(nil, 3))
  106. series.Points = append(series.Points, monitor.NewTimePointByVal(3, 4))
  107. reduce, _ := reduer.Reduce(series)
  108. So(*reduce, ShouldEqual, 3)
  109. })
  110. Convey("diff one point", func() {
  111. result := testReducer("diff", 30)
  112. So(result, ShouldEqual, float64(0))
  113. })
  114. Convey("diff two points", func() {
  115. result := testReducer("diff", 30, 40)
  116. So(result, ShouldEqual, float64(10))
  117. })
  118. Convey("diff three points", func() {
  119. result := testReducer("diff", 30, 40, 40)
  120. So(result, ShouldEqual, float64(10))
  121. })
  122. Convey("diff with only nulls", func() {
  123. reducer := newSimpleReducerByType("diff")
  124. series := &monitor.TimeSeries{
  125. Name: "test time serie",
  126. }
  127. series.Points = append(series.Points, monitor.NewTimePoint(nil, 1))
  128. series.Points = append(series.Points, monitor.NewTimePoint(nil, 2))
  129. reduce, _ := reducer.Reduce(series)
  130. So(reduce, ShouldBeNil)
  131. })
  132. Convey("percent_diff one point", func() {
  133. result := testReducer("percent_diff", 40)
  134. So(result, ShouldEqual, float64(0))
  135. })
  136. Convey("percent_diff two points", func() {
  137. result := testReducer("percent_diff", 30, 40)
  138. So(result, ShouldEqual, float64(33.33333333333333))
  139. })
  140. Convey("percent_diff three points", func() {
  141. result := testReducer("percent_diff", 30, 40, 40)
  142. So(result, ShouldEqual, float64(33.33333333333333))
  143. })
  144. Convey("percent_diff with only nulls", func() {
  145. reducer := newSimpleReducerByType("percent_diff")
  146. series := &monitor.TimeSeries{
  147. Name: "test time serie",
  148. }
  149. series.Points = append(series.Points, monitor.NewTimePoint(nil, 1))
  150. series.Points = append(series.Points, monitor.NewTimePoint(nil, 2))
  151. reduce, _ := reducer.Reduce(series)
  152. So(reduce, ShouldBeNil)
  153. })
  154. })
  155. }
  156. func testReducer(reducerType string, datapoints ...float64) float64 {
  157. reducer := newSimpleReducerByType(reducerType)
  158. serires := &monitor.TimeSeries{
  159. Name: "test time series",
  160. }
  161. for idx := range datapoints {
  162. val := datapoints[idx]
  163. serires.Points = append(serires.Points, monitor.NewTimePoint(&val, 1234134))
  164. }
  165. reduce, _ := reducer.Reduce(serires)
  166. return *reduce
  167. }