From cda2996afa4db6047168f2d734ae07a48e080429 Mon Sep 17 00:00:00 2001 From: Cheena Malhotra Date: Thu, 3 Jan 2019 14:39:33 -0800 Subject: [PATCH 1/8] Test Improvements + Readme changes --- README.md | 36 ++++++++++++++---- pom.xml | 16 ++++---- .../unit/statement/PreparedStatementTest.java | 38 ++++++++----------- 3 files changed, 51 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 8fb19d3f9..3d3cdbe74 100644 --- a/README.md +++ b/README.md @@ -102,8 +102,10 @@ Starting from version 7.0.0, the driver Jars (jre10 and above) will expose 'Auto This project has following dependencies: Compile Time: - - `azure-keyvault` : Azure Key Vault Provider for Always Encrypted Azure Key Vault feature (optional) - - `adal4j` : Azure ActiveDirectory Library for Java for Azure Active Directory Authentication feature and Azure Key Vault feature (optional) + - `com.microsoft.azure:azure-keyvault` : Azure Key Vault Provider for Always Encrypted Azure Key Vault feature (optional) + - `com.microsoft.azure:azure-keyvault-webkey` : Azure Key Vault Provider for Always Encrypted Azure Key Vault feature (optional) + - `com.microsoft.azure:adal4j` : Azure Active Directory Library for Java for Azure Active Directory Authentication feature and Azure Key Vault feature (optional) + - `com.microsoft.rest:client-runtime` : Azure Active Directory Library for Java for Azure Active Directory Authentication feature and Azure Key Vault feature (optional) Test Time: - `junit:jar` : For Unit Test cases. @@ -117,7 +119,7 @@ mvn dependency:tree ### Azure Key Vault and Azure Active Directory Authentication Dependencies Projects that require either of the two features need to explicitly declare the dependency in their pom file. -***For Example:*** If you are using *Azure Active Directory Authentication feature* then you need to redeclare *adal4j* dependency in your project's pom file. Please see the following snippet: +***For Example:*** If you are using *Azure Active Directory Authentication feature* then you need to redeclare *adal4j* and *client-runtime* dependency in your project's pom file. Please see the following snippet: ```xml @@ -130,11 +132,17 @@ Projects that require either of the two features need to explicitly declare the com.microsoft.azure adal4j - 1.6.0 + 1.6.2 + + + + com.microsoft.rest + client-runtime + 1.6.2 ``` -***For Example:*** If you are using *Azure Key Vault feature* then you need to redeclare *azure-keyvault* dependency and *adal4j* dependency in your project's pom file. Please see the following snippet: +***For Example:*** If you are using *Azure Key Vault feature* then you need to redeclare *azure-keyvault*, *azure-keyvault-webkey* dependency and *adal4j*, *client-runtime* dependency in your project's pom file. Please see the following snippet: ```xml @@ -147,13 +155,25 @@ Projects that require either of the two features need to explicitly declare the com.microsoft.azure adal4j - 1.6.0 + 1.6.2 + + + + com.microsoft.rest + client-runtime + 1.6.2 com.microsoft.azure azure-keyvault - 1.0.0 + 1.1.1 + + + + com.microsoft.azure + zure-keyvault-webkey + 1.1.1 ``` @@ -189,7 +209,7 @@ Preview releases happen approximately monthly between stable releases. This give You can see what is going into a future release by monitoring [Milestones](https://github.com/Microsoft/mssql-jdbc/milestones) in the repository. ### Versioning convention -Starting with 6.0, stable versions have an even minor version. For example, 6.0, 6.2, 6.4, 7.0. Preview versions have an odd minor version. For example, 6.1, 6.3, 6.5, 7.1. +Starting with 6.0, stable versions have an even minor version. For example, 6.0, 6.2, 6.4, 7.0, 7.2. Preview versions have an odd minor version. For example, 6.1, 6.3, 6.5, 7.1. ## Contributors Special thanks to everyone who has contributed to the project. diff --git a/pom.xml b/pom.xml index ccc932a71..a9ef778e8 100644 --- a/pom.xml +++ b/pom.xml @@ -64,8 +64,14 @@ 1.6.2 true + + com.microsoft.rest + client-runtime + 1.6.2 + true + - + org.osgi org.osgi.core @@ -79,14 +85,6 @@ provided - - - com.microsoft.rest - client-runtime - 1.6.2 - true - - org.junit.platform diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PreparedStatementTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PreparedStatementTest.java index e2ff2b703..8f4402730 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PreparedStatementTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PreparedStatementTest.java @@ -80,9 +80,9 @@ public void testBatchedUnprepare() throws SQLException { String lookupUniqueifier = UUID.randomUUID().toString(); - String queryCacheLookup = String.format("%%/*unpreparetest_%s%%*/SELECT * FROM sys.tables;", + String queryCacheLookup = String.format("%%/*unpreparetest_%s%%*/SELECT 1;", lookupUniqueifier); - String query = String.format("/*unpreparetest_%s only sp_executesql*/SELECT * FROM sys.tables;", + String query = String.format("/*unpreparetest_%s only sp_executesql*/SELECT 1;", lookupUniqueifier); // Verify nothing in cache. @@ -95,7 +95,7 @@ public void testBatchedUnprepare() throws SQLException { int iterations = 25; query = String.format( - "/*unpreparetest_%s, sp_executesql->sp_prepexec->sp_execute- batched sp_unprepare*/SELECT * FROM sys.tables;", + "/*unpreparetest_%s, sp_executesql->sp_prepexec->sp_execute- batched sp_unprepare*/SELECT 1;", lookupUniqueifier); int prevDiscardActionCount = 0; @@ -185,7 +185,7 @@ public void testStatementPoolingEviction() throws SQLException { con.setServerPreparedStatementDiscardThreshold(discardedStatementCount); String lookupUniqueifier = UUID.randomUUID().toString(); - String query = String.format("/*statementpoolingevictiontest_%s*/SELECT * FROM sys.tables; -- ", + String query = String.format("/*statementpoolingevictiontest_%s*/SELECT 1; -- ", lookupUniqueifier); // Add new statements to fill up the statement pool. @@ -290,9 +290,9 @@ public void run() { public void testPrepareRace() throws Exception { String[] queries = new String[3]; - queries[0] = String.format("SELECT * FROM sys.tables -- %s", UUID.randomUUID()); - queries[1] = String.format("SELECT * FROM sys.tables -- %s", UUID.randomUUID()); - queries[2] = String.format("SELECT * FROM sys.tables -- %s", UUID.randomUUID()); + queries[0] = String.format("SELECT 1 -- %s", UUID.randomUUID()); + queries[1] = String.format("SELECT 1 -- %s", UUID.randomUUID()); + queries[2] = String.format("SELECT 1 -- %s", UUID.randomUUID()); ExecutorService threadPool = Executors.newFixedThreadPool(4); AtomicReference exception = new AtomicReference<>(); @@ -469,7 +469,7 @@ public void testStatementPoolingPreparedStatementExecAndUnprepareConfig() throws // Turn off use of prepared statement cache. con.setStatementPoolingCacheSize(0); - String query = "/*unprepSettingsTest*/SELECT * FROM sys.objects;"; + String query = "/*unprepSettingsTest*/SELECT 1;"; // Verify initial default is not serial: assertTrue(1 < con.getServerPreparedStatementDiscardThreshold()); @@ -506,7 +506,7 @@ private void testStatementPoolingInternal(String mode) throws Exception { if (mode.equalsIgnoreCase("bulkcopy")) { modifyConnectionForBulkCopyAPI(con); } - String query = String.format("/*statementpoolingtest_re-use_%s*/SELECT TOP(1) * FROM sys.tables;", + String query = String.format("/*statementpoolingtest_re-use_%s*/SELECT 1;", UUID.randomUUID().toString()); con.setStatementPoolingCacheSize(10); @@ -525,7 +525,7 @@ private void testStatementPoolingInternal(String mode) throws Exception { } int testsWithHandleReuse = 0; - final int testCount = 500; + final int testCount = 50; for (int i = 0; i < testCount; ++i) { Random random = new Random(); int queryNumber = random.nextInt(queries.length); @@ -548,7 +548,7 @@ private void testStatementPoolingInternal(String mode) throws Exception { if (mode.equalsIgnoreCase("bulkcopy")) { modifyConnectionForBulkCopyAPI(con); } - // Test behvaior with statement pooling. + // Test behavior with statement pooling. con.setStatementPoolingCacheSize(10); this.executeSQL(con, "IF NOT EXISTS (SELECT * FROM sys.messages WHERE message_id = 99586) EXEC sp_addmessage 99586, 16, 'Prepared handle GAH!';"); @@ -576,7 +576,7 @@ private void testStatementPoolingInternal(String mode) throws Exception { // test updated value, should be 1 + 100 = 101 // although executeUpdate() throws exception, update operation should be executed successfully. - try (ResultSet rs = con.createStatement() + try (Statement stmt = con.createStatement(); ResultSet rs = stmt .executeQuery("select * from " + AbstractSQLGenerator.escapeIdentifier(tableName) + "")) { rs.next(); assertSame(101, rs.getInt(1)); @@ -613,24 +613,18 @@ private void testStatementPoolingInternal(String mode) throws Exception { // test updated value, should be 1 + 100 = 101 // although executeBatch() throws exception, update operation should be executed successfully. - try (ResultSet rs = con.createStatement() + try (Statement stmt = con.createStatement(); ResultSet rs = stmt .executeQuery("select * from " + AbstractSQLGenerator.escapeIdentifier(tableName2) + "")) { rs.next(); assertSame(101, rs.getInt(1)); } } - } - - try (SQLServerConnection con = (SQLServerConnection) DriverManager.getConnection(connectionString)) { - if (mode.equalsIgnoreCase("bulkcopy")) { - modifyConnectionForBulkCopyAPI(con); - } - // Test behvaior with statement pooling. + + // Test behavior with statement pooling enabled con.setDisableStatementPooling(false); - con.setStatementPoolingCacheSize(10); String lookupUniqueifier = UUID.randomUUID().toString(); - String query = String.format("/*statementpoolingtest_%s*/SELECT * FROM sys.tables;", lookupUniqueifier); + String query = String.format("/*statementpoolingtest_%s*/SELECT 1;", lookupUniqueifier); // Execute statement first, should create cache entry WITHOUT handle (since sp_executesql was used). try (SQLServerPreparedStatement pstmt = (SQLServerPreparedStatement) con.prepareStatement(query)) { From 3a30eeb12d177d157e1a3c4af8e72b178ceab460 Mon Sep 17 00:00:00 2001 From: Cheena Malhotra Date: Thu, 3 Jan 2019 14:45:38 -0800 Subject: [PATCH 2/8] Remove slow tags --- .../sqlserver/jdbc/unit/statement/PreparedStatementTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PreparedStatementTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PreparedStatementTest.java index 8f4402730..d95338e7e 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PreparedStatementTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PreparedStatementTest.java @@ -146,7 +146,6 @@ public void testBatchedUnprepare() throws SQLException { * @throws SQLException */ @Test - @Tag("slow") public void testStatementPooling() throws Exception { testStatementPoolingInternal("batchInsert"); } @@ -161,7 +160,6 @@ public void testStatementPooling() throws Exception { * @throws IllegalArgumentException */ @Test - @Tag("slow") public void testStatementPoolingUseBulkCopyAPI() throws Exception { testStatementPoolingInternal("BulkCopy"); } From 579a6d51fb2ab47c8e1957c7be2f2fbcf113e917 Mon Sep 17 00:00:00 2001 From: Cheena Malhotra Date: Thu, 3 Jan 2019 16:19:07 -0800 Subject: [PATCH 3/8] Format Tests + more improvements --- .../jdbc/SSLCertificateValidation.java | 84 +++++------------ .../sqlserver/jdbc/TestResource.java | 7 +- .../bulkCopy/BulkCopyResultSetCursorTest.java | 22 +++-- .../jdbc/connection/ConnectionDriverTest.java | 6 +- .../SQLServerSpatialDatatypeTest.java | 8 +- .../jdbc/datatypes/TVPWithSqlVariantTest.java | 6 +- .../sqlserver/jdbc/osgi/DataFactoryTest.java | 5 +- .../jdbc/preparedStatement/SetObjectTest.java | 2 +- .../unit/statement/PreparedStatementTest.java | 93 +++++++------------ .../jdbc/unit/statement/StatementTest.java | 11 +-- 10 files changed, 94 insertions(+), 150 deletions(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/SSLCertificateValidation.java b/src/test/java/com/microsoft/sqlserver/jdbc/SSLCertificateValidation.java index af17708eb..101cfb4b2 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/SSLCertificateValidation.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/SSLCertificateValidation.java @@ -39,133 +39,99 @@ public void testValidateServerName() throws Exception { Object hsoObject = constructor.newInstance(null, tdsc, null, serverName); Method method = hsoObject.getClass().getDeclaredMethod("validateServerName", String.class); method.setAccessible(true); - + /* - * Server Name = msjdbc.database.windows.net - * SAN = msjdbc.database.windows.net - * Expected result: true + * Server Name = msjdbc.database.windows.net SAN = msjdbc.database.windows.net Expected result: true */ assertTrue((boolean) method.invoke(hsoObject, "msjdbc.database.windows.net")); /* - * Server Name = msjdbc.database.windows.net - * SAN = msjdbc***.database.windows.net - * Expected result: true + * Server Name = msjdbc.database.windows.net SAN = msjdbc***.database.windows.net Expected result: true */ assertTrue((boolean) method.invoke(hsoObject, "msjdbc***.database.windows.net")); /* - * Server Name = msjdbc.database.windows.net - * SAN = ms*bc.database.windows.net - * Expected result: true + * Server Name = msjdbc.database.windows.net SAN = ms*bc.database.windows.net Expected result: true */ assertTrue((boolean) method.invoke(hsoObject, "ms*bc.database.windows.net")); /* - * Server Name = msjdbc.database.windows.net - * SAN = *bc.database.windows.net - * Expected result: true + * Server Name = msjdbc.database.windows.net SAN = *bc.database.windows.net Expected result: true */ assertTrue((boolean) method.invoke(hsoObject, "*bc.database.windows.net")); /* - * Server Name = msjdbc.database.windows.net - * SAN = ms*.database.windows.net - * Expected result: true + * Server Name = msjdbc.database.windows.net SAN = ms*.database.windows.net Expected result: true */ assertTrue((boolean) method.invoke(hsoObject, "ms*.database.windows.net")); /* - * Server Name = msjdbc.database.windows.net - * SAN = *jd*.database.windows.net - * Expected result: true + * Server Name = msjdbc.database.windows.net SAN = *jd*.database.windows.net Expected result: true */ assertTrue((boolean) method.invoke(hsoObject, "*jd*.database.windows.net")); /* - * Server Name = msjdbc.database.windows.net - * SAN = ms.*.net - * Expected result: false + * Server Name = msjdbc.database.windows.net SAN = ms.*.net Expected result: false */ assertFalse((boolean) method.invoke(hsoObject, "ms.*.net")); /* - * Server Name = msjdbc.database.windows.net - * SAN = msjdbc.asd*dsa.windows.net - * Expected result: false + * Server Name = msjdbc.database.windows.net SAN = msjdbc.asd*dsa.windows.net Expected result: false */ assertFalse((boolean) method.invoke(hsoObject, "msjdbc.asd*dsa.windows.net")); /* - * Server Name = msjdbc.database.windows.net - * SAN = *.*.windows.net - * Expected result: false + * Server Name = msjdbc.database.windows.net SAN = *.*.windows.net Expected result: false */ assertFalse((boolean) method.invoke(hsoObject, ".*.windows.net")); /* - * Server Name = msjdbc.database.windows.net - * SAN = msjdbc.*.windows.net - * Expected result: false + * Server Name = msjdbc.database.windows.net SAN = msjdbc.*.windows.net Expected result: false */ assertFalse((boolean) method.invoke(hsoObject, "msjdbc.*.windows.net")); /* - * Server Name = msjdbc.database.windows.net - * SAN = *.*.windows.net - * Expected result: false - * Note: multiple wildcards are not allowed, so this case shouldn't happen, but we still make sure to fail this. + * Server Name = msjdbc.database.windows.net SAN = *.*.windows.net Expected result: false Note: multiple + * wildcards are not allowed, so this case shouldn't happen, but we still make sure to fail this. */ assertFalse((boolean) method.invoke(hsoObject, "*.*.windows.net")); /* - * Server Name = msjdbc.database.windows.net - * SAN = *.com - * Expected result: false - * A cert with * plus a top-level domain is not allowed. + * Server Name = msjdbc.database.windows.net SAN = *.com Expected result: false A cert with * plus a top-level + * domain is not allowed. */ assertFalse((boolean) method.invoke(hsoObject, "*.com")); /* - * Server Name = msjdbc.database.windows.net - * SAN = xn--ms*.database.windows.net - * Expected result: false + * Server Name = msjdbc.database.windows.net SAN = xn--ms*.database.windows.net Expected result: false */ assertFalse((boolean) method.invoke(hsoObject, "xn--ms*.database.windows.net")); /* - * Server Name = msjdbc.database.windows.net - * SAN = * - * Expected result: false + * Server Name = msjdbc.database.windows.net SAN = * Expected result: false */ assertFalse((boolean) method.invoke(hsoObject, "*")); - + /* - * Server Name = msjdbc.database.windows.net - * SAN = ms*atabase.windows.net - * Expected result: false + * Server Name = msjdbc.database.windows.net SAN = ms*atabase.windows.net Expected result: false */ assertFalse((boolean) method.invoke(hsoObject, "ms*atabase.windows.net")); - + hsoObject = constructor.newInstance(null, tdsc, null, serverName2); method = hsoObject.getClass().getDeclaredMethod("validateServerName", String.class); method.setAccessible(true); - + /* - * Server Name = bbbbuuzzuzzzzzz.example.net - * SAN = b*zzz.example.net - * Expected result: true + * Server Name = bbbbuuzzuzzzzzz.example.net SAN = b*zzz.example.net Expected result: true */ assertTrue((boolean) method.invoke(hsoObject, "b*zzz.example.net")); - + hsoObject = constructor.newInstance(null, tdsc, null, serverName3); method = hsoObject.getClass().getDeclaredMethod("validateServerName", String.class); method.setAccessible(true); - + /* - * Server Name = xn--ms.database.windows.net - * SAN = xn--ms.database.windows.net - * Expected result: true + * Server Name = xn--ms.database.windows.net SAN = xn--ms.database.windows.net Expected result: true */ assertTrue((boolean) method.invoke(hsoObject, "xn--ms.database.windows.net")); } diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/TestResource.java b/src/test/java/com/microsoft/sqlserver/jdbc/TestResource.java index cdfc565b1..421ba36ec 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/TestResource.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/TestResource.java @@ -28,7 +28,8 @@ protected Object[][] getContents() { {"R_fipsPropertyNotSet", "Aborting test case as FIPS_ENV property is not set."}, {"R_invalidTrustCert", "Invalid TrustServerCertificate value."}, {"R_invalidEncrypt", "Invalid encrypt value."}, {"R_notImplemented", "not implemented"}, - {"R_resultsetClosed", "The result set is closed."}, {"R_resultsetNull", "The result set is null."}, + {"R_resultsetClosed", "The result set is closed."}, {"R_statementClosed", "The statement is closed."}, + {"R_resultsetNull", "The result set is null."}, {"R_invalidFipsConfig", "Unable to verify FIPS mode settings."}, {"R_shouldBeEnabled", "should be enabled."}, {"R_StoredProcedureNotFound", "Could not find stored procedure"}, @@ -144,6 +145,10 @@ protected Object[][] getContents() { {"R_paramNotRecognized", "Not all parameters are recognized by driver."}, {"R_invalidGetPreparedStatementHandle", "Invalid use of getPreparedStatementHandle() after statement close expected."}, + {"R_invalidserverPreparedStatementDiscardThreshold", + "The serverPreparedStatementDiscardThreshold %s is not valid."}, + {"R_invalidenablePrepareOnFirstPreparedStatementCall", + "The property enablePrepareOnFirstPreparedStatementCall does not contain a valid boolean value. Only true or false can be used."}, {"R_cancellationFailed", "Cancellation failed."}, {"R_executionNotTimeout", "Execution did not timeout."}, {"R_executionTooLong", "Execution took too long."}, {"R_executionNotLong", "Execution did not take long enough."}, diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/bulkCopy/BulkCopyResultSetCursorTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/bulkCopy/BulkCopyResultSetCursorTest.java index 3ed177217..e7a6b00de 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/bulkCopy/BulkCopyResultSetCursorTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/bulkCopy/BulkCopyResultSetCursorTest.java @@ -69,8 +69,8 @@ private void serverCursorsTest(int resultSetType, int resultSetConcurrency) thro populateSourceTable(); try (Statement stmt2 = conn.createStatement(resultSetType, resultSetConcurrency); - ResultSet rs = stmt2 - .executeQuery("select * from " + AbstractSQLGenerator.escapeIdentifier(srcTable) + " ORDER BY id ASC"); + ResultSet rs = stmt2.executeQuery( + "select * from " + AbstractSQLGenerator.escapeIdentifier(srcTable) + " ORDER BY id ASC"); SQLServerBulkCopy bulkCopy = new SQLServerBulkCopy(conn)) { bulkCopy.setDestinationTableName(AbstractSQLGenerator.escapeIdentifier(desTable)); bulkCopy.writeToServer(rs); @@ -96,7 +96,8 @@ public void testSelectMethodSetToCursor() throws SQLException { createTables(stmt); populateSourceTable(); - try (ResultSet rs = stmt.executeQuery("select * from " + AbstractSQLGenerator.escapeIdentifier(srcTable) + " ORDER BY id ASC"); + try (ResultSet rs = stmt.executeQuery( + "select * from " + AbstractSQLGenerator.escapeIdentifier(srcTable) + " ORDER BY id ASC"); SQLServerBulkCopy bulkCopy = new SQLServerBulkCopy(conn)) { bulkCopy.setDestinationTableName(AbstractSQLGenerator.escapeIdentifier(desTable)); @@ -121,8 +122,8 @@ public void testMultiplePreparedStatementAndResultSet() throws SQLException { populateSourceTable(); try (Statement stmt1 = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); - ResultSet rs = stmt1 - .executeQuery("select * from " + AbstractSQLGenerator.escapeIdentifier(srcTable) + " ORDER BY id ASC")) { + ResultSet rs = stmt1.executeQuery( + "select * from " + AbstractSQLGenerator.escapeIdentifier(srcTable) + " ORDER BY id ASC")) { try (SQLServerBulkCopy bulkCopy = new SQLServerBulkCopy(conn)) { bulkCopy.setDestinationTableName(AbstractSQLGenerator.escapeIdentifier(desTable)); bulkCopy.writeToServer(rs); @@ -157,8 +158,8 @@ public void testMultiplePreparedStatementAndResultSet() throws SQLException { } try (Statement stmt2 = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); - ResultSet rs2 = stmt2 - .executeQuery("select * from " + AbstractSQLGenerator.escapeIdentifier(srcTable) + " ORDER BY id ASC"); + ResultSet rs2 = stmt2.executeQuery("select * from " + + AbstractSQLGenerator.escapeIdentifier(srcTable) + " ORDER BY id ASC"); SQLServerBulkCopy bulkCopy3 = new SQLServerBulkCopy(conn)) { bulkCopy3.setDestinationTableName(AbstractSQLGenerator.escapeIdentifier(desTable)); bulkCopy3.writeToServer(rs2); @@ -169,8 +170,9 @@ public void testMultiplePreparedStatementAndResultSet() throws SQLException { } private static void verifyDestinationTableData(int expectedNumberOfRows) throws SQLException { - try (Connection conn = DriverManager.getConnection(connectionString); ResultSet rs = conn.createStatement() - .executeQuery("select * from " + AbstractSQLGenerator.escapeIdentifier(desTable) + " ORDER BY id ASC")) { + try (Connection conn = DriverManager.getConnection(connectionString); + ResultSet rs = conn.createStatement().executeQuery( + "select * from " + AbstractSQLGenerator.escapeIdentifier(desTable) + " ORDER BY id ASC")) { int expectedArrayLength = expectedBigDecimals.length; @@ -196,7 +198,7 @@ private static void populateSourceTable() throws SQLException { Calendar calGMT = Calendar.getInstance(TimeZone.getTimeZone("GMT")); try (Connection conn = DriverManager.getConnection(connectionString); - SQLServerPreparedStatement pstmt = (SQLServerPreparedStatement) conn.prepareStatement(sql)) { + SQLServerPreparedStatement pstmt = (SQLServerPreparedStatement) conn.prepareStatement(sql)) { for (int i = 0; i < expectedBigDecimals.length; i++) { pstmt.setBigDecimal(1, expectedBigDecimals[i]); pstmt.setString(2, expectedStrings[i]); diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/connection/ConnectionDriverTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/connection/ConnectionDriverTest.java index 2e256f7b1..26907ce73 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/connection/ConnectionDriverTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/connection/ConnectionDriverTest.java @@ -254,15 +254,13 @@ public void testIsWrapperFor() throws SQLException, ClassNotFoundException { Object[] msgArgs1 = {"SQLServerConnection"}; assertTrue(isWrapper, form.format(msgArgs1)); - assertEquals(ssconn.TRANSACTION_SNAPSHOT, ssconn.TRANSACTION_SNAPSHOT, + assertEquals(ISQLServerConnection.TRANSACTION_SNAPSHOT, ISQLServerConnection.TRANSACTION_SNAPSHOT, TestResource.getResource("R_cantAccessSnapshot")); isWrapper = ssconn.isWrapperFor(Class.forName("com.microsoft.sqlserver.jdbc.ISQLServerConnection")); Object[] msgArgs2 = {"ISQLServerConnection"}; assertTrue(isWrapper, form.format(msgArgs2)); - ISQLServerConnection iSql = (ISQLServerConnection) ssconn - .unwrap(Class.forName("com.microsoft.sqlserver.jdbc.ISQLServerConnection")); - assertEquals(iSql.TRANSACTION_SNAPSHOT, iSql.TRANSACTION_SNAPSHOT, + assertEquals(ISQLServerConnection.TRANSACTION_SNAPSHOT, ISQLServerConnection.TRANSACTION_SNAPSHOT, TestResource.getResource("R_cantAccessSnapshot")); ssconn.unwrap(Class.forName("java.sql.Connection")); diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/SQLServerSpatialDatatypeTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/SQLServerSpatialDatatypeTest.java index cce188515..a2cde12b7 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/SQLServerSpatialDatatypeTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/SQLServerSpatialDatatypeTest.java @@ -1042,7 +1042,7 @@ public void testNull() throws SQLException { } } } - + @Test public void testWrongtype() throws SQLException { beforeEachSetup(); @@ -1059,7 +1059,8 @@ public void testWrongtype() throws SQLException { pstmt.execute(); try { - SQLServerResultSet rs = (SQLServerResultSet) stmt.executeQuery("select * from " + AbstractSQLGenerator.escapeIdentifier(geomTableName)); + SQLServerResultSet rs = (SQLServerResultSet) stmt + .executeQuery("select * from " + AbstractSQLGenerator.escapeIdentifier(geomTableName)); rs.next(); rs.getGeography(1); // should fail fail(); @@ -1074,7 +1075,8 @@ public void testWrongtype() throws SQLException { pstmt.execute(); try { - SQLServerResultSet rs = (SQLServerResultSet) stmt.executeQuery("select * from " + AbstractSQLGenerator.escapeIdentifier(geogTableName)); + SQLServerResultSet rs = (SQLServerResultSet) stmt + .executeQuery("select * from " + AbstractSQLGenerator.escapeIdentifier(geogTableName)); rs.next(); rs.getGeometry(1); // should fail fail(); diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/TVPWithSqlVariantTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/TVPWithSqlVariantTest.java index 307bbdcdf..78501dce2 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/TVPWithSqlVariantTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/TVPWithSqlVariantTest.java @@ -353,10 +353,10 @@ public void testDateTime() throws SQLException { * * @throws SQLException * @throws SQLTimeoutException - * https://msdn.microsoft.com/en-ca/library/dd303302.aspx?f=255&MSPPError=-2147217396 - * Data types cannot be NULL when inside a sql_variant + * https://msdn.microsoft.com/en-ca/library/dd303302.aspx?f=255&MSPPError=-2147217396 Data types cannot be + * NULL when inside a sql_variant */ - @Test + @Test public void testNull() throws SQLException { tvp = new SQLServerDataTable(); tvp.addColumnMetadata("c1", microsoft.sql.Types.SQL_VARIANT); diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/osgi/DataFactoryTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/osgi/DataFactoryTest.java index 092edda02..c283b9d53 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/osgi/DataFactoryTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/osgi/DataFactoryTest.java @@ -19,6 +19,8 @@ import javax.sql.XAConnection; import javax.sql.XADataSource; +import org.eclipse.gemini.blueprint.mock.MockBundleContext; +import org.eclipse.gemini.blueprint.mock.MockServiceRegistration; import org.junit.jupiter.api.Test; import org.junit.platform.runner.JUnitPlatform; import org.junit.runner.RunWith; @@ -30,9 +32,6 @@ import com.microsoft.sqlserver.jdbc.SQLServerDriver; import com.microsoft.sqlserver.testframework.AbstractTest; -import org.eclipse.gemini.blueprint.mock.MockBundleContext; -import org.eclipse.gemini.blueprint.mock.MockServiceRegistration; - @RunWith(JUnitPlatform.class) public class DataFactoryTest extends AbstractTest { diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/preparedStatement/SetObjectTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/preparedStatement/SetObjectTest.java index 1ac70723a..4d13267f8 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/preparedStatement/SetObjectTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/preparedStatement/SetObjectTest.java @@ -4,7 +4,7 @@ */ package com.microsoft.sqlserver.jdbc.preparedStatement; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.sql.Connection; import java.sql.DriverManager; diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PreparedStatementTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PreparedStatementTest.java index d95338e7e..6106e5959 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PreparedStatementTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PreparedStatementTest.java @@ -4,7 +4,6 @@ */ package com.microsoft.sqlserver.jdbc.unit.statement; -import static java.util.concurrent.TimeUnit.SECONDS; import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; @@ -19,11 +18,11 @@ import java.sql.Statement; import java.util.Random; import java.util.UUID; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicReference; -import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.platform.runner.JUnitPlatform; import org.junit.runner.RunWith; @@ -80,10 +79,8 @@ public void testBatchedUnprepare() throws SQLException { String lookupUniqueifier = UUID.randomUUID().toString(); - String queryCacheLookup = String.format("%%/*unpreparetest_%s%%*/SELECT 1;", - lookupUniqueifier); - String query = String.format("/*unpreparetest_%s only sp_executesql*/SELECT 1;", - lookupUniqueifier); + String queryCacheLookup = String.format("%%/*unpreparetest_%s%%*/SELECT 1;", lookupUniqueifier); + String query = String.format("/*unpreparetest_%s only sp_executesql*/SELECT 1;", lookupUniqueifier); // Verify nothing in cache. String verifyTotalCacheUsesQuery = String.format( @@ -183,8 +180,7 @@ public void testStatementPoolingEviction() throws SQLException { con.setServerPreparedStatementDiscardThreshold(discardedStatementCount); String lookupUniqueifier = UUID.randomUUID().toString(); - String query = String.format("/*statementpoolingevictiontest_%s*/SELECT 1; -- ", - lookupUniqueifier); + String query = String.format("/*statementpoolingevictiontest_%s*/SELECT 1; -- ", lookupUniqueifier); // Add new statements to fill up the statement pool. for (int i = 0; i < cacheSize; ++i) { @@ -258,32 +254,6 @@ public void testStatementPoolingEviction() throws SQLException { } } - final class TestPrepareRace implements Runnable { - - SQLServerConnection con; - String[] queries; - AtomicReference exception; - - TestPrepareRace(SQLServerConnection con, String[] queries, AtomicReference exception) { - this.con = con; - this.queries = queries; - this.exception = exception; - } - - @Override - public void run() { - for (int j = 0; j < 500000; j++) { - try (SQLServerPreparedStatement pstmt = (SQLServerPreparedStatement) con - .prepareStatement(queries[j % 3])) { - pstmt.execute(); - } catch (SQLException e) { - exception.set(e); - break; - } - } - } - } - @Test public void testPrepareRace() throws Exception { @@ -292,16 +262,26 @@ public void testPrepareRace() throws Exception { queries[1] = String.format("SELECT 1 -- %s", UUID.randomUUID()); queries[2] = String.format("SELECT 1 -- %s", UUID.randomUUID()); - ExecutorService threadPool = Executors.newFixedThreadPool(4); + ExecutorService WORKER_THREAD_POOL = Executors.newFixedThreadPool(10); + CountDownLatch latch = new CountDownLatch(3); AtomicReference exception = new AtomicReference<>(); - try (SQLServerConnection con = (SQLServerConnection) DriverManager.getConnection(connectionString)) { - for (int i = 0; i < 4; i++) { - threadPool.execute(new TestPrepareRace(con, queries, exception)); + try (SQLServerConnection con = (SQLServerConnection) DriverManager.getConnection(connectionString)) { + for (int i = 0; i < 3; i++) { + WORKER_THREAD_POOL.submit(() -> { + for (int j = 0; j < 500; j++) { + try (SQLServerPreparedStatement pstmt = (SQLServerPreparedStatement) con + .prepareStatement(queries[j % 3])) { + pstmt.execute(); + } catch (SQLException e) { + exception.set(e); + break; + } + } + latch.countDown(); + }); } - - threadPool.shutdown(); - threadPool.awaitTermination(10, SECONDS); + latch.await(); assertNull(exception.get()); @@ -443,22 +423,26 @@ public void testStatementPoolingPreparedStatementExecAndUnprepareConfig() throws assertSame(3, connectionThresholdAndNoExecuteSQL.getServerPreparedStatementDiscardThreshold()); } + String invalidValue = "hello"; // Test that an error is thrown for invalid connection string property values (non int/bool). - String connectionStringThresholdError = connectionString + ";ServerPreparedStatementDiscardThreshold=hej;"; + String connectionStringThresholdError = connectionString + ";ServerPreparedStatementDiscardThreshold=" + + invalidValue; try (SQLServerConnection con = (SQLServerConnection) DriverManager .getConnection(connectionStringThresholdError)) { fail("Error for invalid ServerPreparedStatementDiscardThresholdexpected."); } catch (SQLException e) { - // Good! + assert (e.getMessage().equalsIgnoreCase(String.format( + TestResource.getResource("R_invalidserverPreparedStatementDiscardThreshold"), invalidValue))); } - String connectionStringNoExecuteSQLError = connectionString - + ";enablePrepareOnFirstPreparedStatementCall=dobidoo;"; + String connectionStringNoExecuteSQLError = connectionString + ";enablePrepareOnFirstPreparedStatementCall=" + + invalidValue; try (SQLServerConnection con = (SQLServerConnection) DriverManager .getConnection(connectionStringNoExecuteSQLError)) { fail("Error for invalid enablePrepareOnFirstPreparedStatementCall expected."); } catch (SQLException e) { - // Good! + assert (e.getMessage() + .equalsIgnoreCase(TestResource.getResource("R_invalidenablePrepareOnFirstPreparedStatementCall"))); } // Verify instance setting is followed. @@ -504,8 +488,7 @@ private void testStatementPoolingInternal(String mode) throws Exception { if (mode.equalsIgnoreCase("bulkcopy")) { modifyConnectionForBulkCopyAPI(con); } - String query = String.format("/*statementpoolingtest_re-use_%s*/SELECT 1;", - UUID.randomUUID().toString()); + String query = String.format("/*statementpoolingtest_re-use_%s*/SELECT 1;", UUID.randomUUID().toString()); con.setStatementPoolingCacheSize(10); @@ -522,19 +505,13 @@ private void testStatementPoolingInternal(String mode) throws Exception { queries[i] = String.format("%s--%s--%s--%s", query, i, queryCount, prepOnFirstCall); } - int testsWithHandleReuse = 0; - final int testCount = 50; + final int testCount = 500; for (int i = 0; i < testCount; ++i) { Random random = new Random(); int queryNumber = random.nextInt(queries.length); try (SQLServerPreparedStatement pstmt = (SQLServerPreparedStatement) con .prepareStatement(queries[queryNumber])) { pstmt.execute(); - - // Grab handle-reuse before it would be populated if initially created. - if (0 < pstmt.getPreparedStatementHandle()) - testsWithHandleReuse++; - pstmt.getMoreResults(); // Make sure handle is updated. } } @@ -617,7 +594,7 @@ private void testStatementPoolingInternal(String mode) throws Exception { assertSame(101, rs.getInt(1)); } } - + // Test behavior with statement pooling enabled con.setDisableStatementPooling(false); @@ -663,10 +640,10 @@ private void testStatementPoolingInternal(String mode) throws Exception { assertNotSame(handle, pstmt.getPreparedStatementHandle()); } try { - System.out.println(outer.getPreparedStatementHandle()); + outer.getPreparedStatementHandle(); fail(TestResource.getResource("R_invalidGetPreparedStatementHandle")); } catch (Exception e) { - // Good! + assert (e.getMessage().equalsIgnoreCase(TestResource.getResource("R_statementClosed"))); } finally { if (null != outer) { outer.close(); diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/StatementTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/StatementTest.java index 2603cd811..240ce6038 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/StatementTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/StatementTest.java @@ -29,7 +29,6 @@ import java.util.UUID; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.logging.Logger; @@ -686,7 +685,6 @@ class Hammer { int numCancelSuccesses = 0; int numCancelExceptions = 0; int numCancellations = 0; - int numExecuteTries = 0; int numExecuteSuccesses = 0; int numExecuteExceptions = 0; int numCloseExceptions = 0; @@ -717,8 +715,6 @@ void start(final Connection con) { final Runnable runner = new Runnable() { public void run() { - ++numExecuteTries; - try (ResultSet rs = stmt.executeQuery( "SELECT * FROM " + AbstractSQLGenerator.escapeIdentifier(tableName))) { @@ -751,11 +747,10 @@ public void run() { } }; - final ScheduledFuture runnerHandle = executionScheduler.scheduleAtFixedRate(runner, startDelay, - 1, TimeUnit.MILLISECONDS); + executionScheduler.scheduleAtFixedRate(runner, startDelay, 1, TimeUnit.MILLISECONDS); - final ScheduledFuture cancelHandle = cancelScheduler.scheduleAtFixedRate(canceller, - cancelInterval, cancelInterval, TimeUnit.MILLISECONDS); + cancelScheduler.scheduleAtFixedRate(canceller, cancelInterval, cancelInterval, + TimeUnit.MILLISECONDS); } void stop() { From fa72d17ff5dbb666bc8ebf1b33e422e589a72802 Mon Sep 17 00:00:00 2001 From: Cheena Malhotra Date: Thu, 3 Jan 2019 18:00:03 -0800 Subject: [PATCH 4/8] Update versions of dependencies --- README.md | 12 ++++++------ pom.xml | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 3d3cdbe74..c934ecda2 100644 --- a/README.md +++ b/README.md @@ -132,13 +132,13 @@ Projects that require either of the two features need to explicitly declare the com.microsoft.azure adal4j - 1.6.2 + 1.6.3 com.microsoft.rest client-runtime - 1.6.2 + 1.6.5 ``` @@ -155,25 +155,25 @@ Projects that require either of the two features need to explicitly declare the com.microsoft.azure adal4j - 1.6.2 + 1.6.3 com.microsoft.rest client-runtime - 1.6.2 + 1.6.5 com.microsoft.azure azure-keyvault - 1.1.1 + 1.2.0 com.microsoft.azure zure-keyvault-webkey - 1.1.1 + 1.2.0 ``` diff --git a/pom.xml b/pom.xml index a9ef778e8..6c53a6e8a 100644 --- a/pom.xml +++ b/pom.xml @@ -39,8 +39,8 @@ UTF-8 - 1.3.1 - 5.3.1 + 1.3.2 + 5.3.2 4.3.1 @@ -49,25 +49,25 @@ com.microsoft.azure azure-keyvault - 1.1.1 + 1.2.0 true com.microsoft.azure azure-keyvault-webkey - 1.1.1 + 1.2.0 true com.microsoft.azure adal4j - 1.6.2 + 1.6.3 true com.microsoft.rest client-runtime - 1.6.2 + 1.6.5 true From 8908c9b6c4a24795a71fc6954ecc143829738627 Mon Sep 17 00:00:00 2001 From: Cheena Malhotra Date: Thu, 3 Jan 2019 18:07:39 -0800 Subject: [PATCH 5/8] Update versions --- build.gradle | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/build.gradle b/build.gradle index 4f099b60d..abf1126b2 100644 --- a/build.gradle +++ b/build.gradle @@ -82,18 +82,18 @@ repositories { } dependencies { - compileOnly 'com.microsoft.azure:azure-keyvault:1.1.1', - 'com.microsoft.azure:azure-keyvault-webkey:1.1.1', - 'com.microsoft.rest:client-runtime:1.6.2', - 'com.microsoft.azure:adal4j:1.6.2' - testCompile 'org.junit.platform:junit-platform-console:1.3.1', - 'org.junit.platform:junit-platform-commons:1.3.1', - 'org.junit.platform:junit-platform-engine:1.3.1', - 'org.junit.platform:junit-platform-launcher:1.3.1', - 'org.junit.platform:junit-platform-runner:1.3.1', - 'org.junit.platform:junit-platform-surefire-provider:1.3.1', - 'org.junit.jupiter:junit-jupiter-api:5.3.1', - 'org.junit.jupiter:junit-jupiter-engine:5.3.1', + compileOnly 'com.microsoft.azure:azure-keyvault:1.2.0', + 'com.microsoft.azure:azure-keyvault-webkey:1.2.0', + 'com.microsoft.rest:client-runtime:1.6.5', + 'com.microsoft.azure:adal4j:1.6.3' + testCompile 'org.junit.platform:junit-platform-console:1.3.2', + 'org.junit.platform:junit-platform-commons:1.3.2', + 'org.junit.platform:junit-platform-engine:1.3.2', + 'org.junit.platform:junit-platform-launcher:1.3.2', + 'org.junit.platform:junit-platform-runner:1.3.2', + 'org.junit.platform:junit-platform-surefire-provider:1.3.2', + 'org.junit.jupiter:junit-jupiter-api:5.3.2', + 'org.junit.jupiter:junit-jupiter-engine:5.3.2', 'com.zaxxer:HikariCP:3.2.0', 'org.apache.commons:commons-dbcp2:2.5.0', 'org.slf4j:slf4j-nop:1.7.25' From d9d72344788b97aa57f893a950cc7b4d068055b7 Mon Sep 17 00:00:00 2001 From: Cheena Malhotra Date: Fri, 4 Jan 2019 13:28:52 -0800 Subject: [PATCH 6/8] Fix for Leaking connections --- .../microsoft/sqlserver/jdbc/JDBC43Test.java | 44 +++++++++---------- .../jdbc/bulkCopy/BulkCopyAllTypesTest.java | 2 +- .../jdbc/connection/ConnectionDriverTest.java | 13 ++++-- .../jdbc/connection/PoolingTest.java | 4 ++ .../jdbc/datatypes/TVPWithSqlVariantTest.java | 13 +----- .../sqlserver/jdbc/tvp/TVPAllTypesTest.java | 4 +- .../sqlserver/jdbc/tvp/TVPIssuesTest.java | 4 -- .../unit/statement/PreparedStatementTest.java | 7 +-- .../sqlserver/testframework/DBConnection.java | 7 +++ 9 files changed, 51 insertions(+), 47 deletions(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/JDBC43Test.java b/src/test/java/com/microsoft/sqlserver/jdbc/JDBC43Test.java index b688db202..44388eea1 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/JDBC43Test.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/JDBC43Test.java @@ -141,18 +141,18 @@ public void connectionPoolDataSourceTest() throws TestAbortedException, SQLExcep @Test public void setShardingKeyIfValidTest() throws TestAbortedException, SQLException { assumeTrue(TestUtils.supportJDBC43(connection)); - SQLServerConnection connection43 = (SQLServerConnection43) DriverManager.getConnection(connectionString); - try { - connection43.setShardingKeyIfValid(shardingKey, 10); - } catch (SQLException e) { - assert (e.getMessage().contains(TestResource.getResource("R_operationNotSupported"))); - } - try { - connection43.setShardingKeyIfValid(shardingKey, superShardingKey, 10); - } catch (SQLException e) { - assert (e.getMessage().contains(TestResource.getResource("R_operationNotSupported"))); + try (SQLServerConnection connection43 = (SQLServerConnection43) DriverManager.getConnection(connectionString)) { + try { + connection43.setShardingKeyIfValid(shardingKey, 10); + } catch (SQLException e) { + assert (e.getMessage().contains(TestResource.getResource("R_operationNotSupported"))); + } + try { + connection43.setShardingKeyIfValid(shardingKey, superShardingKey, 10); + } catch (SQLException e) { + assert (e.getMessage().contains(TestResource.getResource("R_operationNotSupported"))); + } } - } /** @@ -165,18 +165,18 @@ public void setShardingKeyIfValidTest() throws TestAbortedException, SQLExceptio @Test public void setShardingKeyTest() throws TestAbortedException, SQLException { assumeTrue(TestUtils.supportJDBC43(connection)); - SQLServerConnection connection43 = (SQLServerConnection43) DriverManager.getConnection(connectionString); - try { - connection43.setShardingKey(shardingKey); - } catch (SQLException e) { - assert (e.getMessage().contains(TestResource.getResource("R_operationNotSupported"))); - } - try { - connection43.setShardingKey(shardingKey, superShardingKey); - } catch (SQLException e) { - assert (e.getMessage().contains(TestResource.getResource("R_operationNotSupported"))); + try (SQLServerConnection connection43 = (SQLServerConnection43) DriverManager.getConnection(connectionString)) { + try { + connection43.setShardingKey(shardingKey); + } catch (SQLException e) { + assert (e.getMessage().contains(TestResource.getResource("R_operationNotSupported"))); + } + try { + connection43.setShardingKey(shardingKey, superShardingKey); + } catch (SQLException e) { + assert (e.getMessage().contains(TestResource.getResource("R_operationNotSupported"))); + } } - } /** diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/bulkCopy/BulkCopyAllTypesTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/bulkCopy/BulkCopyAllTypesTest.java index 7b518741f..ea9ad5103 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/bulkCopy/BulkCopyAllTypesTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/bulkCopy/BulkCopyAllTypesTest.java @@ -64,7 +64,7 @@ private void testBulkCopyResultSet(boolean setSelectMethod, Integer resultSetTyp bcOperation.writeToServer(rs); bcOperation.close(); - ComparisonUtil.compareSrcTableAndDestTableIgnoreRowOrder(new DBConnection(connectionString), tableSrc, + ComparisonUtil.compareSrcTableAndDestTableIgnoreRowOrder(new DBConnection(connection), tableSrc, tableDest); } finally { terminateVariation(); diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/connection/ConnectionDriverTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/connection/ConnectionDriverTest.java index 26907ce73..7c3cf72bd 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/connection/ConnectionDriverTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/connection/ConnectionDriverTest.java @@ -190,8 +190,11 @@ public void testConnectionEvents() throws SQLException { // Check to see if error occurred. assertTrue(myE.errorOccurred, TestResource.getResource("R_errorNotCalled")); + } finally { + // make sure that connection is closed. + if (null != pooledConnection) + pooledConnection.close(); } - // make sure that connection is closed. } @Test @@ -218,6 +221,10 @@ public void testConnectionPoolGetTwice() throws SQLException { con.close(); // check to make sure that connection is closed. assertTrue(con.isClosed(), TestResource.getResource("R_connectionIsNotClosed")); + } finally { + // make sure that connection is closed. + if (null != pooledConnection) + pooledConnection.close(); } } @@ -260,6 +267,8 @@ public void testIsWrapperFor() throws SQLException, ClassNotFoundException { isWrapper = ssconn.isWrapperFor(Class.forName("com.microsoft.sqlserver.jdbc.ISQLServerConnection")); Object[] msgArgs2 = {"ISQLServerConnection"}; assertTrue(isWrapper, form.format(msgArgs2)); + ISQLServerConnection iSql = (ISQLServerConnection) ssconn + .unwrap(Class.forName("com.microsoft.sqlserver.jdbc.ISQLServerConnection")); assertEquals(ISQLServerConnection.TRANSACTION_SNAPSHOT, ISQLServerConnection.TRANSACTION_SNAPSHOT, TestResource.getResource("R_cantAccessSnapshot")); @@ -460,7 +469,6 @@ public void testInvalidCombination() throws SQLException { ds.setFailoverPartner(RandomUtil.getIdentifier("FailoverPartner")); timerStart = System.currentTimeMillis(); try (Connection con = ds.getConnection()) { - long timeDiff = timerEnd - timerStart; assertTrue(con == null, TestResource.getResource("R_shouldNotConnect")); MessageFormat form = new MessageFormat(TestResource.getResource("R_exitedMoreSeconds")); @@ -486,7 +494,6 @@ public void testIncorrectDatabaseWithFailoverPartner() throws SQLException { ds.setFailoverPartner(RandomUtil.getIdentifier("FailoverPartner")); timerStart = System.currentTimeMillis(); try (Connection con = ds.getConnection()) { - long timeDiff = timerEnd - timerStart; assertTrue(con == null, TestResource.getResource("R_shouldNotConnect")); MessageFormat form = new MessageFormat(TestResource.getResource("R_exitedLessSeconds")); diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/connection/PoolingTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/connection/PoolingTest.java index cc56b2681..401cc459a 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/connection/PoolingTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/connection/PoolingTest.java @@ -74,6 +74,10 @@ public void testPooling() throws SQLException { if (e.getMessage().startsWith(TestResource.getResource("R_invalidObjectName"))) { tempTableFileRemoved = true; } + } finally { + if (null != pc) { + pc.close(); + } } assertTrue(tempTableFileRemoved, TestResource.getResource("R_tempTAbleNotRemoved")); } diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/TVPWithSqlVariantTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/TVPWithSqlVariantTest.java index 78501dce2..135816a2e 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/TVPWithSqlVariantTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/TVPWithSqlVariantTest.java @@ -14,7 +14,6 @@ import java.sql.SQLException; import java.sql.SQLTimeoutException; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -322,7 +321,7 @@ public void testLongVarChar() throws SQLException { } /** - * Test ith datetime + * Test with datetime * * @throws SQLException * @throws SQLTimeoutException @@ -509,19 +508,9 @@ public void terminateVariation() throws SQLException { TestUtils.dropProcedureIfExists(AbstractSQLGenerator.escapeIdentifier(procedureName), stmt); TestUtils.dropTableIfExists(AbstractSQLGenerator.escapeIdentifier(destTable), stmt); dropTVPS(); - } - - /** - * drop the tables - * - * @throws SQLException - */ - @AfterAll - public static void afterAll() throws SQLException { if (null != stmt) { stmt.close(); } - if (null != conn) { conn.close(); } diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/tvp/TVPAllTypesTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/tvp/TVPAllTypesTest.java index d5c7e2f9c..a2124deb8 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/tvp/TVPAllTypesTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/tvp/TVPAllTypesTest.java @@ -79,7 +79,7 @@ private void testTVPResultSet(boolean setSelectMethod, Integer resultSetType, "INSERT INTO " + tableDest.getEscapedTableName() + " select * from ? ;")) { pstmt.setStructured(1, tvpName, rs); pstmt.execute(); - ComparisonUtil.compareSrcTableAndDestTableIgnoreRowOrder(new DBConnection(connectionString), tableSrc, + ComparisonUtil.compareSrcTableAndDestTableIgnoreRowOrder(new DBConnection(conn), tableSrc, tableDest); } catch (Exception e) { fail(TestResource.getResource("R_unexpectedErrorMessage") + e.toString()); @@ -130,7 +130,7 @@ private void testTVPStoredProcedureResultSet(boolean setSelectMethod, Integer re .prepareCall("{call " + AbstractSQLGenerator.escapeIdentifier(procedureName) + "(?)}")) { Cstmt.setStructured(1, tvpName, rs); Cstmt.execute(); - ComparisonUtil.compareSrcTableAndDestTableIgnoreRowOrder(new DBConnection(connectionString), tableSrc, + ComparisonUtil.compareSrcTableAndDestTableIgnoreRowOrder(new DBConnection(conn), tableSrc, tableDest); } finally { stmt.close(); diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/tvp/TVPIssuesTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/tvp/TVPIssuesTest.java index 25c626102..badc77b11 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/tvp/TVPIssuesTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/tvp/TVPIssuesTest.java @@ -46,8 +46,6 @@ public class TVPIssuesTest extends AbstractTest { @Test public void tryTVPRSvarcharMax4000Issue() throws Exception { - setup(); - try (SQLServerStatement st = (SQLServerStatement) connection.createStatement(); ResultSet rs = st .executeQuery("select * from " + AbstractSQLGenerator.escapeIdentifier(srcTable_varcharMax)); @@ -98,8 +96,6 @@ public void testExceptionWithInvalidStoredProcedureName() throws Exception { */ @Test public void tryTVPPrecisionmissedissue315() throws Exception { - setup(); - try (Connection connection = DriverManager.getConnection(connectionString); Statement stmt = connection.createStatement(); ResultSet rs = stmt diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PreparedStatementTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PreparedStatementTest.java index 6106e5959..62d2747da 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PreparedStatementTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PreparedStatementTest.java @@ -43,8 +43,9 @@ public class PreparedStatementTest extends AbstractTest { final String tableName2 = RandomUtil.getIdentifier("#update2"); private void executeSQL(SQLServerConnection conn, String sql) throws SQLException { - Statement stmt = conn.createStatement(); - stmt.execute(sql); + try (Statement stmt = conn.createStatement()) { + stmt.execute(sql); + } } private int executeSQLReturnFirstInt(SQLServerConnection conn, String sql) throws SQLException { @@ -551,7 +552,7 @@ private void testStatementPoolingInternal(String mode) throws Exception { // test updated value, should be 1 + 100 = 101 // although executeUpdate() throws exception, update operation should be executed successfully. - try (Statement stmt = con.createStatement(); ResultSet rs = stmt + try (Statement stmt = con.createStatement();ResultSet rs = stmt .executeQuery("select * from " + AbstractSQLGenerator.escapeIdentifier(tableName) + "")) { rs.next(); assertSame(101, rs.getInt(1)); diff --git a/src/test/java/com/microsoft/sqlserver/testframework/DBConnection.java b/src/test/java/com/microsoft/sqlserver/testframework/DBConnection.java index e3631238f..776402962 100644 --- a/src/test/java/com/microsoft/sqlserver/testframework/DBConnection.java +++ b/src/test/java/com/microsoft/sqlserver/testframework/DBConnection.java @@ -7,6 +7,7 @@ import static org.junit.jupiter.api.Assertions.fail; +import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.sql.SQLException; @@ -35,6 +36,12 @@ public DBConnection(String connectionString) { super(null, null, "connection"); getConnection(connectionString); } + + public DBConnection(Connection connection) { + super(null, null, "connection"); + this.connection = (SQLServerConnection) connection; + setInternal(connection); + } /** * establish connection From 01a6bc3d23485203e499f309a79463d093185026 Mon Sep 17 00:00:00 2001 From: Cheena Malhotra Date: Fri, 4 Jan 2019 14:00:07 -0800 Subject: [PATCH 7/8] Update PreparedStatement Test --- .../jdbc/unit/statement/PreparedStatementTest.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PreparedStatementTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PreparedStatementTest.java index 62d2747da..5c457ab96 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PreparedStatementTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PreparedStatementTest.java @@ -324,7 +324,7 @@ public void testStatementPoolingPreparedStatementExecAndUnprepareConfig() throws } // Test connection string properties. - // Test disableStatementPooling + // Test disableStatementPooling=true String connectionStringDisableStatementPooling = connectionString + ";disableStatementPooling=true;"; try (SQLServerConnection connectionDisableStatementPooling = (SQLServerConnection) DriverManager .getConnection(connectionStringDisableStatementPooling)) { @@ -333,9 +333,12 @@ public void testStatementPoolingPreparedStatementExecAndUnprepareConfig() throws connectionDisableStatementPooling.setStatementPoolingCacheSize(10); assertSame(10, connectionDisableStatementPooling.getStatementPoolingCacheSize()); assertTrue(!connectionDisableStatementPooling.isStatementPoolingEnabled()); - String connectionStringEnableStatementPooling = connectionString + ";disableStatementPooling=false;"; - SQLServerConnection connectionEnableStatementPooling = (SQLServerConnection) DriverManager - .getConnection(connectionStringEnableStatementPooling); + } + + // Test disableStatementPooling=false + String connectionStringEnableStatementPooling = connectionString + ";disableStatementPooling=false;"; + try (SQLServerConnection connectionEnableStatementPooling = (SQLServerConnection) DriverManager + .getConnection(connectionStringEnableStatementPooling)) { connectionEnableStatementPooling.setStatementPoolingCacheSize(10); // to turn on caching. // for now, it won't affect if disable is false or true. Since statementPoolingCacheSize is set to 0 as @@ -552,7 +555,7 @@ private void testStatementPoolingInternal(String mode) throws Exception { // test updated value, should be 1 + 100 = 101 // although executeUpdate() throws exception, update operation should be executed successfully. - try (Statement stmt = con.createStatement();ResultSet rs = stmt + try (Statement stmt = con.createStatement(); ResultSet rs = stmt .executeQuery("select * from " + AbstractSQLGenerator.escapeIdentifier(tableName) + "")) { rs.next(); assertSame(101, rs.getInt(1)); From 27155b19f9ff60dc2691f785a9610acc924058c4 Mon Sep 17 00:00:00 2001 From: Cheena Malhotra Date: Fri, 4 Jan 2019 14:09:52 -0800 Subject: [PATCH 8/8] Change name --- .../sqlserver/jdbc/unit/statement/PreparedStatementTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PreparedStatementTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PreparedStatementTest.java index 5c457ab96..f1cfa0bb0 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PreparedStatementTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PreparedStatementTest.java @@ -263,13 +263,13 @@ public void testPrepareRace() throws Exception { queries[1] = String.format("SELECT 1 -- %s", UUID.randomUUID()); queries[2] = String.format("SELECT 1 -- %s", UUID.randomUUID()); - ExecutorService WORKER_THREAD_POOL = Executors.newFixedThreadPool(10); + ExecutorService execServiceThread = Executors.newFixedThreadPool(10); CountDownLatch latch = new CountDownLatch(3); AtomicReference exception = new AtomicReference<>(); try (SQLServerConnection con = (SQLServerConnection) DriverManager.getConnection(connectionString)) { for (int i = 0; i < 3; i++) { - WORKER_THREAD_POOL.submit(() -> { + execServiceThread.submit(() -> { for (int j = 0; j < 500; j++) { try (SQLServerPreparedStatement pstmt = (SQLServerPreparedStatement) con .prepareStatement(queries[j % 3])) {