Repository: james-project Updated Branches: refs/heads/master 9715af0fe -> 86871e52c
JAMES-1969 Add tests and correct IsOverQuota matcher With many thanks to: Nguyen Thi Mai and Le Thi Huong Lai for their work on Quotas and In memory subscriptions Tran Thi & My Linh for their work on TooMuchLines txc1996 & Van Thanh For improving readability of SMTPAuthIsSuccessfulTest thienan090196 & Tran Thi & My Linh for their tests on RecipientIsLocalTest >From Passerelle Numeriques VietNam Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/86871e52 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/86871e52 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/86871e52 Branch: refs/heads/master Commit: 86871e52c985e971bb79ac0829cec2b380ed0566 Parents: 84fd7f0 Author: benwa <btell...@linagora.com> Authored: Fri Mar 17 15:03:32 2017 +0700 Committer: benwa <btell...@linagora.com> Committed: Wed Mar 29 08:00:16 2017 +0700 ---------------------------------------------------------------------- .../org/apache/james/mailbox/model/Quota.java | 2 + .../james/mailbox/store/quota/QuotaImpl.java | 12 +- .../mailbox/store/quota/QuotaImplTest.java | 27 +++ .../james/transport/matchers/IsOverQuota.java | 52 ++++-- .../transport/matchers/IsOverQuotaTest.java | 183 +++++++++++++++++++ 5 files changed, 258 insertions(+), 18 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/86871e52/mailbox/api/src/main/java/org/apache/james/mailbox/model/Quota.java ---------------------------------------------------------------------- diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Quota.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Quota.java index e0771d8..5e303a3 100644 --- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Quota.java +++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Quota.java @@ -59,4 +59,6 @@ public interface Quota { */ boolean isOverQuota(); + boolean isOverQuotaWithAdditionalValue(long additionalValue); + } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/james-project/blob/86871e52/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/QuotaImpl.java ---------------------------------------------------------------------- diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/QuotaImpl.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/QuotaImpl.java index f142a78..967813e 100644 --- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/QuotaImpl.java +++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/QuotaImpl.java @@ -19,6 +19,8 @@ package org.apache.james.mailbox.store.quota; import com.google.common.base.Objects; +import com.google.common.base.Preconditions; + import org.apache.james.mailbox.model.Quota; public final class QuotaImpl implements Quota{ @@ -58,8 +60,7 @@ public final class QuotaImpl implements Quota{ @Override public boolean isOverQuota() { - return max != UNLIMITED - && used > max; + return isOverQuotaWithAdditionalValue(0); } @Override @@ -81,4 +82,11 @@ public final class QuotaImpl implements Quota{ public int hashCode() { return Objects.hashCode(used, max); } + + @Override + public boolean isOverQuotaWithAdditionalValue(long additionalValue) { + Preconditions.checkArgument(additionalValue >= 0); + return max != UNLIMITED + && used + additionalValue > max; + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/james-project/blob/86871e52/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/QuotaImplTest.java ---------------------------------------------------------------------- diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/QuotaImplTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/QuotaImplTest.java index ad82bd7..3faca34 100644 --- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/QuotaImplTest.java +++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/QuotaImplTest.java @@ -22,10 +22,15 @@ package org.apache.james.mailbox.store.quota; import static org.assertj.core.api.Assertions.assertThat; import org.apache.james.mailbox.model.Quota; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; public class QuotaImplTest { + @Rule + public ExpectedException expectedException = ExpectedException.none(); + @Test public void unlimitedQuotaShouldNotBeOverQuota() { assertThat(QuotaImpl.unlimited().isOverQuota()).isFalse(); @@ -51,4 +56,26 @@ public class QuotaImplTest { assertThat(QuotaImpl.quota(360, 36).isOverQuota()).isTrue(); } + @Test + public void isOverQuotaWithAdditionalValueShouldReturnTrueWhenOverLimit() { + assertThat(QuotaImpl.quota(36, 36).isOverQuotaWithAdditionalValue(1)).isTrue(); + } + + @Test + public void isOverQuotaWithAdditionalValueShouldReturnTrueWhenUnderLimit() { + assertThat(QuotaImpl.quota(34, 36).isOverQuotaWithAdditionalValue(1)).isFalse(); + } + + @Test + public void isOverQuotaWithAdditionalValueShouldReturnFalseWhenAtLimit() { + assertThat(QuotaImpl.quota(36, 36).isOverQuotaWithAdditionalValue(0)).isFalse(); + } + + @Test + public void isOverQuotaWithAdditionalValueShouldThrowOnNegativeValue() { + expectedException.expect(IllegalArgumentException.class); + + QuotaImpl.quota(25, 36).isOverQuotaWithAdditionalValue(-1); + } + } http://git-wip-us.apache.org/repos/asf/james-project/blob/86871e52/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/IsOverQuota.java ---------------------------------------------------------------------- diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/IsOverQuota.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/IsOverQuota.java index 238574c..ba97c78 100644 --- a/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/IsOverQuota.java +++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/IsOverQuota.java @@ -1,3 +1,22 @@ +/**************************************************************** + * 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.matchers; import org.apache.james.mailbox.MailboxManager; @@ -7,6 +26,8 @@ import org.apache.james.mailbox.model.MailboxPath; import org.apache.james.mailbox.model.QuotaRoot; import org.apache.james.mailbox.quota.QuotaManager; import org.apache.james.mailbox.quota.QuotaRootResolver; +import org.apache.james.user.api.UsersRepository; +import org.apache.james.user.api.UsersRepositoryException; import org.apache.mailet.Mail; import org.apache.mailet.MailAddress; import org.apache.mailet.base.GenericMatcher; @@ -22,24 +43,19 @@ import java.util.List; public class IsOverQuota extends GenericMatcher { private static final Logger LOGGER = LoggerFactory.getLogger(IsOverQuota.class); + private static final int SINGLE_EMAIL = 1; - private QuotaRootResolver quotaRootResolver; - private QuotaManager quotaManager; - private MailboxManager mailboxManager; + private final QuotaRootResolver quotaRootResolver; + private final QuotaManager quotaManager; + private final MailboxManager mailboxManager; + private final UsersRepository usersRepository; @Inject - public void setQuotaRootResolver(QuotaRootResolver quotaRootResolver) { + public IsOverQuota(QuotaRootResolver quotaRootResolver, QuotaManager quotaManager, MailboxManager mailboxManager, UsersRepository usersRepository) { this.quotaRootResolver = quotaRootResolver; - } - - @Inject - public void setQuotaManager(QuotaManager quotaManager) { this.quotaManager = quotaManager; - } - - @Inject - public void setMailboxManager(MailboxManager mailboxManager) { this.mailboxManager = mailboxManager; + this.usersRepository = usersRepository; } @Override @@ -47,17 +63,21 @@ public class IsOverQuota extends GenericMatcher { try { List<MailAddress> result = new ArrayList<MailAddress>(); for (MailAddress mailAddress : mail.getRecipients()) { - MailboxSession mailboxSession = mailboxManager.createSystemSession(mailAddress.getLocalPart(), LOGGER); + String userName = usersRepository.getUser(mailAddress); + MailboxSession mailboxSession = mailboxManager.createSystemSession(userName, LOGGER); MailboxPath mailboxPath = MailboxPath.inbox(mailboxSession); QuotaRoot quotaRoot = quotaRootResolver.getQuotaRoot(mailboxPath); - if (quotaManager.getMessageQuota(quotaRoot).isOverQuota() && - quotaManager.getStorageQuota(quotaRoot).isOverQuota()) { + + if (quotaManager.getMessageQuota(quotaRoot).isOverQuotaWithAdditionalValue(SINGLE_EMAIL) || + quotaManager.getStorageQuota(quotaRoot).isOverQuotaWithAdditionalValue(mail.getMessageSize())) { result.add(mailAddress); } } return result; - } catch(MailboxException e) { + } catch (MailboxException e) { throw new MessagingException("Exception while checking quotas", e); + } catch (UsersRepositoryException e) { + throw new MessagingException("Exception while retrieving username", e); } } } http://git-wip-us.apache.org/repos/asf/james-project/blob/86871e52/server/mailet/mailets/src/test/java/org/apache/james/transport/matchers/IsOverQuotaTest.java ---------------------------------------------------------------------- diff --git a/server/mailet/mailets/src/test/java/org/apache/james/transport/matchers/IsOverQuotaTest.java b/server/mailet/mailets/src/test/java/org/apache/james/transport/matchers/IsOverQuotaTest.java new file mode 100644 index 0000000..c614555 --- /dev/null +++ b/server/mailet/mailets/src/test/java/org/apache/james/transport/matchers/IsOverQuotaTest.java @@ -0,0 +1,183 @@ +/**************************************************************** + * 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.matchers; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Collection; + +import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver; +import org.apache.james.mailbox.acl.UnionMailboxACLResolver; +import org.apache.james.mailbox.inmemory.InMemoryMailboxManager; +import org.apache.james.mailbox.inmemory.InMemoryMailboxSessionMapperFactory; +import org.apache.james.mailbox.inmemory.InMemoryMessageId; +import org.apache.james.mailbox.inmemory.quota.InMemoryCurrentQuotaManager; +import org.apache.james.mailbox.inmemory.quota.InMemoryPerUserMaxQuotaManager; +import org.apache.james.mailbox.model.MailboxPath; +import org.apache.james.mailbox.model.QuotaRoot; +import org.apache.james.mailbox.store.FakeAuthenticator; +import org.apache.james.mailbox.store.FakeAuthorizator; +import org.apache.james.mailbox.store.NoMailboxPathLocker; +import org.apache.james.mailbox.store.mail.model.impl.MessageParser; +import org.apache.james.mailbox.store.quota.CurrentQuotaCalculator; +import org.apache.james.mailbox.store.quota.DefaultQuotaRootResolver; +import org.apache.james.mailbox.store.quota.StoreQuotaManager; +import org.apache.james.user.api.UsersRepository; +import org.apache.mailet.MailAddress; +import org.apache.mailet.base.MailAddressFixture; +import org.apache.mailet.base.test.FakeMail; +import org.apache.mailet.base.test.FakeMatcherConfig; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class IsOverQuotaTest { + + public static final Logger LOGGER = LoggerFactory.getLogger(IsOverQuotaTest.class); + private IsOverQuota testee; + private InMemoryPerUserMaxQuotaManager maxQuotaManager; + private DefaultQuotaRootResolver quotaRootResolver; + private InMemoryMailboxManager mailboxManager; + private UsersRepository usersRepository; + + @Before + public void setUp() throws Exception { + InMemoryMailboxSessionMapperFactory factory = new InMemoryMailboxSessionMapperFactory(); + mailboxManager = new InMemoryMailboxManager(factory, new FakeAuthenticator(), FakeAuthorizator.defaultReject(), + new NoMailboxPathLocker(), new UnionMailboxACLResolver(), new SimpleGroupMembershipResolver(), new MessageParser(), + new InMemoryMessageId.Factory()); + + quotaRootResolver = new DefaultQuotaRootResolver(factory); + StoreQuotaManager quotaManager = new StoreQuotaManager(); + maxQuotaManager = new InMemoryPerUserMaxQuotaManager(); + quotaManager.setMaxQuotaManager(maxQuotaManager); + quotaManager.setCurrentQuotaManager(new InMemoryCurrentQuotaManager(new CurrentQuotaCalculator(factory, quotaRootResolver), mailboxManager)); + usersRepository = mock(UsersRepository.class); + testee = new IsOverQuota(quotaRootResolver, quotaManager, mailboxManager, usersRepository); + + mailboxManager.setQuotaRootResolver(quotaRootResolver); + mailboxManager.setQuotaManager(quotaManager); + mailboxManager.init(); + + testee.init(FakeMatcherConfig.builder().matcherName("IsOverQuota").build()); + + when(usersRepository.getUser(MailAddressFixture.ANY_AT_JAMES)).thenReturn(MailAddressFixture.ANY_AT_JAMES.getLocalPart()); + when(usersRepository.getUser(MailAddressFixture.OTHER_AT_JAMES)).thenReturn(MailAddressFixture.OTHER_AT_JAMES.getLocalPart()); + } + + @Test + public void matchShouldAcceptMailWhenNoQuota() throws Exception { + FakeMail mail = FakeMail.builder() + .recipient(MailAddressFixture.ANY_AT_JAMES) + .size(1000) + .build(); + + assertThat(testee.match(mail)) + .isEmpty(); + } + + @Test + public void matchShouldKeepAddressesWithTooBigSize() throws Exception { + maxQuotaManager.setDefaultMaxStorage(100); + + FakeMail fakeMail = FakeMail.builder() + .recipient(MailAddressFixture.ANY_AT_JAMES) + .size(1000) + .build(); + Collection<MailAddress> result = testee.match(fakeMail); + + assertThat(result).containsOnly(MailAddressFixture.ANY_AT_JAMES); + } + + @Test + public void matchShouldReturnEmptyAtSizeQuotaLimit() throws Exception { + maxQuotaManager.setDefaultMaxStorage(1000); + + FakeMail fakeMail = FakeMail.builder() + .recipient(MailAddressFixture.ANY_AT_JAMES) + .size(1000) + .build(); + Collection<MailAddress> result = testee.match(fakeMail); + + assertThat(result).isEmpty(); + } + + @Test + public void matchShouldKeepAddressesWithTooMuchMessages() throws Exception { + maxQuotaManager.setDefaultMaxMessage(0); + + FakeMail fakeMail=FakeMail.builder() + .recipient(MailAddressFixture.ANY_AT_JAMES) + .build(); + Collection<MailAddress> result = testee.match(fakeMail); + + assertThat(result).containsOnly(MailAddressFixture.ANY_AT_JAMES); + } + + @Test + public void matchShouldReturnEmptyOnMessageLimit() throws Exception { + maxQuotaManager.setDefaultMaxMessage(1); + + FakeMail fakeMail=FakeMail.builder() + .recipient(MailAddressFixture.ANY_AT_JAMES) + .build(); + Collection <MailAddress> result = testee.match(fakeMail); + + assertThat(result).isEmpty(); + } + + @Test + public void matchShouldNotIncludeRecipientNotOverQuota() throws Exception { + String username = MailAddressFixture.ANY_AT_JAMES.getLocalPart(); + QuotaRoot quotaRoot = quotaRootResolver.getQuotaRoot(MailboxPath.inbox(mailboxManager.createSystemSession(username, LOGGER))); + maxQuotaManager.setMaxStorage(quotaRoot, 100); + + FakeMail fakeMail=FakeMail.builder() + .recipient(MailAddressFixture.ANY_AT_JAMES) + .recipient(MailAddressFixture.OTHER_AT_JAMES) + .size(150) + .build(); + Collection<MailAddress> result = testee.match(fakeMail); + + assertThat(result).containsOnly(MailAddressFixture.ANY_AT_JAMES); + } + + @Test + public void matchShouldSupportVirtualHosting() throws Exception { + when(usersRepository.getUser(MailAddressFixture.ANY_AT_JAMES)).thenReturn(MailAddressFixture.ANY_AT_JAMES.asString()); + when(usersRepository.getUser(MailAddressFixture.OTHER_AT_JAMES)).thenReturn(MailAddressFixture.OTHER_AT_JAMES.asString()); + String username = MailAddressFixture.ANY_AT_JAMES.asString(); + QuotaRoot quotaRoot = quotaRootResolver.getQuotaRoot(MailboxPath.inbox(mailboxManager.createSystemSession(username, LOGGER))); + maxQuotaManager.setMaxStorage(quotaRoot, 100); + + FakeMail fakeMail=FakeMail.builder() + .recipient(MailAddressFixture.ANY_AT_JAMES) + .recipient(MailAddressFixture.OTHER_AT_JAMES) + .size(150) + .build(); + Collection<MailAddress> result = testee.match(fakeMail); + + assertThat(result).containsOnly(MailAddressFixture.ANY_AT_JAMES); + } + +} --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org