package io.dropwizard.metrics; import static io.dropwizard.metrics.MetricRegistry.name; import org.junit.Before; import org.junit.Test; import io.dropwizard.metrics.Counter; import io.dropwizard.metrics.Gauge; import io.dropwizard.metrics.Histogram; import io.dropwizard.metrics.Meter; import io.dropwizard.metrics.Metric; import io.dropwizard.metrics.MetricFilter; import io.dropwizard.metrics.MetricName; import io.dropwizard.metrics.MetricRegistry; import io.dropwizard.metrics.MetricRegistryListener; import io.dropwizard.metrics.MetricSet; import io.dropwizard.metrics.Timer; import java.util.HashMap; import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.entry; import static org.mockito.Mockito.*; public class MetricRegistryTest { private static final MetricName TIMER2 = MetricName.build("timer"); private static final MetricName METER2 = MetricName.build("meter"); private static final MetricName HISTOGRAM2 = MetricName.build("histogram"); private static final MetricName COUNTER = MetricName.build("counter"); private static final MetricName COUNTER2 = MetricName.build("counter2"); private static final MetricName GAUGE = MetricName.build("gauge"); private static final MetricName GAUGE2 = MetricName.build("gauge2"); private static final MetricName THING = MetricName.build("thing"); private final MetricRegistryListener listener = mock(MetricRegistryListener.class); private final MetricRegistry registry = new MetricRegistry(); @SuppressWarnings("unchecked") private final Gauge<String> gauge = mock(Gauge.class); private final Counter counter = mock(Counter.class); private final Histogram histogram = mock(Histogram.class); private final Meter meter = mock(Meter.class); private final Timer timer = mock(Timer.class); @Before public void setUp() throws Exception { registry.addListener(listener); } @Test public void registeringAGaugeTriggersANotification() throws Exception { assertThat(registry.register(THING, gauge)) .isEqualTo(gauge); verify(listener).onGaugeAdded(THING, gauge); } @Test public void removingAGaugeTriggersANotification() throws Exception { registry.register(THING, gauge); assertThat(registry.remove(THING)) .isTrue(); verify(listener).onGaugeRemoved(THING); } @Test public void registeringACounterTriggersANotification() throws Exception { assertThat(registry.register(THING, counter)) .isEqualTo(counter); verify(listener).onCounterAdded(THING, counter); } @Test public void accessingACounterRegistersAndReusesTheCounter() throws Exception { final Counter counter1 = registry.counter(THING); final Counter counter2 = registry.counter(THING); assertThat(counter1) .isSameAs(counter2); verify(listener).onCounterAdded(THING, counter1); } @Test public void removingACounterTriggersANotification() throws Exception { registry.register(THING, counter); assertThat(registry.remove(THING)) .isTrue(); verify(listener).onCounterRemoved(THING); } @Test public void registeringAHistogramTriggersANotification() throws Exception { assertThat(registry.register(THING, histogram)) .isEqualTo(histogram); verify(listener).onHistogramAdded(THING, histogram); } @Test public void accessingAHistogramRegistersAndReusesIt() throws Exception { final Histogram histogram1 = registry.histogram(THING); final Histogram histogram2 = registry.histogram(THING); assertThat(histogram1) .isSameAs(histogram2); verify(listener).onHistogramAdded(THING, histogram1); } @Test public void removingAHistogramTriggersANotification() throws Exception { registry.register(THING, histogram); assertThat(registry.remove(THING)) .isTrue(); verify(listener).onHistogramRemoved(THING); } @Test public void registeringAMeterTriggersANotification() throws Exception { assertThat(registry.register(THING, meter)) .isEqualTo(meter); verify(listener).onMeterAdded(THING, meter); } @Test public void accessingAMeterRegistersAndReusesIt() throws Exception { final Meter meter1 = registry.meter(THING); final Meter meter2 = registry.meter(THING); assertThat(meter1) .isSameAs(meter2); verify(listener).onMeterAdded(THING, meter1); } @Test public void removingAMeterTriggersANotification() throws Exception { registry.register(THING, meter); assertThat(registry.remove(THING)) .isTrue(); verify(listener).onMeterRemoved(THING); } @Test public void registeringATimerTriggersANotification() throws Exception { assertThat(registry.register(THING, timer)) .isEqualTo(timer); verify(listener).onTimerAdded(THING, timer); } @Test public void accessingATimerRegistersAndReusesIt() throws Exception { final Timer timer1 = registry.timer(THING); final Timer timer2 = registry.timer(THING); assertThat(timer1) .isSameAs(timer2); verify(listener).onTimerAdded(THING, timer1); } @Test public void removingATimerTriggersANotification() throws Exception { registry.register(THING, timer); assertThat(registry.remove(THING)) .isTrue(); verify(listener).onTimerRemoved(THING); } @Test public void addingAListenerWithExistingMetricsCatchesItUp() throws Exception { registry.register(GAUGE2, gauge); registry.register(COUNTER2, counter); registry.register(HISTOGRAM2, histogram); registry.register(METER2, meter); registry.register(TIMER2, timer); final MetricRegistryListener other = mock(MetricRegistryListener.class); registry.addListener(other); verify(other).onGaugeAdded(GAUGE2, gauge); verify(other).onCounterAdded(COUNTER2, counter); verify(other).onHistogramAdded(HISTOGRAM2, histogram); verify(other).onMeterAdded(METER2, meter); verify(other).onTimerAdded(TIMER2, timer); } @Test public void aRemovedListenerDoesNotReceiveUpdates() throws Exception { registry.register(GAUGE, gauge); registry.removeListener(listener); registry.register(GAUGE2, gauge); verify(listener, never()).onGaugeAdded(GAUGE2, gauge); } @Test public void hasAMapOfRegisteredGauges() throws Exception { registry.register(GAUGE2, gauge); assertThat(registry.getGauges()) .contains(entry(GAUGE2, gauge)); } @Test public void hasAMapOfRegisteredCounters() throws Exception { registry.register(COUNTER2, counter); assertThat(registry.getCounters()) .contains(entry(COUNTER2, counter)); } @Test public void hasAMapOfRegisteredHistograms() throws Exception { registry.register(HISTOGRAM2, histogram); assertThat(registry.getHistograms()) .contains(entry(HISTOGRAM2, histogram)); } @Test public void hasAMapOfRegisteredMeters() throws Exception { registry.register(METER2, meter); assertThat(registry.getMeters()) .contains(entry(METER2, meter)); } @Test public void hasAMapOfRegisteredTimers() throws Exception { registry.register(TIMER2, timer); assertThat(registry.getTimers()) .contains(entry(TIMER2, timer)); } @Test public void hasASetOfRegisteredMetricNames() throws Exception { registry.register(GAUGE2, gauge); registry.register(COUNTER2, counter); registry.register(HISTOGRAM2, histogram); registry.register(METER2, meter); registry.register(TIMER2, timer); assertThat(registry.getNames()) .containsOnly(GAUGE2, COUNTER2, HISTOGRAM2, METER2, TIMER2); } @Test public void registersMultipleMetrics() throws Exception { final MetricSet metrics = new MetricSet() { @Override public Map<MetricName, Metric> getMetrics() { final Map<MetricName, Metric> metrics = new HashMap<>(); metrics.put(GAUGE2, gauge); metrics.put(COUNTER2, counter); return metrics; } }; registry.registerAll(metrics); assertThat(registry.getNames()) .containsOnly(GAUGE2, COUNTER2); } @Test public void registersMultipleMetricsWithAPrefix() throws Exception { final MetricName myCounter = MetricName.build("my.counter"); final MetricName myGauge = MetricName.build("my.gauge"); final MetricSet metrics = new MetricSet() { @Override public Map<MetricName, Metric> getMetrics() { final Map<MetricName, Metric> metrics = new HashMap<>(); metrics.put(GAUGE, gauge); metrics.put(COUNTER, counter); return metrics; } }; registry.register("my", metrics); assertThat(registry.getNames()) .containsOnly(myGauge, myCounter); } @Test public void registersRecursiveMetricSets() throws Exception { final MetricSet inner = new MetricSet() { @Override public Map<MetricName, Metric> getMetrics() { final Map<MetricName, Metric> metrics = new HashMap<>(); metrics.put(GAUGE, gauge); return metrics; } }; final MetricSet outer = new MetricSet() { @Override public Map<MetricName, Metric> getMetrics() { final Map<MetricName, Metric> metrics = new HashMap<>(); metrics.put(MetricName.build("inner"), inner); metrics.put(COUNTER, counter); return metrics; } }; registry.register("my", outer); final MetricName myCounter = MetricName.build("my.counter"); final MetricName myInnerGauge = MetricName.build("my.inner.gauge"); assertThat(registry.getNames()) .containsOnly(myInnerGauge, myCounter); } @Test public void registersMetricsFromAnotherRegistry() throws Exception { MetricRegistry other = new MetricRegistry(); other.register(GAUGE, gauge); registry.register("nested", other); assertThat(registry.getNames()).containsOnly(MetricName.build("nested.gauge")); } @Test public void concatenatesStringsToFormADottedName() throws Exception { assertThat(name("one", "two", "three")) .isEqualTo(MetricName.build("one.two.three")); } @Test @SuppressWarnings("NullArgumentToVariableArgMethod") public void elidesNullValuesFromNamesWhenOnlyOneNullPassedIn() throws Exception { assertThat(name("one", (String)null)) .isEqualTo(MetricName.build("one")); } @Test public void elidesNullValuesFromNamesWhenManyNullsPassedIn() throws Exception { assertThat(name("one", null, null)) .isEqualTo(MetricName.build("one")); } @Test public void elidesNullValuesFromNamesWhenNullAndNotNullPassedIn() throws Exception { assertThat(name("one", null, "three")) .isEqualTo(MetricName.build("one.three")); } @Test public void elidesEmptyStringsFromNames() throws Exception { assertThat(name("one", "", "three")) .isEqualTo(MetricName.build("one.three")); } @Test public void concatenatesClassNamesWithStringsToFormADottedName() throws Exception { assertThat(name(MetricRegistryTest.class, "one", "two")) .isEqualTo(MetricName.build("io.dropwizard.metrics.MetricRegistryTest.one.two")); } @Test public void concatenatesClassesWithoutCanonicalNamesWithStrings() throws Exception { final Gauge<String> g = new Gauge<String>() { @Override public String getValue() { return null; } }; assertThat(name(g.getClass(), "one", "two")) .isEqualTo(MetricName.build(g.getClass().getName() + ".one.two")); } @Test public void removesMetricsMatchingAFilter() throws Exception { final MetricName timer1 = MetricName.build("timer-1"); final MetricName timer2 = MetricName.build("timer-2"); final MetricName histogram1 = MetricName.build("histogram-1"); registry.timer(timer1); registry.timer(timer2); registry.histogram(histogram1); assertThat(registry.getNames()) .contains(timer1, timer2, histogram1); assertThat(registry.removeMatching(new MetricFilter() { @Override public boolean matches(MetricName name, Metric metric) { return name.getKey().endsWith("1"); } })).isTrue(); assertThat(registry.getNames()) .doesNotContain(timer1, histogram1); assertThat(registry.getNames()) .contains(timer2); verify(listener).onTimerRemoved(timer1); verify(listener).onHistogramRemoved(histogram1); } }