| 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 |