package org.mariadb.jdbc.failover; import org.junit.Test; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import java.util.concurrent.TimeUnit; import static org.junit.Assert.*; public abstract class BaseMonoServer extends BaseMultiHostTest { @Test public void testWriteOnMaster() throws SQLException { try (Connection connection = getNewConnection(false)) { Statement stmt = connection.createStatement(); stmt.execute("drop table if exists auroraMultiNode" + jobId); stmt.execute("create table auroraMultiNode" + jobId + " (id int not null primary key auto_increment, test VARCHAR(10))"); stmt.execute("drop table if exists auroraMultiNode" + jobId); } } @Test public void relaunchWithoutError() throws Throwable { try (Connection connection = getNewConnection("&connectTimeout=1000&socketTimeout=1000", true)) { Statement st = connection.createStatement(); int masterServerId = getServerId(connection); long startTime = System.currentTimeMillis(); stopProxy(masterServerId, 4000); try { st.execute("SELECT 1"); if (System.currentTimeMillis() - startTime < 4 * 1000) { fail("Auto-reconnection must have been done after 4000ms but was " + (System.currentTimeMillis() - startTime)); } } catch (SQLException e) { fail("must not have thrown error"); } } } @Test public void relaunchWithErrorWhenInTransaction() throws Throwable { try (Connection connection = getNewConnection("&connectTimeout=1000&socketTimeout=1000", true)) { Statement st = connection.createStatement(); st.execute("drop table if exists baseReplicationTransaction" + jobId); st.execute("create table baseReplicationTransaction" + jobId + " (id int not null primary key auto_increment, test VARCHAR(10))"); connection.setAutoCommit(false); st.execute("INSERT INTO baseReplicationTransaction" + jobId + "(test) VALUES ('test')"); int masterServerId = getServerId(connection); st.execute("SELECT 1"); long startTime = System.currentTimeMillis(); stopProxy(masterServerId, 2000); try { st.execute("SELECT 1"); fail("must have thrown error since in transaction that is lost"); } catch (SQLException e) { assertEquals("error type not normal after " + (System.currentTimeMillis() - startTime) + "ms", "25S03", e.getSQLState()); } st.execute("drop table if exists baseReplicationTransaction" + jobId); } } @Test public void failoverRelaunchedWhenSelect() throws Throwable { try (Connection connection = getNewConnection("&connectTimeout=1000&socketTimeout=1000&retriesAllDown=6", true)) { Statement st = connection.createStatement(); final int masterServerId = getServerId(connection); st.execute("drop table if exists selectFailover" + jobId); st.execute("create table selectFailover" + jobId + " (id int not null primary key , amount int not null) " + "ENGINE = InnoDB"); stopProxy(masterServerId, 2); try { st.execute("SELECT * from selectFailover" + jobId); } catch (SQLException e) { e.printStackTrace(); fail("must not have thrown error"); } stopProxy(masterServerId, 2); try { st.execute("INSERT INTO selectFailover" + jobId + " VALUES (1,2)"); fail("not have thrown error !"); } catch (SQLException e) { restartProxy(masterServerId); assertEquals("error type not normal", "25S03", e.getSQLState()); } } } @Test public void failoverRelaunchedWhenInTransaction() throws Throwable { try (Connection connection = getNewConnection( "&connectTimeout=1000&socketTimeout=1000&retriesAllDown=6", true)) { Statement st = connection.createStatement(); final int masterServerId = getServerId(connection); st.execute("drop table if exists selectFailoverTrans" + jobId); st.execute("create table selectFailoverTrans" + jobId + " (id int not null primary key , amount int not null) " + "ENGINE = InnoDB"); connection.setAutoCommit(false); st.execute("INSERT INTO selectFailoverTrans" + jobId + " VALUES (0,0)"); stopProxy(masterServerId, 2); try { st.execute("SELECT * from selectFailoverTrans" + jobId); fail("not have thrown error !"); } catch (SQLException e) { assertEquals("error type not normal", "25S03", e.getSQLState()); } stopProxy(masterServerId, 2); try { st.execute("INSERT INTO selectFailoverTrans" + jobId + " VALUES (1,2)"); fail("not have thrown error !"); } catch (SQLException e) { restartProxy(masterServerId); st.execute("drop table if exists selectFailoverTrans" + jobId); assertEquals("error type not normal", "25S03", e.getSQLState()); } } } @Test public void pingReconnectAfterRestart() throws Throwable { try (Connection connection = getNewConnection("&connectTimeout=1000&socketTimeout=1000&retriesAllDown=6", true)) { Statement st = connection.createStatement(); int masterServerId = getServerId(connection); stopProxy(masterServerId); try { st.execute("SELECT 1"); } catch (SQLException e) { //normal exception } restartProxy(masterServerId); long restartTime = System.nanoTime(); boolean loop = true; while (loop) { if (!connection.isClosed()) { loop = false; } try { connection.createStatement(); } catch (SQLException ee) { } long duration = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - restartTime); if (duration > 20 * 1000) { fail("Auto-reconnection not done after " + duration); } Thread.sleep(250); } } } }