package com.ldbc.driver.runtime.metrics; import com.ldbc.driver.generator.GeneratorFactory; import com.ldbc.driver.generator.RandomDataGeneratorFactory; import org.junit.Test; import java.util.Iterator; import java.util.concurrent.TimeUnit; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; public class ContinuousMetricManagerTest { // TODO look into this: hdrHistogram.getEstimatedFootprintInBytes() // TODO read highest durations from config instead of constants // TODO add tests to discover behavior when significant digits change. e.g., what happens if max value is high and actual measurements are low private final GeneratorFactory gf = new GeneratorFactory(new RandomDataGeneratorFactory(42l)); @Test public void shouldBehaveAsExpectedWithSimpleUsage() throws MetricsCollectionException { // Given String name = "name"; TimeUnit timeUnit = TimeUnit.MILLISECONDS; long highestExpectedValue = 3l; int numberOfSignificantDigits = 1; ContinuousMetricManager continuousMetricManager = new ContinuousMetricManager(name, timeUnit, highestExpectedValue, numberOfSignificantDigits); // When continuousMetricManager.addMeasurement(0l); continuousMetricManager.addMeasurement(0l); continuousMetricManager.addMeasurement(0l); continuousMetricManager.addMeasurement(0l); continuousMetricManager.addMeasurement(0l); continuousMetricManager.addMeasurement(0l); continuousMetricManager.addMeasurement(0l); continuousMetricManager.addMeasurement(1l); continuousMetricManager.addMeasurement(2l); continuousMetricManager.addMeasurement(3l); // Then ContinuousMetricSnapshot snapshot = continuousMetricManager.snapshot(); assertThat(snapshot.name(), is(name)); assertThat(snapshot.unit(), is(timeUnit)); assertThat(snapshot.count(), is(10l)); assertThat(snapshot.min(), is(0l)); assertThat(snapshot.max(), is(3l)); assertThat(snapshot.mean(), is(0.6d)); assertThat(snapshot.percentile50(), is(0l)); assertThat(snapshot.percentile90(), is(2l)); assertThat(snapshot.percentile95(), is(3l)); assertThat(snapshot.percentile99(), is(3l)); } @Test public void shouldBehaveAsExpectedWithHighNumberOfMeasurementsAndLargeRange() throws MetricsCollectionException { // Given String name = "name"; TimeUnit timeUnit = TimeUnit.MILLISECONDS; long highestExpectedValue = TimeUnit.MINUTES.toMillis(60); long lowestExpectedValue = TimeUnit.MINUTES.toMillis(1); long measurementCount = 10000000; int numberOfSignificantDigits = 5; ContinuousMetricManager continuousMetricManager = new ContinuousMetricManager(name, timeUnit, highestExpectedValue, numberOfSignificantDigits); // When Iterator<Long> measurements = gf.limit(gf.uniform(lowestExpectedValue, highestExpectedValue), measurementCount); while (measurements.hasNext()) { continuousMetricManager.addMeasurement(measurements.next()); } // Then double expectedMean = ((highestExpectedValue - lowestExpectedValue) / 2) + lowestExpectedValue; long expectedPercentile50 = (((highestExpectedValue - lowestExpectedValue) / 100) * 50) + lowestExpectedValue; long expectedPercentile90 = (((highestExpectedValue - lowestExpectedValue) / 100) * 90) + lowestExpectedValue; long expectedPercentile95 = (((highestExpectedValue - lowestExpectedValue) / 100) * 95) + lowestExpectedValue; long expectedPercentile99 = (((highestExpectedValue - lowestExpectedValue) / 100) * 99) + lowestExpectedValue; ContinuousMetricSnapshot snapshot = continuousMetricManager.snapshot(); assertThat(snapshot.name(), is(name)); assertThat(snapshot.unit(), is(timeUnit)); assertThat(snapshot.count(), is(measurementCount)); assertThat(withinTolerance(snapshot.mean(), expectedMean, 500d), is(true)); assertThat(withinTolerance(snapshot.percentile50(), expectedPercentile50, 500d), is(true)); assertThat(withinTolerance(snapshot.percentile90(), expectedPercentile90, 500d), is(true)); assertThat(withinTolerance(snapshot.percentile95(), expectedPercentile95, 500d), is(true)); assertThat(withinTolerance(snapshot.percentile99(), expectedPercentile99, 500d), is(true)); } private boolean withinTolerance(double actualValue, double expectedValue, double tolerance) { return (expectedValue - tolerance) <= actualValue && actualValue < expectedValue + tolerance; } }