/*
* Copyright 2017 LinkedIn Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package azkaban.metrics;
import com.codahale.metrics.Counter;
import com.codahale.metrics.Gauge;
import com.codahale.metrics.Histogram;
import com.codahale.metrics.Meter;
import com.codahale.metrics.MetricFilter;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.ScheduledReporter;
import com.codahale.metrics.Timer;
import org.junit.Assert;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
/**
* This class is designed for a utility class to test drop wizard metrics
*/
public class MetricsTestUtility {
/**
* One Dummy Reporter extending {@link ScheduledReporter} collects metrics in various maps,
* which test methods are able to access easily.
*/
public static class DummyReporter extends ScheduledReporter{
private Map<String, String> gaugeMap;
private Map<String, Long> meterMap;
public DummyReporter(MetricRegistry registry) {
super(registry, "dummy-reporter", MetricFilter.ALL, TimeUnit.SECONDS, TimeUnit.MILLISECONDS);
this.gaugeMap = new HashMap<>();
this.meterMap = new HashMap<>();
}
@Override
public void report(SortedMap<String, Gauge> gauges,
SortedMap<String, Counter> counters,
SortedMap<String, Histogram> histograms,
SortedMap<String, Meter> meters,
SortedMap<String, Timer> timers) {
for (Map.Entry<String, Gauge> entry : gauges.entrySet()) {
gaugeMap.put(entry.getKey(), entry.getValue().getValue().toString());
}
for (Map.Entry<String, Meter> entry : meters.entrySet()) {
meterMap.put(entry.getKey(), entry.getValue().getCount());
}
}
private String getGauge(String key) {
return gaugeMap.get(key);
}
private long getMeter(String key) {
return meterMap.getOrDefault(key, 0L);
}
}
public static void testMeter(String meterName, DummyReporter dr, Runnable runnable) {
sleepMillis(20);
long currMeter = dr.getMeter(meterName);
runnable.run();
sleepMillis(20);
Assert.assertEquals(dr.getMeter(meterName), currMeter + 1);
runnable.run();
runnable.run();
sleepMillis(20);
Assert.assertEquals(dr.getMeter(meterName), currMeter + 3);
}
public static void testGauge(String meterName, DummyReporter dr, Runnable runnable) {
sleepMillis(20);
long currMeter = Long.valueOf(dr.getGauge(meterName));
runnable.run();
sleepMillis(20);
Assert.assertEquals(Long.valueOf(dr.getGauge(meterName)).longValue(), currMeter + 1);
runnable.run();
runnable.run();
sleepMillis(20);
Assert.assertEquals(Long.valueOf(dr.getGauge(meterName)).longValue(), currMeter + 3);
}
public static void testGauge(String GaugeName, DummyReporter dr, Consumer<Long> func) {
func.accept(1L);
// needs time to let metrics reporter receive the updated value.
sleepMillis(50);
Assert.assertEquals(dr.getGauge(GaugeName), "1");
func.accept(99L);
sleepMillis(50);
Assert.assertEquals(dr.getGauge(GaugeName), "99");
}
/**
* Helper method to sleep milli seconds.
*/
private static void sleepMillis(int numMilli) {
try {
Thread.sleep(numMilli);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}