package io.dropwizard.metrics; import org.junit.Test; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import org.junit.runner.RunWith; import io.dropwizard.metrics.Meter; import java.util.Arrays; import java.util.Collection; import java.util.concurrent.TimeUnit; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.offset; @RunWith(value = Parameterized.class) public class MeterApproximationTest { @Parameters public static Collection<Object[]> ratesPerMinute() { Object[][] data = new Object[][] { { 15 }, { 60 }, { 600 }, { 6000 } }; return Arrays.asList(data); } private final long ratePerMinute; public MeterApproximationTest(long ratePerMinute) { this.ratePerMinute = ratePerMinute; } @Test public void controlMeter1MinuteMeanApproximation() throws Exception { final Meter meter = simulateMetronome( 62934, TimeUnit.MILLISECONDS, 3, TimeUnit.MINUTES); assertThat(meter.getOneMinuteRate()*60.0) .isEqualTo(ratePerMinute, offset(0.1*ratePerMinute)); } @Test public void controlMeter5MinuteMeanApproximation() throws Exception { final Meter meter = simulateMetronome( 62934, TimeUnit.MILLISECONDS, 13, TimeUnit.MINUTES); assertThat(meter.getFiveMinuteRate()*60.0) .isEqualTo(ratePerMinute, offset(0.1*ratePerMinute)); } @Test public void controlMeter15MinuteMeanApproximation() throws Exception { final Meter meter = simulateMetronome( 62934, TimeUnit.MILLISECONDS, 38, TimeUnit.MINUTES); assertThat(meter.getFifteenMinuteRate()*60.0) .isEqualTo(ratePerMinute, offset(0.1*ratePerMinute)); } private Meter simulateMetronome( long introDelay, TimeUnit introDelayUnit, long duration, TimeUnit durationUnit) { final ManualClock clock = new ManualClock(); final Meter meter = new Meter(clock); clock.addNanos(introDelayUnit.toNanos(introDelay)); final long endTick = clock.getTick() + durationUnit.toNanos(duration); final long marksIntervalInNanos = TimeUnit.MINUTES.toNanos(1) / ratePerMinute; while (clock.getTick() <= endTick) { clock.addNanos(marksIntervalInNanos); meter.mark(); } return meter; } }