connectionregressiontest.java
来自「开发MySql数据库的最新JDBC驱动。」· Java 代码 · 共 2,143 行 · 第 1/4 页
JAVA
2,143 行
protected String getMasterSlaveUrl() throws SQLException { StringBuffer urlBuf = new StringBuffer("jdbc:mysql://"); Properties defaultProps = getPropertiesFromTestsuiteUrl(); String hostname = defaultProps .getProperty(NonRegisteringDriver.HOST_PROPERTY_KEY); int colonIndex = hostname.indexOf(":"); String portNumber = "3306"; if (colonIndex != -1 && !hostname.startsWith(":")) { portNumber = hostname.substring(colonIndex + 1); hostname = hostname.substring(0, colonIndex); } else if (hostname.startsWith(":")) { portNumber = hostname.substring(1); hostname = "localhost"; } else { portNumber = defaultProps .getProperty(NonRegisteringDriver.PORT_PROPERTY_KEY); } for (int i = 0; i < 2; i++) { urlBuf.append(hostname); urlBuf.append(":"); urlBuf.append(portNumber); if (i == 0) { urlBuf.append(","); } } urlBuf.append("/"); return urlBuf.toString(); } protected Properties getMasterSlaveProps() throws SQLException { Properties props = getPropertiesFromTestsuiteUrl(); props.remove(NonRegisteringDriver.HOST_PROPERTY_KEY); props.remove(NonRegisteringDriver.PORT_PROPERTY_KEY); return props; } /** * Tests fix for BUG#15570 - ReplicationConnection incorrectly copies state, * doesn't transfer connection context correctly when transitioning between * the same read-only states. * * (note, this test will fail if the test user doesn't have permission to * "USE 'mysql'". * * @throws Exception * if the test fails. */ public void testBug15570() throws Exception { Connection replConn = null; try { replConn = getMasterSlaveReplicationConnection(); int masterConnectionId = Integer .parseInt(getSingleIndexedValueWithQuery(replConn, 1, "SELECT CONNECTION_ID()").toString()); replConn.setReadOnly(false); assertEquals(masterConnectionId, Integer .parseInt(getSingleIndexedValueWithQuery(replConn, 1, "SELECT CONNECTION_ID()").toString())); String currentCatalog = replConn.getCatalog(); replConn.setCatalog(currentCatalog); assertEquals(currentCatalog, replConn.getCatalog()); replConn.setReadOnly(true); int slaveConnectionId = Integer .parseInt(getSingleIndexedValueWithQuery(replConn, 1, "SELECT CONNECTION_ID()").toString()); // The following test is okay for now, as the chance // of MySQL wrapping the connection id counter during our // testsuite is very small. assertTrue("Slave id " + slaveConnectionId + " is not newer than master id " + masterConnectionId, slaveConnectionId > masterConnectionId); assertEquals(currentCatalog, replConn.getCatalog()); String newCatalog = "mysql"; replConn.setCatalog(newCatalog); assertEquals(newCatalog, replConn.getCatalog()); replConn.setReadOnly(true); assertEquals(newCatalog, replConn.getCatalog()); replConn.setReadOnly(false); assertEquals(masterConnectionId, Integer .parseInt(getSingleIndexedValueWithQuery(replConn, 1, "SELECT CONNECTION_ID()").toString())); } finally { if (replConn != null) { replConn.close(); } } } /** * Tests bug where downed slave caused round robin load balance not to * cycle back to first host in the list. * * @throws Exception * if the test fails...Note, test is timing-dependent, but * should work in most cases. */ public void testBug23281() throws Exception { Properties props = new Driver().parseURL(BaseTestCase.dbUrl, null); props.setProperty("autoReconnect", "false"); props.setProperty("roundRobinLoadBalance", "true"); props.setProperty("failoverReadOnly", "false"); if (!isRunningOnJdk131()) { props.setProperty("connectTimeout", "5000"); } // Re-build the connection information int firstIndexOfHost = BaseTestCase.dbUrl.indexOf("//") + 2; int lastIndexOfHost = BaseTestCase.dbUrl.indexOf("/", firstIndexOfHost); String hostPortPair = BaseTestCase.dbUrl.substring(firstIndexOfHost, lastIndexOfHost); StringTokenizer st = new StringTokenizer(hostPortPair, ":"); String host = null; String port = null; if (st.hasMoreTokens()) { String possibleHostOrPort = st.nextToken(); if (Character.isDigit(possibleHostOrPort.charAt(0)) && (possibleHostOrPort.indexOf(".") == -1 /* IPV4 */) && (possibleHostOrPort.indexOf("::") == -1 /* IPV6 */)) { port = possibleHostOrPort; host = "localhost"; } else { host = possibleHostOrPort; } } if (st.hasMoreTokens()) { port = st.nextToken(); } if (host == null) { host = ""; } if (port == null) { port = "3306"; } StringBuffer newHostBuf = new StringBuffer(); newHostBuf.append(host); if (port != null) { newHostBuf.append(":"); newHostBuf.append(port); } newHostBuf.append(","); //newHostBuf.append(host); newHostBuf.append("192.0.2.1"); // non-exsitent machine from RFC3330 test network newHostBuf.append(":65532"); // make sure the slave fails props.remove("PORT"); props.remove("HOST"); Connection failoverConnection = null; try { failoverConnection = getConnectionWithProps("jdbc:mysql://" + newHostBuf.toString() + "/", props); String originalConnectionId = getSingleIndexedValueWithQuery( failoverConnection, 1, "SELECT CONNECTION_ID()").toString(); System.out.println(originalConnectionId); Connection nextConnection = getConnectionWithProps("jdbc:mysql://" + newHostBuf.toString() + "/", props); String nextId = getSingleIndexedValueWithQuery( nextConnection, 1, "SELECT CONNECTION_ID()").toString(); System.out.println(nextId); } finally { if (failoverConnection != null) { failoverConnection.close(); } } } /** * Tests to insure proper behavior for BUG#24706. * * @throws Exception if the test fails. */ public void testBug24706() throws Exception { if (!versionMeetsMinimum(5, 0)) { return; // server status isn't there to support this feature } Properties props = new Properties(); props.setProperty("elideSetAutoCommits", "true"); props.setProperty("logger", "StandardLogger"); props.setProperty("profileSQL", "true"); Connection c = null; StringBuffer logBuf = new StringBuffer(); StandardLogger.bufferedLog = logBuf; try { c = getConnectionWithProps(props); c.setAutoCommit(true); c.createStatement().execute("SELECT 1"); c.setAutoCommit(true); c.setAutoCommit(false); c.createStatement().execute("SELECT 1"); c.setAutoCommit(false); // We should only see _one_ "set autocommit=" sent to the server String log = logBuf.toString(); int searchFrom = 0; int count = 0; int found = 0; while ((found = log.indexOf("SET autocommit=", searchFrom)) != -1) { searchFrom = found + 1; count++; } // The SELECT doesn't actually start a transaction, so being pedantic the // driver issues SET autocommit=0 again in this case. assertEquals(2, count); } finally { StandardLogger.bufferedLog = null; if (c != null) { c.close(); } } } /** * Tests fix for BUG#25514 - Timer instance used for Statement.setQueryTimeout() * created per-connection, rather than per-VM, causing memory leak. * * @throws Exception if the test fails. */ public void testBug25514() throws Exception { for (int i = 0; i < 10; i++) { getConnectionWithProps(null).close(); } ThreadGroup root = Thread.currentThread().getThreadGroup().getParent(); while (root.getParent() != null) { root = root.getParent(); } int numThreadsNamedTimer = findNamedThreadCount(root, "Timer"); if (numThreadsNamedTimer == 0) { numThreadsNamedTimer = findNamedThreadCount(root, "MySQL Statement Cancellation Timer"); } // Notice that this seems impossible to test on JDKs prior to 1.5, as there is no // reliable way to find the TimerThread, so we have to rely on new JDKs for this // test. assertTrue("More than one timer for cancel was created", numThreadsNamedTimer <= 1); } private int findNamedThreadCount(ThreadGroup group, String nameStart) { int count = 0; int numThreads = group.activeCount(); Thread[] threads = new Thread[numThreads*2]; numThreads = group.enumerate(threads, false); for (int i=0; i<numThreads; i++) { if (threads[i].getName().startsWith(nameStart)) { count++; } } int numGroups = group.activeGroupCount(); ThreadGroup[] groups = new ThreadGroup[numGroups*2]; numGroups = group.enumerate(groups, false); for (int i=0; i<numGroups; i++) { count += findNamedThreadCount(groups[i], nameStart); } return count; } /** * Ensures that we don't miss getters/setters for driver properties in * ConnectionProperties so that names given in documentation work with * DataSources which will use JavaBean-style names and reflection to * set the values (and often fail silently! when the method isn't available). * * @throws Exception */ public void testBug23626() throws Exception { Class clazz = this.conn.getClass(); DriverPropertyInfo[] dpi = new NonRegisteringDriver().getPropertyInfo(dbUrl, null); StringBuffer missingSettersBuf = new StringBuffer(); StringBuffer missingGettersBuf = new StringBuffer(); Class[][] argTypes = {new Class[] { String.class }, new Class[] {Integer.TYPE}, new Class[] {Long.TYPE}, new Class[] {Boolean.TYPE}}; for (int i = 0; i < dpi.length; i++) { String propertyName = dpi[i].name; if (propertyName.equals("HOST") || propertyName.equals("PORT") || propertyName.equals("DBNAME") || propertyName.equals("user") || propertyName.equals("password")) { continue; } StringBuffer mutatorName = new StringBuffer("set"); mutatorName.append(Character.toUpperCase(propertyName.charAt(0))); mutatorName.append(propertyName.substring(1)); StringBuffer accessorName = new StringBuffer("get"); accessorName.append(Character.toUpperCase(propertyName.charAt(0))); accessorName.append(propertyName.substring(1)); try { clazz.getMethod(accessorName.toString(), null); } catch (NoSuchMethodException nsme) { missingGettersBuf.append(accessorName.toString()); missingGettersBuf.append("\n"); } boolean foundMethod = false; for (int j = 0; j < argTypes.length; j++) { try { clazz.getMethod(mutatorName.toString(), argTypes[j]); foundMethod = true; break; } catch (NoSuchMethodException nsme) { } } if (!foundMethod) { missingSettersBuf.append(mutatorName); missingSettersBuf.append("\n"); } } assertEquals("Missing setters for listed configuration properties.", "", missingSettersBuf.toString()); assertEquals("Missing getters for listed configuration properties.", "", missingSettersBuf.toString()); } /** * Tests fix for BUG#25545 - Client flags not sent correctly during handshake * when using SSL. * * Requires test certificates from testsuite/ssl-test-certs to be installed * on the server being tested. * * @throws Exception if the test fails. */ public void testBug25545() throws Exception { if (!versionMeetsMinimum(5, 0)) { return; } if (isRunningOnJdk131()) { return; } createProcedure("testBug25545", "() BEGIN SELECT 1; END"); String trustStorePath = "src/testsuite/ssl-test-certs/test-cert-store"; System.setProperty("javax.net.ssl.keyStore", trustStorePath); System.setProperty("javax.net.ssl.keyStorePassword","password"); System.setProperty("javax.net.ssl.trustStore", trustStorePath); System.setProperty("javax.net.ssl.trustStorePassword","password"); Connection sslConn = null; try { Properties props = new Properties(); props.setProperty("useSSL", "true"); props.setProperty("requireSSL", "true"); sslConn = getConnectionWithProps(props); sslConn.prepareCall("{ call testBug25545()}").execute(); } finally { if (sslConn != null) { sslConn.close(); } } } /** * Tests fix for BUG#27655 - getTransactionIsolation() uses * "SHOW VARIABLES LIKE" which is very inefficient on MySQL-5.0+ * * @throws Exception */ public void testBug27655() throws Exception { StringBuffer logBuf = new StringBuffer(); Properties props = new Properties(); props.setProperty("profileSQL", "true"); props.setProperty("logger", "StandardLogger"); StandardLogger.bufferedLog = logBuf; Connection loggedConn = null; try { loggedConn = getConnectionWithProps(props); loggedConn.getTransactionIsolation(); if (versionMeetsMinimum(4, 0, 3)) { assertEquals(-1, logBuf.toString().indexOf("SHOW VARIABLES LIKE 'tx_isolation'")); } } finally { if (loggedConn != null) { loggedConn.close(); } } } /** * Tests fix for issue where a failed-over connection would let * an application call setReadOnly(false), when that call * should be ignored until the connection is reconnected to a * writable master. * * @throws Exception if the test fails. */ public void testFailoverReadOnly() throws Exception { Properties props = getMasterSlaveProps(); props.setProperty("autoReconnect", "true"); Connection failoverConn = null; Statement failoverStmt = null; try { failoverConn = getConnectionWithProps(getMasterSlaveUrl(), props); ((com.mysql.jdbc.Connection)failoverConn).setPreferSlaveDuringFailover(true); failoverStmt = failoverConn.createStatement(); String masterConnectionId = getSingleIndexedValueWithQuery(failoverConn, 1, "SELECT connection_id()").toString(); this.stmt.execute("KILL " + masterConnectionId); // die trying, so we get the next host for (int i = 0; i < 100; i++) { try { failoverStmt.executeQuery("SELECT 1"); } catch (SQLException sqlEx) { break; } } String slaveConnectionId = getSingleIndexedValueWithQuery(failoverConn, 1, "SELECT connection_id()").toString(); assertTrue("Didn't get a new physical connection", !masterConnectionId.equals(slaveConnectionId)); failoverConn.setReadOnly(false); // this should be ignored assertTrue(failoverConn.isReadOnly()); ((com.mysql.jdbc.Connection)failoverConn).setPreferSlaveDuringFailover(false); this.stmt.execute("KILL " + slaveConnectionId); // we can't issue this on our own connection :p // die trying, so we get the next host for (int i = 0; i < 100; i++) { try { failoverStmt.executeQuery("SELECT 1"); } catch (SQLException sqlEx) { break; } } String newMasterId = getSingleIndexedValueWithQuery(failoverConn, 1, "SELECT connection_id()").toString(); assertTrue("Didn't get a new physical connection", !slaveConnectionId.equals(newMasterId)); failoverConn.setReadOnly(false); assertTrue(!failoverConn.isReadOnly()); } finally { if (failoverStmt != null) { failoverStmt.close(); } if (failoverConn != null) { failoverConn.close(); } } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?