JAMES-1999 Add integration testing for retrying connection JAMES-1999 Decrease time for waiting
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/445680d1 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/445680d1 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/445680d1 Branch: refs/heads/master Commit: 445680d1a45fed2c8905896db53187d45063fbdd Parents: 5e1f572 Author: quynhn <qngu...@linagora.com> Authored: Tue Apr 18 17:33:13 2017 +0700 Committer: benwa <btell...@linagora.com> Committed: Fri Apr 21 07:52:53 2017 +0700 ---------------------------------------------------------------------- .../org/apache/james/DockerCassandraRule.java | 4 + .../apache/james/DockerElasticSearchRule.java | 103 +++++++++++++++ .../JamesServerWithRetryConnectionTest.java | 124 +++++++++++++++++++ 3 files changed, 231 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/445680d1/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerCassandraRule.java ---------------------------------------------------------------------- diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerCassandraRule.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerCassandraRule.java index 8b9a000..f5849e6 100644 --- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerCassandraRule.java +++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerCassandraRule.java @@ -87,4 +87,8 @@ public class DockerCassandraRule implements GuiceModuleTestRule { .map(binding -> binding.getHostPortSpec()) .findFirst().get()); } + + public SwarmGenericContainer getCassandraContainer() { + return cassandraContainer; + } } http://git-wip-us.apache.org/repos/asf/james-project/blob/445680d1/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerElasticSearchRule.java ---------------------------------------------------------------------- diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerElasticSearchRule.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerElasticSearchRule.java new file mode 100644 index 0000000..3dd19c2 --- /dev/null +++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerElasticSearchRule.java @@ -0,0 +1,103 @@ +/**************************************************************** + * 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; + +import com.google.inject.Module; +import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.james.modules.mailbox.CassandraSessionConfiguration; +import org.apache.james.modules.mailbox.ElasticSearchConfiguration; +import org.apache.james.util.streams.SwarmGenericContainer; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; +import org.testcontainers.shaded.com.github.dockerjava.api.model.ExposedPort; +import org.testcontainers.shaded.com.github.dockerjava.api.model.Ports.Binding; + +import java.util.Arrays; + + +public class DockerElasticSearchRule implements GuiceModuleTestRule { + + private static final int ELASTIC_SEARCH_PORT = 9300; + public static final int ELASTIC_SEARCH_HTTP_PORT = 9200; + + private static boolean isBindingToEveryThing(Binding binding) { + String bindingIp = binding.getHostIp(); + return bindingIp == null || bindingIp.equals("0.0.0.0"); + } + + public PropertiesConfiguration getElasticSearchConfigurationForDocker() { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + + configuration.addProperty("elasticsearch.masterHost", getIp()); + configuration.addProperty("elasticsearch.port", ELASTIC_SEARCH_PORT); + + configuration.addProperty("elasticsearch.nb.shards", 1); + configuration.addProperty("elasticsearch.nb.replica", 0); + configuration.addProperty("elasticsearch.retryConnection.maxRetries", 7); + configuration.addProperty("elasticsearch.retryConnection.minDelay", 30); + configuration.addProperty("elasticsearch.indexAttachments", false); + configuration.addProperty("elasticsearch.http.host", getIp()); + configuration.addProperty("elasticsearch.http.port", ELASTIC_SEARCH_HTTP_PORT); + configuration.addProperty("elasticsearch.metrics.reports.enabled", true); + configuration.addProperty("elasticsearch.metrics.reports.period", 30); + configuration.addProperty("elasticsearch.metrics.reports.index", "james-metrics"); + + return configuration; + } + + private SwarmGenericContainer elasticSearchContainer = new SwarmGenericContainer("elasticsearch:2.2.2"); + + @Override + public Statement apply(Statement base, Description description) { + return elasticSearchContainer.apply(base, description); + } + + @Override + public void await() { + } + + @Override + public Module getModule() { + return (binder) -> binder.bind(ElasticSearchConfiguration.class).toInstance(this::getElasticSearchConfigurationForDocker); + } + + public String getIp() { + return elasticSearchContainer.getIp(); + } + + public int getBindingPort() { + Binding[] bindings = elasticSearchContainer + .getContainerInfo() + .getNetworkSettings() + .getPorts() + .getBindings() + .get(ExposedPort.tcp(ELASTIC_SEARCH_PORT)); + + return Integer.valueOf( + Arrays.stream(bindings) + .filter(DockerElasticSearchRule::isBindingToEveryThing) + .map(binding -> binding.getHostPortSpec()) + .findFirst().get()); + } + + public SwarmGenericContainer getElasticSearchContainer() { + return elasticSearchContainer; + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/445680d1/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesServerWithRetryConnectionTest.java ---------------------------------------------------------------------- diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesServerWithRetryConnectionTest.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesServerWithRetryConnectionTest.java new file mode 100644 index 0000000..018bda1 --- /dev/null +++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesServerWithRetryConnectionTest.java @@ -0,0 +1,124 @@ +/**************************************************************** + * 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; + +import org.apache.james.util.streams.SwarmGenericContainer; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.testcontainers.DockerClientFactory; +import org.testcontainers.shaded.com.google.common.base.Throwables; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.nio.channels.SocketChannel; +import java.nio.charset.Charset; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import static org.assertj.core.api.Assertions.assertThat; + +public class JamesServerWithRetryConnectionTest { + private static final int IMAP_PORT = 1143; + private static final long WAITING_TIME = TimeUnit.MILLISECONDS.convert(10, TimeUnit.SECONDS); + + private static String getDockerHostIp() { + return DockerClientFactory.instance().dockerHostIpAddress(); + } + + private final DockerCassandraRule dockerCassandraRule = new DockerCassandraRule(); + private final DockerElasticSearchRule dockerElasticSearchRule = new DockerElasticSearchRule(); + + @Rule + public CassandraJmapTestRule cassandraJmapTestRule = new CassandraJmapTestRule(dockerCassandraRule, + dockerElasticSearchRule); + + private GuiceJamesServer jamesServer; + private SocketChannel socketChannel; + private ExecutorService executorService; + + @Before + public void setUp() throws IOException { + executorService = Executors.newFixedThreadPool(1); + socketChannel = SocketChannel.open(); + } + + @After + public void after() throws IOException { + socketChannel.close(); + if (jamesServer != null) { + jamesServer.stop(); + } + executorService.shutdownNow(); + } + + @Test + public void serverShouldStartAtDefault() throws Exception { + jamesServer = cassandraJmapTestRule.jmapServer(); + assertThatServerStartCorrectly(); + } + + @Test + public void serverShouldRetryToConnectToCassandraWhenStartService() throws Exception { + jamesServer = cassandraJmapTestRule.jmapServer(); + dockerCassandraRule.getCassandraContainer().stop(); + + waitToStartContainer(WAITING_TIME, dockerCassandraRule.getCassandraContainer()); + + assertThatServerStartCorrectly(); + } + + @Test + public void serverShouldRetryToConnectToElasticSearchWhenStartService() throws Exception { + jamesServer = cassandraJmapTestRule.jmapServer(); + dockerElasticSearchRule.getElasticSearchContainer().stop(); + + waitToStartContainer(WAITING_TIME, dockerElasticSearchRule.getElasticSearchContainer()); + + assertThatServerStartCorrectly(); + } + + private void waitToStartContainer(long waitingTime, SwarmGenericContainer dockerContainer) { + executorService.submit(() -> { + try { + Thread.sleep(waitingTime); + } catch (InterruptedException e) { + throw Throwables.propagate(e); + } + dockerContainer.start(); + }); + } + + private void assertThatServerStartCorrectly() throws Exception { + jamesServer.start(); + socketChannel.connect(new InetSocketAddress("127.0.0.1", IMAP_PORT)); + assertThat(getServerConnectionResponse(socketChannel)).startsWith("* OK JAMES IMAP4rev1 Server"); + } + + private String getServerConnectionResponse(SocketChannel socketChannel) throws IOException { + ByteBuffer byteBuffer = ByteBuffer.allocate(1000); + socketChannel.read(byteBuffer); + byte[] bytes = byteBuffer.array(); + return new String(bytes, Charset.forName("UTF-8")); + } +} --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org