Migrate HttpServerTest to Armeria (#3240)
* Migrate HttpServerTest to Armeria * Update testing-common/src/main/groovy/io/opentelemetry/instrumentation/test/base/HttpServerTest.groovy Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com> Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
This commit is contained in:
parent
d79fb8cc84
commit
60aaff8972
|
@ -9,13 +9,9 @@ import static io.opentelemetry.api.trace.SpanKind.SERVER
|
|||
|
||||
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
|
||||
import io.opentelemetry.instrumentation.test.RetryOnAddressAlreadyInUseTrait
|
||||
import io.opentelemetry.instrumentation.test.utils.OkHttpUtils
|
||||
import io.opentelemetry.instrumentation.test.utils.PortUtils
|
||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
|
||||
import okhttp3.FormBody
|
||||
import okhttp3.HttpUrl
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import io.opentelemetry.testing.armeria.client.WebClient
|
||||
import org.springframework.boot.SpringApplication
|
||||
import org.springframework.context.ConfigurableApplicationContext
|
||||
import spock.lang.Shared
|
||||
|
@ -25,7 +21,7 @@ class SingleServiceCamelTest extends AgentInstrumentationSpecification implement
|
|||
@Shared
|
||||
ConfigurableApplicationContext server
|
||||
@Shared
|
||||
OkHttpClient client = OkHttpUtils.client()
|
||||
WebClient client = WebClient.of()
|
||||
@Shared
|
||||
int port
|
||||
@Shared
|
||||
|
@ -56,15 +52,9 @@ class SingleServiceCamelTest extends AgentInstrumentationSpecification implement
|
|||
def "single camel service span"() {
|
||||
setup:
|
||||
def requestUrl = address.resolve("/camelService")
|
||||
def url = HttpUrl.get(requestUrl)
|
||||
def request = new Request.Builder()
|
||||
.url(url)
|
||||
.method("POST",
|
||||
new FormBody.Builder().add("", "testContent").build())
|
||||
.build()
|
||||
|
||||
when:
|
||||
client.newCall(request).execute()
|
||||
client.post(requestUrl.toString(), "testContent").aggregate().join()
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
|
|
|
@ -6,11 +6,8 @@
|
|||
import static io.opentelemetry.api.trace.SpanKind.SERVER
|
||||
|
||||
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
|
||||
import io.opentelemetry.instrumentation.test.utils.OkHttpUtils
|
||||
import okhttp3.HttpUrl
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import io.opentelemetry.testing.armeria.client.WebClient
|
||||
import io.opentelemetry.testing.armeria.common.AggregatedHttpResponse
|
||||
import org.jboss.arquillian.container.test.api.Deployment
|
||||
import org.jboss.arquillian.container.test.api.RunAsClient
|
||||
import org.jboss.arquillian.spock.ArquillianSputnik
|
||||
|
@ -28,7 +25,7 @@ import test.RestApplication
|
|||
@RunAsClient
|
||||
abstract class ArquillianRestTest extends AgentInstrumentationSpecification {
|
||||
|
||||
static OkHttpClient client = OkHttpUtils.client()
|
||||
static WebClient client = WebClient.of()
|
||||
|
||||
@ArquillianResource
|
||||
static URI url
|
||||
|
@ -49,15 +46,11 @@ abstract class ArquillianRestTest extends AgentInstrumentationSpecification {
|
|||
@Unroll
|
||||
def "test #path"() {
|
||||
when:
|
||||
Request request = new Request.Builder().url(HttpUrl.get(url.resolve(path))).build()
|
||||
Response response = client.newCall(request).execute()
|
||||
AggregatedHttpResponse response = client.get(url.resolve(path).toString()).aggregate().join()
|
||||
|
||||
then:
|
||||
response.withCloseable {
|
||||
assert response.code() == 200
|
||||
assert response.body().string() == "hello"
|
||||
true
|
||||
}
|
||||
response.status().code() == 200
|
||||
response.contentUtf8() == "hello"
|
||||
|
||||
and:
|
||||
assertTraces(1) {
|
||||
|
|
|
@ -8,11 +8,10 @@ import static Resource.Test2
|
|||
import static Resource.Test3
|
||||
|
||||
import io.opentelemetry.instrumentation.test.base.HttpServerTestTrait
|
||||
import okhttp3.FormBody
|
||||
import io.opentelemetry.testing.armeria.common.AggregatedHttpResponse
|
||||
import okhttp3.HttpUrl
|
||||
import okhttp3.Request
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.Response
|
||||
import org.apache.cxf.endpoint.Server
|
||||
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean
|
||||
|
||||
|
@ -54,10 +53,8 @@ class CxfFilterTest extends JaxRsFilterTest implements HttpServerTestTrait<Serve
|
|||
|
||||
@Override
|
||||
def makeRequest(String path) {
|
||||
def url = HttpUrl.get(address.resolve(path)).newBuilder().build()
|
||||
def request = request(url, "POST", new FormBody.Builder().build()).build()
|
||||
Response response = client.newCall(request).execute()
|
||||
AggregatedHttpResponse response = client.post(address.resolve(path).toString(), "").aggregate().join()
|
||||
|
||||
return [response.body().string(), response.code()]
|
||||
return [response.contentUtf8(), response.status().code()]
|
||||
}
|
||||
}
|
|
@ -18,12 +18,6 @@ import io.opentelemetry.instrumentation.test.asserts.TraceAssert
|
|||
import io.opentelemetry.instrumentation.test.base.HttpServerTest
|
||||
import io.opentelemetry.sdk.trace.data.SpanData
|
||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
|
||||
import java.util.concurrent.CompletableFuture
|
||||
import okhttp3.Call
|
||||
import okhttp3.Callback
|
||||
import okhttp3.HttpUrl
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import spock.lang.Unroll
|
||||
import test.JaxRsTestResource
|
||||
|
||||
|
@ -31,17 +25,11 @@ abstract class JaxRsHttpServerTest<S> extends HttpServerTest<S> implements Agent
|
|||
|
||||
def "test super method without @Path"() {
|
||||
given:
|
||||
def url = HttpUrl.get(address.resolve("test-resource-super")).newBuilder()
|
||||
.build()
|
||||
def request = request(url, "GET", null).build()
|
||||
def response = client.newCall(request).execute()
|
||||
def response = client.get(address.resolve("test-resource-super").toString()).aggregate().join()
|
||||
|
||||
expect:
|
||||
response.withCloseable {
|
||||
assert response.code() == SUCCESS.status
|
||||
assert response.body().string() == SUCCESS.body
|
||||
true
|
||||
}
|
||||
response.status().code() == SUCCESS.status
|
||||
response.contentUtf8() == SUCCESS.body
|
||||
|
||||
assertTraces(1) {
|
||||
trace(0, 2) {
|
||||
|
@ -59,17 +47,11 @@ abstract class JaxRsHttpServerTest<S> extends HttpServerTest<S> implements Agent
|
|||
assumeTrue(testInterfaceMethodWithPath())
|
||||
|
||||
given:
|
||||
def url = HttpUrl.get(address.resolve("test-resource-interface/call")).newBuilder()
|
||||
.build()
|
||||
def request = request(url, "GET", null).build()
|
||||
def response = client.newCall(request).execute()
|
||||
def response = client.get(address.resolve("test-resource-interface/call").toString()).aggregate().join()
|
||||
|
||||
expect:
|
||||
response.withCloseable {
|
||||
assert response.code() == SUCCESS.status
|
||||
assert response.body().string() == SUCCESS.body
|
||||
true
|
||||
}
|
||||
response.status().code() == SUCCESS.status
|
||||
response.contentUtf8() == SUCCESS.body
|
||||
|
||||
assertTraces(1) {
|
||||
trace(0, 2) {
|
||||
|
@ -85,17 +67,11 @@ abstract class JaxRsHttpServerTest<S> extends HttpServerTest<S> implements Agent
|
|||
|
||||
def "test sub resource locator"() {
|
||||
given:
|
||||
def url = HttpUrl.get(address.resolve("test-sub-resource-locator/call/sub")).newBuilder()
|
||||
.build()
|
||||
def request = request(url, "GET", null).build()
|
||||
def response = client.newCall(request).execute()
|
||||
def response = client.get(address.resolve("test-sub-resource-locator/call/sub").toString()).aggregate().join()
|
||||
|
||||
expect:
|
||||
response.withCloseable {
|
||||
assert response.code() == SUCCESS.status
|
||||
assert response.body().string() == SUCCESS.body
|
||||
true
|
||||
}
|
||||
response.status().code() == SUCCESS.status
|
||||
response.contentUtf8() == SUCCESS.body
|
||||
|
||||
assertTraces(1) {
|
||||
trace(0, 5) {
|
||||
|
@ -115,13 +91,10 @@ abstract class JaxRsHttpServerTest<S> extends HttpServerTest<S> implements Agent
|
|||
@Unroll
|
||||
def "should handle #desc AsyncResponse"() {
|
||||
given:
|
||||
def url = HttpUrl.get(address.resolve("async")).newBuilder()
|
||||
.addQueryParameter("action", action)
|
||||
.build()
|
||||
def request = request(url, "GET", null).build()
|
||||
def url = address.resolve("async?action=${action}").toString()
|
||||
|
||||
when: "async call is started"
|
||||
def futureResponse = asyncCall(request)
|
||||
def futureResponse = client.get(url).aggregate()
|
||||
|
||||
then: "there are no traces yet"
|
||||
assertTraces(0) {
|
||||
|
@ -132,8 +105,8 @@ abstract class JaxRsHttpServerTest<S> extends HttpServerTest<S> implements Agent
|
|||
def response = futureResponse.join()
|
||||
|
||||
then:
|
||||
assert response.code() == statusCode
|
||||
assert bodyPredicate(response.body().string())
|
||||
response.status().code() == statusCode
|
||||
bodyPredicate(response.contentUtf8())
|
||||
|
||||
def spanCount = 2
|
||||
def hasSendError = asyncCancelHasSendError() && action == "cancel"
|
||||
|
@ -160,15 +133,11 @@ abstract class JaxRsHttpServerTest<S> extends HttpServerTest<S> implements Agent
|
|||
@Unroll
|
||||
def "should handle #desc CompletionStage (JAX-RS 2.1+ only)"() {
|
||||
assumeTrue(shouldTestCompletableStageAsync())
|
||||
|
||||
given:
|
||||
def url = HttpUrl.get(address.resolve("async-completion-stage")).newBuilder()
|
||||
.addQueryParameter("action", action)
|
||||
.build()
|
||||
def request = request(url, "GET", null).build()
|
||||
def url = address.resolve("async-completion-stage?action=${action}").toString()
|
||||
|
||||
when: "async call is started"
|
||||
def futureResponse = asyncCall(request)
|
||||
def futureResponse = client.get(url).aggregate()
|
||||
|
||||
then: "there are no traces yet"
|
||||
assertTraces(0) {
|
||||
|
@ -179,8 +148,8 @@ abstract class JaxRsHttpServerTest<S> extends HttpServerTest<S> implements Agent
|
|||
def response = futureResponse.join()
|
||||
|
||||
then:
|
||||
assert response.code() == statusCode
|
||||
assert bodyPredicate(response.body().string())
|
||||
response.status().code() == statusCode
|
||||
bodyPredicate(response.contentUtf8())
|
||||
|
||||
assertTraces(1) {
|
||||
trace(0, 2) {
|
||||
|
@ -245,9 +214,9 @@ abstract class JaxRsHttpServerTest<S> extends HttpServerTest<S> implements Agent
|
|||
|
||||
void asyncServerSpan(TraceAssert trace,
|
||||
int index,
|
||||
HttpUrl url,
|
||||
String url,
|
||||
int statusCode) {
|
||||
def rawUrl = url.url()
|
||||
def rawUrl = URI.create(url).toURL()
|
||||
serverSpan(trace, index, null, null, "GET",
|
||||
rawUrl.path,
|
||||
rawUrl.toURI(),
|
||||
|
@ -328,22 +297,4 @@ abstract class JaxRsHttpServerTest<S> extends HttpServerTest<S> implements Agent
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private CompletableFuture<Response> asyncCall(Request request) {
|
||||
def future = new CompletableFuture()
|
||||
|
||||
client.newCall(request).enqueue(new Callback() {
|
||||
@Override
|
||||
void onFailure(Call call, IOException e) {
|
||||
future.completeExceptionally(e)
|
||||
}
|
||||
|
||||
@Override
|
||||
void onResponse(Call call, Response response) throws IOException {
|
||||
future.complete(response)
|
||||
}
|
||||
})
|
||||
|
||||
return future
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,11 +11,13 @@ import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
|
|||
import io.opentelemetry.instrumentation.test.asserts.TraceAssert
|
||||
import io.opentelemetry.instrumentation.test.base.HttpServerTestTrait
|
||||
import io.opentelemetry.sdk.trace.data.SpanData
|
||||
import okhttp3.FormBody
|
||||
import okhttp3.HttpUrl
|
||||
import okhttp3.Request
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.Response
|
||||
import io.opentelemetry.testing.armeria.common.AggregatedHttpRequest
|
||||
import io.opentelemetry.testing.armeria.common.AggregatedHttpResponse
|
||||
import io.opentelemetry.testing.armeria.common.HttpData
|
||||
import io.opentelemetry.testing.armeria.common.HttpMethod
|
||||
import io.opentelemetry.testing.armeria.common.MediaType
|
||||
import io.opentelemetry.testing.armeria.common.QueryParams
|
||||
import io.opentelemetry.testing.armeria.common.RequestHeaders
|
||||
import org.eclipse.jetty.annotations.AnnotationConfiguration
|
||||
import org.eclipse.jetty.server.Server
|
||||
import org.eclipse.jetty.util.resource.Resource
|
||||
|
@ -72,13 +74,11 @@ abstract class BaseJsfTest extends AgentInstrumentationSpecification implements
|
|||
@Unroll
|
||||
def "test #path"() {
|
||||
setup:
|
||||
def url = HttpUrl.get(address.resolve("hello.jsf")).newBuilder().build()
|
||||
def request = request(url, "GET", null).build()
|
||||
Response response = client.newCall(request).execute()
|
||||
AggregatedHttpResponse response = client.get(address.resolve("hello.jsf").toString()).aggregate().join()
|
||||
|
||||
expect:
|
||||
response.code() == 200
|
||||
response.body().string().trim() == "Hello"
|
||||
response.status().code() == 200
|
||||
response.contentUtf8().trim() == "Hello"
|
||||
|
||||
and:
|
||||
assertTraces(1) {
|
||||
|
@ -94,13 +94,11 @@ abstract class BaseJsfTest extends AgentInstrumentationSpecification implements
|
|||
def "test greeting"() {
|
||||
// we need to display the page first before posting data to it
|
||||
setup:
|
||||
def url = HttpUrl.get(address.resolve("greeting.jsf")).newBuilder().build()
|
||||
def request = request(url, "GET", null).build()
|
||||
Response response = client.newCall(request).execute()
|
||||
def doc = Jsoup.parse(response.body().string())
|
||||
AggregatedHttpResponse response = client.get(address.resolve("greeting.jsf").toString()).aggregate().join()
|
||||
def doc = Jsoup.parse(response.contentUtf8())
|
||||
|
||||
expect:
|
||||
response.code() == 200
|
||||
response.status().code() == 200
|
||||
doc.selectFirst("title").text() == "Hello, World!"
|
||||
|
||||
and:
|
||||
|
@ -122,10 +120,8 @@ abstract class BaseJsfTest extends AgentInstrumentationSpecification implements
|
|||
jsessionid != null
|
||||
|
||||
when:
|
||||
// use the session created for first request
|
||||
def url2 = HttpUrl.get(address.resolve("greeting.jsf;jsessionid=" + jsessionid)).newBuilder().build()
|
||||
// set up form parameter for post
|
||||
RequestBody formBody = new FormBody.Builder()
|
||||
QueryParams formBody = QueryParams.builder()
|
||||
.add("app-form", "app-form")
|
||||
// value used for name is returned in app-form:output-message element
|
||||
.add("app-form:name", "test")
|
||||
|
@ -133,13 +129,18 @@ abstract class BaseJsfTest extends AgentInstrumentationSpecification implements
|
|||
.add("app-form_SUBMIT", "1") // MyFaces
|
||||
.add("javax.faces.ViewState", viewState)
|
||||
.build()
|
||||
def request2 = this.request(url2, "POST", formBody).build()
|
||||
Response response2 = client.newCall(request2).execute()
|
||||
def responseContent = response2.body().string()
|
||||
// use the session created for first request
|
||||
def request2 = AggregatedHttpRequest.of(
|
||||
RequestHeaders.builder(HttpMethod.POST, address.resolve("greeting.jsf;jsessionid=" + jsessionid).toString())
|
||||
.contentType(MediaType.FORM_DATA)
|
||||
.build(),
|
||||
HttpData.ofUtf8(formBody.toQueryString()))
|
||||
AggregatedHttpResponse response2 = client.execute(request2).aggregate().join()
|
||||
def responseContent = response2.contentUtf8()
|
||||
def doc2 = Jsoup.parse(responseContent)
|
||||
|
||||
then:
|
||||
response2.code() == 200
|
||||
response2.status().code() == 200
|
||||
doc2.getElementById("app-form:output-message").text() == "Hello test"
|
||||
|
||||
and:
|
||||
|
@ -154,13 +155,11 @@ abstract class BaseJsfTest extends AgentInstrumentationSpecification implements
|
|||
def "test exception"() {
|
||||
// we need to display the page first before posting data to it
|
||||
setup:
|
||||
def url = HttpUrl.get(address.resolve("greeting.jsf")).newBuilder().build()
|
||||
def request = request(url, "GET", null).build()
|
||||
Response response = client.newCall(request).execute()
|
||||
def doc = Jsoup.parse(response.body().string())
|
||||
AggregatedHttpResponse response = client.get(address.resolve("greeting.jsf").toString()).aggregate().join()
|
||||
def doc = Jsoup.parse(response.contentUtf8())
|
||||
|
||||
expect:
|
||||
response.code() == 200
|
||||
response.status().code() == 200
|
||||
doc.selectFirst("title").text() == "Hello, World!"
|
||||
|
||||
and:
|
||||
|
@ -182,10 +181,8 @@ abstract class BaseJsfTest extends AgentInstrumentationSpecification implements
|
|||
jsessionid != null
|
||||
|
||||
when:
|
||||
// use the session created for first request
|
||||
def url2 = HttpUrl.get(address.resolve("greeting.jsf;jsessionid=" + jsessionid)).newBuilder().build()
|
||||
// set up form parameter for post
|
||||
RequestBody formBody = new FormBody.Builder()
|
||||
QueryParams formBody = QueryParams.builder()
|
||||
.add("app-form", "app-form")
|
||||
// setting name parameter to "exception" triggers throwing exception in GreetingForm
|
||||
.add("app-form:name", "exception")
|
||||
|
@ -193,11 +190,16 @@ abstract class BaseJsfTest extends AgentInstrumentationSpecification implements
|
|||
.add("app-form_SUBMIT", "1") // MyFaces
|
||||
.add("javax.faces.ViewState", viewState)
|
||||
.build()
|
||||
def request2 = this.request(url2, "POST", formBody).build()
|
||||
Response response2 = client.newCall(request2).execute()
|
||||
// use the session created for first request
|
||||
def request2 = AggregatedHttpRequest.of(
|
||||
RequestHeaders.builder(HttpMethod.POST, address.resolve("greeting.jsf;jsessionid=" + jsessionid).toString())
|
||||
.contentType(MediaType.FORM_DATA)
|
||||
.build(),
|
||||
HttpData.ofUtf8(formBody.toQueryString()))
|
||||
AggregatedHttpResponse response2 = client.execute(request2).aggregate().join()
|
||||
|
||||
then:
|
||||
response2.code() == 500
|
||||
response2.status().code() == 500
|
||||
|
||||
and:
|
||||
assertTraces(1) {
|
||||
|
@ -208,14 +210,6 @@ abstract class BaseJsfTest extends AgentInstrumentationSpecification implements
|
|||
}
|
||||
}
|
||||
|
||||
Request.Builder request(HttpUrl url, String method, RequestBody body) {
|
||||
return new Request.Builder()
|
||||
.url(url)
|
||||
.method(method, body)
|
||||
.header("User-Agent", TEST_USER_AGENT)
|
||||
.header("X-Forwarded-For", TEST_CLIENT_IP)
|
||||
}
|
||||
|
||||
void handlerSpan(TraceAssert trace, int index, Object parent, String spanName, Exception expectedException = null) {
|
||||
trace.span(index) {
|
||||
name spanName
|
||||
|
|
|
@ -74,8 +74,10 @@ class Netty38ServerTest extends HttpServerTest<ServerBootstrap> implements Agent
|
|||
response.setContent(responseContent)
|
||||
break
|
||||
case INDEXED_CHILD:
|
||||
responseContent = ChannelBuffers.EMPTY_BUFFER
|
||||
endpoint.collectSpanAttributes { new QueryStringDecoder(uri).getParameters().get(it).find() }
|
||||
response = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.valueOf(endpoint.status))
|
||||
response.setContent(responseContent)
|
||||
break
|
||||
case QUERY_PARAM:
|
||||
responseContent = ChannelBuffers.copiedBuffer(uri.query, CharsetUtil.UTF_8)
|
||||
|
@ -83,7 +85,9 @@ class Netty38ServerTest extends HttpServerTest<ServerBootstrap> implements Agent
|
|||
response.setContent(responseContent)
|
||||
break
|
||||
case REDIRECT:
|
||||
responseContent = ChannelBuffers.EMPTY_BUFFER
|
||||
response = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.valueOf(endpoint.status))
|
||||
response.setContent(responseContent)
|
||||
response.headers().set(LOCATION, endpoint.body)
|
||||
break
|
||||
case EXCEPTION:
|
||||
|
|
|
@ -72,15 +72,17 @@ class Netty40ServerTest extends HttpServerTest<EventLoopGroup> implements AgentT
|
|||
response = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.valueOf(endpoint.status), content)
|
||||
break
|
||||
case INDEXED_CHILD:
|
||||
content = Unpooled.EMPTY_BUFFER
|
||||
endpoint.collectSpanAttributes { new QueryStringDecoder(uri).parameters().get(it).find() }
|
||||
response = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.valueOf(endpoint.status))
|
||||
response = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.valueOf(endpoint.status), content)
|
||||
break
|
||||
case QUERY_PARAM:
|
||||
content = Unpooled.copiedBuffer(uri.query, CharsetUtil.UTF_8)
|
||||
response = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.valueOf(endpoint.status), content)
|
||||
break
|
||||
case REDIRECT:
|
||||
response = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.valueOf(endpoint.status))
|
||||
content = Unpooled.EMPTY_BUFFER
|
||||
response = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.valueOf(endpoint.status), content)
|
||||
response.headers().set(HttpHeaders.Names.LOCATION, endpoint.body)
|
||||
break
|
||||
case EXCEPTION:
|
||||
|
|
|
@ -71,15 +71,17 @@ class Netty41ServerTest extends HttpServerTest<EventLoopGroup> implements AgentT
|
|||
response = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.valueOf(endpoint.status), content)
|
||||
break
|
||||
case INDEXED_CHILD:
|
||||
content = Unpooled.EMPTY_BUFFER
|
||||
endpoint.collectSpanAttributes { new QueryStringDecoder(uri).parameters().get(it).find() }
|
||||
response = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.valueOf(endpoint.status))
|
||||
response = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.valueOf(endpoint.status), content)
|
||||
break
|
||||
case QUERY_PARAM:
|
||||
content = Unpooled.copiedBuffer(uri.query, CharsetUtil.UTF_8)
|
||||
response = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.valueOf(endpoint.status), content)
|
||||
break
|
||||
case REDIRECT:
|
||||
response = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.valueOf(endpoint.status))
|
||||
content = Unpooled.EMPTY_BUFFER
|
||||
response = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.valueOf(endpoint.status), content)
|
||||
response.headers().set(HttpHeaderNames.LOCATION, endpoint.body)
|
||||
break
|
||||
case EXCEPTION:
|
||||
|
|
|
@ -7,66 +7,65 @@ import static io.opentelemetry.api.trace.SpanKind.INTERNAL
|
|||
import static io.opentelemetry.api.trace.SpanKind.SERVER
|
||||
|
||||
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
|
||||
import io.opentelemetry.instrumentation.test.utils.OkHttpUtils
|
||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
|
||||
import okhttp3.HttpUrl
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import io.opentelemetry.testing.armeria.client.WebClient
|
||||
import ratpack.path.PathBinding
|
||||
import ratpack.server.RatpackServer
|
||||
import spock.lang.Shared
|
||||
|
||||
class RatpackOtherTest extends AgentInstrumentationSpecification {
|
||||
|
||||
OkHttpClient client = OkHttpUtils.client()
|
||||
|
||||
def "test bindings for #path"() {
|
||||
setup:
|
||||
def app = RatpackServer.start {
|
||||
it.handlers {
|
||||
it.prefix("a") {
|
||||
it.all {context ->
|
||||
context.render(context.get(PathBinding).description)
|
||||
}
|
||||
@Shared
|
||||
RatpackServer app = RatpackServer.start {
|
||||
it.handlers {
|
||||
it.prefix("a") {
|
||||
it.all {context ->
|
||||
context.render(context.get(PathBinding).description)
|
||||
}
|
||||
it.prefix("b/::\\d+") {
|
||||
it.all {context ->
|
||||
context.render(context.get(PathBinding).description)
|
||||
}
|
||||
}
|
||||
it.prefix("b/::\\d+") {
|
||||
it.all {context ->
|
||||
context.render(context.get(PathBinding).description)
|
||||
}
|
||||
it.prefix("c/:val?") {
|
||||
it.all {context ->
|
||||
context.render(context.get(PathBinding).description)
|
||||
}
|
||||
}
|
||||
it.prefix("c/:val?") {
|
||||
it.all {context ->
|
||||
context.render(context.get(PathBinding).description)
|
||||
}
|
||||
it.prefix("d/:val") {
|
||||
it.all {context ->
|
||||
context.render(context.get(PathBinding).description)
|
||||
}
|
||||
}
|
||||
it.prefix("d/:val") {
|
||||
it.all {context ->
|
||||
context.render(context.get(PathBinding).description)
|
||||
}
|
||||
it.prefix("e/:val?:\\d+") {
|
||||
it.all {context ->
|
||||
context.render(context.get(PathBinding).description)
|
||||
}
|
||||
}
|
||||
it.prefix("e/:val?:\\d+") {
|
||||
it.all {context ->
|
||||
context.render(context.get(PathBinding).description)
|
||||
}
|
||||
it.prefix("f/:val:\\d+") {
|
||||
it.all {context ->
|
||||
context.render(context.get(PathBinding).description)
|
||||
}
|
||||
}
|
||||
it.prefix("f/:val:\\d+") {
|
||||
it.all {context ->
|
||||
context.render(context.get(PathBinding).description)
|
||||
}
|
||||
}
|
||||
}
|
||||
def address = "${app.scheme}://${app.bindHost}:${app.bindPort}"
|
||||
def request = new Request.Builder()
|
||||
.url(HttpUrl.get(address).newBuilder().addPathSegments(path).build())
|
||||
.get()
|
||||
.build()
|
||||
}
|
||||
|
||||
// Force HTTP/1 with h1c to prevent tracing of upgrade request.
|
||||
@Shared
|
||||
WebClient client = WebClient.of("h1c://localhost:${app.bindPort}")
|
||||
|
||||
def cleanupSpec() {
|
||||
app.stop()
|
||||
}
|
||||
|
||||
def "test bindings for #path"() {
|
||||
when:
|
||||
def resp = client.newCall(request).execute()
|
||||
def resp = client.get(path).aggregate().join()
|
||||
|
||||
then:
|
||||
resp.code() == 200
|
||||
resp.body.string() == route
|
||||
resp.status().code() == 200
|
||||
resp.contentUtf8() == route
|
||||
|
||||
assertTraces(1) {
|
||||
trace(0, 2) {
|
||||
|
@ -77,7 +76,7 @@ class RatpackOtherTest extends AgentInstrumentationSpecification {
|
|||
attributes {
|
||||
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key}" Long
|
||||
"${SemanticAttributes.HTTP_URL.key}" "${address}/${path}"
|
||||
"${SemanticAttributes.HTTP_URL.key}" "http://localhost:${app.bindPort}/${path}"
|
||||
"${SemanticAttributes.HTTP_METHOD.key}" "GET"
|
||||
"${SemanticAttributes.HTTP_STATUS_CODE.key}" 200
|
||||
"${SemanticAttributes.HTTP_FLAVOR.key}" "1.1"
|
||||
|
@ -95,9 +94,6 @@ class RatpackOtherTest extends AgentInstrumentationSpecification {
|
|||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
app.stop()
|
||||
|
||||
where:
|
||||
path | route
|
||||
"a" | "a"
|
||||
|
|
|
@ -8,6 +8,7 @@ import static io.opentelemetry.api.trace.StatusCode.ERROR
|
|||
import io.opentelemetry.api.trace.SpanKind
|
||||
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
|
||||
import io.opentelemetry.instrumentation.test.base.HttpServerTestTrait
|
||||
import io.opentelemetry.testing.armeria.common.AggregatedHttpResponse
|
||||
import javax.servlet.Servlet
|
||||
import javax.servlet.ServletException
|
||||
import javax.servlet.http.HttpServlet
|
||||
|
@ -16,7 +17,6 @@ import javax.servlet.http.HttpServletResponse
|
|||
import okhttp3.HttpUrl
|
||||
import okhttp3.Request
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.Response
|
||||
import spock.lang.Unroll
|
||||
|
||||
abstract class AbstractServlet3MappingTest<SERVER, CONTEXT> extends AgentInstrumentationSpecification implements HttpServerTestTrait<SERVER> {
|
||||
|
@ -44,12 +44,10 @@ abstract class AbstractServlet3MappingTest<SERVER, CONTEXT> extends AgentInstrum
|
|||
@Unroll
|
||||
def "test path #path"() {
|
||||
setup:
|
||||
def url = HttpUrl.get(address.resolve(path)).newBuilder().build()
|
||||
def request = request(url, "GET", null).build()
|
||||
Response response = client.newCall(request).execute()
|
||||
AggregatedHttpResponse response = client.get(address.resolve(path).toString()).aggregate().join()
|
||||
|
||||
expect:
|
||||
response.code() == success ? 200 : 404
|
||||
response.status().code() == success ? 200 : 404
|
||||
|
||||
and:
|
||||
def spanCount = success ? 1 : 2
|
||||
|
|
|
@ -14,9 +14,8 @@ import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEn
|
|||
import io.opentelemetry.instrumentation.test.AgentTestTrait
|
||||
import io.opentelemetry.instrumentation.test.asserts.TraceAssert
|
||||
import io.opentelemetry.instrumentation.test.base.HttpServerTest
|
||||
import io.opentelemetry.testing.armeria.common.AggregatedHttpRequest
|
||||
import javax.servlet.Servlet
|
||||
import okhttp3.Request
|
||||
import okhttp3.RequestBody
|
||||
|
||||
abstract class AbstractServlet3Test<SERVER, CONTEXT> extends HttpServerTest<SERVER> implements AgentTestTrait {
|
||||
@Override
|
||||
|
@ -49,9 +48,9 @@ abstract class AbstractServlet3Test<SERVER, CONTEXT> extends HttpServerTest<SERV
|
|||
protected ServerEndpoint lastRequest
|
||||
|
||||
@Override
|
||||
Request.Builder request(ServerEndpoint uri, String method, RequestBody body) {
|
||||
AggregatedHttpRequest request(ServerEndpoint uri, String method) {
|
||||
lastRequest = uri
|
||||
super.request(uri, method, body)
|
||||
super.request(uri, method)
|
||||
}
|
||||
|
||||
boolean errorEndpointUsesSendError() {
|
||||
|
|
|
@ -13,6 +13,7 @@ import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEn
|
|||
import static org.junit.Assume.assumeTrue
|
||||
|
||||
import io.opentelemetry.instrumentation.test.asserts.TraceAssert
|
||||
import io.opentelemetry.testing.armeria.common.AggregatedHttpResponse
|
||||
import java.nio.file.Files
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.TimeoutException
|
||||
|
@ -117,17 +118,17 @@ abstract class TomcatServlet3Test extends AbstractServlet3Test<Tomcat, Context>
|
|||
|
||||
def "access log has ids for #count requests"() {
|
||||
given:
|
||||
def request = request(SUCCESS, method, body).build()
|
||||
def request = request(SUCCESS, method)
|
||||
|
||||
when:
|
||||
List<okhttp3.Response> responses = (1..count).collect {
|
||||
return client.newCall(request).execute()
|
||||
List<AggregatedHttpResponse> responses = (1..count).collect {
|
||||
return client.execute(request).aggregate().join()
|
||||
}
|
||||
|
||||
then:
|
||||
responses.each { response ->
|
||||
assert response.code() == SUCCESS.status
|
||||
assert response.body().string() == SUCCESS.body
|
||||
assert response.status().code() == SUCCESS.status
|
||||
assert response.contentUtf8() == SUCCESS.body
|
||||
}
|
||||
|
||||
and:
|
||||
|
@ -150,19 +151,18 @@ abstract class TomcatServlet3Test extends AbstractServlet3Test<Tomcat, Context>
|
|||
|
||||
where:
|
||||
method = "GET"
|
||||
body = null
|
||||
count << [1, 4] // make multiple requests.
|
||||
}
|
||||
|
||||
def "access log has ids for error request"() {
|
||||
setup:
|
||||
assumeTrue(testError())
|
||||
def request = request(ERROR, method, body).build()
|
||||
def response = client.newCall(request).execute()
|
||||
def request = request(ERROR, method)
|
||||
def response = client.execute(request).aggregate().join()
|
||||
|
||||
expect:
|
||||
response.code() == ERROR.status
|
||||
response.body().string() == ERROR.body
|
||||
response.status().code() == ERROR.status
|
||||
response.contentUtf8() == ERROR.body
|
||||
|
||||
and:
|
||||
def spanCount = 2
|
||||
|
@ -171,7 +171,7 @@ abstract class TomcatServlet3Test extends AbstractServlet3Test<Tomcat, Context>
|
|||
}
|
||||
assertTraces(1) {
|
||||
trace(0, spanCount) {
|
||||
serverSpan(it, 0, null, null, method, response.body().contentLength(), ERROR)
|
||||
serverSpan(it, 0, null, null, method, response.content().length(), ERROR)
|
||||
def spanIndex = 1
|
||||
controllerSpan(it, spanIndex, span(spanIndex - 1))
|
||||
spanIndex++
|
||||
|
@ -189,7 +189,6 @@ abstract class TomcatServlet3Test extends AbstractServlet3Test<Tomcat, Context>
|
|||
|
||||
where:
|
||||
method = "GET"
|
||||
body = null
|
||||
}
|
||||
|
||||
// FIXME: Add authentication tests back in...
|
||||
|
|
|
@ -8,6 +8,7 @@ import static io.opentelemetry.api.trace.StatusCode.ERROR
|
|||
import io.opentelemetry.api.trace.SpanKind
|
||||
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
|
||||
import io.opentelemetry.instrumentation.test.base.HttpServerTestTrait
|
||||
import io.opentelemetry.testing.armeria.common.AggregatedHttpResponse
|
||||
import jakarta.servlet.Servlet
|
||||
import jakarta.servlet.ServletException
|
||||
import jakarta.servlet.http.HttpServlet
|
||||
|
@ -16,7 +17,6 @@ import jakarta.servlet.http.HttpServletResponse
|
|||
import okhttp3.HttpUrl
|
||||
import okhttp3.Request
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.Response
|
||||
import spock.lang.Unroll
|
||||
|
||||
abstract class AbstractServlet5MappingTest<SERVER, CONTEXT> extends AgentInstrumentationSpecification implements HttpServerTestTrait<SERVER> {
|
||||
|
@ -44,12 +44,10 @@ abstract class AbstractServlet5MappingTest<SERVER, CONTEXT> extends AgentInstrum
|
|||
@Unroll
|
||||
def "test path #path"() {
|
||||
setup:
|
||||
def url = HttpUrl.get(address.resolve(path)).newBuilder().build()
|
||||
def request = request(url, "GET", null).build()
|
||||
Response response = client.newCall(request).execute()
|
||||
AggregatedHttpResponse response = client.get(address.resolve(path).toString()).aggregate().join()
|
||||
|
||||
expect:
|
||||
response.code() == success ? 200 : 404
|
||||
response.status().code() == (success ? 200 : 404)
|
||||
|
||||
and:
|
||||
def spanCount = success ? 1 : 2
|
||||
|
|
|
@ -14,9 +14,8 @@ import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEn
|
|||
import io.opentelemetry.instrumentation.test.AgentTestTrait
|
||||
import io.opentelemetry.instrumentation.test.asserts.TraceAssert
|
||||
import io.opentelemetry.instrumentation.test.base.HttpServerTest
|
||||
import io.opentelemetry.testing.armeria.common.AggregatedHttpRequest
|
||||
import jakarta.servlet.Servlet
|
||||
import okhttp3.Request
|
||||
import okhttp3.RequestBody
|
||||
|
||||
abstract class AbstractServlet5Test<SERVER, CONTEXT> extends HttpServerTest<SERVER> implements AgentTestTrait {
|
||||
@Override
|
||||
|
@ -49,9 +48,9 @@ abstract class AbstractServlet5Test<SERVER, CONTEXT> extends HttpServerTest<SERV
|
|||
protected ServerEndpoint lastRequest
|
||||
|
||||
@Override
|
||||
Request.Builder request(ServerEndpoint uri, String method, RequestBody body) {
|
||||
AggregatedHttpRequest request(ServerEndpoint uri, String method) {
|
||||
lastRequest = uri
|
||||
super.request(uri, method, body)
|
||||
super.request(uri, method)
|
||||
}
|
||||
|
||||
boolean errorEndpointUsesSendError() {
|
||||
|
|
|
@ -13,6 +13,7 @@ import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEn
|
|||
import static org.junit.Assume.assumeTrue
|
||||
|
||||
import io.opentelemetry.instrumentation.test.asserts.TraceAssert
|
||||
import io.opentelemetry.testing.armeria.common.AggregatedHttpResponse
|
||||
import jakarta.servlet.Servlet
|
||||
import jakarta.servlet.ServletException
|
||||
import java.nio.file.Files
|
||||
|
@ -117,17 +118,17 @@ abstract class TomcatServlet5Test extends AbstractServlet5Test<Tomcat, Context>
|
|||
|
||||
def "access log has ids for #count requests"() {
|
||||
given:
|
||||
def request = request(SUCCESS, method, body).build()
|
||||
def request = request(SUCCESS, method)
|
||||
|
||||
when:
|
||||
List<okhttp3.Response> responses = (1..count).collect {
|
||||
return client.newCall(request).execute()
|
||||
List<AggregatedHttpResponse> responses = (1..count).collect {
|
||||
return client.execute(request).aggregate().join()
|
||||
}
|
||||
|
||||
then:
|
||||
responses.each { response ->
|
||||
assert response.code() == SUCCESS.status
|
||||
assert response.body().string() == SUCCESS.body
|
||||
assert response.status().code() == SUCCESS.status
|
||||
assert response.contentUtf8() == SUCCESS.body
|
||||
}
|
||||
|
||||
and:
|
||||
|
@ -150,19 +151,18 @@ abstract class TomcatServlet5Test extends AbstractServlet5Test<Tomcat, Context>
|
|||
|
||||
where:
|
||||
method = "GET"
|
||||
body = null
|
||||
count << [1, 4] // make multiple requests.
|
||||
}
|
||||
|
||||
def "access log has ids for error request"() {
|
||||
setup:
|
||||
assumeTrue(testError())
|
||||
def request = request(ERROR, method, body).build()
|
||||
def response = client.newCall(request).execute()
|
||||
def request = request(ERROR, method)
|
||||
def response = client.execute(request).aggregate().join()
|
||||
|
||||
expect:
|
||||
response.code() == ERROR.status
|
||||
response.body().string() == ERROR.body
|
||||
response.status().code() == ERROR.status
|
||||
response.contentUtf8() == ERROR.body
|
||||
|
||||
and:
|
||||
def spanCount = 2
|
||||
|
@ -171,7 +171,7 @@ abstract class TomcatServlet5Test extends AbstractServlet5Test<Tomcat, Context>
|
|||
}
|
||||
assertTraces(1) {
|
||||
trace(0, spanCount) {
|
||||
serverSpan(it, 0, null, null, method, response.body().contentLength(), ERROR)
|
||||
serverSpan(it, 0, null, null, method, response.content().length(), ERROR)
|
||||
def spanIndex = 1
|
||||
controllerSpan(it, spanIndex, span(spanIndex - 1))
|
||||
spanIndex++
|
||||
|
@ -189,7 +189,6 @@ abstract class TomcatServlet5Test extends AbstractServlet5Test<Tomcat, Context>
|
|||
|
||||
where:
|
||||
method = "GET"
|
||||
body = null
|
||||
}
|
||||
|
||||
// FIXME: Add authentication tests back in...
|
||||
|
|
|
@ -19,8 +19,10 @@ import io.opentelemetry.instrumentation.test.AgentTestTrait
|
|||
import io.opentelemetry.instrumentation.test.asserts.TraceAssert
|
||||
import io.opentelemetry.instrumentation.test.base.HttpServerTest
|
||||
import io.opentelemetry.sdk.trace.data.SpanData
|
||||
import okhttp3.FormBody
|
||||
import okhttp3.RequestBody
|
||||
import io.opentelemetry.testing.armeria.common.AggregatedHttpRequest
|
||||
import io.opentelemetry.testing.armeria.common.HttpData
|
||||
import io.opentelemetry.testing.armeria.common.MediaType
|
||||
import io.opentelemetry.testing.armeria.common.QueryParams
|
||||
import org.springframework.boot.SpringApplication
|
||||
import org.springframework.context.ConfigurableApplicationContext
|
||||
import org.springframework.web.servlet.view.RedirectView
|
||||
|
@ -91,14 +93,14 @@ class SpringBootBasedTest extends HttpServerTest<ConfigurableApplicationContext>
|
|||
def "test spans with auth error"() {
|
||||
setup:
|
||||
def authProvider = server.getBean(SavingAuthenticationProvider)
|
||||
def request = request(AUTH_ERROR, "GET", null).build()
|
||||
def request = request(AUTH_ERROR, "GET")
|
||||
|
||||
when:
|
||||
authProvider.latestAuthentications.clear()
|
||||
def response = client.newCall(request).execute()
|
||||
def response = client.execute(request).aggregate().join()
|
||||
|
||||
then:
|
||||
response.code() == 401 // not secured
|
||||
response.status().code() == 401 // not secured
|
||||
|
||||
and:
|
||||
assertTraces(1) {
|
||||
|
@ -114,24 +116,23 @@ class SpringBootBasedTest extends HttpServerTest<ConfigurableApplicationContext>
|
|||
setup:
|
||||
def authProvider = server.getBean(SavingAuthenticationProvider)
|
||||
|
||||
RequestBody formBody = new FormBody.Builder()
|
||||
.add("username", "test")
|
||||
.add("password", testPassword).build()
|
||||
|
||||
def request = request(LOGIN, "POST", formBody).build()
|
||||
QueryParams form = QueryParams.of("username", "test", "password", testPassword)
|
||||
def request = AggregatedHttpRequest.of(
|
||||
request(LOGIN, "POST").headers().toBuilder().contentType(MediaType.FORM_DATA).build(),
|
||||
HttpData.ofUtf8(form.toQueryString()))
|
||||
|
||||
when:
|
||||
authProvider.latestAuthentications.clear()
|
||||
def response = client.newCall(request).execute()
|
||||
def response = client.execute(request).aggregate().join()
|
||||
|
||||
then:
|
||||
response.code() == 302 // redirect after success
|
||||
response.status().code() == 302 // redirect after success
|
||||
authProvider.latestAuthentications.get(0).password == testPassword
|
||||
|
||||
and:
|
||||
assertTraces(1) {
|
||||
trace(0, 2) {
|
||||
serverSpan(it, 0, null, null, "POST", response.body()?.contentLength(), LOGIN)
|
||||
serverSpan(it, 0, null, null, "POST", response.contentUtf8().length(), LOGIN)
|
||||
redirectSpan(it, 1, span(0))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ import io.opentelemetry.sdk.trace.data.SpanData
|
|||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
|
||||
import io.opentelemetry.struts.GreetingServlet
|
||||
import javax.servlet.DispatcherType
|
||||
import okhttp3.HttpUrl
|
||||
import org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
|
||||
import org.eclipse.jetty.server.Server
|
||||
import org.eclipse.jetty.servlet.DefaultServlet
|
||||
|
@ -125,14 +124,11 @@ class Struts2ActionSpanTest extends HttpServerTest<Server> implements AgentTestT
|
|||
// does not overwrite server span name given by struts instrumentation.
|
||||
def "test dispatch to servlet"() {
|
||||
setup:
|
||||
def url = HttpUrl.get(address.resolve("dispatch")).newBuilder()
|
||||
.build()
|
||||
def request = request(url, "GET", null).build()
|
||||
def response = client.newCall(request).execute()
|
||||
def response = client.get(address.resolve("dispatch").toString()).aggregate().join()
|
||||
|
||||
expect:
|
||||
response.code() == 200
|
||||
response.body().string() == "greeting"
|
||||
response.status().code() == 200
|
||||
response.contentUtf8() == "greeting"
|
||||
|
||||
and:
|
||||
assertTraces(1) {
|
||||
|
|
|
@ -17,13 +17,11 @@ import io.opentelemetry.api.trace.StatusCode
|
|||
import io.opentelemetry.instrumentation.test.AgentTestTrait
|
||||
import io.opentelemetry.instrumentation.test.base.HttpServerTest
|
||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
|
||||
import io.opentelemetry.testing.armeria.common.AggregatedHttpResponse
|
||||
import io.undertow.Handlers
|
||||
import io.undertow.Undertow
|
||||
import io.undertow.util.Headers
|
||||
import io.undertow.util.StatusCodes
|
||||
import okhttp3.HttpUrl
|
||||
import okhttp3.Response
|
||||
|
||||
//TODO make test which mixes handlers and servlets
|
||||
class UndertowServerTest extends HttpServerTest<Undertow> implements AgentTestTrait {
|
||||
|
||||
|
@ -99,13 +97,11 @@ class UndertowServerTest extends HttpServerTest<Undertow> implements AgentTestTr
|
|||
def "test send response"() {
|
||||
setup:
|
||||
def uri = address.resolve("sendResponse")
|
||||
def url = HttpUrl.get(uri).newBuilder().build()
|
||||
def request = request(url, "GET", null).build()
|
||||
Response response = client.newCall(request).execute()
|
||||
AggregatedHttpResponse response = client.get(uri.toString()).aggregate().join()
|
||||
|
||||
expect:
|
||||
response.code() == 200
|
||||
response.body().string().trim() == "sendResponse"
|
||||
response.status().code() == 200
|
||||
response.contentUtf8().trim() == "sendResponse"
|
||||
|
||||
and:
|
||||
assertTraces(1) {
|
||||
|
@ -141,13 +137,11 @@ class UndertowServerTest extends HttpServerTest<Undertow> implements AgentTestTr
|
|||
def "test send response with exception"() {
|
||||
setup:
|
||||
def uri = address.resolve("sendResponseWithException")
|
||||
def url = HttpUrl.get(uri).newBuilder().build()
|
||||
def request = request(url, "GET", null).build()
|
||||
Response response = client.newCall(request).execute()
|
||||
AggregatedHttpResponse response = client.get(uri.toString()).aggregate().join()
|
||||
|
||||
expect:
|
||||
response.code() == 200
|
||||
response.body().string().trim() == "sendResponseWithException"
|
||||
response.status().code() == 200
|
||||
response.contentUtf8().trim() == "sendResponseWithException"
|
||||
|
||||
and:
|
||||
assertTraces(1) {
|
||||
|
|
|
@ -8,11 +8,8 @@ import static io.opentelemetry.instrumentation.test.utils.TraceUtils.basicServer
|
|||
import hello.HelloApplication
|
||||
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
|
||||
import io.opentelemetry.instrumentation.test.base.HttpServerTestTrait
|
||||
import io.opentelemetry.testing.armeria.common.AggregatedHttpResponse
|
||||
import javax.servlet.DispatcherType
|
||||
import okhttp3.HttpUrl
|
||||
import okhttp3.Request
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.Response
|
||||
import org.apache.wicket.protocol.http.WicketFilter
|
||||
import org.eclipse.jetty.server.Server
|
||||
import org.eclipse.jetty.servlet.DefaultServlet
|
||||
|
@ -55,13 +52,11 @@ class WicketTest extends AgentInstrumentationSpecification implements HttpServer
|
|||
|
||||
def "test hello"() {
|
||||
setup:
|
||||
def url = HttpUrl.get(address.resolve("wicket-test/")).newBuilder().build()
|
||||
def request = request(url, "GET", null).build()
|
||||
Response response = client.newCall(request).execute()
|
||||
def doc = Jsoup.parse(response.body().string())
|
||||
AggregatedHttpResponse response = client.get(address.resolve("wicket-test/").toString()).aggregate().join()
|
||||
def doc = Jsoup.parse(response.contentUtf8())
|
||||
|
||||
expect:
|
||||
response.code() == 200
|
||||
response.status().code() == 200
|
||||
doc.selectFirst("#message").text() == "Hello World!"
|
||||
|
||||
assertTraces(1) {
|
||||
|
@ -73,12 +68,10 @@ class WicketTest extends AgentInstrumentationSpecification implements HttpServer
|
|||
|
||||
def "test exception"() {
|
||||
setup:
|
||||
def url = HttpUrl.get(address.resolve("wicket-test/exception")).newBuilder().build()
|
||||
def request = request(url, "GET", null).build()
|
||||
Response response = client.newCall(request).execute()
|
||||
AggregatedHttpResponse response = client.get(address.resolve("wicket-test/exception").toString()).aggregate().join()
|
||||
|
||||
expect:
|
||||
response.code() == 500
|
||||
response.status().code() == 500
|
||||
|
||||
assertTraces(1) {
|
||||
trace(0, 1) {
|
||||
|
@ -86,12 +79,4 @@ class WicketTest extends AgentInstrumentationSpecification implements HttpServer
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
Request.Builder request(HttpUrl url, String method, RequestBody body) {
|
||||
return new Request.Builder()
|
||||
.url(url)
|
||||
.method(method, body)
|
||||
.header("User-Agent", TEST_USER_AGENT)
|
||||
.header("X-Forwarded-For", TEST_CLIENT_IP)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
package io.opentelemetry.instrumentation.test.base
|
||||
|
||||
|
||||
import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.ERROR
|
||||
import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.EXCEPTION
|
||||
import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.INDEXED_CHILD
|
||||
|
@ -29,13 +28,14 @@ import io.opentelemetry.instrumentation.test.InstrumentationSpecification
|
|||
import io.opentelemetry.instrumentation.test.asserts.TraceAssert
|
||||
import io.opentelemetry.sdk.trace.data.SpanData
|
||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
|
||||
import io.opentelemetry.testing.armeria.common.AggregatedHttpRequest
|
||||
import io.opentelemetry.testing.armeria.common.AggregatedHttpResponse
|
||||
import io.opentelemetry.testing.armeria.common.HttpMethod
|
||||
import io.opentelemetry.testing.armeria.common.HttpRequest
|
||||
import io.opentelemetry.testing.armeria.common.HttpRequestBuilder
|
||||
import java.util.concurrent.Callable
|
||||
import java.util.concurrent.CountDownLatch
|
||||
import java.util.concurrent.Executors
|
||||
import okhttp3.HttpUrl
|
||||
import okhttp3.Request
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.Response
|
||||
import spock.lang.Unroll
|
||||
|
||||
@Unroll
|
||||
|
@ -207,20 +207,14 @@ abstract class HttpServerTest<SERVER> extends InstrumentationSpecification imple
|
|||
}
|
||||
}
|
||||
|
||||
Request.Builder request(ServerEndpoint uri, String method, RequestBody body) {
|
||||
def url = HttpUrl.get(uri.resolvePath(address)).newBuilder()
|
||||
.query(uri.query)
|
||||
.fragment(uri.fragment)
|
||||
.build()
|
||||
return request(url, method, body)
|
||||
}
|
||||
|
||||
Request.Builder request(HttpUrl url, String method, RequestBody body) {
|
||||
return new Request.Builder()
|
||||
.url(url)
|
||||
.method(method, body)
|
||||
.header("User-Agent", TEST_USER_AGENT)
|
||||
.header("X-Forwarded-For", TEST_CLIENT_IP)
|
||||
AggregatedHttpRequest request(ServerEndpoint uri, String method) {
|
||||
def url = uri.resolvePath(address).toString()
|
||||
// Force HTTP/1 via h1c so upgrade requests don't show up as traces
|
||||
url = url.replace("http://", "h1c://")
|
||||
if (uri.query != null) {
|
||||
url += "?${uri.query}"
|
||||
}
|
||||
return AggregatedHttpRequest.of(HttpMethod.valueOf(method), url)
|
||||
}
|
||||
|
||||
static <T> T controller(ServerEndpoint endpoint, Callable<T> closure) {
|
||||
|
@ -233,17 +227,15 @@ abstract class HttpServerTest<SERVER> extends InstrumentationSpecification imple
|
|||
|
||||
def "test success with #count requests"() {
|
||||
setup:
|
||||
def request = request(SUCCESS, method, body).build()
|
||||
List<Response> responses = (1..count).collect {
|
||||
return client.newCall(request).execute()
|
||||
def request = request(SUCCESS, method)
|
||||
List<AggregatedHttpResponse> responses = (1..count).collect {
|
||||
return client.execute(request).aggregate().join()
|
||||
}
|
||||
|
||||
expect:
|
||||
responses.each { response ->
|
||||
response.withCloseable {
|
||||
assert response.code() == SUCCESS.status
|
||||
assert response.body().string() == SUCCESS.body
|
||||
}
|
||||
assert response.status().code() == SUCCESS.status
|
||||
assert response.contentUtf8() == SUCCESS.body
|
||||
}
|
||||
|
||||
and:
|
||||
|
@ -251,7 +243,6 @@ abstract class HttpServerTest<SERVER> extends InstrumentationSpecification imple
|
|||
|
||||
where:
|
||||
method = "GET"
|
||||
body = null
|
||||
count << [1, 4, 50] // make multiple requests.
|
||||
}
|
||||
|
||||
|
@ -259,82 +250,68 @@ abstract class HttpServerTest<SERVER> extends InstrumentationSpecification imple
|
|||
setup:
|
||||
def traceId = "00000000000000000000000000000123"
|
||||
def parentId = "0000000000000456"
|
||||
def request = request(SUCCESS, method, body)
|
||||
.header("traceparent", "00-" + traceId.toString() + "-" + parentId.toString() + "-01")
|
||||
.build()
|
||||
def response = client.newCall(request).execute()
|
||||
def request = AggregatedHttpRequest.of(
|
||||
request(SUCCESS, method).headers().toBuilder()
|
||||
.set("traceparent", "00-" + traceId.toString() + "-" + parentId.toString() + "-01")
|
||||
.build())
|
||||
def response = client.execute(request).aggregate().join()
|
||||
|
||||
expect:
|
||||
response.withCloseable {
|
||||
assert response.code() == SUCCESS.status
|
||||
assert response.body().string() == SUCCESS.body
|
||||
true
|
||||
}
|
||||
response.status().code() == SUCCESS.status
|
||||
response.contentUtf8() == SUCCESS.body
|
||||
|
||||
and:
|
||||
assertTheTraces(1, traceId, parentId, "GET", SUCCESS, null, response)
|
||||
|
||||
where:
|
||||
method = "GET"
|
||||
body = null
|
||||
}
|
||||
|
||||
def "test tag query string for #endpoint"() {
|
||||
setup:
|
||||
def request = request(endpoint, method, body).build()
|
||||
Response response = client.newCall(request).execute()
|
||||
def request = request(endpoint, method)
|
||||
AggregatedHttpResponse response = client.execute(request).aggregate().join()
|
||||
|
||||
expect:
|
||||
response.withCloseable {
|
||||
assert response.code() == endpoint.status
|
||||
assert response.body().string() == endpoint.body
|
||||
true
|
||||
}
|
||||
response.status().code() == endpoint.status
|
||||
response.contentUtf8() == endpoint.body
|
||||
|
||||
and:
|
||||
assertTheTraces(1, null, null, method, endpoint, null, response)
|
||||
|
||||
where:
|
||||
method = "GET"
|
||||
body = null
|
||||
endpoint << [SUCCESS, QUERY_PARAM]
|
||||
}
|
||||
|
||||
def "test redirect"() {
|
||||
setup:
|
||||
assumeTrue(testRedirect())
|
||||
def request = request(REDIRECT, method, body).build()
|
||||
def response = client.newCall(request).execute()
|
||||
def request = request(REDIRECT, method)
|
||||
def response = client.execute(request).aggregate().join()
|
||||
|
||||
expect:
|
||||
response.withCloseable {
|
||||
assert response.code() == REDIRECT.status
|
||||
assert response.header("location") == REDIRECT.body ||
|
||||
new URI(response.header("location")).normalize().toString() == "${address.resolve(REDIRECT.body)}"
|
||||
true
|
||||
}
|
||||
response.status().code() == REDIRECT.status
|
||||
response.headers().get("location") == REDIRECT.body ||
|
||||
new URI(response.headers().get("location")).normalize().toString() == "${address.resolve(REDIRECT.body)}"
|
||||
|
||||
and:
|
||||
assertTheTraces(1, null, null, method, REDIRECT, null, response)
|
||||
|
||||
where:
|
||||
method = "GET"
|
||||
body = null
|
||||
}
|
||||
|
||||
def "test error"() {
|
||||
setup:
|
||||
assumeTrue(testError())
|
||||
def request = request(ERROR, method, body).build()
|
||||
def response = client.newCall(request).execute()
|
||||
def request = request(ERROR, method)
|
||||
def response = client.execute(request).aggregate().join()
|
||||
|
||||
expect:
|
||||
response.withCloseable {
|
||||
assert response.code() == ERROR.status
|
||||
if (testErrorBody()) {
|
||||
assert response.body().string() == ERROR.body
|
||||
}
|
||||
true
|
||||
response.status().code() == ERROR.status
|
||||
if (testErrorBody()) {
|
||||
response.contentUtf8() == ERROR.body
|
||||
}
|
||||
|
||||
and:
|
||||
|
@ -342,68 +319,55 @@ abstract class HttpServerTest<SERVER> extends InstrumentationSpecification imple
|
|||
|
||||
where:
|
||||
method = "GET"
|
||||
body = null
|
||||
}
|
||||
|
||||
def "test exception"() {
|
||||
setup:
|
||||
assumeTrue(testException())
|
||||
def request = request(EXCEPTION, method, body).build()
|
||||
def response = client.newCall(request).execute()
|
||||
def request = request(EXCEPTION, method)
|
||||
def response = client.execute(request).aggregate().join()
|
||||
|
||||
expect:
|
||||
response.withCloseable {
|
||||
assert response.code() == EXCEPTION.status
|
||||
true
|
||||
}
|
||||
response.status().code() == EXCEPTION.status
|
||||
|
||||
and:
|
||||
assertTheTraces(1, null, null, method, EXCEPTION, EXCEPTION.body, response)
|
||||
|
||||
where:
|
||||
method = "GET"
|
||||
body = null
|
||||
}
|
||||
|
||||
def "test notFound"() {
|
||||
setup:
|
||||
assumeTrue(testNotFound())
|
||||
def request = request(NOT_FOUND, method, body).build()
|
||||
def response = client.newCall(request).execute()
|
||||
def request = request(NOT_FOUND, method)
|
||||
def response = client.execute(request).aggregate().join()
|
||||
|
||||
expect:
|
||||
response.withCloseable {
|
||||
assert response.code() == NOT_FOUND.status
|
||||
true
|
||||
}
|
||||
response.status().code() == NOT_FOUND.status
|
||||
|
||||
and:
|
||||
assertTheTraces(1, null, null, method, NOT_FOUND, null, response)
|
||||
|
||||
where:
|
||||
method = "GET"
|
||||
body = null
|
||||
}
|
||||
|
||||
def "test path param"() {
|
||||
setup:
|
||||
assumeTrue(testPathParam())
|
||||
def request = request(PATH_PARAM, method, body).build()
|
||||
def response = client.newCall(request).execute()
|
||||
def request = request(PATH_PARAM, method)
|
||||
def response = client.execute(request).aggregate().join()
|
||||
|
||||
expect:
|
||||
response.withCloseable {
|
||||
assert response.code() == PATH_PARAM.status
|
||||
assert response.body().string() == PATH_PARAM.body
|
||||
true
|
||||
}
|
||||
response.status().code() == PATH_PARAM.status
|
||||
response.contentUtf8() == PATH_PARAM.body
|
||||
|
||||
and:
|
||||
assertTheTraces(1, null, null, method, PATH_PARAM, null, response)
|
||||
|
||||
where:
|
||||
method = "GET"
|
||||
body = null
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -430,7 +394,7 @@ abstract class HttpServerTest<SERVER> extends InstrumentationSpecification imple
|
|||
|
||||
def pool = Executors.newFixedThreadPool(4)
|
||||
def propagator = GlobalOpenTelemetry.getPropagators().getTextMapPropagator()
|
||||
def setter = { Request.Builder carrier, String name, String value ->
|
||||
def setter = { HttpRequestBuilder carrier, String name, String value ->
|
||||
carrier.header(name, value)
|
||||
}
|
||||
|
||||
|
@ -438,14 +402,14 @@ abstract class HttpServerTest<SERVER> extends InstrumentationSpecification imple
|
|||
count.times { index ->
|
||||
def job = {
|
||||
latch.await()
|
||||
def url = HttpUrl.get(endpoint.resolvePath(address)).newBuilder()
|
||||
.query("${ServerEndpoint.ID_PARAMETER_NAME}=$index")
|
||||
.build()
|
||||
Request.Builder builder = request(url, "GET", null)
|
||||
HttpRequestBuilder request = HttpRequest.builder()
|
||||
// Force HTTP/1 via h1c so upgrade requests don't show up as traces
|
||||
.get(endpoint.resolvePath(address).toString().replace("http://", "h1c://"))
|
||||
.queryParam(ServerEndpoint.ID_PARAMETER_NAME, "$index")
|
||||
runUnderTrace("client " + index) {
|
||||
Span.current().setAttribute(ServerEndpoint.ID_ATTRIBUTE_NAME, index)
|
||||
propagator.inject(Context.current(), builder, setter)
|
||||
client.newCall(builder.build()).execute()
|
||||
propagator.inject(Context.current(), request, setter)
|
||||
client.execute(request.build()).aggregate().join()
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -485,7 +449,7 @@ abstract class HttpServerTest<SERVER> extends InstrumentationSpecification imple
|
|||
|
||||
//FIXME: add tests for POST with large/chunked data
|
||||
|
||||
void assertTheTraces(int size, String traceID = null, String parentID = null, String method = "GET", ServerEndpoint endpoint = SUCCESS, String errorMessage = null, Response response = null) {
|
||||
void assertTheTraces(int size, String traceID = null, String parentID = null, String method = "GET", ServerEndpoint endpoint = SUCCESS, String errorMessage = null, AggregatedHttpResponse response = null) {
|
||||
def spanCount = 1 // server span
|
||||
if (hasResponseSpan(endpoint)) {
|
||||
spanCount++
|
||||
|
@ -506,7 +470,7 @@ abstract class HttpServerTest<SERVER> extends InstrumentationSpecification imple
|
|||
(0..size - 1).each {
|
||||
trace(it, spanCount) {
|
||||
def spanIndex = 0
|
||||
serverSpan(it, spanIndex++, traceID, parentID, method, response?.body()?.contentLength(), endpoint)
|
||||
serverSpan(it, spanIndex++, traceID, parentID, method, response?.content()?.length(), endpoint)
|
||||
if (hasHandlerSpan(endpoint)) {
|
||||
handlerSpan(it, spanIndex++, span(0), method, endpoint)
|
||||
}
|
||||
|
@ -611,7 +575,7 @@ abstract class HttpServerTest<SERVER> extends InstrumentationSpecification imple
|
|||
"${SemanticAttributes.HTTP_URL.key}" { it == "${endpoint.resolve(address)}" || it == "${endpoint.resolveWithoutFragment(address)}" }
|
||||
"${SemanticAttributes.HTTP_METHOD.key}" method
|
||||
"${SemanticAttributes.HTTP_STATUS_CODE.key}" endpoint.status
|
||||
"${SemanticAttributes.HTTP_FLAVOR.key}" "1.1"
|
||||
"${SemanticAttributes.HTTP_FLAVOR.key}" { it == "1.1" || it == "2.0" }
|
||||
"${SemanticAttributes.HTTP_USER_AGENT.key}" TEST_USER_AGENT
|
||||
|
||||
if (extraAttributes.contains(SemanticAttributes.HTTP_HOST)) {
|
||||
|
@ -675,6 +639,4 @@ abstract class HttpServerTest<SERVER> extends InstrumentationSpecification imple
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -8,14 +8,16 @@ package io.opentelemetry.instrumentation.test.base
|
|||
import ch.qos.logback.classic.Level
|
||||
import io.opentelemetry.instrumentation.test.RetryOnAddressAlreadyInUseTrait
|
||||
import io.opentelemetry.instrumentation.test.utils.LoggerUtils
|
||||
import io.opentelemetry.instrumentation.test.utils.OkHttpUtils
|
||||
import io.opentelemetry.instrumentation.test.utils.PortUtils
|
||||
import okhttp3.OkHttpClient
|
||||
import io.opentelemetry.testing.armeria.client.ClientFactory
|
||||
import io.opentelemetry.testing.armeria.client.WebClient
|
||||
import io.opentelemetry.testing.armeria.client.logging.LoggingClient
|
||||
import io.opentelemetry.testing.armeria.common.HttpHeaderNames
|
||||
import java.time.Duration
|
||||
import org.junit.AfterClass
|
||||
import org.junit.BeforeClass
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
/**
|
||||
* A trait for testing requests against http server.
|
||||
*/
|
||||
|
@ -29,7 +31,14 @@ trait HttpServerTestTrait<SERVER> implements RetryOnAddressAlreadyInUseTrait {
|
|||
|
||||
// not using SERVER as type because it triggers a bug in groovy and java joint compilation
|
||||
static Object server
|
||||
static OkHttpClient client = OkHttpUtils.client()
|
||||
static WebClient client = WebClient.builder()
|
||||
.responseTimeout(Duration.ofMinutes(1))
|
||||
.writeTimeout(Duration.ofMinutes(1))
|
||||
.factory(ClientFactory.builder().connectTimeout(Duration.ofMinutes(1)).build())
|
||||
.setHeader(HttpHeaderNames.USER_AGENT, TEST_USER_AGENT)
|
||||
.setHeader(HttpHeaderNames.X_FORWARDED_FOR, TEST_CLIENT_IP)
|
||||
.decorator(LoggingClient.newDecorator())
|
||||
.build()
|
||||
static int port
|
||||
static URI address
|
||||
|
||||
|
|
Loading…
Reference in New Issue