This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit c6e725c2394d8757197211a3b132b65b7eaf822a
Author: Tran Tien Duc <[email protected]>
AuthorDate: Thu Feb 13 14:53:26 2020 +0700

    JAMES-3056 Consistency test on failing creations
---
 .../CassandraMailboxManagerConsistencyTest.java    | 168 ++++++++++++++++++++-
 1 file changed, 165 insertions(+), 3 deletions(-)

diff --git 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerConsistencyTest.java
 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerConsistencyTest.java
index 84c2ad3..bd6f93f 100644
--- 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerConsistencyTest.java
+++ 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerConsistencyTest.java
@@ -18,35 +18,68 @@
  ****************************************************************/
 package org.apache.james.mailbox.cassandra;
 
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isA;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 
 import org.apache.james.backends.cassandra.CassandraClusterExtension;
 import org.apache.james.backends.cassandra.init.CassandraTypesProvider;
 import org.apache.james.backends.cassandra.utils.CassandraUtils;
+import org.apache.james.core.Username;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.cassandra.ids.CassandraId;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxPathDAOImpl;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxPathV2DAO;
 import org.apache.james.mailbox.cassandra.mail.MailboxAggregateModule;
+import org.apache.james.mailbox.model.Mailbox;
+import org.apache.james.mailbox.model.MailboxId;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.model.search.MailboxQuery;
+import org.apache.james.mailbox.model.search.Wildcard;
 import org.apache.james.mailbox.store.PreDeletionHooks;
+import org.assertj.core.api.SoftAssertions;
 import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
 import com.datastax.driver.core.Session;
+import com.github.fge.lambdas.Throwing;
+import com.github.fge.lambdas.runnable.ThrowingRunnable;
+
+import reactor.core.publisher.Mono;
 
 class CassandraMailboxManagerConsistencyTest {
+
+    private static final Username USER = Username.of("user");
+    private static final String INBOX = "INBOX";
+
     @RegisterExtension
     static CassandraClusterExtension cassandra = new 
CassandraClusterExtension(MailboxAggregateModule.MODULE_WITH_QUOTA);
 
     private CassandraMailboxManager testee;
+    private MailboxSession mailboxSession;
+
+    private MailboxPath inboxPath;
+    private MailboxQuery.UserBound allMailboxesSearchQuery;
+
+    private CassandraMailboxDAO mailboxDAO;
+    private CassandraMailboxPathDAOImpl mailboxPathDAO;
+    private CassandraMailboxPathV2DAO mailboxPathV2DAO;
 
     @BeforeEach
     void setUp() {
         Session session = cassandra.getCassandraCluster().getConf();
         CassandraTypesProvider typesProvider = 
cassandra.getCassandraCluster().getTypesProvider();
 
-        CassandraMailboxDAO mailboxDAO = spy(new CassandraMailboxDAO(session, 
typesProvider));
-        CassandraMailboxPathDAOImpl mailboxPathDAO = spy(new 
CassandraMailboxPathDAOImpl(session, typesProvider));
-        CassandraMailboxPathV2DAO mailboxPathV2DAO = spy(new 
CassandraMailboxPathV2DAO(session, CassandraUtils.WITH_DEFAULT_CONFIGURATION));
+        mailboxDAO = spy(new CassandraMailboxDAO(session, typesProvider));
+        mailboxPathDAO = spy(new CassandraMailboxPathDAOImpl(session, 
typesProvider));
+        mailboxPathV2DAO = spy(new CassandraMailboxPathV2DAO(session, 
CassandraUtils.WITH_DEFAULT_CONFIGURATION));
 
         testee = CassandraMailboxManagerProvider.provideMailboxManager(
             session,
@@ -55,5 +88,134 @@ class CassandraMailboxManagerConsistencyTest {
             binder -> 
binder.bind(CassandraMailboxDAO.class).toInstance(mailboxDAO),
             binder -> 
binder.bind(CassandraMailboxPathDAOImpl.class).toInstance(mailboxPathDAO),
             binder -> 
binder.bind(CassandraMailboxPathV2DAO.class).toInstance(mailboxPathV2DAO));
+
+        mailboxSession = testee.createSystemSession(USER);
+
+        inboxPath = MailboxPath.forUser(USER, INBOX);
+        allMailboxesSearchQuery = MailboxQuery.builder()
+            .userAndNamespaceFrom(inboxPath)
+            .expression(Wildcard.INSTANCE)
+            .build()
+            .asUserBound();
+    }
+
+    @Nested
+    class FailsOnCreate {
+
+        @Test
+        void createMailboxShouldBeConsistentWhenMailboxDaoFails() {
+            doReturn(Mono.error(new RuntimeException("mock exception")))
+                .when(mailboxDAO)
+                .save(any(Mailbox.class));
+
+            doQuietly(() -> testee.createMailbox(inboxPath, mailboxSession));
+
+            SoftAssertions.assertSoftly(Throwing.consumer(softly -> {
+                softly.assertThat(testee.search(allMailboxesSearchQuery, 
mailboxSession))
+                    .isEmpty();
+                softly.assertThat(testee.list(mailboxSession))
+                    .isEmpty();
+            }));
+        }
+
+        @Test
+        void createMailboxShouldBeConsistentWhenMailboxPathDaoFails() {
+            doReturn(Mono.error(new RuntimeException("mock exception")))
+                .when(mailboxPathV2DAO)
+                .save(eq(inboxPath), isA(CassandraId.class));
+
+            doQuietly(() -> testee.createMailbox(inboxPath, mailboxSession));
+
+            SoftAssertions.assertSoftly(Throwing.consumer(softly -> {
+                softly.assertThat(testee.search(allMailboxesSearchQuery, 
mailboxSession))
+                    .isEmpty();
+                softly.assertThat(testee.list(mailboxSession))
+                    .isEmpty();
+            }));
+        }
+
+        @Disabled("JAMES-3056 createMailbox() return an empty Optional")
+        @Test
+        void 
createMailboxAfterAFailedCreationShouldCreateTheMailboxWhenMailboxDaoFails() 
throws Exception {
+            doReturn(Mono.error(new RuntimeException("mock exception")))
+                .doCallRealMethod()
+                .when(mailboxDAO)
+                .save(any(Mailbox.class));
+
+            doQuietly(() -> testee.createMailbox(inboxPath, mailboxSession));
+
+            assertThat(testee.createMailbox(inboxPath, mailboxSession))
+                .isNotEmpty();
+        }
+
+        @Test
+        void 
createMailboxAfterAFailedCreationShouldCreateTheMailboxWhenMailboxPathDaoFails()
 throws Exception {
+            doReturn(Mono.error(new RuntimeException("mock exception")))
+                .doCallRealMethod()
+                .when(mailboxPathV2DAO)
+                .save(eq(inboxPath), isA(CassandraId.class));
+
+            doQuietly(() -> testee.createMailbox(inboxPath, mailboxSession));
+
+            MailboxId inboxId = testee.createMailbox(inboxPath, mailboxSession)
+                .get();
+
+            SoftAssertions.assertSoftly(Throwing.consumer(softly -> {
+                softly.assertThat(testee.search(allMailboxesSearchQuery, 
mailboxSession))
+                    .hasOnlyOneElementSatisfying(mailboxMetaData -> {
+                        
softly.assertThat(mailboxMetaData.getId()).isEqualTo(inboxId);
+                        
softly.assertThat(mailboxMetaData.getPath()).isEqualTo(inboxPath);
+                    });
+                softly.assertThat(testee.list(mailboxSession))
+                    .containsExactly(inboxPath);
+            }));
+        }
+
+        @Disabled("JAMES-3056 createMailbox() return an empty Optional")
+        @Test
+        void 
createMailboxAfterDeletingShouldCreateTheMailboxWhenMailboxDaoFails() throws 
Exception {
+            doReturn(Mono.error(new RuntimeException("mock exception")))
+                .doCallRealMethod()
+                .when(mailboxDAO)
+                .save(any(Mailbox.class));
+
+            doQuietly(() -> testee.createMailbox(inboxPath, mailboxSession));
+            doQuietly(() -> testee.deleteMailbox(inboxPath, mailboxSession));
+
+            assertThat(testee.createMailbox(inboxPath, mailboxSession))
+                .isNotEmpty();
+        }
+
+        @Test
+        void 
createMailboxAfterDeletingShouldCreateTheMailboxWhenMailboxPathDaoFails() 
throws Exception {
+            doReturn(Mono.error(new RuntimeException("mock exception")))
+                .doCallRealMethod()
+                .when(mailboxPathV2DAO)
+                .save(eq(inboxPath), isA(CassandraId.class));
+
+            doQuietly(() -> testee.createMailbox(inboxPath, mailboxSession));
+            doQuietly(() -> testee.deleteMailbox(inboxPath, mailboxSession));
+
+            MailboxId inboxId = testee.createMailbox(inboxPath, mailboxSession)
+                .get();
+
+            SoftAssertions.assertSoftly(Throwing.consumer(softly -> {
+                softly.assertThat(testee.search(allMailboxesSearchQuery, 
mailboxSession))
+                    .hasOnlyOneElementSatisfying(mailboxMetaData -> {
+                        
softly.assertThat(mailboxMetaData.getId()).isEqualTo(inboxId);
+                        
softly.assertThat(mailboxMetaData.getPath()).isEqualTo(inboxPath);
+                    });
+                softly.assertThat(testee.list(mailboxSession))
+                    .containsExactly(inboxPath);
+            }));
+        }
+    }
+
+    private void doQuietly(ThrowingRunnable runnable) {
+        try {
+            runnable.run();
+        } catch (Throwable th) {
+            // ignore
+        }
     }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to