MAILBOX-342 Use a singleton and surefire::reuseforks to launch a single cassandra container
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/524e43ab Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/524e43ab Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/524e43ab Branch: refs/heads/master Commit: 524e43abc9704513a5d0f1fc21081d1a317442a6 Parents: 8cd1e2c Author: benwa <btell...@linagora.com> Authored: Tue Jul 24 15:36:53 2018 +0700 Committer: Matthieu Baechler <matth...@apache.org> Committed: Wed Aug 1 14:32:01 2018 +0200 ---------------------------------------------------------------------- backends-common/cassandra/pom.xml | 12 +++ .../ContainerLifecycleConfiguration.java | 4 + .../backends/cassandra/DockerCassandra.java | 107 +++++++++++++++++++ .../backends/cassandra/DockerCassandraRule.java | 83 ++------------ .../cassandra/DockerCassandraSingleton.java | 36 +++++++ mailbox/cassandra/pom.xml | 12 +++ .../CassandraMessageIdToImapUidDAOTest.java | 2 + mpt/impl/imap-mailbox/cassandra/pom.xml | 12 +++ mpt/impl/smtp/cassandra/pom.xml | 12 +++ server/container/guice/cassandra-guice/pom.xml | 7 ++ server/data/data-cassandra/pom.xml | 7 ++ server/data/data-jmap-cassandra/pom.xml | 7 ++ .../mailrepository-cassandra/pom.xml | 7 ++ .../protocols/webadmin-integration-test/pom.xml | 12 +++ 14 files changed, 246 insertions(+), 74 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/524e43ab/backends-common/cassandra/pom.xml ---------------------------------------------------------------------- diff --git a/backends-common/cassandra/pom.xml b/backends-common/cassandra/pom.xml index 9be80f7..7516b2b 100644 --- a/backends-common/cassandra/pom.xml +++ b/backends-common/cassandra/pom.xml @@ -134,4 +134,16 @@ </dependency> </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <reuseForks>true</reuseForks> + </configuration> + </plugin> + </plugins> + </build> + </project> http://git-wip-us.apache.org/repos/asf/james-project/blob/524e43ab/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/ContainerLifecycleConfiguration.java ---------------------------------------------------------------------- diff --git a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/ContainerLifecycleConfiguration.java b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/ContainerLifecycleConfiguration.java index 0768f51..d9592f9 100644 --- a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/ContainerLifecycleConfiguration.java +++ b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/ContainerLifecycleConfiguration.java @@ -28,6 +28,10 @@ import org.testcontainers.shaded.com.google.common.base.Preconditions; public class ContainerLifecycleConfiguration { + public static Builder builder() { + return new Builder(); + } + public static Builder withDefaultIterationsBetweenRestart() { return new Builder(); } http://git-wip-us.apache.org/repos/asf/james-project/blob/524e43ab/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandra.java ---------------------------------------------------------------------- diff --git a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandra.java b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandra.java new file mode 100644 index 0000000..bb0feec --- /dev/null +++ b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandra.java @@ -0,0 +1,107 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you 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.apache.james.backends.cassandra; + +import org.apache.james.util.Host; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testcontainers.DockerClientFactory; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.output.OutputFrame; +import org.testcontainers.images.builder.ImageFromDockerfile; +import org.testcontainers.shaded.com.google.common.collect.ImmutableMap; + +import com.github.dockerjava.api.DockerClient; + +public class DockerCassandra { + + private static final Logger logger = LoggerFactory.getLogger(DockerCassandra.class); + + private static final int CASSANDRA_PORT = 9042; + private static final String CASSANDRA_CONFIG_DIR = "$CASSANDRA_CONFIG"; + private static final String CASSANDRA_YAML = CASSANDRA_CONFIG_DIR + "/cassandra.yaml"; + private static final String CASSANDRA_ENV = CASSANDRA_CONFIG_DIR + "/cassandra-env.sh"; + private static final String JVM_OPTIONS = CASSANDRA_CONFIG_DIR + "/jvm.options"; + + private final GenericContainer<?> cassandraContainer; + private final DockerClient client; + + @SuppressWarnings("resource") + public DockerCassandra() { + client = DockerClientFactory.instance().client(); + boolean deleteOnExit = false; + int cassandraMemory = 1000; + long cassandraContainerMemory = Float.valueOf(cassandraMemory * 1.2f * 1024 * 1024L).longValue(); + cassandraContainer = new GenericContainer<>( + new ImageFromDockerfile("cassandra_2_2_12", deleteOnExit) + .withDockerfileFromBuilder(builder -> + builder + .from("cassandra:2.2.12") + .env("ENV CASSANDRA_CONFIG", "/etc/cassandra") + .run("echo \"-Xms" + cassandraMemory + "M\" >> " + JVM_OPTIONS) + .run("echo \"-Xmx" + cassandraMemory + "M\" >> " + JVM_OPTIONS) + .build())) + .withCreateContainerCmdModifier(cmd -> cmd.getHostConfig().withTmpFs(ImmutableMap.of("/var/lib/cassandra", "rw,noexec,nosuid,size=200m"))) + .withCreateContainerCmdModifier(cmd -> cmd.withMemory(cassandraContainerMemory)) + .withExposedPorts(CASSANDRA_PORT) + .withLogConsumer(DockerCassandra::displayDockerLog); + cassandraContainer + .waitingFor(new CassandraWaitStrategy(cassandraContainer)); + } + + private static void displayDockerLog(OutputFrame outputFrame) { + logger.info(outputFrame.getUtf8String()); + } + + public void start() { + cassandraContainer.start(); + } + + public void stop() { + cassandraContainer.stop(); + } + + public Host getHost() { + return Host.from( + getIp(), + getBindingPort()); + } + + public String getIp() { + return cassandraContainer.getContainerIpAddress(); + } + + public int getBindingPort() { + return cassandraContainer.getMappedPort(CASSANDRA_PORT); + } + + public GenericContainer<?> getRawContainer() { + return cassandraContainer; + } + + public void pause() { + client.pauseContainerCmd(cassandraContainer.getContainerId()); + } + + public void unpause() { + client.unpauseContainerCmd(cassandraContainer.getContainerId()); + } + +} http://git-wip-us.apache.org/repos/asf/james-project/blob/524e43ab/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandraRule.java ---------------------------------------------------------------------- diff --git a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandraRule.java b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandraRule.java index 6f634dd..b3eb35e 100644 --- a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandraRule.java +++ b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandraRule.java @@ -23,111 +23,46 @@ import org.apache.james.util.Host; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.testcontainers.DockerClientFactory; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.output.OutputFrame; -import org.testcontainers.images.builder.ImageFromDockerfile; -import org.testcontainers.shaded.com.google.common.collect.ImmutableMap; - -import com.github.dockerjava.api.DockerClient; public class DockerCassandraRule implements TestRule { - private static final Logger logger = LoggerFactory.getLogger(DockerCassandraRule.class); - - private static final int CASSANDRA_PORT = 9042; - private static final String CASSANDRA_CONFIG_DIR = "$CASSANDRA_CONFIG"; - private static final String CASSANDRA_YAML = CASSANDRA_CONFIG_DIR + "/cassandra.yaml"; - private static final String CASSANDRA_ENV = CASSANDRA_CONFIG_DIR + "/cassandra-env.sh"; - private static final String JVM_OPTIONS = CASSANDRA_CONFIG_DIR + "/jvm.options"; - - private final GenericContainer<?> cassandraContainer; - private final DockerClient client; - - @SuppressWarnings("resource") - public DockerCassandraRule() { - client = DockerClientFactory.instance().client(); - boolean deleteOnExit = false; - cassandraContainer = new GenericContainer<>( - new ImageFromDockerfile("cassandra_2_2_12", deleteOnExit) - .withDockerfileFromBuilder(builder -> - builder - .from("cassandra:2.2.12") - .env("ENV CASSANDRA_CONFIG", "/etc/cassandra") - //avoiding token range computation helps starting faster - .run("echo \"JVM_OPTS=\\\"\\$JVM_OPTS -Dcassandra.initial_token=0\\\"\" >> " + CASSANDRA_ENV) - .run("sed -i -e \"s/num_tokens/\\#num_tokens/\" " + CASSANDRA_YAML) - //don't wait for other nodes communication to happen - .run("echo \"JVM_OPTS=\\\"\\$JVM_OPTS -Dcassandra.skip_wait_for_gossip_to_settle=0\\\"\" >> " + CASSANDRA_ENV) - //make sure commit log disk flush won't happen - .run("sed -i -e \"s/commitlog_sync_period_in_ms: 10000/commitlog_sync_period_in_ms: 9999999/\" " + CASSANDRA_YAML) - //auto_bootstrap should be useless when no existing data - .run("echo auto_bootstrap: false >> " + CASSANDRA_YAML) - .run("echo \"-Xms1500M\" >> " + JVM_OPTIONS) - .run("echo \"-Xmx1500M\" >> " + JVM_OPTIONS) - // disable assertions (modest performance benefit) - .run("sed -i -e 's/JVM_OPTS=\"$JVM_OPTS -ea\"/JVM_OPTS=\"$JVM_OPTS -da\"/' " + CASSANDRA_ENV) - // use caches for keys & rows - .run("sed -i -e \"s/key_cache_size_in_mb:/key_cache_size_in_mb: 256/\" " + CASSANDRA_YAML) - .run("sed -i -e \"s/row_cache_size_in_mb: 0/row_cache_size_in_mb: 512/\" " + CASSANDRA_YAML) - .build())) - .withCreateContainerCmdModifier(cmd -> cmd.withMemory(2000 * 1024 * 1024L)) - .withCreateContainerCmdModifier(cmd -> cmd.getHostConfig().withTmpFs(ImmutableMap.of("/var/lib/cassandra", "rw,noexec,nosuid,size=100m"))) - .withExposedPorts(CASSANDRA_PORT) - .withLogConsumer(this::displayDockerLog); - cassandraContainer - .waitingFor(new CassandraWaitStrategy(cassandraContainer)); - } - - private void displayDockerLog(OutputFrame outputFrame) { - logger.info(outputFrame.getUtf8String()); - } - @Override public Statement apply(Statement base, Description description) { - return new Statement() { - @Override - public void evaluate() throws Throwable { - cassandraContainer.apply(base, description).evaluate(); - } - }; + return base; } public void start() { - cassandraContainer.start(); + } public void stop() { - cassandraContainer.stop(); + } public Host getHost() { - return Host.from( - getIp(), - getBindingPort()); + return DockerCassandraSingleton.singleton.getHost(); } public String getIp() { - return cassandraContainer.getContainerIpAddress(); + return DockerCassandraSingleton.singleton.getIp(); } public int getBindingPort() { - return cassandraContainer.getMappedPort(CASSANDRA_PORT); + return DockerCassandraSingleton.singleton.getBindingPort(); } public GenericContainer<?> getRawContainer() { - return cassandraContainer; + return DockerCassandraSingleton.singleton.getRawContainer(); } public void pause() { - client.pauseContainerCmd(cassandraContainer.getContainerId()); + DockerCassandraSingleton.singleton.pause(); } public void unpause() { - client.unpauseContainerCmd(cassandraContainer.getContainerId()); + DockerCassandraSingleton.singleton.unpause(); } } http://git-wip-us.apache.org/repos/asf/james-project/blob/524e43ab/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandraSingleton.java ---------------------------------------------------------------------- diff --git a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandraSingleton.java b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandraSingleton.java new file mode 100644 index 0000000..98fc5fc --- /dev/null +++ b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandraSingleton.java @@ -0,0 +1,36 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you 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.apache.james.backends.cassandra; + +public class DockerCassandraSingleton { + + public static final DockerCassandra singleton = new DockerCassandra(); + + static { + singleton.start(); + } + + public static void restart() { + singleton.stop(); + singleton.start(); + } + + // Cleanup will be performed by test container resource reaper +} http://git-wip-us.apache.org/repos/asf/james-project/blob/524e43ab/mailbox/cassandra/pom.xml ---------------------------------------------------------------------- diff --git a/mailbox/cassandra/pom.xml b/mailbox/cassandra/pom.xml index fb1c5aa..26d57cf 100644 --- a/mailbox/cassandra/pom.xml +++ b/mailbox/cassandra/pom.xml @@ -176,4 +176,16 @@ </dependency> </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <reuseForks>true</reuseForks> + </configuration> + </plugin> + </plugins> + </build> + </project> http://git-wip-us.apache.org/repos/asf/james-project/blob/524e43ab/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdToImapUidDAOTest.java ---------------------------------------------------------------------- diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdToImapUidDAOTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdToImapUidDAOTest.java index a273fb4..c7d6e7d 100644 --- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdToImapUidDAOTest.java +++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdToImapUidDAOTest.java @@ -29,6 +29,7 @@ import javax.mail.Flags.Flag; import org.apache.james.backends.cassandra.CassandraCluster; import org.apache.james.backends.cassandra.DockerCassandraRule; +import org.apache.james.backends.cassandra.DockerCassandraSingleton; import org.apache.james.mailbox.MessageUid; import org.apache.james.mailbox.cassandra.ids.CassandraId; import org.apache.james.mailbox.cassandra.ids.CassandraMessageId; @@ -57,6 +58,7 @@ public class CassandraMessageIdToImapUidDAOTest { @BeforeClass public static void setUpClass() { + DockerCassandraSingleton.restart(); cassandra = CassandraCluster.create(CassandraMessageModule.MODULE, cassandraServer.getHost()); } http://git-wip-us.apache.org/repos/asf/james-project/blob/524e43ab/mpt/impl/imap-mailbox/cassandra/pom.xml ---------------------------------------------------------------------- diff --git a/mpt/impl/imap-mailbox/cassandra/pom.xml b/mpt/impl/imap-mailbox/cassandra/pom.xml index 2289877..4166a7c 100644 --- a/mpt/impl/imap-mailbox/cassandra/pom.xml +++ b/mpt/impl/imap-mailbox/cassandra/pom.xml @@ -60,4 +60,16 @@ <artifactId>blob-cassandra</artifactId> </dependency> </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <reuseForks>true</reuseForks> + </configuration> + </plugin> + </plugins> + </build> </project> http://git-wip-us.apache.org/repos/asf/james-project/blob/524e43ab/mpt/impl/smtp/cassandra/pom.xml ---------------------------------------------------------------------- diff --git a/mpt/impl/smtp/cassandra/pom.xml b/mpt/impl/smtp/cassandra/pom.xml index 3942beb..04784de 100644 --- a/mpt/impl/smtp/cassandra/pom.xml +++ b/mpt/impl/smtp/cassandra/pom.xml @@ -92,5 +92,17 @@ <scope>test</scope> </dependency> </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <reuseForks>true</reuseForks> + </configuration> + </plugin> + </plugins> + </build> </project> http://git-wip-us.apache.org/repos/asf/james-project/blob/524e43ab/server/container/guice/cassandra-guice/pom.xml ---------------------------------------------------------------------- diff --git a/server/container/guice/cassandra-guice/pom.xml b/server/container/guice/cassandra-guice/pom.xml index af6166b..5035f68 100644 --- a/server/container/guice/cassandra-guice/pom.xml +++ b/server/container/guice/cassandra-guice/pom.xml @@ -333,6 +333,13 @@ </execution> </executions> </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <reuseForks>true</reuseForks> + </configuration> + </plugin> </plugins> </build> http://git-wip-us.apache.org/repos/asf/james-project/blob/524e43ab/server/data/data-cassandra/pom.xml ---------------------------------------------------------------------- diff --git a/server/data/data-cassandra/pom.xml b/server/data/data-cassandra/pom.xml index 2e3eb96..3755ffa 100644 --- a/server/data/data-cassandra/pom.xml +++ b/server/data/data-cassandra/pom.xml @@ -158,6 +158,13 @@ <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <reuseForks>true</reuseForks> + </configuration> + </plugin> </plugins> </build> http://git-wip-us.apache.org/repos/asf/james-project/blob/524e43ab/server/data/data-jmap-cassandra/pom.xml ---------------------------------------------------------------------- diff --git a/server/data/data-jmap-cassandra/pom.xml b/server/data/data-jmap-cassandra/pom.xml index 201c98b..115ff7a 100644 --- a/server/data/data-jmap-cassandra/pom.xml +++ b/server/data/data-jmap-cassandra/pom.xml @@ -99,6 +99,13 @@ <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <reuseForks>true</reuseForks> + </configuration> + </plugin> </plugins> </build> http://git-wip-us.apache.org/repos/asf/james-project/blob/524e43ab/server/mailrepository/mailrepository-cassandra/pom.xml ---------------------------------------------------------------------- diff --git a/server/mailrepository/mailrepository-cassandra/pom.xml b/server/mailrepository/mailrepository-cassandra/pom.xml index 69102d9..19f03d0 100644 --- a/server/mailrepository/mailrepository-cassandra/pom.xml +++ b/server/mailrepository/mailrepository-cassandra/pom.xml @@ -112,6 +112,13 @@ <artifactId>maven-bundle-plugin</artifactId> <extensions>true</extensions> </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <reuseForks>true</reuseForks> + </configuration> + </plugin> </plugins> </build> </project> http://git-wip-us.apache.org/repos/asf/james-project/blob/524e43ab/server/protocols/webadmin-integration-test/pom.xml ---------------------------------------------------------------------- diff --git a/server/protocols/webadmin-integration-test/pom.xml b/server/protocols/webadmin-integration-test/pom.xml index 7ea2a82..6a02073 100644 --- a/server/protocols/webadmin-integration-test/pom.xml +++ b/server/protocols/webadmin-integration-test/pom.xml @@ -117,4 +117,16 @@ </dependency> </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <reuseForks>true</reuseForks> + </configuration> + </plugin> + </plugins> + </build> + </project> --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org