/* * Copyright (C) 2012-2015 DataStax Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.datastax.driver.core; import com.datastax.driver.core.exceptions.InvalidQueryException; import com.datastax.driver.core.utils.SocketChannelMonitor; import org.testng.annotations.Test; import java.util.concurrent.TimeUnit; import static com.datastax.driver.core.Assertions.assertThat; import static com.datastax.driver.core.CreateCCM.TestMode.PER_METHOD; import static com.datastax.driver.core.TestUtils.nonDebouncingQueryOptions; import static com.google.common.collect.Lists.newArrayList; import static java.util.concurrent.TimeUnit.MINUTES; import static org.assertj.core.api.Assertions.fail; @CreateCCM(PER_METHOD) @CCMConfig(dirtiesContext = true, createCluster = false) public class SessionLeakTest extends CCMTestsSupport { SocketChannelMonitor channelMonitor; @Test(groups = "long") public void connectionLeakTest() throws Exception { // Checking for JAVA-342 channelMonitor = new SocketChannelMonitor(); channelMonitor.reportAtFixedInterval(1, TimeUnit.SECONDS); Cluster cluster = register(Cluster.builder() .addContactPoints(getContactPoints().get(0)) .withPort(ccm().getBinaryPort()) .withNettyOptions(channelMonitor.nettyOptions()) .withQueryOptions(nonDebouncingQueryOptions()) .build()); cluster.init(); assertThat(cluster.manager.sessions.size()).isEqualTo(0); // Should be 1 control connection after initialization. assertOpenConnections(1, cluster); // ensure sessions.size() returns with 1 control connection + core pool size. int corePoolSize = TestUtils.numberOfLocalCoreConnections(cluster); Session session = cluster.connect(); assertThat(cluster.manager.sessions.size()).isEqualTo(1); assertOpenConnections(1 + corePoolSize, cluster); // ensure sessions.size() returns to 0 with only 1 active connection (the control connection) session.close(); assertThat(cluster.manager.sessions.size()).isEqualTo(0); assertOpenConnections(1, cluster); // ensure bootstrapping a node does not create additional connections ccm().add(2); ccm().start(2); ccm().waitForUp(2); assertThat(cluster).host(2).comesUpWithin(2, MINUTES); assertThat(cluster.manager.sessions.size()).isEqualTo(0); assertOpenConnections(1, cluster); // ensure a new session gets registered and core connections are established // there should be corePoolSize more connections to accommodate for the new host. Session thisSession = cluster.connect(); assertThat(cluster.manager.sessions.size()).isEqualTo(1); assertOpenConnections(1 + (corePoolSize * 2), cluster); // ensure bootstrapping a node does not create additional connections that won't get cleaned up thisSession.close(); assertThat(cluster.manager.sessions.size()).isEqualTo(0); assertOpenConnections(1, cluster); cluster.close(); // Ensure no channels remain open. channelMonitor.stop(); channelMonitor.report(); assertThat(channelMonitor.openChannels(newArrayList(ccm().addressOfNode(1), ccm().addressOfNode(2))).size()).isEqualTo(0); } @Test(groups = "short") public void should_not_leak_session_when_wrong_keyspace() throws Exception { // Checking for JAVA-806 channelMonitor = new SocketChannelMonitor(); channelMonitor.reportAtFixedInterval(1, TimeUnit.SECONDS); Cluster cluster = register(Cluster.builder() .addContactPoints(getContactPoints().get(0)) .withPort(ccm().getBinaryPort()) .withNettyOptions(channelMonitor.nettyOptions()) .build()); cluster.init(); assertThat(cluster.manager.sessions.size()).isEqualTo(0); try { // Should be 1 control connection after initialization. assertOpenConnections(1, cluster); cluster.connect("wrong_keyspace"); fail("Should not have connected to a wrong keyspace"); } catch (InvalidQueryException e) { // ok } assertThat(cluster.manager.sessions.size()).isEqualTo(0); cluster.close(); // Ensure no channels remain open. channelMonitor.stop(); channelMonitor.report(); assertThat(channelMonitor.openChannels(ccm().addressOfNode(1), ccm().addressOfNode(2)).size()).isEqualTo(0); } private void assertOpenConnections(int expected, Cluster cluster) { assertThat(cluster.getMetrics().getOpenConnections().getValue()).isEqualTo(expected); assertThat(channelMonitor.openChannels(ccm().addressOfNode(1), ccm().addressOfNode(2)).size()).isEqualTo(expected); } }