This is an automated email from the ASF dual-hosted git repository. rouazana pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 65c7c4b46f7879a2f971d78392613600e25e7af3 Author: Tran Tien Duc <[email protected]> AuthorDate: Thu Jul 18 19:20:43 2019 +0700 JAMES-2835 DeletedMessageVault can't delete messages having same contents --- .../CassandraDeletedMessageVaultTest.java | 10 +++ .../integration/DeletedMessagesVaultTest.java | 97 +++++++++++++++++++++- ...FileMailRepositoryDeletedMessagesVaultTest.java | 9 ++ .../memory/MemoryDeletedMessagesVaultTest.java | 9 ++ .../rabbitmq/RabbitMQDeletedMessagesVaultTest.java | 10 +++ 5 files changed, 133 insertions(+), 2 deletions(-) diff --git a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraDeletedMessageVaultTest.java b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraDeletedMessageVaultTest.java index fd67be2..97ab298 100644 --- a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraDeletedMessageVaultTest.java +++ b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraDeletedMessageVaultTest.java @@ -31,7 +31,9 @@ import org.apache.james.mailrepository.api.MailRepositoryUrl; import org.apache.james.modules.vault.TestDeleteMessageVaultPreDeletionHookModule; import org.apache.james.vault.MailRepositoryDeletedMessageVault; import org.apache.james.webadmin.WebAdminConfiguration; +import org.junit.Ignore; import org.junit.Rule; +import org.junit.Test; public class CassandraDeletedMessageVaultTest extends DeletedMessagesVaultTest { @Rule @@ -55,4 +57,12 @@ public class CassandraDeletedMessageVaultTest extends DeletedMessagesVaultTest { protected void awaitSearchUpToDate() { rule.await(); } + + + @Ignore("This side effect behaviour is specific to Blobstore based implementation relying on deduplication, " + + "which is not the case of the tested implementation") + @Test + @Override + public void vaultDeleteShouldDeleteAllMessagesHavingSameBlobContent() { + } } diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/DeletedMessagesVaultTest.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/DeletedMessagesVaultTest.java index 2f03a4e..2ab54df 100644 --- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/DeletedMessagesVaultTest.java +++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/DeletedMessagesVaultTest.java @@ -96,6 +96,7 @@ public abstract class DeletedMessagesVaultTest { private static final String SECOND_SUBJECT = "second subject"; private static final String HOMER = "homer@" + DOMAIN; private static final String BART = "bart@" + DOMAIN; + private static final String JACK = "jack@" + DOMAIN; private static final String PASSWORD = "password"; private static final String BOB_PASSWORD = "bobPassword"; private static final ConditionFactory WAIT_TWO_MINUTES = calmlyAwait.atMost(Duration.TWO_MINUTES); @@ -105,6 +106,10 @@ public abstract class DeletedMessagesVaultTest { .userExportFrom(HOMER) .exportTo(BART) .query(MATCH_ALL_QUERY); + private static final ExportRequest EXPORT_ALL_JACK_MESSAGES_TO_HOMER = ExportRequest + .userExportFrom(JACK) + .exportTo(HOMER) + .query(MATCH_ALL_QUERY); private MailboxId otherMailboxId; @@ -119,6 +124,7 @@ public abstract class DeletedMessagesVaultTest { private AccessToken homerAccessToken; private AccessToken bartAccessToken; + private AccessToken jackAccessToken; private GuiceJamesServer jmapServer; private RequestSpecification webAdminApi; private UpdatableTickingClock clock; @@ -141,10 +147,12 @@ public abstract class DeletedMessagesVaultTest { dataProbe.addDomain(DOMAIN); dataProbe.addUser(HOMER, PASSWORD); dataProbe.addUser(BART, BOB_PASSWORD); + dataProbe.addUser(JACK, PASSWORD); mailboxProbe.createMailbox("#private", HOMER, DefaultMailboxes.INBOX); otherMailboxId = mailboxProbe.createMailbox("#private", HOMER, MAILBOX_NAME); homerAccessToken = authenticateJamesUser(baseUri(jmapServer), HOMER, PASSWORD); bartAccessToken = authenticateJamesUser(baseUri(jmapServer), BART, BOB_PASSWORD); + jackAccessToken = authenticateJamesUser(baseUri(jmapServer), JACK, PASSWORD); webAdminApi = WebAdminUtils.spec(jmapServer.getProbe(WebAdminGuiceProbe.class).getWebAdminPort()) .config(WebAdminUtils.defaultConfig() @@ -742,6 +750,55 @@ public abstract class DeletedMessagesVaultTest { .hasSize(0); } + @Test + public void vaultDeleteShouldDeleteAllMessagesHavingSameBlobContent() throws Exception { + bartSendMessageToHomerAndJack(); + WAIT_TWO_MINUTES.until(() -> listMessageIdsForAccount(homerAccessToken).size() == 1); + + String homerInboxMessageId = listMessageIdsForAccount(homerAccessToken).get(0); + homerDeletesMessages(ImmutableList.of(homerInboxMessageId)); + WAIT_TWO_MINUTES.until(() -> listMessageIdsForAccount(homerAccessToken).size() == 0); + + // the message same with homer's one in inbox + String jackInboxMessageId = listMessageIdsForAccount(jackAccessToken).get(0); + jackDeletesMessages(ImmutableList.of(jackInboxMessageId)); + WAIT_TWO_MINUTES.until(() -> listMessageIdsForAccount(jackAccessToken).size() == 0); + + // delete from homer's vault, expecting the message contains the same blob in jack's vault will be deleted + deleteFromVault(webAdminApi, HOMER, homerInboxMessageId); + + String fileLocationOfBartMessages = exportAndGetFileLocationFromLastMail(EXPORT_ALL_JACK_MESSAGES_TO_HOMER, homerAccessToken); + try (ZipAssert zipAssert = assertThatZip(new FileInputStream(fileLocationOfBartMessages))) { + zipAssert.hasNoEntry(); + } + } + + @Test + public void vaultDeleteShouldNotDeleteAllMessagesHavingSameBlobContentWhenMessageNotDeletedWithinTheSameMonth() throws Exception { + bartSendMessageToHomerAndJack(); + WAIT_TWO_MINUTES.until(() -> listMessageIdsForAccount(homerAccessToken).size() == 1); + + String homerInboxMessageId = listMessageIdsForAccount(homerAccessToken).get(0); + homerDeletesMessages(ImmutableList.of(homerInboxMessageId)); + WAIT_TWO_MINUTES.until(() -> listMessageIdsForAccount(homerAccessToken).size() == 0); + + // one year later, delete jack's message + clock.setInstant(NOW.plusYears(1).toInstant()); + // the message same with homer's one in inbox + String jackInboxMessageId = listMessageIdsForAccount(jackAccessToken).get(0); + jackDeletesMessages(ImmutableList.of(jackInboxMessageId)); + WAIT_TWO_MINUTES.until(() -> listMessageIdsForAccount(jackAccessToken).size() == 0); + + // delete from homer's vault, expecting jack's vault still be intact + deleteFromVault(webAdminApi, HOMER, homerInboxMessageId); + + String fileLocationOfBartMessages = exportAndGetFileLocationFromLastMail(EXPORT_ALL_JACK_MESSAGES_TO_HOMER, homerAccessToken); + try (ZipAssert zipAssert = assertThatZip(new FileInputStream(fileLocationOfBartMessages))) { + zipAssert.hasEntriesSize(1) + .allSatisfies(entry -> EntryChecks.hasName(jackInboxMessageId + ".eml")); + } + } + private String exportAndGetFileLocationFromLastMail(ExportRequest exportRequest, AccessToken shareeAccessToken) { int currentNumberOfMessages = listMessageIdsForAccount(shareeAccessToken).size(); exportVaultContent(webAdminApi, exportRequest); @@ -770,7 +827,7 @@ public abstract class DeletedMessagesVaultTest { " {" + " \"update\": {" + " \"" + otherMailboxId.serialize() + "\" : {" + - " \"sharedWith\" : {\"" + BART + "\": [\"a\", \"w\", \"r\"]}" + + " \"sharedWith\" : {\"" + BART + "\": [\"l\", \"w\", \"r\"]}" + " }" + " }" + " }," + @@ -784,6 +841,38 @@ public abstract class DeletedMessagesVaultTest { bartSendMessageToHomerWithSubject(SUBJECT); } + private void bartSendMessageToHomerAndJack() { + String messageCreationId = "creationId"; + String outboxId = getOutboxId(bartAccessToken); + String bigEnoughBody = Strings.repeat("123456789\n", 12 * 100); + String requestBody = "[" + + " [" + + " \"setMessages\"," + + " {" + + " \"create\": { \"" + messageCreationId + "\" : {" + + " \"headers\":{\"Disposition-Notification-To\":\"" + BART + "\"}," + + " \"from\": { \"name\": \"Bob\", \"email\": \"" + BART + "\"}," + + " \"to\": [{ \"name\": \"Homer\", \"email\": \"" + HOMER + "\"}, { \"name\": \"Jack\", \"email\": \"" + JACK + "\"}]," + + " \"subject\": \"" + SUBJECT + "\"," + + " \"textBody\": \"" + bigEnoughBody + "\"," + + " \"htmlBody\": \"Test <b>body</b>, HTML version\"," + + " \"mailboxIds\": [\"" + outboxId + "\"] " + + " }}" + + " }," + + " \"#0\"" + + " ]" + + "]"; + + with() + .header("Authorization", bartAccessToken.serialize()) + .body(requestBody) + .post("/jmap") + .then() + .extract() + .body() + .path(ARGUMENTS + ".created." + messageCreationId + ".id"); + } + private void bartSendMessageToHomerWithSubject(String subject) { String messageCreationId = "creationId"; String outboxId = getOutboxId(bartAccessToken); @@ -824,6 +913,10 @@ public abstract class DeletedMessagesVaultTest { deleteMessages(bartAccessToken, idsToDestroy); } + private void jackDeletesMessages(List<String> idsToDestroy) { + deleteMessages(jackAccessToken, idsToDestroy); + } + private void restoreAllMessagesOfHomer() { restoreMessagesFor(HOMER); } @@ -846,7 +939,7 @@ public abstract class DeletedMessagesVaultTest { "]"; given() - .header("Authorization", bartAccessToken.serialize()) + .header("Authorization", homerAccessToken.serialize()) .body(updateRequestBody) .when() .post("/jmap"); diff --git a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/FileMailRepositoryDeletedMessagesVaultTest.java b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/FileMailRepositoryDeletedMessagesVaultTest.java index e94262f..f4f40b4 100644 --- a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/FileMailRepositoryDeletedMessagesVaultTest.java +++ b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/FileMailRepositoryDeletedMessagesVaultTest.java @@ -30,7 +30,9 @@ import org.apache.james.mailrepository.api.MailRepositoryUrl; import org.apache.james.modules.vault.TestDeleteMessageVaultPreDeletionHookModule; import org.apache.james.vault.MailRepositoryDeletedMessageVault; import org.apache.james.webadmin.WebAdminConfiguration; +import org.junit.Ignore; import org.junit.Rule; +import org.junit.Test; public class FileMailRepositoryDeletedMessagesVaultTest extends DeletedMessagesVaultTest { @@ -52,4 +54,11 @@ public class FileMailRepositoryDeletedMessagesVaultTest extends DeletedMessagesV binder -> binder.bind(FileSystem.class).toInstance(fileSystem), binder -> binder.bind(Clock.class).toInstance(clock)); } + + @Ignore("This side effect behaviour is specific to Blobstore based implementation relying on deduplication, " + + "which is not the case of the tested implementation") + @Test + @Override + public void vaultDeleteShouldDeleteAllMessagesHavingSameBlobContent() { + } } diff --git a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryDeletedMessagesVaultTest.java b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryDeletedMessagesVaultTest.java index ae1fd0c..edc3df4 100644 --- a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryDeletedMessagesVaultTest.java +++ b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryDeletedMessagesVaultTest.java @@ -28,7 +28,9 @@ import org.apache.james.filesystem.api.FileSystem; import org.apache.james.jmap.methods.integration.DeletedMessagesVaultTest; import org.apache.james.modules.vault.TestDeleteMessageVaultPreDeletionHookModule; import org.apache.james.webadmin.WebAdminConfiguration; +import org.junit.Ignore; import org.junit.Rule; +import org.junit.Test; public class MemoryDeletedMessagesVaultTest extends DeletedMessagesVaultTest { @Rule @@ -47,4 +49,11 @@ public class MemoryDeletedMessagesVaultTest extends DeletedMessagesVaultTest { protected void awaitSearchUpToDate() { } + + @Ignore("This side effect behaviour is specific to Blobstore based implementation relying on deduplication, " + + "which is not the case of the tested implementation") + @Test + @Override + public void vaultDeleteShouldDeleteAllMessagesHavingSameBlobContent() { + } } diff --git a/server/protocols/jmap-integration-testing/rabbitmq-jmap-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/RabbitMQDeletedMessagesVaultTest.java b/server/protocols/jmap-integration-testing/rabbitmq-jmap-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/RabbitMQDeletedMessagesVaultTest.java index 215310f..6c20037 100644 --- a/server/protocols/jmap-integration-testing/rabbitmq-jmap-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/RabbitMQDeletedMessagesVaultTest.java +++ b/server/protocols/jmap-integration-testing/rabbitmq-jmap-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/RabbitMQDeletedMessagesVaultTest.java @@ -31,7 +31,9 @@ import org.apache.james.mailrepository.api.MailRepositoryUrl; import org.apache.james.modules.vault.TestDeleteMessageVaultPreDeletionHookModule; import org.apache.james.vault.MailRepositoryDeletedMessageVault; import org.apache.james.webadmin.WebAdminConfiguration; +import org.junit.Ignore; import org.junit.Rule; +import org.junit.Test; public class RabbitMQDeletedMessagesVaultTest extends DeletedMessagesVaultTest { @Rule @@ -55,4 +57,12 @@ public class RabbitMQDeletedMessagesVaultTest extends DeletedMessagesVaultTest { protected void awaitSearchUpToDate() { rule.await(); } + + @Ignore("This side effect behaviour is specific to Blobstore based implementation relying on deduplication, " + + "which is not the case of the tested implementation") + @Test + @Override + public void vaultDeleteShouldDeleteAllMessagesHavingSameBlobContent() { + } } + --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
