From 0172e71f8847f78423919ac1ce8b11616c72ce50 Mon Sep 17 00:00:00 2001 From: Andrew Rouse Date: Mon, 3 Oct 2022 18:20:34 +0100 Subject: [PATCH] Tolerate MP Metrics 5.0 API changes - Methods removed from Snapshot - Gauge changed to Gauge - Breaks binary compatibility because method signatures are different after type erasure --- .../tck/metrics/BulkheadMetricTest.java | 25 +------------ .../tck/metrics/TimeoutMetricTest.java | 14 +------- .../tck/metrics/util/GaugeMetric.java | 36 +++++++++++++++++-- 3 files changed, 35 insertions(+), 40 deletions(-) diff --git a/tck/src/main/java/org/eclipse/microprofile/fault/tolerance/tck/metrics/BulkheadMetricTest.java b/tck/src/main/java/org/eclipse/microprofile/fault/tolerance/tck/metrics/BulkheadMetricTest.java index 8cb567aa..d11a759c 100644 --- a/tck/src/main/java/org/eclipse/microprofile/fault/tolerance/tck/metrics/BulkheadMetricTest.java +++ b/tck/src/main/java/org/eclipse/microprofile/fault/tolerance/tck/metrics/BulkheadMetricTest.java @@ -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. @@ -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; @@ -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(); @@ -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 @@ -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 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(); @@ -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); @@ -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); @@ -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 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(), diff --git a/tck/src/main/java/org/eclipse/microprofile/fault/tolerance/tck/metrics/TimeoutMetricTest.java b/tck/src/main/java/org/eclipse/microprofile/fault/tolerance/tck/metrics/TimeoutMetricTest.java index a6adc190..81633f6d 100644 --- a/tck/src/main/java/org/eclipse/microprofile/fault/tolerance/tck/metrics/TimeoutMetricTest.java +++ b/tck/src/main/java/org/eclipse/microprofile/fault/tolerance/tck/metrics/TimeoutMetricTest.java @@ -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. @@ -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; @@ -95,7 +88,6 @@ public void testTimeoutMetric() { } @Test - @SuppressWarnings("unchecked") public void testTimeoutHistogram() { MetricGetter m = new MetricGetter(TimeoutMetricBean.class, "histogramTestWorkForMillis"); @@ -105,12 +97,8 @@ public void testTimeoutHistogram() { // after 2000 Histogram histogram = m.getTimeoutExecutionDuration().get(); - Snapshot snapshot = histogram.getSnapshot(); - List 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))); } } diff --git a/tck/src/main/java/org/eclipse/microprofile/fault/tolerance/tck/metrics/util/GaugeMetric.java b/tck/src/main/java/org/eclipse/microprofile/fault/tolerance/tck/metrics/util/GaugeMetric.java index 5fec6ca0..6e2ac36f 100644 --- a/tck/src/main/java/org/eclipse/microprofile/fault/tolerance/tck/metrics/util/GaugeMetric.java +++ b/tck/src/main/java/org/eclipse/microprofile/fault/tolerance/tck/metrics/util/GaugeMetric.java @@ -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. @@ -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; @@ -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; @@ -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); } /** @@ -90,9 +102,27 @@ public Optional> gauge() { if (gauge == null) { return Optional.empty(); } else { - assertThat(gauge.getValue(), instanceOf(Long.class)); + assertThat(getValue(gauge), instanceOf(Long.class)); return Optional.of((Gauge) gauge); } } + /** + * Reflectively call `getValue()` to account for different signature in MP Metrics 4.0 vs 5.0 + * + * @param + * the gauge type + * @param gauge + * the gauge + * @return the gauge's value + */ + @SuppressWarnings("unchecked") + private static T getValue(Gauge gauge) { + try { + return (T) GET_VALUE_METHOD.invoke(gauge); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + throw new RuntimeException(e); + } + } + }