class GaugeTest(unittest.TestCase): tid = MeterId("test") def test_set(self): g = Gauge(GaugeTest.tid) self.assertTrue(math.isnan(g.get())) g.set(1) self.assertEqual(1, g.get()) def test_measure(self): g = Gauge(GaugeTest.tid) g.set(42) ms = g._measure() self.assertEqual(42, g.get()) self.assertEqual(1, len(ms)) self.assertEqual(42, ms[GaugeTest.tid.with_stat('gauge')]) def test_ttl_reset(self): clock = ManualClock() g = Gauge(GaugeTest.tid, clock=clock) g.set(42) clock.set_wall_time(g.ttl + 1) ms = g._measure() self.assertTrue(math.isnan(g.get())) self.assertEqual(1, len(ms)) self.assertEqual(42, ms[GaugeTest.tid.with_stat('gauge')]) def test_user_statistic(self): g = Gauge(GaugeTest.tid.with_stat('duration')) g.set(42) for id in g._measure().keys(): self.assertEqual('duration', id.tags()['statistic'])
class PercentileTimerTest(unittest.TestCase): tid = MeterId("test") def test_invalid_meter_type(self): with self.assertRaises(ValueError): Timer(self.tid, meter_type='x') def test_record(self): t = Timer(self.tid, meter_type="T", writer=MemoryWriter()) self.assertTrue(t._writer.is_empty()) t.record(42) self.assertEqual("T:test:42", t._writer.last_line()) def test_record_negative(self): t = Timer(self.tid, meter_type="T", writer=MemoryWriter()) t.record(-42) self.assertTrue(t._writer.is_empty()) def test_record_zero(self): t = Timer(self.tid, meter_type="T", writer=MemoryWriter()) t.record(0) self.assertEqual("T:test:0", t._writer.last_line()) def test_stopwatch(self): clock = ManualClock() t = Timer(self.tid, clock=clock, meter_type="T", writer=MemoryWriter()) with t.stopwatch(): clock.set_monotonic_time(42) self.assertEqual("T:test:42", t._writer.last_line())
class PercentileDistributionSummaryTest(unittest.TestCase): tid = MeterId("test") def test_invalid_meter_type(self): with self.assertRaises(ValueError): DistributionSummary(self.tid, meter_type='x') def test_record(self): d = DistributionSummary(self.tid, meter_type="D", writer=MemoryWriter()) self.assertTrue(d._writer.is_empty()) d.record(42) self.assertEqual("D:test:42", d._writer.last_line()) def test_record_negative(self): d = DistributionSummary(self.tid, meter_type="D", writer=MemoryWriter()) d.record(-42) self.assertTrue(d._writer.is_empty()) def test_record_zero(self): d = DistributionSummary(self.tid, meter_type="D", writer=MemoryWriter()) d.record(0) self.assertEqual("D:test:0", d._writer.last_line())
class CounterTest(unittest.TestCase): tid = MeterId("test") def test_increment(self): c = Counter(CounterTest.tid) self.assertEqual(c.count(), 0) c.increment() self.assertEqual(c.count(), 1) def test_increment_negative(self): c = Counter(CounterTest.tid) c.increment(-1) self.assertEqual(c.count(), 0) def test_measure(self): c = Counter(CounterTest.tid) c.increment() ms = c._measure() self.assertEqual(len(ms), 1) self.assertEqual(ms[CounterTest.tid.with_stat('count')], 1) self.assertEqual(c.count(), 0) def test_user_statistic(self): c = Counter(CounterTest.tid.with_stat('totalTime')) c.increment() for id in c._measure().keys(): self.assertEqual('totalTime', id.tags()['statistic'])
class DistributionSummaryTest(unittest.TestCase): tid = MeterId("test") def test_invalid_meter_type(self): with self.assertRaises(ValueError): DistributionSummary(self.tid, meter_type='x') def test_record(self): d = DistributionSummary(self.tid, writer=MemoryWriter()) self.assertTrue(d._writer.is_empty()) d.record(42) self.assertEqual("d:test:42", d._writer.last_line()) def test_record_negative(self): d = DistributionSummary(self.tid, writer=MemoryWriter()) d.record(-42) self.assertTrue(d._writer.is_empty()) def test_record_zero(self): d = DistributionSummary(self.tid, writer=MemoryWriter()) d.record(0) self.assertEqual("d:test:0", d._writer.last_line()) def test_count_and_total_amount(self): """Avoid breaking the API.""" d = DistributionSummary(self.tid, writer=MemoryWriter()) self.assertTrue(d._writer.is_empty()) d.record(42) self.assertEqual(0, d.count()) self.assertEqual(0, d.total_amount())
class MaxGaugeTest(unittest.TestCase): tid = MeterId("test") def test_set(self): g = MaxGauge(self.tid, writer=MemoryWriter()) self.assertTrue(g._writer.is_empty()) g.set(0) self.assertEqual("m:test:0", g._writer.last_line())
def _create_id_string(self, meter_id: MeterId, meter_type: str) -> str: s = "{}:{}".format(meter_type, self._replace_invalid_chars(meter_id.name)) for key, value in sorted(meter_id.tags().items()): k = self._replace_invalid_chars(key) v = self._replace_invalid_chars(value) s += ",{}={}".format(k, v) return s + ":"
def _new_meter(self, name, tags, meterFactory): with self._lock: if tags is None: tags = {} meterId = MeterId(name, tags) meter = self._meters.get(meterId, None) if meter is None: meter = meterFactory(meterId) self._meters[meterId] = meter return meter
def _new_meter(self, name, tags, meterFactory, meterCls, defaultIns): with self._lock: if tags is None: tags = {} meterId = MeterId(name, tags) meter = self._meters.get(meterId, None) if meter is None: meter = meterFactory(meterId) self._meters[meterId] = meter elif not isinstance(meter, meterCls): logger.warning("Meter is already defined as type %s. " "Please use a unique name or tags", meter.__class__.__name__) return defaultIns return meter
class DistributionSummaryTest(unittest.TestCase): tid = MeterId("test") def test_record(self): t = DistributionSummary(DistributionSummaryTest.tid) t.record(42) self.assertEqual(t.count(), 1) self.assertEqual(t.total_amount(), 42) def test_record_negative(self): t = DistributionSummary(DistributionSummaryTest.tid) t.record(-42) self.assertEqual(t.count(), 0) self.assertEqual(t.total_amount(), 0) def test_record_zero(self): t = DistributionSummary(DistributionSummaryTest.tid) t.record(0) self.assertEqual(t.count(), 1) self.assertEqual(t.total_amount(), 0) def test_record_multiple(self): t = DistributionSummary(DistributionSummaryTest.tid) t.record(42) t.record(2) t.record(7) self.assertEqual(t.count(), 3) self.assertEqual(t.total_amount(), 51) def test_measure(self): t = DistributionSummary(DistributionSummaryTest.tid) t.record(42) t.record(2) t.record(7) ms = t._measure() def get_stat(s): return ms[DistributionSummaryTest.tid.with_stat(s)] self.assertEqual(len(ms), 4) self.assertEqual(get_stat('count'), 3) self.assertEqual(get_stat('totalAmount'), 51) self.assertEqual(get_stat('max'), 42) self.assertEqual(get_stat('totalOfSquares'), 42**2 + 2**2 + 7**2) self.assertEqual(t.count(), 0) self.assertEqual(t.total_amount(), 0)
class MonotonicCounterTest(unittest.TestCase): tid = MeterId("test") def test_set(self): c = MonotonicCounter(self.tid, writer=MemoryWriter()) self.assertTrue(c._writer.is_empty()) c.set(1) self.assertEqual("C:test:1", c._writer.last_line()) def test_set_negative(self): c = MonotonicCounter(self.tid, writer=MemoryWriter()) self.assertTrue(c._writer.is_empty()) c.set(-1) self.assertEqual("C:test:-1", c._writer.last_line())
class GaugeTest(unittest.TestCase): tid = MeterId("test") def test_set(self): g = Gauge(GaugeTest.tid) self.assertTrue(math.isnan(g.get())) g.set(1) self.assertEqual(g.get(), 1) def test_measure(self): g = Gauge(GaugeTest.tid) g.set(42) ms = g._measure() self.assertTrue(math.isnan(g.get())) self.assertEqual(len(ms), 1) self.assertEqual(ms[GaugeTest.tid.with_stat('gauge')], 42)
class CounterTest(unittest.TestCase): tid = MeterId("test") def test_increment(self): c = Counter(self.tid, writer=MemoryWriter()) self.assertTrue(c._writer.is_empty()) c.increment() self.assertEqual("c:test:1", c._writer.last_line()) def test_increment_negative(self): c = Counter(self.tid, writer=MemoryWriter()) c.increment(-1) self.assertTrue(c._writer.is_empty()) def test_count(self): """Avoid breaking the API.""" c = Counter(self.tid, writer=MemoryWriter()) c.increment() self.assertEqual(0, c.count())
class GaugeTest(unittest.TestCase): tid = MeterId("test") def test_set(self): g = Gauge(self.tid, writer=MemoryWriter()) self.assertTrue(g._writer.is_empty()) g.set(1) self.assertEqual("g:test:1", g._writer.last_line()) def test_custom_ttl(self): g = Gauge(self.tid, ttl_seconds=120, writer=MemoryWriter()) g.set(42) self.assertEqual("g,120:test:42", g._writer.last_line()) def test_get(self): """Avoid breaking the API.""" g = Gauge(self.tid, writer=MemoryWriter()) g.set(1) self.assertEqual(0, g.get())
class TimerTest(unittest.TestCase): tid = MeterId("test") def test_invalid_meter_type(self): with self.assertRaises(ValueError): Timer(self.tid, meter_type='x') def test_record(self): t = Timer(self.tid, writer=MemoryWriter()) self.assertTrue(t._writer.is_empty()) t.record(42) self.assertEqual("t:test:42", t._writer.last_line()) def test_record_negative(self): t = Timer(self.tid, writer=MemoryWriter()) t.record(-42) self.assertTrue(t._writer.is_empty()) def test_record_zero(self): t = Timer(self.tid, writer=MemoryWriter()) t.record(0) self.assertEqual("t:test:0", t._writer.last_line()) def test_stopwatch(self): clock = ManualClock() t = Timer(self.tid, clock=clock, writer=MemoryWriter()) with t.stopwatch(): clock.set_monotonic_time(42) self.assertEqual("t:test:42", t._writer.last_line()) def test_count_and_total_time(self): """Avoid breaking the API.""" t = Timer(self.tid, writer=MemoryWriter()) self.assertTrue(t._writer.is_empty()) t.record(42) self.assertEqual(0, t.count()) self.assertEqual(0, t.total_time())
class CounterTest(unittest.TestCase): tid = MeterId("test") def test_increment(self): c = Counter(CounterTest.tid) self.assertEqual(c.count(), 0) c.increment() self.assertEqual(c.count(), 1) def test_increment_negative(self): c = Counter(CounterTest.tid) c.increment(-1) self.assertEqual(c.count(), 0) def test_measure(self): c = Counter(CounterTest.tid) c.increment() ms = c._measure() self.assertEqual(len(ms), 1) self.assertEqual(ms[CounterTest.tid.with_stat('count')], 1) self.assertEquals(c.count(), 0)
def test_id_with_illegal_chars(self): tid = MeterId("test`!@#$%^&*()-=~_+[]{}\\|;:'\",<.>/?foo") m = SidecarMeter(tid, "g,120") self.assertEqual("g,120:test______^____-_~______________.___foo:", m.idString)
def test_lookup_tags(self): id1 = MeterId("foo", {"a": "1", "b": "2", "c": "3"}) id2 = MeterId("foo", {"c": "3", "b": "2", "a": "1"}) d = {id1: "test"} self.assertEqual("test", d[id2])
def test_id_with_tags(self): tid = MeterId("test", {"foo": "bar", "baz": "quux"}) m = SidecarMeter(tid, "g,120") self.assertEqual("g,120:test,baz=quux,foo=bar:", m.idString)
def test_tags(self): id1 = MeterId("foo", {"a": "1"}) self.assertEqual({"a": "1"}, id1.tags())
def test_tags_defensive_copy(self): id1 = MeterId("foo", {"a": "1"}) tags = id1.tags() tags["b"] = "2" self.assertEqual({"a": "1", "b": "2"}, tags) self.assertEqual({"a": "1"}, id1.tags())
def test_different_types_not_equal(self): id1 = MeterId("foo", {"a": "1"}) self.assertTrue(id1 != 1)
def test_with_tags_returns_new_object(self): id1 = MeterId("foo") id2 = id1.with_tags({"a": "1", "b": "2"}) self.assertNotEqual(id1, id2) self.assertEqual({}, id1.tags()) self.assertEqual({"a": "1", "b": "2"}, id2.tags())
def test_hash_tags(self): id1 = MeterId("foo", {"a": "1", "b": "2", "c": "3"}) id2 = MeterId("foo", {"c": "3", "b": "2", "a": "1"}) self.assertEqual(hash(id1), hash(id2))
def _new_meter(self, name: str, tags: Optional[dict] = None) -> MeterId: if tags is None: tags = {} return self._merge_common_tags(MeterId(name, tags))
def test_equals_same_name(self): id1 = MeterId("foo") id2 = MeterId("foo") self.assertEqual(id1, id2)
def test_id(self): tid = MeterId("test") m = SidecarMeter(tid, "g,120") self.assertEqual("g,120:test:", m.idString)
def test_with_default_stat(self): """Avoid breaking the API.""" id1 = MeterId("foo") self.assertEqual(id1, id1.with_default_stat("bar"))
def test_str(self): id1 = MeterId("foo") self.assertEqual("foo", str(id1)) id2 = MeterId("foo", {"a": "1", "b": "2", "c": "3"}) self.assertEqual("foo,a=1,b=2,c=3", str(id2))
def test_equals_tags(self): id1 = MeterId("foo", {"a": "1", "b": "2", "c": "3"}) id2 = MeterId("foo", {"c": "3", "b": "2", "a": "1"}) self.assertEqual(id1, id2)