OLD | NEW |
| (Empty) |
1 # Copyright 2015 The Chromium Authors. All rights reserved. | |
2 # Use of this source code is governed by a BSD-style license that can be | |
3 # found in the LICENSE file. | |
4 | |
5 import sys | |
6 import textwrap | |
7 import unittest | |
8 | |
9 import mock | |
10 | |
11 from monacq.proto import metrics_pb2 | |
12 | |
13 from infra_libs.ts_mon import distribution | |
14 from infra_libs.ts_mon import errors | |
15 from infra_libs.ts_mon import interface | |
16 from infra_libs.ts_mon import metrics | |
17 from infra_libs.ts_mon import targets | |
18 | |
19 | |
20 class FakeState(interface.State): | |
21 def __init__(self): | |
22 super(FakeState, self).__init__() | |
23 self.global_monitor = mock.Mock() | |
24 | |
25 | |
26 class MetricTestBase(unittest.TestCase): | |
27 def setUp(self): | |
28 self.fake_state = FakeState() | |
29 self.state_patcher = mock.patch( | |
30 'infra_libs.ts_mon.interface.state', new=self.fake_state) | |
31 self.send_patcher = mock.patch('infra_libs.ts_mon.interface.send') | |
32 | |
33 self.state_patcher.start() | |
34 self.fake_send = self.send_patcher.start() | |
35 | |
36 def tearDown(self): | |
37 self.state_patcher.stop() | |
38 self.send_patcher.stop() | |
39 | |
40 | |
41 class MetricTest(MetricTestBase): | |
42 | |
43 def test_init_too_may_fields(self): | |
44 fields = {str(i): str(i) for i in xrange(8)} | |
45 with self.assertRaises(errors.MonitoringTooManyFieldsError) as e: | |
46 metrics.Metric('test', fields=fields) | |
47 self.assertEquals(e.exception.metric, 'test') | |
48 self.assertEquals(len(e.exception.fields), 8) | |
49 | |
50 def test_serialize(self): | |
51 t = targets.DeviceTarget('reg', 'net', 'host') | |
52 m = metrics.StringMetric('test', target=t, fields={'bar': 1}) | |
53 m.set('val', fields={'baz': False}) | |
54 p = metrics_pb2.MetricsCollection() | |
55 m.serialize_to(p) | |
56 e = textwrap.dedent('''\ | |
57 data { | |
58 name: "test" | |
59 metric_name_prefix: "/chrome/infra/" | |
60 network_device { | |
61 alertable: true | |
62 realm: "ACQ_CHROME" | |
63 metro: "reg" | |
64 hostname: "host" | |
65 hostgroup: "net" | |
66 } | |
67 fields { | |
68 name: "bar" | |
69 type: INT | |
70 int_value: 1 | |
71 } | |
72 fields { | |
73 name: "baz" | |
74 type: BOOL | |
75 bool_value: false | |
76 } | |
77 string_value: "val" | |
78 } | |
79 ''') | |
80 self.assertEquals(str(p), e) | |
81 | |
82 def test_serialize_multiple_values(self): | |
83 t = targets.DeviceTarget('reg', 'net', 'host') | |
84 m = metrics.StringMetric('test', target=t) | |
85 m.set('val1', fields={'foo': 1}) | |
86 m.set('val2', fields={'foo': 2}) | |
87 p = metrics_pb2.MetricsCollection() | |
88 loop_action = mock.Mock() | |
89 m.serialize_to(p, loop_action=loop_action) | |
90 e = textwrap.dedent('''\ | |
91 data { | |
92 name: "test" | |
93 metric_name_prefix: "/chrome/infra/" | |
94 network_device { | |
95 alertable: true | |
96 realm: "ACQ_CHROME" | |
97 metro: "reg" | |
98 hostname: "host" | |
99 hostgroup: "net" | |
100 } | |
101 fields { | |
102 name: "foo" | |
103 type: INT | |
104 int_value: 2 | |
105 } | |
106 string_value: "val2" | |
107 } | |
108 data { | |
109 name: "test" | |
110 metric_name_prefix: "/chrome/infra/" | |
111 network_device { | |
112 alertable: true | |
113 realm: "ACQ_CHROME" | |
114 metro: "reg" | |
115 hostname: "host" | |
116 hostgroup: "net" | |
117 } | |
118 fields { | |
119 name: "foo" | |
120 type: INT | |
121 int_value: 1 | |
122 } | |
123 string_value: "val1" | |
124 } | |
125 ''') | |
126 self.assertEquals(str(p), e) | |
127 self.assertEquals(2, loop_action.call_count) | |
128 | |
129 def test_serialize_default_target(self): | |
130 t = targets.DeviceTarget('reg', 'net', 'host') | |
131 m = metrics.StringMetric('test') | |
132 m.set('val') | |
133 p = metrics_pb2.MetricsCollection() | |
134 m.serialize_to(p, default_target=t) | |
135 e = textwrap.dedent('''\ | |
136 data { | |
137 name: "test" | |
138 metric_name_prefix: "/chrome/infra/" | |
139 network_device { | |
140 alertable: true | |
141 realm: "ACQ_CHROME" | |
142 metro: "reg" | |
143 hostname: "host" | |
144 hostgroup: "net" | |
145 } | |
146 string_value: "val" | |
147 } | |
148 ''') | |
149 self.assertEquals(str(p), e) | |
150 | |
151 def test_serialize_no_target(self): | |
152 m = metrics.StringMetric('test') | |
153 m.set('val') | |
154 with self.assertRaises(errors.MonitoringNoConfiguredTargetError): | |
155 p = metrics_pb2.MetricsCollection() | |
156 m.serialize_to(p) | |
157 | |
158 def test_serialze_too_many_fields(self): | |
159 t = targets.DeviceTarget('reg', 'net', 'host') | |
160 m = metrics.StringMetric('test', target=t, | |
161 fields={'a': 1, 'b': 2, 'c': 3, 'd': 4}) | |
162 m.set('val', fields={'e': 5, 'f': 6, 'g': 7}) | |
163 with self.assertRaises(errors.MonitoringTooManyFieldsError): | |
164 m.set('val', fields={'e': 5, 'f': 6, 'g': 7, 'h': 8}) | |
165 | |
166 def test_populate_field_values(self): | |
167 pb1 = metrics_pb2.MetricsData() | |
168 m1 = metrics.Metric('foo', fields={'asdf': 1}) | |
169 m1._populate_fields(pb1, m1._normalized_fields) | |
170 self.assertEquals(pb1.fields[0].name, 'asdf') | |
171 self.assertEquals(pb1.fields[0].int_value, 1) | |
172 | |
173 pb2 = metrics_pb2.MetricsData() | |
174 m2 = metrics.Metric('bar', fields={'qwer': True}) | |
175 m2._populate_fields(pb2, m2._normalized_fields) | |
176 self.assertEquals(pb2.fields[0].name, 'qwer') | |
177 self.assertEquals(pb2.fields[0].bool_value, True) | |
178 | |
179 pb3 = metrics_pb2.MetricsData() | |
180 m3 = metrics.Metric('baz', fields={'zxcv': 'baz'}) | |
181 m3._populate_fields(pb3, m3._normalized_fields) | |
182 self.assertEquals(pb3.fields[0].name, 'zxcv') | |
183 self.assertEquals(pb3.fields[0].string_value, 'baz') | |
184 | |
185 def test_invalid_field_value(self): | |
186 pb = metrics_pb2.MetricsData() | |
187 m = metrics.Metric('test', fields={'pi': 3.14}) | |
188 with self.assertRaises(errors.MonitoringInvalidFieldTypeError) as e: | |
189 m._populate_fields(pb, m._normalized_fields) | |
190 self.assertEquals(e.exception.metric, 'test') | |
191 self.assertEquals(e.exception.field, 'pi') | |
192 self.assertEquals(e.exception.value, 3.14) | |
193 | |
194 def test_register_unregister(self): | |
195 self.assertEquals(0, len(self.fake_state.metrics)) | |
196 m = metrics.Metric('test', fields={'pi': 3.14}) | |
197 self.assertEquals(1, len(self.fake_state.metrics)) | |
198 m.unregister() | |
199 self.assertEquals(0, len(self.fake_state.metrics)) | |
200 | |
201 def test_reset(self): | |
202 m = metrics.StringMetric('test') | |
203 self.assertIsNone(m.get()) | |
204 m.set('foo') | |
205 self.assertEqual('foo', m.get()) | |
206 m.reset() | |
207 self.assertIsNone(m.get()) | |
208 | |
209 | |
210 class StringMetricTest(MetricTestBase): | |
211 | |
212 def test_populate_value(self): | |
213 pb = metrics_pb2.MetricsData() | |
214 m = metrics.StringMetric('test') | |
215 m._populate_value(pb, 'foo') | |
216 self.assertEquals(pb.string_value, 'foo') | |
217 | |
218 def test_set(self): | |
219 m = metrics.StringMetric('test') | |
220 m.set('hello world') | |
221 self.assertEquals(m.get(), 'hello world') | |
222 self.assertEquals(self.fake_send.call_count, 1) | |
223 | |
224 def test_non_string_raises(self): | |
225 m = metrics.StringMetric('test') | |
226 with self.assertRaises(errors.MonitoringInvalidValueTypeError): | |
227 m.set(object()) | |
228 | |
229 | |
230 class BooleanMetricTest(MetricTestBase): | |
231 | |
232 def test_populate_value(self): | |
233 pb = metrics_pb2.MetricsData() | |
234 m = metrics.BooleanMetric('test') | |
235 m._populate_value(pb, True) | |
236 self.assertEquals(pb.boolean_value, True) | |
237 | |
238 def test_set(self): | |
239 m = metrics.BooleanMetric('test') | |
240 m.set(False) | |
241 self.assertEquals(m.get(), False) | |
242 self.assertEquals(self.fake_send.call_count, 1) | |
243 | |
244 def test_toggle(self): | |
245 m = metrics.BooleanMetric('test') | |
246 m.set(True) | |
247 self.assertEquals(m.get(), True) | |
248 self.assertEquals(self.fake_send.call_count, 1) | |
249 m.toggle() | |
250 self.assertEquals(m.get(), False) | |
251 self.assertEquals(self.fake_send.call_count, 2) | |
252 | |
253 def test_non_bool_raises(self): | |
254 m = metrics.BooleanMetric('test') | |
255 with self.assertRaises(errors.MonitoringInvalidValueTypeError): | |
256 m.set(object()) | |
257 with self.assertRaises(errors.MonitoringInvalidValueTypeError): | |
258 m.set('True') | |
259 with self.assertRaises(errors.MonitoringInvalidValueTypeError): | |
260 m.set(123) | |
261 | |
262 | |
263 class CounterMetricTest(MetricTestBase): | |
264 | |
265 def test_populate_value(self): | |
266 pb = metrics_pb2.MetricsData() | |
267 m = metrics.CounterMetric('test') | |
268 m._populate_value(pb, 1) | |
269 self.assertEquals(pb.counter, 1) | |
270 | |
271 def test_starts_at_zero(self): | |
272 m = metrics.CounterMetric('test') | |
273 self.assertEquals(m.get(), 0) | |
274 m.increment() | |
275 self.assertEquals(m.get(), 1) | |
276 self.assertEquals(self.fake_send.call_count, 1) | |
277 | |
278 def test_set(self): | |
279 m = metrics.CounterMetric('test') | |
280 m.set(10) | |
281 self.assertEquals(m.get(), 10) | |
282 self.assertEquals(self.fake_send.call_count, 1) | |
283 | |
284 def test_increment(self): | |
285 m = metrics.CounterMetric('test') | |
286 m.set(1) | |
287 self.assertEquals(m.get(), 1) | |
288 self.assertEquals(self.fake_send.call_count, 1) | |
289 m.increment() | |
290 self.assertEquals(m.get(), 2) | |
291 self.assertEquals(self.fake_send.call_count, 2) | |
292 m.increment_by(3) | |
293 self.assertAlmostEquals(m.get(), 5) | |
294 self.assertEquals(self.fake_send.call_count, 3) | |
295 | |
296 def test_decrement_raises(self): | |
297 m = metrics.CounterMetric('test') | |
298 m.set(1) | |
299 with self.assertRaises(errors.MonitoringDecreasingValueError): | |
300 m.set(0) | |
301 with self.assertRaises(errors.MonitoringDecreasingValueError): | |
302 m.increment_by(-1) | |
303 | |
304 def test_non_int_raises(self): | |
305 m = metrics.CounterMetric('test') | |
306 with self.assertRaises(errors.MonitoringInvalidValueTypeError): | |
307 m.set(object()) | |
308 with self.assertRaises(errors.MonitoringInvalidValueTypeError): | |
309 m.set(1.5) | |
310 with self.assertRaises(errors.MonitoringInvalidValueTypeError): | |
311 m.increment_by(1.5) | |
312 | |
313 def test_multiple_field_values(self): | |
314 m = metrics.CounterMetric('test') | |
315 m.increment({'foo': 'bar'}) | |
316 m.increment({'foo': 'baz'}) | |
317 m.increment({'foo': 'bar'}) | |
318 self.assertEquals(0, m.get()) | |
319 self.assertEquals(2, m.get({'foo': 'bar'})) | |
320 self.assertEquals(1, m.get({'foo': 'baz'})) | |
321 | |
322 def test_override_fields(self): | |
323 m = metrics.CounterMetric('test', fields={'foo': 'bar'}) | |
324 m.increment() | |
325 m.increment({'foo': 'baz'}) | |
326 self.assertEquals(1, m.get()) | |
327 self.assertEquals(1, m.get({'foo': 'bar'})) | |
328 self.assertEquals(1, m.get({'foo': 'baz'})) | |
329 | |
330 def test_start_timestamp(self): | |
331 t = targets.DeviceTarget('reg', 'net', 'host') | |
332 m = metrics.CounterMetric( | |
333 'test', target=t, fields={'foo': 'bar'}, time_fn=lambda: 1234) | |
334 m.increment() | |
335 p = metrics_pb2.MetricsCollection() | |
336 m.serialize_to(p) | |
337 self.assertEquals(1234000000, p.data[0].start_timestamp_us) | |
338 | |
339 | |
340 class GaugeMetricTest(MetricTestBase): | |
341 | |
342 def test_populate_value(self): | |
343 pb = metrics_pb2.MetricsData() | |
344 m = metrics.GaugeMetric('test') | |
345 m._populate_value(pb, 1) | |
346 self.assertEquals(pb.gauge, 1) | |
347 | |
348 def test_set(self): | |
349 m = metrics.GaugeMetric('test') | |
350 m.set(10) | |
351 self.assertEquals(m.get(), 10) | |
352 self.assertEquals(self.fake_send.call_count, 1) | |
353 m.set(sys.maxint + 1) | |
354 self.assertEquals(m.get(), sys.maxint + 1) | |
355 self.assertEquals(self.fake_send.call_count, 2) | |
356 | |
357 def test_non_int_raises(self): | |
358 m = metrics.GaugeMetric('test') | |
359 with self.assertRaises(errors.MonitoringInvalidValueTypeError): | |
360 m.set(object()) | |
361 | |
362 def test_unset_increment_raises(self): | |
363 m = metrics.GaugeMetric('test') | |
364 with self.assertRaises(errors.MonitoringIncrementUnsetValueError): | |
365 m.increment() | |
366 | |
367 | |
368 class CumulativeMetricTest(MetricTestBase): | |
369 | |
370 def test_populate_value(self): | |
371 pb = metrics_pb2.MetricsData() | |
372 m = metrics.CumulativeMetric('test') | |
373 m._populate_value(pb, 1.618) | |
374 self.assertAlmostEquals(pb.cumulative_double_value, 1.618) | |
375 | |
376 def test_starts_at_zero(self): | |
377 m = metrics.CumulativeMetric('test') | |
378 self.assertEquals(m.get(), 0.0) | |
379 m.increment() | |
380 self.assertEquals(m.get(), 1.0) | |
381 self.assertEquals(self.fake_send.call_count, 1) | |
382 | |
383 def test_set(self): | |
384 m = metrics.CumulativeMetric('test') | |
385 m.set(3.14) | |
386 self.assertAlmostEquals(m.get(), 3.14) | |
387 self.assertEquals(self.fake_send.call_count, 1) | |
388 | |
389 def test_decrement_raises(self): | |
390 m = metrics.CumulativeMetric('test') | |
391 m.set(3.14) | |
392 with self.assertRaises(errors.MonitoringDecreasingValueError): | |
393 m.set(0) | |
394 with self.assertRaises(errors.MonitoringDecreasingValueError): | |
395 m.increment_by(-1) | |
396 | |
397 def test_non_number_raises(self): | |
398 m = metrics.CumulativeMetric('test') | |
399 with self.assertRaises(errors.MonitoringInvalidValueTypeError): | |
400 m.set(object()) | |
401 | |
402 def test_start_timestamp(self): | |
403 t = targets.DeviceTarget('reg', 'net', 'host') | |
404 m = metrics.CumulativeMetric( | |
405 'test', target=t, fields={'foo': 'bar'}, time_fn=lambda: 1234) | |
406 m.set(3.14) | |
407 p = metrics_pb2.MetricsCollection() | |
408 m.serialize_to(p) | |
409 self.assertEquals(1234000000, p.data[0].start_timestamp_us) | |
410 | |
411 | |
412 class FloatMetricTest(MetricTestBase): | |
413 | |
414 def test_populate_value(self): | |
415 pb = metrics_pb2.MetricsData() | |
416 m = metrics.FloatMetric('test') | |
417 m._populate_value(pb, 1.618) | |
418 self.assertEquals(pb.noncumulative_double_value, 1.618) | |
419 | |
420 def test_set(self): | |
421 m = metrics.FloatMetric('test') | |
422 m.set(3.14) | |
423 self.assertEquals(m.get(), 3.14) | |
424 self.assertEquals(self.fake_send.call_count, 1) | |
425 | |
426 def test_non_number_raises(self): | |
427 m = metrics.FloatMetric('test') | |
428 with self.assertRaises(errors.MonitoringInvalidValueTypeError): | |
429 m.set(object()) | |
430 | |
431 | |
432 class RunningZeroGeneratorTest(unittest.TestCase): | |
433 def assertZeroes(self, expected, sequence): | |
434 self.assertEquals(expected, | |
435 list(metrics.DistributionMetric._running_zero_generator(sequence))) | |
436 | |
437 def test_running_zeroes(self): | |
438 self.assertZeroes([1, -1, 1], [1, 0, 1]) | |
439 self.assertZeroes([1, -2, 1], [1, 0, 0, 1]) | |
440 self.assertZeroes([1, -3, 1], [1, 0, 0, 0, 1]) | |
441 self.assertZeroes([1, -1, 1, -1, 2], [1, 0, 1, 0, 2]) | |
442 self.assertZeroes([1, -1, 1, -2, 2], [1, 0, 1, 0, 0, 2]) | |
443 self.assertZeroes([1, -2, 1, -2, 2], [1, 0, 0, 1, 0, 0, 2]) | |
444 | |
445 def test_leading_zeroes(self): | |
446 self.assertZeroes([-1, 1], [0, 1]) | |
447 self.assertZeroes([-2, 1], [0, 0, 1]) | |
448 self.assertZeroes([-3, 1], [0, 0, 0, 1]) | |
449 | |
450 def test_trailing_zeroes(self): | |
451 self.assertZeroes([1], [1]) | |
452 self.assertZeroes([1], [1, 0]) | |
453 self.assertZeroes([1], [1, 0, 0]) | |
454 self.assertZeroes([], []) | |
455 self.assertZeroes([], [0]) | |
456 self.assertZeroes([], [0, 0]) | |
457 | |
458 | |
459 class DistributionMetricTest(MetricTestBase): | |
460 | |
461 def test_populate_canonical(self): | |
462 pb = metrics_pb2.MetricsData() | |
463 m = metrics.DistributionMetric('test') | |
464 m._populate_value(pb, | |
465 distribution.Distribution(distribution.GeometricBucketer())) | |
466 self.assertEquals(pb.distribution.spec_type, | |
467 metrics_pb2.PrecomputedDistribution.CANONICAL_POWERS_OF_10_P_0_2) | |
468 | |
469 m._populate_value(pb, | |
470 distribution.Distribution(distribution.GeometricBucketer(2))) | |
471 self.assertEquals(pb.distribution.spec_type, | |
472 metrics_pb2.PrecomputedDistribution.CANONICAL_POWERS_OF_2) | |
473 | |
474 m._populate_value(pb, | |
475 distribution.Distribution(distribution.GeometricBucketer(10))) | |
476 self.assertEquals(pb.distribution.spec_type, | |
477 metrics_pb2.PrecomputedDistribution.CANONICAL_POWERS_OF_10) | |
478 | |
479 def test_populate_custom(self): | |
480 pb = metrics_pb2.MetricsData() | |
481 m = metrics.DistributionMetric('test') | |
482 m._populate_value(pb, | |
483 distribution.Distribution(distribution.GeometricBucketer(4))) | |
484 self.assertEquals(pb.distribution.spec_type, | |
485 metrics_pb2.PrecomputedDistribution.CUSTOM_PARAMETERIZED) | |
486 self.assertEquals(0, pb.distribution.width) | |
487 self.assertEquals(4, pb.distribution.growth_factor) | |
488 self.assertEquals(100, pb.distribution.num_buckets) | |
489 | |
490 m._populate_value(pb, | |
491 distribution.Distribution(distribution.FixedWidthBucketer(10))) | |
492 self.assertEquals(pb.distribution.spec_type, | |
493 metrics_pb2.PrecomputedDistribution.CUSTOM_PARAMETERIZED) | |
494 self.assertEquals(10, pb.distribution.width) | |
495 self.assertEquals(0, pb.distribution.growth_factor) | |
496 self.assertEquals(100, pb.distribution.num_buckets) | |
497 | |
498 def test_populate_buckets(self): | |
499 pb = metrics_pb2.MetricsData() | |
500 m = metrics.DistributionMetric('test') | |
501 d = distribution.Distribution( | |
502 distribution.FixedWidthBucketer(10)) | |
503 d.add(5) | |
504 d.add(15) | |
505 d.add(35) | |
506 d.add(65) | |
507 | |
508 m._populate_value(pb, d) | |
509 self.assertEquals([1, 1, -1, 1, -2, 1], pb.distribution.bucket) | |
510 self.assertEquals(0, pb.distribution.underflow) | |
511 self.assertEquals(0, pb.distribution.overflow) | |
512 self.assertEquals(30, pb.distribution.mean) | |
513 | |
514 pb = metrics_pb2.MetricsData() | |
515 d = distribution.Distribution( | |
516 distribution.FixedWidthBucketer(10, num_finite_buckets=1)) | |
517 d.add(5) | |
518 d.add(15) | |
519 d.add(25) | |
520 | |
521 m._populate_value(pb, d) | |
522 self.assertEquals([1], pb.distribution.bucket) | |
523 self.assertEquals(0, pb.distribution.underflow) | |
524 self.assertEquals(2, pb.distribution.overflow) | |
525 self.assertEquals(15, pb.distribution.mean) | |
526 | |
527 def test_populate_buckets_last_zero(self): | |
528 pb = metrics_pb2.MetricsData() | |
529 m = metrics.DistributionMetric('test') | |
530 d = distribution.Distribution( | |
531 distribution.FixedWidthBucketer(10, num_finite_buckets=10)) | |
532 d.add(5) | |
533 d.add(105) | |
534 | |
535 m._populate_value(pb, d) | |
536 self.assertEquals([1], pb.distribution.bucket) | |
537 self.assertEquals(1, pb.distribution.overflow) | |
538 | |
539 def test_populate_buckets_underflow(self): | |
540 pb = metrics_pb2.MetricsData() | |
541 m = metrics.DistributionMetric('test') | |
542 d = distribution.Distribution( | |
543 distribution.FixedWidthBucketer(10, num_finite_buckets=10)) | |
544 d.add(-5) | |
545 d.add(-1000000) | |
546 | |
547 m._populate_value(pb, d) | |
548 self.assertEquals([], pb.distribution.bucket) | |
549 self.assertEquals(2, pb.distribution.underflow) | |
550 self.assertEquals(0, pb.distribution.overflow) | |
551 self.assertEquals(-500002.5, pb.distribution.mean) | |
552 | |
553 def test_populate_is_cumulative(self): | |
554 pb = metrics_pb2.MetricsData() | |
555 d = distribution.Distribution( | |
556 distribution.FixedWidthBucketer(10, num_finite_buckets=10)) | |
557 m = metrics.CumulativeDistributionMetric('test') | |
558 | |
559 m._populate_value(pb, d) | |
560 self.assertTrue(pb.distribution.is_cumulative) | |
561 | |
562 m = metrics.NonCumulativeDistributionMetric('test2') | |
563 | |
564 m._populate_value(pb, d) | |
565 self.assertFalse(pb.distribution.is_cumulative) | |
566 | |
567 def test_add(self): | |
568 m = metrics.DistributionMetric('test') | |
569 m.add(1) | |
570 m.add(10) | |
571 m.add(100) | |
572 self.assertEquals({2: 1, 6: 1, 11: 1}, m.get().buckets) | |
573 self.assertEquals(111, m.get().sum) | |
574 self.assertEquals(3, m.get().count) | |
575 | |
576 def test_add_custom_bucketer(self): | |
577 m = metrics.DistributionMetric('test', | |
578 bucketer=distribution.FixedWidthBucketer(10)) | |
579 m.add(1) | |
580 m.add(10) | |
581 m.add(100) | |
582 self.assertEquals({1: 1, 2: 1, 11: 1}, m.get().buckets) | |
583 self.assertEquals(111, m.get().sum) | |
584 self.assertEquals(3, m.get().count) | |
585 | |
586 def test_set(self): | |
587 d = distribution.Distribution( | |
588 distribution.FixedWidthBucketer(10, num_finite_buckets=10)) | |
589 d.add(1) | |
590 d.add(10) | |
591 d.add(100) | |
592 | |
593 m = metrics.CumulativeDistributionMetric('test') | |
594 with self.assertRaises(TypeError): | |
595 m.set(d) | |
596 | |
597 m = metrics.NonCumulativeDistributionMetric('test2') | |
598 m.set(d) | |
599 self.assertEquals(d, m.get()) | |
600 | |
601 with self.assertRaises(errors.MonitoringInvalidValueTypeError): | |
602 m.set(1) | |
603 with self.assertRaises(errors.MonitoringInvalidValueTypeError): | |
604 m.set('foo') | |
605 | |
606 def test_start_timestamp(self): | |
607 t = targets.DeviceTarget('reg', 'net', 'host') | |
608 m = metrics.CumulativeDistributionMetric( | |
609 'test', target=t, time_fn=lambda: 1234) | |
610 m.add(1) | |
611 m.add(5) | |
612 m.add(25) | |
613 p = metrics_pb2.MetricsCollection() | |
614 m.serialize_to(p) | |
615 self.assertEquals(1234000000, p.data[0].start_timestamp_us) | |
OLD | NEW |