From a83e6ca6522734c1361e190a3e943046469ba72c Mon Sep 17 00:00:00 2001 From: Mateusz Rzeszutek Date: Wed, 24 Aug 2022 18:18:15 +0200 Subject: [PATCH] Refactor OkHttp tests to Java (#6484) * Refactor OkHttp tests to Java * throws Exception --- .../AbstractGoogleHttpClientTest.java | 12 +- .../src/test/groovy/HeadersUtil.groovy | 16 --- .../src/test/groovy/OkHttp2Test.groovy | 99 -------------- .../okhttp/v2_2/OkHttp2Test.java | 114 ++++++++++++++++ .../okhttp/v3_0/OkHttp3Test.groovy | 41 ------ .../okhttp/v3_0/OkHttp3Test.java | 47 +++++++ .../okhttp/v3_0/OkHttp3Test.groovy | 19 --- .../okhttp/v3_0/OkHttp3Test.java | 23 ++++ .../okhttp/v3_0/AbstractOkHttp3Test.groovy | 115 ---------------- .../okhttp/v3_0/AbstractOkHttp3Test.java | 127 ++++++++++++++++++ .../junit/http/AbstractHttpClientTest.java | 3 +- 11 files changed, 316 insertions(+), 300 deletions(-) delete mode 100644 instrumentation/okhttp/okhttp-2.2/javaagent/src/test/groovy/HeadersUtil.groovy delete mode 100644 instrumentation/okhttp/okhttp-2.2/javaagent/src/test/groovy/OkHttp2Test.groovy create mode 100644 instrumentation/okhttp/okhttp-2.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/okhttp/v2_2/OkHttp2Test.java delete mode 100644 instrumentation/okhttp/okhttp-3.0/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/okhttp/v3_0/OkHttp3Test.groovy create mode 100644 instrumentation/okhttp/okhttp-3.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/okhttp/v3_0/OkHttp3Test.java delete mode 100644 instrumentation/okhttp/okhttp-3.0/library/src/test/groovy/io/opentelemetry/instrumentation/okhttp/v3_0/OkHttp3Test.groovy create mode 100644 instrumentation/okhttp/okhttp-3.0/library/src/test/java/io/opentelemetry/instrumentation/okhttp/v3_0/OkHttp3Test.java delete mode 100644 instrumentation/okhttp/okhttp-3.0/testing/src/main/groovy/io/opentelemetry/instrumentation/okhttp/v3_0/AbstractOkHttp3Test.groovy create mode 100644 instrumentation/okhttp/okhttp-3.0/testing/src/main/java/io/opentelemetry/instrumentation/okhttp/v3_0/AbstractOkHttp3Test.java diff --git a/instrumentation/google-http-client-1.19/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/googlehttpclient/AbstractGoogleHttpClientTest.java b/instrumentation/google-http-client-1.19/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/googlehttpclient/AbstractGoogleHttpClientTest.java index 4a8d8b3cd8..df685703a8 100644 --- a/instrumentation/google-http-client-1.19/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/googlehttpclient/AbstractGoogleHttpClientTest.java +++ b/instrumentation/google-http-client-1.19/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/googlehttpclient/AbstractGoogleHttpClientTest.java @@ -20,8 +20,6 @@ import io.opentelemetry.instrumentation.testing.junit.http.HttpClientInstrumenta import io.opentelemetry.instrumentation.testing.junit.http.HttpClientTestOptions; import io.opentelemetry.sdk.trace.data.StatusData; import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; -import java.io.IOException; -import java.io.UncheckedIOException; import java.net.URI; import java.util.Collections; import java.util.Locale; @@ -43,15 +41,11 @@ public abstract class AbstractGoogleHttpClientTest extends AbstractHttpClientTes } @Override - protected final HttpRequest buildRequest(String method, URI uri, Map headers) { + protected final HttpRequest buildRequest(String method, URI uri, Map headers) + throws Exception { GenericUrl genericUrl = new GenericUrl(uri); - HttpRequest request; - try { - request = requestFactory.buildRequest(method, genericUrl, null); - } catch (IOException e) { - throw new UncheckedIOException(e); - } + HttpRequest request = requestFactory.buildRequest(method, genericUrl, null); request.setConnectTimeout((int) connectTimeout().toMillis()); if (uri.toString().contains("/read-timeout")) { request.setReadTimeout((int) readTimeout().toMillis()); diff --git a/instrumentation/okhttp/okhttp-2.2/javaagent/src/test/groovy/HeadersUtil.groovy b/instrumentation/okhttp/okhttp-2.2/javaagent/src/test/groovy/HeadersUtil.groovy deleted file mode 100644 index 79c8745015..0000000000 --- a/instrumentation/okhttp/okhttp-2.2/javaagent/src/test/groovy/HeadersUtil.groovy +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -class HeadersUtil { - static headersToArray(Map headers) { - String[] headersArr = new String[headers.size() * 2] - headers.eachWithIndex { k, v, i -> - headersArr[i] = k - headersArr[i + 1] = v - } - - headersArr - } -} diff --git a/instrumentation/okhttp/okhttp-2.2/javaagent/src/test/groovy/OkHttp2Test.groovy b/instrumentation/okhttp/okhttp-2.2/javaagent/src/test/groovy/OkHttp2Test.groovy deleted file mode 100644 index 14609633ba..0000000000 --- a/instrumentation/okhttp/okhttp-2.2/javaagent/src/test/groovy/OkHttp2Test.groovy +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import com.squareup.okhttp.Callback -import com.squareup.okhttp.MediaType -import com.squareup.okhttp.OkHttpClient -import com.squareup.okhttp.Request -import com.squareup.okhttp.RequestBody -import com.squareup.okhttp.Response -import com.squareup.okhttp.internal.http.HttpMethod -import io.opentelemetry.api.common.AttributeKey -import io.opentelemetry.instrumentation.test.AgentTestTrait -import io.opentelemetry.instrumentation.test.base.HttpClientTest -import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpClientTest -import io.opentelemetry.semconv.trace.attributes.SemanticAttributes -import spock.lang.Shared - -import java.util.concurrent.TimeUnit - -class OkHttp2Test extends HttpClientTest implements AgentTestTrait { - @Shared - def client = new OkHttpClient() - @Shared - def clientWithReadTimeout = new OkHttpClient() - - def setupSpec() { - client.setConnectTimeout(CONNECT_TIMEOUT_MS, TimeUnit.MILLISECONDS) - clientWithReadTimeout.setConnectTimeout(CONNECT_TIMEOUT_MS, TimeUnit.MILLISECONDS) - clientWithReadTimeout.setReadTimeout(READ_TIMEOUT_MS, TimeUnit.MILLISECONDS) - } - - @Override - Request buildRequest(String method, URI uri, Map headers) { - def body = HttpMethod.requiresRequestBody(method) ? RequestBody.create(MediaType.parse("text/plain"), "") : null - def request = new Request.Builder() - .url(uri.toURL()) - .method(method, body) - headers.forEach({ key, value -> request.header(key, value) }) - return request.build() - } - - @Override - int sendRequest(Request request, String method, URI uri, Map headers) { - return getClient(uri).newCall(request).execute().code() - } - - @Override - void sendRequestWithCallback(Request request, String method, URI uri, Map headers, AbstractHttpClientTest.RequestResult requestResult) { - getClient(uri).newCall(request).enqueue(new Callback() { - @Override - void onFailure(Request req, IOException e) { - requestResult.complete(e) - } - - @Override - void onResponse(Response response) throws IOException { - requestResult.complete(response.code()) - } - }) - } - - OkHttpClient getClient(URI uri) { - if (uri.toString().contains("/read-timeout")) { - return clientWithReadTimeout - } - return client - } - - @Override - Set> httpAttributes(URI uri) { - Set> extra = [ - SemanticAttributes.HTTP_HOST, - SemanticAttributes.HTTP_SCHEME - ] - def attributes = super.httpAttributes(uri) + extra - - // flavor is extracted from the response, and those URLs cause exceptions (= null response) - switch (uri.toString()) { - case "http://localhost:61/": - case "https://192.0.2.1/": - case resolveAddress("/read-timeout").toString(): - attributes.remove(SemanticAttributes.HTTP_FLAVOR) - } - - attributes - } - - @Override - boolean testRedirects() { - false - } - - @Override - boolean testReadTimeout() { - true - } -} diff --git a/instrumentation/okhttp/okhttp-2.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/okhttp/v2_2/OkHttp2Test.java b/instrumentation/okhttp/okhttp-2.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/okhttp/v2_2/OkHttp2Test.java new file mode 100644 index 0000000000..8b732419af --- /dev/null +++ b/instrumentation/okhttp/okhttp-2.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/okhttp/v2_2/OkHttp2Test.java @@ -0,0 +1,114 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.okhttp.v2_2; + +import com.squareup.okhttp.Callback; +import com.squareup.okhttp.MediaType; +import com.squareup.okhttp.OkHttpClient; +import com.squareup.okhttp.Request; +import com.squareup.okhttp.RequestBody; +import com.squareup.okhttp.Response; +import com.squareup.okhttp.internal.http.HttpMethod; +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; +import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpClientTest; +import io.opentelemetry.instrumentation.testing.junit.http.HttpClientInstrumentationExtension; +import io.opentelemetry.instrumentation.testing.junit.http.HttpClientTestOptions; +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; +import java.io.IOException; +import java.net.URI; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.extension.RegisterExtension; + +public class OkHttp2Test extends AbstractHttpClientTest { + + @RegisterExtension + static final InstrumentationExtension testing = HttpClientInstrumentationExtension.forAgent(); + + private static final OkHttpClient client = new OkHttpClient(); + private static final OkHttpClient clientWithReadTimeout = new OkHttpClient(); + + @BeforeAll + void setupSpec() { + client.setConnectTimeout(CONNECTION_TIMEOUT.toMillis(), TimeUnit.MILLISECONDS); + clientWithReadTimeout.setConnectTimeout(CONNECTION_TIMEOUT.toMillis(), TimeUnit.MILLISECONDS); + clientWithReadTimeout.setReadTimeout(READ_TIMEOUT.toMillis(), TimeUnit.MILLISECONDS); + } + + @Override + public Request buildRequest(String method, URI uri, Map headers) + throws Exception { + RequestBody body = + HttpMethod.requiresRequestBody(method) + ? RequestBody.create(MediaType.parse("text/plain"), "") + : null; + Request.Builder request = new Request.Builder().url(uri.toURL()).method(method, body); + headers.forEach(request::header); + return request.build(); + } + + @Override + public int sendRequest(Request request, String method, URI uri, Map headers) + throws Exception { + return getClient(uri).newCall(request).execute().code(); + } + + @Override + public void sendRequestWithCallback( + Request request, + String method, + URI uri, + Map headers, + AbstractHttpClientTest.RequestResult requestResult) { + getClient(uri) + .newCall(request) + .enqueue( + new Callback() { + @Override + public void onFailure(Request req, IOException e) { + requestResult.complete(e); + } + + @Override + public void onResponse(Response response) { + requestResult.complete(response.code()); + } + }); + } + + private static OkHttpClient getClient(URI uri) { + if (uri.toString().contains("/read-timeout")) { + return clientWithReadTimeout; + } + return client; + } + + @Override + protected void configure(HttpClientTestOptions options) { + options.disableTestCircularRedirects(); + options.enableTestReadTimeout(); + + options.setHttpAttributes( + uri -> { + Set> attributes = + new HashSet<>(HttpClientTestOptions.DEFAULT_HTTP_ATTRIBUTES); + + // flavor is extracted from the response, and those URLs cause exceptions (= null + // response) + if ("http://localhost:61/".equals(uri.toString()) + || "https://192.0.2.1/".equals(uri.toString()) + || resolveAddress("/read-timeout").toString().equals(uri.toString())) { + attributes.remove(SemanticAttributes.HTTP_FLAVOR); + } + + return attributes; + }); + } +} diff --git a/instrumentation/okhttp/okhttp-3.0/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/okhttp/v3_0/OkHttp3Test.groovy b/instrumentation/okhttp/okhttp-3.0/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/okhttp/v3_0/OkHttp3Test.groovy deleted file mode 100644 index 6dba02b6f6..0000000000 --- a/instrumentation/okhttp/okhttp-3.0/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/okhttp/v3_0/OkHttp3Test.groovy +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.javaagent.instrumentation.okhttp.v3_0 - -import io.opentelemetry.instrumentation.okhttp.v3_0.AbstractOkHttp3Test -import io.opentelemetry.instrumentation.test.AgentTestTrait -import okhttp3.Call -import okhttp3.OkHttpClient - -import java.util.concurrent.TimeUnit - -class OkHttp3Test extends AbstractOkHttp3Test implements AgentTestTrait { - - @Override - Call.Factory createCallFactory(OkHttpClient.Builder clientBuilder) { - return clientBuilder.build() - } - - def "reused builder has one interceptor"() { - def builder = new OkHttpClient.Builder() - .connectTimeout(CONNECT_TIMEOUT_MS, TimeUnit.MILLISECONDS) - .retryOnConnectionFailure(false) - when: - def newClient = builder.build().newBuilder().build() - - then: - newClient.interceptors().size() == 1 - } - - def "builder created from client has one interceptor"() { - when: - def newClient = ((OkHttpClient) client).newBuilder().build() - - then: - newClient.interceptors().size() == 1 - } - -} diff --git a/instrumentation/okhttp/okhttp-3.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/okhttp/v3_0/OkHttp3Test.java b/instrumentation/okhttp/okhttp-3.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/okhttp/v3_0/OkHttp3Test.java new file mode 100644 index 0000000000..7370313a17 --- /dev/null +++ b/instrumentation/okhttp/okhttp-3.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/okhttp/v3_0/OkHttp3Test.java @@ -0,0 +1,47 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.okhttp.v3_0; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.instrumentation.okhttp.v3_0.AbstractOkHttp3Test; +import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; +import io.opentelemetry.instrumentation.testing.junit.http.HttpClientInstrumentationExtension; +import java.util.concurrent.TimeUnit; +import okhttp3.Call; +import okhttp3.OkHttpClient; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +public class OkHttp3Test extends AbstractOkHttp3Test { + + @RegisterExtension + static final InstrumentationExtension testing = HttpClientInstrumentationExtension.forAgent(); + + @Override + public Call.Factory createCallFactory(OkHttpClient.Builder clientBuilder) { + return clientBuilder.build(); + } + + @Test + void reusedBuilderHasOneInterceptor() { + OkHttpClient.Builder builder = + new OkHttpClient.Builder() + .connectTimeout(CONNECTION_TIMEOUT.toMillis(), TimeUnit.MILLISECONDS) + .retryOnConnectionFailure(false); + + OkHttpClient newClient = builder.build().newBuilder().build(); + + assertThat(newClient.interceptors()).hasSize(1); + } + + @Test + void builderCreatedFromClientHasOneInterceptor() { + OkHttpClient newClient = ((OkHttpClient) client).newBuilder().build(); + + assertThat(newClient.interceptors()).hasSize(1); + } +} diff --git a/instrumentation/okhttp/okhttp-3.0/library/src/test/groovy/io/opentelemetry/instrumentation/okhttp/v3_0/OkHttp3Test.groovy b/instrumentation/okhttp/okhttp-3.0/library/src/test/groovy/io/opentelemetry/instrumentation/okhttp/v3_0/OkHttp3Test.groovy deleted file mode 100644 index 8b1ea12120..0000000000 --- a/instrumentation/okhttp/okhttp-3.0/library/src/test/groovy/io/opentelemetry/instrumentation/okhttp/v3_0/OkHttp3Test.groovy +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.okhttp.v3_0 - - -import io.opentelemetry.instrumentation.test.LibraryTestTrait -import okhttp3.Call -import okhttp3.OkHttpClient - -class OkHttp3Test extends AbstractOkHttp3Test implements LibraryTestTrait { - - @Override - Call.Factory createCallFactory(OkHttpClient.Builder clientBuilder) { - return OkHttpTelemetry.create(getOpenTelemetry()).newCallFactory(clientBuilder.build()) - } -} diff --git a/instrumentation/okhttp/okhttp-3.0/library/src/test/java/io/opentelemetry/instrumentation/okhttp/v3_0/OkHttp3Test.java b/instrumentation/okhttp/okhttp-3.0/library/src/test/java/io/opentelemetry/instrumentation/okhttp/v3_0/OkHttp3Test.java new file mode 100644 index 0000000000..4a7db55744 --- /dev/null +++ b/instrumentation/okhttp/okhttp-3.0/library/src/test/java/io/opentelemetry/instrumentation/okhttp/v3_0/OkHttp3Test.java @@ -0,0 +1,23 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.okhttp.v3_0; + +import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; +import io.opentelemetry.instrumentation.testing.junit.http.HttpClientInstrumentationExtension; +import okhttp3.Call; +import okhttp3.OkHttpClient; +import org.junit.jupiter.api.extension.RegisterExtension; + +public class OkHttp3Test extends AbstractOkHttp3Test { + + @RegisterExtension + static final InstrumentationExtension testing = HttpClientInstrumentationExtension.forLibrary(); + + @Override + public Call.Factory createCallFactory(OkHttpClient.Builder clientBuilder) { + return OkHttpTelemetry.create(testing.getOpenTelemetry()).newCallFactory(clientBuilder.build()); + } +} diff --git a/instrumentation/okhttp/okhttp-3.0/testing/src/main/groovy/io/opentelemetry/instrumentation/okhttp/v3_0/AbstractOkHttp3Test.groovy b/instrumentation/okhttp/okhttp-3.0/testing/src/main/groovy/io/opentelemetry/instrumentation/okhttp/v3_0/AbstractOkHttp3Test.groovy deleted file mode 100644 index 05219fdf58..0000000000 --- a/instrumentation/okhttp/okhttp-3.0/testing/src/main/groovy/io/opentelemetry/instrumentation/okhttp/v3_0/AbstractOkHttp3Test.groovy +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.okhttp.v3_0 - -import io.opentelemetry.api.common.AttributeKey -import io.opentelemetry.instrumentation.test.base.HttpClientTest -import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpClientTest -import io.opentelemetry.semconv.trace.attributes.SemanticAttributes -import okhttp3.Call -import okhttp3.Callback -import okhttp3.Headers -import okhttp3.MediaType -import okhttp3.OkHttpClient -import okhttp3.Protocol -import okhttp3.Request -import okhttp3.RequestBody -import okhttp3.Response -import okhttp3.internal.http.HttpMethod -import spock.lang.Shared - -import java.util.concurrent.TimeUnit - -abstract class AbstractOkHttp3Test extends HttpClientTest { - - abstract Call.Factory createCallFactory(OkHttpClient.Builder clientBuilder) - - @Shared - Call.Factory client = createCallFactory(getClientBuilder(false)) - @Shared - Call.Factory clientWithReadTimeout = createCallFactory(getClientBuilder(true)) - - OkHttpClient.Builder getClientBuilder(boolean withReadTimeout) { - OkHttpClient.Builder builder = new OkHttpClient.Builder() - .connectTimeout(CONNECT_TIMEOUT_MS, TimeUnit.MILLISECONDS) - .protocols(Arrays.asList(Protocol.HTTP_1_1)) - .retryOnConnectionFailure(false) - if (withReadTimeout) { - builder.readTimeout(READ_TIMEOUT_MS, TimeUnit.MILLISECONDS) - } - return builder - } - - @Override - Request buildRequest(String method, URI uri, Map headers) { - def body = HttpMethod.requiresRequestBody(method) ? RequestBody.create(MediaType.parse("text/plain"), "") : null - return new Request.Builder() - .url(uri.toURL()) - .method(method, body) - .headers(Headers.of(headers)).build() - } - - @Override - int sendRequest(Request request, String method, URI uri, Map headers) { - def response = getClient(uri).newCall(request).execute() - response.body().withCloseable { - return response.code() - } - } - - @Override - void sendRequestWithCallback(Request request, String method, URI uri, Map headers, AbstractHttpClientTest.RequestResult requestResult) { - getClient(uri).newCall(request).enqueue(new Callback() { - @Override - void onFailure(Call call, IOException e) { - requestResult.complete(e) - } - - @Override - void onResponse(Call call, Response response) throws IOException { - response.body().withCloseable { - requestResult.complete(response.code()) - } - } - }) - } - - Call.Factory getClient(URI uri) { - if (uri.toString().contains("/read-timeout")) { - return clientWithReadTimeout - } - return client - } - - @Override - boolean testCircularRedirects() { - false - } - - @Override - boolean testReadTimeout() { - true - } - - @Override - Set> httpAttributes(URI uri) { - Set> extra = [ - SemanticAttributes.HTTP_HOST, - SemanticAttributes.HTTP_SCHEME - ] - def attributes = super.httpAttributes(uri) + extra - - // flavor is extracted from the response, and those URLs cause exceptions (= null response) - switch (uri.toString()) { - case "http://localhost:61/": - case "https://192.0.2.1/": - case resolveAddress("/read-timeout").toString(): - attributes.remove(SemanticAttributes.HTTP_FLAVOR) - } - - attributes - } -} diff --git a/instrumentation/okhttp/okhttp-3.0/testing/src/main/java/io/opentelemetry/instrumentation/okhttp/v3_0/AbstractOkHttp3Test.java b/instrumentation/okhttp/okhttp-3.0/testing/src/main/java/io/opentelemetry/instrumentation/okhttp/v3_0/AbstractOkHttp3Test.java new file mode 100644 index 0000000000..4e1ef64689 --- /dev/null +++ b/instrumentation/okhttp/okhttp-3.0/testing/src/main/java/io/opentelemetry/instrumentation/okhttp/v3_0/AbstractOkHttp3Test.java @@ -0,0 +1,127 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.okhttp.v3_0; + +import static java.util.Collections.singletonList; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpClientTest; +import io.opentelemetry.instrumentation.testing.junit.http.HttpClientTestOptions; +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; +import java.io.IOException; +import java.net.URI; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.Headers; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Protocol; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; +import okhttp3.ResponseBody; +import okhttp3.internal.http.HttpMethod; + +public abstract class AbstractOkHttp3Test extends AbstractHttpClientTest { + + protected abstract Call.Factory createCallFactory(OkHttpClient.Builder clientBuilder); + + protected final Call.Factory client = createCallFactory(getClientBuilder(false)); + private final Call.Factory clientWithReadTimeout = createCallFactory(getClientBuilder(true)); + + OkHttpClient.Builder getClientBuilder(boolean withReadTimeout) { + OkHttpClient.Builder builder = + new OkHttpClient.Builder() + .connectTimeout(CONNECTION_TIMEOUT.toMillis(), TimeUnit.MILLISECONDS) + .protocols(singletonList(Protocol.HTTP_1_1)) + .retryOnConnectionFailure(false); + if (withReadTimeout) { + builder.readTimeout(READ_TIMEOUT.toMillis(), TimeUnit.MILLISECONDS); + } + return builder; + } + + @Override + protected Request buildRequest(String method, URI uri, Map headers) + throws Exception { + RequestBody body = + HttpMethod.requiresRequestBody(method) + ? RequestBody.create(MediaType.parse("text/plain"), "") + : null; + return new Request.Builder() + .url(uri.toURL()) + .method(method, body) + .headers(Headers.of(headers)) + .build(); + } + + @Override + protected int sendRequest(Request request, String method, URI uri, Map headers) + throws Exception { + Response response = getClient(uri).newCall(request).execute(); + try (ResponseBody ignored = response.body()) { + return response.code(); + } + } + + @Override + protected void sendRequestWithCallback( + Request request, + String method, + URI uri, + Map headers, + AbstractHttpClientTest.RequestResult requestResult) { + getClient(uri) + .newCall(request) + .enqueue( + new Callback() { + @Override + public void onFailure(Call call, IOException e) { + requestResult.complete(e); + } + + @Override + public void onResponse(Call call, Response response) { + try (ResponseBody ignored = response.body()) { + requestResult.complete(response.code()); + } + } + }); + } + + private Call.Factory getClient(URI uri) { + if (uri.toString().contains("/read-timeout")) { + return clientWithReadTimeout; + } + return client; + } + + @Override + protected void configure(HttpClientTestOptions options) { + options.disableTestCircularRedirects(); + options.enableTestReadTimeout(); + + options.setHttpAttributes( + uri -> { + Set> attributes = + new HashSet<>(HttpClientTestOptions.DEFAULT_HTTP_ATTRIBUTES); + + // flavor is extracted from the response, and those URLs cause exceptions (= null + // response) + if ("http://localhost:61/".equals(uri.toString()) + || "https://192.0.2.1/".equals(uri.toString()) + || resolveAddress("/read-timeout").toString().equals(uri.toString())) { + attributes.remove(SemanticAttributes.HTTP_FLAVOR); + } + + return attributes; + }); + } +} diff --git a/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/junit/http/AbstractHttpClientTest.java b/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/junit/http/AbstractHttpClientTest.java index 50cd16f460..911042ffd4 100644 --- a/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/junit/http/AbstractHttpClientTest.java +++ b/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/junit/http/AbstractHttpClientTest.java @@ -63,7 +63,8 @@ public abstract class AbstractHttpClientTest { * request a second time to verify that the traceparent header is not added multiple times to the * request, and that the last one wins. Tests will fail if the header shows multiple times. */ - protected abstract REQUEST buildRequest(String method, URI uri, Map headers); + protected abstract REQUEST buildRequest(String method, URI uri, Map headers) + throws Exception; /** * Helper class for capturing result of asynchronous request and running a callback when result is