From 1332a869eea29f26e1b6f52ee7da52351ee09257 Mon Sep 17 00:00:00 2001 From: "shalk(xiao kun)" Date: Fri, 6 Sep 2024 20:27:48 +0800 Subject: [PATCH 01/10] add undertow test --- .../undertow/UndertowHttp2ServerTest.groovy | 19 ++ .../UndertowServerDispatchTest.groovy | 109 +++++++++ .../undertow/UndertowServerTest.java | 227 ++++++++++++++++++ 3 files changed, 355 insertions(+) create mode 100644 instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowHttp2ServerTest.groovy create mode 100644 instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerDispatchTest.groovy create mode 100644 instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerTest.java diff --git a/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowHttp2ServerTest.groovy b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowHttp2ServerTest.groovy new file mode 100644 index 000000000000..d26d04de6c0b --- /dev/null +++ b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowHttp2ServerTest.groovy @@ -0,0 +1,19 @@ +package io.opentelemetry.javaagent.instrumentation.undertow +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import io.undertow.Undertow +import io.undertow.UndertowOptions + +class UndertowHttp2ServerTest extends UndertowServerTest { + + void configureUndertow(Undertow.Builder builder) { + builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true) + } + + boolean useHttp2() { + true + } +} diff --git a/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerDispatchTest.groovy b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerDispatchTest.groovy new file mode 100644 index 000000000000..4022b2cacc5e --- /dev/null +++ b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerDispatchTest.groovy @@ -0,0 +1,109 @@ +package io.opentelemetry.javaagent.instrumentation.undertow + +import io.opentelemetry.api.common.AttributeKey + +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import io.opentelemetry.instrumentation.test.AgentTestTrait +import io.opentelemetry.instrumentation.test.base.HttpServerTest +import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint +import io.opentelemetry.semconv.HttpAttributes +import io.undertow.Handlers +import io.undertow.Undertow +import io.undertow.util.Headers +import io.undertow.util.HttpString +import io.undertow.util.StatusCodes + +import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.* + +class UndertowServerDispatchTest extends HttpServerTest implements AgentTestTrait { + + @Override + boolean verifyServerSpanEndTime() { + return false + } + + @Override + boolean testException() { + // throwing exception from dispatched task just makes the request time out + return false + } + + @Override + boolean hasResponseCustomizer(ServerEndpoint endpoint) { + true + } + + @Override + Undertow startServer(int port) { + Undertow server = Undertow.builder() + .addHttpListener(port, "localhost") + .setHandler(Handlers.path() + .addExactPath(SUCCESS.rawPath()) { exchange -> + exchange.dispatch { + controller(SUCCESS) { + exchange.getResponseSender().send(SUCCESS.body) + } + } + } + .addExactPath(QUERY_PARAM.rawPath()) { exchange -> + exchange.dispatch { + controller(QUERY_PARAM) { + exchange.getResponseSender().send(exchange.getQueryString()) + } + } + } + .addExactPath(REDIRECT.rawPath()) { exchange -> + exchange.dispatch { + controller(REDIRECT) { + exchange.setStatusCode(StatusCodes.FOUND) + exchange.getResponseHeaders().put(Headers.LOCATION, REDIRECT.body) + exchange.endExchange() + } + } + } + .addExactPath(CAPTURE_HEADERS.rawPath()) { exchange -> + exchange.dispatch { + controller(CAPTURE_HEADERS) { + exchange.setStatusCode(StatusCodes.OK) + exchange.getResponseHeaders().put(new HttpString("X-Test-Response"), exchange.getRequestHeaders().getFirst("X-Test-Request")) + exchange.getResponseSender().send(CAPTURE_HEADERS.body) + } + } + } + .addExactPath(ERROR.rawPath()) { exchange -> + exchange.dispatch { + controller(ERROR) { + exchange.setStatusCode(ERROR.status) + exchange.getResponseSender().send(ERROR.body) + } + } + } + .addExactPath(INDEXED_CHILD.rawPath()) { exchange -> + exchange.dispatch { + controller(INDEXED_CHILD) { + INDEXED_CHILD.collectSpanAttributes { name -> exchange.getQueryParameters().get(name).peekFirst() } + exchange.getResponseSender().send(INDEXED_CHILD.body) + } + } + } + ).build() + server.start() + return server + } + + @Override + void stopServer(Undertow undertow) { + undertow.stop() + } + + @Override + Set> httpAttributes(ServerEndpoint endpoint) { + def attributes = super.httpAttributes(endpoint) + attributes.remove(HttpAttributes.HTTP_ROUTE) + attributes + } +} diff --git a/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerTest.java b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerTest.java new file mode 100644 index 000000000000..ee7a993f5362 --- /dev/null +++ b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerTest.java @@ -0,0 +1,227 @@ +package io.opentelemetry.javaagent.instrumentation.undertow; + +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.api.trace.StatusCode; +import io.opentelemetry.instrumentation.test.AgentTestTrait; +import io.opentelemetry.instrumentation.test.base.HttpServerTest; +import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; +import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerTest; +import io.opentelemetry.instrumentation.testing.junit.http.HttpServerInstrumentationExtension; +import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint; +import io.opentelemetry.semconv.*; +import io.opentelemetry.testing.internal.armeria.common.AggregatedHttpResponse; +import io.undertow.Handlers; +import io.undertow.Undertow; +import io.undertow.server.HttpHandler; +import io.undertow.server.HttpServerExchange; +import io.undertow.util.Headers; +import io.undertow.util.HttpString; +import io.undertow.util.StatusCodes; +import java.util.function.Supplier; +import org.junit.jupiter.api.extension.RegisterExtension; + +import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.*; + +//TODO make test which mixes handlers and servlets +class UndertowServerTest extends AbstractHttpServerTest { + + @RegisterExtension + static final InstrumentationExtension testing = HttpServerInstrumentationExtension.forAgent(); + + @Override + public Undertow setupServer() { + Undertow.Builder builder = Undertow.builder() + .addHttpListener(port, "localhost") + .setHandler(Handlers.path() + .addExactPath(SUCCESS.rawPath(), + controller(SUCCESS, + () -> exchange -> exchange.getResponseSender().send(SUCCESS.getBody())) + ) + .addExactPath(QUERY_PARAM.rawPath(), + controller(QUERY_PARAM, + () -> exchange -> exchange.getResponseSender().send(exchange.getQueryString())) + ) + .addExactPath(REDIRECT.rawPath(), + controller(REDIRECT , + () -> exchange -> { + exchange.setStatusCode(StatusCodes.FOUND); + exchange.getResponseHeaders().put(Headers.LOCATION, REDIRECT.getBody()); + exchange.endExchange(); + }) + ) + .addExactPath(CAPTURE_HEADERS.rawPath()) { exchange -> + controller(CAPTURE_HEADERS) { + exchange.setStatusCode(StatusCodes.OK) + exchange.getResponseHeaders().put(new HttpString("X-Test-Response"), exchange.getRequestHeaders().getFirst("X-Test-Request")) + exchange.getResponseSender().send(CAPTURE_HEADERS.body) + } + } + .addExactPath(ERROR.rawPath()) { exchange -> + controller(ERROR) { + exchange.setStatusCode(ERROR.status) + exchange.getResponseSender().send(ERROR.body) + } + } + .addExactPath(EXCEPTION.rawPath()) { exchange -> + controller(EXCEPTION) { + throw new Exception(EXCEPTION.body) + } + } + .addExactPath(INDEXED_CHILD.rawPath()) { exchange -> + controller(INDEXED_CHILD) { + INDEXED_CHILD.collectSpanAttributes { name -> exchange.getQueryParameters().get(name).peekFirst() } + exchange.getResponseSender().send(INDEXED_CHILD.body) + } + } + .addExactPath("sendResponse") { exchange -> + Span.current().addEvent("before-event") + runWithSpan("sendResponse") { + exchange.setStatusCode(StatusCodes.OK) + exchange.getResponseSender().send("sendResponse") + } + // event is added only when server span has not been ended + // we need to make sure that sending response does not end server span + Span.current().addEvent("after-event") + } + .addExactPath("sendResponseWithException") { exchange -> + Span.current().addEvent("before-event") + runWithSpan("sendResponseWithException") { + exchange.setStatusCode(StatusCodes.OK) + exchange.getResponseSender().send("sendResponseWithException") + } + // event is added only when server span has not been ended + // we need to make sure that sending response does not end server span + Span.current().addEvent("after-event") + throw new Exception("exception after sending response") + } + ) + configureUndertow(builder) + Undertow server = builder.build() + server.start() + return server + } + + @Override + void stopServer(Undertow undertow) { + undertow.stop() + } + + void configureUndertow(Undertow.Builder builder) { + } + + @Override + Set> httpAttributes(ServerEndpoint endpoint) { + def attributes = super.httpAttributes(endpoint) + attributes.remove(HttpAttributes.HTTP_ROUTE) + attributes + } + + @Override + boolean hasResponseCustomizer(ServerEndpoint endpoint) { + true + } + + def "test send response"() { + setup: + def uri = address.resolve("sendResponse") + AggregatedHttpResponse response = client.get(uri.toString()).aggregate().join() + + expect: + response.status().code() == 200 + response.contentUtf8().trim() == "sendResponse" + + and: + assertTraces(1) { + trace(0, 2) { + it.span(0) { + hasNoParent() + name "GET" + kind SpanKind.SERVER + + event(0) { + eventName "before-event" + } + event(1) { + eventName "after-event" + } + + def protocolVersion = useHttp2() ? "2" : "1.1" + attributes { + "$ClientAttributes.CLIENT_ADDRESS" TEST_CLIENT_IP + "$UrlAttributes.URL_SCHEME" uri.getScheme() + "$UrlAttributes.URL_PATH" uri.getPath() + "$HttpAttributes.HTTP_REQUEST_METHOD" "GET" + "$HttpAttributes.HTTP_RESPONSE_STATUS_CODE" 200 + "$UserAgentAttributes.USER_AGENT_ORIGINAL" TEST_USER_AGENT + "$NetworkAttributes.NETWORK_PROTOCOL_VERSION" protocolVersion + "$ServerAttributes.SERVER_ADDRESS" uri.host + "$ServerAttributes.SERVER_PORT" uri.port + "$NetworkAttributes.NETWORK_PEER_ADDRESS" "127.0.0.1" + "$NetworkAttributes.NETWORK_PEER_PORT" Long + } + } + span(1) { + name "sendResponse" + kind SpanKind.INTERNAL + childOf span(0) + } + } + } + } + + def "test send response with exception"() { + setup: + def uri = address.resolve("sendResponseWithException") + AggregatedHttpResponse response = client.get(uri.toString()).aggregate().join() + + expect: + response.status().code() == 200 + response.contentUtf8().trim() == "sendResponseWithException" + + and: + assertTraces(1) { + trace(0, 2) { + it.span(0) { + hasNoParent() + name "GET" + kind SpanKind.SERVER + status StatusCode.ERROR + + event(0) { + eventName "before-event" + } + event(1) { + eventName "after-event" + } + errorEvent(Exception, "exception after sending response", 2) + + def protocolVersion = useHttp2() ? "2" : "1.1" + attributes { + "$ClientAttributes.CLIENT_ADDRESS" TEST_CLIENT_IP + "$UrlAttributes.URL_SCHEME" uri.getScheme() + "$UrlAttributes.URL_PATH" uri.getPath() + "$HttpAttributes.HTTP_REQUEST_METHOD" "GET" + "$HttpAttributes.HTTP_RESPONSE_STATUS_CODE" 200 + "$UserAgentAttributes.USER_AGENT_ORIGINAL" TEST_USER_AGENT + "$NetworkAttributes.NETWORK_PROTOCOL_VERSION" protocolVersion + "$ServerAttributes.SERVER_ADDRESS" uri.host + "$ServerAttributes.SERVER_PORT" uri.port + "$NetworkAttributes.NETWORK_PEER_ADDRESS" "127.0.0.1" + "$NetworkAttributes.NETWORK_PEER_PORT" Long + } + } + span(1) { + name "sendResponseWithException" + kind SpanKind.INTERNAL + childOf span(0) + } + } + } + } +} From 9f12ae621ac203c6fd59a68b49da34ae51281b65 Mon Sep 17 00:00:00 2001 From: "shalk(xiao kun)" Date: Tue, 10 Sep 2024 17:30:45 +0800 Subject: [PATCH 02/10] add undertower test --- .../groovy/UndertowHttp2ServerTest.groovy | 18 - .../groovy/UndertowServerDispatchTest.groovy | 111 ----- .../src/test/groovy/UndertowServerTest.groovy | 228 ---------- .../undertow/UndertowHttp2ServerTest.groovy | 19 - .../undertow/UndertowHttp2ServerTest.java | 22 + .../UndertowServerDispatchTest.groovy | 109 ----- .../undertow/UndertowServerDispatchTest.java | 150 +++++++ .../undertow/UndertowServerTest.java | 413 ++++++++++-------- 8 files changed, 399 insertions(+), 671 deletions(-) delete mode 100644 instrumentation/undertow-1.4/javaagent/src/test/groovy/UndertowHttp2ServerTest.groovy delete mode 100644 instrumentation/undertow-1.4/javaagent/src/test/groovy/UndertowServerDispatchTest.groovy delete mode 100644 instrumentation/undertow-1.4/javaagent/src/test/groovy/UndertowServerTest.groovy delete mode 100644 instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowHttp2ServerTest.groovy create mode 100644 instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowHttp2ServerTest.java delete mode 100644 instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerDispatchTest.groovy create mode 100644 instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerDispatchTest.java diff --git a/instrumentation/undertow-1.4/javaagent/src/test/groovy/UndertowHttp2ServerTest.groovy b/instrumentation/undertow-1.4/javaagent/src/test/groovy/UndertowHttp2ServerTest.groovy deleted file mode 100644 index 536e813940b0..000000000000 --- a/instrumentation/undertow-1.4/javaagent/src/test/groovy/UndertowHttp2ServerTest.groovy +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import io.undertow.Undertow -import io.undertow.UndertowOptions - -class UndertowHttp2ServerTest extends UndertowServerTest { - - void configureUndertow(Undertow.Builder builder) { - builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true) - } - - boolean useHttp2() { - true - } -} diff --git a/instrumentation/undertow-1.4/javaagent/src/test/groovy/UndertowServerDispatchTest.groovy b/instrumentation/undertow-1.4/javaagent/src/test/groovy/UndertowServerDispatchTest.groovy deleted file mode 100644 index 13a125c2d8e6..000000000000 --- a/instrumentation/undertow-1.4/javaagent/src/test/groovy/UndertowServerDispatchTest.groovy +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import io.opentelemetry.api.common.AttributeKey -import io.opentelemetry.instrumentation.test.AgentTestTrait -import io.opentelemetry.instrumentation.test.base.HttpServerTest -import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint -import io.opentelemetry.semconv.HttpAttributes -import io.undertow.Handlers -import io.undertow.Undertow -import io.undertow.util.Headers -import io.undertow.util.HttpString -import io.undertow.util.StatusCodes - -import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.CAPTURE_HEADERS -import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.ERROR -import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.INDEXED_CHILD -import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.QUERY_PARAM -import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.REDIRECT -import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.SUCCESS - -class UndertowServerDispatchTest extends HttpServerTest implements AgentTestTrait { - - @Override - boolean verifyServerSpanEndTime() { - return false - } - - @Override - boolean testException() { - // throwing exception from dispatched task just makes the request time out - return false - } - - @Override - boolean hasResponseCustomizer(ServerEndpoint endpoint) { - true - } - - @Override - Undertow startServer(int port) { - Undertow server = Undertow.builder() - .addHttpListener(port, "localhost") - .setHandler(Handlers.path() - .addExactPath(SUCCESS.rawPath()) { exchange -> - exchange.dispatch { - controller(SUCCESS) { - exchange.getResponseSender().send(SUCCESS.body) - } - } - } - .addExactPath(QUERY_PARAM.rawPath()) { exchange -> - exchange.dispatch { - controller(QUERY_PARAM) { - exchange.getResponseSender().send(exchange.getQueryString()) - } - } - } - .addExactPath(REDIRECT.rawPath()) { exchange -> - exchange.dispatch { - controller(REDIRECT) { - exchange.setStatusCode(StatusCodes.FOUND) - exchange.getResponseHeaders().put(Headers.LOCATION, REDIRECT.body) - exchange.endExchange() - } - } - } - .addExactPath(CAPTURE_HEADERS.rawPath()) { exchange -> - exchange.dispatch { - controller(CAPTURE_HEADERS) { - exchange.setStatusCode(StatusCodes.OK) - exchange.getResponseHeaders().put(new HttpString("X-Test-Response"), exchange.getRequestHeaders().getFirst("X-Test-Request")) - exchange.getResponseSender().send(CAPTURE_HEADERS.body) - } - } - } - .addExactPath(ERROR.rawPath()) { exchange -> - exchange.dispatch { - controller(ERROR) { - exchange.setStatusCode(ERROR.status) - exchange.getResponseSender().send(ERROR.body) - } - } - } - .addExactPath(INDEXED_CHILD.rawPath()) { exchange -> - exchange.dispatch { - controller(INDEXED_CHILD) { - INDEXED_CHILD.collectSpanAttributes { name -> exchange.getQueryParameters().get(name).peekFirst() } - exchange.getResponseSender().send(INDEXED_CHILD.body) - } - } - } - ).build() - server.start() - return server - } - - @Override - void stopServer(Undertow undertow) { - undertow.stop() - } - - @Override - Set> httpAttributes(ServerEndpoint endpoint) { - def attributes = super.httpAttributes(endpoint) - attributes.remove(HttpAttributes.HTTP_ROUTE) - attributes - } -} diff --git a/instrumentation/undertow-1.4/javaagent/src/test/groovy/UndertowServerTest.groovy b/instrumentation/undertow-1.4/javaagent/src/test/groovy/UndertowServerTest.groovy deleted file mode 100644 index 7d2a43bbb4f4..000000000000 --- a/instrumentation/undertow-1.4/javaagent/src/test/groovy/UndertowServerTest.groovy +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import io.opentelemetry.api.common.AttributeKey -import io.opentelemetry.api.trace.Span -import io.opentelemetry.api.trace.SpanKind -import io.opentelemetry.api.trace.StatusCode -import io.opentelemetry.instrumentation.test.AgentTestTrait -import io.opentelemetry.instrumentation.test.base.HttpServerTest -import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint -import io.opentelemetry.semconv.ServerAttributes -import io.opentelemetry.semconv.ClientAttributes -import io.opentelemetry.semconv.UserAgentAttributes -import io.opentelemetry.semconv.HttpAttributes -import io.opentelemetry.semconv.NetworkAttributes -import io.opentelemetry.semconv.UrlAttributes -import io.opentelemetry.testing.internal.armeria.common.AggregatedHttpResponse -import io.undertow.Handlers -import io.undertow.Undertow -import io.undertow.util.Headers -import io.undertow.util.HttpString -import io.undertow.util.StatusCodes - -import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.CAPTURE_HEADERS -import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.ERROR -import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.EXCEPTION -import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.INDEXED_CHILD -import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.QUERY_PARAM -import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.REDIRECT -import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.SUCCESS - -//TODO make test which mixes handlers and servlets -class UndertowServerTest extends HttpServerTest implements AgentTestTrait { - - @Override - Undertow startServer(int port) { - Undertow.Builder builder = Undertow.builder() - .addHttpListener(port, "localhost") - .setHandler(Handlers.path() - .addExactPath(SUCCESS.rawPath()) { exchange -> - controller(SUCCESS) { - exchange.getResponseSender().send(SUCCESS.body) - } - } - .addExactPath(QUERY_PARAM.rawPath()) { exchange -> - controller(QUERY_PARAM) { - exchange.getResponseSender().send(exchange.getQueryString()) - } - } - .addExactPath(REDIRECT.rawPath()) { exchange -> - controller(REDIRECT) { - exchange.setStatusCode(StatusCodes.FOUND) - exchange.getResponseHeaders().put(Headers.LOCATION, REDIRECT.body) - exchange.endExchange() - } - } - .addExactPath(CAPTURE_HEADERS.rawPath()) { exchange -> - controller(CAPTURE_HEADERS) { - exchange.setStatusCode(StatusCodes.OK) - exchange.getResponseHeaders().put(new HttpString("X-Test-Response"), exchange.getRequestHeaders().getFirst("X-Test-Request")) - exchange.getResponseSender().send(CAPTURE_HEADERS.body) - } - } - .addExactPath(ERROR.rawPath()) { exchange -> - controller(ERROR) { - exchange.setStatusCode(ERROR.status) - exchange.getResponseSender().send(ERROR.body) - } - } - .addExactPath(EXCEPTION.rawPath()) { exchange -> - controller(EXCEPTION) { - throw new Exception(EXCEPTION.body) - } - } - .addExactPath(INDEXED_CHILD.rawPath()) { exchange -> - controller(INDEXED_CHILD) { - INDEXED_CHILD.collectSpanAttributes { name -> exchange.getQueryParameters().get(name).peekFirst() } - exchange.getResponseSender().send(INDEXED_CHILD.body) - } - } - .addExactPath("sendResponse") { exchange -> - Span.current().addEvent("before-event") - runWithSpan("sendResponse") { - exchange.setStatusCode(StatusCodes.OK) - exchange.getResponseSender().send("sendResponse") - } - // event is added only when server span has not been ended - // we need to make sure that sending response does not end server span - Span.current().addEvent("after-event") - } - .addExactPath("sendResponseWithException") { exchange -> - Span.current().addEvent("before-event") - runWithSpan("sendResponseWithException") { - exchange.setStatusCode(StatusCodes.OK) - exchange.getResponseSender().send("sendResponseWithException") - } - // event is added only when server span has not been ended - // we need to make sure that sending response does not end server span - Span.current().addEvent("after-event") - throw new Exception("exception after sending response") - } - ) - configureUndertow(builder) - Undertow server = builder.build() - server.start() - return server - } - - @Override - void stopServer(Undertow undertow) { - undertow.stop() - } - - void configureUndertow(Undertow.Builder builder) { - } - - @Override - Set> httpAttributes(ServerEndpoint endpoint) { - def attributes = super.httpAttributes(endpoint) - attributes.remove(HttpAttributes.HTTP_ROUTE) - attributes - } - - @Override - boolean hasResponseCustomizer(ServerEndpoint endpoint) { - true - } - - def "test send response"() { - setup: - def uri = address.resolve("sendResponse") - AggregatedHttpResponse response = client.get(uri.toString()).aggregate().join() - - expect: - response.status().code() == 200 - response.contentUtf8().trim() == "sendResponse" - - and: - assertTraces(1) { - trace(0, 2) { - it.span(0) { - hasNoParent() - name "GET" - kind SpanKind.SERVER - - event(0) { - eventName "before-event" - } - event(1) { - eventName "after-event" - } - - def protocolVersion = useHttp2() ? "2" : "1.1" - attributes { - "$ClientAttributes.CLIENT_ADDRESS" TEST_CLIENT_IP - "$UrlAttributes.URL_SCHEME" uri.getScheme() - "$UrlAttributes.URL_PATH" uri.getPath() - "$HttpAttributes.HTTP_REQUEST_METHOD" "GET" - "$HttpAttributes.HTTP_RESPONSE_STATUS_CODE" 200 - "$UserAgentAttributes.USER_AGENT_ORIGINAL" TEST_USER_AGENT - "$NetworkAttributes.NETWORK_PROTOCOL_VERSION" protocolVersion - "$ServerAttributes.SERVER_ADDRESS" uri.host - "$ServerAttributes.SERVER_PORT" uri.port - "$NetworkAttributes.NETWORK_PEER_ADDRESS" "127.0.0.1" - "$NetworkAttributes.NETWORK_PEER_PORT" Long - } - } - span(1) { - name "sendResponse" - kind SpanKind.INTERNAL - childOf span(0) - } - } - } - } - - def "test send response with exception"() { - setup: - def uri = address.resolve("sendResponseWithException") - AggregatedHttpResponse response = client.get(uri.toString()).aggregate().join() - - expect: - response.status().code() == 200 - response.contentUtf8().trim() == "sendResponseWithException" - - and: - assertTraces(1) { - trace(0, 2) { - it.span(0) { - hasNoParent() - name "GET" - kind SpanKind.SERVER - status StatusCode.ERROR - - event(0) { - eventName "before-event" - } - event(1) { - eventName "after-event" - } - errorEvent(Exception, "exception after sending response", 2) - - def protocolVersion = useHttp2() ? "2" : "1.1" - attributes { - "$ClientAttributes.CLIENT_ADDRESS" TEST_CLIENT_IP - "$UrlAttributes.URL_SCHEME" uri.getScheme() - "$UrlAttributes.URL_PATH" uri.getPath() - "$HttpAttributes.HTTP_REQUEST_METHOD" "GET" - "$HttpAttributes.HTTP_RESPONSE_STATUS_CODE" 200 - "$UserAgentAttributes.USER_AGENT_ORIGINAL" TEST_USER_AGENT - "$NetworkAttributes.NETWORK_PROTOCOL_VERSION" protocolVersion - "$ServerAttributes.SERVER_ADDRESS" uri.host - "$ServerAttributes.SERVER_PORT" uri.port - "$NetworkAttributes.NETWORK_PEER_ADDRESS" "127.0.0.1" - "$NetworkAttributes.NETWORK_PEER_PORT" Long - } - } - span(1) { - name "sendResponseWithException" - kind SpanKind.INTERNAL - childOf span(0) - } - } - } - } -} diff --git a/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowHttp2ServerTest.groovy b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowHttp2ServerTest.groovy deleted file mode 100644 index d26d04de6c0b..000000000000 --- a/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowHttp2ServerTest.groovy +++ /dev/null @@ -1,19 +0,0 @@ -package io.opentelemetry.javaagent.instrumentation.undertow -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import io.undertow.Undertow -import io.undertow.UndertowOptions - -class UndertowHttp2ServerTest extends UndertowServerTest { - - void configureUndertow(Undertow.Builder builder) { - builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true) - } - - boolean useHttp2() { - true - } -} diff --git a/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowHttp2ServerTest.java b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowHttp2ServerTest.java new file mode 100644 index 000000000000..c84f08596b9b --- /dev/null +++ b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowHttp2ServerTest.java @@ -0,0 +1,22 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.undertow; + +import io.undertow.Undertow; +import io.undertow.UndertowOptions; + +class UndertowHttp2ServerTest extends UndertowServerTest { + + @Override + public void configureUndertow(Undertow.Builder builder) { + builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true); + } + + @Override + public boolean useHttp2() { + return true; + } +} diff --git a/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerDispatchTest.groovy b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerDispatchTest.groovy deleted file mode 100644 index 4022b2cacc5e..000000000000 --- a/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerDispatchTest.groovy +++ /dev/null @@ -1,109 +0,0 @@ -package io.opentelemetry.javaagent.instrumentation.undertow - -import io.opentelemetry.api.common.AttributeKey - -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import io.opentelemetry.instrumentation.test.AgentTestTrait -import io.opentelemetry.instrumentation.test.base.HttpServerTest -import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint -import io.opentelemetry.semconv.HttpAttributes -import io.undertow.Handlers -import io.undertow.Undertow -import io.undertow.util.Headers -import io.undertow.util.HttpString -import io.undertow.util.StatusCodes - -import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.* - -class UndertowServerDispatchTest extends HttpServerTest implements AgentTestTrait { - - @Override - boolean verifyServerSpanEndTime() { - return false - } - - @Override - boolean testException() { - // throwing exception from dispatched task just makes the request time out - return false - } - - @Override - boolean hasResponseCustomizer(ServerEndpoint endpoint) { - true - } - - @Override - Undertow startServer(int port) { - Undertow server = Undertow.builder() - .addHttpListener(port, "localhost") - .setHandler(Handlers.path() - .addExactPath(SUCCESS.rawPath()) { exchange -> - exchange.dispatch { - controller(SUCCESS) { - exchange.getResponseSender().send(SUCCESS.body) - } - } - } - .addExactPath(QUERY_PARAM.rawPath()) { exchange -> - exchange.dispatch { - controller(QUERY_PARAM) { - exchange.getResponseSender().send(exchange.getQueryString()) - } - } - } - .addExactPath(REDIRECT.rawPath()) { exchange -> - exchange.dispatch { - controller(REDIRECT) { - exchange.setStatusCode(StatusCodes.FOUND) - exchange.getResponseHeaders().put(Headers.LOCATION, REDIRECT.body) - exchange.endExchange() - } - } - } - .addExactPath(CAPTURE_HEADERS.rawPath()) { exchange -> - exchange.dispatch { - controller(CAPTURE_HEADERS) { - exchange.setStatusCode(StatusCodes.OK) - exchange.getResponseHeaders().put(new HttpString("X-Test-Response"), exchange.getRequestHeaders().getFirst("X-Test-Request")) - exchange.getResponseSender().send(CAPTURE_HEADERS.body) - } - } - } - .addExactPath(ERROR.rawPath()) { exchange -> - exchange.dispatch { - controller(ERROR) { - exchange.setStatusCode(ERROR.status) - exchange.getResponseSender().send(ERROR.body) - } - } - } - .addExactPath(INDEXED_CHILD.rawPath()) { exchange -> - exchange.dispatch { - controller(INDEXED_CHILD) { - INDEXED_CHILD.collectSpanAttributes { name -> exchange.getQueryParameters().get(name).peekFirst() } - exchange.getResponseSender().send(INDEXED_CHILD.body) - } - } - } - ).build() - server.start() - return server - } - - @Override - void stopServer(Undertow undertow) { - undertow.stop() - } - - @Override - Set> httpAttributes(ServerEndpoint endpoint) { - def attributes = super.httpAttributes(endpoint) - attributes.remove(HttpAttributes.HTTP_ROUTE) - attributes - } -} diff --git a/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerDispatchTest.java b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerDispatchTest.java new file mode 100644 index 000000000000..45d5d2b16cd3 --- /dev/null +++ b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerDispatchTest.java @@ -0,0 +1,150 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.undertow; + +import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.CAPTURE_HEADERS; +import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.ERROR; +import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.INDEXED_CHILD; +import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.QUERY_PARAM; +import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.REDIRECT; +import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.SUCCESS; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; +import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerTest; +import io.opentelemetry.instrumentation.testing.junit.http.HttpServerInstrumentationExtension; +import io.opentelemetry.instrumentation.testing.junit.http.HttpServerTestOptions; +import io.opentelemetry.semconv.HttpAttributes; +import io.undertow.Handlers; +import io.undertow.Undertow; +import io.undertow.server.HttpHandler; +import io.undertow.util.Headers; +import io.undertow.util.HttpString; +import io.undertow.util.StatusCodes; +import java.util.HashSet; +import java.util.Set; +import org.junit.jupiter.api.extension.RegisterExtension; + +public class UndertowServerDispatchTest extends AbstractHttpServerTest { + + @RegisterExtension + static final InstrumentationExtension testing = HttpServerInstrumentationExtension.forAgent(); + + @Override + public Undertow setupServer() { + Undertow server = + Undertow.builder() + .addHttpListener(port, "localhost") + .setHandler( + Handlers.path() + .addExactPath( + SUCCESS.rawPath(), + exchange -> + exchange.dispatch( + controller( + SUCCESS, + () -> + (HttpHandler) + k -> k.getResponseSender().send(SUCCESS.getBody())))) + .addExactPath( + QUERY_PARAM.rawPath(), + exchange -> + exchange.dispatch( + controller( + QUERY_PARAM, + () -> + (HttpHandler) + k -> k.getResponseSender().send(k.getQueryString())))) + .addExactPath( + REDIRECT.rawPath(), + exchange -> + exchange.dispatch( + controller( + REDIRECT, + () -> + (HttpHandler) + k -> { + k.setStatusCode(StatusCodes.FOUND); + k.getResponseHeaders() + .put(Headers.LOCATION, REDIRECT.getBody()); + k.endExchange(); + }))) + .addExactPath( + CAPTURE_HEADERS.rawPath(), + exchange -> + exchange.dispatch( + controller( + CAPTURE_HEADERS, + () -> + (HttpHandler) + k -> { + k.setStatusCode(StatusCodes.OK); + k.getResponseHeaders() + .put( + new HttpString("X-Test-Response"), + exchange + .getRequestHeaders() + .getFirst("X-Test-Request")); + k.getResponseSender().send(CAPTURE_HEADERS.getBody()); + }))) + .addExactPath( + ERROR.rawPath(), + exchange -> + exchange.dispatch( + controller( + ERROR, + () -> + (HttpHandler) + k -> { + exchange.setStatusCode(ERROR.getStatus()); + exchange.getResponseSender().send(ERROR.getBody()); + }))) + .addExactPath( + INDEXED_CHILD.rawPath(), + exchange -> + exchange.dispatch( + controller( + INDEXED_CHILD, + () -> + (HttpHandler) + k -> { + INDEXED_CHILD.collectSpanAttributes( + name -> + exchange + .getQueryParameters() + .get(name) + .peekFirst()); + exchange + .getResponseSender() + .send(INDEXED_CHILD.getBody()); + })))) + .build(); + server.start(); + return server; + } + + @Override + public void stopServer(Undertow undertow) { + undertow.stop(); + } + + @Override + protected void configure(HttpServerTestOptions options) { + super.configure(options); + options.setVerifyServerSpanEndTime(false); + // throwing exception from dispatched task just makes the request time out + options.setTestException(false); + options.setHasResponseCustomizer(endpoint -> true); + + options.setHttpAttributes( + endpoint -> { + Set> attributes = + new HashSet<>(HttpServerTestOptions.DEFAULT_HTTP_ATTRIBUTES); + attributes.remove(HttpAttributes.HTTP_ROUTE); + return attributes; + }); + } +} diff --git a/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerTest.java b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerTest.java index ee7a993f5362..77d40ffab5c8 100644 --- a/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerTest.java +++ b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerTest.java @@ -1,3 +1,8 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + package io.opentelemetry.javaagent.instrumentation.undertow; /* @@ -5,30 +10,44 @@ * SPDX-License-Identifier: Apache-2.0 */ +import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.CAPTURE_HEADERS; +import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.ERROR; +import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.EXCEPTION; +import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.INDEXED_CHILD; +import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.QUERY_PARAM; +import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.REDIRECT; +import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.SUCCESS; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies; +import static java.util.Collections.singletonList; +import static org.assertj.core.api.Assertions.assertThat; + import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanKind; -import io.opentelemetry.api.trace.StatusCode; -import io.opentelemetry.instrumentation.test.AgentTestTrait; -import io.opentelemetry.instrumentation.test.base.HttpServerTest; import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerTest; import io.opentelemetry.instrumentation.testing.junit.http.HttpServerInstrumentationExtension; -import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint; -import io.opentelemetry.semconv.*; +import io.opentelemetry.instrumentation.testing.junit.http.HttpServerTestOptions; +import io.opentelemetry.semconv.ClientAttributes; +import io.opentelemetry.semconv.HttpAttributes; +import io.opentelemetry.semconv.NetworkAttributes; +import io.opentelemetry.semconv.ServerAttributes; +import io.opentelemetry.semconv.UrlAttributes; +import io.opentelemetry.semconv.UserAgentAttributes; import io.opentelemetry.testing.internal.armeria.common.AggregatedHttpResponse; import io.undertow.Handlers; import io.undertow.Undertow; -import io.undertow.server.HttpHandler; -import io.undertow.server.HttpServerExchange; import io.undertow.util.Headers; import io.undertow.util.HttpString; import io.undertow.util.StatusCodes; -import java.util.function.Supplier; +import java.net.URI; +import java.util.Collections; +import java.util.HashSet; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.*; - -//TODO make test which mixes handlers and servlets +// TODO make test which mixes handlers and servlets class UndertowServerTest extends AbstractHttpServerTest { @RegisterExtension @@ -36,192 +55,214 @@ class UndertowServerTest extends AbstractHttpServerTest { @Override public Undertow setupServer() { - Undertow.Builder builder = Undertow.builder() - .addHttpListener(port, "localhost") - .setHandler(Handlers.path() - .addExactPath(SUCCESS.rawPath(), - controller(SUCCESS, - () -> exchange -> exchange.getResponseSender().send(SUCCESS.getBody())) - ) - .addExactPath(QUERY_PARAM.rawPath(), - controller(QUERY_PARAM, - () -> exchange -> exchange.getResponseSender().send(exchange.getQueryString())) - ) - .addExactPath(REDIRECT.rawPath(), - controller(REDIRECT , - () -> exchange -> { - exchange.setStatusCode(StatusCodes.FOUND); - exchange.getResponseHeaders().put(Headers.LOCATION, REDIRECT.getBody()); - exchange.endExchange(); - }) - ) - .addExactPath(CAPTURE_HEADERS.rawPath()) { exchange -> - controller(CAPTURE_HEADERS) { - exchange.setStatusCode(StatusCodes.OK) - exchange.getResponseHeaders().put(new HttpString("X-Test-Response"), exchange.getRequestHeaders().getFirst("X-Test-Request")) - exchange.getResponseSender().send(CAPTURE_HEADERS.body) - } - } - .addExactPath(ERROR.rawPath()) { exchange -> - controller(ERROR) { - exchange.setStatusCode(ERROR.status) - exchange.getResponseSender().send(ERROR.body) - } - } - .addExactPath(EXCEPTION.rawPath()) { exchange -> - controller(EXCEPTION) { - throw new Exception(EXCEPTION.body) - } - } - .addExactPath(INDEXED_CHILD.rawPath()) { exchange -> - controller(INDEXED_CHILD) { - INDEXED_CHILD.collectSpanAttributes { name -> exchange.getQueryParameters().get(name).peekFirst() } - exchange.getResponseSender().send(INDEXED_CHILD.body) - } - } - .addExactPath("sendResponse") { exchange -> - Span.current().addEvent("before-event") - runWithSpan("sendResponse") { - exchange.setStatusCode(StatusCodes.OK) - exchange.getResponseSender().send("sendResponse") - } - // event is added only when server span has not been ended - // we need to make sure that sending response does not end server span - Span.current().addEvent("after-event") - } - .addExactPath("sendResponseWithException") { exchange -> - Span.current().addEvent("before-event") - runWithSpan("sendResponseWithException") { - exchange.setStatusCode(StatusCodes.OK) - exchange.getResponseSender().send("sendResponseWithException") - } - // event is added only when server span has not been ended - // we need to make sure that sending response does not end server span - Span.current().addEvent("after-event") - throw new Exception("exception after sending response") - } - ) - configureUndertow(builder) - Undertow server = builder.build() - server.start() - return server + Undertow.Builder builder = + Undertow.builder() + .addHttpListener(port, "localhost") + .setHandler( + Handlers.path() + .addExactPath( + SUCCESS.rawPath(), + controller( + SUCCESS, + () -> exchange -> exchange.getResponseSender().send(SUCCESS.getBody()))) + .addExactPath( + QUERY_PARAM.rawPath(), + controller( + QUERY_PARAM, + () -> + exchange -> + exchange.getResponseSender().send(exchange.getQueryString()))) + .addExactPath( + REDIRECT.rawPath(), + controller( + REDIRECT, + () -> + exchange -> { + exchange.setStatusCode(StatusCodes.FOUND); + exchange + .getResponseHeaders() + .put(Headers.LOCATION, REDIRECT.getBody()); + exchange.endExchange(); + })) + .addExactPath( + CAPTURE_HEADERS.rawPath(), + controller( + CAPTURE_HEADERS, + () -> + exchange -> { + exchange.setStatusCode(StatusCodes.OK); + exchange + .getResponseHeaders() + .put( + new HttpString("X-Test-Response"), + exchange.getRequestHeaders().getFirst("X-Test-Request")); + exchange.getResponseSender().send(CAPTURE_HEADERS.getBody()); + })) + .addExactPath( + ERROR.rawPath(), + controller( + ERROR, + () -> + exchange -> { + exchange.setStatusCode(ERROR.getStatus()); + exchange.getResponseSender().send(ERROR.getBody()); + })) + .addExactPath( + EXCEPTION.rawPath(), + controller( + EXCEPTION, + () -> + exchange -> { + throw new Exception(EXCEPTION.getBody()); + })) + .addExactPath( + INDEXED_CHILD.rawPath(), + controller( + INDEXED_CHILD, + () -> + exchange -> { + INDEXED_CHILD.collectSpanAttributes( + name -> exchange.getQueryParameters().get(name).peekFirst()); + exchange.getResponseSender().send(INDEXED_CHILD.getBody()); + })) + .addExactPath( + "sendResponse", + exchange -> { + Span.current().addEvent("before-event"); + testing.runWithSpan( + "sendResponse", + () -> { + exchange.setStatusCode(StatusCodes.OK); + exchange.getResponseSender().send("sendResponse"); + }); + // event is added only when server span has not been ended + // we need to make sure that sending response does not end server span + Span.current().addEvent("after-event"); + }) + .addExactPath( + "sendResponseWithException", + exchange -> { + Span.current().addEvent("before-event"); + testing.runWithSpan( + "sendResponseWithException", + () -> { + exchange.setStatusCode(StatusCodes.OK); + exchange.getResponseSender().send("sendResponseWithException"); + }); + // event is added only when server span has not been ended + // we need to make sure that sending response does not end server span + Span.current().addEvent("after-event"); + throw new Exception("exception after sending response"); + })); + configureUndertow(builder); + Undertow server = builder.build(); + server.start(); + return server; } @Override - void stopServer(Undertow undertow) { - undertow.stop() - } - - void configureUndertow(Undertow.Builder builder) { + public void stopServer(Undertow undertow) { + undertow.stop(); } @Override - Set> httpAttributes(ServerEndpoint endpoint) { - def attributes = super.httpAttributes(endpoint) - attributes.remove(HttpAttributes.HTTP_ROUTE) - attributes + protected void configure(HttpServerTestOptions options) { + super.configure(options); + options.setHttpAttributes( + endpoint -> + Collections.unmodifiableSet( + new HashSet<>(singletonList(NetworkAttributes.NETWORK_PEER_PORT)))); + options.setHasResponseCustomizer(serverEndpoint -> true); + options.setUseHttp2(useHttp2()); } - @Override - boolean hasResponseCustomizer(ServerEndpoint endpoint) { - true + protected void configureUndertow(Undertow.Builder builder) {} + + protected boolean useHttp2() { + return false; } - def "test send response"() { - setup: - def uri = address.resolve("sendResponse") - AggregatedHttpResponse response = client.get(uri.toString()).aggregate().join() - - expect: - response.status().code() == 200 - response.contentUtf8().trim() == "sendResponse" - - and: - assertTraces(1) { - trace(0, 2) { - it.span(0) { - hasNoParent() - name "GET" - kind SpanKind.SERVER - - event(0) { - eventName "before-event" - } - event(1) { - eventName "after-event" - } - - def protocolVersion = useHttp2() ? "2" : "1.1" - attributes { - "$ClientAttributes.CLIENT_ADDRESS" TEST_CLIENT_IP - "$UrlAttributes.URL_SCHEME" uri.getScheme() - "$UrlAttributes.URL_PATH" uri.getPath() - "$HttpAttributes.HTTP_REQUEST_METHOD" "GET" - "$HttpAttributes.HTTP_RESPONSE_STATUS_CODE" 200 - "$UserAgentAttributes.USER_AGENT_ORIGINAL" TEST_USER_AGENT - "$NetworkAttributes.NETWORK_PROTOCOL_VERSION" protocolVersion - "$ServerAttributes.SERVER_ADDRESS" uri.host - "$ServerAttributes.SERVER_PORT" uri.port - "$NetworkAttributes.NETWORK_PEER_ADDRESS" "127.0.0.1" - "$NetworkAttributes.NETWORK_PEER_PORT" Long - } - } - span(1) { - name "sendResponse" - kind SpanKind.INTERNAL - childOf span(0) - } - } - } + @DisplayName("test send response") + @Test + void testSendResponse() { + URI uri = address.resolve("sendResponse"); + AggregatedHttpResponse response = client.get(uri.toString()).aggregate().join(); + + assertThat(response.status().code()).isEqualTo(200); + assertThat(response.contentUtf8().trim()).isEqualTo("sendResponse"); + + testing.waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> + span.hasName("GET") + .hasNoParent() + .hasKind(SpanKind.SERVER) + .hasEventsSatisfyingExactly( + event -> event.hasName("before-event"), + event -> event.hasName("after-event")) + .hasAttributesSatisfyingExactly( + equalTo(ClientAttributes.CLIENT_ADDRESS, TEST_CLIENT_IP), + equalTo(UrlAttributes.URL_SCHEME, uri.getScheme()), + equalTo(UrlAttributes.URL_PATH, uri.getPath()), + equalTo(HttpAttributes.HTTP_REQUEST_METHOD, "GET"), + equalTo(HttpAttributes.HTTP_RESPONSE_STATUS_CODE, 200), + equalTo(UserAgentAttributes.USER_AGENT_ORIGINAL, TEST_USER_AGENT), + equalTo( + NetworkAttributes.NETWORK_PROTOCOL_VERSION, + useHttp2() ? "2" : "1.1"), + equalTo(ServerAttributes.SERVER_ADDRESS, uri.getHost()), + equalTo(ServerAttributes.SERVER_PORT, uri.getPort()), + equalTo(NetworkAttributes.NETWORK_PEER_ADDRESS, "127.0.0.1"), + satisfies( + NetworkAttributes.NETWORK_PEER_PORT, + k -> k.isInstanceOf(Long.class))), + span -> + span.hasName("sendResponse") + .hasKind(SpanKind.INTERNAL) + .hasParent(trace.getSpan(0)))); } - def "test send response with exception"() { - setup: - def uri = address.resolve("sendResponseWithException") - AggregatedHttpResponse response = client.get(uri.toString()).aggregate().join() - - expect: - response.status().code() == 200 - response.contentUtf8().trim() == "sendResponseWithException" - - and: - assertTraces(1) { - trace(0, 2) { - it.span(0) { - hasNoParent() - name "GET" - kind SpanKind.SERVER - status StatusCode.ERROR - - event(0) { - eventName "before-event" - } - event(1) { - eventName "after-event" - } - errorEvent(Exception, "exception after sending response", 2) - - def protocolVersion = useHttp2() ? "2" : "1.1" - attributes { - "$ClientAttributes.CLIENT_ADDRESS" TEST_CLIENT_IP - "$UrlAttributes.URL_SCHEME" uri.getScheme() - "$UrlAttributes.URL_PATH" uri.getPath() - "$HttpAttributes.HTTP_REQUEST_METHOD" "GET" - "$HttpAttributes.HTTP_RESPONSE_STATUS_CODE" 200 - "$UserAgentAttributes.USER_AGENT_ORIGINAL" TEST_USER_AGENT - "$NetworkAttributes.NETWORK_PROTOCOL_VERSION" protocolVersion - "$ServerAttributes.SERVER_ADDRESS" uri.host - "$ServerAttributes.SERVER_PORT" uri.port - "$NetworkAttributes.NETWORK_PEER_ADDRESS" "127.0.0.1" - "$NetworkAttributes.NETWORK_PEER_PORT" Long - } - } - span(1) { - name "sendResponseWithException" - kind SpanKind.INTERNAL - childOf span(0) - } - } - } + @Test + @DisplayName("test send response with exception") + void testSendReponseWithException() { + URI uri = address.resolve("sendResponseWithException"); + AggregatedHttpResponse response = client.get(uri.toString()).aggregate().join(); + + assertThat(response.status().code()).isEqualTo(200); + assertThat(response.contentUtf8().trim()).isEqualTo("sendResponseWithException"); + + Exception exception = new Exception("exception after sending response"); + testing.waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> + span.hasName("GET") + .hasNoParent() + .hasKind(SpanKind.SERVER) + .hasEventsSatisfyingExactly( + event -> event.hasName("before-event"), + event -> event.hasName("after-event")) + .hasException(exception) + .hasAttributesSatisfyingExactly( + equalTo(ClientAttributes.CLIENT_ADDRESS, TEST_CLIENT_IP), + equalTo(UrlAttributes.URL_SCHEME, uri.getScheme()), + equalTo(UrlAttributes.URL_PATH, uri.getPath()), + equalTo(HttpAttributes.HTTP_REQUEST_METHOD, "GET"), + equalTo(HttpAttributes.HTTP_RESPONSE_STATUS_CODE, 200), + equalTo(UserAgentAttributes.USER_AGENT_ORIGINAL, TEST_USER_AGENT), + equalTo( + NetworkAttributes.NETWORK_PROTOCOL_VERSION, + useHttp2() ? "2" : "1.1"), + equalTo(ServerAttributes.SERVER_ADDRESS, uri.getHost()), + equalTo(ServerAttributes.SERVER_PORT, uri.getPort()), + equalTo(NetworkAttributes.NETWORK_PEER_ADDRESS, "127.0.0.1"), + satisfies( + NetworkAttributes.NETWORK_PEER_PORT, + k -> k.isInstanceOf(Long.class))), + span -> + span.hasName("sendResponseWithException") + .hasKind(SpanKind.INTERNAL) + .hasParent(trace.getSpan(0)))); } } From a8d5843ecaacd854046d9f72686e559e4281b1fb Mon Sep 17 00:00:00 2001 From: "shalk(xiao kun)" Date: Tue, 10 Sep 2024 20:41:59 +0800 Subject: [PATCH 03/10] add undertow ut --- .../undertow/UndertowServerDispatchTest.java | 79 +++++------ .../undertow/UndertowServerTest.java | 134 +++++++++++------- 2 files changed, 118 insertions(+), 95 deletions(-) diff --git a/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerDispatchTest.java b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerDispatchTest.java index 45d5d2b16cd3..d3c5ea415d0d 100644 --- a/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerDispatchTest.java +++ b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerDispatchTest.java @@ -11,24 +11,24 @@ import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.QUERY_PARAM; import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.REDIRECT; import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.SUCCESS; +import static java.util.Collections.singletonList; -import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerTest; import io.opentelemetry.instrumentation.testing.junit.http.HttpServerInstrumentationExtension; import io.opentelemetry.instrumentation.testing.junit.http.HttpServerTestOptions; -import io.opentelemetry.semconv.HttpAttributes; +import io.opentelemetry.instrumentation.testing.util.ThrowingRunnable; +import io.opentelemetry.semconv.NetworkAttributes; import io.undertow.Handlers; import io.undertow.Undertow; -import io.undertow.server.HttpHandler; import io.undertow.util.Headers; import io.undertow.util.HttpString; import io.undertow.util.StatusCodes; +import java.util.Collections; import java.util.HashSet; -import java.util.Set; import org.junit.jupiter.api.extension.RegisterExtension; -public class UndertowServerDispatchTest extends AbstractHttpServerTest { +class UndertowServerDispatchTest extends AbstractHttpServerTest { @RegisterExtension static final InstrumentationExtension testing = HttpServerInstrumentationExtension.forAgent(); @@ -44,29 +44,29 @@ public Undertow setupServer() { SUCCESS.rawPath(), exchange -> exchange.dispatch( - controller( - SUCCESS, - () -> - (HttpHandler) - k -> k.getResponseSender().send(SUCCESS.getBody())))) + k -> + testing.runWithSpan( + "controller", + (ThrowingRunnable) + () -> k.getResponseSender().send(SUCCESS.getBody())))) .addExactPath( QUERY_PARAM.rawPath(), exchange -> exchange.dispatch( - controller( - QUERY_PARAM, - () -> - (HttpHandler) - k -> k.getResponseSender().send(k.getQueryString())))) + k -> + testing.runWithSpan( + "controller", + (ThrowingRunnable) + () -> k.getResponseSender().send(k.getQueryString())))) .addExactPath( REDIRECT.rawPath(), exchange -> exchange.dispatch( - controller( - REDIRECT, - () -> - (HttpHandler) - k -> { + k -> + testing.runWithSpan( + "controller", + (ThrowingRunnable) + () -> { k.setStatusCode(StatusCodes.FOUND); k.getResponseHeaders() .put(Headers.LOCATION, REDIRECT.getBody()); @@ -76,11 +76,11 @@ public Undertow setupServer() { CAPTURE_HEADERS.rawPath(), exchange -> exchange.dispatch( - controller( - CAPTURE_HEADERS, - () -> - (HttpHandler) - k -> { + k -> + testing.runWithSpan( + "controller", + (ThrowingRunnable) + () -> { k.setStatusCode(StatusCodes.OK); k.getResponseHeaders() .put( @@ -94,11 +94,11 @@ public Undertow setupServer() { ERROR.rawPath(), exchange -> exchange.dispatch( - controller( - ERROR, - () -> - (HttpHandler) - k -> { + k -> + testing.runWithSpan( + "controller", + (ThrowingRunnable) + () -> { exchange.setStatusCode(ERROR.getStatus()); exchange.getResponseSender().send(ERROR.getBody()); }))) @@ -106,11 +106,11 @@ public Undertow setupServer() { INDEXED_CHILD.rawPath(), exchange -> exchange.dispatch( - controller( - INDEXED_CHILD, - () -> - (HttpHandler) - k -> { + k -> + testing.runWithSpan( + "controller", + (ThrowingRunnable) + () -> { INDEXED_CHILD.collectSpanAttributes( name -> exchange @@ -140,11 +140,8 @@ protected void configure(HttpServerTestOptions options) { options.setHasResponseCustomizer(endpoint -> true); options.setHttpAttributes( - endpoint -> { - Set> attributes = - new HashSet<>(HttpServerTestOptions.DEFAULT_HTTP_ATTRIBUTES); - attributes.remove(HttpAttributes.HTTP_ROUTE); - return attributes; - }); + endpoint -> + Collections.unmodifiableSet( + new HashSet<>(singletonList(NetworkAttributes.NETWORK_PEER_PORT)))); } } diff --git a/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerTest.java b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerTest.java index 77d40ffab5c8..adfc6e7b154b 100644 --- a/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerTest.java +++ b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerTest.java @@ -28,7 +28,9 @@ import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerTest; import io.opentelemetry.instrumentation.testing.junit.http.HttpServerInstrumentationExtension; import io.opentelemetry.instrumentation.testing.junit.http.HttpServerTestOptions; +import io.opentelemetry.instrumentation.testing.util.ThrowingRunnable; import io.opentelemetry.semconv.ClientAttributes; +import io.opentelemetry.semconv.ExceptionAttributes; import io.opentelemetry.semconv.HttpAttributes; import io.opentelemetry.semconv.NetworkAttributes; import io.opentelemetry.semconv.ServerAttributes; @@ -62,69 +64,82 @@ public Undertow setupServer() { Handlers.path() .addExactPath( SUCCESS.rawPath(), - controller( - SUCCESS, - () -> exchange -> exchange.getResponseSender().send(SUCCESS.getBody()))) + exchange -> + testing.runWithSpan( + "controller", + (ThrowingRunnable) + () -> exchange.getResponseSender().send(SUCCESS.getBody()))) .addExactPath( QUERY_PARAM.rawPath(), - controller( - QUERY_PARAM, - () -> - exchange -> - exchange.getResponseSender().send(exchange.getQueryString()))) + exchange -> + testing.runWithSpan( + "controller", + (ThrowingRunnable) + () -> + exchange + .getResponseSender() + .send(exchange.getQueryString()))) .addExactPath( REDIRECT.rawPath(), - controller( - REDIRECT, - () -> - exchange -> { - exchange.setStatusCode(StatusCodes.FOUND); - exchange - .getResponseHeaders() - .put(Headers.LOCATION, REDIRECT.getBody()); - exchange.endExchange(); - })) + exchange -> + testing.runWithSpan( + "controller", + (ThrowingRunnable) + () -> { + exchange.setStatusCode(StatusCodes.FOUND); + exchange + .getResponseHeaders() + .put(Headers.LOCATION, REDIRECT.getBody()); + exchange.endExchange(); + })) .addExactPath( CAPTURE_HEADERS.rawPath(), - controller( - CAPTURE_HEADERS, - () -> - exchange -> { - exchange.setStatusCode(StatusCodes.OK); - exchange - .getResponseHeaders() - .put( - new HttpString("X-Test-Response"), - exchange.getRequestHeaders().getFirst("X-Test-Request")); - exchange.getResponseSender().send(CAPTURE_HEADERS.getBody()); - })) + exchange -> + testing.runWithSpan( + "controller", + (ThrowingRunnable) + () -> { + exchange.setStatusCode(StatusCodes.OK); + exchange + .getResponseHeaders() + .put( + new HttpString("X-Test-Response"), + exchange + .getRequestHeaders() + .getFirst("X-Test-Request")); + exchange.getResponseSender().send(CAPTURE_HEADERS.getBody()); + })) .addExactPath( ERROR.rawPath(), - controller( - ERROR, - () -> - exchange -> { - exchange.setStatusCode(ERROR.getStatus()); - exchange.getResponseSender().send(ERROR.getBody()); - })) + exchange -> + testing.runWithSpan( + "controller", + (ThrowingRunnable) + () -> { + exchange.setStatusCode(ERROR.getStatus()); + exchange.getResponseSender().send(ERROR.getBody()); + })) .addExactPath( EXCEPTION.rawPath(), - controller( - EXCEPTION, - () -> - exchange -> { - throw new Exception(EXCEPTION.getBody()); - })) + exchange -> + testing.runWithSpan( + "controller", + (ThrowingRunnable) + () -> { + throw new Exception(EXCEPTION.getBody()); + })) .addExactPath( INDEXED_CHILD.rawPath(), - controller( - INDEXED_CHILD, - () -> - exchange -> { - INDEXED_CHILD.collectSpanAttributes( - name -> exchange.getQueryParameters().get(name).peekFirst()); - exchange.getResponseSender().send(INDEXED_CHILD.getBody()); - })) + exchange -> + testing.runWithSpan( + "controller", + (ThrowingRunnable) + () -> { + INDEXED_CHILD.collectSpanAttributes( + name -> + exchange.getQueryParameters().get(name).peekFirst()); + exchange.getResponseSender().send(INDEXED_CHILD.getBody()); + })) .addExactPath( "sendResponse", exchange -> { @@ -232,7 +247,6 @@ void testSendReponseWithException() { assertThat(response.status().code()).isEqualTo(200); assertThat(response.contentUtf8().trim()).isEqualTo("sendResponseWithException"); - Exception exception = new Exception("exception after sending response"); testing.waitAndAssertTraces( trace -> trace.hasSpansSatisfyingExactly( @@ -242,8 +256,20 @@ void testSendReponseWithException() { .hasKind(SpanKind.SERVER) .hasEventsSatisfyingExactly( event -> event.hasName("before-event"), - event -> event.hasName("after-event")) - .hasException(exception) + event -> event.hasName("after-event"), + event -> + event + .hasName("exception") + .hasAttributesSatisfyingExactly( + equalTo( + ExceptionAttributes.EXCEPTION_TYPE, + Exception.class.getName()), + equalTo( + ExceptionAttributes.EXCEPTION_MESSAGE, + "exception after sending response"), + satisfies( + ExceptionAttributes.EXCEPTION_STACKTRACE, + val -> val.isInstanceOf(String.class)))) .hasAttributesSatisfyingExactly( equalTo(ClientAttributes.CLIENT_ADDRESS, TEST_CLIENT_IP), equalTo(UrlAttributes.URL_SCHEME, uri.getScheme()), From 2200061864e8078c288bdc1c7db31d7092bd1728 Mon Sep 17 00:00:00 2001 From: "shalk(xiao kun)" Date: Tue, 10 Sep 2024 20:44:21 +0800 Subject: [PATCH 04/10] clean code --- .../instrumentation/undertow/UndertowServerTest.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerTest.java b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerTest.java index adfc6e7b154b..9944ed983bdb 100644 --- a/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerTest.java +++ b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerTest.java @@ -5,11 +5,6 @@ package io.opentelemetry.javaagent.instrumentation.undertow; -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.CAPTURE_HEADERS; import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.ERROR; import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.EXCEPTION; From 78e4631bc407cfe178c3b3148b22d90a8e65b4f8 Mon Sep 17 00:00:00 2001 From: "shalk(xiao kun)" Date: Thu, 12 Sep 2024 21:15:57 +0800 Subject: [PATCH 05/10] refine ut --- .../undertow/UndertowServerDispatchTest.java | 9 ++------- .../instrumentation/undertow/UndertowServerTest.java | 12 +++--------- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerDispatchTest.java b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerDispatchTest.java index d3c5ea415d0d..0a1bbe91aace 100644 --- a/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerDispatchTest.java +++ b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerDispatchTest.java @@ -11,8 +11,8 @@ import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.QUERY_PARAM; import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.REDIRECT; import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.SUCCESS; -import static java.util.Collections.singletonList; +import com.google.common.collect.ImmutableSet; import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerTest; import io.opentelemetry.instrumentation.testing.junit.http.HttpServerInstrumentationExtension; @@ -24,8 +24,6 @@ import io.undertow.util.Headers; import io.undertow.util.HttpString; import io.undertow.util.StatusCodes; -import java.util.Collections; -import java.util.HashSet; import org.junit.jupiter.api.extension.RegisterExtension; class UndertowServerDispatchTest extends AbstractHttpServerTest { @@ -139,9 +137,6 @@ protected void configure(HttpServerTestOptions options) { options.setTestException(false); options.setHasResponseCustomizer(endpoint -> true); - options.setHttpAttributes( - endpoint -> - Collections.unmodifiableSet( - new HashSet<>(singletonList(NetworkAttributes.NETWORK_PEER_PORT)))); + options.setHttpAttributes(endpoint -> ImmutableSet.of(NetworkAttributes.NETWORK_PEER_PORT)); } } diff --git a/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerTest.java b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerTest.java index 9944ed983bdb..80ac2776d18d 100644 --- a/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerTest.java +++ b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerTest.java @@ -14,9 +14,9 @@ import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.SUCCESS; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies; -import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; +import com.google.common.collect.ImmutableSet; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanKind; import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; @@ -38,13 +38,10 @@ import io.undertow.util.HttpString; import io.undertow.util.StatusCodes; import java.net.URI; -import java.util.Collections; -import java.util.HashSet; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -// TODO make test which mixes handlers and servlets class UndertowServerTest extends AbstractHttpServerTest { @RegisterExtension @@ -178,10 +175,7 @@ public void stopServer(Undertow undertow) { @Override protected void configure(HttpServerTestOptions options) { super.configure(options); - options.setHttpAttributes( - endpoint -> - Collections.unmodifiableSet( - new HashSet<>(singletonList(NetworkAttributes.NETWORK_PEER_PORT)))); + options.setHttpAttributes(endpoint -> ImmutableSet.of(NetworkAttributes.NETWORK_PEER_PORT)); options.setHasResponseCustomizer(serverEndpoint -> true); options.setUseHttp2(useHttp2()); } @@ -235,7 +229,7 @@ void testSendResponse() { @Test @DisplayName("test send response with exception") - void testSendReponseWithException() { + void testSendResponseWithException() { URI uri = address.resolve("sendResponseWithException"); AggregatedHttpResponse response = client.get(uri.toString()).aggregate().join(); From 6b8647d65841cba5698c662730b8b6263ab53d33 Mon Sep 17 00:00:00 2001 From: "shalk(xiao kun)" Date: Sun, 29 Sep 2024 14:49:19 +0800 Subject: [PATCH 06/10] refine ut --- .../undertow/UndertowServerDispatchTest.java | 107 +++++++++--------- .../undertow/UndertowServerTest.java | 100 ++++++++-------- 2 files changed, 104 insertions(+), 103 deletions(-) diff --git a/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerDispatchTest.java b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerDispatchTest.java index 0a1bbe91aace..5a2de0a2de52 100644 --- a/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerDispatchTest.java +++ b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerDispatchTest.java @@ -17,7 +17,6 @@ import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerTest; import io.opentelemetry.instrumentation.testing.junit.http.HttpServerInstrumentationExtension; import io.opentelemetry.instrumentation.testing.junit.http.HttpServerTestOptions; -import io.opentelemetry.instrumentation.testing.util.ThrowingRunnable; import io.opentelemetry.semconv.NetworkAttributes; import io.undertow.Handlers; import io.undertow.Undertow; @@ -43,82 +42,86 @@ public Undertow setupServer() { exchange -> exchange.dispatch( k -> - testing.runWithSpan( - "controller", - (ThrowingRunnable) - () -> k.getResponseSender().send(SUCCESS.getBody())))) + controller( + SUCCESS, + () -> { + k.getResponseSender().send(SUCCESS.getBody()); + return null; + }))) .addExactPath( QUERY_PARAM.rawPath(), exchange -> exchange.dispatch( k -> - testing.runWithSpan( - "controller", - (ThrowingRunnable) - () -> k.getResponseSender().send(k.getQueryString())))) + controller( + CAPTURE_HEADERS, + () -> { + k.getResponseSender().send(k.getQueryString()); + return null; + }))) .addExactPath( REDIRECT.rawPath(), exchange -> exchange.dispatch( k -> - testing.runWithSpan( - "controller", - (ThrowingRunnable) - () -> { - k.setStatusCode(StatusCodes.FOUND); - k.getResponseHeaders() - .put(Headers.LOCATION, REDIRECT.getBody()); - k.endExchange(); - }))) + controller( + CAPTURE_HEADERS, + () -> { + k.setStatusCode(StatusCodes.FOUND); + k.getResponseHeaders() + .put(Headers.LOCATION, REDIRECT.getBody()); + k.endExchange(); + return null; + }))) .addExactPath( CAPTURE_HEADERS.rawPath(), exchange -> exchange.dispatch( k -> - testing.runWithSpan( - "controller", - (ThrowingRunnable) - () -> { - k.setStatusCode(StatusCodes.OK); - k.getResponseHeaders() - .put( - new HttpString("X-Test-Response"), - exchange - .getRequestHeaders() - .getFirst("X-Test-Request")); - k.getResponseSender().send(CAPTURE_HEADERS.getBody()); - }))) + controller( + CAPTURE_HEADERS, + () -> { + k.setStatusCode(StatusCodes.OK); + k.getResponseHeaders() + .put( + new HttpString("X-Test-Response"), + exchange + .getRequestHeaders() + .getFirst("X-Test-Request")); + k.getResponseSender().send(CAPTURE_HEADERS.getBody()); + return null; + }))) .addExactPath( ERROR.rawPath(), exchange -> exchange.dispatch( k -> - testing.runWithSpan( - "controller", - (ThrowingRunnable) - () -> { - exchange.setStatusCode(ERROR.getStatus()); - exchange.getResponseSender().send(ERROR.getBody()); - }))) + controller( + ERROR, + () -> { + exchange.setStatusCode(ERROR.getStatus()); + exchange.getResponseSender().send(ERROR.getBody()); + return null; + }))) .addExactPath( INDEXED_CHILD.rawPath(), exchange -> exchange.dispatch( k -> - testing.runWithSpan( - "controller", - (ThrowingRunnable) - () -> { - INDEXED_CHILD.collectSpanAttributes( - name -> - exchange - .getQueryParameters() - .get(name) - .peekFirst()); - exchange - .getResponseSender() - .send(INDEXED_CHILD.getBody()); - })))) + controller( + INDEXED_CHILD, + () -> { + INDEXED_CHILD.collectSpanAttributes( + name -> + exchange + .getQueryParameters() + .get(name) + .peekFirst()); + exchange + .getResponseSender() + .send(INDEXED_CHILD.getBody()); + return null; + })))) .build(); server.start(); return server; diff --git a/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerTest.java b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerTest.java index 80ac2776d18d..357a9d180778 100644 --- a/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerTest.java +++ b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerTest.java @@ -57,60 +57,59 @@ public Undertow setupServer() { .addExactPath( SUCCESS.rawPath(), exchange -> - testing.runWithSpan( - "controller", - (ThrowingRunnable) - () -> exchange.getResponseSender().send(SUCCESS.getBody()))) + controller( + SUCCESS, + () -> { + exchange.getResponseSender().send(SUCCESS.getBody()); + return null; + })) .addExactPath( QUERY_PARAM.rawPath(), exchange -> - testing.runWithSpan( - "controller", - (ThrowingRunnable) - () -> - exchange - .getResponseSender() - .send(exchange.getQueryString()))) + controller( + QUERY_PARAM, + () -> { + exchange.getResponseSender().send(exchange.getQueryString()); + return null; + })) .addExactPath( REDIRECT.rawPath(), exchange -> - testing.runWithSpan( - "controller", - (ThrowingRunnable) - () -> { - exchange.setStatusCode(StatusCodes.FOUND); - exchange - .getResponseHeaders() - .put(Headers.LOCATION, REDIRECT.getBody()); - exchange.endExchange(); - })) + controller( + REDIRECT, + () -> { + exchange.setStatusCode(StatusCodes.FOUND); + exchange + .getResponseHeaders() + .put(Headers.LOCATION, REDIRECT.getBody()); + exchange.endExchange(); + return null; + })) .addExactPath( CAPTURE_HEADERS.rawPath(), exchange -> - testing.runWithSpan( - "controller", - (ThrowingRunnable) - () -> { - exchange.setStatusCode(StatusCodes.OK); - exchange - .getResponseHeaders() - .put( - new HttpString("X-Test-Response"), - exchange - .getRequestHeaders() - .getFirst("X-Test-Request")); - exchange.getResponseSender().send(CAPTURE_HEADERS.getBody()); - })) + controller( + CAPTURE_HEADERS, + () -> { + exchange.setStatusCode(StatusCodes.OK); + exchange + .getResponseHeaders() + .put( + new HttpString("X-Test-Response"), + exchange.getRequestHeaders().getFirst("X-Test-Request")); + exchange.getResponseSender().send(CAPTURE_HEADERS.getBody()); + return null; + })) .addExactPath( ERROR.rawPath(), exchange -> - testing.runWithSpan( - "controller", - (ThrowingRunnable) - () -> { - exchange.setStatusCode(ERROR.getStatus()); - exchange.getResponseSender().send(ERROR.getBody()); - })) + controller( + ERROR, + () -> { + exchange.setStatusCode(ERROR.getStatus()); + exchange.getResponseSender().send(ERROR.getBody()); + return null; + })) .addExactPath( EXCEPTION.rawPath(), exchange -> @@ -123,15 +122,14 @@ public Undertow setupServer() { .addExactPath( INDEXED_CHILD.rawPath(), exchange -> - testing.runWithSpan( - "controller", - (ThrowingRunnable) - () -> { - INDEXED_CHILD.collectSpanAttributes( - name -> - exchange.getQueryParameters().get(name).peekFirst()); - exchange.getResponseSender().send(INDEXED_CHILD.getBody()); - })) + controller( + INDEXED_CHILD, + () -> { + INDEXED_CHILD.collectSpanAttributes( + name -> exchange.getQueryParameters().get(name).peekFirst()); + exchange.getResponseSender().send(INDEXED_CHILD.getBody()); + return null; + })) .addExactPath( "sendResponse", exchange -> { From 9eabe496e7569950843fedd0c33ddaf9c6c9cf97 Mon Sep 17 00:00:00 2001 From: "shalk(xiao kun)" Date: Mon, 30 Sep 2024 11:42:32 +0800 Subject: [PATCH 07/10] fix latest undertow compile --- instrumentation/undertow-1.4/javaagent/build.gradle.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/instrumentation/undertow-1.4/javaagent/build.gradle.kts b/instrumentation/undertow-1.4/javaagent/build.gradle.kts index c220eb180396..6a8197708943 100644 --- a/instrumentation/undertow-1.4/javaagent/build.gradle.kts +++ b/instrumentation/undertow-1.4/javaagent/build.gradle.kts @@ -22,5 +22,6 @@ dependencies { } tasks.withType().configureEach { + jvmArgs("--add-opens=java.base/java.lang=ALL-UNNAMED") jvmArgs("-Dotel.instrumentation.common.experimental.controller-telemetry.enabled=true") } From ecffd68ccf5a4c0d7b4adfb27df5793d29e33421 Mon Sep 17 00:00:00 2001 From: "shalk(xiao kun)" Date: Mon, 30 Sep 2024 15:48:17 +0800 Subject: [PATCH 08/10] fix undertow testLatestDeps --- instrumentation/undertow-1.4/javaagent/build.gradle.kts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/instrumentation/undertow-1.4/javaagent/build.gradle.kts b/instrumentation/undertow-1.4/javaagent/build.gradle.kts index 6a8197708943..58be5ac61018 100644 --- a/instrumentation/undertow-1.4/javaagent/build.gradle.kts +++ b/instrumentation/undertow-1.4/javaagent/build.gradle.kts @@ -22,6 +22,13 @@ dependencies { } tasks.withType().configureEach { - jvmArgs("--add-opens=java.base/java.lang=ALL-UNNAMED") jvmArgs("-Dotel.instrumentation.common.experimental.controller-telemetry.enabled=true") } + +// since 2.3.x, undertow is compiled by JDK 11 +val latestDepTest = findProperty("testLatestDeps") as Boolean +if (latestDepTest) { + tasks.withType().configureEach { + options.release.set(11) + } +} From 7e725e7df2383c63a3371674b760b31765693941 Mon Sep 17 00:00:00 2001 From: "shalk(xiao kun)" Date: Tue, 8 Oct 2024 14:07:28 +0800 Subject: [PATCH 09/10] fix ut --- .../undertow/UndertowServerDispatchTest.java | 18 ++++-------------- .../undertow/UndertowServerTest.java | 14 ++------------ 2 files changed, 6 insertions(+), 26 deletions(-) diff --git a/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerDispatchTest.java b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerDispatchTest.java index 5a2de0a2de52..3bc1df859e5b 100644 --- a/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerDispatchTest.java +++ b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerDispatchTest.java @@ -44,34 +44,27 @@ public Undertow setupServer() { k -> controller( SUCCESS, - () -> { - k.getResponseSender().send(SUCCESS.getBody()); - return null; - }))) + () -> k.getResponseSender().send(SUCCESS.getBody())))) .addExactPath( QUERY_PARAM.rawPath(), exchange -> exchange.dispatch( k -> controller( - CAPTURE_HEADERS, - () -> { - k.getResponseSender().send(k.getQueryString()); - return null; - }))) + QUERY_PARAM, + () -> k.getResponseSender().send(k.getQueryString())))) .addExactPath( REDIRECT.rawPath(), exchange -> exchange.dispatch( k -> controller( - CAPTURE_HEADERS, + REDIRECT, () -> { k.setStatusCode(StatusCodes.FOUND); k.getResponseHeaders() .put(Headers.LOCATION, REDIRECT.getBody()); k.endExchange(); - return null; }))) .addExactPath( CAPTURE_HEADERS.rawPath(), @@ -89,7 +82,6 @@ public Undertow setupServer() { .getRequestHeaders() .getFirst("X-Test-Request")); k.getResponseSender().send(CAPTURE_HEADERS.getBody()); - return null; }))) .addExactPath( ERROR.rawPath(), @@ -101,7 +93,6 @@ public Undertow setupServer() { () -> { exchange.setStatusCode(ERROR.getStatus()); exchange.getResponseSender().send(ERROR.getBody()); - return null; }))) .addExactPath( INDEXED_CHILD.rawPath(), @@ -120,7 +111,6 @@ public Undertow setupServer() { exchange .getResponseSender() .send(INDEXED_CHILD.getBody()); - return null; })))) .build(); server.start(); diff --git a/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerTest.java b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerTest.java index 357a9d180778..bbadcf3b5c1b 100644 --- a/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerTest.java +++ b/instrumentation/undertow-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowServerTest.java @@ -59,19 +59,13 @@ public Undertow setupServer() { exchange -> controller( SUCCESS, - () -> { - exchange.getResponseSender().send(SUCCESS.getBody()); - return null; - })) + () -> exchange.getResponseSender().send(SUCCESS.getBody()))) .addExactPath( QUERY_PARAM.rawPath(), exchange -> controller( QUERY_PARAM, - () -> { - exchange.getResponseSender().send(exchange.getQueryString()); - return null; - })) + () -> exchange.getResponseSender().send(exchange.getQueryString()))) .addExactPath( REDIRECT.rawPath(), exchange -> @@ -83,7 +77,6 @@ public Undertow setupServer() { .getResponseHeaders() .put(Headers.LOCATION, REDIRECT.getBody()); exchange.endExchange(); - return null; })) .addExactPath( CAPTURE_HEADERS.rawPath(), @@ -98,7 +91,6 @@ public Undertow setupServer() { new HttpString("X-Test-Response"), exchange.getRequestHeaders().getFirst("X-Test-Request")); exchange.getResponseSender().send(CAPTURE_HEADERS.getBody()); - return null; })) .addExactPath( ERROR.rawPath(), @@ -108,7 +100,6 @@ public Undertow setupServer() { () -> { exchange.setStatusCode(ERROR.getStatus()); exchange.getResponseSender().send(ERROR.getBody()); - return null; })) .addExactPath( EXCEPTION.rawPath(), @@ -128,7 +119,6 @@ public Undertow setupServer() { INDEXED_CHILD.collectSpanAttributes( name -> exchange.getQueryParameters().get(name).peekFirst()); exchange.getResponseSender().send(INDEXED_CHILD.getBody()); - return null; })) .addExactPath( "sendResponse", From 2d6e5aae163cbc7a800adedc20f8e886500ff57f Mon Sep 17 00:00:00 2001 From: "shalk(xiao kun)" Date: Wed, 9 Oct 2024 10:46:34 +0800 Subject: [PATCH 10/10] fix undertow ci testLatestDeps --- instrumentation/undertow-1.4/javaagent/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/instrumentation/undertow-1.4/javaagent/build.gradle.kts b/instrumentation/undertow-1.4/javaagent/build.gradle.kts index 58be5ac61018..b3c268a25a03 100644 --- a/instrumentation/undertow-1.4/javaagent/build.gradle.kts +++ b/instrumentation/undertow-1.4/javaagent/build.gradle.kts @@ -28,7 +28,7 @@ tasks.withType().configureEach { // since 2.3.x, undertow is compiled by JDK 11 val latestDepTest = findProperty("testLatestDeps") as Boolean if (latestDepTest) { - tasks.withType().configureEach { - options.release.set(11) + otelJava { + minJavaVersionSupported.set(JavaVersion.VERSION_11) } }