Skip to content
Permalink
Browse files

Make ConnectTimeout test accept NoRouteToHostException (#1526)

* Fix a NullPointerException in uncommon failure cases

* Skip ConnectTimeout timeout on hosts that throw NoRouteToHostException

If a host throws NoRouteToHostException before the ConnectTimeout, the test
has neither failed nor succeeded.

Github issue #1526
  • Loading branch information...
ringerc authored and davecramer committed Jul 11, 2019
1 parent ce8333a commit 08d81291c69d02d8973d6b39dac82bdaad91f2ee
@@ -351,6 +351,10 @@ public void setAutoSave(AutoSave autoSave) {
}

protected boolean willHealViaReparse(SQLException e) {
if (e == null || e.getSQLState() == null) {
return false;
}

// "prepared statement \"S_2\" does not exist"
if (PSQLState.INVALID_SQL_STATEMENT_NAME.getState().equals(e.getSQLState())) {
return true;
@@ -10,9 +10,11 @@

import org.postgresql.test.TestUtil;

import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;

import java.net.NoRouteToHostException;
import java.net.SocketTimeoutException;
import java.sql.DriverManager;
import java.sql.SQLException;
@@ -41,11 +43,27 @@ public void testTimeout() {
try {
DriverManager.getConnection(UNREACHABLE_URL, props);
} catch (SQLException e) {
assertTrue("Unexpected " + e.toString(),
e.getCause() instanceof SocketTimeoutException);
final long interval = System.currentTimeMillis() - startTime;
final long connectTimeoutMillis = CONNECT_TIMEOUT * 1000;
final long maxDeviation = connectTimeoutMillis / 10;

/*
* If the platform fast-fails the unroutable address connection then this
* test may not time out, instead throwing
* java.net.NoRouteToHostException. The test has failed in that the connection
* attempt did not time out.
*
* We treat this as a skipped test, as the test didn't really "succeed"
* in testing the original behaviour, but it didn't fail either.
*/
Assume.assumeTrue("Host fast-failed connection to unreachable address "
+ UNREACHABLE_HOST + " after " + interval + " ms, "
+ " before timeout should have triggered.",
e.getCause() instanceof NoRouteToHostException
&& interval < connectTimeoutMillis );

assertTrue("Unexpected " + e.toString() + " with cause " + e.getCause(),
e.getCause() instanceof SocketTimeoutException);
// check that it was not a default system timeout, an approximate value is used
assertTrue(Math.abs(interval - connectTimeoutMillis) < maxDeviation);
return;

0 comments on commit 08d8129

Please sign in to comment.
You can’t perform that action at this time.