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 + -
显示快捷键?