JAMES-2400 Add contract test for QuotaSearcher
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/24d1b95f Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/24d1b95f Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/24d1b95f Branch: refs/heads/master Commit: 24d1b95f28c5b0dce83a2a1d582c9acb518943b9 Parents: 6b75b1a Author: Antoine Duprat <adup...@linagora.com> Authored: Fri May 18 10:03:36 2018 +0200 Committer: Matthieu Baechler <matth...@apache.org> Committed: Tue May 22 15:32:54 2018 +0200 ---------------------------------------------------------------------- .../java/org/apache/james/core/CoreFixture.java | 49 ++++ mailbox/plugin/quota-search/pom.xml | 11 + .../james/quota/search/QuotaSearcher.java | 4 + .../quota/search/QuotaSearchTestSystem.java | 61 +++++ .../quota/search/QuotaSearcherContract.java | 271 +++++++++++++++++++ pom.xml | 6 + 6 files changed, 402 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/24d1b95f/core/src/test/java/org/apache/james/core/CoreFixture.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/james/core/CoreFixture.java b/core/src/test/java/org/apache/james/core/CoreFixture.java new file mode 100644 index 0000000..237e78e --- /dev/null +++ b/core/src/test/java/org/apache/james/core/CoreFixture.java @@ -0,0 +1,49 @@ +/**************************************************************** + * 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.core; + +import static org.apache.james.core.CoreFixture.Domains.ALPHABET_TLD; +import static org.apache.james.core.CoreFixture.Domains.SIMPSON_COM; +import static org.apache.james.core.CoreFixture.Domains.DOMAIN_TLD; + +public interface CoreFixture { + interface Domains { + Domain DOMAIN_TLD = Domain.of("domain.tld"); + Domain ALPHABET_TLD = Domain.of("alphabet.tld"); + Domain SIMPSON_COM = Domain.of("simpson.com"); + } + + interface Users { + interface Simpson { + User BART = User.fromLocalPartWithDomain("bart", SIMPSON_COM); + User HOMER = User.fromLocalPartWithDomain("homer", SIMPSON_COM); + User LISA = User.fromLocalPartWithDomain("foo3", SIMPSON_COM); + } + + interface Alphabet { + User AAA = User.fromLocalPartWithDomain("aaa", ALPHABET_TLD); + User ABA = User.fromLocalPartWithDomain("aba", ALPHABET_TLD); + User ABB = User.fromLocalPartWithDomain("abb", ALPHABET_TLD); + User ACB = User.fromLocalPartWithDomain("acb", ALPHABET_TLD); + } + + User BENOIT_AT_DOMAIN_TLD = User.fromLocalPartWithDomain("benoit", DOMAIN_TLD); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/24d1b95f/mailbox/plugin/quota-search/pom.xml ---------------------------------------------------------------------- diff --git a/mailbox/plugin/quota-search/pom.xml b/mailbox/plugin/quota-search/pom.xml index d3d2869..9acb4ff 100644 --- a/mailbox/plugin/quota-search/pom.xml +++ b/mailbox/plugin/quota-search/pom.xml @@ -49,6 +49,17 @@ <artifactId>james-core</artifactId> </dependency> <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>james-core</artifactId> + <type>test-jar</type> + <scope>test</scope> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>james-server-data-api</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>nl.jqno.equalsverifier</groupId> <artifactId>equalsverifier</artifactId> <scope>test</scope> http://git-wip-us.apache.org/repos/asf/james-project/blob/24d1b95f/mailbox/plugin/quota-search/src/main/java/org/apache/james/quota/search/QuotaSearcher.java ---------------------------------------------------------------------- diff --git a/mailbox/plugin/quota-search/src/main/java/org/apache/james/quota/search/QuotaSearcher.java b/mailbox/plugin/quota-search/src/main/java/org/apache/james/quota/search/QuotaSearcher.java index 781f62b..63322db 100644 --- a/mailbox/plugin/quota-search/src/main/java/org/apache/james/quota/search/QuotaSearcher.java +++ b/mailbox/plugin/quota-search/src/main/java/org/apache/james/quota/search/QuotaSearcher.java @@ -24,4 +24,8 @@ import org.apache.james.core.User; public interface QuotaSearcher { List<User> search(QuotaQuery query); + + default List<User> search(QuotaQuery.Builder query) { + return search(query.build()); + } } http://git-wip-us.apache.org/repos/asf/james-project/blob/24d1b95f/mailbox/plugin/quota-search/src/test/java/org/apache/james/quota/search/QuotaSearchTestSystem.java ---------------------------------------------------------------------- diff --git a/mailbox/plugin/quota-search/src/test/java/org/apache/james/quota/search/QuotaSearchTestSystem.java b/mailbox/plugin/quota-search/src/test/java/org/apache/james/quota/search/QuotaSearchTestSystem.java new file mode 100644 index 0000000..88e4591 --- /dev/null +++ b/mailbox/plugin/quota-search/src/test/java/org/apache/james/quota/search/QuotaSearchTestSystem.java @@ -0,0 +1,61 @@ +/**************************************************************** + * 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.quota.search; + +import org.apache.james.domainlist.api.DomainList; +import org.apache.james.mailbox.MailboxManager; +import org.apache.james.mailbox.quota.MaxQuotaManager; +import org.apache.james.user.api.UsersRepository; + +public class QuotaSearchTestSystem { + private final MaxQuotaManager maxQuotaManager; + private final MailboxManager mailboxManager; + private final QuotaSearcher quotaSearcher; + private final UsersRepository usersRepository; + private final DomainList domainList; + + public QuotaSearchTestSystem(MaxQuotaManager maxQuotaManager, MailboxManager mailboxManager, QuotaSearcher quotaSearcher, UsersRepository usersRepository, DomainList domainList) { + this.maxQuotaManager = maxQuotaManager; + this.mailboxManager = mailboxManager; + this.quotaSearcher = quotaSearcher; + this.usersRepository = usersRepository; + this.domainList = domainList; + } + + public MaxQuotaManager getMaxQuotaManager() { + return maxQuotaManager; + } + + public MailboxManager getMailboxManager() { + return mailboxManager; + } + + public QuotaSearcher getQuotaSearcher() { + return quotaSearcher; + } + + public UsersRepository getUsersRepository() { + return usersRepository; + } + + public DomainList getDomainList() { + return domainList; + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/24d1b95f/mailbox/plugin/quota-search/src/test/java/org/apache/james/quota/search/QuotaSearcherContract.java ---------------------------------------------------------------------- diff --git a/mailbox/plugin/quota-search/src/test/java/org/apache/james/quota/search/QuotaSearcherContract.java b/mailbox/plugin/quota-search/src/test/java/org/apache/james/quota/search/QuotaSearcherContract.java new file mode 100644 index 0000000..247d902 --- /dev/null +++ b/mailbox/plugin/quota-search/src/test/java/org/apache/james/quota/search/QuotaSearcherContract.java @@ -0,0 +1,271 @@ +/**************************************************************** + * 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.quota.search; + +import static org.apache.james.core.CoreFixture.Domains.ALPHABET_TLD; +import static org.apache.james.core.CoreFixture.Domains.DOMAIN_TLD; +import static org.apache.james.core.CoreFixture.Domains.SIMPSON_COM; +import static org.apache.james.core.CoreFixture.Users.BENOIT_AT_DOMAIN_TLD; +import static org.apache.james.quota.search.QuotaBoundaryFixture._50; +import static org.apache.james.quota.search.QuotaBoundaryFixture._75; +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.ByteArrayInputStream; +import java.nio.charset.StandardCharsets; + +import org.apache.james.core.CoreFixture.Users.Alphabet; +import org.apache.james.core.CoreFixture.Users.Simpson; +import org.apache.james.core.User; +import org.apache.james.domainlist.api.DomainListException; +import org.apache.james.mailbox.MailboxManager; +import org.apache.james.mailbox.MailboxSession; +import org.apache.james.mailbox.MessageManager; +import org.apache.james.mailbox.exception.MailboxException; +import org.apache.james.mailbox.model.MailboxPath; +import org.apache.james.mailbox.quota.QuotaSize; +import org.apache.james.user.api.UsersRepositoryException; +import org.junit.jupiter.api.Test; + +import com.google.common.base.Strings; + +public interface QuotaSearcherContract { + + String PASSWORD = "any"; + + @Test + default void moreThanShouldFilterOutTooSmallValues(QuotaSearchTestSystem testSystem) throws Exception { + testSystem.getDomainList().addDomain(SIMPSON_COM); + testSystem.getUsersRepository().addUser(Simpson.BART.asString(), PASSWORD); + testSystem.getUsersRepository().addUser(Simpson.HOMER.asString(), PASSWORD); + testSystem.getUsersRepository().addUser(Simpson.LISA.asString(), PASSWORD); + testSystem.getMaxQuotaManager().setGlobalMaxStorage(QuotaSize.size(100)); + + appendMessage(testSystem, Simpson.BART, withSize(49)); + appendMessage(testSystem, Simpson.HOMER, withSize(50)); + appendMessage(testSystem, Simpson.LISA, withSize(51)); + + assertThat( + testSystem.getQuotaSearcher() + .search(QuotaQuery.builder() + .moreThan(_50))) + .containsOnly(Simpson.HOMER, Simpson.LISA); + } + + @Test + default void lessThanShouldFilterOutTooBigValues(QuotaSearchTestSystem testSystem) throws Exception { + testSystem.getDomainList().addDomain(SIMPSON_COM); + testSystem.getUsersRepository().addUser(Simpson.BART.asString(), PASSWORD); + testSystem.getUsersRepository().addUser(Simpson.HOMER.asString(), PASSWORD); + testSystem.getUsersRepository().addUser(Simpson.LISA.asString(), PASSWORD); + testSystem.getMaxQuotaManager().setGlobalMaxStorage(QuotaSize.size(100)); + + appendMessage(testSystem, Simpson.BART, withSize(49)); + appendMessage(testSystem, Simpson.HOMER, withSize(50)); + appendMessage(testSystem, Simpson.LISA, withSize(51)); + + assertThat( + testSystem.getQuotaSearcher() + .search(QuotaQuery.builder() + .lessThan(_50))) + .containsOnly(Simpson.HOMER, Simpson.BART); + } + + @Test + default void rangeShouldFilterValuesOutOfRange(QuotaSearchTestSystem testSystem) throws Exception { + testSystem.getDomainList().addDomain(SIMPSON_COM); + testSystem.getUsersRepository().addUser(Simpson.BART.asString(), PASSWORD); + testSystem.getUsersRepository().addUser(Simpson.HOMER.asString(), PASSWORD); + testSystem.getUsersRepository().addUser(Simpson.LISA.asString(), PASSWORD); + testSystem.getMaxQuotaManager().setGlobalMaxStorage(QuotaSize.size(100)); + + appendMessage(testSystem, Simpson.BART, withSize(40)); + appendMessage(testSystem, Simpson.HOMER, withSize(51)); + appendMessage(testSystem, Simpson.LISA, withSize(60)); + appendMessage(testSystem, BENOIT_AT_DOMAIN_TLD, withSize(80)); + + assertThat( + testSystem.getQuotaSearcher() + .search(QuotaQuery.builder() + .moreThan(_50) + .lessThan(_75))) + .containsOnly(Simpson.HOMER, Simpson.LISA); + } + + @Test + default void hasDomainShouldFilterOutValuesWithDifferentDomains(QuotaSearchTestSystem testSystem) throws Exception { + testSystem.getDomainList().addDomain(SIMPSON_COM); + testSystem.getDomainList().addDomain(DOMAIN_TLD); + testSystem.getUsersRepository().addUser(Simpson.BART.asString(), PASSWORD); + testSystem.getUsersRepository().addUser(Simpson.LISA.asString(), PASSWORD); + testSystem.getUsersRepository().addUser(BENOIT_AT_DOMAIN_TLD.asString(), PASSWORD); + testSystem.getMaxQuotaManager().setGlobalMaxStorage(QuotaSize.size(100)); + + appendMessage(testSystem, Simpson.BART, withSize(49)); + appendMessage(testSystem, Simpson.LISA, withSize(51)); + appendMessage(testSystem, BENOIT_AT_DOMAIN_TLD, withSize(50)); + + assertThat( + testSystem.getQuotaSearcher() + .search(QuotaQuery.builder() + .hasDomain(SIMPSON_COM))) + .containsOnly(Simpson.BART, Simpson.LISA); + } + + @Test + default void andShouldCombineClauses(QuotaSearchTestSystem testSystem) throws Exception { + testSystem.getDomainList().addDomain(SIMPSON_COM); + testSystem.getDomainList().addDomain(DOMAIN_TLD); + testSystem.getUsersRepository().addUser(Simpson.BART.asString(), PASSWORD); + testSystem.getUsersRepository().addUser(Simpson.LISA.asString(), PASSWORD); + testSystem.getUsersRepository().addUser(BENOIT_AT_DOMAIN_TLD.asString(), PASSWORD); + testSystem.getMaxQuotaManager().setGlobalMaxStorage(QuotaSize.size(100)); + + appendMessage(testSystem, Simpson.BART, withSize(49)); + appendMessage(testSystem, Simpson.LISA, withSize(51)); + appendMessage(testSystem, BENOIT_AT_DOMAIN_TLD, withSize(50)); + + assertThat( + testSystem.getQuotaSearcher() + .search(QuotaQuery.builder() + .hasDomain(SIMPSON_COM) + .lessThan(_50))) + .containsOnly(Simpson.BART); + } + + @Test + default void resultShouldBeAlphabeticallyOrdered(QuotaSearchTestSystem testSystem) throws Exception { + testSystem.getDomainList().addDomain(ALPHABET_TLD); + testSystem.getUsersRepository().addUser(Alphabet.AAA.asString(), PASSWORD); + testSystem.getUsersRepository().addUser(Alphabet.ABA.asString(), PASSWORD); + testSystem.getUsersRepository().addUser(Alphabet.ABB.asString(), PASSWORD); + testSystem.getUsersRepository().addUser(Alphabet.ACB.asString(), PASSWORD); + testSystem.getMaxQuotaManager().setGlobalMaxStorage(QuotaSize.size(100)); + + appendMessage(testSystem, Alphabet.AAA, withSize(49)); + appendMessage(testSystem, Alphabet.ABA, withSize(50)); + appendMessage(testSystem, Alphabet.ACB, withSize(51)); + appendMessage(testSystem, Alphabet.ABB, withSize(50)); + + assertThat( + testSystem.getQuotaSearcher() + .search(QuotaQuery.builder())) + .containsExactly(Alphabet.AAA, Alphabet.ABA, Alphabet.ABB, Alphabet.ACB); + } + + @Test + default void limitShouldBeTheMaximumValueOfReturnedResults(QuotaSearchTestSystem testSystem) throws Exception { + testSystem.getDomainList().addDomain(ALPHABET_TLD); + testSystem.getUsersRepository().addUser(Alphabet.AAA.asString(), PASSWORD); + testSystem.getUsersRepository().addUser(Alphabet.ABA.asString(), PASSWORD); + testSystem.getUsersRepository().addUser(Alphabet.ABB.asString(), PASSWORD); + testSystem.getUsersRepository().addUser(Alphabet.ACB.asString(), PASSWORD); + testSystem.getMaxQuotaManager().setGlobalMaxStorage(QuotaSize.size(100)); + + appendMessage(testSystem, Alphabet.AAA, withSize(49)); + appendMessage(testSystem, Alphabet.ABA, withSize(50)); + appendMessage(testSystem, Alphabet.ACB, withSize(51)); + appendMessage(testSystem, Alphabet.ABB, withSize(50)); + + assertThat( + testSystem.getQuotaSearcher() + .search(QuotaQuery.builder() + .withLimit(Limit.of(2)))) + .containsOnly(Alphabet.AAA, Alphabet.ABA); + } + + @Test + default void offsetShouldSkipSomeResults(QuotaSearchTestSystem testSystem) throws Exception { + testSystem.getDomainList().addDomain(ALPHABET_TLD); + testSystem.getUsersRepository().addUser(Alphabet.AAA.asString(), PASSWORD); + testSystem.getUsersRepository().addUser(Alphabet.ABA.asString(), PASSWORD); + testSystem.getUsersRepository().addUser(Alphabet.ABB.asString(), PASSWORD); + testSystem.getUsersRepository().addUser(Alphabet.ACB.asString(), PASSWORD); + testSystem.getMaxQuotaManager().setGlobalMaxStorage(QuotaSize.size(100)); + + appendMessage(testSystem, Alphabet.AAA, withSize(49)); + appendMessage(testSystem, Alphabet.ABA, withSize(50)); + appendMessage(testSystem, Alphabet.ACB, withSize(51)); + appendMessage(testSystem, Alphabet.ABB, withSize(50)); + + assertThat( + testSystem.getQuotaSearcher() + .search(QuotaQuery.builder() + .withOffset(Offset.of(2)))) + .containsOnly(Alphabet.ABB, Alphabet.ACB); + } + + @Test + default void searchShouldReturnEmptyOnTooBigOffset(QuotaSearchTestSystem testSystem) throws Exception { + testSystem.getDomainList().addDomain(SIMPSON_COM); + testSystem.getDomainList().addDomain(DOMAIN_TLD); + testSystem.getUsersRepository().addUser(Simpson.BART.asString(), PASSWORD); + testSystem.getUsersRepository().addUser(Simpson.HOMER.asString(), PASSWORD); + testSystem.getUsersRepository().addUser(Simpson.LISA.asString(), PASSWORD); + testSystem.getUsersRepository().addUser(BENOIT_AT_DOMAIN_TLD.asString(), PASSWORD); + testSystem.getMaxQuotaManager().setGlobalMaxStorage(QuotaSize.size(100)); + + appendMessage(testSystem, Simpson.BART, withSize(49)); + appendMessage(testSystem, Simpson.HOMER, withSize(50)); + appendMessage(testSystem, Simpson.LISA, withSize(51)); + appendMessage(testSystem, BENOIT_AT_DOMAIN_TLD, withSize(50)); + + assertThat( + testSystem.getQuotaSearcher() + .search(QuotaQuery.builder() + .withOffset(Offset.of(5)))) + .isEmpty(); + } + + @Test + default void pagingShouldBeSupported(QuotaSearchTestSystem testSystem) throws Exception { + testSystem.getDomainList().addDomain(ALPHABET_TLD); + testSystem.getUsersRepository().addUser(Alphabet.AAA.asString(), PASSWORD); + testSystem.getUsersRepository().addUser(Alphabet.ABA.asString(), PASSWORD); + testSystem.getUsersRepository().addUser(Alphabet.ABB.asString(), PASSWORD); + testSystem.getUsersRepository().addUser(Alphabet.ACB.asString(), PASSWORD); + testSystem.getMaxQuotaManager().setGlobalMaxStorage(QuotaSize.size(100)); + + appendMessage(testSystem, Alphabet.AAA, withSize(49)); + appendMessage(testSystem, Alphabet.ABA, withSize(50)); + appendMessage(testSystem, Alphabet.ACB, withSize(51)); + appendMessage(testSystem, Alphabet.ABB, withSize(50)); + + assertThat( + testSystem.getQuotaSearcher() + .search(QuotaQuery.builder() + .withLimit(Limit.of(2)) + .withOffset(Offset.of(1)))) + .containsExactly(Alphabet.ABA, Alphabet.ABB); + } + + default void appendMessage(QuotaSearchTestSystem testSystem, User user, MessageManager.AppendCommand appendCommand) throws MailboxException, UsersRepositoryException, DomainListException { + MailboxManager mailboxManager = testSystem.getMailboxManager(); + MailboxSession session = mailboxManager.createSystemSession(user.asString()); + + MailboxPath mailboxPath = MailboxPath.inbox(session); + mailboxManager.createMailbox(mailboxPath, session); + mailboxManager.getMailbox(mailboxPath, session) + .appendMessage(appendCommand, session); + } + + default MessageManager.AppendCommand withSize(int size) { + byte[] bytes = Strings.repeat("a", size).getBytes(StandardCharsets.UTF_8); + return MessageManager.AppendCommand.from(new ByteArrayInputStream(bytes)); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/24d1b95f/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 468c331..3b4fa0b 100644 --- a/pom.xml +++ b/pom.xml @@ -983,6 +983,12 @@ </dependency> <dependency> <groupId>${project.groupId}</groupId> + <artifactId>james-core</artifactId> + <type>test-jar</type> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> <artifactId>james-mdn</artifactId> <version>${project.version}</version> </dependency> --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org