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 ro...@apache.org on 2017/01/10 14:18:43 UTC
[28/50] [abbrv] james-project git commit: JAMES-1877 Provide tests
for DeliveryRunnable decision making
JAMES-1877 Provide tests for DeliveryRunnable decision making
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/fc1b1d3e
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/fc1b1d3e
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/fc1b1d3e
Branch: refs/heads/master
Commit: fc1b1d3e7054bf1c8ede4c3fb5d0727f677cf13f
Parents: 9790170
Author: Benoit Tellier <bt...@linagora.com>
Authored: Fri Dec 2 14:35:46 2016 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Tue Jan 10 15:12:51 2017 +0700
----------------------------------------------------------------------
.../remoteDelivery/DeliveryRunnable.java | 33 ++-
.../remoteDelivery/DeliveryRunnableTest.java | 249 +++++++++++++++++++
2 files changed, 276 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/fc1b1d3e/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remoteDelivery/DeliveryRunnable.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remoteDelivery/DeliveryRunnable.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remoteDelivery/DeliveryRunnable.java
index d46a9f5..bc01245 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remoteDelivery/DeliveryRunnable.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remoteDelivery/DeliveryRunnable.java
@@ -31,8 +31,19 @@ import org.apache.mailet.Mail;
import org.apache.mailet.MailetContext;
import org.slf4j.Logger;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Supplier;
+
public class DeliveryRunnable implements Runnable {
+ public static final Supplier<Date> CURRENT_DATE_SUPPLIER = new Supplier<Date>() {
+ @Override
+ public Date get() {
+ return new Date();
+ }
+ };
+ public static final AtomicBoolean DEFAULT_NOT_STARTED = new AtomicBoolean(false);
+
private final MailQueue queue;
private final RemoteDeliveryConfiguration configuration;
private final Metric outgoingMailsMetric;
@@ -40,17 +51,26 @@ public class DeliveryRunnable implements Runnable {
private final Bouncer bouncer;
private final MailDelivrer mailDelivrer;
private final VolatileIsDestroyed volatileIsDestroyed;
+ private final Supplier<Date> dateSupplier;
public DeliveryRunnable(MailQueue queue, RemoteDeliveryConfiguration configuration, DNSService dnsServer, Metric outgoingMailsMetric,
Logger logger, MailetContext mailetContext, VolatileIsDestroyed volatileIsDestroyed) {
+ this(queue, configuration, outgoingMailsMetric, logger, new Bouncer(configuration, mailetContext, logger),
+ new MailDelivrer(configuration, new MailDelivrerToHost(configuration, mailetContext, logger), dnsServer, logger),
+ volatileIsDestroyed, CURRENT_DATE_SUPPLIER);
+ }
+
+ @VisibleForTesting
+ DeliveryRunnable(MailQueue queue, RemoteDeliveryConfiguration configuration, Metric outgoingMailsMetric, Logger logger, Bouncer bouncer,
+ MailDelivrer mailDelivrer, VolatileIsDestroyed volatileIsDestroyed, Supplier<Date> dateSupplier) {
this.queue = queue;
this.configuration = configuration;
this.outgoingMailsMetric = outgoingMailsMetric;
this.logger = logger;
+ this.bouncer = bouncer;
+ this.mailDelivrer = mailDelivrer;
this.volatileIsDestroyed = volatileIsDestroyed;
- this.bouncer = new Bouncer(configuration, mailetContext, logger);
- MailDelivrerToHost mailDelivrerToHost = new MailDelivrerToHost(configuration, mailetContext, logger);
- this.mailDelivrer = new MailDelivrer(configuration, mailDelivrerToHost, dnsServer, logger);
+ this.dateSupplier = dateSupplier;
}
@Override
@@ -98,7 +118,8 @@ public class DeliveryRunnable implements Runnable {
}
}
- private void attemptDelivery(Mail mail) throws MailQueue.MailQueueException {
+ @VisibleForTesting
+ void attemptDelivery(Mail mail) throws MailQueue.MailQueueException {
ExecutionResult executionResult = mailDelivrer.deliver(mail);
switch (executionResult.getExecutionState()) {
case SUCCESS:
@@ -117,7 +138,7 @@ public class DeliveryRunnable implements Runnable {
if (!mail.getState().equals(Mail.ERROR)) {
mail.setState(Mail.ERROR);
DeliveryRetriesHelper.initRetries(mail);
- mail.setLastUpdated(new Date());
+ mail.setLastUpdated(dateSupplier.get());
}
int retries = DeliveryRetriesHelper.retrieveRetries(mail);
@@ -132,7 +153,7 @@ public class DeliveryRunnable implements Runnable {
private void reAttemptDelivery(Mail mail, int retries) throws MailQueue.MailQueueException {
logger.debug("Storing message " + mail.getName() + " into outgoing after " + retries + " retries");
DeliveryRetriesHelper.incrementRetries(mail);
- mail.setLastUpdated(new Date());
+ mail.setLastUpdated(dateSupplier.get());
// Something happened that will delay delivery. Store it back in the retry repository.
long delay = getNextDelay(DeliveryRetriesHelper.retrieveRetries(mail));
http://git-wip-us.apache.org/repos/asf/james-project/blob/fc1b1d3e/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/remoteDelivery/DeliveryRunnableTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/remoteDelivery/DeliveryRunnableTest.java b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/remoteDelivery/DeliveryRunnableTest.java
new file mode 100644
index 0000000..1bfec0d
--- /dev/null
+++ b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/remoteDelivery/DeliveryRunnableTest.java
@@ -0,0 +1,249 @@
+/****************************************************************
+ * 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.transport.mailets.remoteDelivery;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.james.domainlist.api.DomainList;
+import org.apache.james.metrics.api.Metric;
+import org.apache.james.queue.api.MailQueue;
+import org.apache.mailet.Mail;
+import org.apache.mailet.base.test.FakeMail;
+import org.apache.mailet.base.test.FakeMailetConfig;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Supplier;
+
+public class DeliveryRunnableTest {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DeliveryRunnableTest.class);
+ public static final Date FIXED_DATE = new Date(1159599194961L);
+ public static final Supplier<Date> FIXED_DATE_SUPPLIER = new Supplier<Date>() {
+ @Override
+ public Date get() {
+ return FIXED_DATE;
+ }
+ };
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private DeliveryRunnable testee;
+ private Metric outgoingMailsMetric;
+ private Bouncer bouncer;
+ private MailDelivrer mailDelivrer;
+ private MailQueue mailQueue;
+
+ @Before
+ public void setUp() {
+ FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+ .setProperty(RemoteDeliveryConfiguration.DELIVERY_THREADS, "1")
+ .setProperty(RemoteDeliveryConfiguration.DEBUG, "true")
+ .setProperty(RemoteDeliveryConfiguration.DELAY_TIME, "1000,2000,3000,4000,5000")
+ .build();
+
+ RemoteDeliveryConfiguration configuration = new RemoteDeliveryConfiguration(mailetConfig, mock(DomainList.class));
+ outgoingMailsMetric = mock(Metric.class);
+ bouncer = mock(Bouncer.class);
+ mailDelivrer = mock(MailDelivrer.class);
+ mailQueue = mock(MailQueue.class);
+ testee = new DeliveryRunnable(mailQueue, configuration, outgoingMailsMetric, LOGGER, bouncer, mailDelivrer, DeliveryRunnable.DEFAULT_NOT_STARTED, FIXED_DATE_SUPPLIER);
+ }
+
+ @Test
+ public void deliverySuccessShouldIncrementMetric() throws Exception {
+ FakeMail fakeMail = FakeMail.defaultFakeMail();
+ when(mailDelivrer.deliver(fakeMail)).thenReturn(ExecutionResult.success());
+
+ testee.attemptDelivery(fakeMail);
+
+ verify(outgoingMailsMetric).increment();
+ verifyNoMoreInteractions(outgoingMailsMetric);
+ }
+
+ @Test
+ public void deliveryPermanentFailureShouldBounceTheMail() throws Exception {
+ FakeMail fakeMail = FakeMail.defaultFakeMail();
+ Exception exception = new Exception();
+ when(mailDelivrer.deliver(fakeMail)).thenReturn(ExecutionResult.permanentFailure(exception));
+
+ testee.attemptDelivery(fakeMail);
+
+ verify(bouncer).bounce(fakeMail, exception);
+ verifyNoMoreInteractions(bouncer);
+ }
+
+ @Test
+ public void deliveryPermanentFailureShouldNotIncrementDeliveryMetric() throws Exception {
+ FakeMail fakeMail = FakeMail.defaultFakeMail();
+ Exception exception = new Exception();
+ when(mailDelivrer.deliver(fakeMail)).thenReturn(ExecutionResult.permanentFailure(exception));
+
+ testee.attemptDelivery(fakeMail);
+
+ verifyNoMoreInteractions(outgoingMailsMetric);
+ }
+
+ @Test
+ public void deliveryTemporaryFailureShouldNotIncrementDeliveryMetric() throws Exception {
+ FakeMail fakeMail = FakeMail.builder().state(Mail.DEFAULT).build();
+ Exception exception = new Exception();
+ when(mailDelivrer.deliver(fakeMail)).thenReturn(ExecutionResult.temporaryFailure(exception));
+
+ testee.attemptDelivery(fakeMail);
+
+ verifyNoMoreInteractions(outgoingMailsMetric);
+ }
+
+ @Test
+ public void deliveryTemporaryFailureShouldFailOnMailsWithoutState() throws Exception {
+ FakeMail fakeMail = FakeMail.defaultFakeMail();
+ Exception exception = new Exception();
+ when(mailDelivrer.deliver(fakeMail)).thenReturn(ExecutionResult.temporaryFailure(exception));
+
+ expectedException.expect(NullPointerException.class);
+
+ testee.attemptDelivery(fakeMail);
+ }
+
+ @Test
+ public void deliveryTemporaryFailureShouldRetryDelivery() throws Exception {
+ FakeMail fakeMail = FakeMail.builder().state(Mail.DEFAULT).build();
+ Exception exception = new Exception();
+ when(mailDelivrer.deliver(fakeMail)).thenReturn(ExecutionResult.temporaryFailure(exception));
+
+ testee.attemptDelivery(fakeMail);
+
+ verify(mailQueue).enQueue(FakeMail.builder()
+ .attribute(DeliveryRetriesHelper.DELIVERY_RETRY_COUNT, 1)
+ .state(Mail.ERROR)
+ .lastUpdated(FIXED_DATE)
+ .build(),
+ 1000,
+ TimeUnit.MILLISECONDS);
+ verifyNoMoreInteractions(mailQueue);
+ }
+
+ @Test
+ public void deliveryTemporaryFailureShouldRetryDeliveryWithRightDelay() throws Exception {
+ FakeMail fakeMail = FakeMail.builder()
+ .state(Mail.ERROR)
+ .attribute(DeliveryRetriesHelper.DELIVERY_RETRY_COUNT, 2)
+ .build();
+ Exception exception = new Exception();
+ when(mailDelivrer.deliver(fakeMail)).thenReturn(ExecutionResult.temporaryFailure(exception));
+
+ testee.attemptDelivery(fakeMail);
+
+ verify(mailQueue).enQueue(FakeMail.builder()
+ .attribute(DeliveryRetriesHelper.DELIVERY_RETRY_COUNT, 3)
+ .state(Mail.ERROR)
+ .lastUpdated(FIXED_DATE)
+ .build(),
+ 3000,
+ TimeUnit.MILLISECONDS);
+ verifyNoMoreInteractions(mailQueue);
+ }
+
+ @Test
+ public void deliveryTemporaryFailureShouldRetryDeliveryOnMaximumRetryNumber() throws Exception {
+ FakeMail fakeMail = FakeMail.builder()
+ .state(Mail.ERROR)
+ .attribute(DeliveryRetriesHelper.DELIVERY_RETRY_COUNT, 4)
+ .build();
+ Exception exception = new Exception();
+ when(mailDelivrer.deliver(fakeMail)).thenReturn(ExecutionResult.temporaryFailure(exception));
+
+ testee.attemptDelivery(fakeMail);
+
+ verify(mailQueue).enQueue(FakeMail.builder()
+ .attribute(DeliveryRetriesHelper.DELIVERY_RETRY_COUNT, 5)
+ .state(Mail.ERROR)
+ .lastUpdated(FIXED_DATE)
+ .build(),
+ 5000,
+ TimeUnit.MILLISECONDS);
+ verifyNoMoreInteractions(mailQueue);
+ }
+
+ @Test
+ public void deliveryTemporaryFailureShouldNotRetryDeliveryOverMaximumRetryNumber() throws Exception {
+ FakeMail fakeMail = FakeMail.builder()
+ .state(Mail.ERROR)
+ .attribute(DeliveryRetriesHelper.DELIVERY_RETRY_COUNT, 5)
+ .build();
+ Exception exception = new Exception();
+ when(mailDelivrer.deliver(fakeMail)).thenReturn(ExecutionResult.temporaryFailure(exception));
+
+ testee.attemptDelivery(fakeMail);
+
+ verifyNoMoreInteractions(mailQueue);
+ }
+
+ @Test
+ public void deliveryTemporaryFailureShouldBounceWhenRetryExceeded() throws Exception {
+ FakeMail fakeMail = FakeMail.builder()
+ .state(Mail.ERROR)
+ .attribute(DeliveryRetriesHelper.DELIVERY_RETRY_COUNT, 5)
+ .build();
+ Exception exception = new Exception("");
+ when(mailDelivrer.deliver(fakeMail)).thenReturn(ExecutionResult.temporaryFailure(exception));
+
+ testee.attemptDelivery(fakeMail);
+
+ verify(bouncer).bounce(eq(fakeMail), any(Exception.class));
+ verifyNoMoreInteractions(bouncer);
+ }
+
+ @Test
+ public void deliveryTemporaryFailureShouldResetDeliveryCountOnNonErrorState() throws Exception {
+ FakeMail fakeMail = FakeMail.builder()
+ .state(Mail.DEFAULT)
+ .attribute(DeliveryRetriesHelper.DELIVERY_RETRY_COUNT, 5)
+ .build();
+ Exception exception = new Exception();
+ when(mailDelivrer.deliver(fakeMail)).thenReturn(ExecutionResult.temporaryFailure(exception));
+
+ testee.attemptDelivery(fakeMail);
+
+ verify(mailQueue).enQueue(FakeMail.builder()
+ .attribute(DeliveryRetriesHelper.DELIVERY_RETRY_COUNT, 1)
+ .state(Mail.ERROR)
+ .lastUpdated(FIXED_DATE)
+ .build(),
+ 1000,
+ TimeUnit.MILLISECONDS);
+ verifyNoMoreInteractions(mailQueue);
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org