From efba60b72f97c4492f2ce16eaede9be01253c1fb Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Thu, 19 Jan 2017 16:44:40 +0100 Subject: [PATCH] DATACASS-381 - Improve integration test stability. Reuse Thread pools during integration test runs to not recreate and dispose Threads multiple times. Increase build and Cassandra memory. Use an external Cassandra instance for TravisCI build jobs. --- .travis.yml | 14 +-- pom.xml | 2 +- setup-cassandra.sh | 4 +- ...ssandraCqlClusterFactoryBeanUnitTests.java | 1 - .../test/integration/CassandraRule.java | 5 +- ...CqlClusterFactoryBeanIntegrationTests.java | 4 +- .../CqlTemplateConfigIntegrationTests.java | 4 +- .../support/AbstractTestJavaConfig.java | 2 +- .../support/FastShutdownNettyOptions.java | 38 --------- .../support/IntegrationTestNettyOptions.java | 85 +++++++++++++++++++ ...atingXmlConfigIntegrationTests-context.xml | 2 +- ...atingXmlConfigIntegrationTests-context.xml | 4 +- .../xml/XmlConfigIntegrationTests-context.xml | 2 +- .../support/IntegrationTestConfig.java | 4 +- .../config/spring-data-cassandra-basic.xml | 2 +- ...andraNamespaceIntegrationTests-context.xml | 2 +- 16 files changed, 112 insertions(+), 63 deletions(-) delete mode 100644 spring-cql/src/test/java/org/springframework/cassandra/test/integration/support/FastShutdownNettyOptions.java create mode 100644 spring-cql/src/test/java/org/springframework/cassandra/test/integration/support/IntegrationTestNettyOptions.java diff --git a/.travis.yml b/.travis.yml index dd0715ba5..56cb44b09 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,8 @@ jdk: - oraclejdk8 env: + global: + - CASSANDRA_VERSION=3.9 matrix: - PROFILE=ci - PROFILE=ci CASSANDRA_DRIVER_VERSION=3.0.3 @@ -11,10 +13,10 @@ env: - PROFILE=spring43 - PROFILE=spring43-next - PROFILE=spring5-next - - PROFILE=external-cassandra CASSANDRA_VERSION=2.2.8 - - PROFILE=external-cassandra CASSANDRA_VERSION=3.0.10 - - PROFILE=external-cassandra CASSANDRA_VERSION=3.2.1 - - PROFILE=external-cassandra CASSANDRA_VERSION=3.9 + - CASSANDRA_VERSION=2.2.8 + - CASSANDRA_VERSION=3.0.10 + - CASSANDRA_VERSION=3.2.1 + - CASSANDRA_VERSION=3.9 addons: apt: @@ -36,7 +38,7 @@ install: if [ ! -z ${CASSANDRA_VERSION+x} ]; then ./setup-cassandra.sh; fi; script: - | if [ ! -z ${CASSANDRA_DRIVER_VERSION+x} ]; then - mvn clean install -P${PROFILE} -Dcassandra-driver.version=${CASSANDRA_DRIVER_VERSION} -Dmaven.javadoc.skip=true + mvn clean install -P${PROFILE},external-cassandra -Dcassandra-driver.version=${CASSANDRA_DRIVER_VERSION} -Dmaven.javadoc.skip=true else - mvn clean install -P${PROFILE} -Dmaven.javadoc.skip=true + mvn clean install -P${PROFILE},external-cassandra -Dmaven.javadoc.skip=true fi diff --git a/pom.xml b/pom.xml index 522f28427..ced3cdebe 100644 --- a/pom.xml +++ b/pom.xml @@ -294,7 +294,7 @@ ${failsafe.version} 1 - -Xms1g -Xmx1g -Xss256k + -Xms1g -Xmx1500m -Xss256k true false diff --git a/setup-cassandra.sh b/setup-cassandra.sh index b639923b7..14143177b 100755 --- a/setup-cassandra.sh +++ b/setup-cassandra.sh @@ -47,8 +47,8 @@ rm -Rf data mkdir -p data echo "[INFO] Starting Apache Cassandra ${CASSANDRA_VERSION}" -export MAX_HEAP_SIZE=1G -export HEAP_NEWSIZE=100M +export MAX_HEAP_SIZE=1500M +export HEAP_NEWSIZE=300M bin/cassandra for start in {1..20} diff --git a/spring-cql/src/test/java/org/springframework/cassandra/config/CassandraCqlClusterFactoryBeanUnitTests.java b/spring-cql/src/test/java/org/springframework/cassandra/config/CassandraCqlClusterFactoryBeanUnitTests.java index 884943009..5ad24cf90 100755 --- a/spring-cql/src/test/java/org/springframework/cassandra/config/CassandraCqlClusterFactoryBeanUnitTests.java +++ b/spring-cql/src/test/java/org/springframework/cassandra/config/CassandraCqlClusterFactoryBeanUnitTests.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.cassandra.config; import static org.assertj.core.api.Assertions.*; diff --git a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/CassandraRule.java b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/CassandraRule.java index f2a5ab278..c0acf8b36 100644 --- a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/CassandraRule.java +++ b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/CassandraRule.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.cassandra.test.integration; import static org.springframework.cassandra.test.integration.CassandraRule.InvocationMode.*; @@ -28,7 +27,7 @@ import org.junit.rules.ExternalResource; import org.springframework.cassandra.core.SessionCallback; import org.springframework.cassandra.test.integration.support.CassandraConnectionProperties; import org.springframework.cassandra.test.integration.support.CqlDataSet; -import org.springframework.cassandra.test.integration.support.FastShutdownNettyOptions; +import org.springframework.cassandra.test.integration.support.IntegrationTestNettyOptions; import org.springframework.dao.DataAccessException; import org.springframework.util.Assert; import org.springframework.util.SocketUtils; @@ -332,7 +331,7 @@ public class CassandraRule extends ExternalResource { .withQueryOptions(queryOptions) // .withMaxSchemaAgreementWaitSeconds(3) // .withSocketOptions(socketOptions) // - .withNettyOptions(FastShutdownNettyOptions.INSTANCE) // + .withNettyOptions(IntegrationTestNettyOptions.INSTANCE) // .build(); if (properties.getBoolean("build.cassandra.reuse-cluster")) { diff --git a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/config/CassandraCqlClusterFactoryBeanIntegrationTests.java b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/config/CassandraCqlClusterFactoryBeanIntegrationTests.java index 8c619110e..283a6d34c 100755 --- a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/config/CassandraCqlClusterFactoryBeanIntegrationTests.java +++ b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/config/CassandraCqlClusterFactoryBeanIntegrationTests.java @@ -21,7 +21,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import org.springframework.cassandra.config.CassandraCqlClusterFactoryBean; -import org.springframework.cassandra.test.integration.support.FastShutdownNettyOptions; +import org.springframework.cassandra.test.integration.support.IntegrationTestNettyOptions; import org.springframework.test.util.ReflectionTestUtils; import com.datastax.driver.core.ProtocolVersion; @@ -49,7 +49,7 @@ public class CassandraCqlClusterFactoryBeanIntegrationTests { @Test public void configuredProtocolVersionShouldBeSet() throws Exception { - cassandraCqlClusterFactoryBean.setNettyOptions(FastShutdownNettyOptions.INSTANCE); + cassandraCqlClusterFactoryBean.setNettyOptions(IntegrationTestNettyOptions.INSTANCE); cassandraCqlClusterFactoryBean.setProtocolVersion(ProtocolVersion.V2); cassandraCqlClusterFactoryBean.afterPropertiesSet(); diff --git a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/config/java/CqlTemplateConfigIntegrationTests.java b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/config/java/CqlTemplateConfigIntegrationTests.java index 5d6d956b7..5b560fa46 100755 --- a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/config/java/CqlTemplateConfigIntegrationTests.java +++ b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/config/java/CqlTemplateConfigIntegrationTests.java @@ -23,7 +23,7 @@ import org.junit.Test; import org.springframework.cassandra.config.java.AbstractCqlTemplateConfiguration; import org.springframework.cassandra.core.CqlTemplate; import org.springframework.cassandra.test.integration.AbstractEmbeddedCassandraIntegrationTest; -import org.springframework.cassandra.test.integration.support.FastShutdownNettyOptions; +import org.springframework.cassandra.test.integration.support.IntegrationTestNettyOptions; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Configuration; @@ -55,7 +55,7 @@ public class CqlTemplateConfigIntegrationTests extends AbstractEmbeddedCassandra @Override protected NettyOptions getNettyOptions() { - return FastShutdownNettyOptions.INSTANCE; + return IntegrationTestNettyOptions.INSTANCE; } } diff --git a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/support/AbstractTestJavaConfig.java b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/support/AbstractTestJavaConfig.java index d8ae77d2d..dbd851e2a 100644 --- a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/support/AbstractTestJavaConfig.java +++ b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/support/AbstractTestJavaConfig.java @@ -39,7 +39,7 @@ public abstract class AbstractTestJavaConfig extends AbstractSessionConfiguratio @Override protected NettyOptions getNettyOptions() { - return FastShutdownNettyOptions.INSTANCE; + return IntegrationTestNettyOptions.INSTANCE; } @Override diff --git a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/support/FastShutdownNettyOptions.java b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/support/FastShutdownNettyOptions.java deleted file mode 100644 index dbd4188bb..000000000 --- a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/support/FastShutdownNettyOptions.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2016-2017 the original author or authors. - * - * 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 org.springframework.cassandra.test.integration.support; - -import io.netty.channel.EventLoopGroup; - -import java.util.concurrent.TimeUnit; - -import com.datastax.driver.core.NettyOptions; - -/** - * {@link NettyOptions} to shutdown a {@link com.datastax.driver.core.Cluster} instance without wait time. - * - * @author Mark Paluch - * @since 1.5 - */ -public class FastShutdownNettyOptions extends NettyOptions { - - public final static FastShutdownNettyOptions INSTANCE = new FastShutdownNettyOptions(); - - @Override - public void onClusterClose(EventLoopGroup eventLoopGroup) { - eventLoopGroup.shutdownGracefully(0, 0, TimeUnit.MILLISECONDS); - } -} diff --git a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/support/IntegrationTestNettyOptions.java b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/support/IntegrationTestNettyOptions.java new file mode 100644 index 000000000..f4989d2c3 --- /dev/null +++ b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/support/IntegrationTestNettyOptions.java @@ -0,0 +1,85 @@ +/* + * Copyright 2016-2017 the original author or authors. + * + * 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 org.springframework.cassandra.test.integration.support; + +import io.netty.channel.EventLoopGroup; +import io.netty.util.Timer; + +import java.util.concurrent.ThreadFactory; + +import com.datastax.driver.core.NettyOptions; + +/** + * {@link NettyOptions} to for Integration tests a {@link com.datastax.driver.core.Cluster}. This class caches and + * reuses (on a best-effort basis) {@link EventLoopGroup} and {@link Timer} instances during the tests. Caching reduces + * thread disposal that leads to a overall improved resource reusage during tests. + * + * @author Mark Paluch + * @since 1.5 + */ +public class IntegrationTestNettyOptions extends NettyOptions { + + public final static IntegrationTestNettyOptions INSTANCE = new IntegrationTestNettyOptions(); + private volatile static EventLoopGroup eventLoopGroup; + private volatile static Timer timer; + + @Override + public EventLoopGroup eventLoopGroup(final ThreadFactory threadFactory) { + + if (eventLoopGroup != null) { + return eventLoopGroup; + } + + EventLoopGroup eventLoopGroup = super.eventLoopGroup(new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + + Thread thread = threadFactory.newThread(r); + thread.setDaemon(true); + return thread; + } + }); + + IntegrationTestNettyOptions.eventLoopGroup = eventLoopGroup; + return eventLoopGroup; + } + + @Override + public Timer timer(ThreadFactory threadFactory) { + + if (timer != null) { + return timer; + } + + final Timer timer = super.timer(threadFactory); + Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { + @Override + public void run() { + timer.stop(); + } + })); + + IntegrationTestNettyOptions.timer = timer; + return timer; + + } + + @Override + public void onClusterClose(EventLoopGroup eventLoopGroup) {} + + @Override + public void onClusterClose(Timer timer) {} +} diff --git a/spring-cql/src/test/resources/org/springframework/cassandra/test/integration/config/xml/FullySpecifiedKeyspaceCreatingXmlConfigIntegrationTests-context.xml b/spring-cql/src/test/resources/org/springframework/cassandra/test/integration/config/xml/FullySpecifiedKeyspaceCreatingXmlConfigIntegrationTests-context.xml index 434b9dfec..bbdb43aee 100644 --- a/spring-cql/src/test/resources/org/springframework/cassandra/test/integration/config/xml/FullySpecifiedKeyspaceCreatingXmlConfigIntegrationTests-context.xml +++ b/spring-cql/src/test/resources/org/springframework/cassandra/test/integration/config/xml/FullySpecifiedKeyspaceCreatingXmlConfigIntegrationTests-context.xml @@ -10,7 +10,7 @@ - + + + @@ -44,7 +46,7 @@ pool-timeout-milliseconds="${cluster.poolingoptions.pooltimeoutmilliseconds}" reconnection-policy-ref="reconnectionPolicy" retry-policy-ref="retryPolicy" - username="${auth.username}" password="${auth.password}"> + username="${auth.username}" password="${auth.password}" netty-options-ref="nettyOptions"> - + - + diff --git a/spring-data-cassandra/src/test/resources/org/springframework/data/cassandra/config/xml/CassandraNamespaceIntegrationTests-context.xml b/spring-data-cassandra/src/test/resources/org/springframework/data/cassandra/config/xml/CassandraNamespaceIntegrationTests-context.xml index 51c8bf2cd..349e96862 100644 --- a/spring-data-cassandra/src/test/resources/org/springframework/data/cassandra/config/xml/CassandraNamespaceIntegrationTests-context.xml +++ b/spring-data-cassandra/src/test/resources/org/springframework/data/cassandra/config/xml/CassandraNamespaceIntegrationTests-context.xml @@ -7,7 +7,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> - +