Logo Search packages:      
Sourcecode: mysql-connector-java version File versions  Download package

ConnectionRegressionTest.java

/*
  Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.

  The MySQL Connector/J is licensed under the terms of the GPLv2
  <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most MySQL Connectors.
  There are special exceptions to the terms and conditions of the GPLv2 as it is applied to
  this software, see the FLOSS License Exception
  <http://www.mysql.com/about/legal/licensing/foss-exception.html>.

  This program is free software; you can redistribute it and/or modify it under the terms
  of the GNU General Public License as published by the Free Software Foundation; version 2
  of the License.

  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the GNU General Public License for more details.

  You should have received a copy of the GNU General Public License along with this
  program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth
  Floor, Boston, MA 02110-1301  USA
 
 */
package testsuite.regression;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.Socket;
import java.net.SocketException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.DriverPropertyInfo;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.sql.XAConnection;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;

import testsuite.BaseTestCase;
import testsuite.UnreliableSocketFactory;

import com.mysql.jdbc.ConnectionImpl;
import com.mysql.jdbc.Driver;
import com.mysql.jdbc.LoadBalancingConnectionProxy;
import com.mysql.jdbc.Messages;
import com.mysql.jdbc.MySQLConnection;
import com.mysql.jdbc.MysqlDataTruncation;
import com.mysql.jdbc.NonRegisteringDriver;
import com.mysql.jdbc.RandomBalanceStrategy;
import com.mysql.jdbc.ReplicationConnection;
import com.mysql.jdbc.SQLError;
import com.mysql.jdbc.StandardSocketFactory;
import com.mysql.jdbc.integration.jboss.MysqlValidConnectionChecker;
import com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource;
import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource;
import com.mysql.jdbc.jdbc2.optional.MysqlXid;
import com.mysql.jdbc.jdbc2.optional.SuspendableXAConnection;
import com.mysql.jdbc.log.StandardLogger;

/**
 * Regression tests for Connections
 * 
 * @author Mark Matthews
 * @version $Id: ConnectionRegressionTest.java,v 1.1.2.1 2005/05/13 18:58:38
 *          mmatthews Exp $
 */
00085 public class ConnectionRegressionTest extends BaseTestCase {
      /**
       * DOCUMENT ME!
       * 
       * @param name
       *            the name of the testcase
       */
00092       public ConnectionRegressionTest(String name) {
            super(name);
      }

      /**
       * Runs all test cases in this test suite
       * 
       * @param args
       */
00101       public static void main(String[] args) {
            junit.textui.TestRunner.run(ConnectionRegressionTest.class);
      }

      /**
       * DOCUMENT ME!
       * 
       * @throws Exception
       *             ...
       */
00111       public void testBug1914() throws Exception {
            System.out.println(this.conn
                        .nativeSQL("{fn convert(foo(a,b,c), BIGINT)}"));
            System.out.println(this.conn
                        .nativeSQL("{fn convert(foo(a,b,c), BINARY)}"));
            System.out
                        .println(this.conn.nativeSQL("{fn convert(foo(a,b,c), BIT)}"));
            System.out.println(this.conn
                        .nativeSQL("{fn convert(foo(a,b,c), CHAR)}"));
            System.out.println(this.conn
                        .nativeSQL("{fn convert(foo(a,b,c), DATE)}"));
            System.out.println(this.conn
                        .nativeSQL("{fn convert(foo(a,b,c), DECIMAL)}"));
            System.out.println(this.conn
                        .nativeSQL("{fn convert(foo(a,b,c), DOUBLE)}"));
            System.out.println(this.conn
                        .nativeSQL("{fn convert(foo(a,b,c), FLOAT)}"));
            System.out.println(this.conn
                        .nativeSQL("{fn convert(foo(a,b,c), INTEGER)}"));
            System.out.println(this.conn
                        .nativeSQL("{fn convert(foo(a,b,c), LONGVARBINARY)}"));
            System.out.println(this.conn
                        .nativeSQL("{fn convert(foo(a,b,c), LONGVARCHAR)}"));
            System.out.println(this.conn
                        .nativeSQL("{fn convert(foo(a,b,c), TIME)}"));
            System.out.println(this.conn
                        .nativeSQL("{fn convert(foo(a,b,c), TIMESTAMP)}"));
            System.out.println(this.conn
                        .nativeSQL("{fn convert(foo(a,b,c), TINYINT)}"));
            System.out.println(this.conn
                        .nativeSQL("{fn convert(foo(a,b,c), VARBINARY)}"));
            System.out.println(this.conn
                        .nativeSQL("{fn convert(foo(a,b,c), VARCHAR)}"));
      }

      /**
       * Tests fix for BUG#3554 - Not specifying database in URL causes
       * MalformedURL exception.
       * 
       * @throws Exception
       *             if an error ocurrs.
       */
00153       public void testBug3554() throws Exception {
            try {
                  new NonRegisteringDriver().connect(
                              "jdbc:mysql://localhost:3306/?user=root&password=root",
                              new Properties());
            } catch (SQLException sqlEx) {
                  assertTrue(sqlEx.getMessage().indexOf("Malformed") == -1);
            }
      }

      /**
       * DOCUMENT ME!
       * 
       * @throws Exception
       *             ...
       */
00169       public void testBug3790() throws Exception {
            String field2OldValue = "foo";
            String field2NewValue = "bar";
            int field1OldValue = 1;

            Connection conn1 = null;
            Connection conn2 = null;
            Statement stmt1 = null;
            Statement stmt2 = null;
            ResultSet rs2 = null;

            Properties props = new Properties();

            try {
                  createTable("testBug3790",
                              "(field1 INT NOT NULL PRIMARY KEY, field2 VARCHAR(32)) ",
                              "InnoDB");
                  this.stmt.executeUpdate("INSERT INTO testBug3790 VALUES ("
                              + field1OldValue + ", '" + field2OldValue + "')");

                  conn1 = getConnectionWithProps(props); // creates a new connection
                  conn2 = getConnectionWithProps(props); // creates another new
                  // connection
                  conn1.setAutoCommit(false);
                  conn2.setAutoCommit(false);

                  stmt1 = conn1.createStatement();
                  stmt1.executeUpdate("UPDATE testBug3790 SET field2 = '"
                              + field2NewValue + "' WHERE field1=" + field1OldValue);
                  conn1.commit();

                  stmt2 = conn2.createStatement();

                  rs2 = stmt2.executeQuery("SELECT field1, field2 FROM testBug3790");

                  assertTrue(rs2.next());
                  assertTrue(rs2.getInt(1) == field1OldValue);
                  assertTrue(rs2.getString(2).equals(field2NewValue));
            } finally {
                  if (rs2 != null) {
                        rs2.close();
                  }

                  if (stmt2 != null) {
                        stmt2.close();
                  }

                  if (stmt1 != null) {
                        stmt1.close();
                  }

                  if (conn1 != null) {
                        conn1.close();
                  }

                  if (conn2 != null) {
                        conn2.close();
                  }
            }
      }

      /**
       * Tests if the driver configures character sets correctly for 4.1.x
       * servers. Requires that the 'admin connection' is configured, as this test
       * needs to create/drop databases.
       * 
       * @throws Exception
       *             if an error occurs
       */
00238       public void testCollation41() throws Exception {
            if (versionMeetsMinimum(4, 1) && isAdminConnectionConfigured()) {
                  Map charsetsAndCollations = getCharacterSetsAndCollations();
                  charsetsAndCollations.remove("latin7"); // Maps to multiple Java
                  // charsets
                  charsetsAndCollations.remove("ucs2"); // can't be used as a
                  // connection charset

                  Iterator charsets = charsetsAndCollations.keySet().iterator();

                  while (charsets.hasNext()) {
                        Connection charsetConn = null;
                        Statement charsetStmt = null;

                        try {
                              String charsetName = charsets.next().toString();
                              String collationName = charsetsAndCollations.get(
                                          charsetName).toString();
                              Properties props = new Properties();
                              props.put("characterEncoding", charsetName);

                              System.out.println("Testing character set " + charsetName);

                              charsetConn = getAdminConnectionWithProps(props);

                              charsetStmt = charsetConn.createStatement();

                              charsetStmt
                                          .executeUpdate("DROP DATABASE IF EXISTS testCollation41");
                              charsetStmt
                                          .executeUpdate("DROP TABLE IF EXISTS testCollation41");

                              charsetStmt
                                          .executeUpdate("CREATE DATABASE testCollation41 DEFAULT CHARACTER SET "
                                                      + charsetName);
                              charsetConn.setCatalog("testCollation41");

                              // We've switched catalogs, so we need to recreate the
                              // statement to pick this up...
                              charsetStmt = charsetConn.createStatement();

                              StringBuffer createTableCommand = new StringBuffer(
                                          "CREATE TABLE testCollation41"
                                                      + "(field1 VARCHAR(255), field2 INT)");

                              charsetStmt.executeUpdate(createTableCommand.toString());

                              charsetStmt
                                          .executeUpdate("INSERT INTO testCollation41 VALUES ('abc', 0)");

                              int updateCount = charsetStmt
                                          .executeUpdate("UPDATE testCollation41 SET field2=1 WHERE field1='abc'");
                              assertTrue(updateCount == 1);
                        } finally {
                              if (charsetStmt != null) {
                                    charsetStmt
                                                .executeUpdate("DROP TABLE IF EXISTS testCollation41");
                                    charsetStmt
                                                .executeUpdate("DROP DATABASE IF EXISTS testCollation41");
                                    charsetStmt.close();
                              }

                              if (charsetConn != null) {
                                    charsetConn.close();
                              }
                        }
                  }
            }
      }

      /**
       * Tests setReadOnly() being reset during failover
       * 
       * @throws Exception
       *             if an error occurs.
       */
00314       public void testSetReadOnly() throws Exception {
            Properties props = new Properties();
            props.put("autoReconnect", "true");

            String sepChar = "?";

            if (BaseTestCase.dbUrl.indexOf("?") != -1) {
                  sepChar = "&";
            }

            Connection reconnectableConn = DriverManager.getConnection(
                        BaseTestCase.dbUrl + sepChar + "autoReconnect=true", props);

            this.rs = reconnectableConn.createStatement().executeQuery(
                        "SELECT CONNECTION_ID()");
            this.rs.next();

            String connectionId = this.rs.getString(1);

            reconnectableConn.setReadOnly(true);

            boolean isReadOnly = reconnectableConn.isReadOnly();

            Connection killConn = getConnectionWithProps((Properties) null);

            killConn.createStatement().executeUpdate("KILL " + connectionId);
            Thread.sleep(2000);

            SQLException caughtException = null;

            int numLoops = 8;

            while (caughtException == null && numLoops > 0) {
                  numLoops--;

                  try {
                        reconnectableConn.createStatement().executeQuery("SELECT 1");
                  } catch (SQLException sqlEx) {
                        caughtException = sqlEx;
                  }
            }

            System.out
                        .println("Executing statement on reconnectable connection...");

            this.rs = reconnectableConn.createStatement().executeQuery(
                        "SELECT CONNECTION_ID()");
            this.rs.next();
            assertTrue("Connection is not a reconnected-connection",
                        !connectionId.equals(this.rs.getString(1)));

            try {
                  reconnectableConn.createStatement().executeQuery("SELECT 1");
            } catch (SQLException sqlEx) {
                  ; // ignore
            }

            reconnectableConn.createStatement().executeQuery("SELECT 1");

            assertTrue(reconnectableConn.isReadOnly() == isReadOnly);
      }

      private Map getCharacterSetsAndCollations() throws Exception {
            Map charsetsToLoad = new HashMap();

            try {
                  this.rs = this.stmt.executeQuery("SHOW character set");

                  while (this.rs.next()) {
                        charsetsToLoad.put(this.rs.getString("Charset"),
                                    this.rs.getString("Default collation"));
                  }

                  //
                  // These don't have mappings in Java...
                  //
                  charsetsToLoad.remove("swe7");
                  charsetsToLoad.remove("hp8");
                  charsetsToLoad.remove("dec8");
                  charsetsToLoad.remove("koi8u");
                  charsetsToLoad.remove("keybcs2");
                  charsetsToLoad.remove("geostd8");
                  charsetsToLoad.remove("armscii8");
            } finally {
                  if (this.rs != null) {
                        this.rs.close();
                  }
            }

            return charsetsToLoad;
      }

      /**
       * Tests fix for BUG#4334, port #'s not being picked up for
       * failover/autoreconnect.
       * 
       * @throws Exception
       *             if an error occurs.
       */
00413       public void testBug4334() throws Exception {
            if (isAdminConnectionConfigured()) {
                  Connection adminConnection = null;

                  try {
                        adminConnection = getAdminConnection();

                        int bogusPortNumber = 65534;

                        NonRegisteringDriver driver = new NonRegisteringDriver();

                        Properties oldProps = driver.parseURL(BaseTestCase.dbUrl, null);

                        String host = driver.host(oldProps);
                        int port = driver.port(oldProps);
                        String database = oldProps
                                    .getProperty(NonRegisteringDriver.DBNAME_PROPERTY_KEY);
                        String user = oldProps
                                    .getProperty(NonRegisteringDriver.USER_PROPERTY_KEY);
                        String password = oldProps
                                    .getProperty(NonRegisteringDriver.PASSWORD_PROPERTY_KEY);

                        StringBuffer newUrlToTestPortNum = new StringBuffer(
                                    "jdbc:mysql://");

                        if (host != null) {
                              newUrlToTestPortNum.append(host);
                        }

                        newUrlToTestPortNum.append(":").append(port);
                        newUrlToTestPortNum.append(",");

                        if (host != null) {
                              newUrlToTestPortNum.append(host);
                        }

                        newUrlToTestPortNum.append(":").append(bogusPortNumber);
                        newUrlToTestPortNum.append("/");

                        if (database != null) {
                              newUrlToTestPortNum.append(database);
                        }

                        if ((user != null) || (password != null)) {
                              newUrlToTestPortNum.append("?");

                              if (user != null) {
                                    newUrlToTestPortNum.append("user=").append(user);

                                    if (password != null) {
                                          newUrlToTestPortNum.append("&");
                                    }
                              }

                              if (password != null) {
                                    newUrlToTestPortNum.append("password=")
                                                .append(password);
                              }
                        }

                        Properties autoReconnectProps = new Properties();
                        autoReconnectProps.put("autoReconnect", "true");

                        System.out.println(newUrlToTestPortNum);

                        //
                        // First test that port #'s are being correctly picked up
                        //
                        // We do this by looking at the error message that is returned
                        //
                        Connection portNumConn = DriverManager.getConnection(
                                    newUrlToTestPortNum.toString(), autoReconnectProps);
                        Statement portNumStmt = portNumConn.createStatement();
                        this.rs = portNumStmt.executeQuery("SELECT connection_id()");
                        this.rs.next();

                        killConnection(adminConnection, this.rs.getString(1));

                        try {
                              portNumStmt.executeQuery("SELECT connection_id()");
                        } catch (SQLException sqlEx) {
                              // we expect this one
                        }

                        try {
                              portNumStmt.executeQuery("SELECT connection_id()");
                        } catch (SQLException sqlEx) {
                              assertTrue(sqlEx.getMessage().toLowerCase()
                                          .indexOf("connection refused") != -1);
                        }

                        //
                        // Now make sure failover works
                        //
                        StringBuffer newUrlToTestFailover = new StringBuffer(
                                    "jdbc:mysql://");

                        if (host != null) {
                              newUrlToTestFailover.append(host);
                        }

                        newUrlToTestFailover.append(":").append(port);
                        newUrlToTestFailover.append(",");

                        if (host != null) {
                              newUrlToTestFailover.append(host);
                        }

                        newUrlToTestFailover.append(":").append(bogusPortNumber);
                        newUrlToTestFailover.append("/");

                        if (database != null) {
                              newUrlToTestFailover.append(database);
                        }

                        if ((user != null) || (password != null)) {
                              newUrlToTestFailover.append("?");

                              if (user != null) {
                                    newUrlToTestFailover.append("user=").append(user);

                                    if (password != null) {
                                          newUrlToTestFailover.append("&");
                                    }
                              }

                              if (password != null) {
                                    newUrlToTestFailover.append("password=").append(
                                                password);
                              }
                        }

                        Connection failoverConn = DriverManager.getConnection(
                                    newUrlToTestFailover.toString(), autoReconnectProps);
                        Statement failoverStmt = portNumConn.createStatement();
                        this.rs = failoverStmt.executeQuery("SELECT connection_id()");
                        this.rs.next();

                        killConnection(adminConnection, this.rs.getString(1));

                        try {
                              failoverStmt.executeQuery("SELECT connection_id()");
                        } catch (SQLException sqlEx) {
                              // we expect this one
                        }

                        failoverStmt.executeQuery("SELECT connection_id()");
                  } finally {
                        if (adminConnection != null) {
                              adminConnection.close();
                        }
                  }
            }
      }

      private static void killConnection(Connection adminConn, String threadId)
                  throws SQLException {
            adminConn.createStatement().execute("KILL " + threadId);
      }

      /**
       * Tests fix for BUG#6966, connections starting up failed-over (due to down
       * master) never retry master.
       * 
       * @throws Exception
       *             if the test fails...Note, test is timing-dependent, but
       *             should work in most cases.
       */
00581       public void testBug6966() throws Exception {
            Properties props = new Driver().parseURL(BaseTestCase.dbUrl, null);
            props.setProperty("autoReconnect", "true");
            props.setProperty("socketFactory", "testsuite.UnreliableSocketFactory");

            Properties urlProps = new NonRegisteringDriver().parseURL(this.dbUrl,
                        null);

            String host = urlProps.getProperty(Driver.HOST_PROPERTY_KEY);
            String port = urlProps.getProperty(Driver.PORT_PROPERTY_KEY);

            props.remove(Driver.HOST_PROPERTY_KEY);
            props.remove(Driver.NUM_HOSTS_PROPERTY_KEY);
            props.remove(Driver.HOST_PROPERTY_KEY + ".1");
            props.remove(Driver.PORT_PROPERTY_KEY + ".1");

            props.setProperty("queriesBeforeRetryMaster", "50");
            props.setProperty("maxReconnects", "1");

            UnreliableSocketFactory.mapHost("master", host);
            UnreliableSocketFactory.mapHost("slave", host);
            UnreliableSocketFactory.downHost("master");

            Connection failoverConnection = null;

            try {
                  failoverConnection = getConnectionWithProps("jdbc:mysql://master:"
                              + port + ",slave:" + port + "/", props);
                  failoverConnection.setAutoCommit(false);

                  String originalConnectionId = getSingleIndexedValueWithQuery(
                              failoverConnection, 1, "SELECT CONNECTION_ID()").toString();

                  for (int i = 0; i < 50; i++) {
                        failoverConnection.createStatement().executeQuery("SELECT 1");
                  }

                  ((com.mysql.jdbc.Connection) failoverConnection)
                              .clearHasTriedMaster();
                  UnreliableSocketFactory.dontDownHost("master");

                  failoverConnection.setAutoCommit(true);

                  String newConnectionId = getSingleIndexedValueWithQuery(
                              failoverConnection, 1, "SELECT CONNECTION_ID()").toString();

                  assertTrue(((com.mysql.jdbc.Connection) failoverConnection)
                              .hasTriedMaster());

                  assertTrue(!newConnectionId.equals(originalConnectionId));

                  failoverConnection.createStatement().executeQuery("SELECT 1");
            } finally {
                  UnreliableSocketFactory.flushAllHostLists();

                  if (failoverConnection != null) {
                        failoverConnection.close();
                  }
            }
      }

      /**
       * Test fix for BUG#7952 -- Infinite recursion when 'falling back' to master
       * in failover configuration.
       * 
       * @throws Exception
       *             if the tests fails.
       */
00649       public void testBug7952() throws Exception {
            Properties props = new Driver().parseURL(BaseTestCase.dbUrl, null);
            props.setProperty("autoReconnect", "true");

            String host = props.getProperty(NonRegisteringDriver.HOST_PROPERTY_KEY);

            if (!NonRegisteringDriver.isHostPropertiesList(host)) {
                  String port = props.getProperty(
                              NonRegisteringDriver.PORT_PROPERTY_KEY, "3306");

                  host = host + ":" + port;
            }

            host = host + "," + host;

            props.remove("PORT");
            props.remove("HOST");

            props.setProperty("queriesBeforeRetryMaster", "10");
            props.setProperty("maxReconnects", "1");

            Connection failoverConnection = null;
            Connection killerConnection = getConnectionWithProps((String) null);

            try {
                  failoverConnection = getConnectionWithProps("jdbc:mysql://" + host
                              + "/", props);
                  ((com.mysql.jdbc.Connection) failoverConnection)
                              .setPreferSlaveDuringFailover(true);
                  failoverConnection.setAutoCommit(false);

                  String failoverConnectionId = getSingleIndexedValueWithQuery(
                              failoverConnection, 1, "SELECT CONNECTION_ID()").toString();

                  System.out.println("Connection id: " + failoverConnectionId);

                  killConnection(killerConnection, failoverConnectionId);

                  Thread.sleep(3000); // This can take some time....

                  try {
                        failoverConnection.createStatement().executeQuery("SELECT 1");
                  } catch (SQLException sqlEx) {
                        assertTrue("08S01".equals(sqlEx.getSQLState()));
                  }

                  ((com.mysql.jdbc.Connection) failoverConnection)
                              .setPreferSlaveDuringFailover(false);
                  ((com.mysql.jdbc.Connection) failoverConnection)
                              .setFailedOver(true);

                  failoverConnection.setAutoCommit(true);

                  String failedConnectionId = getSingleIndexedValueWithQuery(
                              failoverConnection, 1, "SELECT CONNECTION_ID()").toString();
                  System.out.println("Failed over connection id: "
                              + failedConnectionId);

                  ((com.mysql.jdbc.Connection) failoverConnection)
                              .setPreferSlaveDuringFailover(false);
                  ((com.mysql.jdbc.Connection) failoverConnection)
                              .setFailedOver(true);

                  for (int i = 0; i < 30; i++) {
                        failoverConnection.setAutoCommit(true);
                        System.out.println(getSingleIndexedValueWithQuery(
                                    failoverConnection, 1, "SELECT CONNECTION_ID()"));
                        // failoverConnection.createStatement().executeQuery("SELECT
                        // 1");
                        failoverConnection.setAutoCommit(true);
                  }

                  String fallbackConnectionId = getSingleIndexedValueWithQuery(
                              failoverConnection, 1, "SELECT CONNECTION_ID()").toString();
                  System.out.println("fallback connection id: "
                              + fallbackConnectionId);

                  /*
                   * long begin = System.currentTimeMillis();
                   * 
                   * failoverConnection.setAutoCommit(true);
                   * 
                   * long end = System.currentTimeMillis();
                   * 
                   * assertTrue("Probably didn't try failing back to the
                   * master....check test", (end - begin) > 500);
                   * 
                   * failoverConnection.createStatement().executeQuery("SELECT 1");
                   */
            } finally {
                  if (failoverConnection != null) {
                        failoverConnection.close();
                  }
            }
      }

      /**
       * Tests fix for BUG#7607 - MS932, SHIFT_JIS and Windows_31J not recog. as
       * aliases for sjis.
       * 
       * @throws Exception
       *             if the test fails.
       */
00752       public void testBug7607() throws Exception {
            if (versionMeetsMinimum(4, 1)) {
                  Connection ms932Conn = null, cp943Conn = null, shiftJisConn = null, windows31JConn = null;

                  try {
                        Properties props = new Properties();
                        props.setProperty("characterEncoding", "MS932");

                        ms932Conn = getConnectionWithProps(props);

                        this.rs = ms932Conn.createStatement().executeQuery(
                                    "SHOW VARIABLES LIKE 'character_set_client'");
                        assertTrue(this.rs.next());
                        String encoding = this.rs.getString(2);
                        if (!versionMeetsMinimum(5, 0, 3)
                                    && !versionMeetsMinimum(4, 1, 11)) {
                              assertEquals("sjis", encoding.toLowerCase(Locale.ENGLISH));
                        } else {
                              assertEquals("cp932", encoding.toLowerCase(Locale.ENGLISH));
                        }

                        this.rs = ms932Conn.createStatement().executeQuery(
                                    "SELECT 'abc'");
                        assertTrue(this.rs.next());

                        String charsetToCheck = "ms932";

                        if (versionMeetsMinimum(5, 0, 3)
                                    || versionMeetsMinimum(4, 1, 11)) {
                              charsetToCheck = "windows-31j";
                        }

                        assertEquals(charsetToCheck,
                                    ((com.mysql.jdbc.ResultSetMetaData) this.rs
                                                .getMetaData()).getColumnCharacterSet(1)
                                                .toLowerCase(Locale.ENGLISH));

                        try {
                              ms932Conn.createStatement().executeUpdate(
                                          "drop table if exists testBug7607");
                              ms932Conn
                                          .createStatement()
                                          .executeUpdate(
                                                      "create table testBug7607 (sortCol int, col1 varchar(100) ) character set sjis");
                              ms932Conn.createStatement().executeUpdate(
                                          "insert into testBug7607 values(1, 0x835C)"); // standard
                              // sjis
                              ms932Conn.createStatement().executeUpdate(
                                          "insert into testBug7607 values(2, 0x878A)"); // NEC
                              // kanji

                              this.rs = ms932Conn
                                          .createStatement()
                                          .executeQuery(
                                                      "SELECT col1 FROM testBug7607 ORDER BY sortCol ASC");
                              assertTrue(this.rs.next());
                              String asString = this.rs.getString(1);
                              assertTrue("\u30bd".equals(asString));

                              // Can't be fixed unless server is fixed,
                              // this is fixed in 4.1.7.

                              assertTrue(this.rs.next());
                              asString = this.rs.getString(1);
                              assertEquals("\u3231", asString);
                        } finally {
                              ms932Conn.createStatement().executeUpdate(
                                          "drop table if exists testBug7607");
                        }

                        props = new Properties();
                        props.setProperty("characterEncoding", "SHIFT_JIS");

                        shiftJisConn = getConnectionWithProps(props);

                        this.rs = shiftJisConn.createStatement().executeQuery(
                                    "SHOW VARIABLES LIKE 'character_set_client'");
                        assertTrue(this.rs.next());
                        encoding = this.rs.getString(2);
                        assertTrue("sjis".equalsIgnoreCase(encoding));

                        this.rs = shiftJisConn.createStatement().executeQuery(
                                    "SELECT 'abc'");
                        assertTrue(this.rs.next());

                        String charSetUC = ((com.mysql.jdbc.ResultSetMetaData) this.rs
                                    .getMetaData()).getColumnCharacterSet(1).toUpperCase(
                                    Locale.US);

                        if (isRunningOnJdk131()) {
                              assertEquals("WINDOWS-31J", charSetUC);
                        } else {
                              // assertEquals("SHIFT_JIS", charSetUC);
                        }

                        props = new Properties();
                        props.setProperty("characterEncoding", "WINDOWS-31J");

                        windows31JConn = getConnectionWithProps(props);

                        this.rs = windows31JConn.createStatement().executeQuery(
                                    "SHOW VARIABLES LIKE 'character_set_client'");
                        assertTrue(this.rs.next());
                        encoding = this.rs.getString(2);

                        if (!versionMeetsMinimum(5, 0, 3)
                                    && !versionMeetsMinimum(4, 1, 11)) {
                              assertEquals("sjis", encoding.toLowerCase(Locale.ENGLISH));
                        } else {
                              assertEquals("cp932", encoding.toLowerCase(Locale.ENGLISH));
                        }

                        this.rs = windows31JConn.createStatement().executeQuery(
                                    "SELECT 'abc'");
                        assertTrue(this.rs.next());

                        if (!versionMeetsMinimum(4, 1, 11)) {
                              assertEquals("sjis".toLowerCase(Locale.ENGLISH),
                                          ((com.mysql.jdbc.ResultSetMetaData) this.rs
                                                      .getMetaData()).getColumnCharacterSet(1)
                                                      .toLowerCase(Locale.ENGLISH));
                        } else {
                              assertEquals("windows-31j".toLowerCase(Locale.ENGLISH),
                                          ((com.mysql.jdbc.ResultSetMetaData) this.rs
                                                      .getMetaData()).getColumnCharacterSet(1)
                                                      .toLowerCase(Locale.ENGLISH));
                        }

                        props = new Properties();
                        props.setProperty("characterEncoding", "CP943");

                        cp943Conn = getConnectionWithProps(props);

                        this.rs = cp943Conn.createStatement().executeQuery(
                                    "SHOW VARIABLES LIKE 'character_set_client'");
                        assertTrue(this.rs.next());
                        encoding = this.rs.getString(2);
                        assertTrue("sjis".equalsIgnoreCase(encoding));

                        this.rs = cp943Conn.createStatement().executeQuery(
                                    "SELECT 'abc'");
                        assertTrue(this.rs.next());

                        charSetUC = ((com.mysql.jdbc.ResultSetMetaData) this.rs
                                    .getMetaData()).getColumnCharacterSet(1).toUpperCase(
                                    Locale.US);

                        if (isRunningOnJdk131()) {
                              assertEquals("WINDOWS-31J", charSetUC);
                        } else {
                              assertEquals("CP943", charSetUC);
                        }

                  } finally {
                        if (ms932Conn != null) {
                              ms932Conn.close();
                        }

                        if (shiftJisConn != null) {
                              shiftJisConn.close();
                        }

                        if (windows31JConn != null) {
                              windows31JConn.close();
                        }

                        if (cp943Conn != null) {
                              cp943Conn.close();
                        }
                  }
            }
      }

      /**
       * In some case Connector/J's round-robin function doesn't work.
       * 
       * I had 2 mysqld, node1 "localhost:3306" and node2 "localhost:3307".
       * 
       * 1. node1 is up, node2 is up
       * 
       * 2. java-program connect to node1 by using properties
       * "autoRecconect=true",
       * "roundRobinLoadBalance=true","failOverReadOnly=false".
       * 
       * 3. node1 is down, node2 is up
       * 
       * 4. java-program execute a query and fail, but Connector/J's round-robin
       * fashion failover work and if java-program retry a query it can succeed
       * (connection is change to node2 by Connector/j)
       * 
       * 5. node1 is up, node2 is up
       * 
       * 6. node1 is up, node2 is down
       * 
       * 7. java-program execute a query, but this time Connector/J doesn't work
       * althought node1 is up and usable.
       * 
       * 
       * @throws Exception
       */

      /*
       * FIXME: This test is no longer valid with random selection of hosts public
       * void testBug8643() throws Exception { if (runMultiHostTests()) {
       * Properties defaultProps = getMasterSlaveProps();
       * 
       * defaultProps.remove(NonRegisteringDriver.HOST_PROPERTY_KEY);
       * defaultProps.remove(NonRegisteringDriver.PORT_PROPERTY_KEY);
       * 
       * defaultProps.put("autoReconnect", "true");
       * defaultProps.put("roundRobinLoadBalance", "true");
       * defaultProps.put("failOverReadOnly", "false");
       * 
       * Connection con = null; try { con =
       * DriverManager.getConnection(getMasterSlaveUrl(), defaultProps); Statement
       * stmt1 = con.createStatement();
       * 
       * ResultSet rs1 = stmt1 .executeQuery("show variables like 'port'");
       * rs1.next();
       * 
       * rs1 = stmt1.executeQuery("select connection_id()"); rs1.next(); String
       * originalConnectionId = rs1.getString(1); this.stmt.executeUpdate("kill "
       * + originalConnectionId);
       * 
       * int numLoops = 8;
       * 
       * SQLException caughtException = null;
       * 
       * while (caughtException == null && numLoops > 0) { numLoops--;
       * 
       * try { rs1 = stmt1.executeQuery("show variables like 'port'"); } catch
       * (SQLException sqlEx) { caughtException = sqlEx; } }
       * 
       * assertNotNull(caughtException);
       * 
       * // failover and retry rs1 =
       * stmt1.executeQuery("show variables like 'port'");
       * 
       * rs1.next(); assertTrue(!((com.mysql.jdbc.Connection) con)
       * .isMasterConnection());
       * 
       * rs1 = stmt1.executeQuery("select connection_id()"); rs1.next(); String
       * nextConnectionId = rs1.getString(1);
       * assertTrue(!nextConnectionId.equals(originalConnectionId));
       * 
       * this.stmt.executeUpdate("kill " + nextConnectionId);
       * 
       * numLoops = 8;
       * 
       * caughtException = null;
       * 
       * while (caughtException == null && numLoops > 0) { numLoops--;
       * 
       * try { rs1 = stmt1.executeQuery("show variables like 'port'"); } catch
       * (SQLException sqlEx) { caughtException = sqlEx; } }
       * 
       * assertNotNull(caughtException);
       * 
       * // failover and retry rs1 =
       * stmt1.executeQuery("show variables like 'port'");
       * 
       * rs1.next(); assertTrue(((com.mysql.jdbc.Connection) con)
       * .isMasterConnection());
       * 
       * } finally { if (con != null) { try { con.close(); } catch (Exception e) {
       * e.printStackTrace(); } } } } }
       */

      /**
       * Tests fix for BUG#9206, can not use 'UTF-8' for characterSetResults
       * configuration property.
       */
01024       public void testBug9206() throws Exception {
            Properties props = new Properties();
            props.setProperty("characterSetResults", "UTF-8");
            getConnectionWithProps(props).close();
      }

      /**
       * These two charsets have different names depending on version of MySQL
       * server.
       * 
       * @throws Exception
       *             if the test fails.
       */
01037       public void testNewCharsetsConfiguration() throws Exception {
            Properties props = new Properties();
            props.setProperty("useUnicode", "true");
            props.setProperty("characterEncoding", "EUC_KR");
            getConnectionWithProps(props).close();

            props = new Properties();
            props.setProperty("useUnicode", "true");
            props.setProperty("characterEncoding", "KOI8_R");
            getConnectionWithProps(props).close();
      }

      /**
       * Tests fix for BUG#10144 - Memory leak in ServerPreparedStatement if
       * serverPrepare() fails.
       */

01054       public void testBug10144() throws Exception {
            if (versionMeetsMinimum(4, 1)) {
                  Properties props = new Properties();
                  props.setProperty("emulateUnsupportedPstmts", "false");
                  props.setProperty("useServerPrepStmts", "true");

                  Connection bareConn = getConnectionWithProps(props);

                  int currentOpenStatements = ((com.mysql.jdbc.Connection) bareConn)
                              .getActiveStatementCount();

                  try {
                        bareConn.prepareStatement("Boo!");
                        fail("Should not've been able to prepare that one!");
                  } catch (SQLException sqlEx) {
                        assertEquals(currentOpenStatements,
                                    ((com.mysql.jdbc.Connection) bareConn)
                                                .getActiveStatementCount());
                  } finally {
                        if (bareConn != null) {
                              bareConn.close();
                        }
                  }
            }
      }

      /**
       * Tests fix for BUG#10496 - SQLException is thrown when using property
       * "characterSetResults"
       */
01084       public void testBug10496() throws Exception {
            if (versionMeetsMinimum(5, 0, 3)) {
                  Properties props = new Properties();
                  props.setProperty("useUnicode", "true");
                  props.setProperty("characterEncoding", "WINDOWS-31J");
                  props.setProperty("characterSetResults", "WINDOWS-31J");
                  getConnectionWithProps(props).close();

                  props = new Properties();
                  props.setProperty("useUnicode", "true");
                  props.setProperty("characterEncoding", "EUC_JP");
                  props.setProperty("characterSetResults", "EUC_JP");
                  getConnectionWithProps(props).close();
            }
      }

      /**
       * Tests fix for BUG#11259, autoReconnect ping causes exception on
       * connection startup.
       * 
       * @throws Exception
       *             if the test fails.
       */
01107       public void testBug11259() throws Exception {
            Connection dsConn = null;
            try {
                  Properties props = new Properties();
                  props.setProperty("autoReconnect", "true");
                  dsConn = getConnectionWithProps(props);
            } finally {
                  if (dsConn != null) {
                        dsConn.close();
                  }
            }
      }

      /**
       * Tests fix for BUG#11879 -- ReplicationConnection won't switch to slave,
       * throws "Catalog can't be null" exception.
       * 
       * @throws Exception
       *             if the test fails
       */
01127       public void testBug11879() throws Exception {
            if (runMultiHostTests()) {
                  Connection replConn = null;

                  try {
                        replConn = getMasterSlaveReplicationConnection();
                        replConn.setReadOnly(true);
                        replConn.setReadOnly(false);
                  } finally {
                        if (replConn != null) {
                              replConn.close();
                        }
                  }
            }
      }

      /**
       * Tests fix for BUG#11976 - maxPerformance.properties mis-spells
       * "elideSetAutoCommits".
       * 
       * @throws Exception
       *             if the test fails.
       */
01150       public void testBug11976() throws Exception {
            if (isRunningOnJdk131()) {
                  return; // test not valid on JDK-1.3.1
            }

            if (!versionMeetsMinimum(6, 0)) {
                  return; // server status is broken until MySQL-6.0
            }

            Properties props = new Properties();
            props.setProperty("useConfigs", "maxPerformance");

            Connection maxPerfConn = getConnectionWithProps(props);
            assertEquals(true,
                        ((com.mysql.jdbc.Connection) maxPerfConn)
                                    .getElideSetAutoCommits());
      }

      /**
       * Tests fix for BUG#12218, properties shared between master and slave with
       * replication connection.
       * 
       * @throws Exception
       *             if the test fails.
       */
01175       public void testBug12218() throws Exception {
            if (runMultiHostTests()) {
                  Connection replConn = null;

                  try {
                        replConn = getMasterSlaveReplicationConnection();
                        assertTrue(!((MySQLConnection) ((ReplicationConnection) replConn)
                                    .getMasterConnection())
                                    .hasSameProperties(((ReplicationConnection) replConn)
                                                .getSlavesConnection()));
                  } finally {
                        if (replConn != null) {
                              replConn.close();
                        }
                  }
            }
      }

      /**
       * Tests fix for BUG#12229 - explainSlowQueries hangs with server-side
       * prepared statements.
       * 
       * @throws Exception
       *             if the test fails.
       */
01200       public void testBug12229() throws Exception {
            createTable("testBug12229", "(`int_field` integer )");
            this.stmt.executeUpdate("insert into testBug12229 values (123456),(1)");

            Properties props = new Properties();
            props.put("profileSQL", "true");
            props.put("slowQueryThresholdMillis", "0");
            props.put("logSlowQueries", "true");
            props.put("explainSlowQueries", "true");
            props.put("useServerPrepStmts", "true");

            Connection explainConn = getConnectionWithProps(props);

            this.pstmt = explainConn
                        .prepareStatement("SELECT `int_field` FROM `testBug12229` WHERE `int_field` = ?");
            this.pstmt.setInt(1, 1);

            this.rs = this.pstmt.executeQuery();
            assertTrue(this.rs.next());

            this.rs = this.pstmt.executeQuery();
            assertTrue(this.rs.next());

            this.rs = this.pstmt.executeQuery();
            assertTrue(this.rs.next());
      }

      /**
       * Tests fix for BUG#12752 - Cp1251 incorrectly mapped to win1251 for
       * servers newer than 4.0.x.
       * 
       * @throws Exception
       *             if the test fails.
       */
01234       public void testBug12752() throws Exception {
            Properties props = new Properties();
            props.setProperty("characterEncoding", "Cp1251");
            getConnectionWithProps(props).close();
      }

      /**
       * Tests fix for BUG#12753, sessionVariables=....=...., doesn't work as it's
       * tokenized incorrectly.
       * 
       * @throws Exception
       *             if the test fails.
       */
01247       public void testBug12753() throws Exception {
            if (versionMeetsMinimum(4, 1)) {
                  Properties props = new Properties();
                  props.setProperty("sessionVariables", "sql_mode=ansi");

                  Connection sessionConn = null;

                  try {
                        sessionConn = getConnectionWithProps(props);

                        String sqlMode = getMysqlVariable(sessionConn, "sql_mode");
                        assertTrue(sqlMode.indexOf("ANSI") != -1);
                  } finally {
                        if (sessionConn != null) {
                              sessionConn.close();
                              sessionConn = null;
                        }
                  }
            }
      }

      /**
       * Tests fix for BUG#13048 - maxQuerySizeToLog is not respected.
       * 
       * @throws Exception
       *             if the test fails
       */
01274       public void testBug13048() throws Exception {

            Connection profileConn = null;
            PrintStream oldErr = System.err;

            try {
                  ByteArrayOutputStream bOut = new ByteArrayOutputStream();
                  System.setErr(new PrintStream(bOut));

                  Properties props = new Properties();
                  props.setProperty("profileSQL", "true");
                  props.setProperty("maxQuerySizeToLog", "2");
                  props.setProperty("logger", "com.mysql.jdbc.log.StandardLogger");

                  profileConn = getConnectionWithProps(props);

                  StringBuffer queryBuf = new StringBuffer("SELECT '");

                  for (int i = 0; i < 500; i++) {
                        queryBuf.append("a");
                  }

                  queryBuf.append("'");

                  this.rs = profileConn.createStatement().executeQuery(
                              queryBuf.toString());
                  this.rs.close();

                  String logString = new String(bOut.toString("ISO8859-1"));
                  assertTrue(logString.indexOf("... (truncated)") != -1);

                  bOut = new ByteArrayOutputStream();
                  System.setErr(new PrintStream(bOut));

                  this.rs = profileConn.prepareStatement(queryBuf.toString())
                              .executeQuery();
                  logString = new String(bOut.toString("ISO8859-1"));

                  assertTrue(logString.indexOf("... (truncated)") != -1);
            } finally {
                  System.setErr(oldErr);

                  if (profileConn != null) {
                        profileConn.close();
                  }

                  if (this.rs != null) {
                        ResultSet toClose = this.rs;
                        this.rs = null;
                        toClose.close();
                  }
            }
      }

      /**
       * Tests fix for BUG#13453 - can't use & or = in URL configuration values
       * (we now allow you to use www-form-encoding).
       * 
       * @throws Exception
       *             if the test fails
       */
01335       public void testBug13453() throws Exception {
            StringBuffer urlBuf = new StringBuffer(dbUrl);

            if (dbUrl.indexOf('?') == -1) {
                  urlBuf.append('?');
            } else {
                  urlBuf.append('&');
            }

            urlBuf.append("sessionVariables=@testBug13453='%25%26+%3D'");

            Connection encodedConn = null;

            try {
                  encodedConn = DriverManager.getConnection(urlBuf.toString(), null);

                  this.rs = encodedConn.createStatement().executeQuery(
                              "SELECT @testBug13453");
                  assertTrue(this.rs.next());
                  assertEquals("%& =", this.rs.getString(1));
            } finally {
                  if (this.rs != null) {
                        this.rs.close();
                        this.rs = null;
                  }

                  if (encodedConn != null) {
                        encodedConn.close();
                  }
            }
      }

      /**
       * Tests fix for BUG#15065 - Usage advisor complains about unreferenced
       * columns, even though they've been referenced.
       * 
       * @throws Exception
       *             if the test fails.
       */
01374       public void testBug15065() throws Exception {
            if (isRunningOnJdk131()) {
                  return; // test not valid on JDK-1.3.1
            }

            createTable("testBug15065", "(field1 int)");

            this.stmt.executeUpdate("INSERT INTO testBug15065 VALUES (1)");

            Connection advisorConn = null;
            Statement advisorStmt = null;

            try {
                  Properties props = new Properties();
                  props.setProperty("useUsageAdvisor", "true");
                  props.setProperty("logger", "com.mysql.jdbc.log.StandardLogger");

                  advisorConn = getConnectionWithProps(props);
                  advisorStmt = advisorConn.createStatement();

                  Method[] getMethods = ResultSet.class.getMethods();

                  PrintStream oldErr = System.err;

                  try {
                        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
                        System.setErr(new PrintStream(bOut));

                        HashMap methodsToSkipMap = new HashMap();

                        // Needs an actual URL
                        methodsToSkipMap.put("getURL", null);

                        // Java6 JDBC4.0 methods we don't implement
                        methodsToSkipMap.put("getNCharacterStream", null);
                        methodsToSkipMap.put("getNClob", null);
                        methodsToSkipMap.put("getNString", null);
                        methodsToSkipMap.put("getRowId", null);
                        methodsToSkipMap.put("getSQLXML", null);

                        for (int j = 0; j < 2; j++) {
                              for (int i = 0; i < getMethods.length; i++) {
                                    String methodName = getMethods[i].getName();

                                    if (methodName.startsWith("get")
                                                && !methodsToSkipMap.containsKey(methodName)) {
                                          Class[] parameterTypes = getMethods[i]
                                                      .getParameterTypes();

                                          if (parameterTypes.length == 1
                                                      && parameterTypes[0] == Integer.TYPE) {
                                                if (j == 0) {
                                                      this.rs = advisorStmt
                                                                  .executeQuery("SELECT COUNT(*) FROM testBug15065");
                                                } else {
                                                      this.rs = advisorConn
                                                                  .prepareStatement(
                                                                              "SELECT COUNT(*) FROM testBug15065")
                                                                  .executeQuery();
                                                }

                                                this.rs.next();

                                                try {

                                                      getMethods[i].invoke(this.rs,
                                                                  new Object[] { new Integer(1) });
                                                } catch (InvocationTargetException invokeEx) {
                                                      // we don't care about bad values, just that
                                                      // the
                                                      // column gets "touched"
                                                      if (!invokeEx
                                                                  .getCause()
                                                                  .getClass()
                                                                  .isAssignableFrom(
                                                                              java.sql.SQLException.class)
                                                                  && !invokeEx
                                                                              .getCause()
                                                                              .getClass()
                                                                              .getName()
                                                                              .equals("com.mysql.jdbc.NotImplemented")
                                                                  && !invokeEx
                                                                              .getCause()
                                                                              .getClass()
                                                                              .getName()
                                                                              .equals("java.sql.SQLFeatureNotSupportedException")) {
                                                            throw invokeEx;
                                                      }
                                                }

                                                this.rs.close();
                                                this.rs = null;
                                          }
                                    }
                              }
                        }

                        String logOut = bOut.toString("ISO8859-1");

                        if (logOut.indexOf(".Level") != -1) {
                              return; // we ignore for warnings
                        }

                        assertTrue("Usage advisor complained about columns:\n\n"
                                    + logOut, logOut.indexOf("columns") == -1);
                  } finally {
                        System.setErr(oldErr);
                  }
            } finally {
                  if (advisorConn != null) {
                        advisorConn.close();
                  }
            }
      }

      /**
       * Tests fix for BUG#15544, no "dos" character set in MySQL > 4.1.0
       * 
       * @throws Exception
       *             if the test fails
       */
01495       public void testBug15544() throws Exception {
            Properties props = new Properties();
            props.setProperty("characterEncoding", "Cp437");
            Connection dosConn = null;

            try {
                  dosConn = getConnectionWithProps(props);
            } finally {
                  if (dosConn != null) {
                        dosConn.close();
                  }
            }
      }

      public void testCSC5765() throws Exception {
            if (isRunningOnJdk131()) {
                  return; // test not valid on JDK-1.3.1
            }

            Properties props = new Properties();
            props.setProperty("useUnicode", "true");
            props.setProperty("characterEncoding", "utf8");
            props.setProperty("characterSetResults", "utf8");
            props.setProperty("connectionCollation", "utf8_bin");

            Connection utf8Conn = null;

            try {
                  utf8Conn = getConnectionWithProps(props);
                  this.rs = utf8Conn.createStatement().executeQuery(
                              "SHOW VARIABLES LIKE 'character_%'");
                  while (this.rs.next()) {
                        System.out.println(this.rs.getString(1) + " = "
                                    + this.rs.getString(2));
                  }

                  this.rs = utf8Conn.createStatement().executeQuery(
                              "SHOW VARIABLES LIKE 'collation_%'");
                  while (this.rs.next()) {
                        System.out.println(this.rs.getString(1) + " = "
                                    + this.rs.getString(2));
                  }
            } finally {
                  if (utf8Conn != null) {
                        utf8Conn.close();
                  }
            }
      }

      /**
       * 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.
       */
01555       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.
       */
01621       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");
            }

            String host = props.getProperty(NonRegisteringDriver.HOST_PROPERTY_KEY);

            if (!NonRegisteringDriver.isHostPropertiesList(host)) {
                  String port = props.getProperty(
                              NonRegisteringDriver.PORT_PROPERTY_KEY, "3306");

                  host = host + ":" + port;
            }

            props.remove("PORT");
            props.remove("HOST");

            StringBuffer newHostBuf = new StringBuffer();

            newHostBuf.append(host);

            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.
       */
01688       public void testBug24706() throws Exception {
            if (!versionMeetsMinimum(6, 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.
       */
01746       public void testBug25514() throws Exception {

            for (int i = 0; i < 10; i++) {
                  getConnectionWithProps((Properties) 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
       */
01807       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(), (Class[]) 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.
       */
01879       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
       */
01919       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.
       */
01953       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();
                  }
            }
      }

      public void testPropertiesDescriptionsKeys() throws Exception {
            DriverPropertyInfo[] dpi = new NonRegisteringDriver().getPropertyInfo(
                        dbUrl, null);

            for (int i = 0; i < dpi.length; i++) {
                  String description = dpi[i].description;
                  String propertyName = dpi[i].name;

                  if (description.indexOf("Missing error message for key '") != -1
                              || description.startsWith("!")) {
                        fail("Missing message for configuration property "
                                    + propertyName);
                  }

                  if (description.length() < 10) {
                        fail("Suspiciously short description for configuration property "
                                    + propertyName);
                  }
            }
      }

      public void testBug29106() throws Exception {
            ClassLoader cl = Thread.currentThread().getContextClassLoader();
            Class checkerClass = cl
                        .loadClass("com.mysql.jdbc.integration.jboss.MysqlValidConnectionChecker");
            ((MysqlValidConnectionChecker) checkerClass.newInstance())
                        .isValidConnection(this.conn);
      }

      public void testBug29852() throws Exception {
            Connection lbConn = getLoadBalancedConnection();
            assertTrue(!lbConn.getClass().getName().startsWith("com.mysql.jdbc"));
            lbConn.close();
      }

      /**
       * Test of a new feature to fix BUG 22643, specifying a "validation query"
       * in your connection pool that starts with "slash-star ping slash-star"
       * _exactly_ will cause the driver to " + instead send a ping to the server
       * (much lighter weight), and when using a ReplicationConnection or a
       * LoadBalancedConnection, will send the ping across all active connections.
       * 
       * @throws Exception
       */
02073       public void testBug22643() throws Exception {
            checkPingQuery(this.conn);

            Connection replConnection = getMasterSlaveReplicationConnection();

            try {
                  checkPingQuery(replConnection);
            } finally {
                  if (replConnection != null) {
                        replConnection.close();
                  }
            }

            Connection lbConn = getLoadBalancedConnection();

            try {
                  checkPingQuery(lbConn);
            } finally {
                  if (lbConn != null) {
                        lbConn.close();
                  }
            }
      }

      private void checkPingQuery(Connection c) throws SQLException {
            // Yes, I know we're sending 2, and looking for 1
            // that's part of the test, since we don't _really_
            // send the query to the server!
            String aPingQuery = "/* ping */ SELECT 2";
            Statement pingStmt = c.createStatement();
            PreparedStatement pingPStmt = null;

            this.rs = pingStmt.executeQuery(aPingQuery);
            assertTrue(this.rs.next());
            assertEquals(this.rs.getInt(1), 1);

            assertTrue(pingStmt.execute(aPingQuery));
            this.rs = pingStmt.getResultSet();
            assertTrue(this.rs.next());
            assertEquals(this.rs.getInt(1), 1);

            pingPStmt = c.prepareStatement(aPingQuery);

            assertTrue(pingPStmt.execute());
            this.rs = pingPStmt.getResultSet();
            assertTrue(this.rs.next());
            assertEquals(this.rs.getInt(1), 1);

            this.rs = pingPStmt.executeQuery();
            assertTrue(this.rs.next());
            assertEquals(this.rs.getInt(1), 1);

      }

      public void testBug31053() throws Exception {
            Properties props = new Properties();
            props.setProperty("connectTimeout", "2000");
            props.setProperty("loadBalanceStrategy", "random");

            Connection lbConn = getLoadBalancedConnection(2, "localhost:23", props);

            lbConn.setAutoCommit(false);

            for (int i = 0; i < 10; i++) {
                  lbConn.commit();
            }
      }

      public void testBug32877() throws Exception {
            Properties props = new Properties();
            props.setProperty("connectTimeout", "2000");
            props.setProperty("loadBalanceStrategy", "bestResponseTime");

            Connection lbConn = getLoadBalancedConnection(1, "localhost:23", props);

            lbConn.setAutoCommit(false);

            long begin = System.currentTimeMillis();

            for (int i = 0; i < 4; i++) {
                  lbConn.commit();
            }

            assertTrue(System.currentTimeMillis() - begin < 10000);
      }

      /**
       * Tests fix for BUG#33734 - NullPointerException when using client-side
       * prepared statements and enabling caching of prepared statements (only
       * present in nightly builds of 5.1).
       * 
       * @throws Exception
       */
02166       public void testBug33734() throws Exception {
            Connection testConn = getConnectionWithProps("cachePrepStmts=true,useServerPrepStmts=false");
            try {
                  testConn.prepareStatement("SELECT 1");
            } finally {
                  testConn.close();
            }
      }

      /** 34703 [NEW]: isValild() aborts Connection on timeout */

02177       public void testBug34703() throws Exception {
            if (!com.mysql.jdbc.Util.isJdbc4()) {
                  return;
            }

            Method isValid = java.sql.Connection.class.getMethod("isValid",
                        new Class[] { Integer.TYPE });

            Connection newConn = getConnectionWithProps((Properties) null);
            isValid.invoke(newConn, new Object[] { new Integer(1) });
            Thread.sleep(2000);
            assertTrue(((Boolean) isValid.invoke(newConn,
                        new Object[] { new Integer(0) })).booleanValue());
      }

      public void testBug34937() throws Exception {
            com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource ds = new com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource();
            StringBuffer urlBuf = new StringBuffer();
            urlBuf.append(getMasterSlaveUrl());
            urlBuf.append("?");
            Properties props = getMasterSlaveProps();
            String key = null;

            Enumeration keyEnum = props.keys();

            while (keyEnum.hasMoreElements()) {
                  key = (String) keyEnum.nextElement();
                  urlBuf.append(key);
                  urlBuf.append("=");
                  urlBuf.append(props.get(key));
                  urlBuf.append("&");
            }

            String url = urlBuf.toString();
            url = "jdbc:mysql:replication:"
                        + url.substring(url.indexOf("jdbc:mysql:")
                                    + "jdbc:mysql:".length());
            ds.setURL(url);
            Connection replConn = ds.getPooledConnection().getConnection();

            boolean readOnly = false;

            for (int i = 0; i < 10; i++) {
                  this.rs = replConn.createStatement().executeQuery("SELECT 1");
                  assertTrue(this.rs.next());
                  this.rs = replConn.prepareStatement("SELECT 1").executeQuery();
                  assertTrue(this.rs.next());
                  readOnly = !readOnly;
                  replConn.setReadOnly(readOnly);
            }
      }

      public void testBug35660() throws Exception {

            Connection lbConn = getLoadBalancedConnection(null);
            Connection lbConn2 = getLoadBalancedConnection(null);

            try {
                  assertEquals(this.conn, this.conn);
                  assertEquals(lbConn, lbConn);
                  assertFalse(lbConn.equals(this.conn));
                  assertFalse(lbConn.equals(lbConn2));
            } finally {
                  lbConn.close();
                  lbConn2.close();
            }
      }

      public void testBug37570() throws Exception {
            Properties props = new Properties();
            props.setProperty("characterEncoding", "utf-8");
            props.setProperty("passwordCharacterEncoding", "utf-8");

            Connection adminConn = getAdminConnectionWithProps(props);

            if (adminConn != null) {

                  String unicodePassword = "\u0430\u0431\u0432"; // Cyrillic string
                  String user = "bug37570";
                  Statement adminStmt = adminConn.createStatement();

                  adminStmt.executeUpdate("grant usage on *.* to '" + user
                              + "'@'127.0.0.1' identified by 'foo'");
                  adminStmt.executeUpdate("update mysql.user set password=PASSWORD('"
                              + unicodePassword + "') where user = '" + user + "'");
                  adminStmt.executeUpdate("flush privileges");

                  try {
                        ((MySQLConnection) adminConn).changeUser(user, unicodePassword);
                  } catch (SQLException sqle) {
                        assertTrue("Connection with non-latin1 password failed", false);
                  }

            }
      }

      public void testUnreliableSocketFactory() throws Exception {
            Properties props = new Properties();
            props.setProperty("loadBalanceStrategy", "bestResponseTime");
            Connection conn2 = this.getUnreliableLoadBalancedConnection(
                        new String[] { "first", "second" }, props);
            assertNotNull("Connection should not be null", conn);

            conn2.createStatement().execute("SELECT 1");
            conn2.createStatement().execute("SELECT 1");
            // both connections are live now
            UnreliableSocketFactory.downHost("first");
            UnreliableSocketFactory.downHost("second");
            try {
                  conn2.createStatement().execute("SELECT 1");
                  fail("Should hang here.");
            } catch (SQLException sqlEx) {
                  assertEquals("08S01", sqlEx.getSQLState());
            }
      }

      public void testBug43421() throws Exception {

            Properties props = new Properties();
            props.setProperty("loadBalanceStrategy", "bestResponseTime");

            Connection conn2 = this.getUnreliableLoadBalancedConnection(
                        new String[] { "first", "second" }, props);

            assertNotNull("Connection should not be null", conn2);

            conn2.createStatement().execute("SELECT 1");
            conn2.createStatement().execute("SELECT 1");
            // both connections are live now
            UnreliableSocketFactory.downHost("second");
            UnreliableSocketFactory.downHost("first");
            try {
                  conn2.createStatement().execute("/* ping */");
                  fail("Pings will not succeed when one host is down and using loadbalance w/o global blacklist.");
            } catch (SQLException sqlEx) {
            }

            UnreliableSocketFactory.flushAllHostLists();
            props = new Properties();
            props.setProperty("globalBlacklistTimeout", "200");
            props.setProperty("loadBalanceStrategy", "bestResponseTime");

            conn2 = this.getUnreliableLoadBalancedConnection(new String[] {
                        "first", "second" }, props);

            assertNotNull("Connection should not be null", conn);

            conn2.createStatement().execute("SELECT 1");
            conn2.createStatement().execute("SELECT 1");
            // both connections are live now
            UnreliableSocketFactory.downHost("second");
            try {
                  conn2.createStatement().execute("/* ping */");
            } catch (SQLException sqlEx) {
                  fail("Pings should succeed even though host is down.");
            }
      }

      public void testBug48442() throws Exception {

            Properties props = new Properties();
            props.setProperty("loadBalanceStrategy", "random");
            Connection conn2 = this.getUnreliableLoadBalancedConnection(
                        new String[] { "first", "second" }, props);

            assertNotNull("Connection should not be null", conn2);
            conn2.setAutoCommit(false);
            UnreliableSocketFactory.downHost("second");
            int hc = 0;
            try {
                  conn2.createStatement().execute("SELECT 1");
            } catch (SQLException e) {
                  conn2.createStatement().execute("SELECT 1");
            }
            hc = conn2.hashCode();
            conn2.commit();
            UnreliableSocketFactory.dontDownHost("second");
            UnreliableSocketFactory.downHost("first");
            try {
                  conn2.commit();
            } catch (SQLException e) {
            }
            assertTrue(hc == conn2.hashCode());

      }

      public void testBug45171() throws Exception {
            List statementsToTest = new LinkedList();
            statementsToTest.add(this.conn.createStatement());
            statementsToTest.add(((com.mysql.jdbc.Connection) this.conn)
                        .clientPrepareStatement("SELECT 1"));
            statementsToTest.add(((com.mysql.jdbc.Connection) this.conn)
                        .clientPrepareStatement("SELECT 1",
                                    Statement.RETURN_GENERATED_KEYS));
            statementsToTest.add(((com.mysql.jdbc.Connection) this.conn)
                        .clientPrepareStatement("SELECT 1", new int[0]));
            statementsToTest.add(((com.mysql.jdbc.Connection) this.conn)
                        .clientPrepareStatement("SELECT 1", new String[0]));
            statementsToTest.add(((com.mysql.jdbc.Connection) this.conn)
                        .serverPrepareStatement("SELECT 1"));
            statementsToTest.add(((com.mysql.jdbc.Connection) this.conn)
                        .serverPrepareStatement("SELECT 1",
                                    Statement.RETURN_GENERATED_KEYS));
            statementsToTest.add(((com.mysql.jdbc.Connection) this.conn)
                        .serverPrepareStatement("SELECT 1", new int[0]));
            statementsToTest.add(((com.mysql.jdbc.Connection) this.conn)
                        .serverPrepareStatement("SELECT 1", new String[0]));

            Iterator iter = statementsToTest.iterator();

            while (iter.hasNext()) {
                  Statement toTest = (Statement) iter.next();
                  assertEquals(toTest.getResultSetType(), ResultSet.TYPE_FORWARD_ONLY);
                  assertEquals(toTest.getResultSetConcurrency(),
                              ResultSet.CONCUR_READ_ONLY);
            }

      }

      /**
       * Tests fix for BUG#44587, provide last packet sent/received timing in all
       * connection failure errors.
       */
02400       public void testBug44587() throws Exception {
            Exception e = null;
            String msg = SQLError.createLinkFailureMessageBasedOnHeuristics(
                        (MySQLConnection) this.conn, System.currentTimeMillis() - 1000,
                        System.currentTimeMillis() - 2000, e, false);
            assertTrue(containsMessage(msg,
                        "CommunicationsException.ServerPacketTimingInfo"));
      }

      /**
       * Tests fix for BUG#45419, ensure that time is not converted to seconds
       * before being reported as milliseconds.
       */
02413       public void testBug45419() throws Exception {
            Exception e = null;
            String msg = SQLError.createLinkFailureMessageBasedOnHeuristics(
                        (MySQLConnection) this.conn, System.currentTimeMillis() - 1000,
                        System.currentTimeMillis() - 2000, e, false);
            Matcher m = Pattern.compile("([\\d\\,\\.]+)", Pattern.MULTILINE)
                        .matcher(msg);
            assertTrue(m.find());
            assertTrue(Long.parseLong(m.group(0).replaceAll("[,.]", "")) >= 2000);
            assertTrue(Long.parseLong(m.group(1).replaceAll("[,.]", "")) >= 1000);
      }

      public static boolean containsMessage(String msg, String key) {
            String[] expectedFragments = Messages.getString(key).split("\\{\\d\\}");
            for (int i = 0; i < expectedFragments.length; i++) {
                  if (msg.indexOf(expectedFragments[i]) < 0) {
                        return false;
                  }
            }
            return true;
      }

      public void testBug46637() throws Exception {
            NonRegisteringDriver driver = new NonRegisteringDriver();
            Properties props = new Properties();
            copyBasePropertiesIntoProps(props, driver);
            String hostname = getPortFreeHostname(props, driver);
            UnreliableSocketFactory.flushAllHostLists();
            UnreliableSocketFactory.downHost(hostname);

            try {
                  Connection noConn = getConnectionWithProps("socketFactory=testsuite.UnreliableSocketFactory");
            } catch (SQLException sqlEx) {
                  assertTrue(sqlEx.getMessage().indexOf("has not received") != -1);
            } finally {
                  UnreliableSocketFactory.flushAllHostLists();
            }
      }

      public void testBug32216() throws Exception {
            checkBug32216("www.mysql.com", "12345", "my_database");
            checkBug32216("www.mysql.com", null, "my_database");
      }

      private void checkBug32216(String host, String port, String dbname)
                  throws SQLException {
            NonRegisteringDriver driver = new NonRegisteringDriver();

            StringBuffer url = new StringBuffer("jdbc:mysql://");
            url.append(host);

            if (port != null) {
                  url.append(':');
                  url.append(port);
            }

            url.append('/');
            url.append(dbname);

            Properties result = driver.parseURL(url.toString(), new Properties());

            assertEquals("hostname not equal", host,
                        result.getProperty(Driver.HOST_PROPERTY_KEY));
            if (port != null) {
                  assertEquals("port not equal", port,
                              result.getProperty(Driver.PORT_PROPERTY_KEY));
            } else {
                  assertEquals("port default incorrect", "3306",
                              result.getProperty(Driver.PORT_PROPERTY_KEY));
            }

            assertEquals("dbname not equal", dbname,
                        result.getProperty(Driver.DBNAME_PROPERTY_KEY));
      }

      public void testBug44324() throws Exception {
            createTable(
                        "bug44324",
                        "(Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, SomeVChar VARCHAR(10)) ENGINE=MyISAM;");

            try {
                  this.stmt
                              .executeUpdate("INSERT INTO bug44324 values (null, 'Some text much longer than 10 characters')");
            } catch (MysqlDataTruncation sqlEx) {
                  assertTrue(0 != sqlEx.getErrorCode());
            }

      }

      public void testBug46925() throws Exception {
            MysqlXADataSource xads1 = new MysqlXADataSource();
            MysqlXADataSource xads2 = new MysqlXADataSource();

            Xid txid = new MysqlXid(new byte[] { 0x1 }, new byte[] { 0xf }, 3306);

            xads1.setPinGlobalTxToPhysicalConnection(true);
            xads1.setUrl(dbUrl);

            xads2.setPinGlobalTxToPhysicalConnection(true);
            xads2.setUrl(dbUrl);

            XAConnection c1 = xads1.getXAConnection();
            assertTrue(c1 instanceof SuspendableXAConnection);
            // start a transaction on one connection
            c1.getXAResource().start(txid, XAResource.TMNOFLAGS);
            c1.getXAResource().end(txid, XAResource.TMSUCCESS);

            XAConnection c2 = xads2.getXAConnection();
            assertTrue(c2 instanceof SuspendableXAConnection);
            // prepare on another one. Since we are using a "pinned" connection
            // we should have the same "currentXAConnection" for both
            // SuspendableXAConnection
            c2.getXAResource().prepare(txid); // this will fail without the fix.
            c2.getXAResource().commit(txid, false);
      }

      public void testBug47494() throws Exception {
            try {
                  getConnectionWithProps("jdbc:mysql://localhost:9999/test?socketFactory=testsuite.regression.ConnectionRegressionTest$PortNumberSocketFactory");
            } catch (SQLException sqlEx) {
                  assertTrue(sqlEx.getCause() instanceof IOException);
            }

            try {
                  getConnectionWithProps("jdbc:mysql://:9999/test?socketFactory=testsuite.regression.ConnectionRegressionTest$PortNumberSocketFactory");
            } catch (SQLException sqlEx) {
                  assertTrue(sqlEx.getCause() instanceof IOException);
            }

            try {
                  getConnectionWithProps("jdbc:mysql://:9999,:9999/test?socketFactory=testsuite.regression.ConnectionRegressionTest$PortNumberSocketFactory");
            } catch (SQLException sqlEx) {
                  assertTrue(sqlEx.getCause() instanceof IOException);
            }

            try {
                  getConnectionWithProps("jdbc:mysql://localhost:9999,localhost:9999/test?socketFactory=testsuite.regression.ConnectionRegressionTest$PortNumberSocketFactory");
            } catch (SQLException sqlEx) {
                  assertTrue(sqlEx.getCause() instanceof IOException);
            }
      }

02555       public static class PortNumberSocketFactory extends StandardSocketFactory {

            public PortNumberSocketFactory() {

            }

02561             public Socket connect(String hostname, int portNumber, Properties props)
                        throws SocketException, IOException {
                  assertEquals(9999, portNumber);

                  throw new IOException();
            }

      }

      public void testBug48486() throws Exception {

            Properties props = new NonRegisteringDriver().parseURL(dbUrl, null);
            String host = props.getProperty(NonRegisteringDriver.HOST_PROPERTY_KEY,
                        "localhost");
            String port = props.getProperty(NonRegisteringDriver.PORT_PROPERTY_KEY,
                        "3306");

            String hostSpec = host;

            if (!NonRegisteringDriver.isHostPropertiesList(host)) {
                  hostSpec = host + ":" + port;
            }

            String database = props
                        .getProperty(NonRegisteringDriver.DBNAME_PROPERTY_KEY);
            removeHostRelatedProps(props);
            props.remove(NonRegisteringDriver.DBNAME_PROPERTY_KEY);

            StringBuilder configs = new StringBuilder();
            for (@SuppressWarnings("rawtypes")
            Map.Entry entry : props.entrySet()) {
                  configs.append(entry.getKey());
                  configs.append("=");
                  configs.append(entry.getValue());
                  configs.append("&");
            }

            String newUrl = String.format("jdbc:mysql:loadbalance://%s,%s/%s?%s",
                        hostSpec, hostSpec, database, configs.toString());

            MysqlConnectionPoolDataSource ds = new MysqlConnectionPoolDataSource();
            ds.setUrl(newUrl);

            Connection c = ds.getPooledConnection().getConnection();
            c.createStatement().executeQuery("SELECT 1");
            c.prepareStatement("SELECT 1").executeQuery();
      }

      public void testBug48605() throws Exception {
            Properties props = new Properties();
            props.setProperty("loadBalanceStrategy", "random");
            props.setProperty("selfDestructOnPingMaxOperations", "5");
            Connection conn2 = this.getUnreliableLoadBalancedConnection(
                        new String[] { "first", "second" }, props);

            assertNotNull("Connection should not be null", conn2);
            conn2.setAutoCommit(false);
            conn2.createStatement().execute("SELECT 1");
            conn2.createStatement().execute("SELECT 1");
            conn2.createStatement().execute("SELECT 1");
            conn2.createStatement().execute("SELECT 1");
            conn2.createStatement().execute("SELECT 1");
            conn2.commit();
            try {
                  conn2.createStatement().execute("/* ping */ SELECT 1");
                  // don't care about this - we want the SQLExceptions passed up early
                  // for ping failures, rather
                  // than waiting until commit/rollback and pickNewConnection().
            } catch (SQLException e) {
            }
            assertTrue(conn2.isClosed());
            try {
                  conn2.createStatement().execute("SELECT 1");
                  fail("Should throw Exception, connection is closed.");
            } catch (SQLException e) {
            }
      }

      public void testBug49700() throws Exception {
            Connection c = getConnectionWithProps("sessionVariables=@foo='bar'");
            assertEquals("bar", getSingleIndexedValueWithQuery(c, 1, "SELECT @foo"));
            ((com.mysql.jdbc.Connection) c).resetServerState();
            assertEquals("bar", getSingleIndexedValueWithQuery(c, 1, "SELECT @foo"));
      }

      public void testBug51266() throws Exception {
            Properties props = new Properties();
            props.setProperty("roundRobinLoadBalance", "true"); // shouldn't be
                                                                                          // needed, but used
                                                                                          // in reported bug,
                                                                                          // it's removed by
                                                                                          // the driver
            Set downedHosts = new HashSet();
            downedHosts.add("first");

            // this loop will hang on the first unreliable host if the bug isn't
            // fixed.
            for (int i = 0; i < 20; i++) {
                  getUnreliableLoadBalancedConnection(
                              new String[] { "first", "second" }, props, downedHosts)
                              .close();
            }
      }

      // Tests fix for Bug#51643 - connection chosen by load balancer "sticks" to
      // statements
      // that live past commit()/rollback().

      public void testBug51643() throws Exception {
            Properties props = new Properties();
            props.setProperty("loadBalanceStrategy",
                        "com.mysql.jdbc.SequentialBalanceStrategy");

            Connection lbConn = getUnreliableLoadBalancedConnection(new String[] {
                        "first", "second" }, props);
            try {
                  PreparedStatement cPstmt = lbConn
                              .prepareStatement("SELECT connection_id()");
                  PreparedStatement serverPstmt = lbConn
                              .prepareStatement("SELECT connection_id()");
                  Statement plainStmt = lbConn.createStatement();

                  lbConn.setAutoCommit(false);
                  this.rs = cPstmt.executeQuery();
                  this.rs.next();
                  String cPstmtConnId = this.rs.getString(1);

                  this.rs = serverPstmt.executeQuery();
                  this.rs.next();
                  String serverPstmtConnId = this.rs.getString(1);

                  this.rs = plainStmt.executeQuery("SELECT connection_id()");
                  this.rs.next();
                  String plainStmtConnId = this.rs.getString(1);
                  lbConn.commit();
                  lbConn.setAutoCommit(false);

                  this.rs = cPstmt.executeQuery();
                  this.rs.next();
                  String cPstmtConnId2 = this.rs.getString(1);
                  assertFalse(cPstmtConnId2.equals(cPstmtConnId));

                  this.rs = serverPstmt.executeQuery();
                  this.rs.next();
                  String serverPstmtConnId2 = this.rs.getString(1);
                  assertFalse(serverPstmtConnId2.equals(serverPstmtConnId));

                  this.rs = plainStmt.executeQuery("SELECT connection_id()");
                  this.rs.next();
                  String plainStmtConnId2 = this.rs.getString(1);
                  assertFalse(plainStmtConnId2.equals(plainStmtConnId));
            } finally {
                  lbConn.close();
            }
      }

      public void testBug51783() throws Exception {
            Properties props = new Properties();
            props.setProperty("loadBalanceStrategy",
                        ForcedLoadBalanceStrategy.class.getName());
            props.setProperty("loadBalanceBlacklistTimeout", "5000");
            props.setProperty("loadBalancePingTimeout", "100");
            props.setProperty("loadBalanceValidateConnectionOnSwapServer", "true");

            String portNumber = new NonRegisteringDriver().parseURL(dbUrl, null)
                        .getProperty(NonRegisteringDriver.PORT_PROPERTY_KEY);

            if (portNumber == null) {
                  portNumber = "3306";
            }

            ForcedLoadBalanceStrategy.forceFutureServer("first:" + portNumber, -1);
            Connection conn2 = this.getUnreliableLoadBalancedConnection(
                        new String[] { "first", "second" }, props);
            conn2.setAutoCommit(false);
            conn2.createStatement().execute("SELECT 1");
            ForcedLoadBalanceStrategy.forceFutureServer("second:" + portNumber, -1);
            UnreliableSocketFactory.downHost("second");
            try {
                  conn2.commit(); // will be on second after this
                  assertTrue("Connection should be closed", conn2.isClosed());
            } catch (SQLException e) {
                  fail("Should not error because failure to get another server.");
            }
            conn2.close();

            props = new Properties();
            props.setProperty("loadBalanceStrategy",
                        ForcedLoadBalanceStrategy.class.getName());
            props.setProperty("loadBalanceBlacklistTimeout", "5000");
            props.setProperty("loadBalancePingTimeout", "100");
            props.setProperty("loadBalanceValidateConnectionOnSwapServer", "false");
            ForcedLoadBalanceStrategy.forceFutureServer("first:" + portNumber, -1);
            conn2 = this.getUnreliableLoadBalancedConnection(new String[] {
                        "first", "second" }, props);
            conn2.setAutoCommit(false);
            conn2.createStatement().execute("SELECT 1");
            ForcedLoadBalanceStrategy.forceFutureServer("second:" + portNumber, 1);
            UnreliableSocketFactory.downHost("second");
            try {
                  conn2.commit(); // will be on second after this
                  assertFalse(
                              "Connection should not be closed, should be able to connect to first",
                              conn2.isClosed());
            } catch (SQLException e) {
                  fail("Should not error because failure to get another server.");
            }
      }

02770       public static class ForcedLoadBalanceStrategy extends RandomBalanceStrategy {

            private static String forcedFutureServer = null;
            private static int forceFutureServerTimes = 0;

            public static void forceFutureServer(String host, int times) {
                  forcedFutureServer = host;
                  forceFutureServerTimes = times;
            }

            public com.mysql.jdbc.ConnectionImpl pickConnection(
                        LoadBalancingConnectionProxy proxy, List configuredHosts,
                        Map liveConnections, long[] responseTimes, int numRetries)
                        throws SQLException {
                  if (forcedFutureServer == null || forceFutureServerTimes == 0) {
                        return super.pickConnection(proxy, configuredHosts,
                                    liveConnections, responseTimes, numRetries);
                  }
                  if (forceFutureServerTimes > 0) {
                        forceFutureServerTimes--;
                  }
                  ConnectionImpl conn = (ConnectionImpl) liveConnections
                              .get(forcedFutureServer);

                  if (conn == null) {
                        conn = proxy.createConnectionForHost(forcedFutureServer);

                  }
                  return conn;
            }

02801             public void destroy() {
                  super.destroy();

            }

            public void init(com.mysql.jdbc.Connection conn, Properties props)
                        throws SQLException {
                  super.init(conn, props);

            }

      }

      public void testAutoCommitLB() throws Exception {
            Properties props = new Properties();
            props.setProperty("loadBalanceStrategy",
                        CountingReBalanceStrategy.class.getName());
            props.setProperty("loadBalanceAutoCommitStatementThreshold", "3");

            String portNumber = new NonRegisteringDriver().parseURL(dbUrl, null)
                        .getProperty(NonRegisteringDriver.PORT_PROPERTY_KEY);

            if (portNumber == null) {
                  portNumber = "3306";
            }

            Connection conn2 = this.getUnreliableLoadBalancedConnection(
                        new String[] { "first", "second" }, props);
            conn2.setAutoCommit(true);
            CountingReBalanceStrategy.resetTimesRebalanced();
            conn2.createStatement().execute("SELECT 1");
            conn2.createStatement().execute("SELECT 2");
            assertEquals(0, CountingReBalanceStrategy.getTimesRebalanced());
            conn2.createStatement().execute("SELECT 3");
            assertEquals(1, CountingReBalanceStrategy.getTimesRebalanced());
            conn2.setAutoCommit(false);
            CountingReBalanceStrategy.resetTimesRebalanced();
            assertEquals(0, CountingReBalanceStrategy.getTimesRebalanced());
            conn2.createStatement().execute("SELECT 1");
            conn2.createStatement().execute("SELECT 2");
            conn2.createStatement().execute("SELECT 3");
            assertEquals(0, CountingReBalanceStrategy.getTimesRebalanced());
            conn2.close();

            props.remove("loadBalanceAutoCommitStatementThreshold");
            conn2 = this.getUnreliableLoadBalancedConnection(new String[] {
                        "first", "second" }, props);
            conn2.setAutoCommit(true);
            CountingReBalanceStrategy.resetTimesRebalanced();
            conn2.createStatement().execute("SELECT 1");
            conn2.createStatement().execute("SELECT 2");
            conn2.createStatement().execute("SELECT 3");
            assertEquals(0, CountingReBalanceStrategy.getTimesRebalanced());
            conn2.setAutoCommit(false);
            CountingReBalanceStrategy.resetTimesRebalanced();
            assertEquals(0, CountingReBalanceStrategy.getTimesRebalanced());
            conn2.createStatement().execute("SELECT 1");
            conn2.createStatement().execute("SELECT 2");
            conn2.createStatement().execute("SELECT 3");
            assertEquals(0, CountingReBalanceStrategy.getTimesRebalanced());
            conn2.close();

            props.setProperty("loadBalanceAutoCommitStatementThreshold", "3");
            props.setProperty("loadBalanceAutoCommitStatementRegex", ".*2.*");
            conn2 = this.getUnreliableLoadBalancedConnection(new String[] {
                        "first", "second" }, props);
            conn2.setAutoCommit(true);
            CountingReBalanceStrategy.resetTimesRebalanced();
            conn2.createStatement().execute("SELECT 1");
            conn2.createStatement().execute("SELECT 2");
            conn2.createStatement().execute("SELECT 3");
            conn2.createStatement().execute("SELECT 2");
            assertEquals(0, CountingReBalanceStrategy.getTimesRebalanced());
            conn2.createStatement().execute("SELECT 2");
            assertEquals(1, CountingReBalanceStrategy.getTimesRebalanced());
            conn2.close();

      }

02880       public static class CountingReBalanceStrategy extends RandomBalanceStrategy {

            private static int rebalancedTimes = 0;

            public static int getTimesRebalanced() {
                  return rebalancedTimes;
            }

            public static void resetTimesRebalanced() {
                  rebalancedTimes = 0;
            }

            public com.mysql.jdbc.ConnectionImpl pickConnection(
                        LoadBalancingConnectionProxy proxy, List configuredHosts,
                        Map liveConnections, long[] responseTimes, int numRetries)
                        throws SQLException {
                  rebalancedTimes++;
                  return super.pickConnection(proxy, configuredHosts,
                              liveConnections, responseTimes, numRetries);

            }

02902             public void destroy() {
                  super.destroy();

            }

            public void init(com.mysql.jdbc.Connection conn, Properties props)
                        throws SQLException {
                  super.init(conn, props);

            }

      }

      public void testBug56429() throws Exception {
            Properties props = new Driver().parseURL(BaseTestCase.dbUrl, null);
            props.setProperty("autoReconnect", "true");
            props.setProperty("socketFactory", "testsuite.UnreliableSocketFactory");

            Properties urlProps = new NonRegisteringDriver().parseURL(
                        BaseTestCase.dbUrl, null);

            String host = urlProps.getProperty(Driver.HOST_PROPERTY_KEY);
            String port = urlProps.getProperty(Driver.PORT_PROPERTY_KEY);

            props.remove(Driver.HOST_PROPERTY_KEY);
            props.remove(Driver.NUM_HOSTS_PROPERTY_KEY);
            props.remove(Driver.HOST_PROPERTY_KEY + ".1");
            props.remove(Driver.PORT_PROPERTY_KEY + ".1");

            props.setProperty("queriesBeforeRetryMaster", "50");
            props.setProperty("maxReconnects", "1");

            UnreliableSocketFactory.mapHost("master", host);
            UnreliableSocketFactory.mapHost("slave", host);

            Connection failoverConnection = null;

            try {
                  failoverConnection = getConnectionWithProps("jdbc:mysql://master:"
                              + port + ",slave:" + port + "/", props);

                  String userHost = getSingleIndexedValueWithQuery(1, "SELECT USER()")
                              .toString();
                  String[] userParts = userHost.split("@");

                  this.rs = this.stmt.executeQuery("SHOW PROCESSLIST");

                  int startConnCount = 0;

                  while (this.rs.next()) {
                        if (this.rs.getString("User").equals(userParts[0])
                                    && this.rs.getString("Host").equals(userParts[1])) {
                              startConnCount++;
                        }
                  }

                  assert (startConnCount > 0);

                  failoverConnection.setAutoCommit(false); // this will fail if state
                                                                                    // not copied over

                  for (int i = 0; i < 20; i++) {

                        failoverConnection.commit();
                  }

                  this.rs = this.stmt.executeQuery("SHOW PROCESSLIST");

                  int endConnCount = 0;

                  while (this.rs.next()) {
                        if (this.rs.getString("User").equals(userParts[0])
                                    && this.rs.getString("Host").equals(userParts[1])) {
                              endConnCount++;
                        }
                  }

                  assert (endConnCount > 0);

                  if (endConnCount - startConnCount >= 20) { // this may be bogus if
                                                                                    // run on a real system,
                                                                                    // we should probably
                                                                                    // look to see they're
                                                                                    // coming from this
                                                                                    // testsuite?
                        fail("We're leaking connections even when not failed over");
                  }
            } finally {
                  if (failoverConnection != null) {
                        failoverConnection.close();
                  }
            }
      }

      public void testBug56955() throws Exception {
            assertEquals("JKS",
                        ((com.mysql.jdbc.Connection) this.conn)
                                    .getTrustCertificateKeyStoreType());
            assertEquals("JKS",
                        ((com.mysql.jdbc.Connection) this.conn)
                                    .getClientCertificateKeyStoreType());
      }

      public void testBug57262() throws Exception {
            Properties props = new Properties();
            props.setProperty("characterEncoding", "utf-8");
            props.setProperty("useUnicode", "true");
            props.setProperty("useOldUTF8Behavior", "true");

            Connection c = getConnectionWithProps(props);
            ResultSet rs = c.createStatement().executeQuery(
                        "SHOW SESSION VARIABLES LIKE 'character_set_connection'");
            rs.next();
            assertEquals("latin1", rs.getString(2));
      }
      
      public void testBug58706() throws Exception {
            Properties props = new Driver().parseURL(BaseTestCase.dbUrl, null);
            props.setProperty("autoReconnect", "true");
            props.setProperty("socketFactory", "testsuite.UnreliableSocketFactory");

            Properties urlProps = new NonRegisteringDriver().parseURL(this.dbUrl,
                        null);

            String host = urlProps.getProperty(Driver.HOST_PROPERTY_KEY);
            String port = urlProps.getProperty(Driver.PORT_PROPERTY_KEY);

            props.remove(Driver.HOST_PROPERTY_KEY);
            props.remove(Driver.NUM_HOSTS_PROPERTY_KEY);
            props.remove(Driver.HOST_PROPERTY_KEY + ".1");
            props.remove(Driver.PORT_PROPERTY_KEY + ".1");

            props.setProperty("queriesBeforeRetryMaster", "0");
            props.setProperty("failOverReadOnly", "false");
            props.setProperty("secondsBeforeRetryMaster", "1");

            UnreliableSocketFactory.mapHost("master", host);
            UnreliableSocketFactory.mapHost("slave", host);

            Connection failoverConnection = null;

            try {
                  failoverConnection = getConnectionWithProps("jdbc:mysql://master:"
                              + port + ",slave:" + port + "/", props);
                  failoverConnection.setAutoCommit(false);

                  assertTrue(((com.mysql.jdbc.Connection)failoverConnection).isMasterConnection());
                  
                  for (int i = 0; i < 50; i++) {
                        failoverConnection.createStatement().executeQuery("SELECT 1");
                  }

                  UnreliableSocketFactory.downHost("master");
                  
                  try {
                        failoverConnection.createStatement().executeQuery("SELECT 1"); // this should fail and trigger failover
                        fail("Expected exception");
                  } catch (SQLException sqlEx) {
                        assertEquals("08S01", sqlEx.getSQLState());
                  }

                  failoverConnection.setAutoCommit(true);
                  assertTrue(!((com.mysql.jdbc.Connection)failoverConnection).isMasterConnection());
                  assertTrue(!failoverConnection.isReadOnly());
                  failoverConnection.createStatement().executeQuery("SELECT 1");
                  failoverConnection.createStatement().executeQuery("SELECT 1");
                  UnreliableSocketFactory.dontDownHost("master");
                  Thread.sleep(2000);
                  failoverConnection.setAutoCommit(true);
                  failoverConnection.createStatement().executeQuery("SELECT 1");
                  assertTrue(((com.mysql.jdbc.Connection)failoverConnection).isMasterConnection());
                  failoverConnection.createStatement().executeQuery("SELECT 1");
            } finally {
                  UnreliableSocketFactory.flushAllHostLists();

                  if (failoverConnection != null) {
                        failoverConnection.close();
                  }
            }
      }
      
      public void testStatementComment() throws Exception {
            Connection c = getConnectionWithProps("autoGenerateTestcaseScript=true,logger=StandardLogger");
            PrintStream oldErr = System.err;
            
            try {
                  ByteArrayOutputStream bOut = new ByteArrayOutputStream();
                  PrintStream printStream = new PrintStream(bOut);
                  System.setErr(printStream);
                  
                  ((com.mysql.jdbc.Connection)c).setStatementComment("Hi there");
                  c.setAutoCommit(false);
                  
                  c.createStatement().execute("SELECT 1");
                  c.commit();
                  c.rollback();
                  Pattern pattern = Pattern.compile("Hi");
                  String loggedData = new String(bOut.toByteArray());
                  Matcher matcher = pattern.matcher(loggedData);
                  int count = 0;
                  while (matcher.find()) {
                        count++;
                  }
                  
                  assertEquals(4, count);
            } finally {
                  System.setErr(oldErr);
            }
      }
      
      public void testReconnectWithCachedConfig() throws Exception {
            Connection rConn = getConnectionWithProps("autoReconnect=true,initialTimeout=2,maxReconnects=3,cacheServerConfiguration=true,elideSetAutoCommits=true");
            String threadId = getSingleIndexedValueWithQuery(rConn, 1, "select connection_id()").toString();
            killConnection(this.conn, threadId);
            boolean detectedDeadConn = false;
            
            for (int i = 0; i < 100; i++) {
                  try {
                        rConn.createStatement().executeQuery("SELECT 1");
                  } catch (SQLException sqlEx) {
                        detectedDeadConn = true;
                        break;
                  }
            }
            
            assertTrue(detectedDeadConn);
            rConn.prepareStatement("SELECT 1").executeQuery();
            
            Connection rConn2 = getConnectionWithProps("autoReconnect=true,initialTimeout=2,maxReconnects=3,cacheServerConfiguration=true,elideSetAutoCommits=true");
            rConn2.prepareStatement("SELECT 1").executeQuery();
            
      }
}

Generated by  Doxygen 1.6.0   Back to index