Skip to content

Commit

Permalink
Merge pull request quarkusio#44998 from cescoffier/metrics-path-param…
Browse files Browse the repository at this point in the history
…-test
  • Loading branch information
cescoffier authored Jan 16, 2025
2 parents c45215c + 7c3c88d commit a044827
Show file tree
Hide file tree
Showing 18 changed files with 962 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package io.quarkus.micrometer.deployment.binder;

import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.core.Response;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.micrometer.core.instrument.MeterRegistry;
import io.quarkus.micrometer.test.Util;
import io.quarkus.test.QuarkusUnitTest;
import io.restassured.RestAssured;

public class HttpTagExplosionPreventionTest {
@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.withConfigurationResource("test-logging.properties")
.overrideConfigKey("quarkus.micrometer.binder-enabled-default", "false")
.overrideConfigKey("quarkus.micrometer.binder.http-client.enabled", "true")
.overrideConfigKey("quarkus.micrometer.binder.http-server.enabled", "true")
.overrideConfigKey("quarkus.micrometer.binder.vertx.enabled", "true")
.overrideConfigKey("pingpong/mp-rest/url", "${test.url}")
.overrideConfigKey("quarkus.redis.devservices.enabled", "false")
.overrideConfigKey("quarkus.micrometer.binder.http-server.suppress4xx-errors", "true")
.withApplicationRoot((jar) -> jar
.addClasses(Util.class,
Resource.class));

@Inject
MeterRegistry registry;

@Test
public void test() throws Exception {
RestAssured.get("/api/hello").then().statusCode(200);
Util.waitForMeters(registry.find("http.server.requests").timers(), 1);
Assertions.assertEquals(1, registry.find("http.server.requests").tag("uri", "/api/hello").timers().size());

RestAssured.get("/api/hello/foo").then().statusCode(200);
Util.waitForMeters(registry.find("http.server.requests").timers(), 2);
Assertions.assertEquals(1, registry.find("http.server.requests").tag("uri", "/api/hello/{message}").timers().size());

RestAssured.delete("/api/hello").then().statusCode(405);
Util.waitForMeters(registry.find("http.server.requests").timers(), 3);
Assertions.assertEquals(1, registry.find("http.server.requests").tag("uri", "UNKNOWN").timers().size());

RestAssured.delete("/api/hello/foo").then().statusCode(405);
RestAssured.delete("/api/hello/bar").then().statusCode(405);
RestAssured.delete("/api/hello/baz").then().statusCode(405);
Util.waitForMeters(registry.find("http.server.requests").timers(), 6);
Assertions.assertEquals(4,
registry.find("http.server.requests").tag("uri", "UNKNOWN").timers().iterator().next().count());

for (int i = 0; i < 10; i++) {
RestAssured.get("/api/failure").then().statusCode(500);
RestAssured.get("/api/failure/bar" + i).then().statusCode(500);
}
Util.waitForMeters(registry.find("http.server.requests").timers(), 6 + 10);

Assertions.assertEquals(2, registry.find("http.server.requests").tag("uri", "UNKNOWN").timers().size()); // 2 different set of tags
Assertions.assertEquals(1, registry.find("http.server.requests").tag("uri", "/api/failure/{message}").timers().size());
}

@Path("/")
@Singleton
public static class Resource {

@GET
@Path("api/hello/{message}")
public String hello(@PathParam("message") String message) {
return message;
}

@GET
@Path("api/hello/")
public String hello() {
return "hello";
}

@GET
@Path("api/failure")
public Response failure() {
return Response.status(500).build();
}

@GET
@Path("api/failure/{message}")
public Response failure(@PathParam("message") String message) {
return Response.status(500).build();
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package io.quarkus.micrometer.deployment.pathparams;

import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.core.Response;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.micrometer.core.instrument.MeterRegistry;
import io.quarkus.micrometer.test.Util;
import io.quarkus.test.QuarkusUnitTest;
import io.restassured.RestAssured;

public class HttpPathParamLimitWithJaxRs400Test {
@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.withConfigurationResource("test-logging.properties")
.overrideConfigKey("quarkus.micrometer.binder-enabled-default", "false")
.overrideConfigKey("quarkus.micrometer.binder.http-client.enabled", "true")
.overrideConfigKey("quarkus.micrometer.binder.http-server.enabled", "true")
.overrideConfigKey("quarkus.micrometer.binder.vertx.enabled", "true")
.overrideConfigKey("quarkus.redis.devservices.enabled", "false")
.withApplicationRoot((jar) -> jar
.addClasses(Util.class,
Resource.class));

@Inject
MeterRegistry registry;

public static final int COUNT = 101;

@Test
void testWithResteasy400() throws InterruptedException {
registry.clear();
// Test a JAX-RS endpoint with GET /jaxrs and GET /jaxrs/{message}
// Verify OK response
for (int i = 0; i < COUNT; i++) {
RestAssured.get("/jaxrs").then().statusCode(200);
RestAssured.get("/jaxrs/foo-" + i).then().statusCode(200);
}

// Verify metrics
Util.waitForMeters(registry.find("http.server.requests").timers(), COUNT);

Assertions.assertEquals(COUNT, registry.find("http.server.requests")
.tag("uri", "/jaxrs").timers().iterator().next().count());
Assertions.assertEquals(COUNT, registry.find("http.server.requests")
.tag("uri", "/jaxrs/{message}").timers().iterator().next().count());

// Verify method producing a 400
for (int i = 0; i < COUNT; i++) {
RestAssured.get("/bad").then().statusCode(400);
RestAssured.get("/bad/foo-" + i).then().statusCode(400);
}

Util.waitForMeters(registry.find("http.server.requests").timers(), COUNT * 2);

Assertions.assertEquals(COUNT, registry.find("http.server.requests")
.tag("uri", "/bad").tag("method", "GET").timers().iterator().next().count());
Assertions.assertEquals(4, registry.find("http.server.requests")
.tag("method", "GET").timers().size()); // Pattern recognized

}

@Path("/")
@Singleton
public static class Resource {

@GET
@Path("/jaxrs")
public String jaxrs() {
return "hello";
}

@GET
@Path("/jaxrs/{message}")
public String jaxrsWithPathParam(@PathParam("message") String message) {
return "hello " + message;
}

@GET
@Path("/bad")
public Response bad() {
return Response.status(400).build();
}

@GET
@Path("/bad/{message}")
public Response bad(@PathParam("message") String message) {
return Response.status(400).build();
}

@GET
@Path("/fail")
public Response fail() {
return Response.status(500).build();
}

@GET
@Path("/fail/{message}")
public Response fail(@PathParam("message") String message) {
return Response.status(500).build();
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package io.quarkus.micrometer.deployment.pathparams;

import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.core.Response;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.micrometer.core.instrument.MeterRegistry;
import io.quarkus.micrometer.test.Util;
import io.quarkus.test.QuarkusUnitTest;
import io.restassured.RestAssured;

public class HttpPathParamLimitWithJaxRs500Test {
@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.withConfigurationResource("test-logging.properties")
.overrideConfigKey("quarkus.micrometer.binder-enabled-default", "false")
.overrideConfigKey("quarkus.micrometer.binder.http-client.enabled", "true")
.overrideConfigKey("quarkus.micrometer.binder.http-server.enabled", "true")
.overrideConfigKey("quarkus.micrometer.binder.vertx.enabled", "true")
.overrideConfigKey("quarkus.redis.devservices.enabled", "false")
.withApplicationRoot((jar) -> jar
.addClasses(Util.class,
Resource.class));

@Inject
MeterRegistry registry;

public static final int COUNT = 101;

@Test
void testWithResteasy500() throws InterruptedException {
registry.clear();
// Test a JAX-RS endpoint with GET /jaxrs and GET /jaxrs/{message}
// Verify OK response
for (int i = 0; i < COUNT; i++) {
RestAssured.get("/jaxrs").then().statusCode(200);
RestAssured.get("/jaxrs/foo-" + i).then().statusCode(200);
}

// Verify metrics
Util.waitForMeters(registry.find("http.server.requests").timers(), COUNT);

Assertions.assertEquals(COUNT, registry.find("http.server.requests")
.tag("uri", "/jaxrs").timers().iterator().next().count());
Assertions.assertEquals(COUNT, registry.find("http.server.requests")
.tag("uri", "/jaxrs/{message}").timers().iterator().next().count());

// Verify method producing a 400
for (int i = 0; i < COUNT; i++) {
RestAssured.get("/fail").then().statusCode(500);
RestAssured.get("/fail/foo-" + i).then().statusCode(500);
}

Util.waitForMeters(registry.find("http.server.requests").timers(), COUNT * 2);

Assertions.assertEquals(COUNT, registry.find("http.server.requests")
.tag("uri", "/fail").tag("method", "GET").timers().iterator().next().count());
Assertions.assertEquals(4, registry.find("http.server.requests")
.tag("method", "GET").timers().size()); // Pattern recognized
}

@Path("/")
@Singleton
public static class Resource {

@GET
@Path("/jaxrs")
public String jaxrs() {
return "hello";
}

@GET
@Path("/jaxrs/{message}")
public String jaxrsWithPathParam(@PathParam("message") String message) {
return "hello " + message;
}

@GET
@Path("/bad")
public Response bad() {
return Response.status(400).build();
}

@GET
@Path("/bad/{message}")
public Response bad(@PathParam("message") String message) {
return Response.status(400).build();
}

@GET
@Path("/fail")
public Response fail() {
return Response.status(500).build();
}

@GET
@Path("/fail/{message}")
public Response fail(@PathParam("message") String message) {
return Response.status(500).build();
}

}
}
Loading

0 comments on commit a044827

Please sign in to comment.