Skip to content

Commit

Permalink
More compatibility tests and testing utilities
Browse files Browse the repository at this point in the history
  • Loading branch information
brunobat committed Dec 18, 2024
1 parent 5663e57 commit acd0b25
Show file tree
Hide file tree
Showing 19 changed files with 1,532 additions and 84 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ SyntheticBeanBuildItem createBridgeBean(OTelRuntimeConfig otelRuntimeConfig,
.done();
}

// FIXME disable otel metrics instrumentation

/**
* No point in activating the bridge if the OTel metrics if off or the exporter is none.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package io.quarkus.micrometer.opentelemetry.deployment;

import io.micrometer.core.instrument.DistributionSummary;
import io.micrometer.core.instrument.MeterRegistry;
import io.opentelemetry.sdk.metrics.data.MetricData;
import io.quarkus.micrometer.opentelemetry.deployment.common.InMemoryMetricExporter;
import io.quarkus.micrometer.opentelemetry.deployment.common.InMemoryMetricExporterProvider;
import io.quarkus.test.QuarkusUnitTest;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.attributeEntry;
import static org.junit.jupiter.api.Assertions.assertNotNull;

public class DistributionSummaryTest {

@RegisterExtension
static final QuarkusUnitTest TEST = new QuarkusUnitTest()
.setArchiveProducer(
() -> ShrinkWrap.create(JavaArchive.class)
.addClasses(ManualHistogramBean.class)
.addClasses(InMemoryMetricExporter.class, InMemoryMetricExporterProvider.class)
.addAsResource(new StringAsset(InMemoryMetricExporterProvider.class.getCanonicalName()),
"META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider")
.add(new StringAsset("""
quarkus.otel.metrics.enabled=true\n
quarkus.otel.traces.exporter=none\n
quarkus.otel.logs.exporter=none\n
quarkus.otel.metrics.exporter=in-memory\n
quarkus.otel.metric.export.interval=300ms\n
quarkus.micrometer.binder-enabled-default=false\n
quarkus.micrometer.binder.http-client.enabled=true\n
quarkus.micrometer.binder.http-server.enabled=true\n
quarkus.micrometer.binder.http-server.match-patterns=/one=/two\n
quarkus.micrometer.binder.http-server.ignore-patterns=/two\n
quarkus.micrometer.binder.vertx.enabled=true\n
pingpong/mp-rest/url=${test.url}\n
quarkus.redis.devservices.enabled=false\n
"""),
"application.properties"));

@Inject
ManualHistogramBean manualHistogramBean;

@Inject
InMemoryMetricExporter exporter;

@Test
void histogramTest() {
manualHistogramBean.recordHistogram();

MetricData testSummary = exporter.getLastFinishedHistogramItem("testSummary", 4);
assertNotNull(testSummary);
assertThat(testSummary)
.hasDescription("This is a test distribution summary")
.hasUnit("things")
.hasHistogramSatisfying(
histogram -> histogram.hasPointsSatisfying(
points -> points
.hasSum(555.5)
.hasCount(4)
.hasAttributes(attributeEntry("tag", "value"))));

MetricData textSummaryMax = exporter.getFinishedMetricItem("testSummary.max");
assertNotNull(textSummaryMax);
assertThat(textSummaryMax)
.hasDescription("This is a test distribution summary")
.hasDoubleGaugeSatisfying(
gauge -> gauge.hasPointsSatisfying(
point -> point
.hasValue(500)
.hasAttributes(attributeEntry("tag", "value"))));

MetricData testSummaryHistogram = exporter.getFinishedMetricItem("testSummary.histogram");
assertNotNull(testSummaryHistogram);
assertThat(testSummaryHistogram)
.hasDoubleGaugeSatisfying(
gauge -> gauge.hasPointsSatisfying(
point -> point
.hasValue(1)
.hasAttributes(
attributeEntry("le", "1"),
attributeEntry("tag", "value")),
point -> point
.hasValue(2)
.hasAttributes(
attributeEntry("le", "10"),
attributeEntry("tag", "value")),
point -> point
.hasValue(3)
.hasAttributes(
attributeEntry("le", "100"),
attributeEntry("tag", "value")),
point -> point
.hasValue(4)
.hasAttributes(
attributeEntry("le", "1000"),
attributeEntry("tag", "value"))));
}

@ApplicationScoped
public static class ManualHistogramBean {
@Inject
MeterRegistry registry;

public void recordHistogram() {
DistributionSummary summary = DistributionSummary.builder("testSummary")
.description("This is a test distribution summary")
.baseUnit("things")
.tags("tag", "value")
.serviceLevelObjectives(1, 10, 100, 1000)
.distributionStatisticBufferLength(10)
.register(registry);

summary.record(0.5);
summary.record(5);
summary.record(50);
summary.record(500);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package io.quarkus.micrometer.opentelemetry.deployment;

import io.micrometer.common.annotation.ValueResolver;
import io.micrometer.core.annotation.Counted;
import io.micrometer.core.aop.MeterTag;
import io.opentelemetry.sdk.metrics.data.MetricData;
import io.quarkus.micrometer.opentelemetry.deployment.common.InMemoryMetricExporter;
import io.quarkus.micrometer.opentelemetry.deployment.common.InMemoryMetricExporterProvider;
import io.quarkus.micrometer.opentelemetry.deployment.common.Util;
import io.quarkus.test.QuarkusUnitTest;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.attributeEntry;


public class MicrometerCounterInterceptorTest {

@RegisterExtension
static final QuarkusUnitTest TEST = new QuarkusUnitTest()
.setArchiveProducer(
() -> ShrinkWrap.create(JavaArchive.class)
.addClasses(Util.class, CountedBean.class, TestValueResolver.class)
.addClasses(InMemoryMetricExporter.class, InMemoryMetricExporterProvider.class)
.addAsResource(new StringAsset(InMemoryMetricExporterProvider.class.getCanonicalName()),
"META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider")
.add(new StringAsset("""
quarkus.otel.sdk.disabled=false\n
quarkus.otel.metrics.enabled=true\n
quarkus.otel.traces.exporter=none\n
quarkus.otel.logs.exporter=none\n
quarkus.otel.metrics.exporter=in-memory\n
quarkus.otel.metric.export.interval=300ms\n
quarkus.micrometer.binder.http-client.enabled=true\n
quarkus.micrometer.binder.http-server.enabled=true\n
quarkus.redis.devservices.enabled=false\n
"""),
"application.properties"));

@Inject
CountedBean countedBean;

@Inject
InMemoryMetricExporter exporter;

@BeforeEach
void setup() {
exporter.reset();
}

@Test
void testCountAllMetrics() {
countedBean.countAllInvocations(false);
Assertions.assertThrows(NullPointerException.class, () -> countedBean.countAllInvocations(true));

exporter.assertCountDataPointsAtLeastOrEqual("metric.all", null, 2);

MetricData metricAll = exporter.getFinishedMetricItem("metric.all");
assertThat(metricAll)
.isNotNull()
.hasName("metric.all")
.hasDescription("")// currently empty
.hasUnit("")// currently empty
.hasDoubleSumSatisfying(sum -> sum.hasPointsSatisfying(
point -> point
.hasValue(1d)
.hasAttributes(attributeEntry(
"class",
"io.quarkus.micrometer.opentelemetry.deployment.MicrometerCounterInterceptorTest$CountedBean"),
attributeEntry("method", "countAllInvocations"),
attributeEntry("extra", "tag"),
attributeEntry("do_fail", "prefix_false"),
attributeEntry("exception", "none"),
attributeEntry("result", "success")),
point -> point
.hasValue(1d)
.hasAttributes(attributeEntry(
"class",
"io.quarkus.micrometer.opentelemetry.deployment.MicrometerCounterInterceptorTest$CountedBean"),
attributeEntry("method", "countAllInvocations"),
attributeEntry("extra", "tag"),
attributeEntry("do_fail", "prefix_true"),
attributeEntry("exception", "NullPointerException"),
attributeEntry("result", "failure"))));
}

@ApplicationScoped
public static class CountedBean {
@Counted(value = "metric.none", recordFailuresOnly = true)
public void onlyCountFailures() {
}

@Counted(value = "metric.all", extraTags = {"extra", "tag"})
public void countAllInvocations(@MeterTag(key = "do_fail", resolver = TestValueResolver.class) boolean fail) {
if (fail) {
throw new NullPointerException("Failed on purpose");
}
}

@Counted(description = "nice description")
public void emptyMetricName(@MeterTag boolean fail) {
if (fail) {
throw new NullPointerException("Failed on purpose");
}
}
}

@Singleton
public static class TestValueResolver implements ValueResolver {
@Override
public String resolve(Object parameter) {
return "prefix_" + parameter;
}
}


}
Loading

0 comments on commit acd0b25

Please sign in to comment.