Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 35 additions & 5 deletions src/test/java/ai/spice/ResetTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ of this software and associated documentation files (the "Software"), to deal
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.arrow.flight.FlightRuntimeException;
import org.apache.arrow.flight.FlightStream;
import org.apache.arrow.vector.ipc.ArrowReader;

Expand Down Expand Up @@ -294,10 +296,13 @@ public void testConcurrentResetAndQuery() throws Exception {
try {
FlightStream stream = client.query("SELECT 1");
stream.close();
} catch (NullPointerException e) {
unexpectedErrors.add(e);
} catch (Exception e) {
// Connection errors are expected
// Unwrap ExecutionException to inspect the real cause
Throwable toCheck = (e instanceof ExecutionException && e.getCause() != null)
? e.getCause() : e;
if (!isExpectedTransportError(toCheck)) {
unexpectedErrors.add(toCheck);
}
}
Comment thread
phillipleblanc marked this conversation as resolved.
Thread.sleep(10);
}
Expand All @@ -310,14 +315,39 @@ public void testConcurrentResetAndQuery() throws Exception {
assertTrue("Concurrent reset+query should complete within 30s",
executor.awaitTermination(30, TimeUnit.SECONDS));

assertTrue("Should not get NullPointerException during concurrent reset+query: " + unexpectedErrors,
unexpectedErrors.isEmpty());
assertTrue("Unexpected errors during concurrent reset+query: "
+ unexpectedErrors, unexpectedErrors.isEmpty());
} finally {
executor.shutdownNow();
client.close();
}
}

/**
* Returns true if the throwable is an expected transport/connection error
* that can occur when no server is running or during a mid-reset race.
* Anything else (NPE, IllegalStateException, etc.) is unexpected.
*/
private static boolean isExpectedTransportError(Throwable t) {
if (t instanceof FlightRuntimeException) {
return true; // gRPC status errors (UNAVAILABLE, etc.)
}
if (t instanceof java.net.ConnectException
|| t instanceof java.io.IOException) {
return true; // connection refused, broken pipe, etc.
}
String msg = t.getMessage();
if (msg != null) {
String lower = msg.toLowerCase();
if (lower.contains("unavailable")
|| lower.contains("connection refused")
|| lower.contains("failed to execute")) {
return true;
}
}
return false;
}

// ==================== Construction / DNS / Keep-alive ====================

/**
Expand Down
Loading