Skip to content

Commit

Permalink
Fix | Fix issues with Login Timeout not getting applied appropriately. (
Browse files Browse the repository at this point in the history
  • Loading branch information
cheenamalhotra authored May 15, 2019
1 parent 6697d1b commit 20c0b81
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 30 deletions.
16 changes: 10 additions & 6 deletions src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDriver.java
Original file line number Diff line number Diff line change
Expand Up @@ -756,19 +756,23 @@ private Properties parseAndMergeProperties(String Url, Properties suppliedProper
throw new SQLServerException(null, SQLServerException.getErrString("R_nullConnection"), null, 0, false);
}

// Pull the URL properties into the connection properties
Properties connectProperties = Util.parseUrl(Url, drLogger);
if (connectProperties == null)
if (null == connectProperties)
return null; // If we are the wrong driver dont throw an exception

// put the user properties into the connect properties
int nTimeout = DriverManager.getLoginTimeout();
if (nTimeout > 0) {
connectProperties.put(SQLServerDriverIntProperty.LOGIN_TIMEOUT.toString(),
Integer.valueOf(nTimeout).toString());
String loginTimeoutProp = connectProperties.getProperty(SQLServerDriverIntProperty.LOGIN_TIMEOUT.toString());
int dmLoginTimeout = DriverManager.getLoginTimeout();

// Use Driver Manager's login timeout if it exceeds 0 and loginTimeout connection property is not provided.
if (dmLoginTimeout > 0 && null == loginTimeoutProp) {
connectProperties.setProperty(SQLServerDriverIntProperty.LOGIN_TIMEOUT.toString(),
String.valueOf(dmLoginTimeout));
}

// Merge connectProperties (from URL) and supplied properties from user.
connectProperties = mergeURLAndSuppliedProperties(connectProperties, suppliedProperties);

return connectProperties;
}

Expand Down
107 changes: 83 additions & 24 deletions src/test/java/com/microsoft/sqlserver/jdbc/connection/TimeoutTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import static org.junit.jupiter.api.Assertions.fail;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

Expand All @@ -29,66 +30,124 @@


@RunWith(JUnitPlatform.class)
@Tag("slow")
public class TimeoutTest extends AbstractTest {
String randomServer = RandomUtil.getIdentifier("Server");
static String randomServer = RandomUtil.getIdentifier("Server");
static String waitForDelaySPName = RandomUtil.getIdentifier("waitForDelaySP");
final int waitForDelaySeconds = 10;
static final int waitForDelaySeconds = 10;
static final int defaultTimeout = 15;

@Test
@Tag("slow")
public void testDefaultLoginTimeout() {
long timerStart = 0;
long timerEnd = 0;

timerStart = System.currentTimeMillis();
long timerStart = System.currentTimeMillis();
// Try a non existing server and see if the default timeout is 15 seconds
try (Connection con = PrepUtil.getConnection("jdbc:sqlserver://" + randomServer + ";user=sa;password=pwd;")) {
fail(TestResource.getResource("R_shouldNotConnect"));
} catch (Exception e) {
assertTrue(e.getMessage().contains(TestResource.getResource("R_tcpipConnectionToHost")));
timerEnd = System.currentTimeMillis();
}

verifyTimeout(timerEnd - timerStart, defaultTimeout);
}

@Test
public void testURLLoginTimeout() {
long timerEnd = 0;
int timeout = 10;

long timerStart = System.currentTimeMillis();

try (Connection con = PrepUtil
.getConnection("jdbc:sqlserver://" + randomServer + ";user=sa;password=pwd;logintimeout=" + timeout)) {
fail(TestResource.getResource("R_shouldNotConnect"));
} catch (Exception e) {
assertTrue(e.getMessage().contains(TestResource.getResource("R_tcpipConnectionToHost")));
timerEnd = System.currentTimeMillis();
}

assertTrue(0 != timerEnd, TestResource.getResource("R_shouldNotConnect"));
verifyTimeout(timerEnd - timerStart, timeout);
}

long timeDiff = timerEnd - timerStart;
assertTrue(timeDiff > 14000);
@Test
public void testDMLoginTimeoutApplied() {
long timerEnd = 0;
int timeout = 10;

DriverManager.setLoginTimeout(timeout);
long timerStart = System.currentTimeMillis();

try (Connection con = PrepUtil.getConnection("jdbc:sqlserver://" + randomServer + ";user=sa;password=pwd")) {
fail(TestResource.getResource("R_shouldNotConnect"));
} catch (Exception e) {
assertTrue(e.getMessage().contains(TestResource.getResource("R_tcpipConnectionToHost")));
timerEnd = System.currentTimeMillis();
}

verifyTimeout(timerEnd - timerStart, timeout);
}

@Test
public void testDMLoginTimeoutNotApplied() {
long timerEnd = 0;
int timeout = 10;
try {
DriverManager.setLoginTimeout(timeout * 3); // 30 seconds
long timerStart = System.currentTimeMillis();

try (Connection con = PrepUtil.getConnection(
"jdbc:sqlserver://" + randomServer + ";user=sa;password=pwd;loginTimeout=" + timeout)) {
fail(TestResource.getResource("R_shouldNotConnect"));
} catch (Exception e) {
assertTrue(e.getMessage().contains(TestResource.getResource("R_tcpipConnectionToHost")));
timerEnd = System.currentTimeMillis();
}
verifyTimeout(timerEnd - timerStart, timeout);
} finally {
DriverManager.setLoginTimeout(0); // Default to 0 again
}
}

@Test
public void testFailoverInstanceResolution() throws SQLException {
long timerStart = 0;
long timerEnd = 0;

timerStart = System.currentTimeMillis();
long timerStart = System.currentTimeMillis();
// Try a non existing server and see if the default timeout is 15 seconds
try (Connection con = PrepUtil
.getConnection("jdbc:sqlserver://" + randomServer + ";databaseName=FailoverDB_abc;failoverPartner="
+ randomServer + "\\foo;user=sa;password=pwd;")) {} catch (Exception e) {
try (Connection con = PrepUtil.getConnection("jdbc:sqlserver://" + randomServer
+ ";databaseName=FailoverDB_abc;failoverPartner=" + randomServer + "\\foo;user=sa;password=pwd;")) {
fail(TestResource.getResource("R_shouldNotConnect"));
} catch (Exception e) {
assertTrue(e.getMessage().contains(TestResource.getResource("R_tcpipConnectionToHost")));
timerEnd = System.currentTimeMillis();
}
assertTrue(0 != timerEnd, TestResource.getResource("R_shouldNotConnect"));

long timeDiff = timerEnd - timerStart;
assertTrue(timeDiff > 14000);
verifyTimeout(timerEnd - timerStart, defaultTimeout);
}

@Test
public void testFOInstanceResolution2() throws SQLException {
long timerStart = 0;
long timerEnd = 0;

timerStart = System.currentTimeMillis();
try (Connection con = PrepUtil
.getConnection("jdbc:sqlserver://" + randomServer + "\\fooggg;databaseName=FailoverDB;failoverPartner="
+ randomServer + "\\foo;user=sa;password=pwd;")) {} catch (Exception e) {
long timerStart = System.currentTimeMillis();
try (Connection con = PrepUtil.getConnection("jdbc:sqlserver://" + randomServer
+ "\\fooggg;databaseName=FailoverDB;failoverPartner=" + randomServer + "\\foo;user=sa;password=pwd;")) {
fail(TestResource.getResource("R_shouldNotConnect"));
} catch (Exception e) {
timerEnd = System.currentTimeMillis();
}
assertTrue(0 != timerEnd, TestResource.getResource("R_shouldNotConnect"));

long timeDiff = timerEnd - timerStart;
assertTrue(timeDiff > 14000);
verifyTimeout(timerEnd - timerStart, defaultTimeout);
}

private void verifyTimeout(long timeDiff, int timeout) {
// Verify that login timeout does not take less than <timeout> seconds.
assertTrue(timeDiff > (timeout - 1) * 1000);

// Verify that login timeout does not take longer than <timeout * 2> seconds.
assertTrue(timeDiff < timeout * 2000);
}

/**
Expand Down

0 comments on commit 20c0b81

Please sign in to comment.