You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2018/07/04 02:37:31 UTC

[4/7] james-project git commit: JAMES-2442 Integration tests for RemoteDelivery

JAMES-2442 Integration tests for RemoteDelivery

- That an unreachable MX IP will generate a failover to the second MX when direct resolution
- If all (direct resolution) MX IPs are not reachable, a bounce is sent
- what happens when direct resolution to a domain with no mx records? a bounce is sent


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/80535727
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/80535727
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/80535727

Branch: refs/heads/master
Commit: 805357274248eb5605e3338cc6ccc1abf05540b7
Parents: 42e473e
Author: duc <dt...@linagora.com>
Authored: Wed Jun 27 18:37:42 2018 +0700
Committer: benwa <bt...@linagora.com>
Committed: Wed Jul 4 09:33:55 2018 +0700

----------------------------------------------------------------------
 .../util/docker/SwarmGenericContainer.java      |   5 +
 ...ResolutionRemoteDeliveryIntegrationTest.java | 221 +++++++++++++++++++
 .../GatewayRemoteDeliveryIntegrationTest.java   |  31 ---
 .../java/org/apache/james/utils/FakeSmtp.java   |  27 ++-
 4 files changed, 248 insertions(+), 36 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/80535727/server/container/util-java8/src/test/java/org/apache/james/util/docker/SwarmGenericContainer.java
----------------------------------------------------------------------
diff --git a/server/container/util-java8/src/test/java/org/apache/james/util/docker/SwarmGenericContainer.java b/server/container/util-java8/src/test/java/org/apache/james/util/docker/SwarmGenericContainer.java
index e9fd984..59488c0 100644
--- a/server/container/util-java8/src/test/java/org/apache/james/util/docker/SwarmGenericContainer.java
+++ b/server/container/util-java8/src/test/java/org/apache/james/util/docker/SwarmGenericContainer.java
@@ -108,6 +108,11 @@ public class SwarmGenericContainer implements TestRule {
         return this;
     }
 
+    public SwarmGenericContainer withCommands(String... commands) {
+        container.withCommand(commands);
+        return this;
+    }
+
     public void start() {
         container.start();
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/80535727/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/DirectResolutionRemoteDeliveryIntegrationTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/DirectResolutionRemoteDeliveryIntegrationTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/DirectResolutionRemoteDeliveryIntegrationTest.java
new file mode 100644
index 0000000..fc8c7c4
--- /dev/null
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/DirectResolutionRemoteDeliveryIntegrationTest.java
@@ -0,0 +1,221 @@
+/****************************************************************
+ * 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.mailets;
+
+import static org.apache.james.MemoryJamesServerMain.SMTP_AND_IMAP_MODULE;
+import static org.apache.james.MemoryJamesServerMain.SMTP_ONLY_MODULE;
+import static org.apache.james.mailets.configuration.Constants.*;
+import static org.apache.james.mailets.configuration.MailetConfiguration.LOCAL_DELIVERY;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasSize;
+
+import java.net.InetAddress;
+import java.util.List;
+
+import org.apache.james.dnsservice.api.DNSService;
+import org.apache.james.dnsservice.api.InMemoryDNSService;
+import org.apache.james.mailets.configuration.CommonProcessors;
+import org.apache.james.mailets.configuration.MailetConfiguration;
+import org.apache.james.mailets.configuration.MailetContainer;
+import org.apache.james.mailets.configuration.ProcessorConfiguration;
+import org.apache.james.probe.DataProbe;
+import org.apache.james.transport.matchers.All;
+import org.apache.james.utils.DataProbeImpl;
+import org.apache.james.utils.FakeSmtp;
+import org.apache.james.utils.IMAPMessageReader;
+import org.apache.james.utils.SMTPMessageSender;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import com.google.common.collect.ImmutableList;
+
+public class DirectResolutionRemoteDeliveryIntegrationTest {
+    private static final String JAMES_ANOTHER_DOMAIN = "james.com";
+    private static final String JAMES_ANOTHER_MX_DOMAIN_1 = "mx1.james.com";
+    private static final String JAMES_ANOTHER_MX_DOMAIN_2 = "mx2.james.com";
+    private static final List<String> JAMES_ANOTHER_MX_DOMAINS = ImmutableList.of(JAMES_ANOTHER_MX_DOMAIN_1, JAMES_ANOTHER_MX_DOMAIN_2);
+
+    private static final String FROM = "from@" + DEFAULT_DOMAIN;
+    private static final String RECIPIENT = "touser@" + JAMES_ANOTHER_DOMAIN;
+
+    private static final ImmutableList<InetAddress> ADDRESS_EMPTY_LIST = ImmutableList.of();
+    private static final ImmutableList<String> RECORD_EMPTY_LIST = ImmutableList.of();
+
+    @Rule
+    public TemporaryFolder temporaryFolder = new TemporaryFolder();
+    @Rule
+    public IMAPMessageReader imapMessageReader = new IMAPMessageReader();
+    @Rule
+    public SMTPMessageSender messageSender = new SMTPMessageSender(DEFAULT_DOMAIN);
+    @Rule
+    public FakeSmtp fakeSmtp = new FakeSmtp();
+    @Rule
+    public FakeSmtp fakeSmtpOnPort26 = FakeSmtp.withSmtpPort(26);
+
+    private TemporaryJamesServer jamesServer;
+    private DataProbe dataProbe;
+
+    @Before
+    public void setup() {
+        fakeSmtp.awaitStarted(awaitAtMostOneMinute);
+        fakeSmtpOnPort26.awaitStarted(awaitAtMostOneMinute);
+    }
+
+    @After
+    public void tearDown() {
+        if (jamesServer != null) {
+            jamesServer.shutdown();
+        }
+    }
+
+    @Test
+    public void directResolutionShouldBeWellPerformed() throws Exception {
+        InMemoryDNSService inMemoryDNSService = new InMemoryDNSService()
+            .registerMxRecord(JAMES_ANOTHER_DOMAIN, fakeSmtp.getContainer().getContainerIp());
+
+        jamesServer = TemporaryJamesServer.builder()
+            .withBase(SMTP_ONLY_MODULE)
+            .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
+            .withMailetContainer(MailetContainer.builder()
+                .putProcessor(CommonProcessors.simpleRoot())
+                .putProcessor(CommonProcessors.error())
+                .putProcessor(directResolutionTransport())
+                .putProcessor(CommonProcessors.bounces()))
+            .build(temporaryFolder);
+
+        dataProbe = jamesServer.getProbe(DataProbeImpl.class);
+        dataProbe.addDomain(DEFAULT_DOMAIN);
+        dataProbe.addUser(FROM, PASSWORD);
+
+        messageSender.connect(LOCALHOST_IP, SMTP_PORT)
+            .sendMessage(FROM, RECIPIENT);
+
+        awaitAtMostOneMinute.until(this::messageIsReceivedByTheSmtpServer);
+    }
+
+    @Test
+    public void directResolutionShouldFailoverOnSecondMxWhenFirstMxFailed() throws Exception {
+        InMemoryDNSService inMemoryDNSService = new InMemoryDNSService()
+            .registerRecord(JAMES_ANOTHER_DOMAIN, ADDRESS_EMPTY_LIST, JAMES_ANOTHER_MX_DOMAINS, RECORD_EMPTY_LIST)
+            .registerMxRecord(JAMES_ANOTHER_MX_DOMAIN_1, fakeSmtpOnPort26.getContainer().getContainerIp())
+            .registerMxRecord(JAMES_ANOTHER_MX_DOMAIN_2, fakeSmtp.getContainer().getContainerIp());
+
+        jamesServer = TemporaryJamesServer.builder()
+            .withBase(SMTP_ONLY_MODULE)
+            .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
+            .withMailetContainer(MailetContainer.builder()
+                .putProcessor(CommonProcessors.simpleRoot())
+                .putProcessor(CommonProcessors.error())
+                .putProcessor(directResolutionTransport())
+                .putProcessor(CommonProcessors.bounces()))
+            .build(temporaryFolder);
+
+        dataProbe = jamesServer.getProbe(DataProbeImpl.class);
+        dataProbe.addDomain(DEFAULT_DOMAIN);
+        dataProbe.addUser(FROM, PASSWORD);
+
+        messageSender.connect(LOCALHOST_IP, SMTP_PORT)
+            .sendMessage(FROM, RECIPIENT);
+
+        awaitAtMostOneMinute.until(this::messageIsReceivedByTheSmtpServer);
+    }
+
+    @Test
+    public void directResolutionShouldBounceUponUnreachableMxRecords() throws Exception {
+        InMemoryDNSService inMemoryDNSService = new InMemoryDNSService()
+            .registerRecord(JAMES_ANOTHER_DOMAIN, ADDRESS_EMPTY_LIST, ImmutableList.of("unknown"), RECORD_EMPTY_LIST);
+
+        jamesServer = TemporaryJamesServer.builder()
+            .withBase(SMTP_AND_IMAP_MODULE)
+            .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
+            .withMailetContainer(MailetContainer.builder()
+                .putProcessor(CommonProcessors.simpleRoot())
+                .putProcessor(CommonProcessors.error())
+                .putProcessor(transport())
+                .putProcessor(CommonProcessors.bounces()))
+            .build(temporaryFolder);
+
+        dataProbe = jamesServer.getProbe(DataProbeImpl.class);
+        dataProbe.addDomain(DEFAULT_DOMAIN);
+        dataProbe.addUser(FROM, PASSWORD);
+
+        messageSender.connect(LOCALHOST_IP, SMTP_PORT)
+            .sendMessage(FROM, RECIPIENT);
+
+        imapMessageReader.connect(LOCALHOST_IP, IMAP_PORT)
+            .login(FROM, PASSWORD)
+            .select(IMAPMessageReader.INBOX)
+            .awaitMessage(awaitAtMostOneMinute);
+    }
+
+    @Test
+    public void directResolutionShouldBounceWhenNoMxRecord() throws Exception {
+        InMemoryDNSService inMemoryDNSService = new InMemoryDNSService()
+            .registerRecord(JAMES_ANOTHER_DOMAIN, ADDRESS_EMPTY_LIST, RECORD_EMPTY_LIST, RECORD_EMPTY_LIST);
+
+        jamesServer = TemporaryJamesServer.builder()
+            .withBase(SMTP_AND_IMAP_MODULE)
+            .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
+            .withMailetContainer(MailetContainer.builder()
+                .putProcessor(CommonProcessors.simpleRoot())
+                .putProcessor(CommonProcessors.error())
+                .putProcessor(transport())
+                .putProcessor(CommonProcessors.bounces()))
+            .build(temporaryFolder);
+
+        dataProbe = jamesServer.getProbe(DataProbeImpl.class);
+        dataProbe.addDomain(DEFAULT_DOMAIN);
+        dataProbe.addUser(FROM, PASSWORD);
+
+        messageSender.connect(LOCALHOST_IP, SMTP_PORT)
+            .sendMessage(FROM, RECIPIENT);
+
+        imapMessageReader.connect(LOCALHOST_IP, IMAP_PORT)
+            .login(FROM, PASSWORD)
+            .select(IMAPMessageReader.INBOX)
+            .awaitMessage(awaitAtMostOneMinute);
+    }
+
+    private boolean messageIsReceivedByTheSmtpServer() {
+        return fakeSmtp.isReceived(response -> response
+            .body("", hasSize(1))
+            .body("[0].from", equalTo(FROM))
+            .body("[0].subject", equalTo("test")));
+    }
+
+    private ProcessorConfiguration.Builder directResolutionTransport() {
+        return ProcessorConfiguration.transport()
+            .addMailet(MailetConfiguration.BCC_STRIPPER)
+            .addMailet(MailetConfiguration.remoteDeliveryBuilder()
+                .matcher(All.class));
+    }
+
+    private ProcessorConfiguration.Builder transport() {
+        return ProcessorConfiguration.transport()
+            .addMailet(MailetConfiguration.BCC_STRIPPER)
+            .addMailet(LOCAL_DELIVERY)
+            .addMailet(MailetConfiguration.remoteDeliveryBuilder()
+                .matcher(All.class));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/80535727/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/GatewayRemoteDeliveryIntegrationTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/GatewayRemoteDeliveryIntegrationTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/GatewayRemoteDeliveryIntegrationTest.java
index cb4cf10..0158104 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/GatewayRemoteDeliveryIntegrationTest.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/GatewayRemoteDeliveryIntegrationTest.java
@@ -237,28 +237,6 @@ public class GatewayRemoteDeliveryIntegrationTest {
             .awaitMessage(awaitAtMostOneMinute);
     }
 
-    @Test
-    public void directResolutionShouldBeWellPerformed() throws Exception {
-        jamesServer = TemporaryJamesServer.builder()
-            .withBase(SMTP_ONLY_MODULE)
-            .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
-            .withMailetContainer(MailetContainer.builder()
-                .putProcessor(CommonProcessors.simpleRoot())
-                .putProcessor(CommonProcessors.error())
-                .putProcessor(directResolutionTransport())
-                .putProcessor(CommonProcessors.bounces()))
-            .build(temporaryFolder);
-
-        dataProbe = jamesServer.getProbe(DataProbeImpl.class);
-        dataProbe.addDomain(DEFAULT_DOMAIN);
-        dataProbe.addUser(FROM, PASSWORD);
-
-        messageSender.connect(LOCALHOST_IP, SMTP_PORT)
-            .sendMessage(FROM, RECIPIENT);
-
-        awaitAtMostOneMinute.until(this::messageIsReceivedByTheSmtpServer);
-    }
-
     private boolean messageIsReceivedByTheSmtpServer() {
         return fakeSmtp.isReceived(response -> response
             .body("", hasSize(1))
@@ -278,13 +256,4 @@ public class GatewayRemoteDeliveryIntegrationTest {
                 .addProperty("gateway", gatewayProperty)
                 .matcher(All.class));
     }
-
-    private ProcessorConfiguration.Builder directResolutionTransport() {
-        return ProcessorConfiguration.transport()
-            .addMailet(MailetConfiguration.BCC_STRIPPER)
-            .addMailet(MailetConfiguration.remoteDeliveryBuilder()
-                .matcher(All.class));
-    }
-
-
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/80535727/server/testing/src/main/java/org/apache/james/utils/FakeSmtp.java
----------------------------------------------------------------------
diff --git a/server/testing/src/main/java/org/apache/james/utils/FakeSmtp.java b/server/testing/src/main/java/org/apache/james/utils/FakeSmtp.java
index 4b5fc3a..5013110 100644
--- a/server/testing/src/main/java/org/apache/james/utils/FakeSmtp.java
+++ b/server/testing/src/main/java/org/apache/james/utils/FakeSmtp.java
@@ -42,15 +42,32 @@ import com.jayway.restassured.specification.RequestSpecification;
 import com.jayway.restassured.specification.ResponseSpecification;
 
 public class FakeSmtp implements TestRule {
+
+    public static FakeSmtp withSmtpPort(Integer smtpPort) {
+        SwarmGenericContainer container = fakeSmtpContainer()
+            .withCommands("node", "cli", "--listen", "80", "--smtp", smtpPort.toString());
+
+        return new FakeSmtp(container, smtpPort);
+    }
+
+    private static SwarmGenericContainer fakeSmtpContainer() {
+        return new SwarmGenericContainer(Images.FAKE_SMTP)
+            .withAffinityToContainer()
+            .waitingFor(new HostPortWaitStrategy());
+    }
+
     private static final int SMTP_PORT = 25;
     private static final ResponseSpecification RESPONSE_SPECIFICATION = new ResponseSpecBuilder().build();
     private final SwarmGenericContainer container;
+    private final Integer smtpPort;
 
     public FakeSmtp() {
-        container = new SwarmGenericContainer(Images.FAKE_SMTP)
-            .withExposedPorts(SMTP_PORT)
-            .withAffinityToContainer()
-            .waitingFor(new HostPortWaitStrategy());
+        this(fakeSmtpContainer().withExposedPorts(SMTP_PORT), SMTP_PORT);
+    }
+
+    public FakeSmtp(SwarmGenericContainer container, Integer smtpPort) {
+        this.smtpPort = smtpPort;
+        this.container = container;
     }
 
     @Override
@@ -59,7 +76,7 @@ public class FakeSmtp implements TestRule {
     }
 
     public void awaitStarted(ConditionFactory calmyAwait) {
-        calmyAwait.until(() -> container.tryConnect(SMTP_PORT));
+        calmyAwait.until(() -> container.tryConnect(smtpPort));
     }
 
     public boolean isReceived(Function<ValidatableResponse, ValidatableResponse> expectations) {


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org