Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(217)

Side by Side Diff: infra_libs/ts_mon/test/metrics_test.py

Issue 1260293009: make version of ts_mon compatible with appengine (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: add noncululativedistribution metric to ts_mon imports Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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)
OLDNEW
« no previous file with comments | « infra_libs/ts_mon/test/interface_test.py ('k') | infra_libs/ts_mon/test/standard_metrics_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698