You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2019/01/11 09:58:19 UTC
[6/8] james-project git commit: MAILBOX-368 Separating Group and Key
Contract from EventBusContract
MAILBOX-368 Separating Group and Key Contract from EventBusContract
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/bca9ba01
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/bca9ba01
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/bca9ba01
Branch: refs/heads/master
Commit: bca9ba01b8d52562844c14653f9196a617cc1ae9
Parents: 92842f4
Author: datph <dp...@linagora.com>
Authored: Tue Jan 8 14:03:35 2019 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Fri Jan 11 16:57:08 2019 +0700
----------------------------------------------------------------------
.../james/mailbox/events/EventBusContract.java | 359 -------------------
.../mailbox/events/EventBusTestFixture.java | 65 ++++
.../events/EventDeadLettersContract.java | 4 +-
.../james/mailbox/events/GroupContract.java | 167 +++++++++
.../james/mailbox/events/KeyContract.java | 246 +++++++++++++
.../james/mailbox/events/InVMEventBusTest.java | 2 +-
6 files changed, 481 insertions(+), 362 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/bca9ba01/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusContract.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusContract.java b/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusContract.java
index ab54208..50d8d67 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusContract.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusContract.java
@@ -19,366 +19,7 @@
package org.apache.james.mailbox.events;
-import static org.assertj.core.api.Assertions.assertThatCode;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.junit.jupiter.api.Assertions.assertTimeout;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.after;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import java.time.Duration;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-
-import org.apache.james.core.User;
-import org.apache.james.mailbox.Event;
-import org.apache.james.mailbox.MailboxListener;
-import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.model.MailboxConstants;
-import org.apache.james.mailbox.model.MailboxId;
-import org.apache.james.mailbox.model.MailboxPath;
-import org.apache.james.mailbox.model.TestId;
-import org.junit.jupiter.api.Test;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSortedMap;
-
public interface EventBusContract {
- MailboxListener.MailboxEvent EVENT = new MailboxListener.MailboxAdded(
- MailboxSession.SessionId.of(42),
- User.fromUsername("user"),
- new MailboxPath(MailboxConstants.USER_NAMESPACE, "user", "mailboxName"),
- TestId.of(18),
- Event.EventId.random());
- MailboxListener.Added NOOP_EVENT = new MailboxListener.Added(MailboxSession.SessionId.of(18), User.fromUsername("bob"), MailboxPath.forUser("bob", "mailbox"), TestId.of(58), ImmutableSortedMap.of(), Event.EventId.random());
-
- class GroupA extends Group {}
-
- class GroupB extends Group {}
-
- int ONE_SECOND = 1000;
- int FIVE_HUNDRED_MS = 500;
- MailboxId ID_1 = TestId.of(18);
- MailboxId ID_2 = TestId.of(24);
- ImmutableSet<RegistrationKey> NO_KEYS = ImmutableSet.of();
- MailboxIdRegistrationKey KEY_1 = new MailboxIdRegistrationKey(ID_1);
- MailboxIdRegistrationKey KEY_2 = new MailboxIdRegistrationKey(ID_2);
- List<Class<? extends Group>> ALL_GROUPS = ImmutableList.of(GroupA.class, GroupB.class);
EventBus eventBus();
-
- default MailboxListener newListener() {
- MailboxListener listener = mock(MailboxListener.class);
- when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.SYNCHRONOUS);
- return listener;
- }
-
- @Test
- default void listenerGroupShouldReceiveEvents() {
- MailboxListener listener = newListener();
-
- eventBus().register(listener, new GroupA());
-
- eventBus().dispatch(EVENT, NO_KEYS).block();
-
- verify(listener, timeout(ONE_SECOND).times(1)).event(any());
- }
-
- @Test
- default void groupListenersShouldNotReceiveNoopEvents() {
- MailboxListener listener = newListener();
-
- eventBus().register(listener, new GroupA());
-
- eventBus().dispatch(NOOP_EVENT, NO_KEYS).block();
-
- verifyNoMoreInteractions(listener);
- }
-
- @Test
- default void registeredListenersShouldNotReceiveNoopEvents() {
- MailboxListener listener = newListener();
-
- eventBus().register(listener, KEY_1);
-
- eventBus().dispatch(NOOP_EVENT, KEY_1).block();
-
- verifyNoMoreInteractions(listener);
- }
-
- @Test
- default void dispatchShouldNotThrowWhenAGroupListenerFails() {
- MailboxListener listener = newListener();
- doThrow(new RuntimeException()).when(listener).event(any());
-
- eventBus().register(listener, new GroupA());
-
- assertThatCode(() -> eventBus().dispatch(EVENT, NO_KEYS).block())
- .doesNotThrowAnyException();
- }
-
- @Test
- default void dispatchShouldNotThrowWhenARegisteredListenerFails() {
- MailboxListener listener = newListener();
- doThrow(new RuntimeException()).when(listener).event(any());
-
- eventBus().register(listener, KEY_1);
-
- assertThatCode(() -> eventBus().dispatch(EVENT, NO_KEYS).block())
- .doesNotThrowAnyException();
- }
-
- @Test
- default void eachListenerGroupShouldReceiveEvents() {
- MailboxListener listener = newListener();
- MailboxListener listener2 = newListener();
- eventBus().register(listener, new GroupA());
- eventBus().register(listener2, new GroupB());
-
- eventBus().dispatch(EVENT, NO_KEYS).block();
-
- verify(listener, timeout(ONE_SECOND).times(1)).event(any());
- verify(listener2, timeout(ONE_SECOND).times(1)).event(any());
- }
-
- @Test
- default void unregisteredGroupListenerShouldNotReceiveEvents() {
- MailboxListener listener = newListener();
- Registration registration = eventBus().register(listener, new GroupA());
-
- registration.unregister();
-
- eventBus().dispatch(EVENT, NO_KEYS).block();
- verify(listener, after(FIVE_HUNDRED_MS).never())
- .event(any());
- }
-
- @Test
- default void registerShouldThrowWhenAGroupIsAlreadyUsed() {
- MailboxListener listener = newListener();
- MailboxListener listener2 = newListener();
-
- eventBus().register(listener, new GroupA());
-
- assertThatThrownBy(() -> eventBus().register(listener2, new GroupA()))
- .isInstanceOf(GroupAlreadyRegistered.class);
- }
-
- @Test
- default void registerShouldNotThrowOnAnUnregisteredGroup() {
- MailboxListener listener = newListener();
- MailboxListener listener2 = newListener();
-
- eventBus().register(listener, new GroupA()).unregister();
-
- assertThatCode(() -> eventBus().register(listener2, new GroupA()))
- .doesNotThrowAnyException();
- }
-
- @Test
- default void unregisterShouldBeIdempotentForGroups() {
- MailboxListener listener = newListener();
-
- Registration registration = eventBus().register(listener, new GroupA());
- registration.unregister();
-
- assertThatCode(registration::unregister)
- .doesNotThrowAnyException();
- }
-
- @Test
- default void registerShouldAcceptAlreadyUnregisteredGroups() {
- MailboxListener listener = newListener();
-
- eventBus().register(listener, new GroupA()).unregister();
- eventBus().register(listener, new GroupA());
-
- eventBus().dispatch(EVENT, NO_KEYS).block();
-
- verify(listener, timeout(ONE_SECOND).times(1)).event(any());
- }
-
- @Test
- default void dispatchShouldNotNotifyRegisteredListenerWhenEmptyKeySet() {
- MailboxListener listener = newListener();
- eventBus().register(listener, KEY_1);
-
- eventBus().dispatch(EVENT, NO_KEYS).block();
-
- verify(listener, after(FIVE_HUNDRED_MS).never())
- .event(any());
- }
-
- @Test
- default void dispatchShouldNotNotifyListenerRegisteredOnOtherKeys() {
- MailboxListener listener = newListener();
- eventBus().register(listener, KEY_1);
-
- eventBus().dispatch(EVENT, ImmutableSet.of(KEY_2)).block();
-
- verify(listener, after(FIVE_HUNDRED_MS).never())
- .event(any());
- }
-
- @Test
- default void dispatchShouldNotifyRegisteredListeners() {
- MailboxListener listener = newListener();
- eventBus().register(listener, KEY_1);
-
- eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
-
- verify(listener, timeout(ONE_SECOND).times(1)).event(any());
- }
-
- @Test
- default void dispatchShouldNotifyOnlyRegisteredListener() {
- MailboxListener listener = newListener();
- MailboxListener listener2 = newListener();
- eventBus().register(listener, KEY_1);
- eventBus().register(listener2, KEY_2);
-
- eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
-
- verify(listener, timeout(ONE_SECOND).times(1)).event(any());
- verify(listener2, after(FIVE_HUNDRED_MS).never())
- .event(any());
- }
-
- @Test
- default void dispatchShouldNotifyAllListenersRegisteredOnAKey() {
- MailboxListener listener = newListener();
- MailboxListener listener2 = newListener();
- eventBus().register(listener, KEY_1);
- eventBus().register(listener2, KEY_1);
-
- eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
-
- verify(listener, timeout(ONE_SECOND).times(1)).event(any());
- verify(listener2, timeout(ONE_SECOND).times(1)).event(any());
- }
-
- @Test
- default void registerShouldAllowDuplicatedRegistration() {
- MailboxListener listener = newListener();
- eventBus().register(listener, KEY_1);
- eventBus().register(listener, KEY_1);
-
- eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
-
- verify(listener, timeout(ONE_SECOND).times(1)).event(any());
- }
-
- @Test
- default void unregisterShouldRemoveDoubleRegisteredListener() {
- MailboxListener listener = newListener();
- eventBus().register(listener, KEY_1);
- eventBus().register(listener, KEY_1).unregister();
-
- eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
-
- verify(listener, after(FIVE_HUNDRED_MS).never())
- .event(any());
- }
-
- @Test
- default void callingAllUnregisterMethodShouldUnregisterTheListener() {
- MailboxListener listener = newListener();
- Registration registration = eventBus().register(listener, KEY_1);
- eventBus().register(listener, KEY_1).unregister();
- registration.unregister();
-
- eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
-
- verify(listener, after(FIVE_HUNDRED_MS).never())
- .event(any());
- }
-
- @Test
- default void unregisterShouldHaveNotNotifyWhenCalledOnDifferentKeys() {
- MailboxListener listener = newListener();
- eventBus().register(listener, KEY_1);
- eventBus().register(listener, KEY_2).unregister();
-
- eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
-
- verify(listener, timeout(ONE_SECOND).times(1)).event(any());
- }
-
- @Test
- default void unregisterShouldBeIdempotentForKeyRegistrations() {
- MailboxListener listener = newListener();
-
- Registration registration = eventBus().register(listener, KEY_1);
- registration.unregister();
-
- assertThatCode(registration::unregister)
- .doesNotThrowAnyException();
- }
-
- @Test
- default void dispatchShouldAcceptSeveralKeys() {
- MailboxListener listener = newListener();
- eventBus().register(listener, KEY_1);
-
- eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1, KEY_2)).block();
-
- verify(listener, timeout(ONE_SECOND).times(1)).event(any());
- }
-
- @Test
- default void dispatchShouldCallListenerOnceWhenSeveralKeysMatching() {
- MailboxListener listener = newListener();
- eventBus().register(listener, KEY_1);
- eventBus().register(listener, KEY_2);
-
- eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1, KEY_2)).block();
-
- verify(listener, timeout(ONE_SECOND).times(1)).event(any());
- }
-
- @Test
- default void dispatchShouldNotNotifyUnregisteredListener() {
- MailboxListener listener = newListener();
- eventBus().register(listener, KEY_1).unregister();
-
- eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
-
- verify(listener, after(FIVE_HUNDRED_MS).never())
- .event(any());
- }
-
- @Test
- default void dispatchShouldCallSynchronousListener() {
- MailboxListener listener = newListener();
-
- eventBus().register(listener, new GroupA());
-
- eventBus().dispatch(EVENT, NO_KEYS).block();
-
- verify(listener, timeout(ONE_SECOND).times(1)).event(any());
- }
-
- @Test
- default void dispatchShouldNotBlockAsynchronousListener() {
- MailboxListener listener = newListener();
- when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.ASYNCHRONOUS);
- CountDownLatch latch = new CountDownLatch(1);
- doAnswer(invocation -> {
- latch.await();
- return null;
- }).when(listener).event(EVENT);
-
- assertTimeout(Duration.ofSeconds(2),
- () -> {
- eventBus().dispatch(EVENT, NO_KEYS).block();
- latch.countDown();
- });
- }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/james-project/blob/bca9ba01/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusTestFixture.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusTestFixture.java b/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusTestFixture.java
new file mode 100644
index 0000000..ae2116d
--- /dev/null
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventBusTestFixture.java
@@ -0,0 +1,65 @@
+/****************************************************************
+ * 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.mailbox.events;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.List;
+
+import org.apache.james.core.User;
+import org.apache.james.mailbox.Event;
+import org.apache.james.mailbox.MailboxListener;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.model.MailboxConstants;
+import org.apache.james.mailbox.model.MailboxId;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.model.TestId;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+public interface EventBusTestFixture {
+
+ class GroupA extends Group {}
+ class GroupB extends Group {}
+
+ MailboxListener.MailboxEvent EVENT = new MailboxListener.MailboxAdded(
+ MailboxSession.SessionId.of(42),
+ User.fromUsername("user"),
+ new MailboxPath(MailboxConstants.USER_NAMESPACE, "user", "mailboxName"),
+ TestId.of(18),
+ Event.EventId.random());
+
+ int ONE_SECOND = 1000;
+ int FIVE_HUNDRED_MS = 500;
+ MailboxId ID_1 = TestId.of(18);
+ MailboxId ID_2 = TestId.of(24);
+ ImmutableSet<RegistrationKey> NO_KEYS = ImmutableSet.of();
+ MailboxIdRegistrationKey KEY_1 = new MailboxIdRegistrationKey(ID_1);
+ MailboxIdRegistrationKey KEY_2 = new MailboxIdRegistrationKey(ID_2);
+ List<Class<? extends Group>> ALL_GROUPS = ImmutableList.of(GroupA.class, GroupB.class);
+
+ static MailboxListener newListener() {
+ MailboxListener listener = mock(MailboxListener.class);
+ when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.SYNCHRONOUS);
+ return listener;
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/bca9ba01/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventDeadLettersContract.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventDeadLettersContract.java b/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventDeadLettersContract.java
index d70395a..e2282a1 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventDeadLettersContract.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/events/EventDeadLettersContract.java
@@ -86,8 +86,8 @@ interface EventDeadLettersContract {
MailboxListener.MailboxAdded EVENT_2 = new MailboxListener.MailboxAdded(SESSION_ID, USER, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_2);
MailboxListener.MailboxAdded EVENT_3 = new MailboxListener.MailboxAdded(SESSION_ID, USER, MAILBOX_PATH, MAILBOX_ID, EVENT_ID_3);
- Group GROUP_A = new EventBusContract.GroupA();
- Group GROUP_B = new EventBusContract.GroupB();
+ Group GROUP_A = new EventBusTestFixture.GroupA();
+ Group GROUP_B = new EventBusTestFixture.GroupB();
Group NULL_GROUP = null;
Event NULL_EVENT = null;
Event.EventId NULL_EVENT_ID = null;
http://git-wip-us.apache.org/repos/asf/james-project/blob/bca9ba01/mailbox/api/src/test/java/org/apache/james/mailbox/events/GroupContract.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/GroupContract.java b/mailbox/api/src/test/java/org/apache/james/mailbox/events/GroupContract.java
new file mode 100644
index 0000000..0975e3b
--- /dev/null
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/events/GroupContract.java
@@ -0,0 +1,167 @@
+/****************************************************************
+ * 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.mailbox.events;
+
+import static org.apache.james.mailbox.events.EventBusTestFixture.EVENT;
+import static org.apache.james.mailbox.events.EventBusTestFixture.FIVE_HUNDRED_MS;
+import static org.apache.james.mailbox.events.EventBusTestFixture.GroupA;
+import static org.apache.james.mailbox.events.EventBusTestFixture.GroupB;
+import static org.apache.james.mailbox.events.EventBusTestFixture.NO_KEYS;
+import static org.apache.james.mailbox.events.EventBusTestFixture.ONE_SECOND;
+import static org.apache.james.mailbox.events.EventBusTestFixture.newListener;
+import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.after;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+
+import org.apache.james.core.User;
+import org.apache.james.mailbox.Event;
+import org.apache.james.mailbox.MailboxListener;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.model.TestId;
+import org.junit.jupiter.api.Test;
+
+import com.google.common.collect.ImmutableSortedMap;
+
+public interface GroupContract {
+
+ interface SingleEventBusGroupContract extends EventBusContract {
+
+ @Test
+ default void listenerGroupShouldReceiveEvents() {
+ MailboxListener listener = newListener();
+
+ eventBus().register(listener, new GroupA());
+
+ eventBus().dispatch(EVENT, NO_KEYS).block();
+
+ verify(listener, timeout(ONE_SECOND).times(1)).event(any());
+ }
+
+ @Test
+ default void groupListenersShouldNotReceiveNoopEvents() {
+ MailboxListener listener = newListener();
+
+ eventBus().register(listener, new GroupA());
+
+ MailboxListener.Added noopEvent = new MailboxListener.Added(MailboxSession.SessionId.of(18), User.fromUsername("bob"), MailboxPath.forUser("bob", "mailbox"), TestId.of(58), ImmutableSortedMap.of(), Event.EventId.random());
+ eventBus().dispatch(noopEvent, NO_KEYS).block();
+
+ verify(listener, after(FIVE_HUNDRED_MS).never())
+ .event(any());
+ }
+
+ @Test
+ default void dispatchShouldNotThrowWhenAGroupListenerFails() {
+ MailboxListener listener = newListener();
+ doThrow(new RuntimeException()).when(listener).event(any());
+
+ eventBus().register(listener, new GroupA());
+
+ assertThatCode(() -> eventBus().dispatch(EVENT, NO_KEYS).block())
+ .doesNotThrowAnyException();
+ }
+
+ @Test
+ default void eachListenerGroupShouldReceiveEvents() {
+ MailboxListener listener = newListener();
+ MailboxListener listener2 = newListener();
+ eventBus().register(listener, new GroupA());
+ eventBus().register(listener2, new GroupB());
+
+ eventBus().dispatch(EVENT, NO_KEYS).block();
+
+ verify(listener, timeout(ONE_SECOND).times(1)).event(any());
+ verify(listener2, timeout(ONE_SECOND).times(1)).event(any());
+ }
+
+ @Test
+ default void unregisteredGroupListenerShouldNotReceiveEvents() {
+ MailboxListener listener = newListener();
+ Registration registration = eventBus().register(listener, new GroupA());
+
+ registration.unregister();
+
+ eventBus().dispatch(EVENT, NO_KEYS).block();
+ verify(listener, after(FIVE_HUNDRED_MS).never())
+ .event(any());
+ }
+
+ @Test
+ default void registerShouldThrowWhenAGroupIsAlreadyUsed() {
+ MailboxListener listener = newListener();
+ MailboxListener listener2 = newListener();
+
+ eventBus().register(listener, new GroupA());
+
+ assertThatThrownBy(() -> eventBus().register(listener2, new GroupA()))
+ .isInstanceOf(GroupAlreadyRegistered.class);
+ }
+
+ @Test
+ default void registerShouldNotThrowOnAnUnregisteredGroup() {
+ MailboxListener listener = newListener();
+ MailboxListener listener2 = newListener();
+
+ eventBus().register(listener, new GroupA()).unregister();
+
+ assertThatCode(() -> eventBus().register(listener2, new GroupA()))
+ .doesNotThrowAnyException();
+ }
+
+ @Test
+ default void unregisterShouldBeIdempotentForGroups() {
+ MailboxListener listener = newListener();
+
+ Registration registration = eventBus().register(listener, new GroupA());
+ registration.unregister();
+
+ assertThatCode(registration::unregister)
+ .doesNotThrowAnyException();
+ }
+
+ @Test
+ default void registerShouldAcceptAlreadyUnregisteredGroups() {
+ MailboxListener listener = newListener();
+
+ eventBus().register(listener, new GroupA()).unregister();
+ eventBus().register(listener, new GroupA());
+
+ eventBus().dispatch(EVENT, NO_KEYS).block();
+
+ verify(listener, timeout(ONE_SECOND).times(1)).event(any());
+ }
+
+ @Test
+ default void dispatchShouldCallSynchronousListener() {
+ MailboxListener listener = newListener();
+
+ eventBus().register(listener, new GroupA());
+
+ eventBus().dispatch(EVENT, NO_KEYS).block();
+
+ verify(listener, timeout(ONE_SECOND).times(1)).event(any());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/bca9ba01/mailbox/api/src/test/java/org/apache/james/mailbox/events/KeyContract.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/events/KeyContract.java b/mailbox/api/src/test/java/org/apache/james/mailbox/events/KeyContract.java
new file mode 100644
index 0000000..bd92d82
--- /dev/null
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/events/KeyContract.java
@@ -0,0 +1,246 @@
+/****************************************************************
+ * 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.mailbox.events;
+
+import static org.apache.james.mailbox.events.EventBusTestFixture.EVENT;
+import static org.apache.james.mailbox.events.EventBusTestFixture.FIVE_HUNDRED_MS;
+import static org.apache.james.mailbox.events.EventBusTestFixture.KEY_1;
+import static org.apache.james.mailbox.events.EventBusTestFixture.KEY_2;
+import static org.apache.james.mailbox.events.EventBusTestFixture.NO_KEYS;
+import static org.apache.james.mailbox.events.EventBusTestFixture.ONE_SECOND;
+import static org.apache.james.mailbox.events.EventBusTestFixture.newListener;
+import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.junit.jupiter.api.Assertions.assertTimeout;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.after;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.time.Duration;
+import java.util.concurrent.CountDownLatch;
+
+import org.apache.james.core.User;
+import org.apache.james.mailbox.Event;
+import org.apache.james.mailbox.MailboxListener;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.model.TestId;
+import org.junit.jupiter.api.Test;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSortedMap;
+
+public interface KeyContract extends EventBusContract {
+
+ interface SingleEventBusKeyContract extends EventBusContract {
+ @Test
+ default void registeredListenersShouldNotReceiveNoopEvents() {
+ MailboxListener listener = newListener();
+
+ eventBus().register(listener, KEY_1);
+
+ MailboxListener.Added noopEvent = new MailboxListener.Added(MailboxSession.SessionId.of(18), User.fromUsername("bob"), MailboxPath.forUser("bob", "mailbox"), TestId.of(58), ImmutableSortedMap.of(), Event.EventId.random());
+ eventBus().dispatch(noopEvent, KEY_1).block();
+
+ verify(listener, after(FIVE_HUNDRED_MS).never())
+ .event(any());
+ }
+
+ @Test
+ default void dispatchShouldNotThrowWhenARegisteredListenerFails() {
+ MailboxListener listener = newListener();
+ doThrow(new RuntimeException()).when(listener).event(any());
+
+ eventBus().register(listener, KEY_1);
+
+ assertThatCode(() -> eventBus().dispatch(EVENT, NO_KEYS).block())
+ .doesNotThrowAnyException();
+ }
+
+ @Test
+ default void dispatchShouldNotNotifyRegisteredListenerWhenEmptyKeySet() {
+ MailboxListener listener = newListener();
+ eventBus().register(listener, KEY_1);
+
+ eventBus().dispatch(EVENT, NO_KEYS).block();
+
+ verify(listener, after(FIVE_HUNDRED_MS).never())
+ .event(any());
+ }
+
+ @Test
+ default void dispatchShouldNotNotifyListenerRegisteredOnOtherKeys() {
+ MailboxListener listener = newListener();
+ eventBus().register(listener, KEY_1);
+
+ eventBus().dispatch(EVENT, ImmutableSet.of(KEY_2)).block();
+
+ verify(listener, after(FIVE_HUNDRED_MS).never())
+ .event(any());
+ }
+
+ @Test
+ default void dispatchShouldNotifyRegisteredListeners() {
+ MailboxListener listener = newListener();
+ eventBus().register(listener, KEY_1);
+
+ eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
+
+ verify(listener, timeout(ONE_SECOND).times(1)).event(any());
+ }
+
+ @Test
+ default void dispatchShouldNotifyOnlyRegisteredListener() {
+ MailboxListener listener = newListener();
+ MailboxListener listener2 = newListener();
+ eventBus().register(listener, KEY_1);
+ eventBus().register(listener2, KEY_2);
+
+ eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
+
+ verify(listener, timeout(ONE_SECOND).times(1)).event(any());
+ verify(listener2, after(FIVE_HUNDRED_MS).never())
+ .event(any());
+ }
+
+ @Test
+ default void dispatchShouldNotifyAllListenersRegisteredOnAKey() {
+ MailboxListener listener = newListener();
+ MailboxListener listener2 = newListener();
+ eventBus().register(listener, KEY_1);
+ eventBus().register(listener2, KEY_1);
+
+ eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
+
+ verify(listener, timeout(ONE_SECOND).times(1)).event(any());
+ verify(listener2, timeout(ONE_SECOND).times(1)).event(any());
+ }
+
+ @Test
+ default void registerShouldAllowDuplicatedRegistration() {
+ MailboxListener listener = newListener();
+ eventBus().register(listener, KEY_1);
+ eventBus().register(listener, KEY_1);
+
+ eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
+
+ verify(listener, timeout(ONE_SECOND).times(1)).event(any());
+ }
+
+ @Test
+ default void unregisterShouldRemoveDoubleRegisteredListener() {
+ MailboxListener listener = newListener();
+ eventBus().register(listener, KEY_1);
+ eventBus().register(listener, KEY_1).unregister();
+
+ eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
+
+ verify(listener, after(FIVE_HUNDRED_MS).never())
+ .event(any());
+ }
+
+ @Test
+ default void callingAllUnregisterMethodShouldUnregisterTheListener() {
+ MailboxListener listener = newListener();
+ Registration registration = eventBus().register(listener, KEY_1);
+ eventBus().register(listener, KEY_1).unregister();
+ registration.unregister();
+
+ eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
+
+ verify(listener, after(FIVE_HUNDRED_MS).never())
+ .event(any());
+ }
+
+ @Test
+ default void unregisterShouldHaveNotNotifyWhenCalledOnDifferentKeys() {
+ MailboxListener listener = newListener();
+ eventBus().register(listener, KEY_1);
+ eventBus().register(listener, KEY_2).unregister();
+
+ eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
+
+ verify(listener, timeout(ONE_SECOND).times(1)).event(any());
+ }
+
+ @Test
+ default void unregisterShouldBeIdempotentForKeyRegistrations() {
+ MailboxListener listener = newListener();
+
+ Registration registration = eventBus().register(listener, KEY_1);
+ registration.unregister();
+
+ assertThatCode(registration::unregister)
+ .doesNotThrowAnyException();
+ }
+
+ @Test
+ default void dispatchShouldAcceptSeveralKeys() {
+ MailboxListener listener = newListener();
+ eventBus().register(listener, KEY_1);
+
+ eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1, KEY_2)).block();
+
+ verify(listener, timeout(ONE_SECOND).times(1)).event(any());
+ }
+
+ @Test
+ default void dispatchShouldCallListenerOnceWhenSeveralKeysMatching() {
+ MailboxListener listener = newListener();
+ eventBus().register(listener, KEY_1);
+ eventBus().register(listener, KEY_2);
+
+ eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1, KEY_2)).block();
+
+ verify(listener, timeout(ONE_SECOND).times(1)).event(any());
+ }
+
+ @Test
+ default void dispatchShouldNotNotifyUnregisteredListener() {
+ MailboxListener listener = newListener();
+ eventBus().register(listener, KEY_1).unregister();
+
+ eventBus().dispatch(EVENT, ImmutableSet.of(KEY_1)).block();
+
+ verify(listener, after(FIVE_HUNDRED_MS).never())
+ .event(any());
+ }
+
+ @Test
+ default void dispatchShouldNotBlockAsynchronousListener() {
+ MailboxListener listener = newListener();
+ when(listener.getExecutionMode()).thenReturn(MailboxListener.ExecutionMode.ASYNCHRONOUS);
+ CountDownLatch latch = new CountDownLatch(1);
+ doAnswer(invocation -> {
+ latch.await();
+ return null;
+ }).when(listener).event(EVENT);
+
+ assertTimeout(Duration.ofSeconds(2),
+ () -> {
+ eventBus().dispatch(EVENT, NO_KEYS).block();
+ latch.countDown();
+ });
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/bca9ba01/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/InVMEventBusTest.java
----------------------------------------------------------------------
diff --git a/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/InVMEventBusTest.java b/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/InVMEventBusTest.java
index 6d278aa..0241ac7 100644
--- a/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/InVMEventBusTest.java
+++ b/mailbox/event/event-memory/src/test/java/org/apache/james/mailbox/events/InVMEventBusTest.java
@@ -23,7 +23,7 @@ import org.apache.james.mailbox.events.delivery.InVmEventDelivery;
import org.apache.james.metrics.api.NoopMetricFactory;
import org.junit.jupiter.api.BeforeEach;
-public class InVMEventBusTest implements EventBusContract {
+public class InVMEventBusTest implements KeyContract.SingleEventBusKeyContract, GroupContract.SingleEventBusGroupContract {
private InVMEventBus eventBus;
@BeforeEach
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org