github.com/go-graphite/carbonapi@v0.17.0/zipper/protocols/prometheus/helpers/helpers_test.go (about) 1 package helpers 2 3 import ( 4 "math" 5 "testing" 6 "time" 7 8 "github.com/go-graphite/carbonapi/tests/compare" 9 "github.com/go-graphite/carbonapi/zipper/protocols/prometheus/types" 10 "github.com/stretchr/testify/assert" 11 ) 12 13 func TestAlignValues(t *testing.T) { 14 type args struct { 15 startTime int64 16 stopTime int64 17 step int64 18 promValues []types.Value 19 } 20 tests := []struct { 21 name string 22 args args 23 want []float64 24 }{ 25 { 26 "single value, don't miss it", 27 args{ 28 startTime: 1617736200, 29 stopTime: 1617736200, 30 step: 60, 31 promValues: []types.Value{ 32 { 33 Timestamp: 1617736200, 34 Value: 12, 35 }, 36 }, 37 }, 38 []float64{12}, 39 }, 40 { 41 "multiple values, don't miss the last one", 42 args{ 43 startTime: 1617729600, 44 stopTime: 1617730200, 45 step: 60, 46 promValues: []types.Value{ 47 { 48 Timestamp: 1617729600, 49 Value: 823, 50 }, 51 { 52 Timestamp: 1617730200, 53 Value: 743, 54 }, 55 }, 56 }, 57 []float64{823, math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), 743}, 58 }, 59 { 60 "multiple values, step is not aligned", // last value has timestamp which is not aligned according to step 61 args{ 62 startTime: 1617729600, 63 stopTime: 1617729660, 64 step: 11, 65 promValues: []types.Value{ 66 { 67 Timestamp: 1617729600, 68 Value: 823, 69 }, 70 { 71 Timestamp: 1617729660, 72 Value: 743, 73 }, 74 }, 75 }, 76 []float64{823, math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN()}, 77 }, 78 } 79 for _, tt := range tests { 80 t.Run(tt.name, func(t *testing.T) { 81 if got := AlignValues(tt.args.startTime, tt.args.stopTime, tt.args.step, tt.args.promValues); !compare.NearlyEqual(got, tt.want) { 82 t.Errorf("AlignValues() = %v, want %v", got, tt.want) 83 } 84 }) 85 } 86 } 87 88 func TestAdjustStep(t *testing.T) { 89 type args struct { 90 start int64 91 stop int64 92 maxPointsPerQuery int64 93 minStep int64 94 forceMinStepInterval time.Duration 95 } 96 tests := []struct { 97 name string 98 args args 99 want int64 100 }{ 101 { 102 "(interval/step) points is less than maxPointsPerQuery (not force min_step)", 103 args{ 104 0, 105 60 * 60 * 24, // interval = 24h 106 60 * 24, // maxDataPoints = 60 points for 1 hour x 24 hours 107 60, // step = 1min 108 0, // don't force min_step 109 }, 110 60, 111 }, 112 { 113 "(interval/step) points is more than maxPointsPerQuery (not force min_step)", 114 args{ 115 0, 116 60 * 60 * 25, // interval = 25h 117 60 * 24, // maxDataPoints = 60 points for 1 hour x 24 hours 118 60, // step = 1min 119 0, // don't force min_step 120 }, 121 120, 122 }, 123 { 124 "(interval/step) points is much more than maxPointsPerQuery (not force min_step)", 125 args{ 126 0, 127 60 * 60 * 50, // interval = 50h 128 60 * 24, // maxDataPoints = 60 points for 1 hour x 24 hours 129 60, // step = 1min 130 0, // don't force min_step 131 }, 132 300, 133 }, 134 { 135 "force min_step for more than interval while maxPointsPerQuery is less than (interval/step) points", 136 args{ 137 0, 138 60 * 20, // interval = 20min 139 15, // maxDataPoints = 15 points 140 60, // step = 1min 141 30 * time.Minute, // do(!) force min_step for 30min 142 }, 143 60, 144 }, 145 { 146 "force min_step for less than interval while maxPointsPerQuery is less than (interval/step) points", 147 args{ 148 0, 149 60 * 20, // interval = 20min 150 15, // maxDataPoints = 15 points 151 60, // step = 1min 152 10 * time.Minute, // do(!) force min_step for 10min 153 }, 154 120, 155 }, 156 } 157 for _, tt := range tests { 158 t.Run(tt.name, func(t *testing.T) { 159 if got := AdjustStep(tt.args.start, tt.args.stop, tt.args.maxPointsPerQuery, tt.args.minStep, tt.args.forceMinStepInterval); got != tt.want { 160 t.Errorf("AdjustStep() = %v, want %v", got, tt.want) 161 } 162 }) 163 } 164 } 165 166 func TestPromethizeTagValue(t *testing.T) { 167 testCases := []struct { 168 name string 169 tagValue string 170 wantName string 171 wantTag types.Tag 172 }{ 173 { 174 name: "empty string", 175 }, 176 { 177 name: "string without '='", 178 tagValue: "test>test", 179 }, 180 { 181 name: "check '='", 182 tagValue: "name=1", 183 wantName: "name", 184 wantTag: types.Tag{OP: "=", TagValue: "1"}, 185 }, 186 { 187 name: "check '!='", 188 tagValue: "name!=1", 189 wantName: "name", 190 wantTag: types.Tag{OP: "!=", TagValue: "1"}, 191 }, 192 { 193 name: "check '=~'", 194 tagValue: "name=~1", 195 wantName: "name", 196 wantTag: types.Tag{OP: "=~", TagValue: "1"}, 197 }, 198 { 199 name: "check '!=~'", 200 tagValue: "name!=~1", 201 wantName: "name", 202 wantTag: types.Tag{OP: "!~", TagValue: "1"}, 203 }, 204 { 205 name: "check '!=~' with empty name", 206 tagValue: "!=~1", 207 wantName: "", 208 wantTag: types.Tag{OP: "!~", TagValue: "1"}, 209 }, 210 { 211 name: "check '=~' with empty name", 212 tagValue: "=~1", 213 wantName: "", 214 wantTag: types.Tag{OP: "=~", TagValue: "1"}, 215 }, 216 { 217 name: "check '=' with empty value", 218 tagValue: "name=", 219 wantName: "name", 220 wantTag: types.Tag{OP: "="}, 221 }, 222 { 223 name: "check '!=' with empty value", 224 tagValue: "name!=", 225 wantName: "name", 226 wantTag: types.Tag{OP: "!="}, 227 }, 228 { 229 name: "check '!=~' with empty value", 230 tagValue: "name!=~", 231 wantName: "name", 232 wantTag: types.Tag{OP: "!~"}, 233 }, 234 { 235 name: "check '=~' with empty value", 236 tagValue: "name=~", 237 wantName: "name", 238 wantTag: types.Tag{OP: "=~"}, 239 }, 240 } 241 242 for _, tt := range testCases { 243 t.Run(tt.name, func(t *testing.T) { 244 gotName, gotTag := PromethizeTagValue(tt.tagValue) 245 246 assert.Equal(t, tt.wantName, gotName) 247 assert.Equal(t, tt.wantTag, gotTag) 248 }) 249 250 } 251 252 }