Skip to content

Commit acd0b25

Browse files
committed
More compatibility tests and testing utilities
1 parent 5663e57 commit acd0b25

File tree

19 files changed

+1532
-84
lines changed

19 files changed

+1532
-84
lines changed

extensions/micrometer-opentelemetry-bridge/deployment/src/main/java/io/quarkus/micrometer/opentelemetry/deployment/MicrometerOtelBridgeProcessor.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ SyntheticBeanBuildItem createBridgeBean(OTelRuntimeConfig otelRuntimeConfig,
4646
.done();
4747
}
4848

49+
// FIXME disable otel metrics instrumentation
50+
4951
/**
5052
* No point in activating the bridge if the OTel metrics if off or the exporter is none.
5153
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package io.quarkus.micrometer.opentelemetry.deployment;
2+
3+
import io.micrometer.core.instrument.DistributionSummary;
4+
import io.micrometer.core.instrument.MeterRegistry;
5+
import io.opentelemetry.sdk.metrics.data.MetricData;
6+
import io.quarkus.micrometer.opentelemetry.deployment.common.InMemoryMetricExporter;
7+
import io.quarkus.micrometer.opentelemetry.deployment.common.InMemoryMetricExporterProvider;
8+
import io.quarkus.test.QuarkusUnitTest;
9+
import jakarta.enterprise.context.ApplicationScoped;
10+
import jakarta.inject.Inject;
11+
import org.jboss.shrinkwrap.api.ShrinkWrap;
12+
import org.jboss.shrinkwrap.api.asset.StringAsset;
13+
import org.jboss.shrinkwrap.api.spec.JavaArchive;
14+
import org.junit.jupiter.api.Test;
15+
import org.junit.jupiter.api.extension.RegisterExtension;
16+
17+
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
18+
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.attributeEntry;
19+
import static org.junit.jupiter.api.Assertions.assertNotNull;
20+
21+
public class DistributionSummaryTest {
22+
23+
@RegisterExtension
24+
static final QuarkusUnitTest TEST = new QuarkusUnitTest()
25+
.setArchiveProducer(
26+
() -> ShrinkWrap.create(JavaArchive.class)
27+
.addClasses(ManualHistogramBean.class)
28+
.addClasses(InMemoryMetricExporter.class, InMemoryMetricExporterProvider.class)
29+
.addAsResource(new StringAsset(InMemoryMetricExporterProvider.class.getCanonicalName()),
30+
"META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider")
31+
.add(new StringAsset("""
32+
quarkus.otel.metrics.enabled=true\n
33+
quarkus.otel.traces.exporter=none\n
34+
quarkus.otel.logs.exporter=none\n
35+
quarkus.otel.metrics.exporter=in-memory\n
36+
quarkus.otel.metric.export.interval=300ms\n
37+
quarkus.micrometer.binder-enabled-default=false\n
38+
quarkus.micrometer.binder.http-client.enabled=true\n
39+
quarkus.micrometer.binder.http-server.enabled=true\n
40+
quarkus.micrometer.binder.http-server.match-patterns=/one=/two\n
41+
quarkus.micrometer.binder.http-server.ignore-patterns=/two\n
42+
quarkus.micrometer.binder.vertx.enabled=true\n
43+
pingpong/mp-rest/url=${test.url}\n
44+
quarkus.redis.devservices.enabled=false\n
45+
"""),
46+
"application.properties"));
47+
48+
@Inject
49+
ManualHistogramBean manualHistogramBean;
50+
51+
@Inject
52+
InMemoryMetricExporter exporter;
53+
54+
@Test
55+
void histogramTest() {
56+
manualHistogramBean.recordHistogram();
57+
58+
MetricData testSummary = exporter.getLastFinishedHistogramItem("testSummary", 4);
59+
assertNotNull(testSummary);
60+
assertThat(testSummary)
61+
.hasDescription("This is a test distribution summary")
62+
.hasUnit("things")
63+
.hasHistogramSatisfying(
64+
histogram -> histogram.hasPointsSatisfying(
65+
points -> points
66+
.hasSum(555.5)
67+
.hasCount(4)
68+
.hasAttributes(attributeEntry("tag", "value"))));
69+
70+
MetricData textSummaryMax = exporter.getFinishedMetricItem("testSummary.max");
71+
assertNotNull(textSummaryMax);
72+
assertThat(textSummaryMax)
73+
.hasDescription("This is a test distribution summary")
74+
.hasDoubleGaugeSatisfying(
75+
gauge -> gauge.hasPointsSatisfying(
76+
point -> point
77+
.hasValue(500)
78+
.hasAttributes(attributeEntry("tag", "value"))));
79+
80+
MetricData testSummaryHistogram = exporter.getFinishedMetricItem("testSummary.histogram");
81+
assertNotNull(testSummaryHistogram);
82+
assertThat(testSummaryHistogram)
83+
.hasDoubleGaugeSatisfying(
84+
gauge -> gauge.hasPointsSatisfying(
85+
point -> point
86+
.hasValue(1)
87+
.hasAttributes(
88+
attributeEntry("le", "1"),
89+
attributeEntry("tag", "value")),
90+
point -> point
91+
.hasValue(2)
92+
.hasAttributes(
93+
attributeEntry("le", "10"),
94+
attributeEntry("tag", "value")),
95+
point -> point
96+
.hasValue(3)
97+
.hasAttributes(
98+
attributeEntry("le", "100"),
99+
attributeEntry("tag", "value")),
100+
point -> point
101+
.hasValue(4)
102+
.hasAttributes(
103+
attributeEntry("le", "1000"),
104+
attributeEntry("tag", "value"))));
105+
}
106+
107+
@ApplicationScoped
108+
public static class ManualHistogramBean {
109+
@Inject
110+
MeterRegistry registry;
111+
112+
public void recordHistogram() {
113+
DistributionSummary summary = DistributionSummary.builder("testSummary")
114+
.description("This is a test distribution summary")
115+
.baseUnit("things")
116+
.tags("tag", "value")
117+
.serviceLevelObjectives(1, 10, 100, 1000)
118+
.distributionStatisticBufferLength(10)
119+
.register(registry);
120+
121+
summary.record(0.5);
122+
summary.record(5);
123+
summary.record(50);
124+
summary.record(500);
125+
}
126+
}
127+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
package io.quarkus.micrometer.opentelemetry.deployment;
2+
3+
import io.micrometer.common.annotation.ValueResolver;
4+
import io.micrometer.core.annotation.Counted;
5+
import io.micrometer.core.aop.MeterTag;
6+
import io.opentelemetry.sdk.metrics.data.MetricData;
7+
import io.quarkus.micrometer.opentelemetry.deployment.common.InMemoryMetricExporter;
8+
import io.quarkus.micrometer.opentelemetry.deployment.common.InMemoryMetricExporterProvider;
9+
import io.quarkus.micrometer.opentelemetry.deployment.common.Util;
10+
import io.quarkus.test.QuarkusUnitTest;
11+
import jakarta.enterprise.context.ApplicationScoped;
12+
import jakarta.inject.Inject;
13+
import jakarta.inject.Singleton;
14+
import org.jboss.shrinkwrap.api.ShrinkWrap;
15+
import org.jboss.shrinkwrap.api.asset.StringAsset;
16+
import org.jboss.shrinkwrap.api.spec.JavaArchive;
17+
import org.junit.jupiter.api.Assertions;
18+
import org.junit.jupiter.api.BeforeEach;
19+
import org.junit.jupiter.api.Test;
20+
import org.junit.jupiter.api.extension.RegisterExtension;
21+
22+
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
23+
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.attributeEntry;
24+
25+
26+
public class MicrometerCounterInterceptorTest {
27+
28+
@RegisterExtension
29+
static final QuarkusUnitTest TEST = new QuarkusUnitTest()
30+
.setArchiveProducer(
31+
() -> ShrinkWrap.create(JavaArchive.class)
32+
.addClasses(Util.class, CountedBean.class, TestValueResolver.class)
33+
.addClasses(InMemoryMetricExporter.class, InMemoryMetricExporterProvider.class)
34+
.addAsResource(new StringAsset(InMemoryMetricExporterProvider.class.getCanonicalName()),
35+
"META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider")
36+
.add(new StringAsset("""
37+
quarkus.otel.sdk.disabled=false\n
38+
quarkus.otel.metrics.enabled=true\n
39+
quarkus.otel.traces.exporter=none\n
40+
quarkus.otel.logs.exporter=none\n
41+
quarkus.otel.metrics.exporter=in-memory\n
42+
quarkus.otel.metric.export.interval=300ms\n
43+
quarkus.micrometer.binder.http-client.enabled=true\n
44+
quarkus.micrometer.binder.http-server.enabled=true\n
45+
quarkus.redis.devservices.enabled=false\n
46+
"""),
47+
"application.properties"));
48+
49+
@Inject
50+
CountedBean countedBean;
51+
52+
@Inject
53+
InMemoryMetricExporter exporter;
54+
55+
@BeforeEach
56+
void setup() {
57+
exporter.reset();
58+
}
59+
60+
@Test
61+
void testCountAllMetrics() {
62+
countedBean.countAllInvocations(false);
63+
Assertions.assertThrows(NullPointerException.class, () -> countedBean.countAllInvocations(true));
64+
65+
exporter.assertCountDataPointsAtLeastOrEqual("metric.all", null, 2);
66+
67+
MetricData metricAll = exporter.getFinishedMetricItem("metric.all");
68+
assertThat(metricAll)
69+
.isNotNull()
70+
.hasName("metric.all")
71+
.hasDescription("")// currently empty
72+
.hasUnit("")// currently empty
73+
.hasDoubleSumSatisfying(sum -> sum.hasPointsSatisfying(
74+
point -> point
75+
.hasValue(1d)
76+
.hasAttributes(attributeEntry(
77+
"class",
78+
"io.quarkus.micrometer.opentelemetry.deployment.MicrometerCounterInterceptorTest$CountedBean"),
79+
attributeEntry("method", "countAllInvocations"),
80+
attributeEntry("extra", "tag"),
81+
attributeEntry("do_fail", "prefix_false"),
82+
attributeEntry("exception", "none"),
83+
attributeEntry("result", "success")),
84+
point -> point
85+
.hasValue(1d)
86+
.hasAttributes(attributeEntry(
87+
"class",
88+
"io.quarkus.micrometer.opentelemetry.deployment.MicrometerCounterInterceptorTest$CountedBean"),
89+
attributeEntry("method", "countAllInvocations"),
90+
attributeEntry("extra", "tag"),
91+
attributeEntry("do_fail", "prefix_true"),
92+
attributeEntry("exception", "NullPointerException"),
93+
attributeEntry("result", "failure"))));
94+
}
95+
96+
@ApplicationScoped
97+
public static class CountedBean {
98+
@Counted(value = "metric.none", recordFailuresOnly = true)
99+
public void onlyCountFailures() {
100+
}
101+
102+
@Counted(value = "metric.all", extraTags = {"extra", "tag"})
103+
public void countAllInvocations(@MeterTag(key = "do_fail", resolver = TestValueResolver.class) boolean fail) {
104+
if (fail) {
105+
throw new NullPointerException("Failed on purpose");
106+
}
107+
}
108+
109+
@Counted(description = "nice description")
110+
public void emptyMetricName(@MeterTag boolean fail) {
111+
if (fail) {
112+
throw new NullPointerException("Failed on purpose");
113+
}
114+
}
115+
}
116+
117+
@Singleton
118+
public static class TestValueResolver implements ValueResolver {
119+
@Override
120+
public String resolve(Object parameter) {
121+
return "prefix_" + parameter;
122+
}
123+
}
124+
125+
126+
}

0 commit comments

Comments
 (0)