1820
* Tests to insure proper behavior for BUG#24706.
1822
* @throws Exception if the test fails.
1824
public void testBug24706() throws Exception {
1825
if (!versionMeetsMinimum(5, 0)) {
1826
return; // server status isn't there to support this feature
1829
Properties props = new Properties();
1830
props.setProperty("elideSetAutoCommits", "true");
1831
props.setProperty("logger", "StandardLogger");
1832
props.setProperty("profileSQL", "true");
1833
Connection c = null;
1835
StringBuffer logBuf = new StringBuffer();
1837
StandardLogger.bufferedLog = logBuf;
1840
c = getConnectionWithProps(props);
1841
c.setAutoCommit(true);
1842
c.createStatement().execute("SELECT 1");
1843
c.setAutoCommit(true);
1844
c.setAutoCommit(false);
1845
c.createStatement().execute("SELECT 1");
1846
c.setAutoCommit(false);
1848
// We should only see _one_ "set autocommit=" sent to the server
1850
String log = logBuf.toString();
1855
while ((found = log.indexOf("SET autocommit=", searchFrom)) != -1) {
1856
searchFrom = found + 1;
1860
// The SELECT doesn't actually start a transaction, so being pedantic the
1861
// driver issues SET autocommit=0 again in this case.
1862
assertEquals(2, count);
1864
StandardLogger.bufferedLog = null;
1874
* Tests fix for BUG#25514 - Timer instance used for Statement.setQueryTimeout()
1875
* created per-connection, rather than per-VM, causing memory leak.
1877
* @throws Exception if the test fails.
1879
public void testBug25514() throws Exception {
1881
for (int i = 0; i < 10; i++) {
1882
getConnectionWithProps((Properties)null).close();
1885
ThreadGroup root = Thread.currentThread().getThreadGroup().getParent();
1887
while (root.getParent() != null) {
1888
root = root.getParent();
1891
int numThreadsNamedTimer = findNamedThreadCount(root, "Timer");
1893
if (numThreadsNamedTimer == 0) {
1894
numThreadsNamedTimer = findNamedThreadCount(root, "MySQL Statement Cancellation Timer");
1897
// Notice that this seems impossible to test on JDKs prior to 1.5, as there is no
1898
// reliable way to find the TimerThread, so we have to rely on new JDKs for this
1900
assertTrue("More than one timer for cancel was created", numThreadsNamedTimer <= 1);
1903
private int findNamedThreadCount(ThreadGroup group, String nameStart) {
1907
int numThreads = group.activeCount();
1908
Thread[] threads = new Thread[numThreads*2];
1909
numThreads = group.enumerate(threads, false);
1911
for (int i=0; i<numThreads; i++) {
1912
if (threads[i].getName().startsWith(nameStart)) {
1917
int numGroups = group.activeGroupCount();
1918
ThreadGroup[] groups = new ThreadGroup[numGroups*2];
1919
numGroups = group.enumerate(groups, false);
1921
for (int i=0; i<numGroups; i++) {
1922
count += findNamedThreadCount(groups[i], nameStart);
1929
* Ensures that we don't miss getters/setters for driver properties in
1930
* ConnectionProperties so that names given in documentation work with
1931
* DataSources which will use JavaBean-style names and reflection to
1932
* set the values (and often fail silently! when the method isn't available).
1936
public void testBug23626() throws Exception {
1937
Class clazz = this.conn.getClass();
1939
DriverPropertyInfo[] dpi = new NonRegisteringDriver().getPropertyInfo(dbUrl, null);
1940
StringBuffer missingSettersBuf = new StringBuffer();
1941
StringBuffer missingGettersBuf = new StringBuffer();
1943
Class[][] argTypes = {new Class[] { String.class }, new Class[] {Integer.TYPE}, new Class[] {Long.TYPE}, new Class[] {Boolean.TYPE}};
1945
for (int i = 0; i < dpi.length; i++) {
1947
String propertyName = dpi[i].name;
1949
if (propertyName.equals("HOST") || propertyName.equals("PORT")
1950
|| propertyName.equals("DBNAME") || propertyName.equals("user") ||
1951
propertyName.equals("password")) {
1955
StringBuffer mutatorName = new StringBuffer("set");
1956
mutatorName.append(Character.toUpperCase(propertyName.charAt(0)));
1957
mutatorName.append(propertyName.substring(1));
1959
StringBuffer accessorName = new StringBuffer("get");
1960
accessorName.append(Character.toUpperCase(propertyName.charAt(0)));
1961
accessorName.append(propertyName.substring(1));
1964
clazz.getMethod(accessorName.toString(), null);
1965
} catch (NoSuchMethodException nsme) {
1966
missingGettersBuf.append(accessorName.toString());
1967
missingGettersBuf.append("\n");
1970
boolean foundMethod = false;
1972
for (int j = 0; j < argTypes.length; j++) {
1974
clazz.getMethod(mutatorName.toString(), argTypes[j]);
1977
} catch (NoSuchMethodException nsme) {
1983
missingSettersBuf.append(mutatorName);
1984
missingSettersBuf.append("\n");
1988
assertEquals("Missing setters for listed configuration properties.", "", missingSettersBuf.toString());
1989
assertEquals("Missing getters for listed configuration properties.", "", missingSettersBuf.toString());
1993
* Tests fix for BUG#25545 - Client flags not sent correctly during handshake
1996
* Requires test certificates from testsuite/ssl-test-certs to be installed
1997
* on the server being tested.
1999
* @throws Exception if the test fails.
2001
public void testBug25545() throws Exception {
2002
if (!versionMeetsMinimum(5, 0)) {
2006
if (isRunningOnJdk131()) {
2010
createProcedure("testBug25545", "() BEGIN SELECT 1; END");
2012
String trustStorePath = "src/testsuite/ssl-test-certs/test-cert-store";
2014
System.setProperty("javax.net.ssl.keyStore", trustStorePath);
2015
System.setProperty("javax.net.ssl.keyStorePassword","password");
2016
System.setProperty("javax.net.ssl.trustStore", trustStorePath);
2017
System.setProperty("javax.net.ssl.trustStorePassword","password");
2020
Connection sslConn = null;
2023
Properties props = new Properties();
2024
props.setProperty("useSSL", "true");
2025
props.setProperty("requireSSL", "true");
2027
sslConn = getConnectionWithProps(props);
2028
sslConn.prepareCall("{ call testBug25545()}").execute();
2030
if (sslConn != null) {
2037
* Tests fix for BUG#27655 - getTransactionIsolation() uses
2038
* "SHOW VARIABLES LIKE" which is very inefficient on MySQL-5.0+
2042
public void testBug27655() throws Exception {
2043
StringBuffer logBuf = new StringBuffer();
2044
Properties props = new Properties();
2045
props.setProperty("profileSQL", "true");
2046
props.setProperty("logger", "StandardLogger");
2047
StandardLogger.bufferedLog = logBuf;
2049
Connection loggedConn = null;
2052
loggedConn = getConnectionWithProps(props);
2053
loggedConn.getTransactionIsolation();
2055
if (versionMeetsMinimum(4, 0, 3)) {
2056
assertEquals(-1, logBuf.toString().indexOf("SHOW VARIABLES LIKE 'tx_isolation'"));
2059
if (loggedConn != null) {
2066
* Tests fix for issue where a failed-over connection would let
2067
* an application call setReadOnly(false), when that call
2068
* should be ignored until the connection is reconnected to a
2071
* @throws Exception if the test fails.
2073
public void testFailoverReadOnly() throws Exception {
2074
Properties props = getMasterSlaveProps();
2075
props.setProperty("autoReconnect", "true");
2077
Connection failoverConn = null;
2079
Statement failoverStmt =
2083
failoverConn = getConnectionWithProps(getMasterSlaveUrl(), props);
2085
((com.mysql.jdbc.Connection)failoverConn).setPreferSlaveDuringFailover(true);
2087
failoverStmt = failoverConn.createStatement();
2089
String masterConnectionId = getSingleIndexedValueWithQuery(failoverConn, 1, "SELECT connection_id()").toString();
2091
this.stmt.execute("KILL " + masterConnectionId);
2093
// die trying, so we get the next host
2094
for (int i = 0; i < 100; i++) {
2096
failoverStmt.executeQuery("SELECT 1");
2097
} catch (SQLException sqlEx) {
2102
String slaveConnectionId = getSingleIndexedValueWithQuery(failoverConn, 1, "SELECT connection_id()").toString();
2104
assertTrue("Didn't get a new physical connection",
2105
!masterConnectionId.equals(slaveConnectionId));
2107
failoverConn.setReadOnly(false); // this should be ignored
2109
assertTrue(failoverConn.isReadOnly());
2111
((com.mysql.jdbc.Connection)failoverConn).setPreferSlaveDuringFailover(false);
2113
this.stmt.execute("KILL " + slaveConnectionId); // we can't issue this on our own connection :p
2115
// die trying, so we get the next host
2116
for (int i = 0; i < 100; i++) {
2118
failoverStmt.executeQuery("SELECT 1");
2119
} catch (SQLException sqlEx) {
2124
String newMasterId = getSingleIndexedValueWithQuery(failoverConn, 1, "SELECT connection_id()").toString();
2126
assertTrue("Didn't get a new physical connection",
2127
!slaveConnectionId.equals(newMasterId));
2129
failoverConn.setReadOnly(false);
2131
assertTrue(!failoverConn.isReadOnly());
2133
if (failoverStmt != null) {
2134
failoverStmt.close();
2137
if (failoverConn != null) {
2138
failoverConn.close();
2143
public void testPropertiesDescriptionsKeys() throws Exception {
2144
DriverPropertyInfo[] dpi = new NonRegisteringDriver().getPropertyInfo(
2147
for (int i = 0; i < dpi.length; i++) {
2148
String description = dpi[i].description;
2149
String propertyName = dpi[i].name;
2151
if (description.indexOf("Missing error message for key '") != -1
2152
|| description.startsWith("!")) {
2153
fail("Missing message for configuration property "
2157
if (description.length() < 10) {
2158
fail("Suspiciously short description for configuration property "
2164
public void testBug29852() throws Exception {
2165
Connection lbConn = getLoadBalancedConnection();
2166
assertTrue(!lbConn.getClass().getName().startsWith("com.mysql.jdbc"));
2170
private Connection getLoadBalancedConnection() throws SQLException {
2171
int indexOfHostStart = dbUrl.indexOf("://") + 3;
2172
int indexOfHostEnd = dbUrl.indexOf("/", indexOfHostStart);
2174
String backHalf = dbUrl.substring(indexOfHostStart, indexOfHostEnd);
2176
if (backHalf.length() == 0) {
2177
backHalf = "localhost:3306";
2180
String dbAndConfigs = dbUrl.substring(indexOfHostEnd);
2182
Connection lbConn = DriverManager.getConnection("jdbc:mysql:loadbalance://" + backHalf + "," + backHalf + dbAndConfigs);
2187
* Test of a new feature to fix BUG 22643, specifying a
2188
* "validation query" in your connection pool that starts
2189
* with "slash-star ping slash-star" _exactly_ will cause the driver to " +
2190
* instead send a ping to the server (much lighter weight), and when using
2191
* a ReplicationConnection or a LoadBalancedConnection, will send
2192
* the ping across all active connections.
2196
public void testBug22643() throws Exception {
2197
checkPingQuery(this.conn);
2199
Connection replConnection = getMasterSlaveReplicationConnection();
2202
checkPingQuery(replConnection);
2204
if (replConnection != null) {
2205
replConnection.close();
2209
Connection lbConn = getLoadBalancedConnection();
2212
checkPingQuery(lbConn);
2214
if (lbConn != null) {
2220
private void checkPingQuery(Connection c) throws SQLException {
2221
// Yes, I know we're sending 2, and looking for 1
2222
// that's part of the test, since we don't _really_
2223
// send the query to the server!
2224
String aPingQuery = "/* ping */ SELECT 2";
2225
Statement pingStmt = c.createStatement();
2226
PreparedStatement pingPStmt = null;
2229
this.rs = pingStmt.executeQuery(aPingQuery);
2230
assertTrue(this.rs.next());
2231
assertEquals(this.rs.getInt(1), 1);
2233
assertTrue(pingStmt.execute(aPingQuery));
2234
this.rs = pingStmt.getResultSet();
2235
assertTrue(this.rs.next());
2236
assertEquals(this.rs.getInt(1), 1);
2238
pingPStmt = c.prepareStatement(aPingQuery);
2240
assertTrue(pingPStmt.execute());
2241
this.rs = pingPStmt.getResultSet();
2242
assertTrue(this.rs.next());
2243
assertEquals(this.rs.getInt(1), 1);
2245
this.rs = pingPStmt.executeQuery();
2246
assertTrue(this.rs.next());
2247
assertEquals(this.rs.getInt(1), 1);
2249
closeMemberJDBCResources();