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 5f5d4e5b9453d51acdc2d13e20ede73b0cec1aa5
Author: Benoit Tellier <[email protected]>
AuthorDate: Fri Apr 30 21:49:18 2021 +0700

    JAMES-3574 Add a unit test for the LMTP protocol
---
 server/protocols/protocols-imap4/pom.xml           |   6 +
 .../james/imapserver/netty/IMAPServerTest.java     |  26 +---
 .../james/protocols/lib/mock/ConfigLoader.java     |  43 +++++
 server/protocols/protocols-lmtp/pom.xml            |  58 +++++++
 .../apache/james/lmtpserver/LmtpServerTest.java    | 173 +++++++++++++++++++++
 .../protocols-lmtp/src/test/resources/lmtp.xml     |  34 ++++
 6 files changed, 316 insertions(+), 24 deletions(-)

diff --git a/server/protocols/protocols-imap4/pom.xml 
b/server/protocols/protocols-imap4/pom.xml
index 937f2e7..317fdbd 100644
--- a/server/protocols/protocols-imap4/pom.xml
+++ b/server/protocols/protocols-imap4/pom.xml
@@ -66,6 +66,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>james-server-protocols-library</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>james-server-testing</artifactId>
             <scope>test</scope>
         </dependency>
diff --git 
a/server/protocols/protocols-imap4/src/test/java/org/apache/james/imapserver/netty/IMAPServerTest.java
 
b/server/protocols/protocols-imap4/src/test/java/org/apache/james/imapserver/netty/IMAPServerTest.java
index 2790b7e..417f5c4 100644
--- 
a/server/protocols/protocols-imap4/src/test/java/org/apache/james/imapserver/netty/IMAPServerTest.java
+++ 
b/server/protocols/protocols-imap4/src/test/java/org/apache/james/imapserver/netty/IMAPServerTest.java
@@ -23,8 +23,6 @@ import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatCode;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
 import java.util.Properties;
 
 import javax.mail.Folder;
@@ -38,11 +36,6 @@ import javax.mail.search.RecipientStringTerm;
 import javax.mail.search.SearchTerm;
 import javax.mail.search.SubjectTerm;
 
-import org.apache.commons.configuration2.XMLConfiguration;
-import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
-import org.apache.commons.configuration2.builder.fluent.Parameters;
-import org.apache.commons.configuration2.convert.DisabledListDelimiterHandler;
-import org.apache.commons.configuration2.io.FileHandler;
 import org.apache.james.core.Username;
 import org.apache.james.imap.encode.main.DefaultImapEncoderFactory;
 import org.apache.james.imap.main.DefaultImapDecoderFactory;
@@ -55,9 +48,7 @@ import org.apache.james.mailbox.store.FakeAuthenticator;
 import org.apache.james.mailbox.store.FakeAuthorizator;
 import org.apache.james.mailbox.store.StoreSubscriptionManager;
 import org.apache.james.metrics.tests.RecordingMetricFactory;
-import org.apache.james.mime4j.codec.DecoderUtil;
-import org.apache.james.mime4j.codec.EncoderUtil;
-import org.apache.james.mime4j.util.MimeUtil;
+import org.apache.james.protocols.lib.mock.ConfigLoader;
 import org.apache.james.util.ClassLoaderUtils;
 import org.apache.james.utils.TestIMAPClient;
 import org.junit.jupiter.api.AfterEach;
@@ -75,19 +66,6 @@ class IMAPServerTest {
     public static final String SMALL_MESSAGE = "header: value\r\n\r\nBODY";
     private InMemoryIntegrationResources memoryIntegrationResources;
 
-    private static XMLConfiguration getConfig(InputStream configStream) throws 
Exception {
-        FileBasedConfigurationBuilder<XMLConfiguration> builder = new 
FileBasedConfigurationBuilder<>(XMLConfiguration.class)
-            .configure(new Parameters()
-                .xml()
-                .setListDelimiterHandler(new DisabledListDelimiterHandler()));
-        XMLConfiguration xmlConfiguration = builder.getConfiguration();
-        FileHandler fileHandler = new FileHandler(xmlConfiguration);
-        fileHandler.load(configStream);
-        configStream.close();
-
-        return xmlConfiguration;
-    }
-
     @RegisterExtension
     public TestIMAPClient testIMAPClient = new TestIMAPClient();
 
@@ -119,7 +97,7 @@ class IMAPServerTest {
                 metricFactory),
             new ImapMetrics(metricFactory));
 
-        
imapServer.configure(getConfig(ClassLoaderUtils.getSystemResourceAsSharedStream(configurationFile)));
+        
imapServer.configure(ConfigLoader.getConfig(ClassLoaderUtils.getSystemResourceAsSharedStream(configurationFile)));
         imapServer.init();
 
         return imapServer;
diff --git 
a/server/protocols/protocols-library/src/test/java/org/apache/james/protocols/lib/mock/ConfigLoader.java
 
b/server/protocols/protocols-library/src/test/java/org/apache/james/protocols/lib/mock/ConfigLoader.java
new file mode 100644
index 0000000..3c610d3
--- /dev/null
+++ 
b/server/protocols/protocols-library/src/test/java/org/apache/james/protocols/lib/mock/ConfigLoader.java
@@ -0,0 +1,43 @@
+/****************************************************************
+ * 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.protocols.lib.mock;
+
+import java.io.InputStream;
+
+import org.apache.commons.configuration2.XMLConfiguration;
+import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
+import org.apache.commons.configuration2.builder.fluent.Parameters;
+import org.apache.commons.configuration2.convert.DisabledListDelimiterHandler;
+import org.apache.commons.configuration2.io.FileHandler;
+
+public class ConfigLoader {
+    public static XMLConfiguration getConfig(InputStream configStream) throws 
Exception {
+        FileBasedConfigurationBuilder<XMLConfiguration> builder = new 
FileBasedConfigurationBuilder<>(XMLConfiguration.class)
+            .configure(new Parameters()
+                .xml()
+                .setListDelimiterHandler(new DisabledListDelimiterHandler()));
+        XMLConfiguration xmlConfiguration = builder.getConfiguration();
+        FileHandler fileHandler = new FileHandler(xmlConfiguration);
+        fileHandler.load(configStream);
+        configStream.close();
+
+        return xmlConfiguration;
+    }
+}
diff --git a/server/protocols/protocols-lmtp/pom.xml 
b/server/protocols/protocols-lmtp/pom.xml
index 8090e67..ca07fa0 100644
--- a/server/protocols/protocols-lmtp/pom.xml
+++ b/server/protocols/protocols-lmtp/pom.xml
@@ -39,18 +39,61 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>apache-james-mailbox-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>apache-james-mailbox-memory</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>apache-james-mailbox-memory</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>apache-mailet-api</artifactId>
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>event-bus-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>james-server-data-api</artifactId>
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>james-server-data-memory</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>james-server-dnsservice-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>james-server-mailetcontainer-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>james-server-protocols-library</artifactId>
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>james-server-protocols-library</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>james-server-protocols-smtp</artifactId>
             <exclusions>
                 <exclusion>
@@ -73,6 +116,16 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>james-server-testing</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>metrics-tests</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>testing-base</artifactId>
             <scope>test</scope>
         </dependency>
@@ -93,6 +146,11 @@
             <artifactId>protocols-smtp</artifactId>
         </dependency>
         <dependency>
+            <groupId>com.google.inject</groupId>
+            <artifactId>guice</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>io.netty</groupId>
             <artifactId>netty</artifactId>
         </dependency>
diff --git 
a/server/protocols/protocols-lmtp/src/test/java/org/apache/james/lmtpserver/LmtpServerTest.java
 
b/server/protocols/protocols-lmtp/src/test/java/org/apache/james/lmtpserver/LmtpServerTest.java
new file mode 100644
index 0000000..0de463c
--- /dev/null
+++ 
b/server/protocols/protocols-lmtp/src/test/java/org/apache/james/lmtpserver/LmtpServerTest.java
@@ -0,0 +1,173 @@
+/****************************************************************
+ * 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.lmtpserver;
+
+import static org.apache.james.jmap.JMAPTestingConstants.DOMAIN;
+import static org.apache.james.jmap.JMAPTestingConstants.LOCALHOST_IP;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
+
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.james.core.Domain;
+import org.apache.james.core.Username;
+import org.apache.james.dnsservice.api.DNSService;
+import org.apache.james.dnsservice.api.InMemoryDNSService;
+import org.apache.james.domainlist.api.DomainList;
+import org.apache.james.domainlist.lib.DomainListConfiguration;
+import org.apache.james.domainlist.memory.MemoryDomainList;
+import org.apache.james.filesystem.api.FileSystem;
+import org.apache.james.lmtpserver.netty.LMTPServerFactory;
+import org.apache.james.mailbox.MailboxManager;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.inmemory.InMemoryMailboxManager;
+import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.model.MessageRange;
+import org.apache.james.mailbox.store.FakeAuthenticator;
+import org.apache.james.mailbox.store.FakeAuthorizator;
+import org.apache.james.metrics.api.MetricFactory;
+import org.apache.james.metrics.tests.RecordingMetricFactory;
+import org.apache.james.protocols.lib.mock.ConfigLoader;
+import org.apache.james.protocols.lib.mock.MockProtocolHandlerLoader;
+import org.apache.james.rrt.api.AliasReverseResolver;
+import org.apache.james.rrt.api.CanSendFrom;
+import org.apache.james.rrt.api.RecipientRewriteTable;
+import org.apache.james.rrt.api.RecipientRewriteTableConfiguration;
+import org.apache.james.rrt.lib.AliasReverseResolverImpl;
+import org.apache.james.rrt.lib.CanSendFromImpl;
+import org.apache.james.rrt.memory.MemoryRecipientRewriteTable;
+import org.apache.james.server.core.configuration.Configuration;
+import org.apache.james.server.core.filesystem.FileSystemImpl;
+import org.apache.james.user.api.UsersRepository;
+import org.apache.james.user.memory.MemoryUsersRepository;
+import org.awaitility.Awaitility;
+import org.jboss.netty.util.HashedWheelTimer;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import com.google.inject.name.Names;
+
+import reactor.core.publisher.Flux;
+
+class LmtpServerTest {
+    private InMemoryMailboxManager mailboxManager;
+    private LMTPServerFactory lmtpServerFactory;
+
+    @BeforeEach
+    void setUp()  throws Exception {
+        InMemoryDNSService dnsService = new InMemoryDNSService()
+            .registerMxRecord(Domain.LOCALHOST.asString(), "127.0.0.1")
+            .registerMxRecord("examplebis.local", "127.0.0.1")
+            .registerMxRecord("127.0.0.1", "127.0.0.1");
+        MemoryDomainList domainList = new MemoryDomainList(dnsService);
+        domainList.configure(DomainListConfiguration.builder()
+            .autoDetect(false)
+            .autoDetectIp(false)
+            .build());
+
+        domainList.addDomain(Domain.of("examplebis.local"));
+        MemoryUsersRepository usersRepository = 
MemoryUsersRepository.withVirtualHosting(domainList);
+
+        FakeAuthenticator authenticator = new FakeAuthenticator();
+        mailboxManager = InMemoryIntegrationResources.builder()
+            .authenticator(authenticator)
+            .authorizator(FakeAuthorizator.defaultReject())
+            .inVmEventBus()
+            .defaultAnnotationLimits()
+            .defaultMessageParser()
+            .scanningSearchIndex()
+            .noPreDeletionHooks()
+            .storeQuotaManager()
+            .build().getMailboxManager();
+
+        usersRepository.addUser(Username.of("[email protected]"), "pwd");
+
+        FileSystem fileSystem = new FileSystemImpl(Configuration.builder()
+            .workingDirectory("../")
+            .configurationFromClasspath()
+            .build().directories());
+        MemoryRecipientRewriteTable rewriteTable = new 
MemoryRecipientRewriteTable();
+        
rewriteTable.setConfiguration(RecipientRewriteTableConfiguration.DEFAULT_ENABLED);
+        AliasReverseResolver aliasReverseResolver = new 
AliasReverseResolverImpl(rewriteTable);
+        CanSendFrom canSendFrom = new CanSendFromImpl(rewriteTable, 
aliasReverseResolver);
+        MockProtocolHandlerLoader loader = MockProtocolHandlerLoader.builder()
+            .put(binder -> 
binder.bind(DomainList.class).toInstance(domainList))
+            .put(binder -> 
binder.bind(RecipientRewriteTable.class).toInstance(rewriteTable))
+            .put(binder -> 
binder.bind(CanSendFrom.class).toInstance(canSendFrom))
+            .put(binder -> 
binder.bind(FileSystem.class).toInstance(fileSystem))
+            .put(binder -> 
binder.bind(DNSService.class).toInstance(dnsService))
+            .put(binder -> 
binder.bind(UsersRepository.class).toInstance(usersRepository))
+            .put(binder -> 
binder.bind(MetricFactory.class).to(RecordingMetricFactory.class))
+            .put(binder -> 
binder.bind(MailboxManager.class).annotatedWith(Names.named("mailboxmanager")).toInstance(mailboxManager))
+            .build();
+        lmtpServerFactory = new LMTPServerFactory(loader, fileSystem, new 
RecordingMetricFactory(), new HashedWheelTimer());
+
+        
lmtpServerFactory.configure(ConfigLoader.getConfig(ClassLoader.getSystemResourceAsStream("lmtp.xml")));
+        lmtpServerFactory.init();
+    }
+
+    @AfterEach
+    void tearDown() {
+        lmtpServerFactory.destroy();
+    }
+
+    @Test
+    void emailsShouldWellBeReceived() throws Exception {
+        SocketChannel server = SocketChannel.open();
+        server.connect(new InetSocketAddress(LOCALHOST_IP, getLmtpPort()));
+
+        server.write(ByteBuffer.wrap(("LHLO <" + DOMAIN + 
">\r\n").getBytes(StandardCharsets.UTF_8)));
+        server.write(ByteBuffer.wrap(("MAIL FROM: <bob@" + DOMAIN + 
">\r\n").getBytes(StandardCharsets.UTF_8)));
+        server.write(ByteBuffer.wrap(("RCPT TO: 
<[email protected]>\r\n").getBytes(StandardCharsets.UTF_8)));
+        
server.write(ByteBuffer.wrap(("DATA\r\n").getBytes(StandardCharsets.UTF_8)));
+        server.read(ByteBuffer.allocate(1024)); // needed to synchronize
+        
server.write(ByteBuffer.wrap(("header:value\r\n\r\nbody").getBytes(StandardCharsets.UTF_8)));
+        
server.write(ByteBuffer.wrap(("\r\n").getBytes(StandardCharsets.UTF_8)));
+        server.write(ByteBuffer.wrap((".").getBytes(StandardCharsets.UTF_8)));
+        
server.write(ByteBuffer.wrap(("\r\n").getBytes(StandardCharsets.UTF_8)));
+        
server.write(ByteBuffer.wrap(("QUIT\r\n").getBytes(StandardCharsets.UTF_8)));
+
+        Awaitility.await()
+            .untilAsserted(() -> {
+                Username username = Username.of("[email protected]");
+                MailboxSession systemSession = 
mailboxManager.createSystemSession(username);
+                assertThatCode(() ->
+                    
assertThat(Flux.from(mailboxManager.getMailbox(MailboxPath.inbox(username), 
systemSession)
+                        .listMessagesMetadata(MessageRange.all(), 
systemSession))
+                        .count()
+                        .block())
+                        .isEqualTo(1))
+                    .doesNotThrowAnyException();
+            });
+    }
+
+    public int getLmtpPort() {
+        return lmtpServerFactory.getServers().stream()
+            .findFirst()
+            .flatMap(server -> 
server.getListenAddresses().stream().findFirst())
+            .map(InetSocketAddress::getPort)
+            .orElseThrow(() -> new IllegalStateException("LMTP server not 
defined"));
+    }
+}
\ No newline at end of file
diff --git a/server/protocols/protocols-lmtp/src/test/resources/lmtp.xml 
b/server/protocols/protocols-lmtp/src/test/resources/lmtp.xml
new file mode 100644
index 0000000..7ac3705
--- /dev/null
+++ b/server/protocols/protocols-lmtp/src/test/resources/lmtp.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+  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.
+ -->
+
+<lmtpservers>
+    <lmtpserver enabled="true">
+        <jmxName>lmtpserver</jmxName>
+        <bind>0.0.0.0:0</bind>
+        <connectionBacklog>200</connectionBacklog>
+        <connectiontimeout>1200</connectiontimeout>
+        <connectionLimit>0</connectionLimit>
+        <connectionLimitPerIP>0</connectionLimitPerIP>
+        <maxmessagesize>0</maxmessagesize>
+        <handlerchain>
+            <handler class="org.apache.james.lmtpserver.CoreCmdHandlerLoader"/>
+        </handlerchain>
+    </lmtpserver>
+</lmtpservers>

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to