Package com.opengamma.engine.view.worker

Source Code of com.opengamma.engine.view.worker.ParallelRecompilationViewProcessWorkerTest

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

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNotSame;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertSame;
import static org.testng.Assert.assertTrue;

import java.util.ArrayList;
import java.util.List;

import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.testng.annotations.Test;

import com.google.common.collect.ImmutableList;
import com.opengamma.engine.marketdata.spec.MarketData;
import com.opengamma.engine.view.ViewDefinition;
import com.opengamma.engine.view.execution.ExecutionFlags;
import com.opengamma.engine.view.execution.ExecutionOptions;
import com.opengamma.engine.view.execution.ViewExecutionOptions;
import com.opengamma.engine.view.worker.ParallelRecompilationViewProcessWorker.AbstractViewProcessWorkerContext;
import com.opengamma.util.test.TestGroup;

/**
* Tests the {@link ParallelRecompilationViewProcessWorker} class.
*/
@Test(groups = TestGroup.UNIT)
public class ParallelRecompilationViewProcessWorkerTest {

  @Test(expectedExceptions = IllegalStateException.class)
  public void testIllegalStart_alreadyRunning() {
    final ViewProcessWorkerFactory workerFactory = Mockito.mock(ViewProcessWorkerFactory.class);
    final ViewProcessWorkerContext context = Mockito.mock(ViewProcessWorkerContext.class);
    final ViewExecutionOptions options = ExecutionOptions.infinite(MarketData.live(), ExecutionFlags.none().ignoreCompilationValidity().get());
    final ViewDefinition viewDefinition = Mockito.mock(ViewDefinition.class);
    final ParallelRecompilationViewProcessWorker worker = new ParallelRecompilationViewProcessWorker(workerFactory, context, options, viewDefinition);
    worker.startParallel(options);
    worker.startParallel(options);
  }

  @Test(expectedExceptions = IllegalStateException.class)
  public void testIllegalStart_terminated() {
    final ViewProcessWorkerFactory workerFactory = Mockito.mock(ViewProcessWorkerFactory.class);
    final ViewProcessWorkerContext context = Mockito.mock(ViewProcessWorkerContext.class);
    final ViewExecutionOptions options = ExecutionOptions.infinite(MarketData.live(), ExecutionFlags.none().ignoreCompilationValidity().get());
    final ViewDefinition viewDefinition = Mockito.mock(ViewDefinition.class);
    final ParallelRecompilationViewProcessWorker worker = new ParallelRecompilationViewProcessWorker(workerFactory, context, options, viewDefinition);
    worker.startParallel(options);
    worker.terminate();
    worker.startParallel(options);
  }

  public void testTriggerCycle() {
    // Creates workers that will trigger on the first cycle, ignore the second, and then terminate on the third
    final ViewProcessWorkerFactory workerFactory = new ViewProcessWorkerFactory() {
      @Override
      public ViewProcessWorker createWorker(final ViewProcessWorkerContext context, final ViewExecutionOptions executionOptions, final ViewDefinition viewDefinition) {
        final ViewProcessWorker worker = Mockito.mock(ViewProcessWorker.class);
        Mockito.when(worker.triggerCycle()).thenAnswer(new Answer<Boolean>() {

          private int _count = 0;

          @Override
          public Boolean answer(InvocationOnMock invocation) throws Throwable {
            _count++;
            if (_count == 3) {
              context.workerCompleted();
            }
            return (_count == 1);
          }

        });
        return worker;
      }
    };
    final ViewProcessWorkerContext context = Mockito.mock(ViewProcessWorkerContext.class);
    final ViewExecutionOptions options = ExecutionOptions.infinite(MarketData.live(), ExecutionFlags.none().ignoreCompilationValidity().get());
    final ViewDefinition viewDefinition = Mockito.mock(ViewDefinition.class);
    final ParallelRecompilationViewProcessWorker worker = new ParallelRecompilationViewProcessWorker(workerFactory, context, options, viewDefinition);
    // With no worker
    assertFalse(worker.triggerCycle());
    // With a primary worker that responds TRUE (first time)
    worker.startParallel(options);
    assertTrue(worker.triggerCycle());
    // With a primary worker that responds FALSE (second time)
    worker.startSecondaryWorker(worker.getPrimary(), options.getExecutionSequence());
    assertFalse(worker.triggerCycle());
    // With a primary worker that returns FALSE, causes secondary promotion, and that returns TRUE (first time)
    assertTrue(worker.triggerCycle());
    // With a primary worker that responds FALSE (second time)
    assertFalse(worker.triggerCycle());
    assertFalse(worker.isTerminated());
    // With a primary worker that returns FALSE because of termination
    assertFalse(worker.triggerCycle());
    assertTrue(worker.isTerminated());
    // After explicit termination
    worker.terminate();
    assertFalse(worker.triggerCycle());
  }

  public void testRequestCycle() {
    // Creates workers that will honor the request on the first cycle, ignore the second, and then terminate on the third
    final ViewProcessWorkerFactory workerFactory = new ViewProcessWorkerFactory() {
      @Override
      public ViewProcessWorker createWorker(final ViewProcessWorkerContext context, final ViewExecutionOptions executionOptions, final ViewDefinition viewDefinition) {
        final ViewProcessWorker worker = Mockito.mock(ViewProcessWorker.class);
        Mockito.when(worker.requestCycle()).thenAnswer(new Answer<Boolean>() {

          private int _count = 0;

          @Override
          public Boolean answer(InvocationOnMock invocation) throws Throwable {
            _count++;
            if (_count == 3) {
              context.workerCompleted();
            }
            return (_count == 1);
          }

        });
        return worker;
      }
    };
    final ViewProcessWorkerContext context = Mockito.mock(ViewProcessWorkerContext.class);
    final ViewExecutionOptions options = ExecutionOptions.infinite(MarketData.live(), ExecutionFlags.none().ignoreCompilationValidity().get());
    final ViewDefinition viewDefinition = Mockito.mock(ViewDefinition.class);
    final ParallelRecompilationViewProcessWorker worker = new ParallelRecompilationViewProcessWorker(workerFactory, context, options, viewDefinition);
    // With no worker
    assertFalse(worker.requestCycle());
    // With a primary worker that responds TRUE (first time)
    worker.startParallel(options);
    assertTrue(worker.requestCycle());
    // With a primary worker that responds FALSE (second time)
    worker.startSecondaryWorker(worker.getPrimary(), options.getExecutionSequence());
    assertFalse(worker.requestCycle());
    // With a primary worker that returns FALSE, causes secondary promotion, and that returns TRUE (first time)
    assertTrue(worker.requestCycle());
    // With a primary worker that responds FALSE (second time)
    assertFalse(worker.requestCycle());
    assertFalse(worker.isTerminated());
    // With a primary worker that returns FALSE because of termination
    assertFalse(worker.requestCycle());
    assertTrue(worker.isTerminated());
    // After explicit termination
    worker.terminate();
    assertFalse(worker.requestCycle());
  }

  public void testUpdateViewDefinition() {
    final List<ViewDefinition> viewDefinitions = ImmutableList.of(Mockito.mock(ViewDefinition.class), Mockito.mock(ViewDefinition.class), Mockito.mock(ViewDefinition.class),
        Mockito.mock(ViewDefinition.class));
    final List<ViewProcessWorker> workers = new ArrayList<ViewProcessWorker>(3);
    final ViewProcessWorkerFactory workerFactory = new ViewProcessWorkerFactory() {
      @Override
      public ViewProcessWorker createWorker(final ViewProcessWorkerContext context, final ViewExecutionOptions executionOptions, final ViewDefinition viewDefinition) {
        final ViewProcessWorker worker = Mockito.mock(ViewProcessWorker.class);
        workers.add(worker);
        assertSame(viewDefinition, viewDefinitions.get(workers.size()));
        return worker;
      }
    };
    final ViewProcessWorkerContext context = Mockito.mock(ViewProcessWorkerContext.class);
    final ViewExecutionOptions options = ExecutionOptions.infinite(MarketData.live(), ExecutionFlags.none().ignoreCompilationValidity().get());
    final ParallelRecompilationViewProcessWorker worker = new ParallelRecompilationViewProcessWorker(workerFactory, context, options, viewDefinitions.get(0));
    AbstractViewProcessWorkerContext primary, secondary;
    // With no current workers
    assertNull(worker.getPrimary());
    assertNull(worker.getSecondary());
    worker.updateViewDefinition(viewDefinitions.get(1));
    // With a primary worker only
    worker.startParallel(options);
    assertEquals(workers.size(), 1);
    primary = worker.getPrimary();
    assertNotNull(primary);
    assertNull(worker.getSecondary());
    worker.updateViewDefinition(viewDefinitions.get(2));
    assertEquals(workers.size(), 2);
    assertSame(worker.getPrimary(), primary);
    secondary = worker.getSecondary();
    assertNotNull(secondary);
    // With a secondary worker - should replace the previous
    worker.updateViewDefinition(viewDefinitions.get(3));
    assertEquals(workers.size(), 3);
    assertSame(worker.getPrimary(), primary);
    assertNotSame(worker.getSecondary(), secondary);
    Mockito.verify(workers.get(0), Mockito.never()).terminate();
    Mockito.verify(workers.get(1), Mockito.atLeastOnce()).terminate();
    Mockito.verify(workers.get(2), Mockito.never()).terminate();
  }

  public void testTerminate() {
    final List<ViewProcessWorkerContext> workerContexts = new ArrayList<ViewProcessWorkerContext>(2);
    final List<ViewProcessWorker> workers = new ArrayList<ViewProcessWorker>(2);
    final ViewProcessWorkerFactory workerFactory = new ViewProcessWorkerFactory() {
      @Override
      public ViewProcessWorker createWorker(final ViewProcessWorkerContext context, final ViewExecutionOptions executionOptions, final ViewDefinition viewDefinition) {
        workerContexts.add(context);
        final ViewProcessWorker worker = Mockito.mock(ViewProcessWorker.class);
        workers.add(worker);
        return worker;
      }
    };
    final ViewProcessWorkerContext context = Mockito.mock(ViewProcessWorkerContext.class);
    final ViewExecutionOptions options = ExecutionOptions.infinite(MarketData.live(), ExecutionFlags.none().ignoreCompilationValidity().get());
    final ViewDefinition viewDefinition = Mockito.mock(ViewDefinition.class);
    final ParallelRecompilationViewProcessWorker worker = new ParallelRecompilationViewProcessWorker(workerFactory, context, options, viewDefinition);
    // Initially "terminated"
    assertTrue(worker.isTerminated());
    // Spawn workers
    worker.startParallel(options);
    worker.startSecondaryWorker(worker.getPrimary(), options.getExecutionSequence());
    assertFalse(worker.isTerminated());
    // Terminate
    worker.terminate();
    assertFalse(worker.isTerminated());
    Mockito.verify(workers.get(0), Mockito.atLeastOnce()).terminate();
    Mockito.verify(workers.get(1), Mockito.atLeastOnce()).terminate();
    workerContexts.get(0).workerCompleted();
    assertFalse(worker.isTerminated());
    workerContexts.get(1).workerCompleted();
    assertTrue(worker.isTerminated());
    // Already terminated
    worker.terminate();
    assertTrue(worker.isTerminated());
  }

  @Test(timeOut = 10000)
  public void testJoin_noWorkers() throws InterruptedException {
    final ViewProcessWorkerFactory workerFactory = Mockito.mock(ViewProcessWorkerFactory.class);
    final ViewProcessWorkerContext context = Mockito.mock(ViewProcessWorkerContext.class);
    final ViewExecutionOptions options = ExecutionOptions.infinite(MarketData.live(), ExecutionFlags.none().ignoreCompilationValidity().get());
    final ViewDefinition viewDefinition = Mockito.mock(ViewDefinition.class);
    final ParallelRecompilationViewProcessWorker worker = new ParallelRecompilationViewProcessWorker(workerFactory, context, options, viewDefinition);
    // No-op
    worker.join();
  }

  @Test(timeOut = 10000)
  public void testJoin_workersTerminateBefore() throws InterruptedException {
    final ViewProcessWorkerFactory workerFactory = new ViewProcessWorkerFactory() {
      @Override
      public ViewProcessWorker createWorker(final ViewProcessWorkerContext context, final ViewExecutionOptions executionOptions, final ViewDefinition viewDefinition) {
        final ViewProcessWorker worker = Mockito.mock(ViewProcessWorker.class);
        try {
          Mockito.doAnswer(new Answer<Void>() {
            @Override
            public Void answer(InvocationOnMock invocation) throws Throwable {
              context.workerCompleted();
              return null;
            }
          }).when(worker).join();
        } catch (InterruptedException e) {
          // Doesn't get thrown
        }
        return worker;
      }
    };
    final ViewProcessWorkerContext context = Mockito.mock(ViewProcessWorkerContext.class);
    final ViewExecutionOptions options = ExecutionOptions.infinite(MarketData.live(), ExecutionFlags.none().ignoreCompilationValidity().get());
    final ViewDefinition viewDefinition = Mockito.mock(ViewDefinition.class);
    final ParallelRecompilationViewProcessWorker worker = new ParallelRecompilationViewProcessWorker(workerFactory, context, options, viewDefinition);
    // Start workers
    worker.startParallel(options);
    worker.startSecondaryWorker(worker.getPrimary(), options.getExecutionSequence());
    // Join on the first worker will see the secondary worker promoted, that will join and this will complete
    worker.join();
    assertNull(worker.getPrimary());
    assertNull(worker.getSecondary());
  }

  @Test(timeOut = 10000)
  public void testJoin_workersTerminateAfter() throws InterruptedException {
    final ViewProcessWorkerFactory workerFactory = new ViewProcessWorkerFactory() {
      @Override
      public ViewProcessWorker createWorker(final ViewProcessWorkerContext context, final ViewExecutionOptions executionOptions, final ViewDefinition viewDefinition) {
        return Mockito.mock(ViewProcessWorker.class);
      }
    };
    final ViewProcessWorkerContext context = Mockito.mock(ViewProcessWorkerContext.class);
    final ViewExecutionOptions options = ExecutionOptions.infinite(MarketData.live(), ExecutionFlags.none().ignoreCompilationValidity().get());
    final ViewDefinition viewDefinition = Mockito.mock(ViewDefinition.class);
    final ParallelRecompilationViewProcessWorker worker = new ParallelRecompilationViewProcessWorker(workerFactory, context, options, viewDefinition);
    // Start workers
    worker.startParallel(options);
    worker.startSecondaryWorker(worker.getPrimary(), options.getExecutionSequence());
    // Join on the first worker will see the secondary worker promoted, that will join and this will complete
    worker.join();
    assertNull(worker.getPrimary());
    assertNull(worker.getSecondary());
  }

  @Test(timeOut = 10000)
  public void testJoin_timeout_noWorkers() throws InterruptedException {
    final ViewProcessWorkerFactory workerFactory = new ViewProcessWorkerFactory() {
      @Override
      public ViewProcessWorker createWorker(final ViewProcessWorkerContext context, final ViewExecutionOptions executionOptions, final ViewDefinition viewDefinition) {
        final ViewProcessWorker worker = Mockito.mock(ViewProcessWorker.class);
        try {
          Mockito.when(worker.join(Mockito.anyLong())).thenAnswer(new Answer<Boolean>() {
            @Override
            public Boolean answer(InvocationOnMock invocation) throws Throwable {
              assertTrue(((Long) invocation.getArguments()[0]) <= 20000);
              return Boolean.TRUE;
            }
          });
        } catch (InterruptedException e) {
          // Doesn't get thrown
        }
        return worker;
      }
    };
    final ViewProcessWorkerContext context = Mockito.mock(ViewProcessWorkerContext.class);
    final ViewExecutionOptions options = ExecutionOptions.infinite(MarketData.live(), ExecutionFlags.none().ignoreCompilationValidity().get());
    final ViewDefinition viewDefinition = Mockito.mock(ViewDefinition.class);
    final ParallelRecompilationViewProcessWorker worker = new ParallelRecompilationViewProcessWorker(workerFactory, context, options, viewDefinition);
    // No-op
    assertTrue(worker.join(20000));
  }

  @Test(timeOut = 10000)
  public void testJoin_timeout_workersTerminateBefore() throws InterruptedException {
    final ViewProcessWorkerFactory workerFactory = new ViewProcessWorkerFactory() {
      @Override
      public ViewProcessWorker createWorker(final ViewProcessWorkerContext context, final ViewExecutionOptions executionOptions, final ViewDefinition viewDefinition) {
        final ViewProcessWorker worker = Mockito.mock(ViewProcessWorker.class);
        try {
          Mockito.doAnswer(new Answer<Boolean>() {
            @Override
            public Boolean answer(InvocationOnMock invocation) throws Throwable {
              assertTrue(((Long) invocation.getArguments()[0]) <= 20000);
              context.workerCompleted();
              return Boolean.TRUE;
            }
          }).when(worker).join(Mockito.anyLong());
        } catch (InterruptedException e) {
          // Doesn't get thrown
        }
        return worker;
      }
    };
    final ViewProcessWorkerContext context = Mockito.mock(ViewProcessWorkerContext.class);
    final ViewExecutionOptions options = ExecutionOptions.infinite(MarketData.live(), ExecutionFlags.none().ignoreCompilationValidity().get());
    final ViewDefinition viewDefinition = Mockito.mock(ViewDefinition.class);
    final ParallelRecompilationViewProcessWorker worker = new ParallelRecompilationViewProcessWorker(workerFactory, context, options, viewDefinition);
    // Start workers
    worker.startParallel(options);
    worker.startSecondaryWorker(worker.getPrimary(), options.getExecutionSequence());
    // Join on the first worker will see the secondary worker promoted, that will join and this will complete
    assertTrue(worker.join(20000));
    assertNull(worker.getPrimary());
    assertNull(worker.getSecondary());
  }

  @Test(timeOut = 10000)
  public void testJoin_timeout_workersTerminateAfter() throws InterruptedException {
    final ViewProcessWorkerFactory workerFactory = new ViewProcessWorkerFactory() {
      @Override
      public ViewProcessWorker createWorker(final ViewProcessWorkerContext context, final ViewExecutionOptions executionOptions, final ViewDefinition viewDefinition) {
        final ViewProcessWorker worker = Mockito.mock(ViewProcessWorker.class);
        try {
          Mockito.when(worker.join(Mockito.anyLong())).thenAnswer(new Answer<Boolean>() {
            @Override
            public Boolean answer(InvocationOnMock invocation) throws Throwable {
              assertTrue(((Long) invocation.getArguments()[0]) <= 20000);
              return Boolean.TRUE;
            }
          });
        } catch (InterruptedException e) {
          // Doesn't get thrown
        }
        return worker;
      }
    };
    final ViewProcessWorkerContext context = Mockito.mock(ViewProcessWorkerContext.class);
    final ViewExecutionOptions options = ExecutionOptions.infinite(MarketData.live(), ExecutionFlags.none().ignoreCompilationValidity().get());
    final ViewDefinition viewDefinition = Mockito.mock(ViewDefinition.class);
    final ParallelRecompilationViewProcessWorker worker = new ParallelRecompilationViewProcessWorker(workerFactory, context, options, viewDefinition);
    // Start workers
    worker.startParallel(options);
    worker.startSecondaryWorker(worker.getPrimary(), options.getExecutionSequence());
    // Join on the first worker will see the secondary worker promoted, that will join and this will complete
    assertTrue(worker.join(20000));
    assertNull(worker.getPrimary());
    assertNull(worker.getSecondary());
  }

  @Test(timeOut = 10000)
  public void testJoin_timeout() throws InterruptedException {
    final ViewProcessWorkerFactory workerFactory = new ViewProcessWorkerFactory() {
      @Override
      public ViewProcessWorker createWorker(final ViewProcessWorkerContext context, final ViewExecutionOptions executionOptions, final ViewDefinition viewDefinition) {
        final ViewProcessWorker worker = Mockito.mock(ViewProcessWorker.class);
        try {
          Mockito.when(worker.join(Mockito.anyLong())).thenAnswer(new Answer<Boolean>() {
            @Override
            public Boolean answer(InvocationOnMock invocation) throws Throwable {
              assertTrue(((Long) invocation.getArguments()[0]) <= 20000);
              return Boolean.FALSE;
            }
          });
        } catch (InterruptedException e) {
          // Doesn't get thrown
        }
        return worker;
      }
    };
    final ViewProcessWorkerContext context = Mockito.mock(ViewProcessWorkerContext.class);
    final ViewExecutionOptions options = ExecutionOptions.infinite(MarketData.live(), ExecutionFlags.none().ignoreCompilationValidity().get());
    final ViewDefinition viewDefinition = Mockito.mock(ViewDefinition.class);
    final ParallelRecompilationViewProcessWorker worker = new ParallelRecompilationViewProcessWorker(workerFactory, context, options, viewDefinition);
    // Start workers
    worker.startParallel(options);
    worker.startSecondaryWorker(worker.getPrimary(), options.getExecutionSequence());
    // Join on the first worker will see the secondary worker promoted, that will join and this will complete
    assertFalse(worker.join(20000));
    assertNotNull(worker.getPrimary());
    assertNotNull(worker.getSecondary());
    assertFalse(worker.join(0));
    assertNotNull(worker.getPrimary());
    assertNotNull(worker.getSecondary());
  }

}
TOP

Related Classes of com.opengamma.engine.view.worker.ParallelRecompilationViewProcessWorkerTest

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.