github.com/mrgossett/heapster@v0.18.2/model/util_test.go (about) 1 // Copyright 2015 Google Inc. All Rights Reserved. 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 15 package model 16 17 import ( 18 "testing" 19 "time" 20 21 "github.com/stretchr/testify/assert" 22 23 "k8s.io/heapster/store/daystore" 24 "k8s.io/heapster/store/statstore" 25 ) 26 27 // TestLatestsTimestamp tests all flows of latestTimeStamp. 28 func TestLatestTimestamp(t *testing.T) { 29 assert := assert.New(t) 30 past := time.Unix(1434212566, 0) 31 future := time.Unix(1434212800, 0) 32 assert.Equal(latestTimestamp(past, future), future) 33 assert.Equal(latestTimestamp(future, past), future) 34 assert.Equal(latestTimestamp(future, future), future) 35 } 36 37 // TestNewInfoType tests both flows of the InfoType constructor. 38 func TestNewInfoType(t *testing.T) { 39 var ( 40 metrics = make(map[string]*daystore.DayStore) 41 labels = make(map[string]string) 42 context = make(map[string]*statstore.TimePoint) 43 ) 44 metrics["test"] = newDayStore() 45 labels["name"] = "test" 46 assert := assert.New(t) 47 48 // Invocation with no parameters 49 new_infotype := newInfoType(nil, nil, nil) 50 assert.Empty(new_infotype.Metrics) 51 assert.Empty(new_infotype.Labels) 52 53 // Invocation with all parameters 54 new_infotype = newInfoType(metrics, labels, context) 55 assert.Equal(new_infotype.Metrics, metrics) 56 assert.Equal(new_infotype.Labels, labels) 57 assert.Equal(new_infotype.Context, context) 58 } 59 60 // TestAddContainerToMap tests all the flows of addContainerToMap. 61 func TestAddContainerToMap(t *testing.T) { 62 new_map := make(map[string]*ContainerInfo) 63 64 // First Call: A new ContainerInfo is created 65 cinfo := addContainerToMap("new_container", new_map) 66 67 assert := assert.New(t) 68 assert.NotNil(cinfo) 69 assert.NotNil(cinfo.Metrics) 70 assert.NotNil(cinfo.Labels) 71 assert.Equal(new_map["new_container"], cinfo) 72 73 // Second Call: A ContainerInfo is already available for that key 74 new_cinfo := addContainerToMap("new_container", new_map) 75 assert.Equal(new_map["new_container"], new_cinfo) 76 assert.Equal(cinfo, new_cinfo) 77 } 78 79 // TestAddTimePoints tests all flows of addTimePoints. 80 func TestAddTimePoints(t *testing.T) { 81 var ( 82 tp1 = statstore.TimePoint{ 83 Timestamp: time.Unix(1434212800, 0), 84 Value: uint64(500), 85 } 86 tp2 = statstore.TimePoint{ 87 Timestamp: time.Unix(1434212805, 0), 88 Value: uint64(700), 89 } 90 assert = assert.New(t) 91 ) 92 new_tp := addTimePoints(tp1, tp2) 93 assert.Equal(new_tp.Timestamp, tp2.Timestamp) 94 assert.Equal(new_tp.Value, tp1.Value+tp2.Value) 95 } 96 97 // TestPopTPSlice tests all flows of PopTPSlice. 98 func TestPopTPSlice(t *testing.T) { 99 var ( 100 tp1 = statstore.TimePoint{ 101 Timestamp: time.Now(), 102 Value: uint64(3), 103 } 104 tp2 = statstore.TimePoint{ 105 Timestamp: time.Now(), 106 Value: uint64(4), 107 } 108 assert = assert.New(t) 109 ) 110 111 // Invocations with no popped element 112 assert.Nil(popTPSlice(nil)) 113 assert.Nil(popTPSlice(&[]statstore.TimePoint{})) 114 115 // Invocation with one element 116 tps := []statstore.TimePoint{tp1} 117 res := popTPSlice(&tps) 118 assert.Equal(*res, tp1) 119 assert.Empty(tps) 120 121 // Invocation with two elements 122 tps = []statstore.TimePoint{tp1, tp2} 123 res = popTPSlice(&tps) 124 assert.Equal(*res, tp1) 125 assert.Len(tps, 1) 126 assert.Equal(tps[0], tp2) 127 } 128 129 // TestAddMatchingTimeseries tests the normal flow of addMatchingTimeseries. 130 func TestAddMatchingTimeseries(t *testing.T) { 131 var ( 132 tp11 = statstore.TimePoint{ 133 Timestamp: time.Unix(1434212800, 0), 134 Value: uint64(4), 135 } 136 tp21 = statstore.TimePoint{ 137 Timestamp: time.Unix(1434212805, 0), 138 Value: uint64(9), 139 } 140 tp31 = statstore.TimePoint{ 141 Timestamp: time.Unix(1434212807, 0), 142 Value: uint64(10), 143 } 144 tp41 = statstore.TimePoint{ 145 Timestamp: time.Unix(1434212850, 0), 146 Value: uint64(533), 147 } 148 149 tp12 = statstore.TimePoint{ 150 Timestamp: time.Unix(1434212800, 0), 151 Value: uint64(4), 152 } 153 tp22 = statstore.TimePoint{ 154 Timestamp: time.Unix(1434212806, 0), 155 Value: uint64(8), 156 } 157 tp32 = statstore.TimePoint{ 158 Timestamp: time.Unix(1434212807, 0), 159 Value: uint64(11), 160 } 161 tp42 = statstore.TimePoint{ 162 Timestamp: time.Unix(1434212851, 0), 163 Value: uint64(534), 164 } 165 tp52 = statstore.TimePoint{ 166 Timestamp: time.Unix(1434212859, 0), 167 Value: uint64(538), 168 } 169 assert = assert.New(t) 170 ) 171 // Invocation with 1+1 data points 172 tps1 := []statstore.TimePoint{tp11} 173 tps2 := []statstore.TimePoint{tp12} 174 new_ts := addMatchingTimeseries(tps1, tps2) 175 assert.Len(new_ts, 1) 176 assert.Equal(new_ts[0].Timestamp, tp11.Timestamp) 177 assert.Equal(new_ts[0].Value, uint64(8)) 178 179 // Invocation with 3+1 data points 180 tps1 = []statstore.TimePoint{tp52, tp42, tp11} 181 tps2 = []statstore.TimePoint{tp12} 182 new_ts = addMatchingTimeseries(tps1, tps2) 183 assert.Len(new_ts, 3) 184 assert.Equal(new_ts[0].Timestamp, tp52.Timestamp) 185 assert.Equal(new_ts[0].Value, tp52.Value+tp12.Value) 186 assert.Equal(new_ts[1].Timestamp, tp42.Timestamp) 187 assert.Equal(new_ts[1].Value, tp42.Value+tp12.Value) 188 assert.Equal(new_ts[2].Timestamp, tp11.Timestamp) 189 assert.Equal(new_ts[2].Value, tp11.Value+tp12.Value) 190 191 // Invocation with 4+5 data points 192 tps1 = []statstore.TimePoint{tp41, tp31, tp21, tp11} 193 tps2 = []statstore.TimePoint{tp52, tp42, tp32, tp22, tp12} 194 new_ts = addMatchingTimeseries(tps1, tps2) 195 assert.Len(new_ts, 7) 196 assert.Equal(new_ts[0].Timestamp, tp52.Timestamp) 197 assert.Equal(new_ts[0].Value, tp52.Value+tp41.Value) 198 199 assert.Equal(new_ts[1].Timestamp, tp42.Timestamp) 200 assert.Equal(new_ts[1].Value, tp42.Value+tp41.Value) 201 202 assert.Equal(new_ts[2].Timestamp, tp41.Timestamp) 203 assert.Equal(new_ts[2].Value, tp41.Value+tp32.Value) 204 205 assert.Equal(new_ts[3].Timestamp, tp31.Timestamp) 206 assert.Equal(new_ts[3].Value, tp31.Value+tp32.Value) 207 208 assert.Equal(new_ts[4].Timestamp, tp22.Timestamp) 209 assert.Equal(new_ts[4].Value, tp22.Value+tp21.Value) 210 211 assert.Equal(new_ts[5].Timestamp, tp21.Timestamp) 212 assert.Equal(new_ts[5].Value, tp21.Value+tp12.Value) 213 214 assert.Equal(new_ts[6].Timestamp, tp11.Timestamp) 215 assert.Equal(new_ts[6].Value, tp11.Value+tp12.Value) 216 } 217 218 // TestAddMatchingTimeseriesEmpty tests the alternate flows of addMatchingTimeseries. 219 // Three permutations of empty parameters are tested. 220 func TestAddMatchingTimeseriesEmpty(t *testing.T) { 221 var ( 222 tp12 = statstore.TimePoint{ 223 Timestamp: time.Unix(1434212800, 0), 224 Value: uint64(4), 225 } 226 tp22 = statstore.TimePoint{ 227 Timestamp: time.Unix(1434212806, 0), 228 Value: uint64(8), 229 } 230 tp32 = statstore.TimePoint{ 231 Timestamp: time.Unix(1434212807, 0), 232 Value: uint64(11), 233 } 234 assert = assert.New(t) 235 ) 236 empty_tps := []statstore.TimePoint{} 237 tps := []statstore.TimePoint{tp12, tp22, tp32} 238 239 // First call: first argument is empty 240 new_ts := addMatchingTimeseries(empty_tps, tps) 241 assert.Equal(new_ts, tps) 242 243 // Second call: second argument is empty 244 new_ts = addMatchingTimeseries(tps, empty_tps) 245 assert.Equal(new_ts, tps) 246 247 // Third call: both arguments are empty 248 new_ts = addMatchingTimeseries(empty_tps, empty_tps) 249 assert.Equal(new_ts, empty_tps) 250 } 251 252 // TestInstantFromCumulativeMetric tests all the flows of instantFromCumulativeMetric. 253 func TestInstantFromCumulativeMetric(t *testing.T) { 254 var ( 255 new_value = uint64(15390000000000) 256 now = time.Now().Round(time.Second) 257 assert = assert.New(t) 258 ) 259 afterNow := now.Add(3 * time.Second) 260 oldTP := &statstore.TimePoint{ 261 Timestamp: now, 262 Value: uint64(13851000000000), 263 } 264 265 // Invocation with nil prev argument 266 val, err := instantFromCumulativeMetric(new_value, afterNow, nil) 267 assert.Error(err) 268 assert.Equal(val, uint64(0)) 269 270 // Invocation with regular arguments 271 val, err = instantFromCumulativeMetric(new_value, afterNow, oldTP) 272 assert.NoError(err) 273 assert.Equal(val, 513*1000) 274 275 // Second Invocation with regular arguments, prev TP has changed 276 newerVal := uint64(15900000000000) 277 val, err = instantFromCumulativeMetric(newerVal, afterNow.Add(time.Second), oldTP) 278 assert.NoError(err) 279 assert.Equal(val, 510*1000) 280 281 } 282 283 // TestGetStats tests all flows of getStats. 284 func TestGetStats(t *testing.T) { 285 var ( 286 metrics = make(map[string]*daystore.DayStore) 287 now = time.Now() 288 assert = assert.New(t) 289 ) 290 // Populate a new DayStore with two hours of data 291 metrics[cpuLimit] = newDayStore() 292 for i := 0; i < 2; i++ { 293 metrics[cpuLimit].Put(statstore.TimePoint{ 294 Timestamp: now.Add(time.Duration(i) * time.Hour), 295 Value: uint64(50), 296 }) 297 metrics[cpuLimit].Put(statstore.TimePoint{ 298 Timestamp: now.Add(time.Duration(i) * time.Hour).Add(15 * time.Minute), 299 Value: uint64(500), 300 }) 301 metrics[cpuLimit].Put(statstore.TimePoint{ 302 Timestamp: now.Add(time.Duration(i) * time.Hour).Add(30 * time.Minute), 303 Value: uint64(2000), 304 }) 305 metrics[cpuLimit].Put(statstore.TimePoint{ 306 Timestamp: now.Add(time.Duration(i) * time.Hour).Add(45 * time.Minute), 307 Value: uint64(1000), 308 }) 309 metrics[cpuLimit].Put(statstore.TimePoint{ 310 Timestamp: now.Add(time.Duration(i) * time.Hour).Add(59 * time.Minute), 311 Value: uint64(15000), 312 }) 313 } 314 315 // flushes the latest TimePoint to the last Hour 316 metrics[cpuLimit].Put(statstore.TimePoint{ 317 Timestamp: now.Add(2 * time.Hour), 318 Value: uint64(300000), 319 }) 320 321 metrics[memUsage] = newDayStore() 322 metrics[memUsage].Put(statstore.TimePoint{ 323 Timestamp: now, 324 Value: uint64(50), 325 }) 326 metrics[memUsage].Put(statstore.TimePoint{ 327 Timestamp: now.Add(30 * time.Minute), 328 Value: uint64(2000), 329 }) 330 metrics[memUsage].Put(statstore.TimePoint{ 331 // flushes the previous TimePoint to the last Hour 332 Timestamp: now.Add(60 * time.Minute), 333 Value: uint64(1000), 334 }) 335 info := newInfoType(metrics, nil, nil) 336 337 res := getStats(info) 338 assert.Len(res, 2) 339 assert.Equal(res[cpuLimit].Minute.Average, uint64(300000)) 340 assert.Equal(res[cpuLimit].Minute.Max, uint64(300000)) 341 assert.Equal(res[cpuLimit].Minute.NinetyFifth, uint64(300000)) 342 343 assert.Equal(res[cpuLimit].Hour.Average, uint64(1133)) 344 assert.Equal(res[cpuLimit].Hour.Max, uint64(300000)) 345 assert.Equal(res[cpuLimit].Hour.NinetyFifth, uint64(2000)) 346 347 assert.Equal(res[cpuLimit].Day.Max, res[cpuLimit].Hour.Max) 348 assert.Equal(res[cpuLimit].Day.Average, res[cpuLimit].Hour.Average) 349 assert.Equal(res[cpuLimit].Day.NinetyFifth, res[cpuLimit].Hour.NinetyFifth) 350 } 351 352 func TestEpsilonFromMetric(t *testing.T) { 353 assert := assert.New(t) 354 assert.Equal(cpuLimitEpsilon, epsilonFromMetric(cpuLimit)) 355 assert.Equal(cpuUsageEpsilon, epsilonFromMetric(cpuUsage)) 356 assert.Equal(memLimitEpsilon, epsilonFromMetric(memLimit)) 357 assert.Equal(memUsageEpsilon, epsilonFromMetric(memUsage)) 358 assert.Equal(memWorkingEpsilon, epsilonFromMetric(memWorking)) 359 assert.Equal(fsLimitEpsilon, epsilonFromMetric(fsLimit)) 360 assert.Equal(fsUsageEpsilon, epsilonFromMetric(fsUsage)) 361 assert.Equal(defaultEpsilon, epsilonFromMetric("other")) 362 }