Skip to content

Commit d4146be

Browse files
abdessattar23mohammed-abdessetar
authored andcommitted
Add test coverage for JdkHttpSender.send() callback paths
1 parent 093e806 commit d4146be

1 file changed

Lines changed: 128 additions & 0 deletions

File tree

exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,36 @@
99
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
1010
import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
1111
import static org.mockito.ArgumentMatchers.any;
12+
import static org.mockito.Mockito.doReturn;
1213
import static org.mockito.Mockito.doThrow;
14+
import static org.mockito.Mockito.mock;
1315
import static org.mockito.Mockito.times;
1416
import static org.mockito.Mockito.verify;
1517
import static org.mockito.Mockito.when;
1618

1719
import io.opentelemetry.sdk.common.CompletableResultCode;
20+
import io.opentelemetry.sdk.common.export.HttpResponse;
1821
import io.opentelemetry.sdk.common.export.MessageWriter;
1922
import io.opentelemetry.sdk.common.export.RetryPolicy;
23+
import java.io.ByteArrayInputStream;
2024
import java.io.IOException;
25+
import java.io.InputStream;
2126
import java.io.OutputStream;
2227
import java.lang.reflect.Method;
2328
import java.net.ConnectException;
2429
import java.net.ServerSocket;
2530
import java.net.URI;
2631
import java.net.http.HttpClient;
2732
import java.net.http.HttpConnectTimeoutException;
33+
import java.net.http.HttpHeaders;
2834
import java.time.Duration;
2935
import java.util.Collections;
36+
import java.util.concurrent.CountDownLatch;
37+
import java.util.concurrent.RejectedExecutionException;
38+
import java.util.concurrent.SynchronousQueue;
3039
import java.util.concurrent.ThreadPoolExecutor;
3140
import java.util.concurrent.TimeUnit;
41+
import java.util.concurrent.atomic.AtomicReference;
3242
import javax.net.ssl.SSLException;
3343
import org.assertj.core.api.InstanceOfAssertFactories;
3444
import org.junit.jupiter.api.BeforeEach;
@@ -222,6 +232,124 @@ void connectTimeout() {
222232
assertThat(httpClient.connectTimeout().get()).isEqualTo(Duration.ofSeconds(10)));
223233
}
224234

235+
@SuppressWarnings("unchecked")
236+
@Test
237+
void send_successfulResponse_callsOnResponse() throws Exception {
238+
java.net.http.HttpResponse<InputStream> mockJdkResponse =
239+
mock(java.net.http.HttpResponse.class);
240+
when(mockJdkResponse.statusCode()).thenReturn(200);
241+
when(mockJdkResponse.body()).thenReturn(new ByteArrayInputStream(new byte[0]));
242+
when(mockJdkResponse.headers())
243+
.thenReturn(HttpHeaders.of(Collections.emptyMap(), (a, b) -> true));
244+
doReturn(mockJdkResponse).when(mockHttpClient).send(any(), any());
245+
246+
JdkHttpSender testSender =
247+
new JdkHttpSender(
248+
mockHttpClient,
249+
URI.create("http://localhost"),
250+
"text/plain",
251+
null,
252+
Duration.ofSeconds(10),
253+
Collections::emptyMap,
254+
null,
255+
null,
256+
Long.MAX_VALUE);
257+
258+
try {
259+
CountDownLatch latch = new CountDownLatch(1);
260+
AtomicReference<HttpResponse> responseRef = new AtomicReference<>();
261+
AtomicReference<Throwable> errorRef = new AtomicReference<>();
262+
263+
testSender.send(
264+
new NoOpRequestBodyWriter(),
265+
response -> {
266+
responseRef.set(response);
267+
latch.countDown();
268+
},
269+
error -> {
270+
errorRef.set(error);
271+
latch.countDown();
272+
});
273+
274+
assertThat(latch.await(5, TimeUnit.SECONDS)).isTrue();
275+
assertThat(responseRef.get()).isNotNull();
276+
assertThat(responseRef.get().getStatusCode()).isEqualTo(200);
277+
assertThat(errorRef.get()).isNull();
278+
} finally {
279+
testSender.shutdown();
280+
}
281+
}
282+
283+
@Test
284+
void send_ioException_callsOnError() throws Exception {
285+
doThrow(new IOException("send failed")).when(mockHttpClient).send(any(), any());
286+
287+
JdkHttpSender testSender =
288+
new JdkHttpSender(
289+
mockHttpClient,
290+
URI.create("http://localhost"),
291+
"text/plain",
292+
null,
293+
Duration.ofSeconds(10),
294+
Collections::emptyMap,
295+
null,
296+
null,
297+
Long.MAX_VALUE);
298+
299+
try {
300+
CountDownLatch latch = new CountDownLatch(1);
301+
AtomicReference<HttpResponse> responseRef = new AtomicReference<>();
302+
AtomicReference<Throwable> errorRef = new AtomicReference<>();
303+
304+
testSender.send(
305+
new NoOpRequestBodyWriter(),
306+
response -> {
307+
responseRef.set(response);
308+
latch.countDown();
309+
},
310+
error -> {
311+
errorRef.set(error);
312+
latch.countDown();
313+
});
314+
315+
assertThat(latch.await(5, TimeUnit.SECONDS)).isTrue();
316+
assertThat(errorRef.get()).isNotNull();
317+
assertThat(errorRef.get()).hasRootCauseInstanceOf(IOException.class);
318+
assertThat(errorRef.get()).hasRootCauseMessage("send failed");
319+
assertThat(responseRef.get()).isNull();
320+
} finally {
321+
testSender.shutdown();
322+
}
323+
}
324+
325+
@Test
326+
void send_rejectedExecution_callsOnError() {
327+
ThreadPoolExecutor executor =
328+
new ThreadPoolExecutor(0, 1, 0, TimeUnit.SECONDS, new SynchronousQueue<>());
329+
executor.shutdown();
330+
331+
JdkHttpSender testSender =
332+
new JdkHttpSender(
333+
mockHttpClient,
334+
URI.create("http://localhost"),
335+
"text/plain",
336+
null,
337+
Duration.ofSeconds(10),
338+
Collections::emptyMap,
339+
null,
340+
executor,
341+
Long.MAX_VALUE);
342+
343+
AtomicReference<HttpResponse> responseRef = new AtomicReference<>();
344+
AtomicReference<Throwable> errorRef = new AtomicReference<>();
345+
346+
testSender.send(new NoOpRequestBodyWriter(), responseRef::set, errorRef::set);
347+
348+
assertThat(errorRef.get()).isNotNull();
349+
assertThat(errorRef.get()).isInstanceOf(RejectedExecutionException.class);
350+
assertThat(responseRef.get()).isNull();
351+
}
352+
225353
private static class NoOpRequestBodyWriter implements MessageWriter {
226354
@Override
227355
public void writeMessage(OutputStream output) {}

0 commit comments

Comments
 (0)