Package com.opengamma.engine.exec

Source Code of com.opengamma.engine.exec.CancelExecutionTest

/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.engine.exec;

import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertNotNull;
import static org.testng.AssertJUnit.assertTrue;

import java.util.Collections;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import org.fudgemsg.FudgeContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.threeten.bp.Instant;

import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.core.position.impl.MockPositionSource;
import com.opengamma.core.position.impl.SimplePortfolio;
import com.opengamma.engine.ComputationTarget;
import com.opengamma.engine.DefaultComputationTargetResolver;
import com.opengamma.engine.InMemorySecuritySource;
import com.opengamma.engine.cache.InMemoryViewComputationCacheSource;
import com.opengamma.engine.cache.ViewComputationCacheSource;
import com.opengamma.engine.calcnode.CalculationNodeLogEventListener;
import com.opengamma.engine.calcnode.JobDispatcher;
import com.opengamma.engine.calcnode.LocalNodeJobInvoker;
import com.opengamma.engine.calcnode.SimpleCalculationNode;
import com.opengamma.engine.calcnode.stats.DiscardingInvocationStatisticsGatherer;
import com.opengamma.engine.calcnode.stats.FunctionInvocationStatisticsGatherer;
import com.opengamma.engine.depgraph.DependencyGraph;
import com.opengamma.engine.depgraph.DependencyGraphBuilderFactory;
import com.opengamma.engine.depgraph.DependencyNode;
import com.opengamma.engine.exec.stats.DiscardingGraphStatisticsGathererProvider;
import com.opengamma.engine.exec.stats.GraphExecutorStatisticsGathererProvider;
import com.opengamma.engine.function.CachingFunctionRepositoryCompiler;
import com.opengamma.engine.function.CompiledFunctionService;
import com.opengamma.engine.function.FunctionCompilationContext;
import com.opengamma.engine.function.FunctionExecutionContext;
import com.opengamma.engine.function.FunctionInputs;
import com.opengamma.engine.function.InMemoryFunctionRepository;
import com.opengamma.engine.function.resolver.DefaultFunctionResolver;
import com.opengamma.engine.function.resolver.FunctionResolver;
import com.opengamma.engine.marketdata.DummyOverrideOperationCompiler;
import com.opengamma.engine.marketdata.InMemoryLKVMarketDataProvider;
import com.opengamma.engine.marketdata.SingletonMarketDataProviderFactory;
import com.opengamma.engine.marketdata.resolver.MarketDataProviderResolver;
import com.opengamma.engine.marketdata.resolver.SingleMarketDataProviderResolver;
import com.opengamma.engine.marketdata.spec.MarketDataSpecification;
import com.opengamma.engine.resource.EngineResourceManagerImpl;
import com.opengamma.engine.target.ComputationTargetReference;
import com.opengamma.engine.test.MockConfigSource;
import com.opengamma.engine.test.MockFunction;
import com.opengamma.engine.value.ComputedValue;
import com.opengamma.engine.value.ValueRequirement;
import com.opengamma.engine.view.ViewCalculationConfiguration;
import com.opengamma.engine.view.ViewComputationResultModel;
import com.opengamma.engine.view.ViewDefinition;
import com.opengamma.engine.view.compilation.CompiledViewDefinitionWithGraphsImpl;
import com.opengamma.engine.view.cycle.SingleComputationCycle;
import com.opengamma.engine.view.execution.ViewCycleExecutionOptions;
import com.opengamma.engine.view.impl.ViewProcessContext;
import com.opengamma.engine.view.listener.ComputationResultListener;
import com.opengamma.engine.view.permission.DefaultViewPermissionProvider;
import com.opengamma.engine.view.permission.DefaultViewPortfolioPermissionProvider;
import com.opengamma.engine.view.permission.ViewPermissionProvider;
import com.opengamma.engine.view.worker.SingleThreadViewProcessWorkerFactory;
import com.opengamma.engine.view.worker.cache.InMemoryViewExecutionCache;
import com.opengamma.id.UniqueId;
import com.opengamma.id.VersionCorrection;
import com.opengamma.id.VersionedUniqueIdSupplier;
import com.opengamma.livedata.UserPrincipal;
import com.opengamma.util.log.ThreadLocalLogEventListener;
import com.opengamma.util.test.TestGroup;
import com.opengamma.util.test.Timeout;

/**
* Test.
*/
@Test(groups = TestGroup.INTEGRATION)
public class CancelExecutionTest {

  private static final int JOB_SIZE = 100;
  private static final int JOB_FINISH_TIME = (int) Timeout.standardTimeoutMillis();
  private static final int SLEEP_TIME = JOB_FINISH_TIME / 10;
  private static final Logger s_logger = LoggerFactory.getLogger(CancelExecutionTest.class);

  @DataProvider(name = "executors")
  Object[][] data_executors() {
    return new Object[][] {
        {multipleNodeExecutorFactoryManyJobs() },
        {multipleNodeExecutorFactoryOneJob() },
        {new SingleNodeExecutorFactory() }, };
  }

  //-------------------------------------------------------------------------
  private static MultipleNodeExecutorFactory multipleNodeExecutorFactoryOneJob() {
    final MultipleNodeExecutorFactory factory = new MultipleNodeExecutorFactory();
    factory.afterPropertiesSet();
    return factory;
  }

  private static MultipleNodeExecutorFactory multipleNodeExecutorFactoryManyJobs() {
    final MultipleNodeExecutorFactory factory = multipleNodeExecutorFactoryOneJob();
    factory.setMaximumJobItems(JOB_SIZE / 10);
    return factory;
  }

  private final AtomicInteger _functionCount = new AtomicInteger();

  private void sleep() {
    try {
      Thread.sleep(SLEEP_TIME);
    } catch (final InterruptedException e) {
    }
  }

  private final ComputationResultListener computationCycleResultListener = new ComputationResultListener() {
    @Override
    public void resultAvailable(final ViewComputationResultModel result) {
      //ignore
    }
  };

  private DependencyGraphExecutionFuture executeTestJob(final DependencyGraphExecutorFactory factory) {
    final InMemoryLKVMarketDataProvider marketDataProvider = new InMemoryLKVMarketDataProvider();
    final MarketDataProviderResolver marketDataProviderResolver = new SingleMarketDataProviderResolver(new SingletonMarketDataProviderFactory(marketDataProvider));
    final InMemoryFunctionRepository functionRepository = new InMemoryFunctionRepository();
    _functionCount.set(0);
    final MockFunction mockFunction = new MockFunction(ComputationTarget.NULL) {
      @Override
      public Set<ComputedValue> execute(final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target, final Set<ValueRequirement> desiredValues) {
        try {
          Thread.sleep(JOB_FINISH_TIME / (JOB_SIZE * 2));
        } catch (final InterruptedException e) {
          throw new OpenGammaRuntimeException("Function interrupted", e);
        }
        _functionCount.incrementAndGet();
        return super.execute(executionContext, inputs, target, desiredValues);
      }
    };
    functionRepository.addFunction(mockFunction);
    final FunctionCompilationContext compilationContext = new FunctionCompilationContext();
    final CompiledFunctionService compilationService = new CompiledFunctionService(functionRepository, new CachingFunctionRepositoryCompiler(), compilationContext);
    compilationService.initialize();
    final FunctionResolver functionResolver = new DefaultFunctionResolver(compilationService);
    final InMemorySecuritySource securitySource = new InMemorySecuritySource();
    final MockPositionSource positionSource = new MockPositionSource();
    compilationContext.setRawComputationTargetResolver(new DefaultComputationTargetResolver(securitySource, positionSource));
    final ViewComputationCacheSource computationCacheSource = new InMemoryViewComputationCacheSource(FudgeContext.GLOBAL_DEFAULT);
    final FunctionInvocationStatisticsGatherer functionInvocationStatistics = new DiscardingInvocationStatisticsGatherer();
    final FunctionExecutionContext executionContext = new FunctionExecutionContext();
    final JobDispatcher jobDispatcher = new JobDispatcher(new LocalNodeJobInvoker(new SimpleCalculationNode(computationCacheSource, compilationService, executionContext, "node",
        Executors.newCachedThreadPool(), functionInvocationStatistics, new CalculationNodeLogEventListener(new ThreadLocalLogEventListener()))));
    final ViewPermissionProvider viewPermissionProvider = new DefaultViewPermissionProvider();
    final GraphExecutorStatisticsGathererProvider graphExecutorStatisticsProvider = new DiscardingGraphStatisticsGathererProvider();
    final ViewDefinition viewDefinition = new ViewDefinition("TestView", UserPrincipal.getTestUser());
    viewDefinition.addViewCalculationConfiguration(new ViewCalculationConfiguration(viewDefinition, "default"));
    final MockConfigSource configSource = new MockConfigSource();
    configSource.put(viewDefinition);
    final ViewProcessContext vpc = new ViewProcessContext(UniqueId.of("Process", "Test"), configSource, viewPermissionProvider,
                                                          new DefaultViewPortfolioPermissionProvider(),
                                                          marketDataProviderResolver, compilationService, functionResolver,
        computationCacheSource, jobDispatcher, new SingleThreadViewProcessWorkerFactory(), new DependencyGraphBuilderFactory(), factory, graphExecutorStatisticsProvider,
        new DummyOverrideOperationCompiler(), new EngineResourceManagerImpl<SingleComputationCycle>(), new VersionedUniqueIdSupplier("Test", "1"), new InMemoryViewExecutionCache());
    final DependencyGraph graph = new DependencyGraph("Default");
    DependencyNode previous = null;
    for (int i = 0; i < JOB_SIZE; i++) {
      final DependencyNode node = new DependencyNode(ComputationTarget.NULL);
      node.setFunction(mockFunction);
      if (previous != null) {
        node.addInputNode(previous);
      }
      graph.addDependencyNode(node);
      previous = node;
    }
    final CompiledViewDefinitionWithGraphsImpl viewEvaluationModel = new CompiledViewDefinitionWithGraphsImpl(VersionCorrection.LATEST, "", viewDefinition, Collections.singleton(graph),
        Collections.<ComputationTargetReference, UniqueId>emptyMap(), new SimplePortfolio("Test Portfolio"), 0);
    final ViewCycleExecutionOptions cycleOptions = ViewCycleExecutionOptions.builder().setValuationTime(Instant.ofEpochMilli(1)).setMarketDataSpecification(new MarketDataSpecification()).create();
    final SingleComputationCycle cycle = new SingleComputationCycle(UniqueId.of("Test", "Cycle1"), computationCycleResultListener, vpc, viewEvaluationModel,
        cycleOptions, VersionCorrection.of(Instant.ofEpochMilli(1), Instant.ofEpochMilli(1)));
    return factory.createExecutor(cycle).execute(graph);
  }

  private boolean jobFinished() {
    return _functionCount.get() == JOB_SIZE;
  }

  /**
   * Allow the job to finish, then call {@link Future#cancel}.
   */
  @Test(dataProvider = "executors")
  public void testJobFinish(final DependencyGraphExecutorFactory factory) throws Exception {
    s_logger.info("testJobFinish");
    final Future<?> job = executeTestJob(factory);
    assertNotNull(job);
    for (int i = 0; i < JOB_FINISH_TIME / SLEEP_TIME; i++) {
      if (jobFinished()) {
        job.get(Timeout.standardTimeoutMillis(), TimeUnit.MILLISECONDS);
        assertFalse(job.isCancelled());
        assertTrue(job.isDone());
        s_logger.info("Job finished in {}", i);
        return;
      }
      sleep();
    }
    Assert.fail("Job didn't finish in time available");
  }

  /**
   * Call {@link Future#cancel} before the job finishes, with interrupt enabled.
   */
  @Test(dataProvider = "executors")
  public void testJobCancelWithInterrupt(final DependencyGraphExecutorFactory factory) {
    s_logger.info("testJobCancelWithInterrupt");
    final Future<?> job = executeTestJob(factory);
    assertNotNull(job);
    job.cancel(true);
    for (int i = 0; i < JOB_FINISH_TIME / SLEEP_TIME; i++) {
      if (jobFinished()) {
        assertTrue(job.isCancelled());
        assertTrue(job.isDone());
        s_logger.info("Job finished in {}", i);
        Assert.fail("Job finished normally despite cancel");
        return;
      }
      sleep();
    }
  }

  /**
   * Call {@link Future#cancel} before the job finishes, with no interrupt.
   */
  @Test(dataProvider = "executors")
  public void testJobCancelWithoutInterrupt(final DependencyGraphExecutorFactory factory) {
    s_logger.info("testJobCancelWithoutInterrupt");
    final Future<?> job = executeTestJob(factory);
    assertNotNull(job);
    job.cancel(false);
    for (int i = 0; i < JOB_FINISH_TIME / SLEEP_TIME; i++) {
      if (jobFinished()) {
        assertTrue(job.isCancelled());
        assertTrue(job.isDone());
        s_logger.info("Job finished in {}", i);
        Assert.fail("Job finished normally despite cancel");
        return;
      }
      sleep();
    }
  }

}
TOP

Related Classes of com.opengamma.engine.exec.CancelExecutionTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.