/** * Copyright (C) 2009 - 2009 by OpenGamma Inc. * * Please see distribution for license. */ package com.opengamma.financial.view; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertFalse; import static org.testng.AssertJUnit.assertNotNull; import static org.testng.AssertJUnit.assertNull; import static org.testng.AssertJUnit.assertTrue; import java.util.Collection; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import org.testng.annotations.Test; import org.threeten.bp.Instant; import com.opengamma.core.change.ChangeEvent; import com.opengamma.core.change.ChangeListener; import com.opengamma.core.change.ChangeManager; import com.opengamma.core.change.ChangeProvider; import com.opengamma.core.change.ChangeType; import com.opengamma.core.config.ConfigSource; import com.opengamma.engine.ComputationTarget; import com.opengamma.engine.function.CachingFunctionRepositoryCompiler; import com.opengamma.engine.function.CompiledFunctionService; import com.opengamma.engine.function.FunctionCompilationContext; import com.opengamma.engine.function.InMemoryFunctionRepository; import com.opengamma.engine.marketdata.InMemoryNamedMarketDataSpecificationRepository; import com.opengamma.engine.resource.EngineResourceManager; import com.opengamma.engine.test.MockFunction; import com.opengamma.engine.view.ViewProcess; import com.opengamma.engine.view.client.ViewClient; import com.opengamma.engine.view.cycle.ViewCycle; import com.opengamma.engine.view.event.ViewProcessorEventListenerRegistry; import com.opengamma.engine.view.impl.ViewProcessorInternal; import com.opengamma.id.ObjectId; import com.opengamma.id.UniqueId; import com.opengamma.livedata.UserPrincipal; import com.opengamma.util.test.TestGroup; import com.opengamma.util.test.Timeout; /** * Test. */ @Test(groups = TestGroup.INTEGRATION) public class ViewProcessorManagerTest { //------------------------------------------------------------------------- private static class MockViewProcessor implements ViewProcessorInternal { private final CompiledFunctionService _compiledFunctionService; private final LinkedBlockingQueue<Boolean> _suspendState = new LinkedBlockingQueue<Boolean>(); private boolean _running; private boolean _suspended; public MockViewProcessor() { final InMemoryFunctionRepository functions = new InMemoryFunctionRepository(); _compiledFunctionService = new CompiledFunctionService(functions, new CachingFunctionRepositoryCompiler(), new FunctionCompilationContext()); functions.addFunction(new MockFunction("mock", ComputationTarget.NULL) { @Override public void init(final FunctionCompilationContext context) { context.getFunctionReinitializer().reinitializeFunction(getFunctionDefinition(), ObjectId.of("Test", "Watched")); } }); } @Override public Future<Runnable> suspend(final ExecutorService executorService) { return executorService.submit(new Runnable() { @Override public void run() { synchronized (MockViewProcessor.this) { assertTrue(_running); assertFalse(_suspended); _suspended = true; _suspendState.add(Boolean.TRUE); } } }, (Runnable) new Runnable() { @Override public void run() { synchronized (MockViewProcessor.this) { assertTrue(_running); assertTrue(_suspended); _suspended = false; _suspendState.add(Boolean.FALSE); } } }); } @Override public synchronized boolean isRunning() { return _running; } @Override public synchronized void start() { assertFalse(_running); _running = true; } @Override public synchronized void stop() { assertTrue(_running); _running = false; } public Boolean isSuspended(final long timeout) throws InterruptedException { return _suspendState.poll(timeout, TimeUnit.MILLISECONDS); } @Override public String getName() { return null; } @Override public ConfigSource getConfigSource() { return null; } @Override public Collection<? extends ViewProcess> getViewProcesses() { return null; } @Override public ViewProcess getViewProcess(UniqueId viewProcessId) { return null; } @Override public Collection<ViewClient> getViewClients() { return null; } @Override public ViewClient createViewClient(UserPrincipal clientUser) { return null; } @Override public ViewClient getViewClient(UniqueId clientId) { return null; } @Override public CompiledFunctionService getFunctionCompilationService() { return _compiledFunctionService; } @Override public ViewProcessorEventListenerRegistry getViewProcessorEventListenerRegistry() { return null; } @Override public EngineResourceManager<ViewCycle> getViewCycleManager() { return null; } @Override public InMemoryNamedMarketDataSpecificationRepository getNamedMarketDataSpecificationRepository() { return null; } } //------------------------------------------------------------------------- private static final class MockChangeManager implements ChangeManager { private ChangeListener _listener; @Override public void addChangeListener(ChangeListener listener) { assertNull(_listener); _listener = listener; } @Override public void removeChangeListener(ChangeListener listener) { assertEquals(listener, _listener); _listener = null; } public boolean hasListener() { return _listener != null; } @Override public void entityChanged(ChangeType type, ObjectId oid, Instant versionFrom, Instant versionTo, Instant versionInstant) { } public void notifyListenerUnwatchedIdentifier() { _listener.entityChanged(new ChangeEvent(ChangeType.CHANGED, ObjectId.of("Test", "Unwatched"), null, null, Instant.now())); } public void notifyListenerWatchedIdentifier() { _listener.entityChanged(new ChangeEvent(ChangeType.CHANGED, ObjectId.of("Test", "Watched"), null, null, Instant.now())); } } //------------------------------------------------------------------------- private static class MockNotifyingMaster implements ChangeProvider { private ChangeManager _changeManager = new MockChangeManager(); @Override public ChangeManager changeManager() { return _changeManager; } } //------------------------------------------------------------------------- @Test public void testBasicOperation() throws InterruptedException { final ViewProcessorManager vpm = new ViewProcessorManager(); final MockViewProcessor vp = new MockViewProcessor(); vpm.setViewProcessor(vp); final MockNotifyingMaster master = new MockNotifyingMaster(); final MockChangeManager changeManger = (MockChangeManager) master.changeManager(); vpm.setMaster(master); // Check normal startup vpm.start(); assertTrue(changeManger.hasListener()); assertTrue(vpm.isRunning()); assertTrue(vp.isRunning()); Long initialId = vp.getFunctionCompilationService().getFunctionCompilationContext().getFunctionInitId(); assertNotNull(initialId); // Notify it of a change to the master Thread.sleep(10); changeManger.notifyListenerUnwatchedIdentifier(); assertNull(vp.isSuspended(Timeout.standardTimeoutMillis())); changeManger.notifyListenerWatchedIdentifier(); assertEquals(Boolean.TRUE, vp.isSuspended(Timeout.standardTimeoutMillis())); Long newId = 0L; for (int i = 0; i < 10; i++) { Thread.sleep(Timeout.standardTimeoutMillis() / 10); newId = vp.getFunctionCompilationService().getFunctionCompilationContext().getFunctionInitId(); } assertTrue(newId > initialId); assertEquals(Boolean.FALSE, vp.isSuspended(Timeout.standardTimeoutMillis())); // Shutdown vpm.stop(); assertFalse(vpm.isRunning()); assertFalse(vp.isRunning()); assertFalse(changeManger.hasListener()); } }