blob: 02236010c2526e0da435af2eca9e98e7b410d403 [file] [log] [blame]
/****************************************************************
* 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.rspamd.task;
import static org.apache.james.rspamd.RspamdExtension.PASSWORD;
import static org.apache.james.rspamd.task.FeedSpamToRspamdTask.SPAM_MAILBOX_NAME;
import static org.apache.james.rspamd.task.RunningOptions.ALL_MESSAGES;
import static org.apache.james.rspamd.task.RunningOptions.DEFAULT_MESSAGES_PER_SECOND;
import static org.apache.james.rspamd.task.RunningOptions.DEFAULT_SAMPLING_PROBABILITY;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import java.io.ByteArrayInputStream;
import java.net.URI;
import java.nio.ByteBuffer;
import java.time.Clock;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;
import jakarta.mail.Flags;
import org.apache.james.core.Domain;
import org.apache.james.core.Username;
import org.apache.james.domainlist.api.DomainList;
import org.apache.james.junit.categories.Unstable;
import org.apache.james.mailbox.MailboxSession;
import org.apache.james.mailbox.MessageIdManager;
import org.apache.james.mailbox.exception.MailboxException;
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.store.MailboxSessionMapperFactory;
import org.apache.james.rspamd.RspamdExtension;
import org.apache.james.rspamd.client.RspamdClientConfiguration;
import org.apache.james.rspamd.client.RspamdHttpClient;
import org.apache.james.task.Task;
import org.apache.james.user.api.UsersRepository;
import org.apache.james.user.memory.MemoryUsersRepository;
import org.apache.james.utils.UpdatableTickingClock;
import org.assertj.core.api.SoftAssertions;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.mockito.Mockito;
import org.mockserver.integration.ClientAndServer;
import org.mockserver.model.Delay;
import org.mockserver.model.HttpRequest;
import org.mockserver.model.HttpResponse;
import org.reactivestreams.Publisher;
import com.github.fge.lambdas.Throwing;
import reactor.core.publisher.Mono;
@Tag(Unstable.TAG)
public class FeedSpamToRspamdTaskTest {
@RegisterExtension
static RspamdExtension rspamdExtension = new RspamdExtension();
public static final Domain DOMAIN = Domain.of("domain.tld");
public static final Username CEDRIC = Username.fromLocalPartWithDomain("cedric", DOMAIN);
public static final Username BOB = Username.fromLocalPartWithDomain("bob", DOMAIN);
public static final Username ALICE = Username.fromLocalPartWithDomain("alice", DOMAIN);
public static final MailboxPath BOB_SPAM_MAILBOX = MailboxPath.forUser(BOB, SPAM_MAILBOX_NAME);
public static final MailboxPath ALICE_SPAM_MAILBOX = MailboxPath.forUser(ALICE, SPAM_MAILBOX_NAME);
public static final long THREE_DAYS_IN_SECOND = 259200;
public static final long TWO_DAYS_IN_SECOND = 172800;
public static final long ONE_DAY_IN_SECOND = 86400;
public static final Instant NOW = ZonedDateTime.now().toInstant();
static ClientAndServer mockServer = null;
static class TestRspamdHttpClient extends RspamdHttpClient {
private final AtomicInteger hitCounter;
public TestRspamdHttpClient(RspamdClientConfiguration configuration) {
super(configuration);
this.hitCounter = new AtomicInteger(0);
}
@Override
public Mono<Void> reportAsSpam(Publisher<ByteBuffer> content, Options options) {
return Mono.from(content)
.doOnNext(e -> hitCounter.incrementAndGet())
.then();
}
public int getHitCounter() {
return hitCounter.get();
}
}
private InMemoryMailboxManager mailboxManager;
private MessageIdManager messageIdManager;
private MailboxSessionMapperFactory mapperFactory;
private UsersRepository usersRepository;
private Clock clock;
private RspamdHttpClient client;
private RspamdClientConfiguration rspamdConfiguration;
private FeedSpamToRspamdTask task;
private UpdatableTickingClock saveDateClock;
@BeforeEach
void setup() throws Exception {
InMemoryIntegrationResources inMemoryIntegrationResources = InMemoryIntegrationResources.defaultResources();
mailboxManager = inMemoryIntegrationResources.getMailboxManager();
saveDateClock = (UpdatableTickingClock) mailboxManager.getClock();
DomainList domainList = mock(DomainList.class);
Mockito.when(domainList.containsDomain(any())).thenReturn(true);
usersRepository = MemoryUsersRepository.withVirtualHosting(domainList);
usersRepository.addUser(BOB, "anyPassword");
usersRepository.addUser(ALICE, "anyPassword");
mailboxManager.createMailbox(BOB_SPAM_MAILBOX, mailboxManager.createSystemSession(BOB));
mailboxManager.createMailbox(ALICE_SPAM_MAILBOX, mailboxManager.createSystemSession(ALICE));
clock = new UpdatableTickingClock(NOW);
rspamdConfiguration = new RspamdClientConfiguration(rspamdExtension.getBaseUrl(), PASSWORD, Optional.empty(), true);
client = new RspamdHttpClient(rspamdConfiguration);
messageIdManager = inMemoryIntegrationResources.getMessageIdManager();
mapperFactory = mailboxManager.getMapperFactory();
task = new FeedSpamToRspamdTask(mailboxManager, usersRepository, messageIdManager, mapperFactory, client, RunningOptions.DEFAULT, clock, rspamdConfiguration);
}
@AfterEach
void afterEach() {
if (mockServer != null) {
mockServer.stop();
}
}
@Test
void shouldReturnDefaultInformationWhenDataIsEmpty() {
Task.Result result = task.run();
assertThat(result).isEqualTo(Task.Result.COMPLETED);
assertThat(task.snapshot())
.isEqualTo(FeedSpamToRspamdTask.Context.Snapshot.builder()
.spamMessageCount(0)
.reportedSpamMessageCount(0)
.errorCount(0)
.build());
}
@Test
void taskShouldReportAllSpamMessagesOfAllUsersByDefault() throws MailboxException {
appendSpamMessage(BOB_SPAM_MAILBOX, Date.from(NOW));
appendSpamMessage(ALICE_SPAM_MAILBOX, Date.from(NOW));
Task.Result result = task.run();
assertThat(result).isEqualTo(Task.Result.COMPLETED);
assertThat(task.snapshot())
.isEqualTo(FeedSpamToRspamdTask.Context.Snapshot.builder()
.spamMessageCount(2)
.reportedSpamMessageCount(2)
.errorCount(0)
.build());
}
@Test
void taskShouldHitToRspamdServerWhenLearnSpam() throws MailboxException {
appendSpamMessage(BOB_SPAM_MAILBOX, Date.from(NOW));
appendSpamMessage(ALICE_SPAM_MAILBOX, Date.from(NOW));
TestRspamdHttpClient rspamdHttpClient = new TestRspamdHttpClient(new RspamdClientConfiguration(rspamdExtension.getBaseUrl(), PASSWORD, Optional.empty()));
FeedSpamToRspamdTask feedSpamToRspamdTask = new FeedSpamToRspamdTask(mailboxManager, usersRepository, messageIdManager, mapperFactory, rspamdHttpClient, RunningOptions.DEFAULT, clock, rspamdConfiguration);
Task.Result result = feedSpamToRspamdTask.run();
assertThat(result).isEqualTo(Task.Result.COMPLETED);
assertThat(rspamdHttpClient.getHitCounter()).isEqualTo(2);
}
@Test
void taskShouldReportSpamMessageInPeriod() throws MailboxException {
RunningOptions runningOptions = new RunningOptions(Optional.of(TWO_DAYS_IN_SECOND),
DEFAULT_MESSAGES_PER_SECOND, DEFAULT_SAMPLING_PROBABILITY, ALL_MESSAGES);
task = new FeedSpamToRspamdTask(mailboxManager, usersRepository, messageIdManager, mapperFactory, client, runningOptions, clock, rspamdConfiguration);
appendSpamMessage(BOB_SPAM_MAILBOX, Date.from(NOW.minusSeconds(ONE_DAY_IN_SECOND)));
Task.Result result = task.run();
assertThat(result).isEqualTo(Task.Result.COMPLETED);
assertThat(task.snapshot())
.isEqualTo(FeedSpamToRspamdTask.Context.Snapshot.builder()
.spamMessageCount(1)
.reportedSpamMessageCount(1)
.errorCount(0)
.build());
}
@Test
void taskShouldNotReportSpamMessageNotInPeriod() throws MailboxException {
RunningOptions runningOptions = new RunningOptions(Optional.of(TWO_DAYS_IN_SECOND),
DEFAULT_MESSAGES_PER_SECOND, DEFAULT_SAMPLING_PROBABILITY, ALL_MESSAGES);
task = new FeedSpamToRspamdTask(mailboxManager, usersRepository, messageIdManager, mapperFactory, client, runningOptions, clock, rspamdConfiguration);
saveDateClock.setInstant(NOW.minusSeconds(THREE_DAYS_IN_SECOND));
appendSpamMessage(BOB_SPAM_MAILBOX, Date.from(NOW.minusSeconds(THREE_DAYS_IN_SECOND)));
Task.Result result = task.run();
assertThat(result).isEqualTo(Task.Result.COMPLETED);
assertThat(task.snapshot())
.isEqualTo(FeedSpamToRspamdTask.Context.Snapshot.builder()
.spamMessageCount(0)
.reportedSpamMessageCount(0)
.errorCount(0)
.build());
}
@Test
void taskShouldNotFailWhenMissingSpamMailbox() throws Exception {
RunningOptions runningOptions = new RunningOptions(Optional.of(TWO_DAYS_IN_SECOND),
DEFAULT_MESSAGES_PER_SECOND, DEFAULT_SAMPLING_PROBABILITY, ALL_MESSAGES);
task = new FeedSpamToRspamdTask(mailboxManager, usersRepository, messageIdManager, mapperFactory, client, runningOptions, clock, rspamdConfiguration);
usersRepository.addUser(CEDRIC, "kdvebv");
Task.Result result = task.run();
assertThat(result).isEqualTo(Task.Result.COMPLETED);
}
@Test
void taskShouldCountAndReportOnlySpamMessagesInPeriodBasedOnSaveDate() throws MailboxException {
Date nowInternalDate = Date.from(NOW);
saveDateClock.setInstant(NOW.minusSeconds(THREE_DAYS_IN_SECOND));
appendSpamMessage(BOB_SPAM_MAILBOX, nowInternalDate);
saveDateClock.setInstant(NOW.minusSeconds(ONE_DAY_IN_SECOND));
appendSpamMessage(BOB_SPAM_MAILBOX, nowInternalDate);
RunningOptions runningOptions = new RunningOptions(Optional.of(TWO_DAYS_IN_SECOND),
DEFAULT_MESSAGES_PER_SECOND, DEFAULT_SAMPLING_PROBABILITY, ALL_MESSAGES);
task = new FeedSpamToRspamdTask(mailboxManager, usersRepository, messageIdManager, mapperFactory, client, runningOptions, clock, rspamdConfiguration);
Task.Result result = task.run();
assertThat(result).isEqualTo(Task.Result.COMPLETED);
assertThat(task.snapshot())
.isEqualTo(FeedSpamToRspamdTask.Context.Snapshot.builder()
.spamMessageCount(1)
.reportedSpamMessageCount(1)
.errorCount(0)
.build());
}
@Test
void taskWithSamplingProbabilityIsZeroShouldReportNonSpamMessage() {
RunningOptions runningOptions = new RunningOptions(Optional.empty(),
DEFAULT_MESSAGES_PER_SECOND, 0, ALL_MESSAGES);
task = new FeedSpamToRspamdTask(mailboxManager, usersRepository, messageIdManager, mapperFactory, client, runningOptions, clock, rspamdConfiguration);
IntStream.range(0, 10)
.forEach(Throwing.intConsumer(any -> appendSpamMessage(BOB_SPAM_MAILBOX, Date.from(NOW.minusSeconds(ONE_DAY_IN_SECOND)))));
Task.Result result = task.run();
assertThat(result).isEqualTo(Task.Result.COMPLETED);
assertThat(task.snapshot())
.isEqualTo(FeedSpamToRspamdTask.Context.Snapshot.builder()
.spamMessageCount(10)
.reportedSpamMessageCount(0)
.errorCount(0)
.build());
}
@Test
void taskWithDefaultSamplingProbabilityShouldReportAllSpamMessages() {
IntStream.range(0, 10)
.forEach(Throwing.intConsumer(any -> appendSpamMessage(BOB_SPAM_MAILBOX, Date.from(NOW.minusSeconds(ONE_DAY_IN_SECOND)))));
Task.Result result = task.run();
assertThat(result).isEqualTo(Task.Result.COMPLETED);
assertThat(task.snapshot())
.isEqualTo(FeedSpamToRspamdTask.Context.Snapshot.builder()
.spamMessageCount(10)
.reportedSpamMessageCount(10)
.errorCount(0)
.build());
}
@Test
void taskWithVeryLowSamplingProbabilityShouldReportNotAllSpamMessages() {
RunningOptions runningOptions = new RunningOptions(Optional.empty(),
DEFAULT_MESSAGES_PER_SECOND, 0.01, ALL_MESSAGES);
task = new FeedSpamToRspamdTask(mailboxManager, usersRepository, messageIdManager, mapperFactory, client, runningOptions, clock, rspamdConfiguration);
IntStream.range(0, 10)
.forEach(Throwing.intConsumer(any -> appendSpamMessage(BOB_SPAM_MAILBOX, Date.from(NOW.minusSeconds(ONE_DAY_IN_SECOND)))));
Task.Result result = task.run();
SoftAssertions.assertSoftly(softly -> {
assertThat(result).isEqualTo(Task.Result.COMPLETED);
assertThat(task.snapshot().getSpamMessageCount()).isEqualTo(10);
assertThat(task.snapshot().getReportedSpamMessageCount()).isLessThan(10);
assertThat(task.snapshot().getErrorCount()).isZero();
});
}
@Test
void taskWithVeryHighSamplingProbabilityShouldReportMoreThanZeroMessage() {
RunningOptions runningOptions = new RunningOptions(Optional.empty(),
DEFAULT_MESSAGES_PER_SECOND, 0.99, ALL_MESSAGES);
task = new FeedSpamToRspamdTask(mailboxManager, usersRepository, messageIdManager, mapperFactory, client, runningOptions, clock, rspamdConfiguration);
IntStream.range(0, 10)
.forEach(Throwing.intConsumer(any -> appendSpamMessage(BOB_SPAM_MAILBOX, Date.from(NOW.minusSeconds(ONE_DAY_IN_SECOND)))));
Task.Result result = task.run();
SoftAssertions.assertSoftly(softly -> {
assertThat(result).isEqualTo(Task.Result.COMPLETED);
assertThat(task.snapshot().getSpamMessageCount()).isEqualTo(10);
assertThat(task.snapshot().getReportedSpamMessageCount()).isPositive();
assertThat(task.snapshot().getErrorCount()).isZero();
});
}
@Test
void taskWithAverageSamplingProbabilityShouldReportSomeMessages() {
RunningOptions runningOptions = new RunningOptions(Optional.empty(),
DEFAULT_MESSAGES_PER_SECOND, 0.5, ALL_MESSAGES);
task = new FeedSpamToRspamdTask(mailboxManager, usersRepository, messageIdManager, mapperFactory, client, runningOptions, clock, rspamdConfiguration);
IntStream.range(0, 10)
.forEach(Throwing.intConsumer(any -> appendSpamMessage(BOB_SPAM_MAILBOX, Date.from(NOW.minusSeconds(ONE_DAY_IN_SECOND)))));
Task.Result result = task.run();
SoftAssertions.assertSoftly(softly -> {
assertThat(result).isEqualTo(Task.Result.COMPLETED);
assertThat(task.snapshot().getSpamMessageCount()).isEqualTo(10);
assertThat(task.snapshot().getReportedSpamMessageCount()).isBetween(1L, 9L); // skip 0 and 10 cases cause their probability is very low (0.5^10)
assertThat(task.snapshot().getErrorCount()).isZero();
});
}
@Test
void shouldReportUnclassifiedWhenClassifiedAsSpamIsTrue() throws Exception {
RunningOptions runningOptions = new RunningOptions(Optional.empty(),
DEFAULT_MESSAGES_PER_SECOND, 1.0, Optional.of(true));
task = new FeedSpamToRspamdTask(mailboxManager, usersRepository, messageIdManager, mapperFactory, client, runningOptions, clock, rspamdConfiguration);
appendMessage(BOB_SPAM_MAILBOX, Date.from(NOW.minusSeconds(ONE_DAY_IN_SECOND)), "Unrelated: at all");
Task.Result result = task.run();
SoftAssertions.assertSoftly(softly -> {
assertThat(result).isEqualTo(Task.Result.COMPLETED);
assertThat(task.snapshot().getSpamMessageCount()).isEqualTo(1);
assertThat(task.snapshot().getReportedSpamMessageCount()).isEqualTo(1);
assertThat(task.snapshot().getErrorCount()).isZero();
});
}
@Test
void shouldNotReportHamWhenClassifiedAsSpamIsTrue() throws Exception {
RunningOptions runningOptions = new RunningOptions(Optional.empty(),
DEFAULT_MESSAGES_PER_SECOND, 1.0, Optional.of(true));
task = new FeedSpamToRspamdTask(mailboxManager, usersRepository, messageIdManager, mapperFactory, client, runningOptions, clock, rspamdConfiguration);
appendMessage(BOB_SPAM_MAILBOX, Date.from(NOW.minusSeconds(ONE_DAY_IN_SECOND)), "org.apache.james.rspamd.flag: NO");
Task.Result result = task.run();
SoftAssertions.assertSoftly(softly -> {
assertThat(result).isEqualTo(Task.Result.COMPLETED);
assertThat(task.snapshot().getSpamMessageCount()).isEqualTo(1);
assertThat(task.snapshot().getReportedSpamMessageCount()).isZero();
assertThat(task.snapshot().getErrorCount()).isZero();
});
}
@Test
void shouldReportSpamWhenClassifiedAsSpamIsTrue() throws Exception {
RunningOptions runningOptions = new RunningOptions(Optional.empty(),
DEFAULT_MESSAGES_PER_SECOND, 1.0, Optional.of(true));
task = new FeedSpamToRspamdTask(mailboxManager, usersRepository, messageIdManager, mapperFactory, client, runningOptions, clock, rspamdConfiguration);
appendMessage(BOB_SPAM_MAILBOX, Date.from(NOW.minusSeconds(ONE_DAY_IN_SECOND)), "org.apache.james.rspamd.flag: YES");
Task.Result result = task.run();
SoftAssertions.assertSoftly(softly -> {
assertThat(result).isEqualTo(Task.Result.COMPLETED);
assertThat(task.snapshot().getSpamMessageCount()).isEqualTo(1);
assertThat(task.snapshot().getReportedSpamMessageCount()).isEqualTo(1);
assertThat(task.snapshot().getErrorCount()).isZero();
});
}
@Test
void shouldReportUnclassifiedWhenClassifiedAsSpamIsOmited() throws Exception {
RunningOptions runningOptions = new RunningOptions(Optional.empty(),
DEFAULT_MESSAGES_PER_SECOND, 1.0, Optional.empty());
task = new FeedSpamToRspamdTask(mailboxManager, usersRepository, messageIdManager, mapperFactory, client, runningOptions, clock, rspamdConfiguration);
appendMessage(BOB_SPAM_MAILBOX, Date.from(NOW.minusSeconds(ONE_DAY_IN_SECOND)), "Unrelated: at all");
Task.Result result = task.run();
SoftAssertions.assertSoftly(softly -> {
assertThat(result).isEqualTo(Task.Result.COMPLETED);
assertThat(task.snapshot().getSpamMessageCount()).isEqualTo(1);
assertThat(task.snapshot().getReportedSpamMessageCount()).isEqualTo(1);
assertThat(task.snapshot().getErrorCount()).isZero();
});
}
@Test
void shouldReportHamWhenClassifiedAsSpamIsOmited() throws Exception {
RunningOptions runningOptions = new RunningOptions(Optional.empty(),
DEFAULT_MESSAGES_PER_SECOND, 1.0, Optional.empty());
task = new FeedSpamToRspamdTask(mailboxManager, usersRepository, messageIdManager, mapperFactory, client, runningOptions, clock, rspamdConfiguration);
appendMessage(BOB_SPAM_MAILBOX, Date.from(NOW.minusSeconds(ONE_DAY_IN_SECOND)), "org.apache.james.rspamd.flag: NO");
Task.Result result = task.run();
SoftAssertions.assertSoftly(softly -> {
assertThat(result).isEqualTo(Task.Result.COMPLETED);
assertThat(task.snapshot().getSpamMessageCount()).isEqualTo(1);
assertThat(task.snapshot().getReportedSpamMessageCount()).isEqualTo(1);
assertThat(task.snapshot().getErrorCount()).isZero();
});
}
@Test
void shouldNotReportSpamWhenClassifiedAsSpamIsOmited() throws Exception {
RunningOptions runningOptions = new RunningOptions(Optional.empty(),
DEFAULT_MESSAGES_PER_SECOND, 1.0, Optional.empty());
task = new FeedSpamToRspamdTask(mailboxManager, usersRepository, messageIdManager, mapperFactory, client, runningOptions, clock, rspamdConfiguration);
appendMessage(BOB_SPAM_MAILBOX, Date.from(NOW.minusSeconds(ONE_DAY_IN_SECOND)), "org.apache.james.rspamd.flag: YES");
Task.Result result = task.run();
SoftAssertions.assertSoftly(softly -> {
assertThat(result).isEqualTo(Task.Result.COMPLETED);
assertThat(task.snapshot().getSpamMessageCount()).isEqualTo(1);
assertThat(task.snapshot().getReportedSpamMessageCount()).isEqualTo(1);
assertThat(task.snapshot().getErrorCount()).isZero();
});
}
@Test
void shouldReportUnclassifiedWhenClassifiedAsSpamIsFalse() throws Exception {
RunningOptions runningOptions = new RunningOptions(Optional.empty(),
DEFAULT_MESSAGES_PER_SECOND, 1.0, Optional.of(false));
task = new FeedSpamToRspamdTask(mailboxManager, usersRepository, messageIdManager, mapperFactory, client, runningOptions, clock, rspamdConfiguration);
appendMessage(BOB_SPAM_MAILBOX, Date.from(NOW.minusSeconds(ONE_DAY_IN_SECOND)), "Unrelated: at all");
Task.Result result = task.run();
SoftAssertions.assertSoftly(softly -> {
assertThat(result).isEqualTo(Task.Result.COMPLETED);
assertThat(task.snapshot().getSpamMessageCount()).isEqualTo(1);
assertThat(task.snapshot().getReportedSpamMessageCount()).isEqualTo(1);
assertThat(task.snapshot().getErrorCount()).isZero();
});
}
@Test
void shouldReportHamWhenClassifiedAsSpamIsFalse() throws Exception {
RunningOptions runningOptions = new RunningOptions(Optional.empty(),
DEFAULT_MESSAGES_PER_SECOND, 1.0, Optional.of(false));
task = new FeedSpamToRspamdTask(mailboxManager, usersRepository, messageIdManager, mapperFactory, client, runningOptions, clock, rspamdConfiguration);
appendMessage(BOB_SPAM_MAILBOX, Date.from(NOW.minusSeconds(ONE_DAY_IN_SECOND)), "org.apache.james.rspamd.flag: NO");
Task.Result result = task.run();
SoftAssertions.assertSoftly(softly -> {
assertThat(result).isEqualTo(Task.Result.COMPLETED);
assertThat(task.snapshot().getSpamMessageCount()).isEqualTo(1);
assertThat(task.snapshot().getReportedSpamMessageCount()).isEqualTo(1);
assertThat(task.snapshot().getErrorCount()).isZero();
});
}
@Test
void shouldNotReportSpamWhenClassifiedAsSpamIsFalse() throws Exception {
RunningOptions runningOptions = new RunningOptions(Optional.empty(),
DEFAULT_MESSAGES_PER_SECOND, 1.0, Optional.of(false));
task = new FeedSpamToRspamdTask(mailboxManager, usersRepository, messageIdManager, mapperFactory, client, runningOptions, clock, rspamdConfiguration);
appendMessage(BOB_SPAM_MAILBOX, Date.from(NOW.minusSeconds(ONE_DAY_IN_SECOND)), "org.apache.james.rspamd.flag: YES");
Task.Result result = task.run();
SoftAssertions.assertSoftly(softly -> {
assertThat(result).isEqualTo(Task.Result.COMPLETED);
assertThat(task.snapshot().getSpamMessageCount()).isEqualTo(1);
assertThat(task.snapshot().getReportedSpamMessageCount()).isZero();
assertThat(task.snapshot().getErrorCount()).isZero();
});
}
@Test
void shouldErrorCountWhenRspamdTimeout() throws Exception {
mockServer = ClientAndServer.startClientAndServer(0);
mockServer
.when(HttpRequest.request().withPath("/learnspam"))
.respond(httpRequest -> HttpResponse.response().withStatusCode(200), Delay.delay(TimeUnit.SECONDS, 10));
RspamdHttpClient httpClient = new RspamdHttpClient(new RspamdClientConfiguration(new URI(String.format("http://localhost:%s", mockServer.getLocalPort())).toURL(),
PASSWORD, Optional.of(3)));
RunningOptions runningOptions = new RunningOptions(Optional.empty(),
DEFAULT_MESSAGES_PER_SECOND, 1.0, Optional.empty());
task = new FeedSpamToRspamdTask(mailboxManager, usersRepository, messageIdManager, mapperFactory, httpClient, runningOptions, clock, rspamdConfiguration);
appendMessage(BOB_SPAM_MAILBOX, Date.from(NOW.minusSeconds(ONE_DAY_IN_SECOND)), "org.apache.james.rspamd.flag: NO");
Task.Result result = task.run();
SoftAssertions.assertSoftly(softly -> {
assertThat(result).isEqualTo(Task.Result.PARTIAL);
assertThat(task.snapshot().getSpamMessageCount()).isEqualTo(1);
assertThat(task.snapshot().getReportedSpamMessageCount()).isEqualTo(0);
assertThat(task.snapshot().getErrorCount()).isEqualTo(1);
});
}
private void appendSpamMessage(MailboxPath mailboxPath, Date internalDate) throws MailboxException {
MailboxSession session = mailboxManager.createSystemSession(mailboxPath.getUser());
mailboxManager.getMailbox(mailboxPath, session)
.appendMessage(new ByteArrayInputStream(String.format("random content %4.3f", Math.random()).getBytes()),
internalDate,
session,
true,
new Flags());
}
private void appendMessage(MailboxPath mailboxPath, Date internalDate, String header) throws MailboxException {
MailboxSession session = mailboxManager.createSystemSession(mailboxPath.getUser());
mailboxManager.getMailbox(mailboxPath, session)
.appendMessage(new ByteArrayInputStream((header + "\r\n\r\n" + String.format("random content %4.3f", Math.random())).getBytes()),
internalDate,
session,
true,
new Flags());
}
}