package org.mariadb.jdbc; import org.junit.Assert; import org.junit.Assume; import org.junit.BeforeClass; import org.junit.Test; import java.io.UnsupportedEncodingException; import java.sql.*; import java.util.Arrays; import java.util.Map; import java.util.Properties; import java.util.concurrent.Executor; import static org.junit.Assert.*; public class ConnectionTest extends BaseTest { /** * Initialisation. * * @throws SQLException exception */ @BeforeClass() public static void initClass() throws SQLException { createTable("dummy", "a BLOB"); } /** * Conj-166. * Connection error code must be thrown * * @throws SQLException exception */ @Test public void testAccessDeniedErrorCode() throws SQLException { try { DriverManager.getConnection("jdbc:mariadb://" + ((hostname != null) ? hostname : "localhost") + ":" + port + "/" + database + "?user=foo"); Assert.fail(); } catch (SQLException e) { switch (e.getErrorCode()) { case (1524) : //GSSAPI plugin not loaded Assert.assertTrue("HY000".equals(e.getSQLState())); break; case (1045) : Assert.assertTrue("28000".equals(e.getSQLState())); break; case (1044) : //mysql Assert.assertTrue("42000".equals(e.getSQLState())); break; default: e.printStackTrace(); } } } /** * Conj-75 (corrected with CONJ-156) * Needs permission java.sql.SQLPermission "abort" or will be skipped. * * @throws SQLException exception */ @Test public void abortTest() throws SQLException { try (Connection connection = setConnection()) { try (Statement stmt = connection.createStatement()) { SQLPermission sqlPermission = new SQLPermission("callAbort"); SecurityManager securityManager = System.getSecurityManager(); if (securityManager != null && sqlPermission != null) { try { securityManager.checkPermission(sqlPermission); } catch (SecurityException se) { System.out.println("test 'abortTest' skipped due to missing policy"); return; } } Executor executor = new Executor() { @Override public void execute(Runnable command) { command.run(); } }; connection.abort(executor); assertTrue(connection.isClosed()); try { stmt.executeQuery("SELECT 1"); fail(); } catch (SQLException sqle) { //normal exception } } } } /** * Conj-121: implemented Connection.getNetworkTimeout and Connection.setNetworkTimeout. * * @throws SQLException exception */ @Test public void networkTimeoutTest() throws SQLException { try (Connection connection = setConnection()) { int timeout = 1000; SQLPermission sqlPermission = new SQLPermission("setNetworkTimeout"); SecurityManager securityManager = System.getSecurityManager(); if (securityManager != null && sqlPermission != null) { try { securityManager.checkPermission(sqlPermission); } catch (SecurityException se) { System.out.println("test 'setNetworkTimeout' skipped due to missing policy"); return; } } Executor executor = new Executor() { @Override public void execute(Runnable command) { command.run(); } }; try { connection.setNetworkTimeout(executor, timeout); } catch (SQLException sqlex) { sqlex.printStackTrace(); fail(sqlex.getMessage()); } try { int networkTimeout = connection.getNetworkTimeout(); assertEquals(timeout, networkTimeout); } catch (SQLException sqlex) { sqlex.printStackTrace(); fail(sqlex.getMessage()); } try { connection.createStatement().execute("select sleep(2)"); fail("Network timeout is " + timeout / 1000 + "sec, but slept for 2sec"); } catch (SQLException sqlex) { assertTrue(connection.isClosed()); } } } /** * Conj-120 Fix Connection.isValid method. * * @throws SQLException exception */ @Test public void isValidShouldThrowExceptionWithNegativeTimeout() throws SQLException { try { sharedConnection.isValid(-1); fail("The above row should have thrown an SQLException"); } catch (SQLException sqlex) { assertTrue(sqlex.getMessage().contains("negative")); } } /** * Conj-116: Make SQLException prettier when too large stream is sent to the server. * * @throws SQLException exception * @throws UnsupportedEncodingException exception */ @Test public void checkMaxAllowedPacket() throws Throwable { Statement statement = sharedConnection.createStatement(); ResultSet rs = statement.executeQuery("show variables like 'max_allowed_packet'"); rs.next(); int maxAllowedPacket = rs.getInt(2); //Create a SQL stream bigger than maxAllowedPacket StringBuilder sb = new StringBuilder(); String rowData = "('this is a dummy row values')"; int rowsToWrite = (maxAllowedPacket / rowData.getBytes("UTF-8").length) + 1; try { for (int row = 1; row <= rowsToWrite; row++) { if (row >= 2) { sb.append(", "); } sb.append(rowData); } statement.executeUpdate("INSERT INTO dummy VALUES " + sb.toString()); fail("The previous statement should throw an SQLException"); } catch (OutOfMemoryError e) { System.out.println("skip test 'maxAllowedPackedExceptionIsPrettyTest' - not enough memory"); Assume.assumeNoException(e); } catch (SQLException e) { assertTrue(e.getMessage().contains("max_allowed_packet")); } catch (Exception e) { fail("The previous statement should throw an SQLException not a general Exception"); } statement.execute("select count(*) from dummy"); //check that the connection is still working //added in CONJ-151 to check the 2 different type of query implementation PreparedStatement preparedStatement = sharedConnection.prepareStatement("INSERT INTO dummy VALUES (?)"); try { byte[] arr = new byte[maxAllowedPacket + 1000]; Arrays.fill(arr, (byte) 'a'); preparedStatement.setBytes(1, arr); preparedStatement.addBatch(); preparedStatement.executeBatch(); fail("The previous statement should throw an SQLException"); } catch (OutOfMemoryError e) { System.out.println("skip second test 'maxAllowedPackedExceptionIsPrettyTest' - not enough memory"); Assume.assumeNoException(e); } catch (SQLException e) { assertTrue(e.getMessage().contains("max_allowed_packet")); } catch (Exception e) { e.printStackTrace(); fail("The previous statement should throw an SQLException not a general Exception"); } finally { statement.execute("select count(*) from dummy"); //to check that connection is open } } @Test public void isValidTestWorkingConnection() throws SQLException { assertTrue(sharedConnection.isValid(0)); } /** * CONJ-120 Fix Connection.isValid method * * @throws SQLException exception */ @Test public void isValidClosedConnection() throws SQLException { try (Connection connection = setConnection()) { connection.close(); boolean isValid = connection.isValid(0); assertFalse(isValid); } } /** * CONJ-120 Fix Connection.isValid method * * @throws SQLException exception * @throws InterruptedException exception */ @Test public void isValidConnectionThatTimesOutByServer() throws SQLException, InterruptedException { try (Connection connection = setConnection()) { try (Statement statement = connection.createStatement()) { statement.execute("set session wait_timeout=1"); Thread.sleep(3000); // Wait for the server to kill the connection boolean isValid = connection.isValid(0); assertFalse(isValid); } } } /** * CONJ-363 : follow JDBC connection client infos rules. * * @throws Exception if any occur. */ @Test public void testConnectionClientInfos() throws Exception { assertEquals(null, sharedConnection.getClientInfo("ApplicationName")); assertEquals(null, sharedConnection.getClientInfo("ClientUser")); assertEquals(null, sharedConnection.getClientInfo("ClientHostname")); try { sharedConnection.getClientInfo("otherName"); fail("Must have throw exception since name wasn't correct"); } catch (SQLException sqlEx) { assertTrue(sqlEx.getMessage().contains("name must be")); } Properties properties = sharedConnection.getClientInfo(); assertEquals(null, properties.get("ApplicationName")); assertEquals(null, properties.get("ClientUser")); assertEquals(null, properties.get("ClientHostname")); sharedConnection.setClientInfo("ClientHostname", "testHostName"); assertEquals("testHostName", sharedConnection.getClientInfo("ClientHostname")); sharedConnection.setClientInfo("ClientHostname", null); assertNull(sharedConnection.getClientInfo("ClientHostname")); sharedConnection.setClientInfo("ClientHostname", ""); assertEquals("", sharedConnection.getClientInfo("ClientHostname")); properties = new Properties(); properties.setProperty("ApplicationName", "testDriver"); properties.setProperty("ClientUser", "testClientUser"); properties.setProperty("NotPermitted", "blabla"); properties.setProperty("NotPermitted2", "blabla"); try { sharedConnection.setClientInfo(properties); } catch (SQLClientInfoException sqle) { assertEquals("setClientInfo errors : the following properties where not set :{NotPermitted,NotPermitted2}", sqle.getMessage()); Map<String, ClientInfoStatus> failedProperties = sqle.getFailedProperties(); assertTrue(failedProperties.containsKey("NotPermitted")); assertTrue(failedProperties.containsKey("NotPermitted2")); assertEquals(2, failedProperties.size()); } assertEquals("testDriver", sharedConnection.getClientInfo("ApplicationName")); assertEquals("testClientUser", sharedConnection.getClientInfo("ClientUser")); assertEquals(null, sharedConnection.getClientInfo("ClientHostname")); sharedConnection.setClientInfo("ClientUser", "otherValue"); assertEquals("testDriver", sharedConnection.getClientInfo("ApplicationName")); assertEquals("otherValue", sharedConnection.getClientInfo("ClientUser")); assertEquals(null, sharedConnection.getClientInfo("ClientHostname")); try { sharedConnection.setClientInfo("NotPermitted", "otherValue"); fail("Must have send an exception"); } catch (SQLClientInfoException sqle) { assertEquals("setClientInfo() parameters can only be \"ApplicationName\",\"ClientUser\" or \"ClientHostname\", " + "but was : NotPermitted", sqle.getMessage()); Map<String, ClientInfoStatus> failedProperties = sqle.getFailedProperties(); assertTrue(failedProperties.containsKey("NotPermitted")); assertEquals(1, failedProperties.size()); } } }