Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 1 | package stats_test |
| 2 | |
| 3 | import ( |
| 4 | "reflect" |
| 5 | "testing" |
| 6 | "time" |
| 7 | |
Jiri Simsa | 519c507 | 2014-09-17 21:37:57 -0700 | [diff] [blame] | 8 | libstats "veyron.io/veyron/veyron/lib/stats" |
| 9 | "veyron.io/veyron/veyron/lib/stats/counter" |
| 10 | "veyron.io/veyron/veyron/lib/stats/histogram" |
| 11 | istats "veyron.io/veyron/veyron/services/mgmt/stats" |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 12 | |
Jiri Simsa | 519c507 | 2014-09-17 21:37:57 -0700 | [diff] [blame] | 13 | "veyron.io/veyron/veyron2/rt" |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 14 | ) |
| 15 | |
Robin Thellend | 14a09ef | 2014-08-29 13:55:19 -0700 | [diff] [blame] | 16 | func doGlob(root, pattern string, since time.Time, includeValues bool) ([]libstats.KeyValue, error) { |
| 17 | it := libstats.Glob(root, pattern, since, includeValues) |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 18 | out := []libstats.KeyValue{} |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 19 | for it.Advance() { |
| 20 | v := it.Value() |
| 21 | out = append(out, v) |
| 22 | } |
| 23 | if err := it.Err(); err != nil { |
| 24 | return nil, err |
| 25 | } |
| 26 | return out, nil |
| 27 | } |
| 28 | |
| 29 | func TestStats(t *testing.T) { |
| 30 | rt.Init() |
| 31 | |
| 32 | now := time.Unix(1, 0) |
| 33 | counter.Now = func() time.Time { return now } |
| 34 | |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 35 | a := libstats.NewInteger("ipc/test/aaa") |
| 36 | b := libstats.NewFloat("ipc/test/bbb") |
| 37 | c := libstats.NewString("ipc/test/ccc") |
| 38 | d := libstats.NewCounter("ipc/test/ddd") |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 39 | |
| 40 | a.Set(1) |
| 41 | b.Set(2) |
| 42 | c.Set("Hello") |
| 43 | d.Set(4) |
| 44 | |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 45 | got, err := libstats.Value("ipc/test/aaa") |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 46 | if err != nil { |
| 47 | t.Errorf("unexpected error: %v", err) |
| 48 | } |
| 49 | if expected := int64(1); got != expected { |
| 50 | t.Errorf("unexpected result. Got %v, want %v", got, expected) |
| 51 | } |
| 52 | |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 53 | if _, err := libstats.Value(""); err != libstats.ErrNotFound { |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 54 | t.Errorf("expected error, got err=%v", err) |
| 55 | } |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 56 | if _, err := libstats.Value("does/not/exist"); err != libstats.ErrNotFound { |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 57 | t.Errorf("expected error, got err=%v", err) |
| 58 | } |
| 59 | |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 60 | root := libstats.NewInteger("") |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 61 | root.Set(42) |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 62 | got, err = libstats.Value("") |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 63 | if err != nil { |
| 64 | t.Errorf("unexpected error: %v", err) |
| 65 | } |
| 66 | if expected := int64(42); got != expected { |
| 67 | t.Errorf("unexpected result. Got %v, want %v", got, expected) |
| 68 | } |
| 69 | |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 70 | foo := libstats.NewInteger("foo") |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 71 | foo.Set(55) |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 72 | got, err = libstats.Value("foo") |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 73 | if err != nil { |
| 74 | t.Errorf("unexpected error: %v", err) |
| 75 | } |
| 76 | if expected := int64(55); got != expected { |
| 77 | t.Errorf("unexpected result. Got %v, want %v", got, expected) |
| 78 | } |
| 79 | |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 80 | bar := libstats.NewInteger("foo/bar") |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 81 | bar.Set(44) |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 82 | got, err = libstats.Value("foo/bar") |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 83 | if err != nil { |
| 84 | t.Errorf("unexpected error: %v", err) |
| 85 | } |
| 86 | if expected := int64(44); got != expected { |
| 87 | t.Errorf("unexpected result. Got %v, want %v", got, expected) |
| 88 | } |
| 89 | |
Robin Thellend | 14a09ef | 2014-08-29 13:55:19 -0700 | [diff] [blame] | 90 | // Glob showing only nodes with a value. |
| 91 | result, err := doGlob("", "...", now, true) |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 92 | if err != nil { |
| 93 | t.Errorf("unexpected error: %v", err) |
| 94 | } |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 95 | expected := []libstats.KeyValue{ |
| 96 | libstats.KeyValue{Key: "", Value: int64(42)}, |
| 97 | libstats.KeyValue{Key: "foo", Value: int64(55)}, |
| 98 | libstats.KeyValue{Key: "foo/bar", Value: int64(44)}, |
| 99 | libstats.KeyValue{Key: "ipc/test/aaa", Value: int64(1)}, |
| 100 | libstats.KeyValue{Key: "ipc/test/bbb", Value: float64(2)}, |
| 101 | libstats.KeyValue{Key: "ipc/test/ccc", Value: string("Hello")}, |
| 102 | libstats.KeyValue{Key: "ipc/test/ddd", Value: int64(4)}, |
Robin Thellend | 1eb8169 | 2014-09-03 10:48:24 -0700 | [diff] [blame] | 103 | libstats.KeyValue{Key: "ipc/test/ddd/delta10m", Value: int64(4)}, |
| 104 | libstats.KeyValue{Key: "ipc/test/ddd/delta1h", Value: int64(4)}, |
| 105 | libstats.KeyValue{Key: "ipc/test/ddd/delta1m", Value: int64(4)}, |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 106 | libstats.KeyValue{Key: "ipc/test/ddd/rate10m", Value: float64(0)}, |
| 107 | libstats.KeyValue{Key: "ipc/test/ddd/rate1h", Value: float64(0)}, |
| 108 | libstats.KeyValue{Key: "ipc/test/ddd/rate1m", Value: float64(0)}, |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 109 | } |
| 110 | if !reflect.DeepEqual(result, expected) { |
| 111 | t.Errorf("unexpected result. Got %#v, want %#v", result, expected) |
| 112 | } |
| 113 | |
Robin Thellend | 14a09ef | 2014-08-29 13:55:19 -0700 | [diff] [blame] | 114 | result, err = doGlob("", "ipc/test/*", now, true) |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 115 | if err != nil { |
| 116 | t.Errorf("unexpected error: %v", err) |
| 117 | } |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 118 | expected = []libstats.KeyValue{ |
| 119 | libstats.KeyValue{Key: "ipc/test/aaa", Value: int64(1)}, |
| 120 | libstats.KeyValue{Key: "ipc/test/bbb", Value: float64(2)}, |
| 121 | libstats.KeyValue{Key: "ipc/test/ccc", Value: string("Hello")}, |
| 122 | libstats.KeyValue{Key: "ipc/test/ddd", Value: int64(4)}, |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 123 | } |
| 124 | if !reflect.DeepEqual(result, expected) { |
| 125 | t.Errorf("unexpected result. Got %#v, want %#v", result, expected) |
| 126 | } |
| 127 | |
Robin Thellend | 14a09ef | 2014-08-29 13:55:19 -0700 | [diff] [blame] | 128 | // Glob showing all nodes without values |
| 129 | result, err = doGlob("", "ipc/...", time.Time{}, false) |
| 130 | if err != nil { |
| 131 | t.Errorf("unexpected error: %v", err) |
| 132 | } |
| 133 | expected = []libstats.KeyValue{ |
| 134 | libstats.KeyValue{Key: "ipc"}, |
| 135 | libstats.KeyValue{Key: "ipc/test"}, |
| 136 | libstats.KeyValue{Key: "ipc/test/aaa"}, |
| 137 | libstats.KeyValue{Key: "ipc/test/bbb"}, |
| 138 | libstats.KeyValue{Key: "ipc/test/ccc"}, |
| 139 | libstats.KeyValue{Key: "ipc/test/ddd"}, |
| 140 | libstats.KeyValue{Key: "ipc/test/ddd/delta10m"}, |
| 141 | libstats.KeyValue{Key: "ipc/test/ddd/delta1h"}, |
| 142 | libstats.KeyValue{Key: "ipc/test/ddd/delta1m"}, |
| 143 | libstats.KeyValue{Key: "ipc/test/ddd/rate10m"}, |
| 144 | libstats.KeyValue{Key: "ipc/test/ddd/rate1h"}, |
| 145 | libstats.KeyValue{Key: "ipc/test/ddd/rate1m"}, |
| 146 | } |
| 147 | if !reflect.DeepEqual(result, expected) { |
| 148 | t.Errorf("unexpected result. Got %#v, want %#v", result, expected) |
| 149 | } |
| 150 | |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 151 | // Test the rate counter. |
| 152 | now = now.Add(10 * time.Second) |
| 153 | d.Incr(100) |
Robin Thellend | 14a09ef | 2014-08-29 13:55:19 -0700 | [diff] [blame] | 154 | result, err = doGlob("", "ipc/test/ddd/*", now, true) |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 155 | if err != nil { |
| 156 | t.Errorf("unexpected error: %v", err) |
| 157 | } |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 158 | expected = []libstats.KeyValue{ |
Robin Thellend | 1eb8169 | 2014-09-03 10:48:24 -0700 | [diff] [blame] | 159 | libstats.KeyValue{Key: "ipc/test/ddd/delta10m", Value: int64(104)}, |
| 160 | libstats.KeyValue{Key: "ipc/test/ddd/delta1h", Value: int64(104)}, |
| 161 | libstats.KeyValue{Key: "ipc/test/ddd/delta1m", Value: int64(104)}, |
| 162 | libstats.KeyValue{Key: "ipc/test/ddd/rate10m", Value: float64(10.4)}, |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 163 | libstats.KeyValue{Key: "ipc/test/ddd/rate1h", Value: float64(0)}, |
Robin Thellend | 1eb8169 | 2014-09-03 10:48:24 -0700 | [diff] [blame] | 164 | libstats.KeyValue{Key: "ipc/test/ddd/rate1m", Value: float64(10.4)}, |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 165 | } |
| 166 | if !reflect.DeepEqual(result, expected) { |
| 167 | t.Errorf("unexpected result. Got %#v, want %#v", result, expected) |
| 168 | } |
| 169 | |
| 170 | // Test Glob on non-root object. |
Robin Thellend | 14a09ef | 2014-08-29 13:55:19 -0700 | [diff] [blame] | 171 | result, err = doGlob("ipc/test", "*", time.Time{}, true) |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 172 | if err != nil { |
| 173 | t.Errorf("unexpected error: %v", err) |
| 174 | } |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 175 | expected = []libstats.KeyValue{ |
| 176 | libstats.KeyValue{Key: "aaa", Value: int64(1)}, |
| 177 | libstats.KeyValue{Key: "bbb", Value: float64(2)}, |
| 178 | libstats.KeyValue{Key: "ccc", Value: string("Hello")}, |
| 179 | libstats.KeyValue{Key: "ddd", Value: int64(104)}, |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 180 | } |
| 181 | if !reflect.DeepEqual(result, expected) { |
| 182 | t.Errorf("unexpected result. Got %#v, want %#v", result, expected) |
| 183 | } |
| 184 | |
Robin Thellend | 14a09ef | 2014-08-29 13:55:19 -0700 | [diff] [blame] | 185 | result, err = doGlob("ipc/test/aaa", "", time.Time{}, true) |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 186 | if err != nil { |
| 187 | t.Errorf("unexpected error: %v", err) |
| 188 | } |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 189 | expected = []libstats.KeyValue{ |
| 190 | libstats.KeyValue{Key: "", Value: int64(1)}, |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 191 | } |
| 192 | if !reflect.DeepEqual(result, expected) { |
| 193 | t.Errorf("unexpected result. Got %#v, want %#v", result, expected) |
| 194 | } |
| 195 | |
| 196 | // Test LastUpdate. The test only works on Counters. |
Robin Thellend | 14a09ef | 2014-08-29 13:55:19 -0700 | [diff] [blame] | 197 | result, err = doGlob("ipc/test", "ddd", now, true) |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 198 | if err != nil { |
| 199 | t.Errorf("unexpected error: %v", err) |
| 200 | } |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 201 | expected = []libstats.KeyValue{ |
| 202 | libstats.KeyValue{Key: "ddd", Value: int64(104)}, |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 203 | } |
| 204 | if !reflect.DeepEqual(result, expected) { |
| 205 | t.Errorf("unexpected result. Got %#v, want %#v", result, expected) |
| 206 | } |
| 207 | |
Robin Thellend | 14a09ef | 2014-08-29 13:55:19 -0700 | [diff] [blame] | 208 | result, err = doGlob("ipc/test", "ddd", now.Add(time.Second), true) |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 209 | if err != nil { |
| 210 | t.Errorf("unexpected error: %v", err) |
| 211 | } |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 212 | expected = []libstats.KeyValue{} |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 213 | if !reflect.DeepEqual(result, expected) { |
| 214 | t.Errorf("unexpected result. Got %#v, want %#v", result, expected) |
| 215 | } |
| 216 | |
| 217 | // Test histogram |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 218 | h := libstats.NewHistogram("ipc/test/hhh", histogram.Options{NumBuckets: 5, GrowthFactor: 0}) |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 219 | h.Add(1) |
| 220 | h.Add(2) |
| 221 | |
Robin Thellend | 14a09ef | 2014-08-29 13:55:19 -0700 | [diff] [blame] | 222 | result, err = doGlob("", "ipc/test/hhh", now, true) |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 223 | if err != nil { |
| 224 | t.Errorf("unexpected error: %v", err) |
| 225 | } |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 226 | expected = []libstats.KeyValue{ |
| 227 | libstats.KeyValue{ |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 228 | Key: "ipc/test/hhh", |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 229 | Value: istats.HistogramValue{ |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 230 | Count: 2, |
| 231 | Sum: 3, |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 232 | Buckets: []istats.HistogramBucket{ |
| 233 | istats.HistogramBucket{LowBound: 0, Count: 0}, |
| 234 | istats.HistogramBucket{LowBound: 1, Count: 1}, |
| 235 | istats.HistogramBucket{LowBound: 2, Count: 1}, |
| 236 | istats.HistogramBucket{LowBound: 3, Count: 0}, |
| 237 | istats.HistogramBucket{LowBound: 4, Count: 0}, |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 238 | }, |
| 239 | }, |
| 240 | }, |
| 241 | } |
| 242 | if !reflect.DeepEqual(result, expected) { |
| 243 | t.Errorf("unexpected result. Got %#v, want %#v", result, expected) |
| 244 | } |
| 245 | |
| 246 | now = now.Add(30 * time.Second) |
| 247 | h.Add(2) |
| 248 | now = now.Add(30 * time.Second) |
| 249 | h.Add(3) |
| 250 | |
Robin Thellend | 14a09ef | 2014-08-29 13:55:19 -0700 | [diff] [blame] | 251 | result, err = doGlob("", "ipc/test/hhh/delta1m", now, true) |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 252 | if err != nil { |
| 253 | t.Errorf("unexpected error: %v", err) |
| 254 | } |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 255 | expected = []libstats.KeyValue{ |
| 256 | libstats.KeyValue{ |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 257 | Key: "ipc/test/hhh/delta1m", |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 258 | Value: istats.HistogramValue{ |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 259 | Count: 2, |
| 260 | Sum: 5, |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 261 | Buckets: []istats.HistogramBucket{ |
| 262 | istats.HistogramBucket{LowBound: 0, Count: 0}, |
| 263 | istats.HistogramBucket{LowBound: 1, Count: 0}, |
| 264 | istats.HistogramBucket{LowBound: 2, Count: 1}, |
| 265 | istats.HistogramBucket{LowBound: 3, Count: 1}, |
| 266 | istats.HistogramBucket{LowBound: 4, Count: 0}, |
Robin Thellend | ac59e97 | 2014-08-19 18:26:11 -0700 | [diff] [blame] | 267 | }, |
| 268 | }, |
| 269 | }, |
| 270 | } |
| 271 | if !reflect.DeepEqual(result, expected) { |
| 272 | t.Errorf("unexpected result. Got %#v, want %#v", result, expected) |
| 273 | } |
| 274 | } |
Robin Thellend | df42823 | 2014-10-06 12:50:44 -0700 | [diff] [blame] | 275 | |
| 276 | func TestDelete(t *testing.T) { |
| 277 | _ = libstats.NewInteger("a/b/c/d") |
| 278 | if _, err := libstats.GetStatsObject("a/b/c/d"); err != nil { |
| 279 | t.Errorf("unexpected error value: %v", err) |
| 280 | } |
| 281 | if err := libstats.Delete("a/b/c/d"); err != nil { |
| 282 | t.Errorf("unexpected error value: %v", err) |
| 283 | } |
| 284 | if _, err := libstats.GetStatsObject("a/b/c/d"); err != libstats.ErrNotFound { |
| 285 | t.Errorf("unexpected error value: Got %v, want %v", err, libstats.ErrNotFound) |
| 286 | } |
| 287 | if err := libstats.Delete("a/b"); err != nil { |
| 288 | t.Errorf("unexpected error value: %v", err) |
| 289 | } |
| 290 | if _, err := libstats.GetStatsObject("a/b"); err != libstats.ErrNotFound { |
| 291 | t.Errorf("unexpected error value: Got %v, want %v", err, libstats.ErrNotFound) |
| 292 | } |
| 293 | if _, err := libstats.GetStatsObject("a/b/c"); err != libstats.ErrNotFound { |
| 294 | t.Errorf("unexpected error value: Got %v, want %v", err, libstats.ErrNotFound) |
| 295 | } |
| 296 | } |