gt:             Statement st = connection.createStatement();
context: package org.mariadb.jdbc.multihost;
  
  import org.junit.Assert;
  import org.junit.Assume;
  import org.junit.Test;
  import org.junit.experimental.theories.suppliers.TestedOn;
  import org.mariadb.jdbc.internal.common.QueryException;
  
  import java.sql.Connection;
  import java.sql.ResultSet;
  import java.sql.SQLException;
  import java.sql.Statement;
  import java.util.concurrent.ExecutorService;
  import java.util.concurrent.Executors;
  import java.util.concurrent.ScheduledFuture;
  import java.util.concurrent.TimeUnit;
  
  public class MultiHostFailoverTest extends BaseMultiHostTest {
  
      @Test
      public void testMultiHostWriteOnMaster() throws SQLException {
          Assume.assumeTrue(multihostUrlOk);
          Connection connection = null;
          log.fine("testMultiHostWriteOnMaster begin");
          try {
              connection = getNewConnection();
              Statement stmt = connection.createStatement();
              stmt.execute("drop table  if exists multinode");
              stmt.execute("create table multinode (id int not null primary key auto_increment, test VARCHAR(10))");
              log.fine("testMultiHostWriteOnMaster OK");
          } finally {
              log.fine("testMultiHostWriteOnMaster done");
              if (connection != null) connection.close();
          }
      }
  
      @Test
      public void testMultiHostWriteOnSlave() throws SQLException {
          Assume.assumeTrue(multihostUrlOk);
          Connection connection = null;
          log.fine("testMultiHostWriteOnSlave begin");
          try {
              connection = getNewConnection();
              //if super user, has write to write on slaves
              Assume.assumeTrue(!hasSuperPrivilege(connection, "testMultiHostWriteOnSlave"));
              connection.setReadOnly(true);
              Statement stmt = connection.createStatement();
              Assert.assertTrue(connection.isReadOnly());
              stmt.execute("drop table  if exists multinodeFail");
              try {
                  stmt.execute("create table multinodeFail (id int not null primary key auto_increment, test VARCHAR(10))");
                  log.severe("ERROR - > must not be able to write on slave --> check if you database is start with --read-only");
                  Assert.fail();
              } catch (SQLException e) { }
          } finally {
              log.fine("testMultiHostWriteOnMaster done");
              if (connection != null) connection.close();
          }
      }
  
      @Test
      public void testMultiHostReadOnSlave() throws SQLException {
          Assume.assumeTrue(multihostUrlOk);
          Connection connection = null;
          log.fine("testMultiHostReadOnSlave begin");
          try {
              connection = getNewConnection();
              Statement stmt = connection.createStatement();
              stmt.execute("drop table  if exists multinodeRead");
              stmt.execute("create table multinodeRead (id int not null primary key auto_increment, test VARCHAR(10))");
  
              connection.setReadOnly(true);
              ResultSet rs = stmt.executeQuery("Select count(*) from multinodeRead");
              Assert.assertTrue(rs.next());
          } finally {
              log.fine("testMultiHostReadOnSlave done");
              if (connection != null) connection.close();
          }
      }
  
      @Test
      public void failoverSlaveToMaster() throws SQLException {
          Assume.assumeTrue(multihostUrlOk);
          Connection connection = null;
          log.fine("failoverSlaveToMaster begin");
          try {
              connection = getNewConnection();
              connection.setReadOnly(true);
              Statement st = connection.createStatement();
              ResultSet rs = st.executeQuery("SHOW SESSION VARIABLES LIKE 'server_id'");
              rs.next();
              int salveServerId = rs.getInt(2);
  
              tcpProxies[1].restart(2000);
  
              rs = st.executeQuery("SHOW SESSION VARIABLES LIKE 'server_id'");
              rs.next();
              int masterServerId = rs.getInt(2);
  
              Assert.assertFalse(salveServerId == masterServerId);
              Assert.assertFalse(connection.isReadOnly());
          } finally {
              log.fine("failoverSlaveToMaster done");
              try {
                  Thread.sleep(2000); //wait to not have problem with next test
              } catch (InterruptedException e) {
              }
              if (connection != null) connection.close();
          }
      }
  
  
      @Test(expected = SQLException.class)
      public void failoverSlaveAndMasterWithoutAutoConnect() throws SQLException {
          Assume.assumeTrue(multihostUrlOk);
          Connection connection = null;
          log.fine("failoverSlaveAndMasterWithoutAutoConnect begin");
          try {
              connection = getNewConnection();
              Statement st = connection.createStatement();
              connection.setReadOnly(true);
              tcpProxies[0].restart(2000);
              tcpProxies[1].restart(2000);
  
              //must throw an error, because not in autoreconnect Mode
              ResultSet rs = st.executeQuery("SELECT CONNECTION_ID()");
              rs.next();
          } finally {
              log.fine("failoverSlaveAndMasterWithoutAutoConnect done");
              try {
                  Thread.sleep(2000); //wait to not have problem with next test
              } catch (InterruptedException e) {
              }
              if (connection != null) connection.close();
          }
      }
  
      @Test
      public void failoverSlaveAndMasterWithAutoConnect() throws Throwable {
          Assume.assumeTrue(multihostUrlOk);
          Connection connection = null;
          log.fine("failoverSlaveAndMasterWithAutoConnect begin");
          try {
              connection = getNewConnection("&autoReconnect=true");
              Statement st = connection.createStatement();
  
              //search actual server_id for master and slave
              ResultSet rs = st.executeQuery("SHOW SESSION VARIABLES LIKE 'server_id'");
              rs.next();
              int masterServerId = rs.getInt(2);
              log.fine("master server_id = " + masterServerId);
              connection.setReadOnly(true);
              rs = st.executeQuery("SHOW SESSION VARIABLES LIKE 'server_id'");
              rs.next();
              int firstSlaveId = rs.getInt(2);
              log.fine("slave1 server_id = " + firstSlaveId);
  
              tcpProxies[0].restart(3000);
              tcpProxies[1].restart(3000);
  
              //must reconnect to the second slave without error
              rs = st.executeQuery("SHOW SESSION VARIABLES LIKE 'server_id'");
              rs.next();
              int currentSlaveId = rs.getInt(2);
              log.fine("currentSlaveId server_id = " + currentSlaveId);
              rs.next();
              Assert.assertTrue(currentSlaveId != firstSlaveId);
              Assert.assertTrue(currentSlaveId != masterServerId);
          } finally {
              log.fine("failoverSlaveAndMasterWithAutoConnect done");
              try {
                  Thread.sleep(3000); //wait to not have problem with next test
              } catch (InterruptedException e) {
              }
              if (connection != null) connection.close();
          }
      }
      @Test
      public void failoverMasterWithAutoConnect() throws SQLException, InterruptedException{
          Assume.assumeTrue(multihostUrlOk);
          Connection connection = null;
          log.fine("failoverMasterWithAutoConnect begin");
          try {
              connection = getNewConnection("&autoReconnect=true");
              Statement st = connection.createStatement();
              ResultSet rs = st.executeQuery("SHOW SESSION VARIABLES LIKE 'server_id'");
              rs.next();
              int masterServerId = rs.getInt(2);
  
              tcpProxies[0].restart(100);
              //with autoreconnect, the connection must reconnect automatically
              rs = st.executeQuery("SHOW SESSION VARIABLES LIKE 'server_id'");
              rs.next();
              int currentServerId = rs.getInt(2);
  
              Assert.assertTrue(currentServerId == masterServerId);
              Assert.assertFalse(connection.isReadOnly());
          } finally {
              log.fine("failoverMasterWithAutoConnect done");
              try {
                  Thread.sleep(2000); //wait to not have problem with next test
              } catch (InterruptedException e) {
              }
              if (connection != null) connection.close();
          }
      }
  
      @Test
      public void checkReconnectionToMasterAfterTimeout() throws SQLException, NoSuchFieldException, InterruptedException {
          Assume.assumeTrue(multihostUrlOk);
          Connection connection = null;
          log.fine("checkReconnectionToMasterAfterTimeout begin");
          try {
              connection = getNewConnection("&secondsBeforeRetryMaster=1");
              Statement st = connection.createStatement();
              ResultSet rs = st.executeQuery("SHOW SESSION VARIABLES LIKE 'server_id'");
              rs.next();
              int masterServerId = rs.getInt(2);
  
              tcpProxies[0].restart(2000);
              try {
                  st.execute("SELECT 1");
              } catch (Exception e) {
              }
  
              //wait for more than the 1s (secondsBeforeRetryMaster) timeout, to check that master is on
              Thread.sleep(3000);
  
              rs = st.executeQuery("SHOW SESSION VARIABLES LIKE 'server_id'");
              rs.next();
              int currentServerId = rs.getInt(2);
  
              Assert.assertTrue(currentServerId == masterServerId);
              Assert.assertFalse(connection.isReadOnly());
          } finally {
              log.fine("checkReconnectionToMasterAfterTimeout done");
              if (connection != null) connection.close();
          }
      }
  
      @Test
      public void checkReconnectionToMasterAfterQueryNumber() throws SQLException, NoSuchFieldException, InterruptedException {
          Assume.assumeTrue(multihostUrlOk);
          Connection connection = null;
          log.fine("checkReconnectionToMasterAfterQueryNumber begin");
          try {
              connection = getNewConnection("&autoReconnect=true&secondsBeforeRetryMaster=30&queriesBeforeRetryMaster=10");
              Statement st = connection.createStatement();
              ResultSet rs = st.executeQuery("SHOW SESSION VARIABLES LIKE 'server_id'");
              rs.next();
              int masterServerId = rs.getInt(2);
              tcpProxies[0].restart(2000);
  
              for (int i = 0; i < 10; i++) {
                  rs = st.executeQuery("SHOW SESSION VARIABLES LIKE 'server_id'");
                  rs.next();
                  int currentServerId = rs.getInt(2);
                  Assert.assertFalse(currentServerId == masterServerId);
                  Thread.sleep(250);
              }
  
              Thread.sleep(500);
              rs = st.executeQuery("SHOW SESSION VARIABLES LIKE 'server_id'");
              rs.next();
              int currentServerId = rs.getInt(2);
              Assert.assertTrue(currentServerId == masterServerId);
          } finally {
              log.fine("checkReconnectionToMasterAfterQueryNumber done");
              if (connection != null) connection.close();
          }
      }
  
      @Test
      public void writeToSlaveAfterFailover() throws SQLException, InterruptedException{
          Assume.assumeTrue(multihostUrlOk);
          Connection connection = null;
          log.fine("writeToSlaveAfterFailover begin");
          try {
              connection = getNewConnection();
              //if super user can write on slave
              Assume.assumeTrue(!hasSuperPrivilege(connection, "writeToSlaveAfterFailover"));
  