/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.toolkit.modules.concurrency.internal; import java.util.Random; import java.util.concurrent.CountDownLatch; import org.junit.Assert; import org.junit.Test; import de.rcenvironment.toolkit.modules.concurrency.api.AsyncCallback; import de.rcenvironment.toolkit.modules.concurrency.api.AsyncCallbackExceptionPolicy; import de.rcenvironment.toolkit.modules.concurrency.api.AsyncOrderedCallbackManager; /** * Unit test for {@link AsyncOrderedCallbackManagerImpl}. * * @author Robert Mischke */ public class AsyncOrderedCallbackManagerImplTest extends AbstractConcurrencyModuleTest { private static final int TEST_TIMEOUT = 10000; private static final int CALLBACK_COUNT = 1000; private static final int NONE = -1; private static final int NUM_LISTENERS = 200; private volatile CountDownLatch cdl; /** * A callback interface for exceptions in asynchronous tasks. * * @author Robert Mischke */ public class TestListener { private int last = NONE; private final Random random = new Random(); public TestListener(int listenerId) {} /** * Verifying callback method. * * @param i test value */ public void onNewValue(int i) { // verify sequence if (last == NONE) { Assert.assertEquals(0, i); } else { Assert.assertEquals(last + 1, i); } last = i; try { // add some jitter Thread.sleep(random.nextInt(5)); } catch (InterruptedException e) { throw new RuntimeException(e); } if (i == CALLBACK_COUNT - 1) { cdl.countDown(); } } } /** * Verifies that callbacks are received in-order by multiple listeners. * * @throws InterruptedException on test cancellation */ @Test(timeout = TEST_TIMEOUT) public void testMultithreadedCallbackBehaviour() throws InterruptedException { AsyncOrderedCallbackManager<TestListener> callbackManager = getConcurrencyUtilsFactory().createAsyncOrderedCallbackManager(AsyncCallbackExceptionPolicy.LOG_AND_PROCEED); cdl = new CountDownLatch(NUM_LISTENERS); for (int listenerId = 0; listenerId < NUM_LISTENERS; listenerId++) { callbackManager.addListener(new TestListener(listenerId)); } for (int i = 0; i < CALLBACK_COUNT; i++) { final int i2 = i; callbackManager.enqueueCallback(new AsyncCallback<TestListener>() { @Override public void performCallback(TestListener listener) { listener.onNewValue(i2); } }); } cdl.await(); // LogFactory.getLog(getClass()).info(SharedThreadPool.getInstance().getFormattedStatistics()); } // TODO add test to verify that a blocking listener does not stop callbacks to other listeners // TODO add test for listener exception handling }