From 8735e91b0ba40d34327828855b16c0ce4aedde15 Mon Sep 17 00:00:00 2001 From: Terry Chow Date: Thu, 20 Mar 2025 14:43:49 -0700 Subject: [PATCH 01/14] Updated dependency download to pull from Azure Artifacts --- pom.xml | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index ad2156bc0..e5c073b5a 100644 --- a/pom.xml +++ b/pom.xml @@ -62,7 +62,7 @@ 6.0.0 - 4.3.6 + 4.9.2 1.4.3 5.0.0 4.9.3 @@ -232,7 +232,30 @@ test - + + + central + https://sqlclientdrivers.pkgs.visualstudio.com/public/_packaging/mssql-jdbc/maven/v1 + + true + + + true + + + + + + central + https://sqlclientdrivers.pkgs.visualstudio.com/public/_packaging/mssql-jdbc/maven/v1 + + true + + + true + + + jre8 From 817154bd1b6bf67c932d8445518853cb1ee9bcd5 Mon Sep 17 00:00:00 2001 From: Terry Chow Date: Thu, 20 Mar 2025 15:30:55 -0700 Subject: [PATCH 02/14] Added requireSecret tag --- pom.xml | 12 +++++++----- .../BulkCopySendTemporalDataTypesAsStringAETest.java | 2 ++ .../jdbc/AlwaysEncrypted/CallableStatementTest.java | 2 ++ .../sqlserver/jdbc/AlwaysEncrypted/EnclaveTest.java | 1 + .../JDBCEncryptionDecryptionTest.java | 2 ++ .../sqlserver/jdbc/AlwaysEncrypted/MSITest.java | 1 + .../jdbc/AlwaysEncrypted/MultiUserAKVTest.java | 2 ++ .../jdbc/AlwaysEncrypted/PrecisionScaleTest.java | 2 ++ .../RegressionAlwaysEncryptedTest.java | 2 ++ .../microsoft/sqlserver/jdbc/EnclavePackageTest.java | 1 + .../sqlserver/jdbc/fedauth/ConcurrentLoginTest.java | 1 + .../jdbc/fedauth/ConnectionEncryptionTest.java | 1 + .../jdbc/fedauth/ConnectionSuspensionTest.java | 1 + .../sqlserver/jdbc/fedauth/ErrorMessageTest.java | 1 + .../sqlserver/jdbc/fedauth/FedauthTest.java | 1 + .../sqlserver/jdbc/fedauth/FedauthWithAE.java | 1 + .../sqlserver/jdbc/fedauth/PooledConnectionTest.java | 1 + .../microsoft/sqlserver/testframework/Constants.java | 1 + 18 files changed, 30 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index e5c073b5a..89740e8f8 100644 --- a/pom.xml +++ b/pom.xml @@ -50,13 +50,15 @@ xAzureSQLDB - - - - For tests not compatible with Azure SQL Database - - xAzureSQLDW - - - - For tests not compatible with Azure Data Warehouse - xAzureSQLMI - - - - For tests not compatible with Azure SQL Managed Instance - NTLM - - - - - - - For tests using NTLM Authentication mode (excluded by default) - reqExternalSetup - For tests requiring external setup (excluded by default) - clientCertAuth - - For tests requiring client certificate authentication setup (excluded by default) + NTLM - - - For tests using NTLM Authentication mode (excluded by default) + kerberos - - - - For tests using Kerberos authentication (excluded by default) + reqExternalSetup - For tests requiring external setup (excluded by default) + clientCertAuth - - For tests requiring client certificate authentication + setup (excluded by default) - - - - - - - - - - - - - - - - - - - - - - - + requireSecret - For tests requiring setting up secrets manually - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Default testing enabled with SQL Server 2019 (SQLv15) --> - xSQLv12,xSQLv15,NTLM,MSI,reqExternalSetup,clientCertAuth,fedAuth - + xSQLv12,xSQLv15,NTLM,MSI,reqExternalSetup,clientCertAuth,fedAuth,kerberos,requireSecret diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/BulkCopySendTemporalDataTypesAsStringAETest.java b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/BulkCopySendTemporalDataTypesAsStringAETest.java index d8552ad3d..47f717f54 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/BulkCopySendTemporalDataTypesAsStringAETest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/BulkCopySendTemporalDataTypesAsStringAETest.java @@ -57,6 +57,8 @@ @Tag(Constants.xSQLv12) @Tag(Constants.xAzureSQLDB) @Tag(Constants.xAzureSQLDW) +@Tag(Constants.reqExternalSetup) +@Tag(Constants.requireSecret) public class BulkCopySendTemporalDataTypesAsStringAETest extends AESetup { static String inputFile = "BulkCopyCSVSendTemporalDataTypesAsStringForBulkCopy.csv"; static String encoding = "UTF-8"; diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/CallableStatementTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/CallableStatementTest.java index 7fd94b498..0ddf791fa 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/CallableStatementTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/CallableStatementTest.java @@ -51,6 +51,8 @@ @Tag(Constants.xSQLv12) @Tag(Constants.xAzureSQLDW) @Tag(Constants.xAzureSQLDB) +@Tag(Constants.reqExternalSetup) +@Tag(Constants.requireSecret) public class CallableStatementTest extends AESetup { private static String multiStatementsProcedure = AbstractSQLGenerator diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/EnclaveTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/EnclaveTest.java index 9b136afd3..b142cd1dd 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/EnclaveTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/EnclaveTest.java @@ -42,6 +42,7 @@ @Tag(Constants.xAzureSQLDW) @Tag(Constants.xAzureSQLDB) @Tag(Constants.reqExternalSetup) +@Tag(Constants.requireSecret) public class EnclaveTest extends AESetup { /** * Tests basic connection. diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/JDBCEncryptionDecryptionTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/JDBCEncryptionDecryptionTest.java index d4c2771c5..bad811a20 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/JDBCEncryptionDecryptionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/JDBCEncryptionDecryptionTest.java @@ -64,6 +64,8 @@ @Tag(Constants.xSQLv12) @Tag(Constants.xAzureSQLDW) @Tag(Constants.xAzureSQLDB) +@Tag(Constants.reqExternalSetup) +@Tag(Constants.requireSecret) public class JDBCEncryptionDecryptionTest extends AESetup { private boolean nullable = false; diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/MSITest.java b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/MSITest.java index 7eec04b70..dc98d33d8 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/MSITest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/MSITest.java @@ -43,6 +43,7 @@ */ @RunWith(JUnitPlatform.class) @Tag(Constants.MSI) +@Tag(Constants.requireSecret) public class MSITest extends AESetup { /* diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/MultiUserAKVTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/MultiUserAKVTest.java index b597c2052..eb42d9ebb 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/MultiUserAKVTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/MultiUserAKVTest.java @@ -58,6 +58,8 @@ @Tag(Constants.xSQLv12) @Tag(Constants.xAzureSQLDW) @Tag(Constants.xAzureSQLDB) +@Tag(Constants.reqExternalSetup) +@Tag(Constants.requireSecret) public class MultiUserAKVTest extends AESetup { private static Map requiredKeyStoreProvider = new HashMap<>(); diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/PrecisionScaleTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/PrecisionScaleTest.java index 5343b1fcd..dcbe907b5 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/PrecisionScaleTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/PrecisionScaleTest.java @@ -42,6 +42,8 @@ @Tag(Constants.xSQLv12) @Tag(Constants.xAzureSQLDW) @Tag(Constants.xAzureSQLDB) +@Tag(Constants.reqExternalSetup) +@Tag(Constants.requireSecret) public class PrecisionScaleTest extends AESetup { private static java.util.Date date = null; private static int offsetFromGMT = 0; diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/RegressionAlwaysEncryptedTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/RegressionAlwaysEncryptedTest.java index c30dc0e50..793835e78 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/RegressionAlwaysEncryptedTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/RegressionAlwaysEncryptedTest.java @@ -29,6 +29,8 @@ @Tag(Constants.xSQLv12) @Tag(Constants.xAzureSQLDW) @Tag(Constants.xAzureSQLDB) +@Tag(Constants.reqExternalSetup) +@Tag(Constants.requireSecret) public class RegressionAlwaysEncryptedTest extends AESetup { static String numericTable[][] = {{"Bit", "bit"}, {"Tinyint", "tinyint"}, {"Smallint", "smallint"},}; diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/EnclavePackageTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/EnclavePackageTest.java index ffcb80b7f..b6509c500 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/EnclavePackageTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/EnclavePackageTest.java @@ -33,6 +33,7 @@ @Tag(Constants.xAzureSQLDW) @Tag(Constants.xAzureSQLDB) @Tag(Constants.reqExternalSetup) +@Tag(Constants.requireSecret) public class EnclavePackageTest extends AbstractTest { private static String connectionStringEnclave = null; diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConcurrentLoginTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConcurrentLoginTest.java index 6b8509978..cde66ae2e 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConcurrentLoginTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConcurrentLoginTest.java @@ -23,6 +23,7 @@ @RunWith(JUnitPlatform.class) @Tag(Constants.fedAuth) +@Tag(Constants.requireSecret) public class ConcurrentLoginTest extends FedauthCommon { final AtomicReference throwableRef = new AtomicReference(); diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConnectionEncryptionTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConnectionEncryptionTest.java index 1904ff69d..1df4e4ed2 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConnectionEncryptionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConnectionEncryptionTest.java @@ -29,6 +29,7 @@ @RunWith(JUnitPlatform.class) @Tag(Constants.fedAuth) +@Tag(Constants.requireSecret) public class ConnectionEncryptionTest extends FedauthCommon { static String charTable = TestUtils.escapeSingleQuotes( diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConnectionSuspensionTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConnectionSuspensionTest.java index c23d6f813..559da4074 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConnectionSuspensionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConnectionSuspensionTest.java @@ -31,6 +31,7 @@ @RunWith(JUnitPlatform.class) @Tag("slow") @Tag(Constants.fedAuth) +@Tag(Constants.requireSecret) public class ConnectionSuspensionTest extends FedauthCommon { static String charTable = TestUtils.escapeSingleQuotes( diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ErrorMessageTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ErrorMessageTest.java index 0630c05c5..8eb8e0f67 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ErrorMessageTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ErrorMessageTest.java @@ -26,6 +26,7 @@ @RunWith(JUnitPlatform.class) @Tag(Constants.fedAuth) +@Tag(Constants.requireSecret) public class ErrorMessageTest extends FedauthCommon { String badUserName = "abc" + azureUserName; diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthTest.java index 8d8cb5b5d..1e7531efb 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthTest.java @@ -36,6 +36,7 @@ @RunWith(JUnitPlatform.class) @Tag(Constants.fedAuth) +@Tag(Constants.requireSecret) public class FedauthTest extends FedauthCommon { static String charTable = TestUtils .escapeSingleQuotes(AbstractSQLGenerator.escapeIdentifier(RandomUtil.getIdentifier("JDBC_FedAuthTest"))); diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthWithAE.java b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthWithAE.java index a34d4ee32..e264b8afd 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthWithAE.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthWithAE.java @@ -37,6 +37,7 @@ @RunWith(JUnitPlatform.class) @Tag(Constants.fedAuth) +@Tag(Constants.requireSecret) public class FedauthWithAE extends FedauthCommon { static String cmkName1 = Constants.CMK_NAME + "fedauthAE1"; diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/PooledConnectionTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/PooledConnectionTest.java index 884b6c276..6dc98ee2a 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/PooledConnectionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/PooledConnectionTest.java @@ -39,6 +39,7 @@ @RunWith(JUnitPlatform.class) @Tag("slow") @Tag(Constants.fedAuth) +@Tag(Constants.requireSecret) public class PooledConnectionTest extends FedauthCommon { static String charTable = TestUtils.escapeSingleQuotes( diff --git a/src/test/java/com/microsoft/sqlserver/testframework/Constants.java b/src/test/java/com/microsoft/sqlserver/testframework/Constants.java index acac806cb..92efb79ca 100644 --- a/src/test/java/com/microsoft/sqlserver/testframework/Constants.java +++ b/src/test/java/com/microsoft/sqlserver/testframework/Constants.java @@ -43,6 +43,7 @@ private Constants() {} public static final String reqExternalSetup = "reqExternalSetup"; public static final String clientCertAuth = "clientCertAuth"; public static final String fedAuth = "fedAuth"; + public static final String requireSecret = "requireSecret"; public static final ThreadLocalRandom RANDOM = ThreadLocalRandom.current(); public static final Logger LOGGER = Logger.getLogger("AbstractTest"); From b3a790cb2fd97c73c5e9f5eca7fca1ccf0a893e9 Mon Sep 17 00:00:00 2001 From: Terry Chow Date: Thu, 20 Mar 2025 16:01:17 -0700 Subject: [PATCH 03/14] Cherry-picked: azureAADPrincipialId/azureAADPrincipialSecret to applicationKey/applicationClientID --- .../sqlserver/jdbc/fedauth/FedauthCommon.java | 6 ---- .../sqlserver/jdbc/fedauth/FedauthTest.java | 28 ++++++++++--------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthCommon.java b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthCommon.java index de29d9158..d9ab963ae 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthCommon.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthCommon.java @@ -42,11 +42,7 @@ public class FedauthCommon extends AbstractTest { static String azureUserName = null; static String azurePassword = null; static String azureGroupUserName = null; - static String azureAADPrincipialId = null; - static String azureAADPrincipialSecret = null; - static boolean enableADIntegrated = false; - static String spn = null; static String stsurl = null; static String fedauthClientId = null; @@ -124,8 +120,6 @@ public static void getConfigs() throws Exception { azureUserName = getConfiguredProperty("azureUserName"); azurePassword = getConfiguredProperty("azurePassword"); azureGroupUserName = getConfiguredProperty("azureGroupUserName"); - azureAADPrincipialId = getConfiguredProperty("AADSecurePrincipalId"); - azureAADPrincipialSecret = getConfiguredProperty("AADSecurePrincipalSecret"); String prop = getConfiguredProperty("enableADIntegrated"); enableADIntegrated = (null != prop && prop.equalsIgnoreCase("true")) ? true : false; diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthTest.java index 1e7531efb..2de6547d4 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthTest.java @@ -254,10 +254,11 @@ public void testCorrectAccessTokenDS() throws SQLException { * @deprecated */ @Test + @Tag(Constants.requireSecret) public void testAADServicePrincipalAuthDeprecated() { String url = "jdbc:sqlserver://" + azureServer + ";database=" + azureDatabase + ";authentication=" - + SqlAuthentication.ActiveDirectoryServicePrincipal + ";AADSecurePrincipalId=" + azureAADPrincipialId - + ";AADSecurePrincipalSecret=" + azureAADPrincipialSecret; + + SqlAuthentication.ActiveDirectoryServicePrincipal + ";AADSecurePrincipalId=" + applicationClientID + + ";AADSecurePrincipalSecret=" + applicationKey; String urlEncrypted = url + ";encrypt=true;trustServerCertificate=true;"; SQLServerDataSource ds = new SQLServerDataSource(); updateDataSource(url, ds); @@ -276,10 +277,11 @@ public void testAADServicePrincipalAuthDeprecated() { * encryption. */ @Test + @Tag(Constants.requireSecret) public void testAADServicePrincipalAuth() { String url = "jdbc:sqlserver://" + azureServer + ";database=" + azureDatabase + ";authentication=" - + SqlAuthentication.ActiveDirectoryServicePrincipal + ";Username=" + azureAADPrincipialId + ";Password=" - + azureAADPrincipialSecret; + + SqlAuthentication.ActiveDirectoryServicePrincipal + ";Username=" + applicationClientID + ";Password=" + + applicationKey; String urlEncrypted = url + ";encrypt=true;trustServerCertificate=true;"; SQLServerDataSource ds = new SQLServerDataSource(); updateDataSource(url, ds); @@ -297,36 +299,36 @@ public void testAADServicePrincipalAuth() { * Test invalid connection property combinations when using AAD Service Principal Authentication. */ @Test + @Tag(Constants.requireSecret) public void testAADServicePrincipalAuthWrong() { String baseUrl = "jdbc:sqlserver://" + azureServer + ";database=" + azureDatabase + ";authentication=" + SqlAuthentication.ActiveDirectoryServicePrincipal + ";"; // Wrong AADSecurePrincipalSecret provided. - String url = baseUrl + "AADSecurePrincipalId=" + azureAADPrincipialId + ";AADSecurePrincipalSecret=wrongSecret"; + String url = baseUrl + "AADSecurePrincipalId=" + applicationClientID + ";AADSecurePrincipalSecret=wrongSecret"; validateException(url, "R_MSALExecution"); // Wrong AADSecurePrincipalId provided. - url = baseUrl + "AADSecurePrincipalId=wrongId;AADSecurePrincipalSecret=" + azureAADPrincipialSecret; + url = baseUrl + "AADSecurePrincipalId=wrongId;AADSecurePrincipalSecret=" + applicationKey; validateException(url, "R_MSALExecution"); // AADSecurePrincipalSecret/password not provided. - url = baseUrl + "AADSecurePrincipalId=" + azureAADPrincipialId; + url = baseUrl + "AADSecurePrincipalId=" + applicationClientID; validateException(url, "R_NoUserPasswordForActiveServicePrincipal"); - url = baseUrl + "Username=" + azureAADPrincipialId; + url = baseUrl + "Username=" + applicationClientID; validateException(url, "R_NoUserPasswordForActiveServicePrincipal"); // AADSecurePrincipalId/username not provided. - url = baseUrl + "AADSecurePrincipalSecret=" + azureAADPrincipialSecret; + url = baseUrl + "AADSecurePrincipalSecret=" + applicationKey; validateException(url, "R_NoUserPasswordForActiveServicePrincipal"); - url = baseUrl + "password=" + azureAADPrincipialSecret; + url = baseUrl + "password=" + applicationKey; validateException(url, "R_NoUserPasswordForActiveServicePrincipal"); // Both AADSecurePrincipalId/username and AADSecurePrincipalSecret/password not provided. validateException(baseUrl, "R_NoUserPasswordForActiveServicePrincipal"); // both username/password and AADSecurePrincipalId/AADSecurePrincipalSecret provided - url = baseUrl + "Username=" + azureAADPrincipialId + ";password=" + azureAADPrincipialSecret - + ";AADSecurePrincipalId=" + azureAADPrincipialId + ";AADSecurePrincipalSecret=" - + azureAADPrincipialSecret; + url = baseUrl + "Username=" + applicationClientID + ";password=" + applicationKey + ";AADSecurePrincipalId=" + + applicationClientID + ";AADSecurePrincipalSecret=" + applicationKey; validateException(url, "R_BothUserPasswordandDeprecated"); } From c8fecdfab12b1af3bf36b435158fb2fee26c7dcf Mon Sep 17 00:00:00 2001 From: Terry Chow Date: Thu, 20 Mar 2025 16:09:49 -0700 Subject: [PATCH 04/14] Cherry-picked: ErrorMessageTest update --- .../jdbc/fedauth/ErrorMessageTest.java | 21 +++++++++++++------ .../sqlserver/jdbc/fedauth/FedauthCommon.java | 3 +++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ErrorMessageTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ErrorMessageTest.java index 8eb8e0f67..efa35e500 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ErrorMessageTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ErrorMessageTest.java @@ -403,8 +403,11 @@ public void testADPasswordWrongPasswordWithConnectionStringUserName() throws SQL assertTrue(INVALID_EXCEPTION_MSG + ": " + e.getMessage(), e.getMessage() .contains(ERR_MSG_FAILED_AUTHENTICATE + " the user " + azureUserName + " in Active Directory (Authentication=ActiveDirectoryPassword).") - && (e.getCause().getCause().getMessage().toLowerCase().contains("invalid username or password") - || e.getCause().getCause().getMessage().contains(ERR_MSG_SIGNIN_TOO_MANY))); + && e.getCause().getCause().getMessage().toLowerCase().contains("invalid username or password") + || e.getCause().getCause().getMessage().contains(ERR_MSG_SIGNIN_TOO_MANY) + || e.getCause().getCause().getMessage().contains(ERR_FAULT_ID3342) + || e.getMessage().contains(ERR_MSG_REQUEST_THROTTLED) + || e.getMessage().contains(ERR_FAULT_AUTH_FAIL)); } } @@ -428,8 +431,11 @@ public void testADPasswordWrongPasswordWithDatasource() throws SQLException { assertTrue(INVALID_EXCEPTION_MSG + ": " + e.getMessage(), e.getMessage() .contains(ERR_MSG_FAILED_AUTHENTICATE + " the user " + azureUserName + " in Active Directory (Authentication=ActiveDirectoryPassword).") - && (e.getCause().getCause().getMessage().toLowerCase().contains("invalid username or password") - || e.getCause().getCause().getMessage().contains(ERR_MSG_SIGNIN_TOO_MANY))); + && e.getCause().getCause().getMessage().toLowerCase().contains("invalid username or password") + || e.getCause().getCause().getMessage().contains(ERR_MSG_SIGNIN_TOO_MANY) + || e.getCause().getCause().getMessage().contains(ERR_FAULT_ID3342) + || e.getMessage().contains(ERR_MSG_REQUEST_THROTTLED) + || e.getMessage().contains(ERR_FAULT_AUTH_FAIL)); } } @@ -447,8 +453,11 @@ public void testADPasswordWrongPasswordWithConnectionStringUser() throws SQLExce assertTrue(INVALID_EXCEPTION_MSG + ": " + e.getMessage(), e.getMessage() .contains(ERR_MSG_FAILED_AUTHENTICATE + " the user " + azureUserName + " in Active Directory (Authentication=ActiveDirectoryPassword).") - && (e.getCause().getCause().getMessage().toLowerCase().contains("invalid username or password") - || e.getCause().getCause().getMessage().contains(ERR_MSG_SIGNIN_TOO_MANY))); + && e.getCause().getCause().getMessage().toLowerCase().contains("invalid username or password") + || e.getCause().getCause().getMessage().contains(ERR_MSG_SIGNIN_TOO_MANY) + || e.getCause().getCause().getMessage().contains(ERR_FAULT_ID3342) + || e.getMessage().contains(ERR_MSG_REQUEST_THROTTLED) + || e.getMessage().contains(ERR_FAULT_AUTH_FAIL)); } } diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthCommon.java b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthCommon.java index d9ab963ae..810baaa0f 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthCommon.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthCommon.java @@ -68,6 +68,8 @@ public class FedauthCommon extends AbstractTest { static final String ERR_MSG_HAS_CLOSED = TestResource.getResource("R_hasClosed"); static final String ERR_MSG_HAS_BEEN_CLOSED = TestResource.getResource("R_hasBeenClosed"); static final String ERR_MSG_SIGNIN_TOO_MANY = TestResource.getResource("R_signinTooManyTimes"); + static final String ERR_FAULT_ID3342 = "FaultMessage: ID3242"; + static final String ERR_FAULT_AUTH_FAIL = "FaultMessage: Authentication Failure"; static final String ERR_MSG_NOT_AUTH_AND_IS = TestUtils.R_BUNDLE .getString("R_SetAuthenticationWhenIntegratedSecurityTrue"); static final String ERR_MSG_NOT_AUTH_AND_USER_PASSWORD = TestUtils.R_BUNDLE @@ -76,6 +78,7 @@ public class FedauthCommon extends AbstractTest { static final String ERR_MSG_RESULTSET_IS_CLOSED = TestUtils.R_BUNDLE.getString("R_resultsetClosed"); static final String ERR_MSG_SOCKET_CLOSED = TestResource.getResource("R_socketClosed"); static final String ERR_TCPIP_CONNECTION = TestResource.getResource("R_tcpipConnectionToHost"); + static final String ERR_MSG_REQUEST_THROTTLED = "Request was throttled"; enum SqlAuthentication { NotSpecified, From e2339928c9a86ef4bbb684a071e7a90de066623d Mon Sep 17 00:00:00 2001 From: lilgreenbird Date: Thu, 6 Mar 2025 10:34:07 -0800 Subject: [PATCH 05/14] Update FedAuth tests to use ManagedIdentity (#2629) --- .../jdbc/fedauth/ConcurrentLoginTest.java | 2 - .../fedauth/ConnectionEncryptionTest.java | 2 - .../jdbc/fedauth/ErrorMessageTest.java | 1 - .../sqlserver/jdbc/fedauth/FedauthCommon.java | 43 +++++++++++++++++++ .../sqlserver/jdbc/fedauth/FedauthTest.java | 2 +- .../sqlserver/jdbc/fedauth/FedauthWithAE.java | 20 +++++---- .../sqlserver/testframework/AbstractTest.java | 3 ++ 7 files changed, 58 insertions(+), 15 deletions(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConcurrentLoginTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConcurrentLoginTest.java index cde66ae2e..bbce02554 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConcurrentLoginTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConcurrentLoginTest.java @@ -10,7 +10,6 @@ import java.util.Random; import java.util.concurrent.atomic.AtomicReference; -import com.microsoft.sqlserver.jdbc.TestUtils; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -23,7 +22,6 @@ @RunWith(JUnitPlatform.class) @Tag(Constants.fedAuth) -@Tag(Constants.requireSecret) public class ConcurrentLoginTest extends FedauthCommon { final AtomicReference throwableRef = new AtomicReference(); diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConnectionEncryptionTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConnectionEncryptionTest.java index 1df4e4ed2..d5dbc79f1 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConnectionEncryptionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConnectionEncryptionTest.java @@ -11,7 +11,6 @@ import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; -import java.text.MessageFormat; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -29,7 +28,6 @@ @RunWith(JUnitPlatform.class) @Tag(Constants.fedAuth) -@Tag(Constants.requireSecret) public class ConnectionEncryptionTest extends FedauthCommon { static String charTable = TestUtils.escapeSingleQuotes( diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ErrorMessageTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ErrorMessageTest.java index efa35e500..35050e201 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ErrorMessageTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ErrorMessageTest.java @@ -26,7 +26,6 @@ @RunWith(JUnitPlatform.class) @Tag(Constants.fedAuth) -@Tag(Constants.requireSecret) public class ErrorMessageTest extends FedauthCommon { String badUserName = "abc" + azureUserName; diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthCommon.java b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthCommon.java index 810baaa0f..57d3caec1 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthCommon.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthCommon.java @@ -7,6 +7,13 @@ import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.fail; +import com.azure.core.credential.AccessToken; +import com.azure.core.credential.TokenRequestContext; +import com.azure.identity.ManagedIdentityCredential; +import com.azure.identity.ManagedIdentityCredentialBuilder; +import com.microsoft.aad.msal4j.ClientCredentialFactory; +import com.microsoft.aad.msal4j.ClientCredentialParameters; +import com.microsoft.aad.msal4j.ConfidentialClientApplication; import com.microsoft.aad.msal4j.IAuthenticationResult; import com.microsoft.aad.msal4j.PublicClientApplication; import com.microsoft.aad.msal4j.UserNamePasswordParameters; @@ -150,6 +157,42 @@ public static void getConfigs() throws Exception { * */ static void getFedauthInfo() { + int retry = 0; + long interval = THROTTLE_RETRY_INTERVAL; + ManagedIdentityCredential credential = new ManagedIdentityCredentialBuilder() + .clientId(akvProviderManagedClientId).build(); + + while (retry <= THROTTLE_RETRY_COUNT) { + try { + TokenRequestContext requestContext = new TokenRequestContext() + .setScopes(Collections.singletonList(spn + "/.default")); + + AccessToken token = credential.getToken(requestContext).block(); + + if (token != null) { + secondsBeforeExpiration = TimeUnit.MILLISECONDS + .toSeconds(token.getExpiresAt().toInstant().toEpochMilli() - new Date().getTime()); + accessToken = token.getToken(); + } + + retry = THROTTLE_RETRY_COUNT + 1; + } catch (MsalThrottlingException te) { + interval = te.retryInMs(); + if (!checkForRetry(te, retry++, interval)) { + te.printStackTrace(); + fail(ERR_FAILED_FEDAUTH + "no more retries: " + te.getMessage()); + } + } catch (Exception e) { + e.printStackTrace(); + fail(ERR_FAILED_FEDAUTH + e.getMessage()); + } + } + } + + static boolean checkForRetry(Exception e, int retry, long interval) { + if (retry > THROTTLE_RETRY_COUNT) { + return false; + } try { final PublicClientApplication clientApplication = PublicClientApplication.builder(fedauthClientId) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthTest.java index 2de6547d4..c7a201649 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthTest.java @@ -17,6 +17,7 @@ import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; +import java.text.MessageFormat; import java.util.Properties; import org.junit.jupiter.api.AfterAll; @@ -36,7 +37,6 @@ @RunWith(JUnitPlatform.class) @Tag(Constants.fedAuth) -@Tag(Constants.requireSecret) public class FedauthTest extends FedauthCommon { static String charTable = TestUtils .escapeSingleQuotes(AbstractSQLGenerator.escapeIdentifier(RandomUtil.getIdentifier("JDBC_FedAuthTest"))); diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthWithAE.java b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthWithAE.java index e264b8afd..47478d2fc 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthWithAE.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthWithAE.java @@ -23,6 +23,8 @@ import org.junit.platform.runner.JUnitPlatform; import org.junit.runner.RunWith; +import com.azure.identity.ManagedIdentityCredential; +import com.azure.identity.ManagedIdentityCredentialBuilder; import com.microsoft.sqlserver.jdbc.RandomUtil; import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionAzureKeyVaultProvider; import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionJavaKeyStoreProvider; @@ -37,7 +39,6 @@ @RunWith(JUnitPlatform.class) @Tag(Constants.fedAuth) -@Tag(Constants.requireSecret) public class FedauthWithAE extends FedauthCommon { static String cmkName1 = Constants.CMK_NAME + "fedauthAE1"; @@ -283,16 +284,17 @@ private SQLServerColumnEncryptionKeyStoreProvider setupKeyStoreProvider_JKS() th private SQLServerColumnEncryptionKeyStoreProvider setupKeyStoreProvider_AKV() throws SQLServerException { SQLServerConnection.unregisterColumnEncryptionKeyStoreProviders(); - return registerAKVProvider( - new SQLServerColumnEncryptionAzureKeyVaultProvider(applicationClientID, applicationKey)); + return registerAKVProvider(); } - private SQLServerColumnEncryptionKeyStoreProvider registerAKVProvider( - SQLServerColumnEncryptionKeyStoreProvider provider) throws SQLServerException { - Map map1 = new HashMap(); - map1.put(provider.getName(), provider); - SQLServerConnection.registerColumnEncryptionKeyStoreProviders(map1); - return provider; + private SQLServerColumnEncryptionKeyStoreProvider registerAKVProvider() throws SQLServerException { + Map map = new HashMap(); + ManagedIdentityCredential credential = new ManagedIdentityCredentialBuilder() + .clientId(akvProviderManagedClientId).build(); + akvProvider = new SQLServerColumnEncryptionAzureKeyVaultProvider(credential); + map.put(Constants.AZURE_KEY_VAULT_NAME, akvProvider); + SQLServerConnection.registerColumnEncryptionKeyStoreProviders(map); + return akvProvider; } private void createCMK(String cmkName, String keyStoreName, String keyPath, Statement stmt) throws SQLException { diff --git a/src/test/java/com/microsoft/sqlserver/testframework/AbstractTest.java b/src/test/java/com/microsoft/sqlserver/testframework/AbstractTest.java index 2bacd129b..1727db4cf 100644 --- a/src/test/java/com/microsoft/sqlserver/testframework/AbstractTest.java +++ b/src/test/java/com/microsoft/sqlserver/testframework/AbstractTest.java @@ -108,6 +108,9 @@ public abstract class AbstractTest { protected static boolean isWindows = System.getProperty("os.name").startsWith("Windows"); + protected static final int THROTTLE_RETRY_COUNT = 3; // max number of throttling retries + protected static final int THROTTLE_RETRY_INTERVAL = 60000; // default throttling retry interval in ms + public static Properties properties = null; /** From bb04efafbc69efe5edd38bb3a35869d8921c6091 Mon Sep 17 00:00:00 2001 From: lilgreenbird Date: Mon, 24 Feb 2025 12:33:31 -0800 Subject: [PATCH 06/14] Re-enable AE Tests (#2611) --- ...pySendTemporalDataTypesAsStringAETest.java | 1 - .../CallableStatementTest.java | 1 - .../JDBCEncryptionDecryptionTest.java | 18 +++---- .../jdbc/AlwaysEncrypted/MSITest.java | 20 +++++++- .../AlwaysEncrypted/MultiUserAKVTest.java | 48 +++++-------------- .../AlwaysEncrypted/PrecisionScaleTest.java | 1 - .../RegressionAlwaysEncryptedTest.java | 1 - .../sqlserver/jdbc/EnclavePackageTest.java | 1 - .../sqlserver/testframework/AbstractTest.java | 19 +++++++- 9 files changed, 56 insertions(+), 54 deletions(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/BulkCopySendTemporalDataTypesAsStringAETest.java b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/BulkCopySendTemporalDataTypesAsStringAETest.java index 47f717f54..6dd177ab5 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/BulkCopySendTemporalDataTypesAsStringAETest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/BulkCopySendTemporalDataTypesAsStringAETest.java @@ -58,7 +58,6 @@ @Tag(Constants.xAzureSQLDB) @Tag(Constants.xAzureSQLDW) @Tag(Constants.reqExternalSetup) -@Tag(Constants.requireSecret) public class BulkCopySendTemporalDataTypesAsStringAETest extends AESetup { static String inputFile = "BulkCopyCSVSendTemporalDataTypesAsStringForBulkCopy.csv"; static String encoding = "UTF-8"; diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/CallableStatementTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/CallableStatementTest.java index 0ddf791fa..0b9f0a4f0 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/CallableStatementTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/CallableStatementTest.java @@ -52,7 +52,6 @@ @Tag(Constants.xAzureSQLDW) @Tag(Constants.xAzureSQLDB) @Tag(Constants.reqExternalSetup) -@Tag(Constants.requireSecret) public class CallableStatementTest extends AESetup { private static String multiStatementsProcedure = AbstractSQLGenerator diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/JDBCEncryptionDecryptionTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/JDBCEncryptionDecryptionTest.java index bad811a20..e54011872 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/JDBCEncryptionDecryptionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/JDBCEncryptionDecryptionTest.java @@ -29,10 +29,6 @@ import com.azure.identity.ClientSecretCredentialBuilder; import java.util.Set; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; - import org.junit.jupiter.api.Tag; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -65,7 +61,6 @@ @Tag(Constants.xAzureSQLDW) @Tag(Constants.xAzureSQLDB) @Tag(Constants.reqExternalSetup) -@Tag(Constants.requireSecret) public class JDBCEncryptionDecryptionTest extends AESetup { private boolean nullable = false; @@ -107,8 +102,7 @@ public void testJksName(String serverName, String url, String protocol) throws E public void testAkvName(String serverName, String url, String protocol) throws Exception { setAEConnectionString(serverName, url, protocol); - SQLServerColumnEncryptionAzureKeyVaultProvider akv = new SQLServerColumnEncryptionAzureKeyVaultProvider( - applicationClientID, applicationKey); + SQLServerColumnEncryptionAzureKeyVaultProvider akv = akvProvider; String keystoreName = "keystoreName"; akv.setName(keystoreName); assertTrue(akv.getName().equals(keystoreName), "AKV name: " + akv.getName() + " keystoreName: " + keystoreName); @@ -138,6 +132,7 @@ public void testBadJks(String serverName, String url, String protocol) throws Ex @SuppressWarnings("unused") @ParameterizedTest @MethodSource("enclaveParams") + @Tag(Constants.requireSecret) public void testBadAkvCallback(String serverName, String url, String protocol) throws Exception { setAEConnectionString(serverName, url, protocol); @@ -211,8 +206,7 @@ public void testJksBadEncryptColumnEncryptionKey(String serverName, String url, public void testAkvBadEncryptColumnEncryptionKey(String serverName, String url, String protocol) throws Exception { setAEConnectionString(serverName, url, protocol); - SQLServerColumnEncryptionAzureKeyVaultProvider akv = null; - akv = new SQLServerColumnEncryptionAzureKeyVaultProvider(applicationClientID, applicationKey); + SQLServerColumnEncryptionAzureKeyVaultProvider akv = akvProvider; // null encryptedColumnEncryptionKey try { @@ -290,8 +284,7 @@ public void testJksDecryptColumnEncryptionKey(String serverName, String url, Str public void testAkvDecryptColumnEncryptionKey(String serverName, String url, String protocol) throws Exception { setAEConnectionString(serverName, url, protocol); - SQLServerColumnEncryptionAzureKeyVaultProvider akv = null; - akv = new SQLServerColumnEncryptionAzureKeyVaultProvider(applicationClientID, applicationKey); + SQLServerColumnEncryptionAzureKeyVaultProvider akv = akvProvider; // null akvpath try { @@ -2270,6 +2263,7 @@ void testNumerics(SQLServerStatement stmt, String cekName, String[][] table, Str @ParameterizedTest @MethodSource("enclaveParams") @Tag(Constants.reqExternalSetup) + @Tag(Constants.requireSecret) public void testAkvNameWithAuthCallback(String serverName, String url, String protocol) throws Exception { setAEConnectionString(serverName, url, protocol); @@ -2288,6 +2282,7 @@ public void testAkvNameWithAuthCallback(String serverName, String url, String pr @ParameterizedTest @MethodSource("enclaveParams") @Tag(Constants.reqExternalSetup) + @Tag(Constants.requireSecret) public void testAkvNameWithTokenCredential(String serverName, String url, String protocol) throws Exception { setAEConnectionString(serverName, url, protocol); @@ -2309,6 +2304,7 @@ public void testAkvNameWithTokenCredential(String serverName, String url, String @ParameterizedTest @MethodSource("enclaveParams") @Tag(Constants.reqExternalSetup) + @Tag(Constants.requireSecret) public void testAkvBadEncryptColumnEncryptionKeyWithAuthCallback(String serverName, String url, String protocol) throws Exception { setAEConnectionString(serverName, url, protocol); diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/MSITest.java b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/MSITest.java index dc98d33d8..5a35e9cb3 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/MSITest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/MSITest.java @@ -18,6 +18,10 @@ import java.util.Map; import java.util.Properties; +import com.azure.identity.CredentialUnavailableException; +import com.azure.identity.ManagedIdentityCredential; +import com.azure.identity.ManagedIdentityCredentialBuilder; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -43,7 +47,6 @@ */ @RunWith(JUnitPlatform.class) @Tag(Constants.MSI) -@Tag(Constants.requireSecret) public class MSITest extends AESetup { /* @@ -366,11 +369,20 @@ private void testNumericAKV(String connStr) throws SQLException { @BeforeEach public void registerAKVProvider() throws Exception { + try { // unregister the custom providers registered in AESetup SQLServerConnection.unregisterColumnEncryptionKeyStoreProviders(); Map map = new HashMap(); - if (null != applicationClientID && null != applicationKey) { + if (null != akvProviderManagedClientId) { + System.out.println("ManagedIdentityCredential: registering akvProvider"); + + ManagedIdentityCredential credential = new ManagedIdentityCredentialBuilder() + .clientId(akvProviderManagedClientId).build(); + akvProvider = new SQLServerColumnEncryptionAzureKeyVaultProvider(credential); + map.put(Constants.AZURE_KEY_VAULT_NAME, akvProvider); + System.out.println("ManagedIdentityCredential: registered akvProvider"); + } else if (null != applicationClientID && null != applicationKey) { File file = null; try { file = new File(Constants.MSSQL_JDBC_PROPERTIES); @@ -387,8 +399,12 @@ public void registerAKVProvider() throws Exception { file.delete(); } } + System.out.println("applicationClientID: registered akvProvider"); } SQLServerConnection.registerColumnEncryptionKeyStoreProviders(map); + } catch (Exception e) { + System.out.println("MSITest registerAKVProvider exception: " +e.getMessage()); + } } } diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/MultiUserAKVTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/MultiUserAKVTest.java index eb42d9ebb..3852b606e 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/MultiUserAKVTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/MultiUserAKVTest.java @@ -35,6 +35,8 @@ import org.junit.platform.runner.JUnitPlatform; import org.junit.runner.RunWith; +import com.azure.identity.ManagedIdentityCredential; +import com.azure.identity.ManagedIdentityCredentialBuilder; import com.microsoft.sqlserver.jdbc.RandomUtil; import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionAzureKeyVaultProvider; import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionKeyStoreProvider; @@ -59,7 +61,6 @@ @Tag(Constants.xAzureSQLDW) @Tag(Constants.xAzureSQLDB) @Tag(Constants.reqExternalSetup) -@Tag(Constants.requireSecret) public class MultiUserAKVTest extends AESetup { private static Map requiredKeyStoreProvider = new HashMap<>(); @@ -101,7 +102,7 @@ public static void testCleanUp() throws Exception { tempMap.put(Constants.CUSTOM_KEYSTORE_NAME, jksProvider); } - if (null != akvProvider && null != applicationClientID && null != applicationKey) { + if (null != akvProvider) { tempMap.put(Constants.AZURE_KEY_VAULT_NAME, akvProvider); } @@ -113,7 +114,7 @@ public static void testCleanUp() throws Exception { @Test @Tag(Constants.reqExternalSetup) public void decryptedCekIsCachedDuringDecryption() throws Exception { - SQLServerColumnEncryptionAzureKeyVaultProvider provider = createAKVProvider(); + SQLServerColumnEncryptionAzureKeyVaultProvider provider = akvProvider; if (null == provider) { fail(TestResource.getResource("R_AKVProviderNull")); @@ -153,8 +154,9 @@ public void decryptedCekIsCachedDuringDecryption() throws Exception { @Test @Tag(Constants.reqExternalSetup) + @Tag(Constants.requireSecret) public void signatureVerificationResultIsCachedDuringVerification() throws Exception { - SQLServerColumnEncryptionAzureKeyVaultProvider provider = createAKVProvider(); + SQLServerColumnEncryptionAzureKeyVaultProvider provider = akvProvider; if (provider == null) { fail(TestResource.getResource("R_AKVProviderNull")); @@ -186,7 +188,7 @@ public void signatureVerificationResultIsCachedDuringVerification() throws Excep @Test @Tag(Constants.reqExternalSetup) public void cekCacheEntryIsEvictedAfterTtlExpires() throws Exception { - SQLServerColumnEncryptionAzureKeyVaultProvider provider = createAKVProvider(); + SQLServerColumnEncryptionAzureKeyVaultProvider provider = akvProvider; if (provider == null) { fail(TestResource.getResource("R_AKVProviderNull")); @@ -214,7 +216,7 @@ public void cekCacheEntryIsEvictedAfterTtlExpires() throws Exception { @Test @Tag(Constants.reqExternalSetup) public void cekCacheShouldBeDisabledWhenAkvProviderIsRegisteredGlobally() throws Exception { - SQLServerColumnEncryptionAzureKeyVaultProvider provider = createAKVProvider(); + SQLServerColumnEncryptionAzureKeyVaultProvider provider = akvProvider; if (provider == null) { fail(TestResource.getResource("R_AKVProviderNull")); @@ -258,8 +260,9 @@ public void cekCacheShouldBeDisabledWhenAkvProviderIsRegisteredGlobally() throws @Test @Tag(Constants.reqExternalSetup) + @Tag(Constants.requireSecret) public void testLocalCekCacheIsScopedToProvider() throws Exception { - SQLServerColumnEncryptionAzureKeyVaultProvider provider = createAKVProvider(); + SQLServerColumnEncryptionAzureKeyVaultProvider provider = akvProvider; if (provider == null) { fail(TestResource.getResource("R_AKVProviderNull")); @@ -270,6 +273,8 @@ public void testLocalCekCacheIsScopedToProvider() throws Exception { fail((new MessageFormat(TestResource.getResource("R_objectNullOrEmpty"))).format(msgArg)); } + SQLServerConnection.unregisterColumnEncryptionKeyStoreProviders(); + SQLServerConnection.unregisterColumnEncryptionKeyStoreProviders(); Map providerMap = new HashMap(); providerMap.put(Constants.AZURE_KEY_VAULT_NAME, akvProvider); @@ -327,7 +332,7 @@ public void testLocalCekCacheIsScopedToProvider() throws Exception { } fail(TestResource.getResource("R_expectedExceptionNotThrown")); } catch (SQLServerException ex) { - assertTrue(ex.getMessage().contains("AADSTS700016")); + org.junit.jupiter.api.Assertions.assertTrue(ex.getMessage().contains("AADSTS700016"), ex.getMessage()); } } finally { dropObject(AETestConnectionString, "TABLE", customProviderTableName); @@ -610,31 +615,4 @@ private int getCacheSize(String methodName, return (int) method.invoke(provider); } - - private SQLServerColumnEncryptionAzureKeyVaultProvider createAKVProvider() throws Exception { - - SQLServerColumnEncryptionAzureKeyVaultProvider azureKeyVaultProvider = null; - - if (null != applicationClientID && null != applicationKey) { - File file = null; - try { - file = new File(Constants.MSSQL_JDBC_PROPERTIES); - try (OutputStream os = new FileOutputStream(file);) { - Properties props = new Properties(); - // Append to the list of hardcoded endpoints - props.setProperty(Constants.AKV_TRUSTED_ENDPOINTS_KEYWORD, ";vault.azure.net"); - props.store(os, ""); - } - azureKeyVaultProvider = new SQLServerColumnEncryptionAzureKeyVaultProvider(applicationClientID, - applicationKey); - - } finally { - if (null != file) { - file.delete(); - } - } - } - - return azureKeyVaultProvider; - } } diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/PrecisionScaleTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/PrecisionScaleTest.java index dcbe907b5..162fe8cef 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/PrecisionScaleTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/PrecisionScaleTest.java @@ -43,7 +43,6 @@ @Tag(Constants.xAzureSQLDW) @Tag(Constants.xAzureSQLDB) @Tag(Constants.reqExternalSetup) -@Tag(Constants.requireSecret) public class PrecisionScaleTest extends AESetup { private static java.util.Date date = null; private static int offsetFromGMT = 0; diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/RegressionAlwaysEncryptedTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/RegressionAlwaysEncryptedTest.java index 793835e78..1644bfc59 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/RegressionAlwaysEncryptedTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/RegressionAlwaysEncryptedTest.java @@ -30,7 +30,6 @@ @Tag(Constants.xAzureSQLDW) @Tag(Constants.xAzureSQLDB) @Tag(Constants.reqExternalSetup) -@Tag(Constants.requireSecret) public class RegressionAlwaysEncryptedTest extends AESetup { static String numericTable[][] = {{"Bit", "bit"}, {"Tinyint", "tinyint"}, {"Smallint", "smallint"},}; diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/EnclavePackageTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/EnclavePackageTest.java index b6509c500..ffcb80b7f 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/EnclavePackageTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/EnclavePackageTest.java @@ -33,7 +33,6 @@ @Tag(Constants.xAzureSQLDW) @Tag(Constants.xAzureSQLDB) @Tag(Constants.reqExternalSetup) -@Tag(Constants.requireSecret) public class EnclavePackageTest extends AbstractTest { private static String connectionStringEnclave = null; diff --git a/src/test/java/com/microsoft/sqlserver/testframework/AbstractTest.java b/src/test/java/com/microsoft/sqlserver/testframework/AbstractTest.java index 1727db4cf..b290d979d 100644 --- a/src/test/java/com/microsoft/sqlserver/testframework/AbstractTest.java +++ b/src/test/java/com/microsoft/sqlserver/testframework/AbstractTest.java @@ -32,6 +32,14 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; +<<<<<<< HEAD +======= +import com.azure.identity.ClientSecretCredential; +import com.azure.identity.ClientSecretCredentialBuilder; +import com.azure.identity.ManagedIdentityCredential; +import com.azure.identity.ManagedIdentityCredentialBuilder; +import com.microsoft.aad.msal4j.ConfidentialClientApplication; +>>>>>>> c01814b5 (Re-enable AE Tests (#2611)) import com.microsoft.sqlserver.jdbc.ISQLServerDataSource; import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionAzureKeyVaultProvider; import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionJavaKeyStoreProvider; @@ -60,6 +68,7 @@ public abstract class AbstractTest { protected static String applicationKey = null; protected static String tenantID; protected static String[] keyIDs = null; + protected static String akvProviderManagedClientId = null; protected static String[] enclaveServer = null; protected static String[] enclaveAttestationUrl = null; @@ -136,6 +145,9 @@ public static void setup() throws Exception { applicationClientID = getConfiguredProperty("applicationClientID"); applicationKey = getConfiguredProperty("applicationKey"); + + akvProviderManagedClientId = getConfiguredProperty("akvProviderManagedClientId"); + tenantID = getConfiguredProperty("tenantID"); trustServerCertificate = getConfiguredProperty("trustServerCertificate", "true"); @@ -180,7 +192,12 @@ public static void setup() throws Exception { map.put(Constants.CUSTOM_KEYSTORE_NAME, jksProvider); } - if (null == akvProvider && null != applicationClientID && null != applicationKey) { + if (null == akvProvider && null != akvProviderManagedClientId) { + ManagedIdentityCredential credential = new ManagedIdentityCredentialBuilder() + .clientId(akvProviderManagedClientId).build(); + akvProvider = new SQLServerColumnEncryptionAzureKeyVaultProvider(credential); + map.put(Constants.AZURE_KEY_VAULT_NAME, akvProvider); + } else if (null == akvProvider && null != applicationClientID && null != applicationKey) { File file = null; try { file = new File(Constants.MSSQL_JDBC_PROPERTIES); From 7ec5a252ba71d25b37c97d6ea03a6dd25c9f1370 Mon Sep 17 00:00:00 2001 From: Terry Chow Date: Thu, 20 Mar 2025 16:34:16 -0700 Subject: [PATCH 07/14] Added error string to TestResource --- src/test/java/com/microsoft/sqlserver/jdbc/TestResource.java | 1 + .../com/microsoft/sqlserver/jdbc/fedauth/FedauthCommon.java | 2 ++ .../com/microsoft/sqlserver/testframework/AbstractTest.java | 3 --- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/TestResource.java b/src/test/java/com/microsoft/sqlserver/jdbc/TestResource.java index dd664bc72..80db9a7b6 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/TestResource.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/TestResource.java @@ -199,6 +199,7 @@ protected Object[][] getContents() { {"R_AKVProviderNull", "The Azure key store provider is null."}, {"R_objectNullOrEmpty", "The {0} is null or empty."}, {"R_cekDecryptionFailed", "Failed to decrypt a column encryption key using key store provider: {0}."}, + {"R_failedFedauth", "Failed to acquire fedauth token: "}, {"R_connectTimedOut", "connect timed out"}, {"R_queryCanceled", "The query was canceled."}, {"R_sessionKilled", "Cannot continue the execution because the session is in the kill state"}}; diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthCommon.java b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthCommon.java index 57d3caec1..7d6e9a52c 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthCommon.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthCommon.java @@ -15,6 +15,7 @@ import com.microsoft.aad.msal4j.ClientCredentialParameters; import com.microsoft.aad.msal4j.ConfidentialClientApplication; import com.microsoft.aad.msal4j.IAuthenticationResult; +import com.microsoft.aad.msal4j.MsalThrottlingException; import com.microsoft.aad.msal4j.PublicClientApplication; import com.microsoft.aad.msal4j.UserNamePasswordParameters; import java.sql.Connection; @@ -86,6 +87,7 @@ public class FedauthCommon extends AbstractTest { static final String ERR_MSG_SOCKET_CLOSED = TestResource.getResource("R_socketClosed"); static final String ERR_TCPIP_CONNECTION = TestResource.getResource("R_tcpipConnectionToHost"); static final String ERR_MSG_REQUEST_THROTTLED = "Request was throttled"; + static final String ERR_FAILED_FEDAUTH = TestResource.getResource("R_failedFedauth"); enum SqlAuthentication { NotSpecified, diff --git a/src/test/java/com/microsoft/sqlserver/testframework/AbstractTest.java b/src/test/java/com/microsoft/sqlserver/testframework/AbstractTest.java index b290d979d..9df82e517 100644 --- a/src/test/java/com/microsoft/sqlserver/testframework/AbstractTest.java +++ b/src/test/java/com/microsoft/sqlserver/testframework/AbstractTest.java @@ -32,14 +32,11 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; -<<<<<<< HEAD -======= import com.azure.identity.ClientSecretCredential; import com.azure.identity.ClientSecretCredentialBuilder; import com.azure.identity.ManagedIdentityCredential; import com.azure.identity.ManagedIdentityCredentialBuilder; import com.microsoft.aad.msal4j.ConfidentialClientApplication; ->>>>>>> c01814b5 (Re-enable AE Tests (#2611)) import com.microsoft.sqlserver.jdbc.ISQLServerDataSource; import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionAzureKeyVaultProvider; import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionJavaKeyStoreProvider; From df2b471ff54a7531d8af2e1514a2bfc53ee0c749 Mon Sep 17 00:00:00 2001 From: Terry Chow Date: Thu, 20 Mar 2025 16:40:13 -0700 Subject: [PATCH 08/14] Test fixes --- .../jdbc/fedauth/ConcurrentLoginTest.java | 1 + .../jdbc/fedauth/ConnectionEncryptionTest.java | 1 + .../sqlserver/jdbc/fedauth/FedauthCommon.java | 18 +++++------------- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConcurrentLoginTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConcurrentLoginTest.java index bbce02554..6b8509978 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConcurrentLoginTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConcurrentLoginTest.java @@ -10,6 +10,7 @@ import java.util.Random; import java.util.concurrent.atomic.AtomicReference; +import com.microsoft.sqlserver.jdbc.TestUtils; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConnectionEncryptionTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConnectionEncryptionTest.java index d5dbc79f1..1904ff69d 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConnectionEncryptionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConnectionEncryptionTest.java @@ -11,6 +11,7 @@ import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; +import java.text.MessageFormat; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthCommon.java b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthCommon.java index 7d6e9a52c..d9b3be8c3 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthCommon.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthCommon.java @@ -196,21 +196,13 @@ static boolean checkForRetry(Exception e, int retry, long interval) { return false; } try { + Thread.sleep(interval); + } catch (InterruptedException ex) { + e.printStackTrace(); - final PublicClientApplication clientApplication = PublicClientApplication.builder(fedauthClientId) - .executorService(Executors.newFixedThreadPool(1)).authority(stsurl).build(); - final CompletableFuture future = clientApplication - .acquireToken(UserNamePasswordParameters.builder(Collections.singleton(spn + "/.default"), - azureUserName, azurePassword.toCharArray()).build()); - - final IAuthenticationResult authenticationResult = future.get(); - - secondsBeforeExpiration = TimeUnit.MILLISECONDS - .toSeconds(authenticationResult.expiresOnDate().getTime() - new Date().getTime()); - accessToken = authenticationResult.accessToken(); - } catch (Exception e) { - fail(e.getMessage()); + fail(ERR_FAILED_FEDAUTH + ex.getMessage()); } + return true; } void testUserName(Connection conn, String user, SqlAuthentication authentication) throws SQLException { From c75eb22fc46f1be152492b94bab68a8cfff5dba1 Mon Sep 17 00:00:00 2001 From: Terry Chow Date: Thu, 20 Mar 2025 17:45:37 -0700 Subject: [PATCH 09/14] Test fixes p2 --- .../jdbc/resiliency/BasicConnectionTest.java | 39 +++++++-- .../jdbc/resiliency/ReflectiveTests.java | 7 +- .../ResultSetsWithResiliencyTest.java | 87 ------------------- 3 files changed, 36 insertions(+), 97 deletions(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/resiliency/BasicConnectionTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/resiliency/BasicConnectionTest.java index 3a6c7dd08..6204ec61c 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/resiliency/BasicConnectionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/resiliency/BasicConnectionTest.java @@ -49,15 +49,36 @@ public void testBasicReconnectDefault() throws SQLException { } @Test - public void testBasicConnectionAAD() throws SQLException { - String azureServer = getConfiguredProperty("azureServer"); - String azureDatabase = getConfiguredProperty("azureDatabase"); - String azureUserName = getConfiguredProperty("azureUserName"); - String azurePassword = getConfiguredProperty("azurePassword"); - org.junit.Assume.assumeTrue(azureServer != null && !azureServer.isEmpty()); - - basicReconnect("jdbc:sqlserver://" + azureServer + ";database=" + azureDatabase + ";user=" + azureUserName - + ";password=" + azurePassword + ";loginTimeout=30;Authentication=ActiveDirectoryPassword"); + @Tag(Constants.fedAuth) + public void testBasicConnectionAAD() throws Exception { + // retry since this could fail due to server throttling + int retry = 1; + while (retry <= THROTTLE_RETRY_COUNT) { + try { + String azureServer = getConfiguredProperty("azureServer"); + String azureDatabase = getConfiguredProperty("azureDatabase"); + String azureUserName = getConfiguredProperty("azureUserName"); + String azurePassword = getConfiguredProperty("azurePassword"); + org.junit.Assume.assumeTrue(azureServer != null && !azureServer.isEmpty()); + + basicReconnect("jdbc:sqlserver://" + azureServer + ";database=" + azureDatabase + ";user=" + + azureUserName + ";password=" + azurePassword + + ";loginTimeout=90;Authentication=ActiveDirectoryPassword"); + retry = THROTTLE_RETRY_COUNT + 1; + } catch (Exception e) { + if (e.getMessage().matches(TestUtils.formatErrorMsg("R_crClientAllRecoveryAttemptsFailed"))) { + System.out.println(e.getMessage() + ". Recovery failed, retry #" + retry + " in " + + THROTTLE_RETRY_INTERVAL + " ms"); + + Thread.sleep(THROTTLE_RETRY_INTERVAL); + retry++; + } else { + e.printStackTrace(); + + fail(e.getMessage()); + } + } + } } @Test diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/resiliency/ReflectiveTests.java b/src/test/java/com/microsoft/sqlserver/jdbc/resiliency/ReflectiveTests.java index e2206deb9..c08f42275 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/resiliency/ReflectiveTests.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/resiliency/ReflectiveTests.java @@ -77,12 +77,17 @@ public void testDefaultTimeout() throws SQLException { } /* - * Default retry count is 1. Expect timeout to be just above login timeout. + * Default retry count is 1 (for non-Azure). Expect timeout to be just above login timeout. */ @Test + @Tag(Constants.xAzureSQLDB) + @Tag(Constants.xAzureSQLDW) public void testDefaultRetry() throws SQLException { Map m = new HashMap<>(); m.put("loginTimeout", "5"); + + // ensure count is not set to something else as this test assumes exactly just 1 retry + // this is only true for non-Azure as retry counts gets auto changed for Azure servers timeoutVariations(m, 6000, Optional.empty()); } diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/resiliency/ResultSetsWithResiliencyTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/resiliency/ResultSetsWithResiliencyTest.java index 1147cbe79..663f9d599 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/resiliency/ResultSetsWithResiliencyTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/resiliency/ResultSetsWithResiliencyTest.java @@ -167,93 +167,6 @@ public void testAdaptiveBufferingWithPartiallyBufferedResultSet() throws SQLExce } } - /* - * Test killing a session while retrieving result set should result in exception thrown - */ - @Test - public void testKillSession() throws Exception { - // setup test with big tables - String table1 = AbstractSQLGenerator.escapeIdentifier(RandomUtil.getIdentifier("killSessionTestTable1")); - String table2 = AbstractSQLGenerator.escapeIdentifier(RandomUtil.getIdentifier("killSessionTestTable2")); - String table3 = AbstractSQLGenerator.escapeIdentifier(RandomUtil.getIdentifier("killSessionTestTable3")); - - try (Connection c = DriverManager.getConnection(connectionString); Statement s = c.createStatement(); - PreparedStatement ps1 = c.prepareStatement("INSERT INTO " + table1 + " values (?)"); - PreparedStatement ps2 = c.prepareStatement("INSERT INTO " + table2 + " values (?)"); - PreparedStatement ps3 = c.prepareStatement("INSERT INTO " + table3 + " values (?)")) { - TestUtils.dropTableIfExists(table1, s); - TestUtils.dropTableIfExists(table2, s); - TestUtils.dropTableIfExists(table3, s); - s.execute("CREATE TABLE " + table1 - + " (ID int primary key IDENTITY(1,1) NOT NULL, NAME varchar(255) NOT NULL); CREATE TABLE " + table2 - + " (ID int primary key IDENTITY(1,1) NOT NULL, NAME varchar(255) NOT NULL); CREATE TABLE " + table3 - + "( ID int primary key IDENTITY(1,1) NOT NULL, NAME varchar(255) NOT NULL);"); - - for (int i = 0; i < 1000; i++) { - ps1.setString(1, "value" + i); - ps2.setString(1, "value" + i); - ps3.setString(1, "value" + i); - - ps1.addBatch(); - ps2.addBatch(); - ps3.addBatch(); - } - - ps1.executeBatch(); - ps2.executeBatch(); - ps3.executeBatch(); - - c.commit(); - - try (Connection c2 = DriverManager.getConnection(connectionString)) { - int sessionId = ResiliencyUtils.getSessionId(c2); - - Runnable r1 = () -> { - try { - ResiliencyUtils.killConnection(sessionId, connectionString, c2, 10); - } catch (Exception e) { - fail(e.getMessage());; - } - }; - - Thread t1 = new Thread(r1); - t1.start(); - - // execute query which takes a long time and kill session in another thread - try (PreparedStatement ps = c2.prepareStatement("SELECT e1.* FROM " + table1 + " e1, " + table2 - + " e2, " + table3 + " e3, " + table1 - + " e4 where e1.name = 'abc' or e2.name = 'def'or e3.name = 'ghi' or e4.name = 'xxx' and e1.name not in (select name FROM " - + table2 + ") and e2.name not in (select name FROM " + table1 - + " ) and e3.name not in (SELECT name FROM " + table2 - + ") and e4.name not in (SELECT name FROM " + table3 + ");"); - ResultSet rs = ps.executeQuery()) { - - fail(TestResource.getResource("R_expectedExceptionNotThrown")); - } catch (SQLException e) { - // may get different error message depending on SQL servers. - // Local servers will report a TDS error where as Azure servers will have a DONE error - if (!(e.getMessage().matches(TestUtils.formatErrorMsg("R_serverError")) - || e.getMessage().contains(TestResource.getResource("R_sessionKilled")) - || e.getMessage().contains(TestResource.getResource("R_connectionReset")))) { - e.printStackTrace(); - } - - assertTrue( - e.getMessage().matches(TestUtils.formatErrorMsg("R_serverError")) - || e.getMessage().contains(TestResource.getResource("R_sessionKilled")) - || e.getMessage().contains(TestResource.getResource("R_connectionReset")), - e.getMessage()); - } - t1.join(); - - } finally { - TestUtils.dropTableIfExists(table1, s); - TestUtils.dropTableIfExists(table2, s); - TestUtils.dropTableIfExists(table3, s); - } - } - } - @Test public void testResultSetClientCursorInitializerOnDone() throws SQLException { try (Connection con = ResiliencyUtils.getConnection(connectionString); Statement stmt = con.createStatement()) { From 80e4d1ae5f7bf1c403c68cae45bc3526198fcfb9 Mon Sep 17 00:00:00 2001 From: Terry Chow Date: Fri, 21 Mar 2025 10:01:11 -0700 Subject: [PATCH 10/14] Test fixes p3 --- .../sqlserver/jdbc/AlwaysEncrypted/AESetup.java | 17 +++++++++++++---- .../jdbc/resiliency/ReflectiveTests.java | 2 +- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/AESetup.java b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/AESetup.java index dbd270451..f7d623aab 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/AESetup.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/AESetup.java @@ -177,17 +177,26 @@ static void setAEConnectionString(String serverName, String url, String protocol if (!isSqlLinux() && null != serverName && null != url && null != protocol) { enclaveProperties = "serverName=" + serverName + ";" + Constants.ENCLAVE_ATTESTATIONURL + "=" + url + ";" + Constants.ENCLAVE_ATTESTATIONPROTOCOL + "=" + protocol; - AETestConnectionString = connectionString + ";sendTimeAsDateTime=false" + ";columnEncryptionSetting=enabled" - + ";" + enclaveProperties; + AETestConnectionString = connectionString + ";sendTimeAsDateTime=false;columnEncryptionSetting=enabled;" + + enclaveProperties; // show progress if testing multiple servers if (enclaveServer.length > 1) { System.out.println("Testing enclave: " + enclaveProperties); } + + // remove the password in connection string + // this is necessary as updateDataSource will only use 1st occurrence + String password = getConfiguredProperty("enclaveServerPassword"); + AETestConnectionString = TestUtils.removeProperty(AETestConnectionString, Constants.PASSWORD); + AETestConnectionString = TestUtils.addOrOverrideProperty(AETestConnectionString, Constants.PASSWORD, + password); } else { - AETestConnectionString = connectionString + ";sendTimeAsDateTime=false" - + ";columnEncryptionSetting=enabled"; + AETestConnectionString = connectionString + ";sendTimeAsDateTime=false;columnEncryptionSetting=enabled;"; } + + // TODO: update AE test servers to support + AETestConnectionString += ";encrypt=false;trustServerCertificate=true;"; } @BeforeAll diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/resiliency/ReflectiveTests.java b/src/test/java/com/microsoft/sqlserver/jdbc/resiliency/ReflectiveTests.java index c08f42275..f204df76a 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/resiliency/ReflectiveTests.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/resiliency/ReflectiveTests.java @@ -88,7 +88,7 @@ public void testDefaultRetry() throws SQLException { // ensure count is not set to something else as this test assumes exactly just 1 retry // this is only true for non-Azure as retry counts gets auto changed for Azure servers - timeoutVariations(m, 6000, Optional.empty()); + timeoutVariations(m, 15000, Optional.empty()); } /* From 18b9e6b9656b8b38ff4d5a074789dfe6e86fdd71 Mon Sep 17 00:00:00 2001 From: Terry Chow Date: Fri, 21 Mar 2025 10:33:03 -0700 Subject: [PATCH 11/14] Test fixes p4: Update tests to run with ManagedIdentity --- .../jdbc/SQLServerConnectionTest.java | 29 ++++- .../jdbc/connection/TimeoutTest.java | 101 ++++++++++-------- .../sqlserver/jdbc/fips/FipsTest.java | 14 ++- .../jdbc/unit/SQLServerErrorTest.java | 5 + 4 files changed, 102 insertions(+), 47 deletions(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/SQLServerConnectionTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/SQLServerConnectionTest.java index 5330d3db0..d1b2e7177 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/SQLServerConnectionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/SQLServerConnectionTest.java @@ -644,13 +644,22 @@ public void testIncorrectDatabase() throws SQLException { assertTrue(timeDiff <= milsecs, form.format(msgArgs)); } } catch (Exception e) { - assertTrue(e.getMessage().contains(TestResource.getResource("R_cannotOpenDatabase"))); + assertTrue( + e.getMessage().contains(TestResource.getResource("R_cannotOpenDatabase")) + || (TestUtils.getProperty(connectionString, "msiClientId") != null + && e.getMessage().toLowerCase() + .contains(TestResource.getResource("R_loginFailedMI").toLowerCase())), + e.getMessage()); timerEnd = System.currentTimeMillis(); } } @Test public void testIncorrectUserName() throws SQLException { + String auth = TestUtils.getProperty(connectionString, "authentication"); + org.junit.Assume.assumeTrue(auth != null + && (auth.equalsIgnoreCase("SqlPassword") || auth.equalsIgnoreCase("ActiveDirectoryPassword"))); + long timerStart = 0; long timerEnd = 0; final long milsecs = threshHoldForNoRetryInMilliseconds; @@ -668,13 +677,22 @@ public void testIncorrectUserName() throws SQLException { assertTrue(timeDiff <= milsecs, form.format(msgArgs)); } } catch (Exception e) { - assertTrue(e.getMessage().contains(TestResource.getResource("R_loginFailed"))); + assertTrue( + e.getMessage().contains(TestResource.getResource("R_loginFailed")) + || (TestUtils.getProperty(connectionString, "msiClientId") != null + && e.getMessage().toLowerCase() + .contains(TestResource.getResource("R_loginFailedMI").toLowerCase())), + e.getMessage()); timerEnd = System.currentTimeMillis(); } } @Test public void testIncorrectPassword() throws SQLException { + String auth = TestUtils.getProperty(connectionString, "authentication"); + org.junit.Assume.assumeTrue(auth != null + && (auth.equalsIgnoreCase("SqlPassword") || auth.equalsIgnoreCase("ActiveDirectoryPassword"))); + long timerStart = 0; long timerEnd = 0; final long milsecs = threshHoldForNoRetryInMilliseconds; @@ -692,7 +710,12 @@ public void testIncorrectPassword() throws SQLException { assertTrue(timeDiff <= milsecs, form.format(msgArgs)); } } catch (Exception e) { - assertTrue(e.getMessage().contains(TestResource.getResource("R_loginFailed"))); + assertTrue( + e.getMessage().contains(TestResource.getResource("R_loginFailed")) + || (TestUtils.getProperty(connectionString, "msiClientId") != null + && e.getMessage().toLowerCase() + .contains(TestResource.getResource("R_loginFailedMI").toLowerCase())), + e.getMessage()); timerEnd = System.currentTimeMillis(); } } diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/connection/TimeoutTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/connection/TimeoutTest.java index ba084cb8f..0cd898bff 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/connection/TimeoutTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/connection/TimeoutTest.java @@ -168,87 +168,104 @@ public void testConnectRetryBadServer() { // Test connect retry for database error @Test public void testConnectRetryServerError() { - long timerEnd = 0; + String auth = TestUtils.getProperty(connectionString, "authentication"); + org.junit.Assume.assumeTrue(auth != null + && (auth.equalsIgnoreCase("SqlPassword") || auth.equalsIgnoreCase("ActiveDirectoryPassword"))); + + long totalTime = 0; long timerStart = System.currentTimeMillis(); + int interval = defaultTimeout; // long interval so we can tell if there was a retry + long timeout = defaultTimeout * 2; // long loginTimeout to accommodate the long interval - // non existent database with interval < loginTimeout this will generate a 4060 transient error and retry - int connectRetryCount = new Random().nextInt(256); - int connectRetryInterval = new Random().nextInt(defaultTimeout) + 1; + // non existent database with interval < loginTimeout this will generate a 4060 transient error and retry 1 time try (Connection con = PrepUtil.getConnection( TestUtils.addOrOverrideProperty(connectionString, "database", RandomUtil.getIdentifier("database")) - + ";logintimeout=" + defaultTimeout + ";connectRetryCount=" + connectRetryCount - + ";connectRetryInterval=" + connectRetryInterval)) { + + ";loginTimeout=" + timeout + ";connectRetryCount=" + 1 + ";connectRetryInterval=" + interval + + ";transparentNetworkIPResolution=false")) { fail(TestResource.getResource("R_shouldNotConnect")); } catch (Exception e) { - assertTrue((e.getMessage().contains(TestResource.getResource("R_cannotOpenDatabase"))) - || ((isSqlAzure() || isSqlAzureDW()) - ? e.getMessage().contains( - TestResource.getResource("R_connectTimedOut")) - : false), + totalTime = System.currentTimeMillis() - timerStart; + + assertTrue( + (e.getMessage().toLowerCase() + .contains(TestResource.getResource("R_cannotOpenDatabase").toLowerCase())) + || (TestUtils.getProperty(connectionString, "msiClientId") != null && e.getMessage() + .toLowerCase().contains(TestResource.getResource("R_loginFailedMI").toLowerCase())) + || ((isSqlAzure() || isSqlAzureDW()) ? e.getMessage().toLowerCase() + .contains(TestResource.getResource("R_connectTimedOut").toLowerCase()) : false), e.getMessage()); - timerEnd = System.currentTimeMillis(); - } - - // connect + all retries should always be <= loginTimeout - verifyTimeout(timerEnd - timerStart, defaultTimeout); } // Test connect retry for database error using Datasource @Test public void testConnectRetryServerErrorDS() { - long timerEnd = 0; - long timerStart = System.currentTimeMillis(); + String auth = TestUtils.getProperty(connectionString, "authentication"); + org.junit.Assume.assumeTrue(auth != null + && (auth.equalsIgnoreCase("SqlPassword") || auth.equalsIgnoreCase("ActiveDirectoryPassword"))); - // non existent database with interval < loginTimeout this will generate a 4060 transient error and retry - int connectRetryCount = new Random().nextInt(256); - int connectRetryInterval = new Random().nextInt(defaultTimeout) + 1; + long totalTime = 0; + long timerStart = System.currentTimeMillis(); + int interval = defaultTimeout; // long interval so we can tell if there was a retry + long loginTimeout = defaultTimeout * 2; // long loginTimeout to accommodate the long interval + // non existent database with interval < loginTimeout this will generate a 4060 transient error and retry 1 time SQLServerDataSource ds = new SQLServerDataSource(); String connectStr = TestUtils.addOrOverrideProperty(connectionString, "database", - RandomUtil.getIdentifier("database")) + ";logintimeout=" + defaultTimeout + ";connectRetryCount=" - + connectRetryCount + ";connectRetryInterval=" + connectRetryInterval; + RandomUtil.getIdentifier("database")) + ";logintimeout=" + loginTimeout + ";connectRetryCount=1" + + ";connectRetryInterval=" + interval; updateDataSource(connectStr, ds); try (Connection con = PrepUtil.getConnection(connectStr)) { fail(TestResource.getResource("R_shouldNotConnect")); } catch (Exception e) { - assertTrue((e.getMessage().contains(TestResource.getResource("R_cannotOpenDatabase"))) - || ((isSqlAzure() || isSqlAzureDW()) - ? e.getMessage().contains( - TestResource.getResource("R_connectTimedOut")) - : false), + assertTrue( + (e.getMessage().toLowerCase() + .contains(TestResource.getResource("R_cannotOpenDatabase").toLowerCase())) + || (TestUtils.getProperty(connectionString, "msiClientId") != null && e.getMessage() + .toLowerCase().contains(TestResource.getResource("R_loginFailedMI").toLowerCase())) + || ((isSqlAzure() || isSqlAzureDW()) ? e.getMessage().toLowerCase() + .contains(TestResource.getResource("R_connectTimedOut").toLowerCase()) : false), e.getMessage()); - timerEnd = System.currentTimeMillis(); + totalTime = System.currentTimeMillis() - timerStart; } - // connect + all retries should always be <= loginTimeout - verifyTimeout(timerEnd - timerStart, defaultTimeout); + // 1 retry should be at least 1 interval long but < 2 intervals + assertTrue(TimeUnit.SECONDS.toMillis(interval) < totalTime, + "interval: " + TimeUnit.SECONDS.toMillis(interval) + " total time: " + totalTime); + assertTrue(totalTime < TimeUnit.SECONDS.toMillis(2 * interval), + "total time: " + totalTime + " 2 * interval: " + TimeUnit.SECONDS.toMillis(2 * interval)); } // Test connect retry for database error with loginTimeout @Test public void testConnectRetryTimeout() { - long timerEnd = 0; + long totalTime = 0; long timerStart = System.currentTimeMillis(); + int interval = defaultTimeout; // long interval so we can tell if there was a retry int loginTimeout = 2; - // non existent server with very short loginTimeout so there is no time to do all retries + // non existent database with very short loginTimeout so there is no time to do any retry try (Connection con = PrepUtil.getConnection( TestUtils.addOrOverrideProperty(connectionString, "database", RandomUtil.getIdentifier("database")) - + "connectRetryCount=" + (new Random().nextInt(256)) + ";connectRetryInterval=" - + (new Random().nextInt(defaultTimeout - 1) + 1) + ";loginTimeout=" + loginTimeout)) { + + "connectRetryCount=" + (new Random().nextInt(256)) + ";connectRetryInterval=" + interval + + ";loginTimeout=" + loginTimeout)) { fail(TestResource.getResource("R_shouldNotConnect")); } catch (Exception e) { - assertTrue((e.getMessage().contains(TestResource.getResource("R_cannotOpenDatabase"))) - || ((isSqlAzure() || isSqlAzureDW()) - ? e.getMessage().contains( - TestResource.getResource("R_connectTimedOut")) - : false), + totalTime = System.currentTimeMillis() - timerStart; + + assertTrue( + (e.getMessage().toLowerCase() + .contains(TestResource.getResource("R_cannotOpenDatabase").toLowerCase())) + || (TestUtils.getProperty(connectionString, "msiClientId") != null && e.getMessage() + .toLowerCase().contains(TestResource.getResource("R_loginFailedMI").toLowerCase())) + || ((isSqlAzure() || isSqlAzureDW()) ? e.getMessage().toLowerCase() + .contains(TestResource.getResource("R_connectTimedOut").toLowerCase()) : false), e.getMessage()); - timerEnd = System.currentTimeMillis(); } - verifyTimeout(timerEnd - timerStart, loginTimeout); + // if there was a retry then it would take at least 1 interval long, so if < interval means there were no retries + assertTrue(totalTime < TimeUnit.SECONDS.toMillis(interval), + "total time: " + totalTime + " interval: " + TimeUnit.SECONDS.toMillis(interval)); } @Test diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/fips/FipsTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/fips/FipsTest.java index a486e3c27..9a02cd956 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/fips/FipsTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/fips/FipsTest.java @@ -62,13 +62,18 @@ public void fipsTrustServerCertificateTest() throws Exception { */ @Test public void fipsEncryptTest() throws Exception { + // test doesn't apply to managed identity as encrypt is set to on by default + String auth = TestUtils.getProperty(connectionString, "authentication"); + org.junit.Assume.assumeTrue(auth != null && !(auth.equalsIgnoreCase("ActiveDirectoryManagedIdentity") + || auth.equalsIgnoreCase("ActiveDirectoryMSI"))); + Properties props = buildConnectionProperties(); props.setProperty(Constants.ENCRYPT, Boolean.FALSE.toString()); try (Connection con = PrepUtil.getConnection(connectionString, props)) { Assertions.fail(TestResource.getResource("R_expectedExceptionNotThrown")); } catch (SQLException e) { Assertions.assertTrue(e.getMessage().contains(TestResource.getResource("R_invalidFipsConfig")), - TestResource.getResource("R_invalidEncrypt")); + TestResource.getResource("R_invalidTrustCert") + ": " + e.getMessage()); } } @@ -116,6 +121,11 @@ public void fipsDataSourcePropertyTest() throws Exception { */ @Test public void fipsDatSourceEncrypt() { + // test doesn't apply to managed identity as encrypt is set to on by default + String auth = TestUtils.getProperty(connectionString, "authentication"); + org.junit.Assume.assumeTrue(auth != null && !(auth.equalsIgnoreCase("ActiveDirectoryManagedIdentity") + || auth.equalsIgnoreCase("ActiveDirectoryMSI"))); + SQLServerDataSource ds = new SQLServerDataSource(); setDataSourceProperties(ds); ds.setEncrypt(false); @@ -124,7 +134,7 @@ public void fipsDatSourceEncrypt() { Assertions.fail(TestResource.getResource("R_expectedExceptionNotThrown")); } catch (SQLException e) { Assertions.assertTrue(e.getMessage().contains(TestResource.getResource("R_invalidFipsConfig")), - TestResource.getResource("R_invalidEncrypt")); + TestResource.getResource("R_invalidEncrypt") + ": " + e.getMessage()); } } diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/unit/SQLServerErrorTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/unit/SQLServerErrorTest.java index 834e6da49..5318236a8 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/unit/SQLServerErrorTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/unit/SQLServerErrorTest.java @@ -43,6 +43,11 @@ public static void setupTests() throws Exception { @Test @Tag(Constants.xAzureSQLDW) public void testLoginFailedError() { + // test to remove password only valid for password auth + String auth = TestUtils.getProperty(connectionString, "authentication"); + org.junit.Assume.assumeTrue(auth != null + && (auth.equalsIgnoreCase("SqlPassword") || auth.equalsIgnoreCase("ActiveDirectoryPassword"))); + SQLServerDataSource ds = new SQLServerDataSource(); ds.setURL(connectionString); ds.setLoginTimeout(loginTimeOutInSeconds); From e2f18c3526d3f02f2d80416ec0645e1a5c53944a Mon Sep 17 00:00:00 2001 From: Terry Chow Date: Fri, 21 Mar 2025 10:58:23 -0700 Subject: [PATCH 12/14] Test fixes p5: Added missing brace and removed TestUtils.removeProperty method --- .../sqlserver/jdbc/AlwaysEncrypted/AESetup.java | 1 - .../sqlserver/jdbc/connection/TimeoutTest.java | 11 +++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/AESetup.java b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/AESetup.java index f7d623aab..ca71de69e 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/AESetup.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/AESetup.java @@ -188,7 +188,6 @@ static void setAEConnectionString(String serverName, String url, String protocol // remove the password in connection string // this is necessary as updateDataSource will only use 1st occurrence String password = getConfiguredProperty("enclaveServerPassword"); - AETestConnectionString = TestUtils.removeProperty(AETestConnectionString, Constants.PASSWORD); AETestConnectionString = TestUtils.addOrOverrideProperty(AETestConnectionString, Constants.PASSWORD, password); } else { diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/connection/TimeoutTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/connection/TimeoutTest.java index 0cd898bff..cde1e6c31 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/connection/TimeoutTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/connection/TimeoutTest.java @@ -186,14 +186,13 @@ public void testConnectRetryServerError() { } catch (Exception e) { totalTime = System.currentTimeMillis() - timerStart; - assertTrue( - (e.getMessage().toLowerCase() - .contains(TestResource.getResource("R_cannotOpenDatabase").toLowerCase())) - || (TestUtils.getProperty(connectionString, "msiClientId") != null && e.getMessage() - .toLowerCase().contains(TestResource.getResource("R_loginFailedMI").toLowerCase())) - || ((isSqlAzure() || isSqlAzureDW()) ? e.getMessage().toLowerCase() + assertTrue((e.getMessage().toLowerCase().contains( + TestResource.getResource("R_cannotOpenDatabase").toLowerCase())) || (TestUtils.getProperty( + connectionString, "msiClientId") != null && e.getMessage().toLowerCase() + .contains(TestResource.getResource("R_loginFailedMI").toLowerCase())) || ((isSqlAzure() || isSqlAzureDW()) ? e.getMessage().toLowerCase() .contains(TestResource.getResource("R_connectTimedOut").toLowerCase()) : false), e.getMessage()); + } } // Test connect retry for database error using Datasource From a2d1f80a97d61ffe20ed2c55421819a3ddf8094a Mon Sep 17 00:00:00 2001 From: Terry Chow Date: Fri, 21 Mar 2025 12:22:51 -0700 Subject: [PATCH 13/14] Test fixes p5: Adjusted test timings and added missing exception to TestResource --- .../com/microsoft/sqlserver/jdbc/AlwaysEncrypted/MSITest.java | 1 + src/test/java/com/microsoft/sqlserver/jdbc/TestResource.java | 1 + .../microsoft/sqlserver/jdbc/resiliency/ReflectiveTests.java | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/MSITest.java b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/MSITest.java index 5a35e9cb3..88cfa2593 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/MSITest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/MSITest.java @@ -47,6 +47,7 @@ */ @RunWith(JUnitPlatform.class) @Tag(Constants.MSI) +@Tag(Constants.requireSecret) public class MSITest extends AESetup { /* diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/TestResource.java b/src/test/java/com/microsoft/sqlserver/jdbc/TestResource.java index 80db9a7b6..3182654f9 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/TestResource.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/TestResource.java @@ -202,5 +202,6 @@ protected Object[][] getContents() { {"R_failedFedauth", "Failed to acquire fedauth token: "}, {"R_connectTimedOut", "connect timed out"}, {"R_queryCanceled", "The query was canceled."}, + {"R_loginFailedMI", "Login failed for user ''"}, {"R_sessionKilled", "Cannot continue the execution because the session is in the kill state"}}; } diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/resiliency/ReflectiveTests.java b/src/test/java/com/microsoft/sqlserver/jdbc/resiliency/ReflectiveTests.java index f204df76a..1a4f9dd4b 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/resiliency/ReflectiveTests.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/resiliency/ReflectiveTests.java @@ -114,7 +114,7 @@ public void testQueryTimeout() throws SQLException { m.put("queryTimeout", "10"); m.put("loginTimeout", "65535"); m.put("connectRetryCount", "1"); - timeoutVariations(m, 12000, Optional.empty()); + timeoutVariations(m, 14000, Optional.empty()); } /* @@ -128,7 +128,7 @@ public void testValidRetryWindow() throws SQLException { m.put("loginTimeout", "5"); m.put("connectRetryCount", "2"); m.put("connectRetryInterval", "10"); - timeoutVariations(m, 25000, Optional.of("R_crClientAllRecoveryAttemptsFailed")); + timeoutVariations(m, 28000, Optional.of("R_crClientAllRecoveryAttemptsFailed")); } @Test From c61c32af7f92dfda406f2b4790911b16a8eac358 Mon Sep 17 00:00:00 2001 From: Terry Chow Date: Fri, 21 Mar 2025 13:09:49 -0700 Subject: [PATCH 14/14] Test fixes p6: Added additional requestSecret tag to more tests --- .../microsoft/sqlserver/jdbc/connection/XADataSourceTest.java | 4 +--- .../microsoft/sqlserver/jdbc/fedauth/ConcurrentLoginTest.java | 1 + .../microsoft/sqlserver/jdbc/fedauth/ErrorMessageTest.java | 1 + .../com/microsoft/sqlserver/jdbc/fedauth/FedauthTest.java | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/connection/XADataSourceTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/connection/XADataSourceTest.java index 7b867f23a..0fe9a1e12 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/connection/XADataSourceTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/connection/XADataSourceTest.java @@ -7,7 +7,6 @@ import javax.sql.XAConnection; -import com.microsoft.sqlserver.jdbc.TestUtils; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -22,11 +21,10 @@ @RunWith(JUnitPlatform.class) @Tag(Constants.reqExternalSetup) public class XADataSourceTest extends AbstractTest { - private static String connectionUrlSSL = connectionString + ";encrypt=true;trustServerCertificate=false;"; + private static String connectionUrlSSL = connectionString; @BeforeAll public static void setupTests() throws Exception { - connectionString = TestUtils.addOrOverrideProperty(connectionString,"trustServerCertificate", "true"); setConnection(); } diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConcurrentLoginTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConcurrentLoginTest.java index 6b8509978..cde66ae2e 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConcurrentLoginTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ConcurrentLoginTest.java @@ -23,6 +23,7 @@ @RunWith(JUnitPlatform.class) @Tag(Constants.fedAuth) +@Tag(Constants.requireSecret) public class ConcurrentLoginTest extends FedauthCommon { final AtomicReference throwableRef = new AtomicReference(); diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ErrorMessageTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ErrorMessageTest.java index 35050e201..efa35e500 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ErrorMessageTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ErrorMessageTest.java @@ -26,6 +26,7 @@ @RunWith(JUnitPlatform.class) @Tag(Constants.fedAuth) +@Tag(Constants.requireSecret) public class ErrorMessageTest extends FedauthCommon { String badUserName = "abc" + azureUserName; diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthTest.java index c7a201649..ec239e6b1 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthTest.java @@ -37,6 +37,7 @@ @RunWith(JUnitPlatform.class) @Tag(Constants.fedAuth) +@Tag(Constants.requireSecret) public class FedauthTest extends FedauthCommon { static String charTable = TestUtils .escapeSingleQuotes(AbstractSQLGenerator.escapeIdentifier(RandomUtil.getIdentifier("JDBC_FedAuthTest")));