convert undertow groovy test to java (#12207)
This commit is contained in:
parent
2986b570b4
commit
8f18c30493
|
@ -24,3 +24,11 @@ dependencies {
|
|||
tasks.withType<Test>().configureEach {
|
||||
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) {
|
||||
otelJava {
|
||||
minJavaVersionSupported.set(JavaVersion.VERSION_11)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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<Undertow> 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<AttributeKey<?>> httpAttributes(ServerEndpoint endpoint) {
|
||||
def attributes = super.httpAttributes(endpoint)
|
||||
attributes.remove(HttpAttributes.HTTP_ROUTE)
|
||||
attributes
|
||||
}
|
||||
}
|
|
@ -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<Undertow> 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<AttributeKey<?>> 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* 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 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;
|
||||
import io.opentelemetry.instrumentation.testing.junit.http.HttpServerTestOptions;
|
||||
import io.opentelemetry.semconv.NetworkAttributes;
|
||||
import io.undertow.Handlers;
|
||||
import io.undertow.Undertow;
|
||||
import io.undertow.util.Headers;
|
||||
import io.undertow.util.HttpString;
|
||||
import io.undertow.util.StatusCodes;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
|
||||
class UndertowServerDispatchTest extends AbstractHttpServerTest<Undertow> {
|
||||
|
||||
@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(
|
||||
k ->
|
||||
controller(
|
||||
SUCCESS,
|
||||
() -> k.getResponseSender().send(SUCCESS.getBody()))))
|
||||
.addExactPath(
|
||||
QUERY_PARAM.rawPath(),
|
||||
exchange ->
|
||||
exchange.dispatch(
|
||||
k ->
|
||||
controller(
|
||||
QUERY_PARAM,
|
||||
() -> k.getResponseSender().send(k.getQueryString()))))
|
||||
.addExactPath(
|
||||
REDIRECT.rawPath(),
|
||||
exchange ->
|
||||
exchange.dispatch(
|
||||
k ->
|
||||
controller(
|
||||
REDIRECT,
|
||||
() -> {
|
||||
k.setStatusCode(StatusCodes.FOUND);
|
||||
k.getResponseHeaders()
|
||||
.put(Headers.LOCATION, REDIRECT.getBody());
|
||||
k.endExchange();
|
||||
})))
|
||||
.addExactPath(
|
||||
CAPTURE_HEADERS.rawPath(),
|
||||
exchange ->
|
||||
exchange.dispatch(
|
||||
k ->
|
||||
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());
|
||||
})))
|
||||
.addExactPath(
|
||||
ERROR.rawPath(),
|
||||
exchange ->
|
||||
exchange.dispatch(
|
||||
k ->
|
||||
controller(
|
||||
ERROR,
|
||||
() -> {
|
||||
exchange.setStatusCode(ERROR.getStatus());
|
||||
exchange.getResponseSender().send(ERROR.getBody());
|
||||
})))
|
||||
.addExactPath(
|
||||
INDEXED_CHILD.rawPath(),
|
||||
exchange ->
|
||||
exchange.dispatch(
|
||||
k ->
|
||||
controller(
|
||||
INDEXED_CHILD,
|
||||
() -> {
|
||||
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 -> ImmutableSet.of(NetworkAttributes.NETWORK_PEER_PORT));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,271 @@
|
|||
/*
|
||||
* 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.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 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;
|
||||
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;
|
||||
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.util.Headers;
|
||||
import io.undertow.util.HttpString;
|
||||
import io.undertow.util.StatusCodes;
|
||||
import java.net.URI;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
|
||||
class UndertowServerTest extends AbstractHttpServerTest<Undertow> {
|
||||
|
||||
@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(),
|
||||
exchange ->
|
||||
controller(
|
||||
SUCCESS,
|
||||
() -> exchange.getResponseSender().send(SUCCESS.getBody())))
|
||||
.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.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.getBody());
|
||||
}))
|
||||
.addExactPath(
|
||||
ERROR.rawPath(),
|
||||
exchange ->
|
||||
controller(
|
||||
ERROR,
|
||||
() -> {
|
||||
exchange.setStatusCode(ERROR.getStatus());
|
||||
exchange.getResponseSender().send(ERROR.getBody());
|
||||
}))
|
||||
.addExactPath(
|
||||
EXCEPTION.rawPath(),
|
||||
exchange ->
|
||||
testing.runWithSpan(
|
||||
"controller",
|
||||
(ThrowingRunnable<Exception>)
|
||||
() -> {
|
||||
throw new Exception(EXCEPTION.getBody());
|
||||
}))
|
||||
.addExactPath(
|
||||
INDEXED_CHILD.rawPath(),
|
||||
exchange ->
|
||||
controller(
|
||||
INDEXED_CHILD,
|
||||
() -> {
|
||||
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
|
||||
public void stopServer(Undertow undertow) {
|
||||
undertow.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(HttpServerTestOptions options) {
|
||||
super.configure(options);
|
||||
options.setHttpAttributes(endpoint -> ImmutableSet.of(NetworkAttributes.NETWORK_PEER_PORT));
|
||||
options.setHasResponseCustomizer(serverEndpoint -> true);
|
||||
options.setUseHttp2(useHttp2());
|
||||
}
|
||||
|
||||
protected void configureUndertow(Undertow.Builder builder) {}
|
||||
|
||||
protected boolean useHttp2() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@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))));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("test send response with exception")
|
||||
void testSendResponseWithException() {
|
||||
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");
|
||||
|
||||
testing.waitAndAssertTraces(
|
||||
trace ->
|
||||
trace.hasSpansSatisfyingExactly(
|
||||
span ->
|
||||
span.hasName("GET")
|
||||
.hasNoParent()
|
||||
.hasKind(SpanKind.SERVER)
|
||||
.hasEventsSatisfyingExactly(
|
||||
event -> event.hasName("before-event"),
|
||||
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()),
|
||||
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))));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue