Skip to content

Commit

Permalink
Tolerate MP Metrics 5.0 API changes
Browse files Browse the repository at this point in the history
- Methods removed from Snapshot
- Gauge<T> changed to Gauge<T extends Number>
  - Breaks binary compatibility because method signatures are different
    after type erasure
  • Loading branch information
Azquelt committed Oct 3, 2022
1 parent 0cc75cb commit 0172e71
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 40 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Contributors to the Eclipse Foundation
* Copyright (c) 2018-2022 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
Expand All @@ -19,20 +19,16 @@
package org.eclipse.microprofile.fault.tolerance.tck.metrics;

import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.stream.Collectors.toList;
import static org.eclipse.microprofile.fault.tolerance.tck.metrics.util.MetricComparator.approxMillis;
import static org.eclipse.microprofile.fault.tolerance.tck.metrics.util.MetricComparator.lessThanMillis;
import static org.eclipse.microprofile.fault.tolerance.tck.metrics.util.MetricDefinition.BulkheadResult.ACCEPTED;
import static org.eclipse.microprofile.fault.tolerance.tck.metrics.util.MetricDefinition.BulkheadResult.REJECTED;
import static org.eclipse.microprofile.fault.tolerance.tck.metrics.util.MetricDefinition.InvocationResult.EXCEPTION_THROWN;
import static org.eclipse.microprofile.fault.tolerance.tck.metrics.util.MetricDefinition.InvocationResult.VALUE_RETURNED;
import static org.eclipse.microprofile.fault.tolerance.tck.util.Exceptions.expectBulkheadException;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.is;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
Expand Down Expand Up @@ -169,7 +165,6 @@ public void bulkheadMetricRejectionTest() throws InterruptedException, Execution
}

@Test
@SuppressWarnings("unchecked")
public void bulkheadMetricHistogramTest() throws InterruptedException, ExecutionException, TimeoutException {
MetricGetter m = new MetricGetter(BulkheadMetricBean.class, "waitForHistogram");
m.baselineMetrics();
Expand All @@ -194,7 +189,6 @@ public void bulkheadMetricHistogramTest() throws InterruptedException, Execution

assertThat("histogram count", executionTimes.getCount(), is(2L)); // Rejected executions not recorded in
// histogram
assertThat("median", Math.round(snap.getMedian()), approxMillis(1000));
assertThat("mean", Math.round(snap.getMean()), approxMillis(1000));

// Now let's put some quick results through the bulkhead
Expand All @@ -204,15 +198,9 @@ public void bulkheadMetricHistogramTest() throws InterruptedException, Execution
// Should have 4 results, ~0ms * 2 and ~1000ms * 2
snap = executionTimes.getSnapshot();
assertThat("histogram count", executionTimes.getCount(), is(4L));
List<Long> values = Arrays.stream(snap.getValues()).sorted().boxed().collect(toList());
assertThat("histogram values", values, contains(lessThanMillis(500),
lessThanMillis(500),
approxMillis(1000),
approxMillis(1000)));
}

@Test
@SuppressWarnings("unchecked")
public void bulkheadMetricAsyncTest() throws InterruptedException, ExecutionException, TimeoutException {
MetricGetter m = new MetricGetter(BulkheadMetricBean.class, "waitForAsync");
m.baselineMetrics();
Expand All @@ -222,7 +210,6 @@ public void bulkheadMetricAsyncTest() throws InterruptedException, ExecutionExce
Future<?> f1 = bulkheadBean.waitForAsync(waitingFuture);
Future<?> f2 = bulkheadBean.waitForAsync(waitingFuture);
bulkheadBean.waitForRunningExecutions(2);
long startTime = System.nanoTime();

Future<?> f3 = bulkheadBean.waitForAsync(waitingFuture);
Future<?> f4 = bulkheadBean.waitForAsync(waitingFuture);
Expand All @@ -235,10 +222,6 @@ public void bulkheadMetricAsyncTest() throws InterruptedException, ExecutionExce

Thread.sleep(config.getTimeoutInMillis(1000));
waitingFuture.complete(null);
long durationms = (System.nanoTime() - startTime) / 1_000_000;
durationms /= config.getBaseMultiplier(); // This value is used with approxMillis which always applies the
// baseMultiplier
// so preemptively divide it by the baseMultiplier here

f1.get(1, MINUTES);
f2.get(1, MINUTES);
Expand All @@ -250,15 +233,9 @@ public void bulkheadMetricAsyncTest() throws InterruptedException, ExecutionExce
assertThat("rejections", m.getBulkheadCalls(REJECTED).delta(), is(1L));

Histogram queueWaits = m.getBulkheadWaitingDuration().get();
Snapshot snap = queueWaits.getSnapshot();
List<Long> values = Arrays.stream(snap.getValues()).sorted().boxed().collect(toList());

// Expect 2 * wait for 0ms, 2 * wait for durationms
assertThat("waiting duration histogram counts", queueWaits.getCount(), is(4L));
assertThat("waiting duration histogram values", values, contains(lessThanMillis(500),
lessThanMillis(500),
approxMillis(durationms),
approxMillis(durationms)));

// General metrics should be updated
assertThat("successful invocations", m.getInvocations(VALUE_RETURNED, InvocationFallback.NOT_DEFINED).delta(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Contributors to the Eclipse Foundation
* Copyright (c) 2018-2022 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
Expand All @@ -18,27 +18,20 @@
*/
package org.eclipse.microprofile.fault.tolerance.tck.metrics;

import static java.util.stream.Collectors.toList;
import static org.eclipse.microprofile.fault.tolerance.tck.metrics.util.MetricDefinition.InvocationResult.EXCEPTION_THROWN;
import static org.eclipse.microprofile.fault.tolerance.tck.metrics.util.MetricDefinition.InvocationResult.VALUE_RETURNED;
import static org.eclipse.microprofile.fault.tolerance.tck.util.Exceptions.expectTimeout;
import static org.eclipse.microprofile.fault.tolerance.tck.util.TCKConfig.getConfig;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.is;

import java.util.Arrays;
import java.util.List;

import org.eclipse.microprofile.fault.tolerance.tck.config.ConfigAnnotationAsset;
import org.eclipse.microprofile.fault.tolerance.tck.metrics.util.MetricComparator;
import org.eclipse.microprofile.fault.tolerance.tck.metrics.util.MetricDefinition.InvocationFallback;
import org.eclipse.microprofile.fault.tolerance.tck.metrics.util.MetricDefinition.TimeoutTimedOut;
import org.eclipse.microprofile.fault.tolerance.tck.metrics.util.MetricGetter;
import org.eclipse.microprofile.fault.tolerance.tck.util.Packages;
import org.eclipse.microprofile.faulttolerance.Timeout;
import org.eclipse.microprofile.metrics.Histogram;
import org.eclipse.microprofile.metrics.Snapshot;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.testng.Arquillian;
import org.jboss.shrinkwrap.api.ShrinkWrap;
Expand Down Expand Up @@ -95,7 +88,6 @@ public void testTimeoutMetric() {
}

@Test
@SuppressWarnings("unchecked")
public void testTimeoutHistogram() {
MetricGetter m = new MetricGetter(TimeoutMetricBean.class, "histogramTestWorkForMillis");

Expand All @@ -105,12 +97,8 @@ public void testTimeoutHistogram() {
// after 2000

Histogram histogram = m.getTimeoutExecutionDuration().get();
Snapshot snapshot = histogram.getSnapshot();
List<Long> values = Arrays.stream(snapshot.getValues()).boxed().sorted().collect(toList());

assertThat("Histogram count", histogram.getCount(), is(2L));
assertThat("SnapshotValues", values, contains(MetricComparator.approxMillis(300),
MetricComparator.approxMillis(2000)));
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (c) 2020 Contributors to the Eclipse Foundation
* Copyright (c) 2020-2022 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
Expand All @@ -23,6 +23,8 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.instanceOf;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Optional;

import org.eclipse.microprofile.metrics.Counter;
Expand All @@ -43,6 +45,16 @@ public class GaugeMetric {
private MetricID metricId;
private long baseline;

private static final Method GET_VALUE_METHOD;

static {
try {
GET_VALUE_METHOD = Gauge.class.getMethod("getValue");
} catch (NoSuchMethodException | SecurityException e1) {
throw new RuntimeException(e1);
}
}

public GaugeMetric(MetricRegistryProxy registry, MetricID metricId) {
this.registry = registry;
this.metricId = metricId;
Expand All @@ -57,7 +69,7 @@ public GaugeMetric(MetricRegistryProxy registry, MetricID metricId) {
* @return the counter value, or zero if the metric doesn't exist
*/
public long value() {
return gauge().map(Gauge::getValue).orElse(0L);
return gauge().map(GaugeMetric::getValue).orElse(0L);
}

/**
Expand Down Expand Up @@ -90,9 +102,27 @@ public Optional<Gauge<Long>> gauge() {
if (gauge == null) {
return Optional.empty();
} else {
assertThat(gauge.getValue(), instanceOf(Long.class));
assertThat(getValue(gauge), instanceOf(Long.class));
return Optional.of((Gauge<Long>) gauge);
}
}

/**
* Reflectively call `getValue()` to account for different signature in MP Metrics 4.0 vs 5.0
*
* @param <T>
* the gauge type
* @param gauge
* the gauge
* @return the gauge's value
*/
@SuppressWarnings("unchecked")
private static <T> T getValue(Gauge<T> gauge) {
try {
return (T) GET_VALUE_METHOD.invoke(gauge);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}

}

0 comments on commit 0172e71

Please sign in to comment.