PageRenderTime 54ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/branches/ui/project/mysql-connector/src/testsuite/regression/ConnectionRegressionTest.java

https://bitbucket.org/novelli/josser
Java | 1799 lines | 1108 code | 307 blank | 384 comment | 190 complexity | efddfa25aeb42667f89c7ce8804610d3 MD5 | raw file
Possible License(s): Apache-2.0, GPL-2.0, LGPL-2.1, BSD-3-Clause
  1. /*
  2. Copyright 2002-2007 MySQL AB, 2008 Sun Microsystems
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of version 2 of the GNU General Public License as
  5. published by the Free Software Foundation.
  6. There are special exceptions to the terms and conditions of the GPL
  7. as it is applied to this software. View the full text of the
  8. exception in file EXCEPTIONS-CONNECTOR-J in the directory of this
  9. software distribution.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17. */
  18. package testsuite.regression;
  19. import java.io.ByteArrayOutputStream;
  20. import java.io.IOException;
  21. import java.io.PrintStream;
  22. import java.lang.reflect.InvocationTargetException;
  23. import java.lang.reflect.Method;
  24. import java.net.Socket;
  25. import java.net.SocketException;
  26. import java.sql.Connection;
  27. import java.sql.DriverManager;
  28. import java.sql.DriverPropertyInfo;
  29. import java.sql.PreparedStatement;
  30. import java.sql.ResultSet;
  31. import java.sql.SQLException;
  32. import java.sql.Statement;
  33. import java.util.Collection;
  34. import java.util.Enumeration;
  35. import java.util.HashMap;
  36. import java.util.Iterator;
  37. import java.util.LinkedList;
  38. import java.util.List;
  39. import java.util.Locale;
  40. import java.util.Map;
  41. import java.util.Properties;
  42. import java.util.StringTokenizer;
  43. import java.util.regex.Matcher;
  44. import java.util.regex.Pattern;
  45. import javax.sql.XAConnection;
  46. import javax.transaction.xa.XAResource;
  47. import javax.transaction.xa.Xid;
  48. import testsuite.BaseTestCase;
  49. import testsuite.UnreliableSocketFactory;
  50. import com.mysql.jdbc.ConnectionImpl;
  51. import com.mysql.jdbc.Driver;
  52. import com.mysql.jdbc.Messages;
  53. import com.mysql.jdbc.MysqlDataTruncation;
  54. import com.mysql.jdbc.MysqlErrorNumbers;
  55. import com.mysql.jdbc.NonRegisteringDriver;
  56. import com.mysql.jdbc.ReplicationConnection;
  57. import com.mysql.jdbc.ReplicationDriver;
  58. import com.mysql.jdbc.SQLError;
  59. import com.mysql.jdbc.StandardSocketFactory;
  60. import com.mysql.jdbc.integration.jboss.MysqlValidConnectionChecker;
  61. import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource;
  62. import com.mysql.jdbc.jdbc2.optional.MysqlXid;
  63. import com.mysql.jdbc.jdbc2.optional.SuspendableXAConnection;
  64. import com.mysql.jdbc.log.StandardLogger;
  65. /**
  66. * Regression tests for Connections
  67. *
  68. * @author Mark Matthews
  69. * @version $Id: ConnectionRegressionTest.java,v 1.1.2.1 2005/05/13 18:58:38
  70. * mmatthews Exp $
  71. */
  72. public class ConnectionRegressionTest extends BaseTestCase {
  73. /**
  74. * DOCUMENT ME!
  75. *
  76. * @param name
  77. * the name of the testcase
  78. */
  79. public ConnectionRegressionTest(String name) {
  80. super(name);
  81. }
  82. /**
  83. * Runs all test cases in this test suite
  84. *
  85. * @param args
  86. */
  87. public static void main(String[] args) {
  88. junit.textui.TestRunner.run(ConnectionRegressionTest.class);
  89. }
  90. /**
  91. * DOCUMENT ME!
  92. *
  93. * @throws Exception
  94. * ...
  95. */
  96. public void testBug1914() throws Exception {
  97. System.out.println(this.conn
  98. .nativeSQL("{fn convert(foo(a,b,c), BIGINT)}"));
  99. System.out.println(this.conn
  100. .nativeSQL("{fn convert(foo(a,b,c), BINARY)}"));
  101. System.out
  102. .println(this.conn.nativeSQL("{fn convert(foo(a,b,c), BIT)}"));
  103. System.out.println(this.conn
  104. .nativeSQL("{fn convert(foo(a,b,c), CHAR)}"));
  105. System.out.println(this.conn
  106. .nativeSQL("{fn convert(foo(a,b,c), DATE)}"));
  107. System.out.println(this.conn
  108. .nativeSQL("{fn convert(foo(a,b,c), DECIMAL)}"));
  109. System.out.println(this.conn
  110. .nativeSQL("{fn convert(foo(a,b,c), DOUBLE)}"));
  111. System.out.println(this.conn
  112. .nativeSQL("{fn convert(foo(a,b,c), FLOAT)}"));
  113. System.out.println(this.conn
  114. .nativeSQL("{fn convert(foo(a,b,c), INTEGER)}"));
  115. System.out.println(this.conn
  116. .nativeSQL("{fn convert(foo(a,b,c), LONGVARBINARY)}"));
  117. System.out.println(this.conn
  118. .nativeSQL("{fn convert(foo(a,b,c), LONGVARCHAR)}"));
  119. System.out.println(this.conn
  120. .nativeSQL("{fn convert(foo(a,b,c), TIME)}"));
  121. System.out.println(this.conn
  122. .nativeSQL("{fn convert(foo(a,b,c), TIMESTAMP)}"));
  123. System.out.println(this.conn
  124. .nativeSQL("{fn convert(foo(a,b,c), TINYINT)}"));
  125. System.out.println(this.conn
  126. .nativeSQL("{fn convert(foo(a,b,c), VARBINARY)}"));
  127. System.out.println(this.conn
  128. .nativeSQL("{fn convert(foo(a,b,c), VARCHAR)}"));
  129. }
  130. /**
  131. * Tests fix for BUG#3554 - Not specifying database in URL causes
  132. * MalformedURL exception.
  133. *
  134. * @throws Exception
  135. * if an error ocurrs.
  136. */
  137. public void testBug3554() throws Exception {
  138. try {
  139. new NonRegisteringDriver().connect(
  140. "jdbc:mysql://localhost:3306/?user=root&password=root",
  141. new Properties());
  142. } catch (SQLException sqlEx) {
  143. assertTrue(sqlEx.getMessage().indexOf("Malformed") == -1);
  144. }
  145. }
  146. /**
  147. * DOCUMENT ME!
  148. *
  149. * @throws Exception
  150. * ...
  151. */
  152. public void testBug3790() throws Exception {
  153. String field2OldValue = "foo";
  154. String field2NewValue = "bar";
  155. int field1OldValue = 1;
  156. Connection conn1 = null;
  157. Connection conn2 = null;
  158. Statement stmt1 = null;
  159. Statement stmt2 = null;
  160. ResultSet rs2 = null;
  161. Properties props = new Properties();
  162. try {
  163. createTable("testBug3790", "(field1 INT NOT NULL PRIMARY KEY, field2 VARCHAR(32)) ", "InnoDB");
  164. this.stmt.executeUpdate("INSERT INTO testBug3790 VALUES ("
  165. + field1OldValue + ", '" + field2OldValue + "')");
  166. conn1 = getConnectionWithProps(props); // creates a new connection
  167. conn2 = getConnectionWithProps(props); // creates another new
  168. // connection
  169. conn1.setAutoCommit(false);
  170. conn2.setAutoCommit(false);
  171. stmt1 = conn1.createStatement();
  172. stmt1.executeUpdate("UPDATE testBug3790 SET field2 = '"
  173. + field2NewValue + "' WHERE field1=" + field1OldValue);
  174. conn1.commit();
  175. stmt2 = conn2.createStatement();
  176. rs2 = stmt2.executeQuery("SELECT field1, field2 FROM testBug3790");
  177. assertTrue(rs2.next());
  178. assertTrue(rs2.getInt(1) == field1OldValue);
  179. assertTrue(rs2.getString(2).equals(field2NewValue));
  180. } finally {
  181. if (rs2 != null) {
  182. rs2.close();
  183. }
  184. if (stmt2 != null) {
  185. stmt2.close();
  186. }
  187. if (stmt1 != null) {
  188. stmt1.close();
  189. }
  190. if (conn1 != null) {
  191. conn1.close();
  192. }
  193. if (conn2 != null) {
  194. conn2.close();
  195. }
  196. }
  197. }
  198. /**
  199. * Tests if the driver configures character sets correctly for 4.1.x
  200. * servers. Requires that the 'admin connection' is configured, as this test
  201. * needs to create/drop databases.
  202. *
  203. * @throws Exception
  204. * if an error occurs
  205. */
  206. public void testCollation41() throws Exception {
  207. if (versionMeetsMinimum(4, 1) && isAdminConnectionConfigured()) {
  208. Map charsetsAndCollations = getCharacterSetsAndCollations();
  209. charsetsAndCollations.remove("latin7"); // Maps to multiple Java
  210. // charsets
  211. charsetsAndCollations.remove("ucs2"); // can't be used as a
  212. // connection charset
  213. Iterator charsets = charsetsAndCollations.keySet().iterator();
  214. while (charsets.hasNext()) {
  215. Connection charsetConn = null;
  216. Statement charsetStmt = null;
  217. try {
  218. String charsetName = charsets.next().toString();
  219. String collationName = charsetsAndCollations.get(
  220. charsetName).toString();
  221. Properties props = new Properties();
  222. props.put("characterEncoding", charsetName);
  223. System.out.println("Testing character set " + charsetName);
  224. charsetConn = getAdminConnectionWithProps(props);
  225. charsetStmt = charsetConn.createStatement();
  226. charsetStmt
  227. .executeUpdate("DROP DATABASE IF EXISTS testCollation41");
  228. charsetStmt
  229. .executeUpdate("DROP TABLE IF EXISTS testCollation41");
  230. charsetStmt
  231. .executeUpdate("CREATE DATABASE testCollation41 DEFAULT CHARACTER SET "
  232. + charsetName);
  233. charsetConn.setCatalog("testCollation41");
  234. // We've switched catalogs, so we need to recreate the
  235. // statement to pick this up...
  236. charsetStmt = charsetConn.createStatement();
  237. StringBuffer createTableCommand = new StringBuffer(
  238. "CREATE TABLE testCollation41"
  239. + "(field1 VARCHAR(255), field2 INT)");
  240. charsetStmt.executeUpdate(createTableCommand.toString());
  241. charsetStmt
  242. .executeUpdate("INSERT INTO testCollation41 VALUES ('abc', 0)");
  243. int updateCount = charsetStmt
  244. .executeUpdate("UPDATE testCollation41 SET field2=1 WHERE field1='abc'");
  245. assertTrue(updateCount == 1);
  246. } finally {
  247. if (charsetStmt != null) {
  248. charsetStmt
  249. .executeUpdate("DROP TABLE IF EXISTS testCollation41");
  250. charsetStmt
  251. .executeUpdate("DROP DATABASE IF EXISTS testCollation41");
  252. charsetStmt.close();
  253. }
  254. if (charsetConn != null) {
  255. charsetConn.close();
  256. }
  257. }
  258. }
  259. }
  260. }
  261. /**
  262. * Tests setReadOnly() being reset during failover
  263. *
  264. * @throws Exception
  265. * if an error occurs.
  266. */
  267. public void testSetReadOnly() throws Exception {
  268. Properties props = new Properties();
  269. props.put("autoReconnect", "true");
  270. String sepChar = "?";
  271. if (BaseTestCase.dbUrl.indexOf("?") != -1) {
  272. sepChar = "&";
  273. }
  274. Connection reconnectableConn = DriverManager.getConnection(
  275. BaseTestCase.dbUrl + sepChar + "autoReconnect=true", props);
  276. this.rs = reconnectableConn.createStatement().executeQuery(
  277. "SELECT CONNECTION_ID()");
  278. this.rs.next();
  279. String connectionId = this.rs.getString(1);
  280. reconnectableConn.setReadOnly(true);
  281. boolean isReadOnly = reconnectableConn.isReadOnly();
  282. Connection killConn = getConnectionWithProps((Properties)null);
  283. killConn.createStatement().executeUpdate("KILL " + connectionId);
  284. Thread.sleep(2000);
  285. SQLException caughtException = null;
  286. int numLoops = 8;
  287. while (caughtException == null && numLoops > 0) {
  288. numLoops--;
  289. try {
  290. reconnectableConn.createStatement().executeQuery("SELECT 1");
  291. } catch (SQLException sqlEx) {
  292. caughtException = sqlEx;
  293. }
  294. }
  295. System.out
  296. .println("Executing statement on reconnectable connection...");
  297. this.rs = reconnectableConn.createStatement().executeQuery(
  298. "SELECT CONNECTION_ID()");
  299. this.rs.next();
  300. assertTrue("Connection is not a reconnected-connection", !connectionId
  301. .equals(this.rs.getString(1)));
  302. try {
  303. reconnectableConn.createStatement().executeQuery("SELECT 1");
  304. } catch (SQLException sqlEx) {
  305. ; // ignore
  306. }
  307. reconnectableConn.createStatement().executeQuery("SELECT 1");
  308. assertTrue(reconnectableConn.isReadOnly() == isReadOnly);
  309. }
  310. private Map getCharacterSetsAndCollations() throws Exception {
  311. Map charsetsToLoad = new HashMap();
  312. try {
  313. this.rs = this.stmt.executeQuery("SHOW character set");
  314. while (this.rs.next()) {
  315. charsetsToLoad.put(this.rs.getString("Charset"), this.rs
  316. .getString("Default collation"));
  317. }
  318. //
  319. // These don't have mappings in Java...
  320. //
  321. charsetsToLoad.remove("swe7");
  322. charsetsToLoad.remove("hp8");
  323. charsetsToLoad.remove("dec8");
  324. charsetsToLoad.remove("koi8u");
  325. charsetsToLoad.remove("keybcs2");
  326. charsetsToLoad.remove("geostd8");
  327. charsetsToLoad.remove("armscii8");
  328. } finally {
  329. if (this.rs != null) {
  330. this.rs.close();
  331. }
  332. }
  333. return charsetsToLoad;
  334. }
  335. /**
  336. * Tests fix for BUG#4334, port #'s not being picked up for
  337. * failover/autoreconnect.
  338. *
  339. * @throws Exception
  340. * if an error occurs.
  341. */
  342. public void testBug4334() throws Exception {
  343. if (isAdminConnectionConfigured()) {
  344. Connection adminConnection = null;
  345. try {
  346. adminConnection = getAdminConnection();
  347. int bogusPortNumber = 65534;
  348. NonRegisteringDriver driver = new NonRegisteringDriver();
  349. Properties oldProps = driver.parseURL(BaseTestCase.dbUrl, null);
  350. String host = driver.host(oldProps);
  351. int port = driver.port(oldProps);
  352. String database = oldProps
  353. .getProperty(NonRegisteringDriver.DBNAME_PROPERTY_KEY);
  354. String user = oldProps
  355. .getProperty(NonRegisteringDriver.USER_PROPERTY_KEY);
  356. String password = oldProps
  357. .getProperty(NonRegisteringDriver.PASSWORD_PROPERTY_KEY);
  358. StringBuffer newUrlToTestPortNum = new StringBuffer(
  359. "jdbc:mysql://");
  360. if (host != null) {
  361. newUrlToTestPortNum.append(host);
  362. }
  363. newUrlToTestPortNum.append(":").append(port);
  364. newUrlToTestPortNum.append(",");
  365. if (host != null) {
  366. newUrlToTestPortNum.append(host);
  367. }
  368. newUrlToTestPortNum.append(":").append(bogusPortNumber);
  369. newUrlToTestPortNum.append("/");
  370. if (database != null) {
  371. newUrlToTestPortNum.append(database);
  372. }
  373. if ((user != null) || (password != null)) {
  374. newUrlToTestPortNum.append("?");
  375. if (user != null) {
  376. newUrlToTestPortNum.append("user=").append(user);
  377. if (password != null) {
  378. newUrlToTestPortNum.append("&");
  379. }
  380. }
  381. if (password != null) {
  382. newUrlToTestPortNum.append("password=")
  383. .append(password);
  384. }
  385. }
  386. Properties autoReconnectProps = new Properties();
  387. autoReconnectProps.put("autoReconnect", "true");
  388. System.out.println(newUrlToTestPortNum);
  389. //
  390. // First test that port #'s are being correctly picked up
  391. //
  392. // We do this by looking at the error message that is returned
  393. //
  394. Connection portNumConn = DriverManager.getConnection(
  395. newUrlToTestPortNum.toString(), autoReconnectProps);
  396. Statement portNumStmt = portNumConn.createStatement();
  397. this.rs = portNumStmt.executeQuery("SELECT connection_id()");
  398. this.rs.next();
  399. killConnection(adminConnection, this.rs.getString(1));
  400. try {
  401. portNumStmt.executeQuery("SELECT connection_id()");
  402. } catch (SQLException sqlEx) {
  403. // we expect this one
  404. }
  405. try {
  406. portNumStmt.executeQuery("SELECT connection_id()");
  407. } catch (SQLException sqlEx) {
  408. assertTrue(sqlEx.getMessage().toLowerCase().indexOf(
  409. "connection refused") != -1);
  410. }
  411. //
  412. // Now make sure failover works
  413. //
  414. StringBuffer newUrlToTestFailover = new StringBuffer(
  415. "jdbc:mysql://");
  416. if (host != null) {
  417. newUrlToTestFailover.append(host);
  418. }
  419. newUrlToTestFailover.append(":").append(port);
  420. newUrlToTestFailover.append(",");
  421. if (host != null) {
  422. newUrlToTestFailover.append(host);
  423. }
  424. newUrlToTestFailover.append(":").append(bogusPortNumber);
  425. newUrlToTestFailover.append("/");
  426. if (database != null) {
  427. newUrlToTestFailover.append(database);
  428. }
  429. if ((user != null) || (password != null)) {
  430. newUrlToTestFailover.append("?");
  431. if (user != null) {
  432. newUrlToTestFailover.append("user=").append(user);
  433. if (password != null) {
  434. newUrlToTestFailover.append("&");
  435. }
  436. }
  437. if (password != null) {
  438. newUrlToTestFailover.append("password=").append(
  439. password);
  440. }
  441. }
  442. Connection failoverConn = DriverManager.getConnection(
  443. newUrlToTestFailover.toString(), autoReconnectProps);
  444. Statement failoverStmt = portNumConn.createStatement();
  445. this.rs = failoverStmt.executeQuery("SELECT connection_id()");
  446. this.rs.next();
  447. killConnection(adminConnection, this.rs.getString(1));
  448. try {
  449. failoverStmt.executeQuery("SELECT connection_id()");
  450. } catch (SQLException sqlEx) {
  451. // we expect this one
  452. }
  453. failoverStmt.executeQuery("SELECT connection_id()");
  454. } finally {
  455. if (adminConnection != null) {
  456. adminConnection.close();
  457. }
  458. }
  459. }
  460. }
  461. private static void killConnection(Connection adminConn, String threadId)
  462. throws SQLException {
  463. adminConn.createStatement().execute("KILL " + threadId);
  464. }
  465. /**
  466. * Tests fix for BUG#6966, connections starting up failed-over (due to down
  467. * master) never retry master.
  468. *
  469. * @throws Exception
  470. * if the test fails...Note, test is timing-dependent, but
  471. * should work in most cases.
  472. */
  473. public void testBug6966() throws Exception {
  474. Properties props = new Driver().parseURL(BaseTestCase.dbUrl, null);
  475. props.setProperty("autoReconnect", "true");
  476. props.setProperty("socketFactory", "testsuite.UnreliableSocketFactory");
  477. Properties urlProps = new NonRegisteringDriver().parseURL(this.dbUrl, null);
  478. String host = urlProps.getProperty(Driver.HOST_PROPERTY_KEY);
  479. String port = urlProps.getProperty(Driver.PORT_PROPERTY_KEY);
  480. props.remove(Driver.HOST_PROPERTY_KEY);
  481. props.remove(Driver.NUM_HOSTS_PROPERTY_KEY);
  482. props.remove(Driver.HOST_PROPERTY_KEY + ".1");
  483. props.remove(Driver.PORT_PROPERTY_KEY + ".1");
  484. props.setProperty("queriesBeforeRetryMaster", "50");
  485. props.setProperty("maxReconnects", "1");
  486. UnreliableSocketFactory.mapHost("master", host);
  487. UnreliableSocketFactory.mapHost("slave", host);
  488. UnreliableSocketFactory.downHost("master");
  489. Connection failoverConnection = null;
  490. try {
  491. failoverConnection = getConnectionWithProps("jdbc:mysql://master:" + port + ",slave:" + port + "/", props);
  492. failoverConnection.setAutoCommit(false);
  493. String originalConnectionId = getSingleIndexedValueWithQuery(
  494. failoverConnection, 1, "SELECT CONNECTION_ID()").toString();
  495. for (int i = 0; i < 49; i++) {
  496. failoverConnection.createStatement().executeQuery("SELECT 1");
  497. }
  498. ((com.mysql.jdbc.Connection)failoverConnection).clearHasTriedMaster();
  499. UnreliableSocketFactory.dontDownHost("master");
  500. failoverConnection.setAutoCommit(true);
  501. String newConnectionId = getSingleIndexedValueWithQuery(
  502. failoverConnection, 1, "SELECT CONNECTION_ID()").toString();
  503. assertTrue(((com.mysql.jdbc.Connection)failoverConnection).hasTriedMaster());
  504. assertTrue(!newConnectionId.equals(originalConnectionId));
  505. failoverConnection.createStatement().executeQuery("SELECT 1");
  506. } finally {
  507. UnreliableSocketFactory.flushAllHostLists();
  508. if (failoverConnection != null) {
  509. failoverConnection.close();
  510. }
  511. }
  512. }
  513. /**
  514. * Test fix for BUG#7952 -- Infinite recursion when 'falling back' to master
  515. * in failover configuration.
  516. *
  517. * @throws Exception
  518. * if the tests fails.
  519. */
  520. public void testBug7952() throws Exception {
  521. Properties props = new Driver().parseURL(BaseTestCase.dbUrl, null);
  522. props.setProperty("autoReconnect", "true");
  523. // Re-build the connection information
  524. int firstIndexOfHost = BaseTestCase.dbUrl.indexOf("//") + 2;
  525. int lastIndexOfHost = BaseTestCase.dbUrl.indexOf("/", firstIndexOfHost);
  526. String hostPortPair = BaseTestCase.dbUrl.substring(firstIndexOfHost,
  527. lastIndexOfHost);
  528. StringTokenizer st = new StringTokenizer(hostPortPair, ":");
  529. String host = null;
  530. String port = null;
  531. if (st.hasMoreTokens()) {
  532. String possibleHostOrPort = st.nextToken();
  533. if (possibleHostOrPort.indexOf(".") == -1
  534. && Character.isDigit(possibleHostOrPort.charAt(0))) {
  535. port = possibleHostOrPort;
  536. host = "localhost";
  537. } else {
  538. host = possibleHostOrPort;
  539. }
  540. }
  541. if (st.hasMoreTokens()) {
  542. port = st.nextToken();
  543. }
  544. if (host == null) {
  545. host = "";
  546. }
  547. if (port == null) {
  548. port = "3306";
  549. }
  550. StringBuffer newHostBuf = new StringBuffer();
  551. newHostBuf.append(host);
  552. newHostBuf.append(":");
  553. newHostBuf.append(port);
  554. newHostBuf.append(",");
  555. newHostBuf.append(host);
  556. if (port != null) {
  557. newHostBuf.append(":");
  558. newHostBuf.append(port);
  559. }
  560. props.remove("PORT");
  561. props.setProperty("HOST", newHostBuf.toString());
  562. props.setProperty("queriesBeforeRetryMaster", "10");
  563. props.setProperty("maxReconnects", "1");
  564. Connection failoverConnection = null;
  565. Connection killerConnection = getConnectionWithProps((String)null);
  566. try {
  567. failoverConnection = getConnectionWithProps("jdbc:mysql://"
  568. + newHostBuf + "/", props);
  569. ((com.mysql.jdbc.Connection) failoverConnection)
  570. .setPreferSlaveDuringFailover(true);
  571. failoverConnection.setAutoCommit(false);
  572. String failoverConnectionId = getSingleIndexedValueWithQuery(
  573. failoverConnection, 1, "SELECT CONNECTION_ID()").toString();
  574. System.out.println("Connection id: " + failoverConnectionId);
  575. killConnection(killerConnection, failoverConnectionId);
  576. Thread.sleep(3000); // This can take some time....
  577. try {
  578. failoverConnection.createStatement().executeQuery("SELECT 1");
  579. } catch (SQLException sqlEx) {
  580. assertTrue("08S01".equals(sqlEx.getSQLState()));
  581. }
  582. ((com.mysql.jdbc.Connection) failoverConnection)
  583. .setPreferSlaveDuringFailover(false);
  584. ((com.mysql.jdbc.Connection) failoverConnection)
  585. .setFailedOver(true);
  586. failoverConnection.setAutoCommit(true);
  587. String failedConnectionId = getSingleIndexedValueWithQuery(
  588. failoverConnection, 1, "SELECT CONNECTION_ID()").toString();
  589. System.out.println("Failed over connection id: "
  590. + failedConnectionId);
  591. ((com.mysql.jdbc.Connection) failoverConnection)
  592. .setPreferSlaveDuringFailover(false);
  593. ((com.mysql.jdbc.Connection) failoverConnection)
  594. .setFailedOver(true);
  595. for (int i = 0; i < 30; i++) {
  596. failoverConnection.setAutoCommit(true);
  597. System.out.println(getSingleIndexedValueWithQuery(
  598. failoverConnection, 1, "SELECT CONNECTION_ID()"));
  599. // failoverConnection.createStatement().executeQuery("SELECT
  600. // 1");
  601. failoverConnection.setAutoCommit(true);
  602. }
  603. String fallbackConnectionId = getSingleIndexedValueWithQuery(
  604. failoverConnection, 1, "SELECT CONNECTION_ID()").toString();
  605. System.out.println("fallback connection id: "
  606. + fallbackConnectionId);
  607. /*
  608. * long begin = System.currentTimeMillis();
  609. *
  610. * failoverConnection.setAutoCommit(true);
  611. *
  612. * long end = System.currentTimeMillis();
  613. *
  614. * assertTrue("Probably didn't try failing back to the
  615. * master....check test", (end - begin) > 500);
  616. *
  617. * failoverConnection.createStatement().executeQuery("SELECT 1");
  618. */
  619. } finally {
  620. if (failoverConnection != null) {
  621. failoverConnection.close();
  622. }
  623. }
  624. }
  625. /**
  626. * Tests fix for BUG#7607 - MS932, SHIFT_JIS and Windows_31J not recog. as
  627. * aliases for sjis.
  628. *
  629. * @throws Exception
  630. * if the test fails.
  631. */
  632. public void testBug7607() throws Exception {
  633. if (versionMeetsMinimum(4, 1)) {
  634. Connection ms932Conn = null, cp943Conn = null, shiftJisConn = null, windows31JConn = null;
  635. try {
  636. Properties props = new Properties();
  637. props.setProperty("characterEncoding", "MS932");
  638. ms932Conn = getConnectionWithProps(props);
  639. this.rs = ms932Conn.createStatement().executeQuery(
  640. "SHOW VARIABLES LIKE 'character_set_client'");
  641. assertTrue(this.rs.next());
  642. String encoding = this.rs.getString(2);
  643. if (!versionMeetsMinimum(5, 0, 3)
  644. && !versionMeetsMinimum(4, 1, 11)) {
  645. assertEquals("sjis", encoding.toLowerCase(Locale.ENGLISH));
  646. } else {
  647. assertEquals("cp932", encoding.toLowerCase(Locale.ENGLISH));
  648. }
  649. this.rs = ms932Conn.createStatement().executeQuery(
  650. "SELECT 'abc'");
  651. assertTrue(this.rs.next());
  652. String charsetToCheck = "ms932";
  653. if (versionMeetsMinimum(5, 0, 3)
  654. || versionMeetsMinimum(4, 1, 11)) {
  655. charsetToCheck = "windows-31j";
  656. }
  657. assertEquals(charsetToCheck,
  658. ((com.mysql.jdbc.ResultSetMetaData) this.rs
  659. .getMetaData()).getColumnCharacterSet(1)
  660. .toLowerCase(Locale.ENGLISH));
  661. try {
  662. ms932Conn.createStatement().executeUpdate(
  663. "drop table if exists testBug7607");
  664. ms932Conn
  665. .createStatement()
  666. .executeUpdate(
  667. "create table testBug7607 (sortCol int, col1 varchar(100) ) character set sjis");
  668. ms932Conn.createStatement().executeUpdate(
  669. "insert into testBug7607 values(1, 0x835C)"); // standard
  670. // sjis
  671. ms932Conn.createStatement().executeUpdate(
  672. "insert into testBug7607 values(2, 0x878A)"); // NEC
  673. // kanji
  674. this.rs = ms932Conn
  675. .createStatement()
  676. .executeQuery(
  677. "SELECT col1 FROM testBug7607 ORDER BY sortCol ASC");
  678. assertTrue(this.rs.next());
  679. String asString = this.rs.getString(1);
  680. assertTrue("\u30bd".equals(asString));
  681. // Can't be fixed unless server is fixed,
  682. // this is fixed in 4.1.7.
  683. assertTrue(this.rs.next());
  684. asString = this.rs.getString(1);
  685. assertEquals("\u3231", asString);
  686. } finally {
  687. ms932Conn.createStatement().executeUpdate(
  688. "drop table if exists testBug7607");
  689. }
  690. props = new Properties();
  691. props.setProperty("characterEncoding", "SHIFT_JIS");
  692. shiftJisConn = getConnectionWithProps(props);
  693. this.rs = shiftJisConn.createStatement().executeQuery(
  694. "SHOW VARIABLES LIKE 'character_set_client'");
  695. assertTrue(this.rs.next());
  696. encoding = this.rs.getString(2);
  697. assertTrue("sjis".equalsIgnoreCase(encoding));
  698. this.rs = shiftJisConn.createStatement().executeQuery(
  699. "SELECT 'abc'");
  700. assertTrue(this.rs.next());
  701. String charSetUC = ((com.mysql.jdbc.ResultSetMetaData) this.rs
  702. .getMetaData()).getColumnCharacterSet(1).toUpperCase(
  703. Locale.US);
  704. if (isRunningOnJdk131()) {
  705. assertEquals("WINDOWS-31J", charSetUC);
  706. } else {
  707. // assertEquals("SHIFT_JIS", charSetUC);
  708. }
  709. props = new Properties();
  710. props.setProperty("characterEncoding", "WINDOWS-31J");
  711. windows31JConn = getConnectionWithProps(props);
  712. this.rs = windows31JConn.createStatement().executeQuery(
  713. "SHOW VARIABLES LIKE 'character_set_client'");
  714. assertTrue(this.rs.next());
  715. encoding = this.rs.getString(2);
  716. if (!versionMeetsMinimum(5, 0, 3)
  717. && !versionMeetsMinimum(4, 1, 11)) {
  718. assertEquals("sjis", encoding.toLowerCase(Locale.ENGLISH));
  719. } else {
  720. assertEquals("cp932", encoding.toLowerCase(Locale.ENGLISH));
  721. }
  722. this.rs = windows31JConn.createStatement().executeQuery(
  723. "SELECT 'abc'");
  724. assertTrue(this.rs.next());
  725. if (!versionMeetsMinimum(4, 1, 11)) {
  726. assertEquals("sjis".toLowerCase(Locale.ENGLISH),
  727. ((com.mysql.jdbc.ResultSetMetaData) this.rs
  728. .getMetaData()).getColumnCharacterSet(1)
  729. .toLowerCase(Locale.ENGLISH));
  730. } else {
  731. assertEquals("windows-31j".toLowerCase(Locale.ENGLISH),
  732. ((com.mysql.jdbc.ResultSetMetaData) this.rs
  733. .getMetaData()).getColumnCharacterSet(1)
  734. .toLowerCase(Locale.ENGLISH));
  735. }
  736. props = new Properties();
  737. props.setProperty("characterEncoding", "CP943");
  738. cp943Conn = getConnectionWithProps(props);
  739. this.rs = cp943Conn.createStatement().executeQuery(
  740. "SHOW VARIABLES LIKE 'character_set_client'");
  741. assertTrue(this.rs.next());
  742. encoding = this.rs.getString(2);
  743. assertTrue("sjis".equalsIgnoreCase(encoding));
  744. this.rs = cp943Conn.createStatement().executeQuery(
  745. "SELECT 'abc'");
  746. assertTrue(this.rs.next());
  747. charSetUC = ((com.mysql.jdbc.ResultSetMetaData) this.rs
  748. .getMetaData()).getColumnCharacterSet(1).toUpperCase(
  749. Locale.US);
  750. if (isRunningOnJdk131()) {
  751. assertEquals("WINDOWS-31J", charSetUC);
  752. } else {
  753. assertEquals("CP943", charSetUC);
  754. }
  755. } finally {
  756. if (ms932Conn != null) {
  757. ms932Conn.close();
  758. }
  759. if (shiftJisConn != null) {
  760. shiftJisConn.close();
  761. }
  762. if (windows31JConn != null) {
  763. windows31JConn.close();
  764. }
  765. if (cp943Conn != null) {
  766. cp943Conn.close();
  767. }
  768. }
  769. }
  770. }
  771. /**
  772. * In some case Connector/J's round-robin function doesn't work.
  773. *
  774. * I had 2 mysqld, node1 "localhost:3306" and node2 "localhost:3307".
  775. *
  776. * 1. node1 is up, node2 is up
  777. *
  778. * 2. java-program connect to node1 by using properties
  779. * "autoRecconect=true","roundRobinLoadBalance=true","failOverReadOnly=false".
  780. *
  781. * 3. node1 is down, node2 is up
  782. *
  783. * 4. java-program execute a query and fail, but Connector/J's round-robin
  784. * fashion failover work and if java-program retry a query it can succeed
  785. * (connection is change to node2 by Connector/j)
  786. *
  787. * 5. node1 is up, node2 is up
  788. *
  789. * 6. node1 is up, node2 is down
  790. *
  791. * 7. java-program execute a query, but this time Connector/J doesn't work
  792. * althought node1 is up and usable.
  793. *
  794. *
  795. * @throws Exception
  796. */
  797. /* FIXME: This test is no longer valid with random selection of hosts
  798. public void testBug8643() throws Exception {
  799. if (runMultiHostTests()) {
  800. Properties defaultProps = getMasterSlaveProps();
  801. defaultProps.remove(NonRegisteringDriver.HOST_PROPERTY_KEY);
  802. defaultProps.remove(NonRegisteringDriver.PORT_PROPERTY_KEY);
  803. defaultProps.put("autoReconnect", "true");
  804. defaultProps.put("roundRobinLoadBalance", "true");
  805. defaultProps.put("failOverReadOnly", "false");
  806. Connection con = null;
  807. try {
  808. con = DriverManager.getConnection(getMasterSlaveUrl(),
  809. defaultProps);
  810. Statement stmt1 = con.createStatement();
  811. ResultSet rs1 = stmt1
  812. .executeQuery("show variables like 'port'");
  813. rs1.next();
  814. rs1 = stmt1.executeQuery("select connection_id()");
  815. rs1.next();
  816. String originalConnectionId = rs1.getString(1);
  817. this.stmt.executeUpdate("kill " + originalConnectionId);
  818. int numLoops = 8;
  819. SQLException caughtException = null;
  820. while (caughtException == null && numLoops > 0) {
  821. numLoops--;
  822. try {
  823. rs1 = stmt1.executeQuery("show variables like 'port'");
  824. } catch (SQLException sqlEx) {
  825. caughtException = sqlEx;
  826. }
  827. }
  828. assertNotNull(caughtException);
  829. // failover and retry
  830. rs1 = stmt1.executeQuery("show variables like 'port'");
  831. rs1.next();
  832. assertTrue(!((com.mysql.jdbc.Connection) con)
  833. .isMasterConnection());
  834. rs1 = stmt1.executeQuery("select connection_id()");
  835. rs1.next();
  836. String nextConnectionId = rs1.getString(1);
  837. assertTrue(!nextConnectionId.equals(originalConnectionId));
  838. this.stmt.executeUpdate("kill " + nextConnectionId);
  839. numLoops = 8;
  840. caughtException = null;
  841. while (caughtException == null && numLoops > 0) {
  842. numLoops--;
  843. try {
  844. rs1 = stmt1.executeQuery("show variables like 'port'");
  845. } catch (SQLException sqlEx) {
  846. caughtException = sqlEx;
  847. }
  848. }
  849. assertNotNull(caughtException);
  850. // failover and retry
  851. rs1 = stmt1.executeQuery("show variables like 'port'");
  852. rs1.next();
  853. assertTrue(((com.mysql.jdbc.Connection) con)
  854. .isMasterConnection());
  855. } finally {
  856. if (con != null) {
  857. try {
  858. con.close();
  859. } catch (Exception e) {
  860. e.printStackTrace();
  861. }
  862. }
  863. }
  864. }
  865. }
  866. */
  867. /**
  868. * Tests fix for BUG#9206, can not use 'UTF-8' for characterSetResults
  869. * configuration property.
  870. */
  871. public void testBug9206() throws Exception {
  872. Properties props = new Properties();
  873. props.setProperty("characterSetResults", "UTF-8");
  874. getConnectionWithProps(props).close();
  875. }
  876. /**
  877. * These two charsets have different names depending on version of MySQL
  878. * server.
  879. *
  880. * @throws Exception
  881. * if the test fails.
  882. */
  883. public void testNewCharsetsConfiguration() throws Exception {
  884. Properties props = new Properties();
  885. props.setProperty("useUnicode", "true");
  886. props.setProperty("characterEncoding", "EUC_KR");
  887. getConnectionWithProps(props).close();
  888. props = new Properties();
  889. props.setProperty("useUnicode", "true");
  890. props.setProperty("characterEncoding", "KOI8_R");
  891. getConnectionWithProps(props).close();
  892. }
  893. /**
  894. * Tests fix for BUG#10144 - Memory leak in ServerPreparedStatement if
  895. * serverPrepare() fails.
  896. */
  897. public void testBug10144() throws Exception {
  898. if (versionMeetsMinimum(4, 1)) {
  899. Properties props = new Properties();
  900. props.setProperty("emulateUnsupportedPstmts", "false");
  901. props.setProperty("useServerPrepStmts", "true");
  902. Connection bareConn = getConnectionWithProps(props);
  903. int currentOpenStatements = ((com.mysql.jdbc.Connection) bareConn)
  904. .getActiveStatementCount();
  905. try {
  906. bareConn.prepareStatement("Boo!");
  907. fail("Should not've been able to prepare that one!");
  908. } catch (SQLException sqlEx) {
  909. assertEquals(currentOpenStatements,
  910. ((com.mysql.jdbc.Connection) bareConn)
  911. .getActiveStatementCount());
  912. } finally {
  913. if (bareConn != null) {
  914. bareConn.close();
  915. }
  916. }
  917. }
  918. }
  919. /**
  920. * Tests fix for BUG#10496 - SQLException is thrown when using property
  921. * "characterSetResults"
  922. */
  923. public void testBug10496() throws Exception {
  924. if (versionMeetsMinimum(5, 0, 3)) {
  925. Properties props = new Properties();
  926. props.setProperty("useUnicode", "true");
  927. props.setProperty("characterEncoding", "WINDOWS-31J");
  928. props.setProperty("characterSetResults", "WINDOWS-31J");
  929. getConnectionWithProps(props).close();
  930. props = new Properties();
  931. props.setProperty("useUnicode", "true");
  932. props.setProperty("characterEncoding", "EUC_JP");
  933. props.setProperty("characterSetResults", "EUC_JP");
  934. getConnectionWithProps(props).close();
  935. }
  936. }
  937. /**
  938. * Tests fix for BUG#11259, autoReconnect ping causes exception on
  939. * connection startup.
  940. *
  941. * @throws Exception
  942. * if the test fails.
  943. */
  944. public void testBug11259() throws Exception {
  945. Connection dsConn = null;
  946. try {
  947. Properties props = new Properties();
  948. props.setProperty("autoReconnect", "true");
  949. dsConn = getConnectionWithProps(props);
  950. } finally {
  951. if (dsConn != null) {
  952. dsConn.close();
  953. }
  954. }
  955. }
  956. /**
  957. * Tests fix for BUG#11879 -- ReplicationConnection won't switch to slave,
  958. * throws "Catalog can't be null" exception.
  959. *
  960. * @throws Exception
  961. * if the test fails
  962. */
  963. public void testBug11879() throws Exception {
  964. if (runMultiHostTests()) {
  965. Connection replConn = null;
  966. try {
  967. replConn = getMasterSlaveReplicationConnection();
  968. replConn.setReadOnly(true);
  969. replConn.setReadOnly(false);
  970. } finally {
  971. if (replConn != null) {
  972. replConn.close();
  973. }
  974. }
  975. }
  976. }
  977. /**
  978. * Tests fix for BUG#11976 - maxPerformance.properties mis-spells
  979. * "elideSetAutoCommits".
  980. *
  981. * @throws Exception
  982. * if the test fails.
  983. */
  984. public void testBug11976() throws Exception {
  985. if (isRunningOnJdk131()) {
  986. return; // test not valid on JDK-1.3.1
  987. }
  988. if (!versionMeetsMinimum(6, 0)) {
  989. return; // server status is broken until MySQL-6.0
  990. }
  991. Properties props = new Properties();
  992. props.setProperty("useConfigs", "maxPerformance");
  993. Connection maxPerfConn = getConnectionWithProps(props);
  994. assertEquals(true, ((com.mysql.jdbc.Connection) maxPerfConn)
  995. .getElideSetAutoCommits());
  996. }
  997. /**
  998. * Tests fix for BUG#12218, properties shared between master and slave with
  999. * replication connection.
  1000. *
  1001. * @throws Exception
  1002. * if the test fails.
  1003. */
  1004. public void testBug12218() throws Exception {
  1005. if (runMultiHostTests()) {
  1006. Connection replConn = null;
  1007. try {
  1008. replConn = getMasterSlaveReplicationConnection();
  1009. assertTrue(!((ConnectionImpl) ((ReplicationConnection) replConn)
  1010. .getMasterConnection()).hasSameProperties(
  1011. ((ReplicationConnection) replConn)
  1012. .getSlavesConnection()));
  1013. } finally {
  1014. if (replConn != null) {
  1015. replConn.close();
  1016. }
  1017. }
  1018. }
  1019. }
  1020. /**
  1021. * Tests fix for BUG#12229 - explainSlowQueries hangs with server-side
  1022. * prepared statements.
  1023. *
  1024. * @throws Exception
  1025. * if the test fails.
  1026. */
  1027. public void testBug12229() throws Exception {
  1028. createTable("testBug12229", "(`int_field` integer )");
  1029. this.stmt.executeUpdate("insert into testBug12229 values (123456),(1)");
  1030. Properties props = new Properties();
  1031. props.put("profileSQL", "true");
  1032. props.put("slowQueryThresholdMillis", "0");
  1033. props.put("logSlowQueries", "true");
  1034. props.put("explainSlowQueries", "true");
  1035. props.put("useServerPrepStmts", "true");
  1036. Connection explainConn = getConnectionWithProps(props);
  1037. this.pstmt = explainConn
  1038. .prepareStatement("SELECT `int_field` FROM `testBug12229` WHERE `int_field` = ?");
  1039. this.pstmt.setInt(1, 1);
  1040. this.rs = this.pstmt.executeQuery();
  1041. assertTrue(this.rs.next());
  1042. this.rs = this.pstmt.executeQuery();
  1043. assertTrue(this.rs.next());
  1044. this.rs = this.pstmt.executeQuery();
  1045. assertTrue(this.rs.next());
  1046. }
  1047. /**
  1048. * Tests fix for BUG#12752 - Cp1251 incorrectly mapped to win1251 for
  1049. * servers newer than 4.0.x.
  1050. *
  1051. * @throws Exception
  1052. * if the test fails.
  1053. */
  1054. public void testBug12752() throws Exception {
  1055. Properties props = new Properties();
  1056. props.setProperty("characterEncoding", "Cp1251");
  1057. getConnectionWithProps(props).close();
  1058. }
  1059. /**
  1060. * Tests fix for BUG#12753, sessionVariables=....=...., doesn't work as it's
  1061. * tokenized incorrectly.
  1062. *
  1063. * @throws Exception
  1064. * if the test fails.
  1065. */
  1066. public void testBug12753() throws Exception {
  1067. if (versionMeetsMinimum(4, 1)) {
  1068. Properties props = new Properties();
  1069. props.setProperty("sessionVariables", "sql_mode=ansi");
  1070. Connection sessionConn = null;
  1071. try {
  1072. sessionConn = getConnectionWithProps(props);
  1073. String sqlMode = getMysqlVariable(sessionConn, "sql_mode");
  1074. assertTrue(sqlMode.indexOf("ANSI") != -1);
  1075. } finally {
  1076. if (sessionConn != null) {
  1077. sessionConn.close();
  1078. sessionConn = null;
  1079. }
  1080. }
  1081. }
  1082. }
  1083. /**
  1084. * Tests fix for BUG#13048 - maxQuerySizeToLog is not respected.
  1085. *
  1086. * @throws Exception
  1087. * if the test fails
  1088. */
  1089. public void testBug13048() throws Exception {
  1090. Connection profileConn = null;
  1091. PrintStream oldErr = System.err;
  1092. try {
  1093. ByteArrayOutputStream bOut = new ByteArrayOutputStream();
  1094. System.setErr(new PrintStream(bOut));
  1095. Properties props = new Properties();
  1096. props.setProperty("profileSQL", "true");
  1097. props.setProperty("maxQuerySizeToLog", "2");
  1098. props.setProperty("logger", "com.mysql.jdbc.log.StandardLogger");
  1099. profileConn = getConnectionWithProps(props);
  1100. StringBuffer queryBuf = new StringBuffer("SELECT '");
  1101. for (int i = 0; i < 500; i++) {
  1102. queryBuf.append("a");
  1103. }
  1104. queryBuf.append("'");
  1105. this.rs = profileConn.createStatement().executeQuery(
  1106. queryBuf.toString());
  1107. this.rs.close();
  1108. String logString = new String(bOut.toString("ISO8859-1"));
  1109. assertTrue(logString.indexOf("... (truncated)") != -1);
  1110. bOut = new ByteArrayOutputStream();
  1111. System.setErr(new PrintStream(bOut));
  1112. this.rs = profileConn.prepareStatement(queryBuf.toString())
  1113. .executeQuery();
  1114. logString = new String(bOut.toString("ISO8859-1"));
  1115. assertTrue(logString.indexOf("... (truncated)") != -1);
  1116. } finally {
  1117. System.setErr(oldErr);
  1118. if (profileConn != null) {
  1119. profileConn.close();
  1120. }
  1121. if (this.rs != null) {
  1122. ResultSet toClose = this.rs;
  1123. this.rs = null;
  1124. toClose.close();
  1125. }
  1126. }
  1127. }
  1128. /**
  1129. * Tests fix for BUG#13453 - can't use & or = in URL configuration values
  1130. * (we now allow you to use www-form-encoding).
  1131. *
  1132. * @throws Exception
  1133. * if the test fails
  1134. */
  1135. public void testBug13453() throws Exception {
  1136. StringBuffer urlBuf = new StringBuffer(dbUrl);
  1137. if (dbUrl.indexOf('?') == -1) {
  1138. urlBuf.append('?');
  1139. } else {
  1140. urlBuf.append('&');
  1141. }
  1142. urlBuf.append("sessionVariables=@testBug13453='%25%26+%3D'");
  1143. Connection encodedConn = null;
  1144. try {
  1145. encodedConn = DriverManager.getConnection(urlBuf.toString(), null);
  1146. this.rs = encodedConn.createStatement().executeQuery(
  1147. "SELECT @testBug13453");
  1148. assertTrue(this.rs.next());
  1149. assertEquals("%& =", this.rs.getString(1));
  1150. } finally {
  1151. if (this.rs != null) {
  1152. this.rs.close();
  1153. this.rs = null;
  1154. }
  1155. if (encodedConn != null) {
  1156. encodedConn.close();
  1157. }
  1158. }
  1159. }
  1160. /**
  1161. * Tests fix for BUG#15065 - Usage advisor complains about unreferenced
  1162. * columns, even though they've been referenced.
  1163. *
  1164. * @throws Exception
  1165. * if the test fails.
  1166. */
  1167. public void testBug15065() throws Exception {
  1168. if (isRunningOnJdk131()) {
  1169. return; // test not valid on JDK-1.3.1
  1170. }
  1171. createTable("testBug15065", "(field1 int)");
  1172. this.stmt.executeUpdate("INSERT INTO testBug15065 VALUES (1)");
  1173. Connection advisorConn = null;
  1174. Statement advisorStmt = null;
  1175. try {
  1176. Properties props = new Properties();
  1177. props.setProperty("useUsageAdvisor", "true");
  1178. props.setProperty("logger", "com.mysql.jdbc.log.StandardLogger");
  1179. advisorConn = getConnectionWithProps(props);
  1180. advisorStmt = advisorConn.createStatement();
  1181. Method[] getMethods = ResultSet.class.getMethods();
  1182. PrintStream oldErr = System.err;
  1183. try {
  1184. ByteArrayOutputStream bOut = new ByteArrayOutputStream();
  1185. System.setErr(new PrintStream(bOut));
  1186. HashMap methodsToSkipMap = new HashMap();
  1187. // Needs an actual URL
  1188. methodsToSkipMap.put("getURL", null);
  1189. // Java6 JDBC4.0 methods we don't implement
  1190. methodsToSkipMap.put("getNCharacterStream", null);
  1191. methodsToSkipMap.put("getNClob", null);
  1192. methodsToSkipMap.put("getNString", null);
  1193. methodsToSkipMap.put("getRowId", null);
  1194. methodsToSkipMap.put("getSQLXML", null);
  1195. for (int j = 0; j < 2; j++) {
  1196. for (int i = 0; i < getMethods.length; i++) {
  1197. String methodName = getMethods[i].getName();
  1198. if (methodName.startsWith("get")
  1199. && !methodsToSkipMap.containsKey(methodName)) {
  1200. Class[] parameterTypes = getMethods[i]
  1201. .getParameterTypes();
  1202. if (parameterTypes.length == 1
  1203. && parameterTypes[0] == Integer.TYPE) {
  1204. if (j == 0) {
  1205. this.rs = advisorStmt
  1206. .executeQuery("SELECT COUNT(*) FROM testBug15065");
  1207. } else {
  1208. this.rs = advisorConn
  1209. .prepareStatement(
  1210. "SELECT COUNT(*) FROM testBug15065")
  1211. .executeQuery();
  1212. }
  1213. this.rs.next();
  1214. try {
  1215. getMethods[i].invoke(this.rs,
  1216. new Object[] { new Integer(1) });
  1217. } catch (InvocationTargetException invokeEx) {
  1218. // we don't care about bad values, just that
  1219. // the
  1220. // column gets "touched"
  1221. if (!invokeEx
  1222. .getCause()
  1223. .getClass()
  1224. .isAssignableFrom(
  1225. java.sql.SQLException.class)
  1226. && !invokeEx
  1227. .getCause()
  1228. .getClass()
  1229. .getName()
  1230. .equals(
  1231. "com.mysql.jdbc.NotImplemented")
  1232. && !invokeEx
  1233. .getCause()
  1234. .getClass()
  1235. .getName()
  1236. .equals(
  1237. "java.sql.SQLFeatureNotSupportedException")) {
  1238. throw invokeEx;
  1239. }
  1240. }
  1241. this.rs.close();
  1242. this.rs = null;
  1243. }
  1244. }
  1245. }
  1246. }
  1247. String logOut = bOut.toString("ISO8859-1");
  1248. if (logOut.indexOf(".Level") != -1) {
  1249. return; // we ignore for warnings
  1250. }
  1251. assertTrue("Usage advisor complained about columns:\n\n"
  1252. + logOut, logOut.indexOf("columns") == -1);
  1253. } finally {
  1254. System.setErr(oldErr);
  1255. }
  1256. } finally {
  1257. if (advisorConn != null) {
  1258. advisorConn.close();
  1259. }
  1260. }
  1261. }
  1262. /**
  1263. * Tests fix for BUG#15544, no "dos" character set in MySQL > 4.1.0
  1264. *
  1265. * @throws Exception
  1266. * if the test fails
  1267. */
  1268. public void testBug15544() throws Exception {
  1269. Properties props = new Properties();
  1270. props.setProperty("characterEncoding", "Cp437");
  1271. Connection dosConn = null;
  1272. try {
  1273. dosConn = getConnectionWithProps(props);
  1274. } finally {
  1275. if (dosConn != null) {
  1276. dosConn.close();
  1277. }
  1278. }
  1279. }
  1280. public void testCSC5765() throws Exception {
  1281. if (isRunningOnJdk131()) {
  1282. return; // test not valid on JDK-1.3.1
  1283. }
  1284. Properties props = new Properties();
  1285. props.setProperty("useUnicode", "true");
  1286. props.setProperty("characterEncoding", "utf8");
  1287. props.setProperty("characterSetResults", "utf8");
  1288. props.setProperty("connectionCollation", "utf8_bin");
  1289. Connection utf8Conn = null;
  1290. try {
  1291. utf8Conn = getConnectionWithProps(props);
  1292. this.rs = utf8Conn.createStatement().executeQuery(
  1293. "SHOW VARIABLES LIKE 'character_%'");
  1294. while (this.rs.next()) {
  1295. System.out.println(this.rs.getString(1) + " = "
  1296. + this.rs.getString(2));
  1297. }
  1298. this.rs = utf8Conn.createStatement().executeQuery(
  1299. "SHOW VARIABLES LIKE 'collation_%'");
  1300. while (this.rs.next()) {
  1301. System.out.println(this.rs.getString(1) + " = "
  1302. + this.rs.getString(2));
  1303. }
  1304. } finally {
  1305. if (utf8Conn != null) {
  1306. utf8Conn.close();
  1307. }
  1308. }
  1309. }
  1310. protected Connection getMasterSlaveReplicationConnection()
  1311. throws SQLException {
  1312. Connection replConn = new ReplicationDriver().connect(
  1313. getMasterSlaveUrl(), getMasterSlaveProps());
  1314. return replConn;
  1315. }
  1316. protected String getMasterSlaveUrl() throws SQLException {
  1317. StringBuffer urlBuf = new StringBuffer("jdbc:mysql://");
  1318. Properties defaultProps = getPropertiesFromTestsuiteUrl();
  1319. String hostname = defaultProps
  1320. .getProperty(NonRegisteringDriver.HOST_PROPERTY_KEY);
  1321. int colonIndex = hostname.indexOf(":");
  1322. String portNumber = "3306";
  1323. if (colonIndex != -1 && !hostname.startsWith(":")) {
  1324. portNumber = hostname.substring(colonIndex + 1);
  1325. hostname = hostname.substring(0, colonIndex);
  1326. } else if (hostname.startsWith(":")) {
  1327. portNumber = hostname.substring(1);
  1328. hostname = "localhost";
  1329. } else {
  1330. portNumber = defaultProps
  1331. .getProperty(NonRegisteringDriver.PORT_PROPERTY_KEY);
  1332. }
  1333. for (int i = 0; i < 2; i++) {
  1334. urlBuf.append(hostname);
  1335. urlBuf.append(":");
  1336. urlBuf.append(portNumber);
  1337. if (i == 0) {
  1338. urlBuf.append(",");
  1339. }
  1340. }
  1341. urlBuf.append("/");
  1342. return urlBuf.toString();
  1343. }
  1344. protected Properties getMasterSlaveProps() throws SQLException {
  1345. Properties props = getPropertiesFromTestsuiteUrl();
  1346. props.remove(NonRegisteringDriver.HOST_PROPERTY_KEY);
  1347. props.remove(NonRegisteringDriver.PORT_PROPERTY_KEY);
  1348. return props;
  1349. }
  1350. /**
  1351. * Tests fix for BUG#15570 - ReplicationConnection incorrectly copies state,
  1352. * doesn't transfer connection context correctly when transitioning between
  1353. * the same read-only states.
  1354. *
  1355. * (note, this test will fail if the test user doesn't have permission to
  1356. * "USE 'mysql'".
  1357. *
  1358. * @throws Exception
  1359. * if the test fails.
  1360. */
  1361. public void testBug15570() throws Exception {
  1362. Connection replConn = null;
  1363. try {
  1364. replConn = getMasterSlaveReplicationConnection();
  1365. int masterConnectionId = Integer
  1366. .parseInt(getSingleIndexedValueWithQuery(replConn, 1,
  1367. "SELECT CONNECTION_ID()").toString());
  1368. replConn.setReadOnly(false);
  1369. assertEquals(masterConnectionId, Integer
  1370. .parseInt(getSingleIndexedValueWithQuery(replConn, 1,
  1371. "SELECT CONNECTION_ID()").toString()));
  1372. String currentCatalog = replConn.getCatalog();
  1373. replConn.setCatalog(currentCatalog);
  1374. assertEquals(currentCatalog, replConn.getCatalog());
  1375. replConn.setReadOnly(true);
  1376. int slaveConnectionId = Integer
  1377. .parseInt(getSingleIndexedValueWithQuery(replConn, 1,
  1378. "SELECT CONNECTION_ID()").toString());
  1379. // The following test is okay for now, as the chance
  1380. // of MySQL wrapping the connection id counter during our
  1381. // testsuite is very small.
  1382. assertTrue("Slave id " + slaveConnectionId
  1383. + " is not newer than master id " + masterConnectionId,
  1384. slaveConnectionId > masterConnectionId);
  1385. assertEquals(currentCatalog, replConn.getCatalog());
  1386. String newCatalog = "mysql";
  1387. replConn.setCatalog(newCatalog);
  1388. assertEquals(newCatalog, replConn.getCatalog());
  1389. replConn.setReadOnly(true);
  1390. assertEquals(newCatalog, replConn.getCatalog());
  1391. replConn.setReadOnly(false);
  1392. assertEquals(masterConnectionId, Integer
  1393. .parseInt(getSingleIndexedValueWithQuery(replConn, 1,
  1394. "SELECT CONNECTION_ID()").toString()));
  1395. } finally {
  1396. if (replConn != null) {
  1397. replConn.close();
  1398. }
  1399. }
  1400. }
  1401. /**
  1402. * Tests bug where downed slave caused round robin load balance not to
  1403. * cycle back to first host in the list.
  1404. *
  1405. * @throws Exception
  1406. * if the test fails...Note, test is timing-dependent, but
  1407. * should work in most cases.
  1408. */
  1409. public void testBug23281() throws Exception {
  1410. Properties props = new Driver().parseURL(BaseTestCase.dbUrl, null);
  1411. props.setProperty("autoReconnect", "false");
  1412. props.setProperty("roundRobinLoadBalance", "true");
  1413. props.setProperty("failoverReadOnly", "false");
  1414. if (!isRunningOnJdk131()) {
  1415. props.setProperty("connectTimeout", "5000");
  1416. }
  1417. // Re-build the connection information
  1418. int firstIndexOfHost = BaseTestCase.dbUrl.indexOf("//") + 2;
  1419. int lastIndexOfHost = BaseTestCase.dbUrl.indexOf("/", firstIndexOfHost);
  1420. String hostPortPair = BaseTestCase.dbUrl.substring(firstIndexOfHost,
  1421. lastIndexOfHost);
  1422. StringTokenizer st = new StringTokenizer(hostPortPair, ":");
  1423. String host = null;
  1424. String port = null;
  1425. if (st.hasMoreTokens()) {
  1426. String possibleHostOrPort = st.nextToken();
  1427. if (Character.isDigit(possibleHostOrPort.charAt(0)) &&
  1428. (possibleHostOrPort.indexOf(".") == -1 /* IPV4 */) &&
  1429. (possibleHostOrPort.indexOf("::") == -1 /* IPV6 */)) {
  1430. port = possibleHostOrPort;
  1431. host = "localhost";
  1432. } else {
  1433. host = possibleHostOrPort;
  1434. }
  1435. }
  1436. if (st.hasMoreTokens()) {
  1437. port = st.nextToken();
  1438. }
  1439. if (host == null) {
  1440. host = "";
  1441. }
  1442. if (port == null) {
  1443. port = "3306";
  1444. }
  1445. StringBuffer newHostBuf = new StringBuffer();
  1446. newHostBuf.append(host);
  1447. if (port != null) {
  1448. newHostBuf.append(":");
  1449. newHostBuf.append(port);
  1450. }
  1451. newHostBuf.append(",");
  1452. //newHostBuf.append(host);
  1453. newHostBuf.append("192.0.2.1"); // non-exsitent machine from RFC3330 test network
  1454. newHostBuf.append(":65532"); // make sure the slave fails
  1455. props.remove("PORT");
  1456. props.remove("HOST");
  1457. Connection failoverConnection = null;
  1458. try {
  1459. failoverConnection = getConnectionWithProps("jdbc:mysql://"
  1460. + newHostBuf.toString() + "/", props);
  1461. String originalConnectionId = getSingleIndexedValueWithQuery(
  1462. failoverConnection, 1, "SELECT CONNECTION_ID()"