/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.engine.calcnode;
import static org.testng.AssertJUnit.assertNotNull;
import static org.testng.AssertJUnit.assertTrue;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.fudgemsg.FudgeContext;
import org.fudgemsg.FudgeMsgEnvelope;
import org.fudgemsg.mapping.FudgeDeserializer;
import org.fudgemsg.mapping.FudgeSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.annotations.Test;
import com.opengamma.engine.cache.InMemoryIdentifierMap;
import com.opengamma.engine.calcnode.msg.Execute;
import com.opengamma.engine.calcnode.msg.Ready;
import com.opengamma.engine.calcnode.msg.RemoteCalcNodeMessage;
import com.opengamma.engine.calcnode.msg.Result;
import com.opengamma.engine.calcnode.stats.FunctionCosts;
import com.opengamma.engine.function.blacklist.DummyFunctionBlacklistMaintainer;
import com.opengamma.engine.function.blacklist.DummyFunctionBlacklistQuery;
import com.opengamma.transport.DirectFudgeConnection;
import com.opengamma.transport.FudgeConnection;
import com.opengamma.transport.FudgeMessageReceiver;
import com.opengamma.util.fudgemsg.OpenGammaFudgeContext;
import com.opengamma.util.test.TestGroup;
import com.opengamma.util.test.Timeout;
/**
* Tests the RemoteNodeJobInvoker
*/
@Test(groups = TestGroup.UNIT)
public class RemoteNodeJobInvokerTest {
private static final Logger s_logger = LoggerFactory.getLogger(RemoteNodeJobInvokerTest.class);
private static final FudgeContext s_fudgeContext = OpenGammaFudgeContext.getInstance();
private static final long TIMEOUT = Timeout.standardTimeoutMillis();
public void simpleInvocation() {
final ExecutorService executor = Executors.newCachedThreadPool();
try {
final JobDispatcher jobDispatcher = new JobDispatcher();
final Ready initialMessage = new Ready(1, "Test");
final DirectFudgeConnection conduit = new DirectFudgeConnection(s_fudgeContext);
final RemoteNodeJobInvoker jobInvoker = new RemoteNodeJobInvoker(executor, initialMessage, conduit.getEnd1(), new InMemoryIdentifierMap(), new FunctionCosts(),
new DummyFunctionBlacklistQuery(), new DummyFunctionBlacklistMaintainer());
jobDispatcher.registerJobInvoker(jobInvoker);
final TestJobResultReceiver resultReceiver = new TestJobResultReceiver();
final FudgeConnection remoteNode = conduit.getEnd2();
remoteNode.setFudgeMessageReceiver(new FudgeMessageReceiver() {
@Override
public void messageReceived(FudgeContext fudgeContext, FudgeMsgEnvelope msgEnvelope) {
final FudgeDeserializer dcontext = new FudgeDeserializer(fudgeContext);
s_logger.debug("message = {}", msgEnvelope.getMessage());
final RemoteCalcNodeMessage message = dcontext.fudgeMsgToObject(RemoteCalcNodeMessage.class, msgEnvelope.getMessage());
assertNotNull(message);
s_logger.debug("request = {}", message);
assertTrue(message instanceof Execute);
final Execute job = (Execute) message;
final Result result = new Result(JobDispatcherTest.createTestJobResult(job.getJob().getSpecification(), 0, "Test"));
final FudgeSerializer scontext = new FudgeSerializer(fudgeContext);
remoteNode.getFudgeMessageSender().send(FudgeSerializer.addClassHeader(scontext.objectToFudgeMsg(result), result.getClass(), RemoteCalcNodeMessage.class));
}
});
jobDispatcher.dispatchJob(JobDispatcherTest.createTestJob(), resultReceiver);
assertNotNull(resultReceiver.waitForResult(TIMEOUT));
} finally {
executor.shutdown();
}
}
public void saturate() {
final ExecutorService executor = Executors.newCachedThreadPool();
try {
final JobDispatcher jobDispatcher = new JobDispatcher();
final Ready initialMessage = new Ready(3, "Test");
final DirectFudgeConnection conduit = new DirectFudgeConnection(s_fudgeContext);
final RemoteNodeJobInvoker jobInvoker = new RemoteNodeJobInvoker(executor, initialMessage, conduit.getEnd1(), new InMemoryIdentifierMap(), new FunctionCosts(),
new DummyFunctionBlacklistQuery(), new DummyFunctionBlacklistMaintainer());
jobDispatcher.registerJobInvoker(jobInvoker);
final FudgeConnection remoteNode = conduit.getEnd2();
final Random rnd = new Random();
remoteNode.setFudgeMessageReceiver(new FudgeMessageReceiver() {
@Override
public void messageReceived(FudgeContext fudgeContext, FudgeMsgEnvelope msgEnvelope) {
final FudgeDeserializer dcontext = new FudgeDeserializer(fudgeContext);
final RemoteCalcNodeMessage message = dcontext.fudgeMsgToObject(RemoteCalcNodeMessage.class, msgEnvelope.getMessage());
assertNotNull(message);
assertTrue(message instanceof Execute);
final Execute job = (Execute) message;
try {
Thread.sleep(rnd.nextInt(30));
} catch (InterruptedException e) {
}
final Result result = new Result(JobDispatcherTest.createTestJobResult(job.getJob().getSpecification(), 0, "Test"));
final FudgeSerializer scontext = new FudgeSerializer(fudgeContext);
remoteNode.getFudgeMessageSender().send(FudgeSerializer.addClassHeader(scontext.objectToFudgeMsg(result), result.getClass(), RemoteCalcNodeMessage.class));
}
});
final TestJobResultReceiver[] resultReceivers = new TestJobResultReceiver[100];
for (int i = 0; i < resultReceivers.length; i++) {
resultReceivers[i] = new TestJobResultReceiver();
jobDispatcher.dispatchJob(JobDispatcherTest.createTestJob(), resultReceivers[i]);
}
for (int i = 0; i < resultReceivers.length; i++) {
assertNotNull(resultReceivers[i].waitForResult(TIMEOUT));
}
} finally {
executor.shutdown();
}
}
}