/* * Copyright 2000-2006 JetBrains s.r.o. * * Licensed 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 jetbrains.communicator.core.impl.dispatcher; import jetbrains.communicator.BaseTestCase; import jetbrains.communicator.core.users.User; import jetbrains.communicator.mock.MockIDEFacade; import jetbrains.communicator.mock.MockMessage; import jetbrains.communicator.mock.MockUser; import jetbrains.communicator.util.WaitFor; import org.apache.log4j.Logger; /** * @author kir */ @SuppressWarnings({"HardCodedStringLiteral"}) public class AsyncMessageDispatcherTest extends BaseTestCase { private static final Logger LOG = Logger.getLogger(AsyncMessageDispatcherTest.class); private AsyncMessageDispatcherImpl myDispatcher; private MockUser myUser; private MockIDEFacade myIdeFacade; private String[] myLog; @Override protected void setUp() throws Exception { super.setUp(); myIdeFacade = new MockIDEFacade(getClass()); myUser = new MockUser("user", null); myUser.setOnline(true); myDispatcher = new AsyncMessageDispatcherImpl(getBroadcaster(), myIdeFacade); new WaitFor(1000) { @Override protected boolean condition() { return myDispatcher.isRunning(); } }; myLog = new String[]{""}; } @Override protected void tearDown() throws Exception { myDispatcher.clearAll(); myDispatcher.dispose(); assertFalse(myDispatcher.isRunning()); super.tearDown(); } public void testDispose() throws Exception { } public void testAsyncDispatch_Success() throws Exception { NotifyableMessage mockMessage = new NotifyableMessage(true, myLog); myDispatcher.sendLater(new MockUser(), mockMessage); myLog[0] += "Returned"; mockMessage.waitUntilDispatchingStarted(); triggerMessageProcessing(mockMessage); assertEquals("Should return from method call and than process the message", "ReturnedProcessed", myLog[0]); assertEquals("Messages should be delivered", 0, myDispatcher.getUsersWithMessages().length); } private void triggerMessageProcessing(final NotifyableMessage mockMessage) { mockMessage.triggerProcess(); new WaitFor(10000) { @Override protected boolean condition() { return !myDispatcher.isMessageDispatchInProgress(); } }; } public void testAsyncDispatch_Failure() throws Exception { NotifyableMessage mockMessage = new NotifyableMessage(false, myLog); myDispatcher.sendLater(new MockUser(), mockMessage); myLog[0] += "Returned"; mockMessage.waitUntilDispatchingStarted(); triggerMessageProcessing(mockMessage); assertEquals("Should return from method call and than process the message", "ReturnedProcessed", myLog[0]); assertEquals("Messages should not be delivered", 1, myDispatcher.getUsersWithMessages().length); } public void testAddMessagesWhileDispatching() throws Exception { NotifyableMessage mockMessage = new NotifyableMessage(true, myLog); MockUser user1 = new MockUser("user1", null); MockUser user2 = new MockUser("user2", null); user1.setOnline(true); user2.setOnline(true); myDispatcher.sendLater(user1, mockMessage); mockMessage.waitUntilDispatchingStarted(); myDispatcher.sendLater(user2, new MockMessage(true)); assertEquals("Messages not delivered yet", 2, myDispatcher.getUsersWithMessages().length); triggerMessageProcessing(mockMessage); new WaitFor(200) { @Override protected boolean condition() { return myDispatcher.getUsersWithMessages().length == 0; } }; assertEquals("All messages should be delivered", 0, myDispatcher.getUsersWithMessages().length); } private static class NotifyableMessage extends MockMessage { private boolean myDispatchingStarted; private boolean myProcessed; private final String[] myLog1; NotifyableMessage(boolean successfulDelivery, String[] log) { super(successfulDelivery); myLog1 = log; } public void waitUntilDispatchingStarted() { new WaitFor(10000) { @Override protected boolean condition() { return myDispatchingStarted; } }; } @Override public synchronized boolean send(User user) { try { LOG.debug("AsyncMessageDispatcherTest$NotifyableMessage.StartProcessing"); myDispatchingStarted = true; wait(); myLog1[0] += "Processed"; LOG.debug("AsyncMessageDispatcherTest$NotifyableMessage.Processed"); myProcessed = true; } catch (InterruptedException e) { fail("Unexpected interrupt"); } return super.send(user); } public synchronized boolean isProcessed() { return myProcessed; } public synchronized void triggerProcess() { LOG.debug("Before trigger"); notifyAll(); LOG.debug("After trigger"); } public String toString() { return "TestMessage@" + System.identityHashCode(this); } } }