package org.marketcetera.marketdata; import static org.junit.Assert.*; import static org.marketcetera.marketdata.AssetClass.EQUITY; import static org.marketcetera.marketdata.AssetClass.FUTURE; import static org.marketcetera.marketdata.AssetClass.OPTION; import java.util.*; import java.util.concurrent.Callable; import java.util.concurrent.Semaphore; import org.junit.Assert; import org.junit.Test; import org.marketcetera.core.ExpectedTestFailure; import org.marketcetera.core.IFeedComponentListener; import org.marketcetera.core.publisher.ISubscriber; import org.marketcetera.core.publisher.MockSubscriber; import org.marketcetera.event.*; import org.marketcetera.marketdata.IFeedComponent.FeedType; import org.marketcetera.marketdata.MarketDataFeedToken.Status; import org.marketcetera.module.ExpectedFailure; import org.marketcetera.trade.Equity; import org.marketcetera.util.misc.ClassVersion; /* $License$ */ /** * Tests {@link AbstractMarketDataFeed}. * * @author <a href="mailto:colin@marketcetera.com">Colin DuPlantis</a> * @version $Id: AbstractMarketDataFeedTest.java 16154 2012-07-14 16:34:05Z colin $ * @since 0.5.0 */ @ClassVersion("$Id: AbstractMarketDataFeedTest.java 16154 2012-07-14 16:34:05Z colin $") public class AbstractMarketDataFeedTest extends MarketDataFeedTestBase implements Messages { private final Equity metc = new Equity("METC"); private final String exchange = "TEST"; @Test public void testConstructor() throws Exception { final String providerName = "TestProviderName"; final FeedType type = FeedType.UNKNOWN; new ExpectedTestFailure(NullPointerException.class) { protected void execute() throws Throwable { new MockMarketDataFeed(null, providerName, 0); } }.run(); new ExpectedTestFailure(NullPointerException.class) { protected void execute() throws Throwable { new MockMarketDataFeed(type, null, 0); } }.run(); MockMarketDataFeed feed = new MockMarketDataFeed(type, providerName, 0); assertNotNull(feed); assertEquals(type, feed.getFeedType()); assertNotNull(feed.getID()); assertEquals(FeedStatus.OFFLINE, feed.getFeedStatus()); feed = new MockMarketDataFeed(type, providerName, 0); assertNotNull(feed); assertEquals(type, feed.getFeedType()); assertNotNull(feed.getID()); assertEquals(FeedStatus.OFFLINE, feed.getFeedStatus()); } @Test public void testCancel() throws Exception { final MockMarketDataFeed feed = new MockMarketDataFeed(FeedType.UNKNOWN); feed.start(); feed.login(new MockMarketDataFeedCredentials()); ISubscriber[] subscribers = new ISubscriber[0]; new ExpectedTestFailure(NullPointerException.class) { protected void execute() throws Throwable { feed.cancel(null); } }.run(); MarketDataFeedTokenSpec spec = MarketDataFeedTokenSpec.generateTokenSpec(dataRequest, subscribers); MockMarketDataFeedToken token = feed.execute(spec); feed.cancel(token); verifyAllCanceled(feed); feed.setCancelFails(true); token = feed.execute(token.getTokenSpec()); feed.cancel(token); verifyAllCanceled(feed); // set it so the execution step returns no handles, thus guaranteeing that the cancel // token request can't match any handles feed.setExecuteReturnsNothing(true); feed.setCancelFails(false); // execute the same query token = feed.execute(token.getTokenSpec()); feed.cancel(token); verifyAllCanceled(feed); } @Test public void testStart() throws Exception { MockMarketDataFeed feed = new MockMarketDataFeed(FeedType.UNKNOWN); assertFalse(feed.isRunning()); feed.start(); assertFalse(feed.isRunning()); feed.login(new MockMarketDataFeedCredentials()); assertTrue(feed.isRunning()); feed.stop(); assertFalse(feed.isRunning()); } @Test public void testStop() throws Exception { MockMarketDataFeed feed = new MockMarketDataFeed(FeedType.UNKNOWN); MarketDataRequest request1 = MarketDataRequestBuilder.newRequest().withExchange("Exchange").withSymbols("GOOG,MSFT").create(); MarketDataRequest request2 = MarketDataRequestBuilder.newRequest().withExchange("Exchange").withSymbols("YHOO").create(); MockMarketDataFeedCredentials credentials = new MockMarketDataFeedCredentials(); MockSubscriber subscriber = new MockSubscriber(); MarketDataFeedTokenSpec spec1 = MarketDataFeedTokenSpec.generateTokenSpec(request1, subscriber); MarketDataFeedTokenSpec spec2 = MarketDataFeedTokenSpec.generateTokenSpec(request2, subscriber); feed.start(); feed.login(credentials); MockMarketDataFeedToken token1 = feed.execute(spec1); MockMarketDataFeedToken token2 = feed.execute(spec2); assertEquals(Status.ACTIVE, token1.getStatus()); assertEquals(Status.ACTIVE, token2.getStatus()); assertTrue(feed.getCanceledHandles().isEmpty()); feed.stop(); assertEquals(Status.SUSPENDED, token1.getStatus()); assertEquals(Status.SUSPENDED, token2.getStatus()); assertEquals(2, feed.getCanceledHandles().size()); } @Test public void testDoInitialize() throws Exception { MockMarketDataFeed feed = new MockMarketDataFeed(FeedType.UNKNOWN); feed.setInitFails(false); assertTrue(feed.doInitialize(null)); MarketDataFeedTokenSpec tokenSpec = MarketDataFeedTokenSpec.generateTokenSpec(dataRequest, new ISubscriber[0]); MockMarketDataFeedToken token = MockMarketDataFeedToken.getToken(tokenSpec, feed); assertTrue(feed.doInitialize(token)); } @Test public void testBeforeDoExecute() throws Exception { MockMarketDataFeed feed = new MockMarketDataFeed(FeedType.UNKNOWN); assertTrue(feed.beforeDoExecute(null)); MarketDataFeedTokenSpec tokenSpec = MarketDataFeedTokenSpec.generateTokenSpec(dataRequest, new ISubscriber[0]); MockMarketDataFeedToken token = MockMarketDataFeedToken.getToken(tokenSpec, feed); assertTrue(feed.beforeDoExecute(token)); } @Test public void testAfterDoExecute() throws Exception { MockMarketDataFeed feed = new MockMarketDataFeed(FeedType.UNKNOWN); MarketDataFeedTokenSpec tokenSpec = MarketDataFeedTokenSpec.generateTokenSpec(dataRequest, new ISubscriber[0]); MockMarketDataFeedToken token = MockMarketDataFeedToken.getToken(tokenSpec, feed); feed.afterDoExecute(null, null, null); feed.afterDoExecute(token, null, null); feed.afterDoExecute(token, new ArrayList<String>(), null); } @Test public void testSetFeedStatus() throws Exception { final MockMarketDataFeed feed = new MockMarketDataFeed(FeedType.UNKNOWN); new ExpectedTestFailure(NullPointerException.class) { protected void execute() throws Throwable { feed.setFeedStatus(null); } }.run(); TestFeedComponentListener listener = new TestFeedComponentListener(); assertTrue(listener.getChangedComponents().isEmpty()); feed.addFeedComponentListener(listener); assertEquals(FeedStatus.OFFLINE, feed.getFeedStatus()); feed.setFeedStatus(FeedStatus.UNKNOWN); listener.mSemaphore.acquire(); assertEquals(1, listener.getChangedComponents().size()); assertEquals(feed, listener.getChangedComponents().get(0)); listener.mSemaphore.release(); listener.reset(); // change feed status, make sure listener gets updated feed.setFeedStatus(FeedStatus.AVAILABLE); listener.mSemaphore.acquire(); assertEquals(FeedStatus.AVAILABLE, feed.getFeedStatus()); assertEquals(1, listener.getChangedComponents().size()); assertEquals(feed, listener.getChangedComponents().get(0)); listener.mSemaphore.release(); listener.reset(); // make sure listener is not notified if set to the same status feed.setFeedStatus(FeedStatus.AVAILABLE); Thread.sleep(1000); assertTrue(listener.getChangedComponents().isEmpty()); } @Test public void testFeedComponentListener() throws Exception { final MockMarketDataFeed feed = new MockMarketDataFeed(FeedType.UNKNOWN); new ExpectedTestFailure(NullPointerException.class) { protected void execute() throws Throwable { feed.addFeedComponentListener(null); } }.run(); new ExpectedTestFailure(NullPointerException.class) { protected void execute() throws Throwable { feed.removeFeedComponentListener(null); } }.run(); TestFeedComponentListener listener = new TestFeedComponentListener(); assertTrue(listener.getChangedComponents().isEmpty()); feed.start(); assertTrue(listener.getChangedComponents().isEmpty()); feed.addFeedComponentListener(listener); feed.stop(); listener.mSemaphore.acquire(); assertEquals(1, listener.getChangedComponents().size()); assertEquals(feed, listener.getChangedComponents().get(0)); listener.mSemaphore.release(); listener.reset(); // re-add the same listener, make sure there's only one notification feed.addFeedComponentListener(listener); feed.start(); listener.mSemaphore.acquire(); assertEquals(1, listener.getChangedComponents().size()); assertEquals(feed, listener.getChangedComponents().get(0)); listener.mSemaphore.release(); listener.reset(); // remove a listener that's not subscribed feed.removeFeedComponentListener(new IFeedComponentListener() { @Override public void feedComponentChanged(IFeedComponent component) { } }); feed.stop(); listener.mSemaphore.acquire(); assertEquals(1, listener.getChangedComponents().size()); assertEquals(feed, listener.getChangedComponents().get(0)); listener.mSemaphore.release(); listener.reset(); // remove actual listener feed.removeFeedComponentListener(listener); feed.start(); Thread.sleep(1000); assertTrue(listener.getChangedComponents().isEmpty()); } @Test public void testDataReceived() throws Exception { final MockMarketDataFeed feed = new MockMarketDataFeed(FeedType.UNKNOWN); new ExpectedTestFailure(NullPointerException.class) { protected void execute() throws Throwable { feed.dataReceived(null, this); } }.run(); feed.dataReceived("handle", null); } /** * Tests the feed's ability to timeout a request and throw the correct exception. * * @throws Exception if an error occurs */ @Test public void testTimeout() throws Exception { final MockMarketDataFeed feed = new MockMarketDataFeed(FeedType.UNKNOWN); feed.start(); feed.login(new MockMarketDataFeedCredentials()); feed.setShouldTimeout(true); final MarketDataFeedTokenSpec spec = MarketDataFeedTokenSpec.generateTokenSpec(MarketDataRequestBuilder.newRequest().withExchange("Exchange").withSymbols("GOOG").create(), new ISubscriber[0]); new ExpectedTestFailure(FeedException.class, Messages.ERROR_MARKET_DATA_FEED_EXECUTION_FAILED.getText()) { protected void execute() throws Throwable { feed.execute(spec); } }.run(); } /** * Tests the ability of a feed to resubmit active queries * upon reconnect. * * @throws Exception if the test fails */ @Test public void testReconnect() throws Exception { // 1) Create feed, verify status is !running, verify no active queries // 2) Start feed, verify status is running, verify no active queries // 3) Submit a query, verify subscriber gets response // 4) Stop feed, verify status is !running, verify active queries // 5) Start feed, verify status is running, verify active queries // 6) Verify subscriber gets update // #1 MockMarketDataFeed feed = new MockMarketDataFeed(FeedType.UNKNOWN); assertEquals(FeedStatus.OFFLINE, feed.getFeedStatus()); assertFalse(feed.getFeedStatus().isRunning()); assertTrue(feed.getCreatedHandles().isEmpty()); // #2 feed.start(); feed.login(new MockMarketDataFeedCredentials()); assertEquals(FeedStatus.AVAILABLE, feed.getFeedStatus()); assertTrue(feed.getFeedStatus().isRunning()); assertTrue(feed.getCreatedHandles().isEmpty()); // #3 MockSubscriber s1 = new MockSubscriber(); MarketDataRequest request0 = MarketDataRequestBuilder.newRequest().withExchange("Exchange").withSymbols("test").create(); MarketDataFeedTokenSpec spec = MarketDataFeedTokenSpec.generateTokenSpec(request0, s1); MockMarketDataFeedToken token = feed.execute(spec); waitForPublication(s1); assertEquals(token, ((MockEvent)s1.getData()).getSource()); assertEquals(1, s1.getPublishCount()); assertEquals(Status.ACTIVE, token.getStatus()); // #4 assertTrue(feed.isLoggedIn()); feed.stop(); assertFalse(feed.isLoggedIn()); assertEquals(FeedStatus.OFFLINE, feed.getFeedStatus()); assertFalse(feed.getFeedStatus().isRunning()); List<String> handleList1 = feed.getCreatedHandles(); assertEquals(1, handleList1.size()); assertEquals(Status.SUSPENDED, token.getStatus()); // #5 // reset the statistics on s1 s1.reset(); assertEquals(0, s1.getPublishCount()); // restart feed, should trigger a resubmission of the query for message0 feed.start(); feed.login(new MockMarketDataFeedCredentials()); assertTrue(feed.isLoggedIn()); assertEquals(FeedStatus.AVAILABLE, feed.getFeedStatus()); assertTrue(feed.getFeedStatus().isRunning()); assertEquals(handleList1, feed.getCanceledHandles()); // #6 // query should have been resubmitted, waitForPublication(s1); assertEquals(1, s1.getPublishCount()); assertEquals(token, ((MockEvent)s1.getData()).getSource()); assertEquals(Status.ACTIVE, token.getStatus()); // now check to make sure that the resubmitted query has a new handle List<String> handleList2 = feed.getCreatedHandles(); assertEquals(2, handleList2.size()); // create two new requests to use MarketDataRequest request1 = MarketDataRequestBuilder.newRequest().withExchange("Exchange").withSymbols("COLIN").create(); MarketDataRequest request2 = MarketDataRequestBuilder.newRequest().withExchange("Exchange").withSymbols("NOT-COLIN").create(); assertFalse(request1.equals(request2)); // reset the subscriber counters s1.reset(); // submit data to the old handle feed.submitData(handleList1.get(0), request1); // we could wait for a little bit and make sure the data wasn't received, // but that wouldn't be deterministic. instead, we'll right away submit a // second message to the new handle and make sure that s1 got that one and // only that one. since the second message will have to be delivered after // the first one, once we're sure the second one has gotten through, if the // first one still isn't there, then we know for sure it worked as planned feed.submitData(handleList2.get(1), request2); waitForPublication(s1); assertEquals(1, s1.getPublishCount()); assertEquals(token, ((MockEvent)s1.getPublications().get(0)).getSource()); // bonus testing - make a resubmission fail and verify that the token status is set correctly // there is already one active query represented by "spec" and "token" - add another one that // we can set to fail when it is resubmitted s1.reset(); MarketDataFeedTokenSpec spec2 = MarketDataFeedTokenSpec.generateTokenSpec(spec.getDataRequest(), spec.getSubscribers()); MockMarketDataFeedToken token2 = feed.execute(spec2); waitForPublication(s1); assertEquals(token2, ((MockEvent)s1.getData()).getSource()); assertEquals(1, s1.getPublishCount()); assertEquals(Status.ACTIVE, token2.getStatus()); // the feed now has 2 active queries assertTrue(feed.isLoggedIn()); feed.stop(); assertFalse(feed.isLoggedIn()); // before we restart the feed, set the first query to fail on resubmission s1.reset(); token.setShouldFail(true); feed.start(); feed.login(new MockMarketDataFeedCredentials()); assertTrue(feed.isLoggedIn()); assertEquals(FeedStatus.AVAILABLE, feed.getFeedStatus()); assertTrue(feed.getFeedStatus().isRunning()); waitForPublication(s1); // check token status assertEquals(Status.EXECUTION_FAILED, token.getStatus()); assertEquals(Status.ACTIVE, token2.getStatus()); } /** * Tests the ability of a feed to reject a request for an unsupported asset class. * * @throws Exception if an unexpected error occurs */ @Test public void unsupportedAssetClass() throws Exception { final MockMarketDataFeed feed = new MockMarketDataFeed(FeedType.UNKNOWN); feed.start(); feed.login(new MockMarketDataFeedCredentials()); // feed supports no asset classes feed.setAssetClasses(EnumSet.noneOf(AssetClass.class)); assertTrue(feed.getSupportedAssetClasses().isEmpty()); final MarketDataRequestBuilder builder = MarketDataRequestBuilder.newRequest().withSymbols("COLIN"); assertNotNull(builder.create().getAssetClass()); new ExpectedFailure<FeedException>(Messages.UNSUPPORTED_ASSET_CLASS) { @Override protected void run() throws Exception { feed.execute(MarketDataFeedTokenSpec.generateTokenSpec(builder.create())); } }; // feed supports some asset classes, but not all feed.setAssetClasses(EnumSet.of(FUTURE, EQUITY)); builder.withAssetClass(OPTION); new ExpectedFailure<FeedException>(Messages.UNSUPPORTED_ASSET_CLASS) { @Override protected void run() throws Exception { feed.execute(MarketDataFeedTokenSpec.generateTokenSpec(builder.create())); } }; // feed supports all asset classes feed.setAssetClasses(EnumSet.allOf(AssetClass.class)); for(AssetClass asset : AssetClass.values()) { builder.withAssetClass(asset); feed.execute(MarketDataFeedTokenSpec.generateTokenSpec(builder.create())); } } private static class TestFeedComponentListener implements IFeedComponentListener { private Semaphore mSemaphore = new Semaphore(1); private List<IFeedComponent> mChangedComponents = new ArrayList<IFeedComponent>(); private TestFeedComponentListener() throws Exception { mSemaphore.acquire(); } @Override public void feedComponentChanged(IFeedComponent component) { synchronized(mChangedComponents) { mChangedComponents.add(component); } mSemaphore.release(); } private void reset() throws InterruptedException { synchronized(mChangedComponents) { mChangedComponents.clear(); } mSemaphore.acquire(); } private List<IFeedComponent> getChangedComponents() { synchronized(mChangedComponents) { return new ArrayList<IFeedComponent>(mChangedComponents); } } } private void verifyAllCanceled(MockMarketDataFeed inFeed) throws Exception { List<String> createdHandles = inFeed.getCreatedHandles(); List<String> canceledHandles = inFeed.getCanceledHandles(); assertEquals(createdHandles.size(), canceledHandles.size()); assertTrue(Arrays.equals(createdHandles.toArray(), canceledHandles.toArray())); } @Test public void testPublishEventsThrowsException() throws Exception { MockSubscriber subscriber1 = new MockSubscriber(); MockSubscriber subscriber2 = new MockSubscriber(); MockSubscriber subscriber3 = new MockSubscriber(); subscriber2.setPublishThrows(true); assertFalse(subscriber1.getPublishThrows()); assertTrue(subscriber2.getPublishThrows()); assertFalse(subscriber3.getPublishThrows()); MockMarketDataFeed feed = new MockMarketDataFeed(); feed.start(); feed.login(new MockMarketDataFeedCredentials()); ISubscriber[] subscribers = new ISubscriber[] { subscriber1, subscriber2, subscriber3 }; MarketDataFeedTokenSpec spec = MarketDataFeedTokenSpec.generateTokenSpec(dataRequest, subscribers); MockMarketDataFeedToken token = feed.execute(spec); // make sure that 1 & 3 received publications despite 2's rudeness assertNotNull(token); while(subscriber1.getData() == null) { Thread.sleep(100); } assertEquals(1, subscriber1.getPublishCount()); assertEquals(0, subscriber2.getPublishCount()); while(subscriber3.getData() == null) { Thread.sleep(100); } assertEquals(1, subscriber3.getPublishCount()); } @Test public void testExecute() throws Exception { MockSubscriber subscriber = new MockSubscriber(); for(int a=0;a<=1;a++) { for(int b=0;b<=1;b++) { doExecuteTest(a==0 ? null : dataRequest, b==0 ? null : subscriber, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false); } } subscriber.reset(); MarketDataRequest fullDepthMessage = MarketDataRequestBuilder.newRequest().withExchange("Exchange").withSymbols("GOOG").withContent(Content.TOTAL_VIEW).create(); doExecuteTest(fullDepthMessage, subscriber, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false); } @Test public void testParallelExecution() throws Exception { MockMarketDataFeed feed = new MockMarketDataFeed(FeedType.UNKNOWN, "MockMarketDataFeed", 25); feed.start(); feed.login(new MockMarketDataFeedCredentials()); List<MockSubscriber> subscribers = new ArrayList<MockSubscriber>(); List<MockMarketDataFeedToken> tokens = new ArrayList<MockMarketDataFeedToken>(); for(int i=0;i<1000;i++) { MockSubscriber s = new MockSubscriber(); subscribers.add(s); MarketDataFeedTokenSpec tokenSpec = MarketDataFeedTokenSpec.generateTokenSpec(dataRequest, subscribers.toArray(new MockSubscriber[subscribers.size()])); tokens.add(feed.execute(tokenSpec)); } for(MockSubscriber s : subscribers) { while(s.getData() == null) { Thread.sleep(50); } } for(MockMarketDataFeedToken token : tokens) { feed.cancel(token); } assertEquals(feed.getCreatedHandles(), feed.getCanceledHandles()); assertTrue(Arrays.equals(feed.getCreatedHandles().toArray(), feed.getCanceledHandles().toArray())); } /** * Tests feed's ability to return capabilities. */ @Test public void testCapabilities() throws Exception { MockMarketDataFeed feed = new MockMarketDataFeed(); assertTrue(Arrays.equals(new Capability[0], feed.getCapabilities().toArray())); Set<Capability> capabilities = EnumSet.of(Capability.MARKET_STAT, Capability.TOP_OF_BOOK); feed.setCapabilities(capabilities); Assert.assertArrayEquals(capabilities.toArray(), feed.getCapabilities().toArray()); } /** * Verifies that {@link AggregateEvent} objects are properly decomposed. * * @throws Exception if an error occurs */ @Test public void decomposition() throws Exception { MockMarketDataFeed feed = new MockMarketDataFeed(FeedType.UNKNOWN); feed.start(); feed.login(new MockMarketDataFeedCredentials()); // set up a subscriber to receive events final MockSubscriber s = new MockSubscriber(); // a market data request (doesn't matter what) MarketDataRequest request = MarketDataRequestBuilder.newRequest().withProvider("not-a-real-provider").withSymbols("METC").create(); // first, have the feed return a non-aggregate event MockEvent e = new MockEvent(); assertTrue(Event.class.isAssignableFrom(e.getClass())); assertFalse(AggregateEvent.class.isAssignableFrom(e.getClass())); feed.setEventsToReturn(Arrays.asList(new Event[] { e } )); feed.execute(MarketDataFeedTokenSpec.generateTokenSpec(request, s)); waitForPublication(s); assertEquals(1, s.getPublishCount()); assertEquals(e, s.getPublications().get(0)); // next, send in an aggregate event and make sure it gets properly decomposed List<QuoteEvent> expectedEvents = Arrays.asList(new QuoteEvent[] { EventTestBase.generateEquityAskEvent(metc, exchange), EventTestBase.generateEquityBidEvent(metc, exchange) } ); MockAggregateEvent mae = new MockAggregateEvent(expectedEvents); feed.setEventsToReturn(Arrays.asList(new Event[] { mae } )); s.reset(); feed.execute(MarketDataFeedTokenSpec.generateTokenSpec(request, s)); MarketDataFeedTestBase.wait(new Callable<Boolean>() { @Override public Boolean call() throws Exception { return s.getPublishCount() == 2; } }); assertEquals(expectedEvents, s.getPublications()); } @Test public void testExecuteFailures() throws Exception { final MockMarketDataFeed feed = new MockMarketDataFeed(); feed.start(); feed.login(new MockMarketDataFeedCredentials()); // test nulls // test execute new ExpectedTestFailure(NullPointerException.class) { protected void execute() throws Throwable { feed.execute(null); } }.run(); // test more intricate failure conditions doExecuteTest(dataRequest, null, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false); doExecuteTest(dataRequest, null, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false); doExecuteTest(dataRequest, null, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false); doExecuteTest(dataRequest, null, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false); doExecuteTest(dataRequest, null, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false); doExecuteTest(dataRequest, null, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false); doExecuteTest(dataRequest, null, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false); doExecuteTest(dataRequest, null, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false); doExecuteTest(dataRequest, null, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false); doExecuteTest(dataRequest, null, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false); doExecuteTest(dataRequest, null, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false); doExecuteTest(dataRequest, null, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false); doExecuteTest(dataRequest, null, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false); doExecuteTest(dataRequest, null, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false); doExecuteTest(dataRequest, null, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false); doExecuteTest(dataRequest, null, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false); doExecuteTest(dataRequest, null, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false); doExecuteTest(dataRequest, null, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true); } private void doExecuteTest(final MarketDataRequest inRequest, final MockSubscriber inSubscriber, boolean inLoginFails, boolean inInitFails, boolean inLoginThrows, boolean inIsLoggedInThrows, boolean inInitThrows, boolean inExecThrows, boolean inGenerateTokenThrows, boolean inGetEventTranslatorThrows, boolean inTranslateToEventsThrows, boolean inTranslateToEventsReturnsNull, boolean inTranslateToEventsReturnsZeroEvents, boolean inBeforeExecuteReturnsFalse, boolean inGetMessageTranslatorThrows, boolean inTranslateThrows, boolean inAfterExecuteThrows, boolean inBeforeExecuteThrows, boolean inRequestReturnsZeroHandles, boolean inRequestReturnsNull) throws Exception { if(inRequest == null) { new ExpectedTestFailure(NullPointerException.class) { protected void execute() throws Throwable { MarketDataFeedTokenSpec.generateTokenSpec(inRequest, inSubscriber); } }.run(); } else { MarketDataFeedTokenSpec tokenSpec = MarketDataFeedTokenSpec.generateTokenSpec(inRequest, inSubscriber); doExecuteTest(tokenSpec, inLoginFails, inInitFails, inLoginThrows, inIsLoggedInThrows, inInitThrows, inExecThrows, inGenerateTokenThrows, inGetEventTranslatorThrows, inTranslateToEventsThrows, inTranslateToEventsReturnsNull, inTranslateToEventsReturnsZeroEvents, inBeforeExecuteReturnsFalse, inGetMessageTranslatorThrows, inTranslateThrows, inAfterExecuteThrows, inBeforeExecuteThrows, inRequestReturnsZeroHandles, inRequestReturnsNull); } } private void doExecuteTest(final MarketDataFeedTokenSpec inTokenSpec, boolean inLoginFails, boolean inInitFails, boolean inLoginThrows, boolean inIsLoggedInThrows, boolean inInitThrows, boolean inExecThrows, boolean inGenerateTokenThrows, boolean inGetEventTranslatorThrows, boolean inTranslateToEventsThrows, boolean inTranslateToEventsReturnsNull, boolean inTranslateToEventsReturnsZeroEvents, boolean inBeforeExecuteReturnsFalse, boolean inGetMessageTranslatorThrows, boolean inTranslateThrows, boolean inAfterExecuteThrows, boolean inBeforeExecuteThrows, boolean inRequestReturnsZeroHandles, boolean inRequestReturnsNull) throws Exception { final MockMarketDataFeed feed = new MockMarketDataFeed(FeedType.UNKNOWN, "obnoxious-feed-name-with-dashes", 0); final ISubscriber[] subscribers = inTokenSpec.getSubscribers(); if(subscribers != null) { for(ISubscriber subscriber : subscribers) { if(subscriber != null) { MockSubscriber s = (MockSubscriber)subscriber; assertNull(s.getData()); } } } feed.setLoginFails(inLoginFails); feed.setInitFails(inInitFails); feed.setExecutionFails(inExecThrows); feed.setLoginThrows(inLoginThrows); feed.setIsLoggedInThrows(inIsLoggedInThrows); feed.setInitThrows(inInitThrows); feed.setGenerateTokenThrows(inGenerateTokenThrows); feed.setGetEventTranslatorThrows(inGetEventTranslatorThrows); MockEventTranslator.setTranslateToEventsThrows(inTranslateToEventsThrows); MockEventTranslator.setTranslateToEventsReturnsNull(inTranslateToEventsReturnsNull); MockEventTranslator.setTranslateToEventsReturnsZeroEvents(inTranslateToEventsReturnsZeroEvents); feed.setBeforeExecuteReturnsFalse(inBeforeExecuteReturnsFalse); feed.setGetMessageTranslatorThrows(inGetMessageTranslatorThrows); MockDataRequestTranslator.setTranslateThrows(inTranslateThrows); feed.setAfterExecuteThrows(inAfterExecuteThrows); feed.setBeforeExecuteThrows(inBeforeExecuteThrows); feed.setExecuteReturnsNothing(inRequestReturnsZeroHandles); feed.setExecuteReturnsNull(inRequestReturnsNull); // start the feed feed.start(); // log in to the feed if(inLoginThrows || inIsLoggedInThrows) { new ExpectedFailure<NullPointerException>() { @Override protected void run() throws Exception { feed.login(new MockMarketDataFeedCredentials()); } }; return; } assertEquals(!inLoginFails, feed.login(new MockMarketDataFeedCredentials())); // check login-failed conditions first if(inLoginFails) { assertEquals(FeedStatus.OFFLINE, feed.getFeedStatus()); return; } // feed is logged in assertEquals(FeedStatus.AVAILABLE, feed.getFeedStatus()); // test token generation if(inGenerateTokenThrows) { new ExpectedFailure<FeedException>(Messages.ERROR_MARKET_DATA_FEED_EXECUTION_FAILED) { @Override protected void run() throws Exception { feed.execute(inTokenSpec); } }; return; } MockMarketDataFeedToken token = feed.execute(inTokenSpec); assertNotNull(token); verifyExecution(inExecThrows, inGetEventTranslatorThrows, inTranslateToEventsThrows, inTranslateToEventsReturnsNull, inTranslateToEventsReturnsZeroEvents, inBeforeExecuteReturnsFalse, inGetMessageTranslatorThrows, inTranslateThrows, inAfterExecuteThrows, inBeforeExecuteThrows, inRequestReturnsZeroHandles, inRequestReturnsNull, feed, token, subscribers); } private void verifyExecution(boolean inExecThrows, boolean inGetEventTranslatorThrows, boolean inTranslateToEventsThrows, boolean inTranslateToEventsReturnsNull, boolean inTranslateToEventsReturnsZeroEvents, boolean inBeforeExecuteReturnsFalse, boolean inGetMessageTranslatorThrows, boolean inTranslateThrows, boolean inAfterExecuteThrows, boolean inBeforeExecuteThrows, boolean inRequestReturnsZeroHandles, boolean inRequestReturnsNull, MockMarketDataFeed inFeed, MockMarketDataFeedToken inToken, ISubscriber[] inSubscribers) throws Exception { if(inExecThrows || inBeforeExecuteReturnsFalse || inBeforeExecuteThrows || inAfterExecuteThrows) { assertEquals(MarketDataFeedToken.Status.EXECUTION_FAILED, inToken.getStatus()); if(inSubscribers != null) { for(ISubscriber subscriber : inSubscribers) { if(subscriber != null) { MockSubscriber s = (MockSubscriber)subscriber; assertEquals(0, s.getPublishCount()); } } } return; } if(inGetMessageTranslatorThrows || inTranslateThrows) { assertEquals(Status.EXECUTION_FAILED, inToken.getStatus()); if(inSubscribers != null) { for(ISubscriber subscriber : inSubscribers) { if(subscriber != null) { MockSubscriber s = (MockSubscriber)subscriber; assertEquals(0, s.getPublishCount()); } } } return; } if(inGetEventTranslatorThrows || inTranslateToEventsThrows || inTranslateToEventsReturnsNull || inTranslateToEventsReturnsZeroEvents) { assertEquals(Status.ACTIVE, inToken.getStatus()); if(inSubscribers != null) { for(ISubscriber subscriber : inSubscribers) { if(subscriber != null) { MockSubscriber s = (MockSubscriber)subscriber; assertEquals(0, s.getPublishCount()); } } } return; } if(inSubscribers != null && !inRequestReturnsZeroHandles && !inRequestReturnsNull) { for(ISubscriber subscriber : inSubscribers) { if(subscriber != null) { MockSubscriber s = (MockSubscriber)subscriber; waitForPublication(s); assertEquals(1, s.getPublishCount()); } } } assertEquals(FeedStatus.AVAILABLE, inFeed.getFeedStatus()); assertEquals(Status.ACTIVE, inToken.getStatus()); } }