Migrate vertx tests to HttpServerTest
This commit is contained in:
parent
c5ccc67743
commit
668b1059f5
|
@ -20,7 +20,7 @@ abstract class AkkaHttpServerInstrumentationTest extends HttpServerTest<AkkaHttp
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean hasExceptionBody() {
|
boolean testExceptionBody() {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,12 @@ muzzle {
|
||||||
versions = "[4.0.0.Final,4.1.0.Final)"
|
versions = "[4.0.0.Final,4.1.0.Final)"
|
||||||
assertInverse = true
|
assertInverse = true
|
||||||
}
|
}
|
||||||
|
pass {
|
||||||
|
group = "io.vertx"
|
||||||
|
module = "vertx-core"
|
||||||
|
versions = "[2.0.0,3.3.0)"
|
||||||
|
assertInverse = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'org.unbroken-dome.test-sets'
|
apply plugin: 'org.unbroken-dome.test-sets'
|
||||||
|
|
|
@ -18,6 +18,12 @@ muzzle {
|
||||||
versions = "[4.1.0.Final,)"
|
versions = "[4.1.0.Final,)"
|
||||||
assertInverse = true
|
assertInverse = true
|
||||||
}
|
}
|
||||||
|
pass {
|
||||||
|
group = "io.vertx"
|
||||||
|
module = "vertx-core"
|
||||||
|
versions = "[3.3.0,)"
|
||||||
|
assertInverse = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'org.unbroken-dome.test-sets'
|
apply plugin: 'org.unbroken-dome.test-sets'
|
||||||
|
|
|
@ -1,157 +0,0 @@
|
||||||
import datadog.trace.agent.test.AgentTestRunner
|
|
||||||
import datadog.trace.agent.test.utils.OkHttpUtils
|
|
||||||
import datadog.trace.agent.test.utils.PortUtils
|
|
||||||
import datadog.trace.api.DDSpanTypes
|
|
||||||
import io.netty.handler.codec.http.HttpResponseStatus
|
|
||||||
import io.opentracing.tag.Tags
|
|
||||||
import io.vertx.core.Vertx
|
|
||||||
import okhttp3.OkHttpClient
|
|
||||||
import okhttp3.Request
|
|
||||||
import spock.lang.Shared
|
|
||||||
|
|
||||||
class VertxRxServerTest extends AgentTestRunner {
|
|
||||||
|
|
||||||
@Shared
|
|
||||||
OkHttpClient client = OkHttpUtils.client()
|
|
||||||
|
|
||||||
@Shared
|
|
||||||
int port
|
|
||||||
@Shared
|
|
||||||
Vertx server
|
|
||||||
|
|
||||||
def setupSpec() {
|
|
||||||
port = PortUtils.randomOpenPort()
|
|
||||||
server = VertxRxWebTestServer.start(port)
|
|
||||||
}
|
|
||||||
|
|
||||||
def cleanupSpec() {
|
|
||||||
server.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
def "test server request/response"() {
|
|
||||||
setup:
|
|
||||||
def request = new Request.Builder()
|
|
||||||
.url("http://localhost:$port/proxy")
|
|
||||||
.header("x-datadog-trace-id", "123")
|
|
||||||
.header("x-datadog-parent-id", "456")
|
|
||||||
.get()
|
|
||||||
.build()
|
|
||||||
def response = client.newCall(request).execute()
|
|
||||||
|
|
||||||
expect:
|
|
||||||
response.code() == 200
|
|
||||||
response.body().string() == "Hello World"
|
|
||||||
|
|
||||||
and:
|
|
||||||
assertTraces(2) {
|
|
||||||
trace(0, 2) {
|
|
||||||
span(0) {
|
|
||||||
serviceName "unnamed-java-app"
|
|
||||||
operationName "netty.request"
|
|
||||||
resourceName "GET /test"
|
|
||||||
childOf(trace(1).get(1))
|
|
||||||
spanType DDSpanTypes.HTTP_SERVER
|
|
||||||
errored false
|
|
||||||
tags {
|
|
||||||
"$Tags.COMPONENT.key" "netty"
|
|
||||||
"$Tags.HTTP_METHOD.key" "GET"
|
|
||||||
"$Tags.HTTP_STATUS.key" 200
|
|
||||||
"$Tags.HTTP_URL.key" "http://localhost:$port/test"
|
|
||||||
"$Tags.PEER_HOSTNAME.key" "localhost"
|
|
||||||
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
|
|
||||||
"$Tags.PEER_PORT.key" Integer
|
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
|
||||||
defaultTags(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
span(1) {
|
|
||||||
childOf span(0)
|
|
||||||
assert span(1).operationName.endsWith('.tracedMethod')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
trace(1, 2) {
|
|
||||||
span(0) {
|
|
||||||
serviceName "unnamed-java-app"
|
|
||||||
operationName "netty.request"
|
|
||||||
resourceName "GET /proxy"
|
|
||||||
traceId "123"
|
|
||||||
parentId "456"
|
|
||||||
spanType DDSpanTypes.HTTP_SERVER
|
|
||||||
errored false
|
|
||||||
tags {
|
|
||||||
"$Tags.COMPONENT.key" "netty"
|
|
||||||
"$Tags.HTTP_METHOD.key" "GET"
|
|
||||||
"$Tags.HTTP_STATUS.key" 200
|
|
||||||
"$Tags.HTTP_URL.key" "http://localhost:$port/proxy"
|
|
||||||
"$Tags.PEER_HOSTNAME.key" "localhost"
|
|
||||||
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
|
|
||||||
"$Tags.PEER_PORT.key" Integer
|
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
|
||||||
defaultTags(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
span(1) {
|
|
||||||
serviceName "unnamed-java-app"
|
|
||||||
operationName "netty.client.request"
|
|
||||||
resourceName "GET /test"
|
|
||||||
childOf(span(0))
|
|
||||||
spanType DDSpanTypes.HTTP_CLIENT
|
|
||||||
errored false
|
|
||||||
tags {
|
|
||||||
"$Tags.COMPONENT.key" "netty-client"
|
|
||||||
"$Tags.HTTP_METHOD.key" "GET"
|
|
||||||
"$Tags.HTTP_STATUS.key" 200
|
|
||||||
"$Tags.HTTP_URL.key" "http://localhost:$port/test"
|
|
||||||
"$Tags.PEER_HOSTNAME.key" "localhost"
|
|
||||||
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
|
|
||||||
"$Tags.PEER_PORT.key" Integer
|
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT
|
|
||||||
defaultTags()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def "test #responseCode response handling"() {
|
|
||||||
setup:
|
|
||||||
def request = new Request.Builder().url("http://localhost:$port/$path").get().build()
|
|
||||||
def response = client.newCall(request).execute()
|
|
||||||
|
|
||||||
expect:
|
|
||||||
response.code() == responseCode.code()
|
|
||||||
|
|
||||||
and:
|
|
||||||
assertTraces(1) {
|
|
||||||
trace(0, 1) {
|
|
||||||
span(0) {
|
|
||||||
serviceName "unnamed-java-app"
|
|
||||||
operationName "netty.request"
|
|
||||||
resourceName name
|
|
||||||
spanType DDSpanTypes.HTTP_SERVER
|
|
||||||
errored error
|
|
||||||
tags {
|
|
||||||
"$Tags.COMPONENT.key" "netty"
|
|
||||||
"$Tags.HTTP_METHOD.key" "GET"
|
|
||||||
"$Tags.HTTP_STATUS.key" responseCode.code()
|
|
||||||
"$Tags.HTTP_URL.key" "http://localhost:$port/$path"
|
|
||||||
"$Tags.PEER_HOSTNAME.key" "localhost"
|
|
||||||
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
|
|
||||||
"$Tags.PEER_PORT.key" Integer
|
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
|
||||||
if (error) {
|
|
||||||
tag("error", true)
|
|
||||||
}
|
|
||||||
defaultTags()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
where:
|
|
||||||
responseCode | name | path | error
|
|
||||||
HttpResponseStatus.OK | "GET /" | "" | false
|
|
||||||
HttpResponseStatus.NOT_FOUND | "404" | "doesnt-exit" | false
|
|
||||||
HttpResponseStatus.INTERNAL_SERVER_ERROR | "GET /error" | "error" | true
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,157 +0,0 @@
|
||||||
import datadog.trace.agent.test.AgentTestRunner
|
|
||||||
import datadog.trace.agent.test.utils.OkHttpUtils
|
|
||||||
import datadog.trace.agent.test.utils.PortUtils
|
|
||||||
import datadog.trace.api.DDSpanTypes
|
|
||||||
import io.netty.handler.codec.http.HttpResponseStatus
|
|
||||||
import io.opentracing.tag.Tags
|
|
||||||
import io.vertx.core.Vertx
|
|
||||||
import okhttp3.OkHttpClient
|
|
||||||
import okhttp3.Request
|
|
||||||
import spock.lang.Shared
|
|
||||||
|
|
||||||
class VertxServerTest extends AgentTestRunner {
|
|
||||||
|
|
||||||
@Shared
|
|
||||||
OkHttpClient client = OkHttpUtils.client()
|
|
||||||
|
|
||||||
@Shared
|
|
||||||
int port
|
|
||||||
@Shared
|
|
||||||
Vertx server
|
|
||||||
|
|
||||||
def setupSpec() {
|
|
||||||
port = PortUtils.randomOpenPort()
|
|
||||||
server = VertxWebTestServer.start(port)
|
|
||||||
}
|
|
||||||
|
|
||||||
def cleanupSpec() {
|
|
||||||
server.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
def "test server request/response"() {
|
|
||||||
setup:
|
|
||||||
def request = new Request.Builder()
|
|
||||||
.url("http://localhost:$port/proxy")
|
|
||||||
.header("x-datadog-trace-id", "123")
|
|
||||||
.header("x-datadog-parent-id", "456")
|
|
||||||
.get()
|
|
||||||
.build()
|
|
||||||
def response = client.newCall(request).execute()
|
|
||||||
|
|
||||||
expect:
|
|
||||||
response.code() == 200
|
|
||||||
response.body().string() == "Hello World"
|
|
||||||
|
|
||||||
and:
|
|
||||||
assertTraces(2) {
|
|
||||||
trace(0, 2) {
|
|
||||||
span(0) {
|
|
||||||
serviceName "unnamed-java-app"
|
|
||||||
operationName "netty.request"
|
|
||||||
resourceName "GET /test"
|
|
||||||
childOf(trace(1).get(1))
|
|
||||||
spanType DDSpanTypes.HTTP_SERVER
|
|
||||||
errored false
|
|
||||||
tags {
|
|
||||||
"$Tags.COMPONENT.key" "netty"
|
|
||||||
"$Tags.HTTP_METHOD.key" "GET"
|
|
||||||
"$Tags.HTTP_STATUS.key" 200
|
|
||||||
"$Tags.HTTP_URL.key" "http://localhost:$port/test"
|
|
||||||
"$Tags.PEER_HOSTNAME.key" "localhost"
|
|
||||||
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
|
|
||||||
"$Tags.PEER_PORT.key" Integer
|
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
|
||||||
defaultTags(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
span(1) {
|
|
||||||
childOf span(0)
|
|
||||||
assert span(1).operationName.endsWith('.tracedMethod')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
trace(1, 2) {
|
|
||||||
span(0) {
|
|
||||||
serviceName "unnamed-java-app"
|
|
||||||
operationName "netty.request"
|
|
||||||
resourceName "GET /proxy"
|
|
||||||
traceId "123"
|
|
||||||
parentId "456"
|
|
||||||
spanType DDSpanTypes.HTTP_SERVER
|
|
||||||
errored false
|
|
||||||
tags {
|
|
||||||
"$Tags.COMPONENT.key" "netty"
|
|
||||||
"$Tags.HTTP_METHOD.key" "GET"
|
|
||||||
"$Tags.HTTP_STATUS.key" 200
|
|
||||||
"$Tags.HTTP_URL.key" "http://localhost:$port/proxy"
|
|
||||||
"$Tags.PEER_HOSTNAME.key" "localhost"
|
|
||||||
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
|
|
||||||
"$Tags.PEER_PORT.key" Integer
|
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
|
||||||
defaultTags(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
span(1) {
|
|
||||||
serviceName "unnamed-java-app"
|
|
||||||
operationName "netty.client.request"
|
|
||||||
resourceName "GET /test"
|
|
||||||
childOf(span(0))
|
|
||||||
spanType DDSpanTypes.HTTP_CLIENT
|
|
||||||
errored false
|
|
||||||
tags {
|
|
||||||
"$Tags.COMPONENT.key" "netty-client"
|
|
||||||
"$Tags.HTTP_METHOD.key" "GET"
|
|
||||||
"$Tags.HTTP_STATUS.key" 200
|
|
||||||
"$Tags.HTTP_URL.key" "http://localhost:$port/test"
|
|
||||||
"$Tags.PEER_HOSTNAME.key" "localhost"
|
|
||||||
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
|
|
||||||
"$Tags.PEER_PORT.key" Integer
|
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT
|
|
||||||
defaultTags()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def "test #responseCode response handling"() {
|
|
||||||
setup:
|
|
||||||
def request = new Request.Builder().url("http://localhost:$port/$path").get().build()
|
|
||||||
def response = client.newCall(request).execute()
|
|
||||||
|
|
||||||
expect:
|
|
||||||
response.code() == responseCode.code()
|
|
||||||
|
|
||||||
and:
|
|
||||||
assertTraces(1) {
|
|
||||||
trace(0, 1) {
|
|
||||||
span(0) {
|
|
||||||
serviceName "unnamed-java-app"
|
|
||||||
operationName "netty.request"
|
|
||||||
resourceName name
|
|
||||||
spanType DDSpanTypes.HTTP_SERVER
|
|
||||||
errored error
|
|
||||||
tags {
|
|
||||||
"$Tags.COMPONENT.key" "netty"
|
|
||||||
"$Tags.HTTP_METHOD.key" "GET"
|
|
||||||
"$Tags.HTTP_STATUS.key" responseCode.code()
|
|
||||||
"$Tags.HTTP_URL.key" "http://localhost:$port/$path"
|
|
||||||
"$Tags.PEER_HOSTNAME.key" "localhost"
|
|
||||||
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
|
|
||||||
"$Tags.PEER_PORT.key" Integer
|
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
|
||||||
if (error) {
|
|
||||||
tag("error", true)
|
|
||||||
}
|
|
||||||
defaultTags()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
where:
|
|
||||||
responseCode | name | path | error
|
|
||||||
HttpResponseStatus.OK | "GET /" | "" | false
|
|
||||||
HttpResponseStatus.NOT_FOUND | "404" | "doesnt-exit" | false
|
|
||||||
HttpResponseStatus.INTERNAL_SERVER_ERROR | "GET /error" | "error" | true
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
package client
|
||||||
|
|
||||||
import datadog.trace.agent.test.base.HttpClientTest
|
import datadog.trace.agent.test.base.HttpClientTest
|
||||||
import datadog.trace.instrumentation.netty41.client.NettyHttpClientDecorator
|
import datadog.trace.instrumentation.netty41.client.NettyHttpClientDecorator
|
||||||
import io.vertx.core.Vertx
|
import io.vertx.core.Vertx
|
|
@ -0,0 +1,74 @@
|
||||||
|
package client
|
||||||
|
|
||||||
|
import datadog.trace.agent.test.base.HttpClientTest
|
||||||
|
import datadog.trace.instrumentation.netty41.client.NettyHttpClientDecorator
|
||||||
|
import io.vertx.circuitbreaker.CircuitBreakerOptions
|
||||||
|
import io.vertx.core.VertxOptions
|
||||||
|
import io.vertx.core.http.HttpMethod
|
||||||
|
import io.vertx.ext.web.client.HttpResponse
|
||||||
|
import io.vertx.reactivex.circuitbreaker.CircuitBreaker
|
||||||
|
import io.vertx.reactivex.core.Future
|
||||||
|
import io.vertx.reactivex.core.Vertx
|
||||||
|
import io.vertx.reactivex.ext.web.client.WebClient
|
||||||
|
import spock.lang.Shared
|
||||||
|
import spock.lang.Timeout
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture
|
||||||
|
|
||||||
|
@Timeout(10)
|
||||||
|
class VertxRxCircuitBreakerWebClientTest extends HttpClientTest<NettyHttpClientDecorator> {
|
||||||
|
|
||||||
|
@Shared
|
||||||
|
Vertx vertx = Vertx.vertx(new VertxOptions())
|
||||||
|
@Shared
|
||||||
|
WebClient client = WebClient.create(vertx)
|
||||||
|
@Shared
|
||||||
|
CircuitBreaker breaker = CircuitBreaker.create("my-circuit-breaker", vertx,
|
||||||
|
new CircuitBreakerOptions()
|
||||||
|
.setTimeout(-1) // Disable the timeout otherwise it makes each test take this long.
|
||||||
|
)
|
||||||
|
|
||||||
|
@Override
|
||||||
|
int doRequest(String method, URI uri, Map<String, String> headers, Closure callback) {
|
||||||
|
def request = client.request(HttpMethod.valueOf(method), uri.port, uri.host, "$uri")
|
||||||
|
headers.each { request.putHeader(it.key, it.value) }
|
||||||
|
Future<HttpResponse> result = breaker.execute { command ->
|
||||||
|
request.rxSend().doOnSuccess {
|
||||||
|
command.complete(it)
|
||||||
|
}.doOnError {
|
||||||
|
command.fail(it)
|
||||||
|
}.subscribe()
|
||||||
|
}
|
||||||
|
|
||||||
|
def future = new CompletableFuture<Integer>()
|
||||||
|
result.setHandler {
|
||||||
|
callback?.call()
|
||||||
|
if (it.succeeded()) {
|
||||||
|
future.complete(it.result().statusCode())
|
||||||
|
} else {
|
||||||
|
future.completeExceptionally(it.cause())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return future.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
NettyHttpClientDecorator decorator() {
|
||||||
|
return NettyHttpClientDecorator.DECORATE
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String expectedOperationName() {
|
||||||
|
return "netty.client.request"
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean testRedirects() {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean testConnectionFailure() {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,5 @@
|
||||||
|
package client
|
||||||
|
|
||||||
import datadog.trace.agent.test.base.HttpClientTest
|
import datadog.trace.agent.test.base.HttpClientTest
|
||||||
import datadog.trace.instrumentation.netty41.client.NettyHttpClientDecorator
|
import datadog.trace.instrumentation.netty41.client.NettyHttpClientDecorator
|
||||||
import io.vertx.core.VertxOptions
|
import io.vertx.core.VertxOptions
|
|
@ -0,0 +1,22 @@
|
||||||
|
package server;
|
||||||
|
|
||||||
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
|
|
||||||
|
import com.google.auto.service.AutoService;
|
||||||
|
import datadog.trace.agent.test.base.HttpServerTestAdvice;
|
||||||
|
import datadog.trace.agent.tooling.Instrumenter;
|
||||||
|
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||||
|
|
||||||
|
@AutoService(Instrumenter.class)
|
||||||
|
public class NettyServerTestInstrumentation implements Instrumenter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AgentBuilder instrument(final AgentBuilder agentBuilder) {
|
||||||
|
return agentBuilder
|
||||||
|
.type(named("io.netty.handler.codec.ByteToMessageDecoder"))
|
||||||
|
.transform(
|
||||||
|
new AgentBuilder.Transformer.ForAdvice()
|
||||||
|
.advice(
|
||||||
|
named("channelRead"), HttpServerTestAdvice.ServerEntryAdvice.class.getName()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,128 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
import datadog.trace.agent.test.asserts.ListWriterAssert
|
||||||
|
import datadog.trace.agent.test.base.HttpServerTest
|
||||||
|
import datadog.trace.instrumentation.netty41.server.NettyHttpServerDecorator
|
||||||
|
import groovy.transform.stc.ClosureParams
|
||||||
|
import groovy.transform.stc.SimpleType
|
||||||
|
import io.vertx.core.AbstractVerticle
|
||||||
|
import io.vertx.core.DeploymentOptions
|
||||||
|
import io.vertx.core.Future
|
||||||
|
import io.vertx.core.Vertx
|
||||||
|
import io.vertx.core.VertxOptions
|
||||||
|
import io.vertx.core.json.JsonObject
|
||||||
|
import io.vertx.ext.web.Router
|
||||||
|
import spock.lang.Shared
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture
|
||||||
|
|
||||||
|
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.ERROR
|
||||||
|
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.EXCEPTION
|
||||||
|
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.REDIRECT
|
||||||
|
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.SUCCESS
|
||||||
|
|
||||||
|
class VertxHttpServerTest extends HttpServerTest<NettyHttpServerDecorator> {
|
||||||
|
public static final String CONFIG_HTTP_SERVER_PORT = "http.server.port"
|
||||||
|
|
||||||
|
@Shared
|
||||||
|
Vertx server
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void startServer(int port) {
|
||||||
|
server = Vertx.vertx(new VertxOptions()
|
||||||
|
// Useful for debugging:
|
||||||
|
// .setBlockedThreadCheckInterval(Integer.MAX_VALUE)
|
||||||
|
.setClusterPort(port))
|
||||||
|
final CompletableFuture<Void> future = new CompletableFuture<>()
|
||||||
|
server.deployVerticle(verticle().name,
|
||||||
|
new DeploymentOptions()
|
||||||
|
.setConfig(new JsonObject().put(CONFIG_HTTP_SERVER_PORT, port))
|
||||||
|
.setInstances(3)) { res ->
|
||||||
|
if (!res.succeeded()) {
|
||||||
|
throw new RuntimeException("Cannot deploy server Verticle", res.cause())
|
||||||
|
}
|
||||||
|
future.complete(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
future.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Class<io.vertx.reactivex.core.AbstractVerticle> verticle() {
|
||||||
|
return VertxWebTestServer
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void stopServer() {
|
||||||
|
server.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
NettyHttpServerDecorator decorator() {
|
||||||
|
return NettyHttpServerDecorator.DECORATE
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String expectedOperationName() {
|
||||||
|
"netty.request"
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean testExceptionBody() {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
static class VertxWebTestServer extends AbstractVerticle {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void start(final Future<Void> startFuture) {
|
||||||
|
final int port = config().getInteger(CONFIG_HTTP_SERVER_PORT)
|
||||||
|
final Router router = Router.router(vertx)
|
||||||
|
|
||||||
|
router.route(SUCCESS.path).handler { ctx ->
|
||||||
|
controller(SUCCESS) {
|
||||||
|
ctx.response().setStatusCode(SUCCESS.status).end(SUCCESS.body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
router.route(REDIRECT.path).handler { ctx ->
|
||||||
|
controller(REDIRECT) {
|
||||||
|
ctx.response().setStatusCode(REDIRECT.status).putHeader("location", REDIRECT.body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
router.route(ERROR.path).handler { ctx ->
|
||||||
|
controller(ERROR) {
|
||||||
|
ctx.response().setStatusCode(ERROR.status).end(ERROR.body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
router.route(EXCEPTION.path).handler { ctx ->
|
||||||
|
controller(EXCEPTION) {
|
||||||
|
throw new Exception(EXCEPTION.body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vertx.createHttpServer()
|
||||||
|
.requestHandler { router.accept(it) }
|
||||||
|
.listen(port) { startFuture.complete() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cleanAndAssertTraces(
|
||||||
|
final int size,
|
||||||
|
@ClosureParams(value = SimpleType, options = "datadog.trace.agent.test.asserts.ListWriterAssert")
|
||||||
|
@DelegatesTo(value = ListWriterAssert, strategy = Closure.DELEGATE_FIRST)
|
||||||
|
final Closure spec) {
|
||||||
|
// If this is failing, make sure HttpServerTestAdvice is applied correctly.
|
||||||
|
TEST_WRITER.waitForTraces(size * 2)
|
||||||
|
|
||||||
|
// Netty closes the parent span before the controller returns, so we need to manually reorder it.
|
||||||
|
TEST_WRITER.each {
|
||||||
|
def controllerSpan = it.find {
|
||||||
|
it.operationName == "controller"
|
||||||
|
}
|
||||||
|
if (controllerSpan) {
|
||||||
|
it.remove(controllerSpan)
|
||||||
|
it.add(controllerSpan)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.cleanAndAssertTraces(size, spec)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,99 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
import datadog.trace.agent.test.base.HttpServerTest
|
||||||
|
import io.vertx.circuitbreaker.CircuitBreakerOptions
|
||||||
|
import io.vertx.reactivex.circuitbreaker.CircuitBreaker
|
||||||
|
import io.vertx.reactivex.core.AbstractVerticle
|
||||||
|
import io.vertx.reactivex.core.Future
|
||||||
|
import io.vertx.reactivex.ext.web.Router
|
||||||
|
|
||||||
|
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.ERROR
|
||||||
|
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.EXCEPTION
|
||||||
|
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.REDIRECT
|
||||||
|
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.SUCCESS
|
||||||
|
|
||||||
|
class VertxRxCircuitBreakerHttpServerTest extends VertxHttpServerTest {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<AbstractVerticle> verticle() {
|
||||||
|
return VertxRxCircuitBreakerWebTestServer
|
||||||
|
}
|
||||||
|
|
||||||
|
static class VertxRxCircuitBreakerWebTestServer extends AbstractVerticle {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void start(final io.vertx.core.Future<Void> startFuture) {
|
||||||
|
final int port = config().getInteger(CONFIG_HTTP_SERVER_PORT)
|
||||||
|
final Router router = Router.router(super.@vertx)
|
||||||
|
final CircuitBreaker breaker =
|
||||||
|
CircuitBreaker.create(
|
||||||
|
"my-circuit-breaker",
|
||||||
|
super.@vertx,
|
||||||
|
new CircuitBreakerOptions()
|
||||||
|
.setTimeout(-1) // Disable the timeout otherwise it makes each test take this long.
|
||||||
|
)
|
||||||
|
|
||||||
|
router.route(SUCCESS.path).handler { ctx ->
|
||||||
|
def result = breaker.execute { future ->
|
||||||
|
future.complete(SUCCESS)
|
||||||
|
}
|
||||||
|
result.setHandler {
|
||||||
|
if (it.failed()) {
|
||||||
|
throw it.cause();
|
||||||
|
}
|
||||||
|
HttpServerTest.ServerEndpoint endpoint = it.result()
|
||||||
|
controller(endpoint) {
|
||||||
|
ctx.response().setStatusCode(endpoint.status).end(endpoint.body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
router.route(REDIRECT.path).handler { ctx ->
|
||||||
|
def result = breaker.execute { future ->
|
||||||
|
future.complete(REDIRECT)
|
||||||
|
}
|
||||||
|
result.setHandler {
|
||||||
|
if (it.failed()) {
|
||||||
|
throw it.cause();
|
||||||
|
}
|
||||||
|
HttpServerTest.ServerEndpoint endpoint = it.result()
|
||||||
|
controller(endpoint) {
|
||||||
|
ctx.response().setStatusCode(endpoint.status).putHeader("location", endpoint.body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
router.route(ERROR.path).handler { ctx ->
|
||||||
|
def result = breaker.execute { future ->
|
||||||
|
future.complete(ERROR)
|
||||||
|
}
|
||||||
|
result.setHandler {
|
||||||
|
if (it.failed()) {
|
||||||
|
throw it.cause();
|
||||||
|
}
|
||||||
|
HttpServerTest.ServerEndpoint endpoint = it.result()
|
||||||
|
controller(endpoint) {
|
||||||
|
ctx.response().setStatusCode(endpoint.status).end(endpoint.body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
router.route(EXCEPTION.path).handler { ctx ->
|
||||||
|
def result = breaker.execute { future ->
|
||||||
|
future.fail(new Exception(EXCEPTION.body))
|
||||||
|
}
|
||||||
|
result.setHandler {
|
||||||
|
try {
|
||||||
|
def cause = it.cause()
|
||||||
|
controller(EXCEPTION) {
|
||||||
|
throw cause
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ctx.response().setStatusCode(EXCEPTION.status).end(ex.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
super.@vertx.createHttpServer()
|
||||||
|
.requestHandler { router.accept(it) }
|
||||||
|
.listen(port) { startFuture.complete() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
|
||||||
|
import io.vertx.core.Future
|
||||||
|
import io.vertx.reactivex.core.AbstractVerticle
|
||||||
|
import io.vertx.reactivex.ext.web.Router
|
||||||
|
|
||||||
|
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.ERROR
|
||||||
|
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.EXCEPTION
|
||||||
|
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.REDIRECT
|
||||||
|
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.SUCCESS
|
||||||
|
|
||||||
|
class VertxRxHttpServerTest extends VertxHttpServerTest {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<AbstractVerticle> verticle() {
|
||||||
|
return VertxRxWebTestServer
|
||||||
|
}
|
||||||
|
|
||||||
|
static class VertxRxWebTestServer extends AbstractVerticle {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void start(final Future<Void> startFuture) {
|
||||||
|
final int port = config().getInteger(CONFIG_HTTP_SERVER_PORT)
|
||||||
|
final Router router = Router.router(super.@vertx)
|
||||||
|
|
||||||
|
router.route(SUCCESS.path).handler { ctx ->
|
||||||
|
controller(SUCCESS) {
|
||||||
|
ctx.response().setStatusCode(SUCCESS.status).end(SUCCESS.body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
router.route(REDIRECT.path).handler { ctx ->
|
||||||
|
controller(REDIRECT) {
|
||||||
|
ctx.response().setStatusCode(REDIRECT.status).putHeader("location", REDIRECT.body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
router.route(ERROR.path).handler { ctx ->
|
||||||
|
controller(ERROR) {
|
||||||
|
ctx.response().setStatusCode(ERROR.status).end(ERROR.body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
router.route(EXCEPTION.path).handler { ctx ->
|
||||||
|
controller(EXCEPTION) {
|
||||||
|
throw new Exception(EXCEPTION.body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
super.@vertx.createHttpServer()
|
||||||
|
.requestHandler { router.accept(it) }
|
||||||
|
.listen(port) { startFuture.complete() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,116 +0,0 @@
|
||||||
import datadog.trace.api.Trace;
|
|
||||||
import io.vertx.circuitbreaker.CircuitBreakerOptions;
|
|
||||||
import io.vertx.core.DeploymentOptions;
|
|
||||||
import io.vertx.core.Future;
|
|
||||||
import io.vertx.core.Vertx;
|
|
||||||
import io.vertx.core.VertxOptions;
|
|
||||||
import io.vertx.core.json.JsonObject;
|
|
||||||
import io.vertx.reactivex.circuitbreaker.CircuitBreaker;
|
|
||||||
import io.vertx.reactivex.core.AbstractVerticle;
|
|
||||||
import io.vertx.reactivex.core.buffer.Buffer;
|
|
||||||
import io.vertx.reactivex.ext.web.Router;
|
|
||||||
import io.vertx.reactivex.ext.web.RoutingContext;
|
|
||||||
import io.vertx.reactivex.ext.web.client.WebClient;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
|
|
||||||
public class VertxRxWebTestServer extends AbstractVerticle {
|
|
||||||
public static final String CONFIG_HTTP_SERVER_PORT = "http.server.port";
|
|
||||||
|
|
||||||
public static Vertx start(final int port) throws ExecutionException, InterruptedException {
|
|
||||||
/* This is highly against Vertx ideas, but our tests are synchronous
|
|
||||||
so we have to make sure server is up and running */
|
|
||||||
final CompletableFuture<Void> future = new CompletableFuture<>();
|
|
||||||
|
|
||||||
final Vertx vertx = Vertx.vertx(new VertxOptions().setClusterPort(port));
|
|
||||||
|
|
||||||
vertx.deployVerticle(
|
|
||||||
VertxRxWebTestServer.class.getName(),
|
|
||||||
new DeploymentOptions()
|
|
||||||
.setConfig(new JsonObject().put(CONFIG_HTTP_SERVER_PORT, port))
|
|
||||||
.setInstances(3),
|
|
||||||
res -> {
|
|
||||||
if (!res.succeeded()) {
|
|
||||||
throw new RuntimeException("Cannot deploy server Verticle", res.cause());
|
|
||||||
}
|
|
||||||
future.complete(null);
|
|
||||||
});
|
|
||||||
|
|
||||||
future.get();
|
|
||||||
|
|
||||||
return vertx;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void start(final Future<Void> startFuture) {
|
|
||||||
// final io.vertx.reactivex.core.Vertx vertx = new io.vertx.reactivex.core.Vertx(this.vertx);
|
|
||||||
final WebClient client = WebClient.create(vertx);
|
|
||||||
|
|
||||||
final int port = config().getInteger(CONFIG_HTTP_SERVER_PORT);
|
|
||||||
|
|
||||||
final Router router = Router.router(vertx);
|
|
||||||
final CircuitBreaker breaker =
|
|
||||||
CircuitBreaker.create(
|
|
||||||
"my-circuit-breaker",
|
|
||||||
vertx,
|
|
||||||
new CircuitBreakerOptions()
|
|
||||||
.setMaxFailures(5) // number of failure before opening the circuit
|
|
||||||
.setTimeout(2000) // consider a failure if the operation does not succeed in time
|
|
||||||
// .setFallbackOnFailure(true) // do we call the fallback on failure
|
|
||||||
.setResetTimeout(10000) // time spent in open state before attempting to re-try
|
|
||||||
);
|
|
||||||
|
|
||||||
router
|
|
||||||
.route("/")
|
|
||||||
.handler(
|
|
||||||
routingContext -> {
|
|
||||||
routingContext.response().putHeader("content-type", "text/html").end("Hello World");
|
|
||||||
});
|
|
||||||
router
|
|
||||||
.route("/error")
|
|
||||||
.handler(
|
|
||||||
routingContext -> {
|
|
||||||
routingContext.response().setStatusCode(500).end();
|
|
||||||
});
|
|
||||||
router
|
|
||||||
.route("/proxy")
|
|
||||||
.handler(
|
|
||||||
routingContext -> {
|
|
||||||
breaker.execute(
|
|
||||||
ctx -> {
|
|
||||||
client
|
|
||||||
.get(port, "localhost", "/test")
|
|
||||||
.rxSendBuffer(
|
|
||||||
Optional.ofNullable(routingContext.getBody()).orElse(Buffer.buffer()))
|
|
||||||
.subscribe(
|
|
||||||
response -> {
|
|
||||||
routingContext
|
|
||||||
.response()
|
|
||||||
.setStatusCode(response.statusCode())
|
|
||||||
.end(response.body());
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
router
|
|
||||||
.route("/test")
|
|
||||||
.handler(
|
|
||||||
routingContext -> {
|
|
||||||
tracedMethod();
|
|
||||||
routingContext.next();
|
|
||||||
})
|
|
||||||
.blockingHandler(RoutingContext::next)
|
|
||||||
.handler(
|
|
||||||
routingContext -> {
|
|
||||||
routingContext.response().putHeader("content-type", "text/html").end("Hello World");
|
|
||||||
});
|
|
||||||
|
|
||||||
vertx
|
|
||||||
.createHttpServer()
|
|
||||||
.requestHandler(router::accept)
|
|
||||||
.listen(port, h -> startFuture.complete());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Trace
|
|
||||||
private void tracedMethod() {}
|
|
||||||
}
|
|
|
@ -1,107 +0,0 @@
|
||||||
import static datadog.trace.agent.test.AgentTestRunner.blockUntilChildSpansFinished;
|
|
||||||
|
|
||||||
import datadog.trace.api.Trace;
|
|
||||||
import io.vertx.core.AbstractVerticle;
|
|
||||||
import io.vertx.core.DeploymentOptions;
|
|
||||||
import io.vertx.core.Future;
|
|
||||||
import io.vertx.core.Vertx;
|
|
||||||
import io.vertx.core.VertxOptions;
|
|
||||||
import io.vertx.core.buffer.Buffer;
|
|
||||||
import io.vertx.core.http.HttpClient;
|
|
||||||
import io.vertx.core.json.JsonObject;
|
|
||||||
import io.vertx.ext.web.Router;
|
|
||||||
import io.vertx.ext.web.RoutingContext;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
|
|
||||||
public class VertxWebTestServer extends AbstractVerticle {
|
|
||||||
public static final String CONFIG_HTTP_SERVER_PORT = "http.server.port";
|
|
||||||
|
|
||||||
public static Vertx start(final int port) throws ExecutionException, InterruptedException {
|
|
||||||
/* This is highly against Vertx ideas, but our tests are synchronous
|
|
||||||
so we have to make sure server is up and running */
|
|
||||||
final CompletableFuture<Void> future = new CompletableFuture<>();
|
|
||||||
|
|
||||||
final Vertx vertx = Vertx.vertx(new VertxOptions().setClusterPort(port));
|
|
||||||
|
|
||||||
vertx.deployVerticle(
|
|
||||||
VertxWebTestServer.class.getName(),
|
|
||||||
new DeploymentOptions()
|
|
||||||
.setConfig(new JsonObject().put(CONFIG_HTTP_SERVER_PORT, port))
|
|
||||||
.setInstances(3),
|
|
||||||
res -> {
|
|
||||||
if (!res.succeeded()) {
|
|
||||||
throw new RuntimeException("Cannot deploy server Verticle", res.cause());
|
|
||||||
}
|
|
||||||
future.complete(null);
|
|
||||||
});
|
|
||||||
|
|
||||||
future.get();
|
|
||||||
|
|
||||||
return vertx;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void start(final Future<Void> startFuture) {
|
|
||||||
final HttpClient client = vertx.createHttpClient();
|
|
||||||
|
|
||||||
final int port = config().getInteger(CONFIG_HTTP_SERVER_PORT);
|
|
||||||
|
|
||||||
final Router router = Router.router(vertx);
|
|
||||||
|
|
||||||
router
|
|
||||||
.route("/")
|
|
||||||
.handler(
|
|
||||||
routingContext -> {
|
|
||||||
routingContext.response().putHeader("content-type", "text/html").end("Hello World");
|
|
||||||
});
|
|
||||||
router
|
|
||||||
.route("/error")
|
|
||||||
.handler(
|
|
||||||
routingContext -> {
|
|
||||||
routingContext.response().setStatusCode(500).end();
|
|
||||||
});
|
|
||||||
router
|
|
||||||
.route("/proxy")
|
|
||||||
.handler(
|
|
||||||
routingContext -> {
|
|
||||||
client
|
|
||||||
.get(
|
|
||||||
port,
|
|
||||||
"localhost",
|
|
||||||
"/test",
|
|
||||||
response -> {
|
|
||||||
response.bodyHandler(
|
|
||||||
buffer -> {
|
|
||||||
routingContext
|
|
||||||
.response()
|
|
||||||
.setStatusCode(response.statusCode())
|
|
||||||
.end(buffer);
|
|
||||||
});
|
|
||||||
blockUntilChildSpansFinished(1);
|
|
||||||
})
|
|
||||||
.end(Optional.ofNullable(routingContext.getBody()).orElse(Buffer.buffer()));
|
|
||||||
});
|
|
||||||
router
|
|
||||||
.route("/test")
|
|
||||||
.handler(
|
|
||||||
routingContext -> {
|
|
||||||
tracedMethod();
|
|
||||||
routingContext.next();
|
|
||||||
})
|
|
||||||
.blockingHandler(RoutingContext::next)
|
|
||||||
.handler(
|
|
||||||
routingContext -> {
|
|
||||||
routingContext.response().putHeader("content-type", "text/html").end("Hello World");
|
|
||||||
});
|
|
||||||
|
|
||||||
vertx
|
|
||||||
.createHttpServer()
|
|
||||||
.requestHandler(router::accept)
|
|
||||||
.listen(port, h -> startFuture.complete());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Trace
|
|
||||||
private void tracedMethod() {}
|
|
||||||
}
|
|
|
@ -5,21 +5,6 @@ ext {
|
||||||
|
|
||||||
apply from: "${rootDir}/gradle/java.gradle"
|
apply from: "${rootDir}/gradle/java.gradle"
|
||||||
|
|
||||||
muzzle {
|
|
||||||
pass {
|
|
||||||
group = "io.vertx"
|
|
||||||
module = "vertx-web"
|
|
||||||
versions = "[4.1.0.Final,)"
|
|
||||||
assertInverse = true
|
|
||||||
}
|
|
||||||
pass {
|
|
||||||
group = "io.netty"
|
|
||||||
module = "netty"
|
|
||||||
versions = "[4.1.0.Final,)"
|
|
||||||
assertInverse = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
apply plugin: 'org.unbroken-dome.test-sets'
|
apply plugin: 'org.unbroken-dome.test-sets'
|
||||||
|
|
||||||
testSets {
|
testSets {
|
||||||
|
|
|
@ -72,15 +72,15 @@ abstract class HttpServerTest<DECORATOR extends HttpServerDecorator> extends Age
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean hasExceptionBody() {
|
boolean testExceptionBody() {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ServerEndpoint {
|
public enum ServerEndpoint {
|
||||||
SUCCESS("success", 200, "success"),
|
SUCCESS("success", 200, "success"),
|
||||||
|
REDIRECT("redirect", 302, null),
|
||||||
ERROR("error", 500, "controller error"),
|
ERROR("error", 500, "controller error"),
|
||||||
EXCEPTION("exception", 500, "controller exception"),
|
EXCEPTION("exception", 500, "controller exception"),
|
||||||
REDIRECT("redirect", 302, null),
|
|
||||||
NOT_FOUND("notFound", 404, "not found"),
|
NOT_FOUND("notFound", 404, "not found"),
|
||||||
AUTH_REQUIRED("authRequired", 200, null),
|
AUTH_REQUIRED("authRequired", 200, null),
|
||||||
|
|
||||||
|
@ -214,7 +214,7 @@ abstract class HttpServerTest<DECORATOR extends HttpServerDecorator> extends Age
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
response.code() == EXCEPTION.status
|
response.code() == EXCEPTION.status
|
||||||
if (hasExceptionBody()) {
|
if (testExceptionBody()) {
|
||||||
assert response.body().string() == EXCEPTION.body
|
assert response.body().string() == EXCEPTION.body
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue