Search in sources :

Example 16 with Session

use of com.mysql.cj.xdevapi.Session in project aws-mysql-jdbc by awslabs.

the class SessionTest method basicSessionFailoverRandomSort.

@Test
public void basicSessionFailoverRandomSort() {
    UnreliableSocketFactory.flushAllStaticData();
    final String testUriPattern = "mysqlx://%s:%s@[%s]/%s?" + PropertyKey.xdevapiConnectTimeout.getKeyName() + "=100&" + PropertyKey.socketFactory.getKeyName() + "=" + UnreliableSocketFactory.class.getName();
    String testHosts = IntStream.range(1, 6).mapToObj(i -> "host" + i).peek(h -> UnreliableSocketFactory.mapHost(h, getTestHost())).map(h -> h + ":" + getTestPort()).collect(Collectors.joining(","));
    String testUri = String.format(testUriPattern, getTestUser() == null ? "" : getTestUser(), getTestPassword() == null ? "" : getTestPassword(), testHosts, getTestDatabase());
    Set<String> downHosts = new HashSet<>();
    for (int i = 1; i <= 5; i++) {
        Session testSession = this.fact.getSession(testUri);
        assertTrue(UnreliableSocketFactory.isConnected());
        testSession.close();
        String lastHost = UnreliableSocketFactory.getHostFromLastConnection();
        for (String h : downHosts) {
            assertNotEquals(h, lastHost);
        }
        downHosts.add(lastHost);
        UnreliableSocketFactory.downHost(lastHost.substring(1));
    }
    // None of the hosts is available by now.
    assertThrows(CJCommunicationsException.class, "Unable to connect to any of the target hosts\\.", () -> {
        this.fact.getSession(testUri);
        return null;
    });
    UnreliableSocketFactory.dontDownHost("host3");
    UnreliableSocketFactory.flushConnectionAttempts();
    Session testSession = this.fact.getSession(testUri);
    assertTrue(UnreliableSocketFactory.isConnected());
    testSession.close();
    assertEquals(UnreliableSocketFactory.getHostConnectedStatus("host3"), UnreliableSocketFactory.getHostFromLastConnection());
}
Also used : BeforeEach(org.junit.jupiter.api.BeforeEach) XDevAPIError(com.mysql.cj.xdevapi.XDevAPIError) RowResult(com.mysql.cj.xdevapi.RowResult) JsonNumber(com.mysql.cj.xdevapi.JsonNumber) ServerMessages(com.mysql.cj.x.protobuf.Mysqlx.ServerMessages) Assertions.assertNotEquals(org.junit.jupiter.api.Assertions.assertNotEquals) Random(java.util.Random) Collection(com.mysql.cj.xdevapi.Collection) ByteBuffer(java.nio.ByteBuffer) Constants(com.mysql.cj.Constants) Future(java.util.concurrent.Future) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) SqlStatement(com.mysql.cj.xdevapi.SqlStatement) Map(java.util.Map) ClientImpl(com.mysql.cj.xdevapi.ClientImpl) CoreSession(com.mysql.cj.CoreSession) ServerVersion(com.mysql.cj.ServerVersion) WrongArgumentException(com.mysql.cj.exceptions.WrongArgumentException) CJCommunicationsException(com.mysql.cj.exceptions.CJCommunicationsException) Warning(com.mysql.cj.xdevapi.Warning) SocketFactory(com.mysql.cj.protocol.SocketFactory) Set(java.util.Set) BlockingQueue(java.util.concurrent.BlockingQueue) XdevapiSslMode(com.mysql.cj.conf.PropertyDefinitions.XdevapiSslMode) Collectors(java.util.stream.Collectors) FileNotFoundException(java.io.FileNotFoundException) Executors(java.util.concurrent.Executors) PropertyDefinitions(com.mysql.cj.conf.PropertyDefinitions) Test(org.junit.jupiter.api.Test) ByteOrder(java.nio.ByteOrder) List(java.util.List) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) FeatureNotAvailableException(com.mysql.cj.exceptions.FeatureNotAvailableException) SqlMultiResult(com.mysql.cj.xdevapi.SqlMultiResult) InjectedSocketFactory(testsuite.InjectedSocketFactory) FindStatement(com.mysql.cj.xdevapi.FindStatement) Assertions.fail(org.junit.jupiter.api.Assertions.fail) IntStream(java.util.stream.IntStream) MysqlErrorNumbers(com.mysql.cj.exceptions.MysqlErrorNumbers) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) UnreliableSocketFactory(testsuite.UnreliableSocketFactory) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) HashMap(java.util.HashMap) Callable(java.util.concurrent.Callable) CompletableFuture(java.util.concurrent.CompletableFuture) JsonString(com.mysql.cj.xdevapi.JsonString) Schema(com.mysql.cj.xdevapi.Schema) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) ClientFactory(com.mysql.cj.xdevapi.ClientFactory) Client(com.mysql.cj.xdevapi.Client) ClientProperty(com.mysql.cj.xdevapi.Client.ClientProperty) Assumptions.assumeTrue(org.junit.jupiter.api.Assumptions.assumeTrue) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) WeakReference(java.lang.ref.WeakReference) SessionImpl(com.mysql.cj.xdevapi.SessionImpl) ExecutorService(java.util.concurrent.ExecutorService) Session(com.mysql.cj.xdevapi.Session) Properties(java.util.Properties) Frame(com.mysql.cj.x.protobuf.MysqlxNotice.Frame) Iterator(java.util.Iterator) DbDoc(com.mysql.cj.xdevapi.DbDoc) DocResult(com.mysql.cj.xdevapi.DocResult) Field(java.lang.reflect.Field) Compression(com.mysql.cj.conf.PropertyDefinitions.Compression) XProtocolError(com.mysql.cj.protocol.x.XProtocolError) SessionFactory(com.mysql.cj.xdevapi.SessionFactory) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) Row(com.mysql.cj.xdevapi.Row) SqlResult(com.mysql.cj.xdevapi.SqlResult) MessageLite(com.google.protobuf.MessageLite) AfterEach(org.junit.jupiter.api.AfterEach) SelectStatement(com.mysql.cj.xdevapi.SelectStatement) PooledXProtocol(com.mysql.cj.xdevapi.ClientImpl.PooledXProtocol) PropertyKey(com.mysql.cj.conf.PropertyKey) CJPacketTooBigException(com.mysql.cj.exceptions.CJPacketTooBigException) UnreliableSocketFactory(testsuite.UnreliableSocketFactory) JsonString(com.mysql.cj.xdevapi.JsonString) HashSet(java.util.HashSet) CoreSession(com.mysql.cj.CoreSession) Session(com.mysql.cj.xdevapi.Session) Test(org.junit.jupiter.api.Test)

Example 17 with Session

use of com.mysql.cj.xdevapi.Session in project aws-mysql-jdbc by awslabs.

the class SessionTest method testBug97269.

/**
 * Test fix for Bug#97269 (30438500), POSSIBLE BUG IN COM.MYSQL.CJ.XDEVAPI.STREAMINGDOCRESULTBUILDER.
 *
 * @throws Exception
 */
@Test
public void testBug97269() throws Exception {
    Session sess = null;
    try {
        String message1 = "W1";
        String message2 = "W2";
        // create notice message buffers
        Frame.Builder notice1 = Frame.newBuilder().setScope(Frame.Scope.LOCAL).setType(Frame.Type.WARNING_VALUE).setPayload(com.mysql.cj.x.protobuf.MysqlxNotice.Warning.newBuilder().setCode(MysqlErrorNumbers.ER_BAD_DB_ERROR).setMsg(message1).build().toByteString());
        Frame.Builder notice2 = Frame.newBuilder().setScope(Frame.Scope.GLOBAL).setType(Frame.Type.WARNING_VALUE).setPayload(com.mysql.cj.x.protobuf.MysqlxNotice.Warning.newBuilder().setCode(MysqlErrorNumbers.ER_BAD_DB_ERROR).setMsg(message2).build().toByteString());
        byte[] notice1Bytes = makeNoticeBytes(notice1.build());
        byte[] notice2Bytes = makeNoticeBytes(notice2.build());
        int size = notice1Bytes.length + notice2Bytes.length;
        byte[] noticesBytes = new byte[size];
        System.arraycopy(notice1Bytes, 0, noticesBytes, 0, notice1Bytes.length);
        System.arraycopy(notice2Bytes, 0, noticesBytes, notice1Bytes.length, notice2Bytes.length);
        InjectedSocketFactory.flushAllStaticData();
        String url = this.baseUrl + (this.baseUrl.contains("?") ? "" : "?") + makeParam(PropertyKey.socketFactory, InjectedSocketFactory.class.getName(), !this.baseUrl.contains("?") || this.baseUrl.endsWith("?")) + makeParam(PropertyKey.xdevapiSslMode, XdevapiSslMode.DISABLED.toString()) + makeParam(PropertyKey.xdevapiCompression, Compression.DISABLED.toString()) + // to allow injection between result rows
        makeParam(PropertyKey.useReadAheadInput, "false");
        sess = this.fact.getSession(url);
        SocketFactory sf = ((SessionImpl) sess).getSession().getProtocol().getSocketConnection().getSocketFactory();
        assertTrue(InjectedSocketFactory.class.isAssignableFrom(sf.getClass()));
        Collection collection = sess.getDefaultSchema().createCollection("testBug97269");
        collection.add("{\"_id\":\"the_id\",\"g\":1}").execute();
        // StreamingDocResultBuilder
        InjectedSocketFactory.injectedBuffer = noticesBytes;
        DocResult docs = collection.find().fields("$._id as _id, $.g as g, 1 + 1 as q").execute();
        DbDoc doc = docs.next();
        assertEquals("the_id", ((JsonString) doc.get("_id")).getString());
        assertEquals(new Integer(1), ((JsonNumber) doc.get("g")).getInteger());
        assertEquals(new Integer(2), ((JsonNumber) doc.get("q")).getInteger());
        int cnt = 0;
        for (Iterator<Warning> warn = docs.getWarnings(); warn.hasNext(); ) {
            Warning w = warn.next();
            if (w.getMessage().equals(message1) || w.getMessage().equals(message2)) {
                cnt++;
            }
        }
        assertEquals(2, cnt);
        InjectedSocketFactory.flushAllStaticData();
        InjectedSocketFactory.injectedBuffer = noticesBytes;
        SqlResult rs1 = sess.sql("select 1").execute();
        assertEquals(1, rs1.fetchOne().getInt(0));
        cnt = 0;
        for (Iterator<Warning> warn = rs1.getWarnings(); warn.hasNext(); ) {
            Warning w = warn.next();
            if (w.getMessage().equals(message1) || w.getMessage().equals(message2)) {
                cnt++;
            }
        }
        assertEquals(2, cnt);
    } finally {
        InjectedSocketFactory.flushAllStaticData();
        dropCollection("testBug97269");
        if (sess != null) {
            sess.close();
        }
    }
}
Also used : Frame(com.mysql.cj.x.protobuf.MysqlxNotice.Frame) Warning(com.mysql.cj.xdevapi.Warning) SqlResult(com.mysql.cj.xdevapi.SqlResult) SocketFactory(com.mysql.cj.protocol.SocketFactory) InjectedSocketFactory(testsuite.InjectedSocketFactory) UnreliableSocketFactory(testsuite.UnreliableSocketFactory) JsonString(com.mysql.cj.xdevapi.JsonString) DbDoc(com.mysql.cj.xdevapi.DbDoc) InjectedSocketFactory(testsuite.InjectedSocketFactory) Collection(com.mysql.cj.xdevapi.Collection) DocResult(com.mysql.cj.xdevapi.DocResult) CoreSession(com.mysql.cj.CoreSession) Session(com.mysql.cj.xdevapi.Session) Test(org.junit.jupiter.api.Test)

Example 18 with Session

use of com.mysql.cj.xdevapi.Session in project aws-mysql-jdbc by awslabs.

the class SessionTest method testPooledSessions.

@SuppressWarnings("unchecked")
@Test
public void testPooledSessions() throws Exception {
    final ClientFactory cf = new ClientFactory();
    final String url = this.baseUrl;
    final Properties props = new Properties();
    /*
         * UT8/1: Verify that setting an incorrect value in the client options defined in the Pooling options in the HLS throw an exception with the expected
         * message.
         */
    // pooling.enabled
    props.clear();
    assertThrows(XDevAPIError.class, "Client option 'pooling\\.enabled' does not support value 'sure'\\.", new Callable<Void>() {

        public Void call() throws Exception {
            props.setProperty(ClientProperty.POOLING_ENABLED.getKeyName(), "sure");
            cf.getClient(url, props);
            return null;
        }
    });
    assertThrows(XDevAPIError.class, "Client option 'pooling\\.enabled' does not support value 'sure'\\.", new Callable<Void>() {

        public Void call() throws Exception {
            cf.getClient(url, "{\"pooling\": {\"enabled\": \"sure\"}}");
            return null;
        }
    });
    // pooling.maxSize
    props.clear();
    assertThrows(XDevAPIError.class, "Client option 'pooling\\.maxSize' does not support value '0'\\.", new Callable<Void>() {

        public Void call() throws Exception {
            props.setProperty(ClientProperty.POOLING_MAX_SIZE.getKeyName(), "0");
            cf.getClient(url, props);
            return null;
        }
    });
    assertThrows(XDevAPIError.class, "Client option 'pooling\\.maxSize' does not support value '0'\\.", new Callable<Void>() {

        public Void call() throws Exception {
            cf.getClient(url, "{\"pooling\": {\"maxSize\": 0}}");
            return null;
        }
    });
    assertThrows(XDevAPIError.class, "Client option 'pooling\\.maxSize' does not support value 'one'\\.", new Callable<Void>() {

        public Void call() throws Exception {
            cf.getClient(url, "{\"pooling\": {\"maxSize\": \"one\"}}");
            return null;
        }
    });
    // pooling.maxIdleTime
    props.clear();
    assertThrows(XDevAPIError.class, "Client option 'pooling\\.maxIdleTime' does not support value '-1'\\.", new Callable<Void>() {

        public Void call() throws Exception {
            props.setProperty(ClientProperty.POOLING_MAX_IDLE_TIME.getKeyName(), "-1");
            cf.getClient(url, props);
            return null;
        }
    });
    assertThrows(XDevAPIError.class, "Client option 'pooling\\.maxIdleTime' does not support value '-1'\\.", new Callable<Void>() {

        public Void call() throws Exception {
            cf.getClient(url, "{\"pooling\": {\"maxIdleTime\": -1}}");
            return null;
        }
    });
    assertThrows(XDevAPIError.class, "Client option 'pooling\\.maxIdleTime' does not support value 'one'\\.", new Callable<Void>() {

        public Void call() throws Exception {
            cf.getClient(url, "{\"pooling\": {\"maxIdleTime\": \"one\"}}");
            return null;
        }
    });
    // pooling.queueTimeout
    props.clear();
    assertThrows(XDevAPIError.class, "Client option 'pooling\\.queueTimeout' does not support value '-1'\\.", new Callable<Void>() {

        public Void call() throws Exception {
            props.setProperty(ClientProperty.POOLING_QUEUE_TIMEOUT.getKeyName(), "-1");
            cf.getClient(url, props);
            return null;
        }
    });
    assertThrows(XDevAPIError.class, "Client option 'pooling\\.queueTimeout' does not support value '-1'\\.", new Callable<Void>() {

        public Void call() throws Exception {
            cf.getClient(url, "{\"pooling\": {\"queueTimeout\": -1}}");
            return null;
        }
    });
    assertThrows(XDevAPIError.class, "Client option 'pooling\\.queueTimeout' does not support value 'one'\\.", new Callable<Void>() {

        public Void call() throws Exception {
            cf.getClient(url, "{\"pooling\": {\"queueTimeout\": \"one\"}}");
            return null;
        }
    });
    // Unknown pooling option.
    props.clear();
    assertThrows(XDevAPIError.class, "Client option 'pooling\\.foo' is not recognized as valid\\.", new Callable<Void>() {

        public Void call() throws Exception {
            props.setProperty("pooling.foo", "bar");
            cf.getClient(url, props);
            return null;
        }
    });
    assertThrows(XDevAPIError.class, "Client option 'pooling\\.foo' is not recognized as valid\\.", new Callable<Void>() {

        public Void call() throws Exception {
            cf.getClient(url, "{\"pooling\": {\"foo\": \"bar\"}}");
            return null;
        }
    });
    // Unknown clientProps option.
    props.clear();
    assertThrows(XDevAPIError.class, "Client option 'foo' is not recognized as valid\\.", new Callable<Void>() {

        public Void call() throws Exception {
            props.setProperty("foo", "bar");
            cf.getClient(url, props);
            return null;
        }
    });
    assertThrows(XDevAPIError.class, "Client option 'foo' is not recognized as valid\\.", new Callable<Void>() {

        public Void call() throws Exception {
            cf.getClient(url, "{\"foo\": {\"bar\": \"baz\"}}");
            return null;
        }
    });
    /*
         * UT9/1: Verify that when no pooling properties passed their values set to defaults: pooling.maxSize=25, pooling.maxIdleTime=0, pooling.queueTimeout=0.
         */
    props.clear();
    testPooledSessions_checkClientProperties(cf.getClient(this.baseUrl, props), 25, 0, 0);
    testPooledSessions_checkClientProperties(cf.getClient(this.baseUrl, (Properties) null), 25, 0, 0);
    testPooledSessions_checkClientProperties(cf.getClient(this.baseUrl, "{}"), 25, 0, 0);
    testPooledSessions_checkClientProperties(cf.getClient(this.baseUrl, (String) null), 25, 0, 0);
    /*
         * UT9/2: Verify that when all pooling properties passed via Properties object the Client is configured according to their values.
         */
    props.setProperty(ClientProperty.POOLING_ENABLED.getKeyName(), "true");
    props.setProperty(ClientProperty.POOLING_MAX_SIZE.getKeyName(), "5");
    props.setProperty(ClientProperty.POOLING_MAX_IDLE_TIME.getKeyName(), "6");
    props.setProperty(ClientProperty.POOLING_QUEUE_TIMEOUT.getKeyName(), "7");
    testPooledSessions_checkClientProperties(cf.getClient(this.baseUrl, props), 5, 6, 7);
    /*
         * UT9/3: Verify that when all pooling properties passed via json string ({"pooling" : {"enabled" : true, "maxSize" : 8, "maxIdleTime" : 9,
         * "queueTimeout" : 10} }) the Client is configured according to their values.
         */
    testPooledSessions_checkClientProperties(cf.getClient(this.baseUrl, "{\"pooling\" : {\"enabled\" : true, \"maxSize\" : 8, \"maxIdleTime\" : 9, \"queueTimeout\" : 10} }"), 8, 9, 10);
    /*
         * UT3/2: Start a client with pooling enabled, call Client.getSession() twice and verify that the objects returned are different and the internal
         * connection instances are different too.
         */
    Client cli0 = cf.getClient(this.baseUrl, "{\"pooling\": {\"enabled\": true}}");
    Session s0 = cli0.getSession();
    Session s1 = cli0.getSession();
    assertNotEquals(s0, s1);
    Field fProtocol = CoreSession.class.getDeclaredField("protocol");
    fProtocol.setAccessible(true);
    assertNotEquals(fProtocol.get(((SessionImpl) s0).getSession()), fProtocol.get(((SessionImpl) s1).getSession()));
    cli0.close();
    /*
         * UT3/3: Start a client with pooling enabled, call Client.getSession() twice, closing the first session before getting the second one, and verify that
         * the objects returned are different and that the internal connection instances are the same.
         */
    cli0 = cf.getClient(this.baseUrl, "{\"pooling\": {\"enabled\": true}}");
    s0 = cli0.getSession();
    s0.close();
    s1 = cli0.getSession();
    s1.sql("SELECT 1").execute();
    assertNotEquals(s0, s1);
    assertEquals(fProtocol.get(((SessionImpl) s0).getSession()), fProtocol.get(((SessionImpl) s1).getSession()));
    cli0.close();
    /*
         * UT3/4: Start a client with pooling disabled, call Client.getSession() twice and verify that the objects returned are different and the internal
         * connection instances are different too.
         */
    cli0 = cf.getClient(this.baseUrl, "{\"pooling\": {\"enabled\": false}}");
    s0 = cli0.getSession();
    s1 = cli0.getSession();
    assertNotEquals(s0, s1);
    assertNotEquals(fProtocol.get(((SessionImpl) s0).getSession()), fProtocol.get(((SessionImpl) s1).getSession()));
    cli0.close();
    /*
         * UT3/5: Start a client with pooling disabled, call Client.getSession() twice, closing the first session before getting the second one, and verify that
         * the objects returned are different and that the internal connection instances are different too.
         */
    cli0 = cf.getClient(this.baseUrl, "{\"pooling\": {\"enabled\": false}}");
    s0 = cli0.getSession();
    s0.close();
    s1 = cli0.getSession();
    assertNotEquals(s0, s1);
    assertNotEquals(fProtocol.get(((SessionImpl) s0).getSession()), fProtocol.get(((SessionImpl) s1).getSession()));
    cli0.close();
    /*
         * UT5/1: Having a full pool and queueTimeout = 0, verify that a new Client.getSession() waits until a Session is released.
         * UT6/1: Verify that that a client object can not open/create more sessions that the specified in the maxSize option.
         */
    props.setProperty(ClientProperty.POOLING_MAX_SIZE.getKeyName(), "3");
    props.setProperty(ClientProperty.POOLING_MAX_IDLE_TIME.getKeyName(), "1000");
    props.setProperty(ClientProperty.POOLING_QUEUE_TIMEOUT.getKeyName(), "1000");
    Client cli1 = cf.getClient(this.baseUrl, props);
    s1 = cli1.getSession();
    Session s2 = cli1.getSession();
    Session s3 = cli1.getSession();
    testPooledSessions_assertFailureTimeout(cli1, 1000, 2000, XDevAPIError.class, "Session can not be obtained within 1000 milliseconds.");
    cli1.close();
    /*
         * UT12/1: Having a pool with a single connection, close the Session, get another Session with Client.getSession(). Verify that the received Session
         * object is new and uses the same internal connection (MysqlxSession) instance.
         */
    cli0 = cf.getClient(this.baseUrl, "{\"pooling\": {\"enabled\": true, \"maxSize\" : 1}}");
    s0 = cli0.getSession();
    s0.close();
    s1 = cli0.getSession();
    s1.sql("SELECT 1").execute();
    assertNotEquals(s0, s1);
    assertEquals(fProtocol.get(((SessionImpl) s0).getSession()), fProtocol.get(((SessionImpl) s1).getSession()));
    cli0.close();
    /*
         * UT12/2: Having a pool with a number of connections greater than 1 and lower than maxPoolSize, close on Session, get another Session with
         * Client.getSession(). Verify that the received Session object is new and uses the same internal connection (MysqlxSession) instance.
         */
    cli0 = cf.getClient(this.baseUrl, "{\"pooling\": {\"enabled\": true, \"maxSize\" : 3}}");
    s0 = cli0.getSession();
    s0.close();
    s1 = cli0.getSession();
    s1.sql("SELECT 1").execute();
    assertNotEquals(s0, s1);
    assertEquals(fProtocol.get(((SessionImpl) s0).getSession()), fProtocol.get(((SessionImpl) s1).getSession()));
    cli0.close();
    /*
         * UT12/3: Having a full pool with all sessions in active state, close one Session, get another Session with Client.getSession(). Verify that the
         * received Session object is new and uses the same internal connection (MysqlxSession) instance.
         */
    cli0 = cf.getClient(this.baseUrl, "{\"pooling\": {\"enabled\": true, \"maxSize\" : 3}}");
    s0 = cli0.getSession();
    s1 = cli0.getSession();
    s2 = cli0.getSession();
    s0.close();
    s3 = cli0.getSession();
    s3.sql("SELECT 1").execute();
    assertNotEquals(s0, s3);
    assertEquals(fProtocol.get(((SessionImpl) s0).getSession()), fProtocol.get(((SessionImpl) s3).getSession()));
    cli0.close();
    /*
         * UT11/2: Having a pool with a single idle connection and maxIdleTime = n, verify that after n milliseconds a Client.getSession() call will remove all
         * expired sessions from pool and return a new Session object that uses a new MysqlxSession instance.
         */
    cli0 = cf.getClient(this.baseUrl, "{\"pooling\": {\"enabled\": true, \"maxSize\" : 3, \"maxIdleTime\" : 1000}}");
    s0 = cli0.getSession();
    s0.close();
    Thread.sleep(2000);
    s1 = cli0.getSession();
    assertNotEquals(s0, s1);
    assertNotEquals(fProtocol.get(((SessionImpl) s0).getSession()), fProtocol.get(((SessionImpl) s1).getSession()));
    Field fIdleSessions = ClientImpl.class.getDeclaredField("idleProtocols");
    fIdleSessions.setAccessible(true);
    assertTrue(((BlockingQueue<PooledXProtocol>) fIdleSessions.get(cli0)).isEmpty());
    /*
         * UT4/1: Verify that all idle and active sessions are closed after Client.close() call.
         */
    cli0 = cf.getClient(this.baseUrl, "{\"pooling\": {\"enabled\": true, \"maxSize\" : 3}}");
    s0 = cli0.getSession();
    s1 = cli0.getSession();
    s0.close();
    Field fActiveSessions = ClientImpl.class.getDeclaredField("activeProtocols");
    fActiveSessions.setAccessible(true);
    assertEquals(1, ((BlockingQueue<PooledXProtocol>) fIdleSessions.get(cli0)).size());
    assertEquals(1, ((Set<WeakReference<PooledXProtocol>>) fActiveSessions.get(cli0)).size());
    cli0.close();
    assertEquals(0, ((BlockingQueue<PooledXProtocol>) fIdleSessions.get(cli0)).size());
    assertEquals(0, ((Set<WeakReference<PooledXProtocol>>) fActiveSessions.get(cli0)).size());
    final Session ses = s1;
    assertThrows(CJCommunicationsException.class, new Callable<Void>() {

        public Void call() throws Exception {
            ses.getSchemas();
            return null;
        }
    });
    /*
         * UT4/2: Verify that after Client was closed the Client.getSession() throws an XDevAPIError with the message "Client is closed."
         */
    Client cli2 = cf.getClient(this.baseUrl, "{\"pooling\": {\"enabled\": true}}");
    cli2.close();
    assertThrows(XDevAPIError.class, "Client is closed.", new Callable<Void>() {

        public Void call() throws Exception {
            cli2.getSession();
            return null;
        }
    });
    /*
         * UT11/1: Having a pool with a single active and maxIdleTime = 0, verify that if closing the session then after any long inactivity time a new Session
         * object returned by Client.getSession() uses the same internal MysqlxSession object.
         */
    props.setProperty(ClientProperty.POOLING_MAX_SIZE.getKeyName(), "2");
    props.setProperty(ClientProperty.POOLING_MAX_IDLE_TIME.getKeyName(), "0");
    props.setProperty(ClientProperty.POOLING_QUEUE_TIMEOUT.getKeyName(), "20000");
    Client cli3 = cf.getClient(this.baseUrl, props);
    s0 = cli3.getSession();
    s1 = cli3.getSession();
    assertEquals(2, ((Set<WeakReference<PooledXProtocol>>) fActiveSessions.get(cli3)).size());
    s0.close();
    Thread.sleep(10000);
    s2 = cli3.getSession();
    s2.sql("SELECT 1").execute();
    assertNotEquals(s0, s2);
    assertEquals(fProtocol.get(((SessionImpl) s0).getSession()), fProtocol.get(((SessionImpl) s2).getSession()));
    cli3.close();
    /*
         * UT5/1: Having a full pool and queueTimeout = 0, verify that a new Client.getSession() waits until a Session is released.
         */
    props.setProperty(ClientProperty.POOLING_MAX_SIZE.getKeyName(), "2");
    props.setProperty(ClientProperty.POOLING_MAX_IDLE_TIME.getKeyName(), "1000");
    props.setProperty(ClientProperty.POOLING_QUEUE_TIMEOUT.getKeyName(), "0");
    cli3 = cf.getClient(this.baseUrl, props);
    s1 = cli3.getSession();
    Session s6 = cli3.getSession();
    Thread t = new Thread(new Runnable() {

        @Override
        public void run() {
            try {
                Thread.sleep(10000);
                s6.close();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    });
    long begin = System.currentTimeMillis();
    t.start();
    s1 = cli3.getSession();
    long end = System.currentTimeMillis() - begin;
    s1.sql("SELECT 1").execute();
    assertTrue(end >= 10000, "Expected wait time 10000 ms but was " + end);
    assertEquals(fProtocol.get(((SessionImpl) s1).getSession()), fProtocol.get(((SessionImpl) s6).getSession()));
    /*
         * TS10_2 Verify that RuntimProperty objects are reset to initial values when Session returned to pool.
         */
    assertEquals(2, ((Set<WeakReference<PooledXProtocol>>) fActiveSessions.get(cli3)).size());
    ((SessionImpl) s1).getSession().getPropertySet().getStringProperty(PropertyKey.connectionAttributes).setValue("orig:s1");
    s1.close();
    assertEquals(1, ((Set<WeakReference<PooledXProtocol>>) fActiveSessions.get(cli3)).size());
    s2 = cli3.getSession();
    s2.sql("SELECT 1").execute();
    assertEquals(fProtocol.get(((SessionImpl) s1).getSession()), fProtocol.get(((SessionImpl) s2).getSession()));
    assertNotEquals("orig:s1", ((SessionImpl) s1).getSession().getPropertySet().getStringProperty(PropertyKey.connectionAttributes).getValue());
    assertEquals(((SessionImpl) s1).getSession().getPropertySet().getStringProperty(PropertyKey.connectionAttributes).getInitialValue(), ((SessionImpl) s1).getSession().getPropertySet().getStringProperty(PropertyKey.connectionAttributes).getValue());
    /*
         * UT10/1: Get the max sessions allowed in the pool, create the same variables and temp tables in all the sessions,
         * save ((SessionImpl) sN).getSession().getServerSession().getThreadId() values.
         * Then close all the sessions and get a new one: the variables and the temp tables must not exist,
         * ((SessionImpl) sN).getSession().getServerSession().getThreadId() must return values equal to saved ones.
         */
    cli0 = cf.getClient(this.baseUrl, "{\"pooling\": {\"enabled\": true, \"maxSize\" : 2}}");
    s0 = cli0.getSession();
    s1 = cli0.getSession();
    long id0 = ((SessionImpl) s0).getSession().getServerSession().getCapabilities().getThreadId();
    long id1 = ((SessionImpl) s1).getSession().getServerSession().getCapabilities().getThreadId();
    s0.sql("SET @a='s0'").execute();
    s0.sql("CREATE TEMPORARY TABLE testpooledsessionstmps0(x int)").execute();
    s1.sql("SET @a='s1'").execute();
    s1.sql("CREATE TEMPORARY TABLE testpooledsessionstmps1(x int)").execute();
    SqlResult res = s0.sql("SELECT @a as a").execute();
    assertTrue(res.hasNext());
    assertEquals("s0", res.next().getString(0));
    res = s0.sql("SHOW CREATE TABLE testpooledsessionstmps0").execute();
    assertTrue(res.hasNext());
    assertEquals("testpooledsessionstmps0", res.next().getString(0));
    res = s1.sql("SELECT @a as a").execute();
    assertTrue(res.hasNext());
    assertEquals("s1", res.next().getString(0));
    res = s1.sql("SHOW CREATE TABLE testpooledsessionstmps1").execute();
    assertTrue(res.hasNext());
    assertEquals("testpooledsessionstmps1", res.next().getString(0));
    s0.close();
    s1.close();
    Session s0_new = cli0.getSession();
    Session s1_new = cli0.getSession();
    assertEquals(id0, ((SessionImpl) s0_new).getSession().getServerSession().getCapabilities().getThreadId());
    assertEquals(id1, ((SessionImpl) s1_new).getSession().getServerSession().getCapabilities().getThreadId());
    res = s0_new.sql("SELECT @a as a").execute();
    assertTrue(res.hasNext());
    assertNull(res.next().getString(0));
    assertThrows(XProtocolError.class, ".*testpooledsessionstmps0' doesn't exist", new Callable<Void>() {

        public Void call() throws Exception {
            s0_new.sql("SHOW CREATE TABLE testpooledsessionstmps0").execute();
            return null;
        }
    });
    res = s1_new.sql("SELECT @a as a").execute();
    assertTrue(res.hasNext());
    assertNull(res.next().getString(0));
    assertThrows(XProtocolError.class, ".*testpooledsessionstmps1' doesn't exist", new Callable<Void>() {

        public Void call() throws Exception {
            s1_new.sql("SHOW CREATE TABLE testpooledsessionstmps1").execute();
            return null;
        }
    });
    cli0.close();
}
Also used : SqlResult(com.mysql.cj.xdevapi.SqlResult) PooledXProtocol(com.mysql.cj.xdevapi.ClientImpl.PooledXProtocol) ClientFactory(com.mysql.cj.xdevapi.ClientFactory) JsonString(com.mysql.cj.xdevapi.JsonString) Properties(java.util.Properties) WrongArgumentException(com.mysql.cj.exceptions.WrongArgumentException) CJCommunicationsException(com.mysql.cj.exceptions.CJCommunicationsException) FileNotFoundException(java.io.FileNotFoundException) FeatureNotAvailableException(com.mysql.cj.exceptions.FeatureNotAvailableException) ExecutionException(java.util.concurrent.ExecutionException) CJPacketTooBigException(com.mysql.cj.exceptions.CJPacketTooBigException) Field(java.lang.reflect.Field) WeakReference(java.lang.ref.WeakReference) SessionImpl(com.mysql.cj.xdevapi.SessionImpl) Client(com.mysql.cj.xdevapi.Client) CoreSession(com.mysql.cj.CoreSession) Session(com.mysql.cj.xdevapi.Session) Test(org.junit.jupiter.api.Test)

Example 19 with Session

use of com.mysql.cj.xdevapi.Session in project aws-mysql-jdbc by awslabs.

the class SessionTest method testSessionAttributes.

@Test
public void testSessionAttributes() throws Exception {
    assumeTrue(mysqlVersionMeetsMinimum(ServerVersion.parseVersion("8.0.16")), "MySQL 8.0.16+ is required to run this test.");
    ClientFactory cf = new ClientFactory();
    Map<String, String> userAttributes = new HashMap<>();
    // TSFR1/TSFR2/TSFR3 Create a Session with xdevapi.connection-attributes in the connection string, verify that
    // the session is successfully established. Create a Session using a connection string containing the properties
    // as listed below, verify that the session is successfully established and the server contains the defined session attributes.
    // xdevapi.connection-attributes=[key1=value1]
    // xdevapi.connection-attributes=[key1=value1,key2=value2]
    // xdevapi.connection-attributes=key1=value1
    // xdevapi.connection-attributes=key1=value1,key2=value2
    userAttributes.clear();
    userAttributes.put("key1", "value1");
    String baseUrlLocal = this.baseUrl + (this.baseUrl.contains("?") ? "&" : "?");
    testSessionAttributes_checkSession(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "key1=value1", true), userAttributes);
    testSessionAttributes_checkSession(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "[key1=value1]", true), userAttributes);
    testSessionAttributes_checkClient(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "key1=value1", true), userAttributes);
    testSessionAttributes_checkClient(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "[key1=value1]", true), userAttributes);
    userAttributes.put("key2", "value2");
    testSessionAttributes_checkSession(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "key1=value1,key2=value2", true), userAttributes);
    testSessionAttributes_checkSession(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "[key1=value1,key2=value2]", true), userAttributes);
    testSessionAttributes_checkClient(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "key1=value1,key2=value2", true), userAttributes);
    testSessionAttributes_checkClient(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "[key1=value1,key2=value2]", true), userAttributes);
    // TSFR4/TSFR5/TSFR6 Create a Session without xdevapi.connection-attributes in the connection string, verify that all predefined attributes
    // exist and contain the correct values. Verify that only connection attributes starting with "_" were set for current session.
    userAttributes.clear();
    testSessionAttributes_checkSession(this.baseUrl, userAttributes);
    testSessionAttributes_checkClient(this.baseUrl, userAttributes);
    // TSFR7 Create a Session using a connection string containing the properties as listed below, verify that a WrongArgumentException exception is thrown
    // with the message Key names in "xdevapi.connection-attributes" cannot start with "_".
    // xdevapi.connection-attributes=[_key1=value1]
    // xdevapi.connection-attributes=[key1=value1,_key2=value2]
    // xdevapi.connection-attributes=_key1=value1
    // xdevapi.connection-attributes=key1=value1,_key2=value2
    assertThrows(WrongArgumentException.class, "Key names in \"xdevapi.connection-attributes\" cannot start with \"_\".", () -> {
        this.fact.getSession(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "[_key1=value1]", true));
        return null;
    });
    assertThrows(WrongArgumentException.class, "Key names in \"xdevapi.connection-attributes\" cannot start with \"_\".", () -> {
        Client cli1 = cf.getClient(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "[_key1=value1]", true), new Properties());
        cli1.getSession();
        return null;
    });
    assertThrows(WrongArgumentException.class, "Key names in \"xdevapi.connection-attributes\" cannot start with \"_\".", () -> {
        this.fact.getSession(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "[key1=value1,_key2=value2]", true));
        return null;
    });
    assertThrows(WrongArgumentException.class, "Key names in \"xdevapi.connection-attributes\" cannot start with \"_\".", () -> {
        Client cli1 = cf.getClient(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "[key1=value1,_key2=value2]", true), new Properties());
        cli1.getSession();
        return null;
    });
    assertThrows(WrongArgumentException.class, "Key names in \"xdevapi.connection-attributes\" cannot start with \"_\".", () -> {
        this.fact.getSession(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "_key1=value1", true));
        return null;
    });
    assertThrows(WrongArgumentException.class, "Key names in \"xdevapi.connection-attributes\" cannot start with \"_\".", () -> {
        Client cli1 = cf.getClient(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "_key1=value1", true), new Properties());
        cli1.getSession();
        return null;
    });
    assertThrows(WrongArgumentException.class, "Key names in \"xdevapi.connection-attributes\" cannot start with \"_\".", () -> {
        this.fact.getSession(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "key1=value1,_key2=value2", true));
        return null;
    });
    assertThrows(WrongArgumentException.class, "Key names in \"xdevapi.connection-attributes\" cannot start with \"_\".", () -> {
        Client cli1 = cf.getClient(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "key1=value1,_key2=value2", true), new Properties());
        cli1.getSession();
        return null;
    });
    // TSFR9 Create a Session using a connection string containing the properties as listed below, verify
    // that the user-defined connection attribute key1 has an empty value.
    // xdevapi.connection-attributes=[key1]
    // xdevapi.connection-attributes=[key1,key2=value2]
    // xdevapi.connection-attributes=[key1=]
    // xdevapi.connection-attributes=[key1=,key2=value2]
    // xdevapi.connection-attributes=key1
    // xdevapi.connection-attributes=key1,key2=value2
    // xdevapi.connection-attributes=key1=
    // xdevapi.connection-attributes=key1=,key2=value2
    userAttributes.clear();
    userAttributes.put("key1", "");
    testSessionAttributes_checkSession(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "[key1]", true), userAttributes);
    testSessionAttributes_checkSession(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "[key1=]", true), userAttributes);
    testSessionAttributes_checkSession(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "key1", true), userAttributes);
    testSessionAttributes_checkSession(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "key1=", true), userAttributes);
    testSessionAttributes_checkClient(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "[key1]", true), userAttributes);
    testSessionAttributes_checkClient(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "[key1=]", true), userAttributes);
    testSessionAttributes_checkClient(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "key1", true), userAttributes);
    testSessionAttributes_checkClient(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "key1=", true), userAttributes);
    userAttributes.put("key2", "value2");
    testSessionAttributes_checkSession(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "[key1,key2=value2]", true), userAttributes);
    testSessionAttributes_checkSession(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "[key1=,key2=value2]", true), userAttributes);
    testSessionAttributes_checkSession(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "key1,key2=value2", true), userAttributes);
    testSessionAttributes_checkSession(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "key1=,key2=value2", true), userAttributes);
    testSessionAttributes_checkClient(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "[key1,key2=value2]", true), userAttributes);
    testSessionAttributes_checkClient(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "[key1=,key2=value2]", true), userAttributes);
    testSessionAttributes_checkClient(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "key1,key2=value2", true), userAttributes);
    testSessionAttributes_checkClient(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "key1=,key2=value2", true), userAttributes);
    // TSFR10 Create a Session with xdevapi.connection-attributes=false in the connection string, verify
    // that no connection attribute was set for current session.
    Session s10 = this.fact.getSession(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "false", true));
    SqlResult res = s10.sql("SELECT * FROM performance_schema.session_connect_attrs WHERE processlist_id = CONNECTION_ID()").execute();
    assertFalse(res.hasNext(), "Expected no connection attributes.");
    s10.close();
    Client c10 = cf.getClient(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "false", true), new Properties());
    s10 = c10.getSession();
    res = s10.sql("SELECT * FROM performance_schema.session_connect_attrs WHERE processlist_id = CONNECTION_ID()").execute();
    assertFalse(res.hasNext(), "Expected no connection attributes.");
    s10.close();
    c10.close();
    // TSFR11 Create a Session using a connection string containing the properties as listed below, verify
    // that only the client-defined connection attributes were set for the current session.
    // xdevapi.connection-attributes
    // xdevapi.connection-attributes=
    // xdevapi.connection-attributes=true
    // xdevapi.connection-attributes=[]
    userAttributes.clear();
    testSessionAttributes_checkSession(baseUrlLocal + PropertyKey.xdevapiConnectionAttributes.getKeyName(), userAttributes);
    testSessionAttributes_checkSession(baseUrlLocal + PropertyKey.xdevapiConnectionAttributes.getKeyName() + "=", userAttributes);
    testSessionAttributes_checkSession(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "true", true), userAttributes);
    testSessionAttributes_checkSession(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "[]", true), userAttributes);
    testSessionAttributes_checkClient(baseUrlLocal + PropertyKey.xdevapiConnectionAttributes.getKeyName(), userAttributes);
    testSessionAttributes_checkClient(baseUrlLocal + PropertyKey.xdevapiConnectionAttributes.getKeyName() + "=", userAttributes);
    testSessionAttributes_checkClient(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "true", true), userAttributes);
    testSessionAttributes_checkClient(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "[]", true), userAttributes);
    // TSFR13 Create a Session with xdevapi.connection-attributes=[key1=value1,key1=value2] in the connection string, verify that
    // a WrongArgumentException exception is thrown with the message Duplicate key "key1" used in "xdevapi.connection-attributes".
    assertThrows(WrongArgumentException.class, "Duplicate key \"key1\" used in \"xdevapi.connection-attributes\".", () -> {
        this.fact.getSession(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "key1=value1,key1=value2", true));
        return null;
    });
    assertThrows(WrongArgumentException.class, "Duplicate key \"key1\" used in \"xdevapi.connection-attributes\".", () -> {
        Client cli1 = cf.getClient(baseUrlLocal + makeParam(PropertyKey.xdevapiConnectionAttributes, "key1=value1,key1=value2", true), new Properties());
        cli1.getSession();
        return null;
    });
}
Also used : SqlResult(com.mysql.cj.xdevapi.SqlResult) HashMap(java.util.HashMap) ClientFactory(com.mysql.cj.xdevapi.ClientFactory) JsonString(com.mysql.cj.xdevapi.JsonString) Client(com.mysql.cj.xdevapi.Client) Properties(java.util.Properties) CoreSession(com.mysql.cj.CoreSession) Session(com.mysql.cj.xdevapi.Session) Test(org.junit.jupiter.api.Test)

Example 20 with Session

use of com.mysql.cj.xdevapi.Session in project aws-mysql-jdbc by awslabs.

the class SessionTest method testPreparedStatementsCleanup.

@Test
public void testPreparedStatementsCleanup() {
    assumeTrue(mysqlVersionMeetsMinimum(ServerVersion.parseVersion("8.0.14")), "MySQL 8.0.14+ is required to run this test.");
    try {
        // Prepare test data.
        this.schema.createCollection("testPrepStmtClean", true).add("{\"_id\":\"1\"}").execute();
        SessionFactory sf = new SessionFactory();
        /*
             * Test common usage.
             */
        Session testSession = sf.getSession(this.testProperties);
        int sessionThreadId = getThreadId(testSession);
        assertPreparedStatementsCount(sessionThreadId, 0, 1);
        assertPreparedStatementsStatusCounts(testSession, 0, 0, 0);
        // Initialize several *Statement objects.
        FindStatement testFind1 = testSession.getDefaultSchema().getCollection("testPrepStmtClean").find();
        SelectStatement testSelect1 = testSession.getDefaultSchema().getCollectionAsTable("testPrepStmtClean").select("_id");
        FindStatement testFind2 = testSession.getDefaultSchema().getCollection("testPrepStmtClean").find();
        SelectStatement testSelect2 = testSession.getDefaultSchema().getCollectionAsTable("testPrepStmtClean").select("_id");
        // 1st execute -> don't prepare.
        testFind1.execute();
        assertPreparedStatementsCountsAndId(testSession, 0, testFind1, 0, -1);
        testSelect1.execute();
        assertPreparedStatementsCountsAndId(testSession, 0, testSelect1, 0, -1);
        testFind2.execute();
        assertPreparedStatementsCountsAndId(testSession, 0, testFind2, 0, -1);
        testSelect2.execute();
        assertPreparedStatementsCountsAndId(testSession, 0, testSelect2, 0, -1);
        assertPreparedStatementsStatusCounts(testSession, 0, 0, 0);
        // 2nd execute -> prepare + execute.
        testFind1.execute();
        assertPreparedStatementsCountsAndId(testSession, 1, testFind1, 1, 1);
        testSelect1.execute();
        assertPreparedStatementsCountsAndId(testSession, 2, testSelect1, 2, 1);
        testFind2.execute();
        assertPreparedStatementsCountsAndId(testSession, 3, testFind2, 3, 1);
        testSelect2.execute();
        assertPreparedStatementsCountsAndId(testSession, 4, testSelect2, 4, 1);
        assertPreparedStatementsStatusCounts(testSession, 4, 4, 0);
        assertPreparedStatementsCount(sessionThreadId, 4, 1);
        /*
             * The following verifications are non-deterministic as System.gc() only hints the JVM to perform a garbage collection. This approach allows some
             * time for the JVM to execute the GC. In case of failure the repeats or wait times may have to be adjusted.
             * The test can be deleted entirely if no reasonable setup can be found.
             */
        // Nullify first statement.
        testFind1 = null;
        System.gc();
        int psCount, countdown = 10;
        do {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
            }
            testSession.sql("SELECT 1").execute();
            psCount = getPreparedStatementsCount(sessionThreadId);
        } while (psCount != 3 && --countdown > 0);
        assertPreparedStatementsStatusCounts(testSession, 4, 4, 1);
        assertPreparedStatementsCount(sessionThreadId, 3, 1);
        // Nullify second and third statements.
        testSelect1 = null;
        testFind2 = null;
        System.gc();
        countdown = 10;
        do {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
            }
            testSession.sql("SELECT 1").execute();
            psCount = getPreparedStatementsCount(sessionThreadId);
        } while (psCount != 1 && --countdown > 0);
        assertPreparedStatementsStatusCounts(testSession, 4, 4, 3);
        assertPreparedStatementsCount(sessionThreadId, 1, 1);
        // Nullify last statement.
        testSelect2 = null;
        System.gc();
        countdown = 10;
        do {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
            }
            testSession.sql("SELECT 1").execute();
            psCount = getPreparedStatementsCount(sessionThreadId);
        } while (psCount != 0 && --countdown > 0);
        assertPreparedStatementsStatusCounts(testSession, 4, 4, 4);
        assertPreparedStatementsCount(sessionThreadId, 0, 1);
        testSession.close();
        assertPreparedStatementsCount(sessionThreadId, 0, 1);
    } finally {
        this.schema.dropCollection("testPrepStmtClean");
    }
}
Also used : SessionFactory(com.mysql.cj.xdevapi.SessionFactory) SelectStatement(com.mysql.cj.xdevapi.SelectStatement) FindStatement(com.mysql.cj.xdevapi.FindStatement) CoreSession(com.mysql.cj.CoreSession) Session(com.mysql.cj.xdevapi.Session) Test(org.junit.jupiter.api.Test)

Aggregations

Session (com.mysql.cj.xdevapi.Session)85 Test (org.junit.jupiter.api.Test)79 JsonString (com.mysql.cj.xdevapi.JsonString)40 SessionFactory (com.mysql.cj.xdevapi.SessionFactory)39 CoreSession (com.mysql.cj.CoreSession)38 Collection (com.mysql.cj.xdevapi.Collection)33 Properties (java.util.Properties)29 ExecutionException (java.util.concurrent.ExecutionException)26 WrongArgumentException (com.mysql.cj.exceptions.WrongArgumentException)23 Schema (com.mysql.cj.xdevapi.Schema)22 DocResult (com.mysql.cj.xdevapi.DocResult)16 DbDoc (com.mysql.cj.xdevapi.DbDoc)15 SessionImpl (com.mysql.cj.xdevapi.SessionImpl)15 SqlResult (com.mysql.cj.xdevapi.SqlResult)15 Row (com.mysql.cj.xdevapi.Row)14 Client (com.mysql.cj.xdevapi.Client)11 ClientFactory (com.mysql.cj.xdevapi.ClientFactory)11 RowResult (com.mysql.cj.xdevapi.RowResult)10 Field (java.lang.reflect.Field)9 CJCommunicationsException (com.mysql.cj.exceptions.CJCommunicationsException)8