blob: 88ee4337eb5037ebf6f34808d99dce7e0d6760ad [file] [log] [blame]
# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import time
import unittest
import mock
from infra_libs.ts_mon.common import metrics
from infra_libs.ts_mon.common import helpers
class _CustomException(Exception):
pass
class ScopedIncrementCounterTest(unittest.TestCase):
def setUp(self):
self.counter = mock.create_autospec(metrics.CounterMetric, spec_set=True)
def test_success(self):
with helpers.ScopedIncrementCounter(self.counter):
pass
self.counter.increment.assert_called_once_with({'status': 'success'})
def test_exception(self):
with self.assertRaises(_CustomException):
with helpers.ScopedIncrementCounter(self.counter):
raise _CustomException()
self.counter.increment.assert_called_once_with({'status': 'failure'})
def test_custom_status(self):
with helpers.ScopedIncrementCounter(self.counter) as sc:
sc.set_status('foo')
self.counter.increment.assert_called_once_with({'status': 'foo'})
def test_set_failure(self):
with helpers.ScopedIncrementCounter(self.counter) as sc:
sc.set_failure()
self.counter.increment.assert_called_once_with({'status': 'failure'})
def test_custom_status_and_exception(self):
with self.assertRaises(_CustomException):
with helpers.ScopedIncrementCounter(self.counter) as sc:
sc.set_status('foo')
raise _CustomException()
self.counter.increment.assert_called_once_with({'status': 'foo'})
def test_multiple_custom_status_calls(self):
with helpers.ScopedIncrementCounter(self.counter) as sc:
sc.set_status('foo')
sc.set_status('bar')
self.counter.increment.assert_called_once_with({'status': 'bar'})
def test_custom_label_success(self):
with helpers.ScopedIncrementCounter(self.counter, 'a', 'b', 'c'):
pass
self.counter.increment.assert_called_once_with({'a': 'b'})
def test_custom_label_exception(self):
with self.assertRaises(_CustomException):
with helpers.ScopedIncrementCounter(self.counter, 'a', 'b', 'c'):
raise _CustomException()
self.counter.increment.assert_called_once_with({'a': 'c'})
class ScopedMeasureTimeTest(unittest.TestCase):
def setUp(self):
# To avoid floating point nightmare, use values which are exact in IEEE754.
self.time_fn = mock.Mock(time.time, autospec=True, side_effect=[0.25, 0.50])
self.metric = mock.create_autospec(metrics.CumulativeDistributionMetric,
spec_set=True)
self.metric.field_spec = [metrics.StringField('status')]
self.metric.units = metrics.MetricsDataUnits.SECONDS
def test_wrong_field(self):
self.metric.field_spec = [metrics.StringField('wrong')]
with self.assertRaises(AssertionError):
helpers.ScopedMeasureTime(self.metric, 'status')
def test_bad_units(self):
self.metric.units = metrics.MetricsDataUnits.GIBIBYTES
with self.assertRaises(AssertionError):
helpers.ScopedMeasureTime(self.metric)
self.metric.units = ''
with self.assertRaises(AssertionError):
helpers.ScopedMeasureTime(self.metric)
def test_success(self):
with helpers.ScopedMeasureTime(self.metric, time_fn=self.time_fn):
pass
self.metric.add.assert_called_once_with(0.25, {'status': 'success'})
def test_exception(self):
with self.assertRaises(_CustomException):
with helpers.ScopedMeasureTime(self.metric, time_fn=self.time_fn):
raise _CustomException()
self.metric.add.assert_called_once_with(0.25, {'status': 'failure'})
def test_custom_status(self):
with helpers.ScopedMeasureTime(self.metric, time_fn=self.time_fn) as sd:
sd.set_status('foo')
self.metric.add.assert_called_once_with(0.25, {'status': 'foo'})
def test_set_failure(self):
with helpers.ScopedMeasureTime(self.metric, time_fn=self.time_fn) as sd:
sd.set_failure()
self.metric.add.assert_called_once_with(0.25, {'status': 'failure'})
def test_custom_status_and_exception(self):
with self.assertRaises(_CustomException):
with helpers.ScopedMeasureTime(self.metric, time_fn=self.time_fn) as sd:
sd.set_status('foo')
raise _CustomException()
self.metric.add.assert_called_once_with(0.25, {'status': 'foo'})
def test_multiple_custom_status_calls(self):
with helpers.ScopedMeasureTime(self.metric, time_fn=self.time_fn) as sd:
sd.set_status('foo')
sd.set_status('bar')
self.metric.add.assert_called_once_with(0.25, {'status': 'bar'})
def test_custom_success(self):
self.metric.field_spec = [metrics.StringField('label')]
self.metric.units = metrics.MetricsDataUnits.MILLISECONDS
with helpers.ScopedMeasureTime(self.metric, 'label', 'ok', 'fail',
time_fn=self.time_fn):
pass
self.metric.add.assert_called_once_with(250.0, {'label': 'ok'})
def test_custom_exception(self):
self.metric.field_spec = [metrics.StringField('label')]
self.metric.units = metrics.MetricsDataUnits.MICROSECONDS
with self.assertRaises(_CustomException):
with helpers.ScopedMeasureTime(self.metric, 'label', 'ok', 'fail',
time_fn=self.time_fn):
raise _CustomException()
self.metric.add.assert_called_once_with(250000.0, {'label': 'fail'})
def test_extra_fields_should_exclude_status(self):
with self.assertRaises(AssertionError):
helpers.ScopedMeasureTime(self.metric,
extra_fields_values={'status': 'x'})
def test_extra_fields(self):
self.metric.field_spec = [metrics.StringField('custom'),
metrics.StringField('type')]
with helpers.ScopedMeasureTime(self.metric, 'custom', 'ok', 'fail',
extra_fields_values={'type': 'normal'},
time_fn=self.time_fn):
pass
self.metric.add.assert_called_once_with(0.25, {'custom': 'ok',
'type': 'normal'})