Skip to content

Commit 24fe24d

Browse files
even more tests
1 parent 092aadb commit 24fe24d

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed

exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSenderTest.java

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717
import java.time.Duration;
1818
import java.util.Collections;
1919
import java.util.Set;
20+
import java.util.concurrent.CountDownLatch;
2021
import java.util.concurrent.ExecutorService;
2122
import java.util.concurrent.Executors;
23+
import java.util.concurrent.TimeUnit;
2224
import okhttp3.MediaType;
2325
import okhttp3.Protocol;
2426
import okhttp3.Request;
@@ -143,6 +145,125 @@ void shutdown_NonManagedExecutor_ReturnsImmediately() {
143145
}
144146
}
145147

148+
@Test
149+
void shutdown_ExecutorDoesNotTerminateInTime_LogsWarningButSucceeds() throws Exception {
150+
// This test verifies that when threads don't terminate within 5 seconds,
151+
// a warning is logged but shutdown still succeeds.
152+
153+
// Allocate an ephemeral port
154+
int port;
155+
try (ServerSocket socket = new ServerSocket(0)) {
156+
port = socket.getLocalPort();
157+
}
158+
159+
// Create sender with managed executor (default)
160+
OkHttpGrpcSender<TestMarshaler> sender =
161+
new OkHttpGrpcSender<>(
162+
"http://localhost:" + port,
163+
null,
164+
Duration.ofSeconds(10).toNanos(),
165+
Duration.ofSeconds(10).toNanos(),
166+
Collections::emptyMap,
167+
null,
168+
null,
169+
null,
170+
null); // null executor = managed
171+
172+
// Start multiple long-running tasks that will block during shutdown
173+
CountDownLatch tasksStarted = new CountDownLatch(3);
174+
CountDownLatch blockTasks = new CountDownLatch(1);
175+
176+
for (int i = 0; i < 3; i++) {
177+
sender.send(
178+
new TestMarshaler(),
179+
response -> {
180+
tasksStarted.countDown();
181+
try {
182+
// Block for longer than the 5-second timeout
183+
blockTasks.await(10, TimeUnit.SECONDS);
184+
} catch (InterruptedException e) {
185+
Thread.currentThread().interrupt();
186+
}
187+
},
188+
error -> {
189+
tasksStarted.countDown();
190+
try {
191+
blockTasks.await(10, TimeUnit.SECONDS);
192+
} catch (InterruptedException e) {
193+
Thread.currentThread().interrupt();
194+
}
195+
});
196+
}
197+
198+
// Wait for tasks to start
199+
assertTrue(tasksStarted.await(2, TimeUnit.SECONDS), "Tasks should start");
200+
201+
// Shutdown will now try to terminate threads that are blocked
202+
CompletableResultCode shutdownResult = sender.shutdown();
203+
204+
// The shutdown should eventually complete successfully
205+
// even though threads didn't terminate in 5 seconds
206+
assertTrue(
207+
shutdownResult.join(10, TimeUnit.SECONDS).isSuccess(),
208+
"Shutdown should succeed even when threads don't terminate quickly");
209+
210+
// Release the blocking tasks
211+
blockTasks.countDown();
212+
}
213+
214+
@Test
215+
void shutdown_InterruptedWhileWaiting_StillSucceeds() throws Exception {
216+
// This test verifies that if the shutdown thread is interrupted while waiting
217+
// for termination, it still marks the shutdown as successful.
218+
219+
// Allocate an ephemeral port
220+
int port;
221+
try (ServerSocket socket = new ServerSocket(0)) {
222+
port = socket.getLocalPort();
223+
}
224+
225+
OkHttpGrpcSender<TestMarshaler> sender =
226+
new OkHttpGrpcSender<>(
227+
"http://localhost:" + port,
228+
null,
229+
Duration.ofSeconds(10).toNanos(),
230+
Duration.ofSeconds(10).toNanos(),
231+
Collections::emptyMap,
232+
null,
233+
null,
234+
null,
235+
null);
236+
237+
// Trigger some activity
238+
CountDownLatch taskStarted = new CountDownLatch(1);
239+
sender.send(
240+
new TestMarshaler(),
241+
response -> taskStarted.countDown(),
242+
error -> taskStarted.countDown());
243+
244+
// Wait for task to start
245+
assertTrue(taskStarted.await(2, TimeUnit.SECONDS), "Task should start");
246+
247+
// Start shutdown
248+
CompletableResultCode shutdownResult = sender.shutdown();
249+
250+
// Find and interrupt the okhttp-shutdown thread to trigger the InterruptedException path
251+
Thread[] threads = new Thread[Thread.activeCount()];
252+
Thread.enumerate(threads);
253+
for (Thread thread : threads) {
254+
if (thread != null && thread.getName().equals("okhttp-shutdown")) {
255+
// Interrupt the shutdown thread to test the InterruptedException handling
256+
thread.interrupt();
257+
break;
258+
}
259+
}
260+
261+
// Even with interruption, shutdown should still succeed
262+
assertTrue(
263+
shutdownResult.join(10, TimeUnit.SECONDS).isSuccess(),
264+
"Shutdown should succeed even when interrupted");
265+
}
266+
146267
/** Simple test marshaler for testing purposes. */
147268
private static class TestMarshaler extends Marshaler {
148269
@Override

0 commit comments

Comments
 (0)