This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit f8288c2a4cadaebcf5659edccbef4a75aebc0a1d
Author: Benoit Tellier <btell...@linagora.com>
AuthorDate: Tue Sep 3 14:49:02 2019 +0700

    JAMES-2097 Reproduce failover + partial send bug for remote delivery
    
    When doing a partial send across several MX as part of the retry policy,
    James RemoteDelivery service duplicates mails
---
 .../james/mailets/RemoteDeliveryErrorTest.java     | 105 ++++++++++++++++++---
 1 file changed, 93 insertions(+), 12 deletions(-)

diff --git 
a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/RemoteDeliveryErrorTest.java
 
b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/RemoteDeliveryErrorTest.java
index 4a6feaa..4461cb5 100644
--- 
a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/RemoteDeliveryErrorTest.java
+++ 
b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/RemoteDeliveryErrorTest.java
@@ -34,7 +34,9 @@ import static org.hamcrest.Matchers.containsString;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
 
+import java.net.InetAddress;
 import java.nio.charset.StandardCharsets;
+import java.util.List;
 
 import org.apache.james.core.MailAddress;
 import org.apache.james.dnsservice.api.DNSService;
@@ -59,12 +61,15 @@ import org.apache.james.utils.SMTPMessageSender;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.ClassRule;
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.collect.ImmutableList;
+
 import io.restassured.RestAssured;
 import io.restassured.builder.RequestSpecBuilder;
 import io.restassured.builder.ResponseSpecBuilder;
@@ -157,12 +162,22 @@ public class RemoteDeliveryErrorTest {
         .forInputContaining(RECIPIENT1)
         .onlySomeAnswers(1)
         .build();
+    private static final MockSmtpBehaviors ALWAYS_PARTIAL_RCPT_421_BEHAVIOR =  
MockSmtpBehaviors.builder()
+        .addNewBehavior()
+        .onCommand(SMTPCommand.RCPT_TO)
+        .respond(Response.SMTPStatusCode.SERVICE_NOT_AVAILABLE_421, "mock 
response")
+        .forInputContaining(RECIPIENT2)
+        .unlimitedNumberOfAnswer()
+        .build();
     private static final String BOUNCE_MESSAGE = "Hi. This is the James mail 
server at localhost.\n" +
         "I'm afraid I wasn't able to deliver your message to the following 
addresses.\n" +
         "This is a permanent error; I've given up. Sorry it didn't work out. 
Below\n" +
         "I include the list of recipients and the reason why I was unable to 
deliver\n" +
         "your message.";
     private static final ResponseSpecification RESPONSE_SPECIFICATION = new 
ResponseSpecBuilder().build();
+    private InMemoryDNSService inMemoryDNSService;
+    private RequestSpecification requestSpecificationForMockSMTP1;
+    private RequestSpecification requestSpecificationForMockSMTP2;
 
     @Rule
     public TemporaryFolder temporaryFolder = new TemporaryFolder();
@@ -172,13 +187,16 @@ public class RemoteDeliveryErrorTest {
     public SMTPMessageSender messageSender = new 
SMTPMessageSender(DEFAULT_DOMAIN);
     @ClassRule
     public static DockerContainer mockSmtp = 
DockerContainer.fromName("linagora/mock-smtp-server")
-        .withLogConsumer(outputFrame -> 
LOGGER.debug(outputFrame.getUtf8String()));
+        .withLogConsumer(outputFrame -> LOGGER.debug("MockSMTP 1: " + 
outputFrame.getUtf8String()));
+    @ClassRule
+    public static DockerContainer mockSmtp2 = 
DockerContainer.fromName("linagora/mock-smtp-server")
+        .withLogConsumer(outputFrame -> LOGGER.debug("MockSMTP 2: " + 
outputFrame.getUtf8String()));
 
     private TemporaryJamesServer jamesServer;
 
     @Before
     public void setUp() throws Exception {
-        InMemoryDNSService inMemoryDNSService = new InMemoryDNSService()
+        inMemoryDNSService = new InMemoryDNSService()
             .registerMxRecord(DEFAULT_DOMAIN, LOCALHOST_IP)
             .registerMxRecord(ANOTHER_DOMAIN, mockSmtp.getContainerIp());
 
@@ -197,7 +215,9 @@ public class RemoteDeliveryErrorTest {
             .addDomain(DEFAULT_DOMAIN)
             .addUser(FROM, PASSWORD);
 
-        RestAssured.requestSpecification = requestSpecification();
+        requestSpecificationForMockSMTP1 = requestSpecification(mockSmtp);
+        requestSpecificationForMockSMTP2 = requestSpecification(mockSmtp2);
+        RestAssured.requestSpecification = requestSpecificationForMockSMTP1;
         RestAssured.enableLoggingOfRequestAndResponseIfValidationFails();
     }
 
@@ -318,7 +338,7 @@ public class RemoteDeliveryErrorTest {
         messageSender.connect(LOCALHOST_IP, 
jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
             .sendMessage(FROM, RECIPIENT);
 
-        awaitAtMostOneMinute.untilAsserted(() -> given(requestSpecification(), 
RESPONSE_SPECIFICATION)
+        awaitAtMostOneMinute.untilAsserted(() -> given()
             .get("/smtpMails")
         .then()
             .body("", hasSize(1))
@@ -337,7 +357,7 @@ public class RemoteDeliveryErrorTest {
         messageSender.connect(LOCALHOST_IP, 
jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
             .sendMessage(FROM, RECIPIENT);
 
-        awaitAtMostOneMinute.untilAsserted(() -> given(requestSpecification(), 
RESPONSE_SPECIFICATION)
+        awaitAtMostOneMinute.untilAsserted(() -> given()
             .get("/smtpMails")
         .then()
             .body("", hasSize(1))
@@ -356,7 +376,7 @@ public class RemoteDeliveryErrorTest {
         messageSender.connect(LOCALHOST_IP, 
jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
             .sendMessage(FROM, RECIPIENT);
 
-        awaitAtMostOneMinute.untilAsserted(() -> given(requestSpecification(), 
RESPONSE_SPECIFICATION)
+        awaitAtMostOneMinute.untilAsserted(() -> given()
             .get("/smtpMails")
         .then()
             .body("", hasSize(1))
@@ -370,7 +390,7 @@ public class RemoteDeliveryErrorTest {
     public void remoteDeliveryShouldNotDuplicateContentWhenSendPartial() 
throws Exception {
         with()
             .body(SINGLE_PARTIAL_RCPT_421_BEHAVIOR)
-            .put("/smtpBehaviors").prettyPeek();
+            .put("/smtpBehaviors");
 
         messageSender.connect(LOCALHOST_IP, 
jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
             .sendMessage(MailImpl.builder()
@@ -381,12 +401,15 @@ public class RemoteDeliveryErrorTest {
                 
.mimeMessage(MimeMessageUtil.mimeMessageFromString(MIME_MESSAGE))
                 .build());
 
-        awaitAtMostOneMinute.untilAsserted(() -> given(requestSpecification(), 
RESPONSE_SPECIFICATION)
+        awaitAtMostOneMinute.until(() -> given()
             .get("/smtpMails")
         .then()
-            .body("", hasSize(2)));
+            .extract()
+            .body()
+            .as(List.class)
+            .size() == 2);
 
-        String mailsAsJson = given(requestSpecification(), 
RESPONSE_SPECIFICATION)
+        String mailsAsJson = given()
             .get("/smtpMails")
         .then()
             .extract()
@@ -408,6 +431,64 @@ public class RemoteDeliveryErrorTest {
                 "]");
     }
 
+    @Ignore("JAMES-2097 Using full recipients for following MX iteration when 
partial fails on delivering")
+    @Test
+    public void 
remoteDeliveryShouldNotDuplicateContentWhenSendPartialWhenFailover() throws 
Exception {
+        ImmutableList<InetAddress> addresses = 
ImmutableList.of(InetAddress.getByName(mockSmtp.getContainerIp()));
+        ImmutableList<String> mxs = 
ImmutableList.of(mockSmtp.getContainerIp(), mockSmtp2.getContainerIp());
+        ImmutableList<String> txtRecords = ImmutableList.of();
+
+        inMemoryDNSService.registerRecord(ANOTHER_DOMAIN, addresses, mxs, 
txtRecords)
+            .registerMxRecord(mockSmtp.getContainerIp(), 
mockSmtp.getContainerIp())
+            .registerMxRecord(mockSmtp2.getContainerIp(), 
mockSmtp2.getContainerIp());
+
+        given(requestSpecificationForMockSMTP1)
+            .body(ALWAYS_PARTIAL_RCPT_421_BEHAVIOR)
+            .put("/smtpBehaviors");
+
+        messageSender.connect(LOCALHOST_IP, 
jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
+            .sendMessage(MailImpl.builder()
+                .name("name")
+                .sender(new MailAddress(FROM))
+                .addRecipient(RECIPIENT1)
+                .addRecipient(RECIPIENT2)
+                
.mimeMessage(MimeMessageUtil.mimeMessageFromString(MIME_MESSAGE))
+                .build());
+
+        awaitAtMostOneMinute.until(() -> 
given(requestSpecificationForMockSMTP1, RESPONSE_SPECIFICATION)
+            .get("/smtpMails")
+        .then()
+            .extract()
+            .body()
+            .as(List.class)
+            .size() == 1);
+        awaitAtMostOneMinute.until(() -> 
given(requestSpecificationForMockSMTP2, RESPONSE_SPECIFICATION)
+            .get("/smtpMails")
+        .then()
+            .extract()
+            .body()
+            .as(List.class)
+            .size() == 1);
+
+        given(requestSpecificationForMockSMTP1, RESPONSE_SPECIFICATION)
+            .get("/smtpMails")
+        .then()
+            .body("", hasSize(1))
+            .body("[0].from", is(FROM))
+            .body("[0].recipients", hasSize(1))
+            .body("[0].recipients[0]", is(RECIPIENT2))
+            .body("[0].message", containsString("subject: test"));
+        
+        given(requestSpecificationForMockSMTP2, RESPONSE_SPECIFICATION)
+            .get("/smtpMails")
+        .then()
+            .body("", hasSize(1))
+            .body("[0].from", is(FROM))
+            .body("[0].recipients", hasSize(1))
+            .body("[0].recipients[0]", is(RECIPIENT1))
+            .body("[0].message", containsString("subject: test"));
+    }
+
     private ProcessorConfiguration.Builder directResolutionTransport() {
         return ProcessorConfiguration.transport()
             .addMailet(MailetConfiguration.BCC_STRIPPER)
@@ -423,13 +504,13 @@ public class RemoteDeliveryErrorTest {
                 .addProperty("sendpartial", "true"));
     }
 
-    private RequestSpecification requestSpecification() {
+    private RequestSpecification requestSpecification(DockerContainer 
container) {
         return new RequestSpecBuilder()
             .setContentType(ContentType.JSON)
             .setAccept(ContentType.JSON)
             
.setConfig(newConfig().encoderConfig(encoderConfig().defaultContentCharset(StandardCharsets.UTF_8)))
             .setPort(8000)
-            .setBaseUri("http://"; + mockSmtp.getContainerIp())
+            .setBaseUri("http://"; + container.getContainerIp())
             .build();
     }
 }


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

Reply via email to