@Override
 public Set<ValueRequirement> getRequirements(
     final FunctionCompilationContext context,
     final ComputationTarget target,
     final ValueRequirement desiredValue) {
   final ValueProperties constraints = desiredValue.getConstraints();
   final Set<String> curveNames = constraints.getValues(CURVE);
   if (curveNames == null || curveNames.size() != 1) {
     return null;
   }
   final Set<String> curveExposureConfigs = constraints.getValues(CURVE_EXPOSURES);
   if (curveExposureConfigs == null) {
     return null;
   }
   final Set<String> curveType = constraints.getValues(PROPERTY_CURVE_TYPE);
   if (curveType == null) {
     return null;
   }
   if (super.getRequirements(context, target, desiredValue) == null) {
     return null;
   }
   final Set<ValueRequirement> requirements = new HashSet<>();
   final ValueProperties curveProperties = ValueProperties.with(CURVE, curveNames).get();
   final ValueProperties properties =
       ValueProperties.with(PROPERTY_CURVE_TYPE, curveType)
           .with(CURVE_EXPOSURES, curveExposureConfigs)
           .get();
   requirements.add(
       new ValueRequirement(
           CURVE_DEFINITION, ComputationTargetSpecification.NULL, curveProperties));
   requirements.add(
       new ValueRequirement(BLOCK_CURVE_SENSITIVITIES, target.toSpecification(), properties));
   return requirements;
 }
 protected ValueRequirement getCurveRequirement(
     final ComputationTarget target, final String curveName, final String curveCalculationConfig) {
   final Currency currency = FinancialSecurityUtils.getCurrency(target.getSecurity());
   final ValueProperties.Builder properties =
       ValueProperties.with(ValuePropertyNames.CURVE, curveName);
   properties.with(ValuePropertyNames.CURVE_CALCULATION_CONFIG, curveCalculationConfig);
   return new ValueRequirement(
       ValueRequirementNames.YIELD_CURVE,
       ComputationTargetSpecification.of(currency),
       properties.get());
 }
 /**
  * Tests applying an index shift to a surface where there are fewer shifts specified than expiries
  * in the surface.
  */
 @Test
 public void indexSurfaceFewerShiftsThanExpiries() {
   NodalDoublesSurface surface =
       new NodalDoublesSurface(
           new double[] {1.1, 1.2, 1.2, 1.3, 1.3, 1.3},
           new double[] {0.1, 0.1, 0.2, 0.1, 0.2, 0.3},
           new double[] {1, 2, 3, 4, 5, 6});
   List<Double> shiftList = Lists.newArrayList(0d, 0.1);
   VolatilitySurfaceIndexShifts shifts =
       new VolatilitySurfaceIndexShifts(ScenarioShiftType.ABSOLUTE, shiftList);
   ValueProperties properties = ValueProperties.with(ValuePropertyNames.FUNCTION, "bar").get();
   ValueSpecification spec =
       new ValueSpecification("foo", ComputationTargetSpecification.NULL, properties);
   VolatilitySurface shiftedSurface =
       shifts.execute(new VolatilitySurface(surface), spec, new FunctionExecutionContext());
   assertEquals(1.0, shiftedSurface.getVolatility(1.1, 0.1), DELTA);
   assertEquals(2.1, shiftedSurface.getVolatility(1.2, 0.1), DELTA);
   assertEquals(3.1, shiftedSurface.getVolatility(1.2, 0.2), DELTA);
   assertEquals(4.0, shiftedSurface.getVolatility(1.3, 0.1), DELTA);
   assertEquals(5.0, shiftedSurface.getVolatility(1.3, 0.2), DELTA);
   assertEquals(6.0, shiftedSurface.getVolatility(1.3, 0.3), DELTA);
 }
 /** Tests applying a relative index shift to a surface. */
 @Test
 public void indexSurfaceRelative() {
   NodalDoublesSurface surface =
       new NodalDoublesSurface(
           new double[] {1.1, 1.2, 1.2, 1.3, 1.3, 1.3},
           new double[] {10, 10, 20, 10, 20, 30},
           new double[] {1, 2, 3, 4, 5, 6});
   List<Double> shiftList = Lists.newArrayList(0d, 0.1, 0.2);
   VolatilitySurfaceIndexShifts shifts =
       new VolatilitySurfaceIndexShifts(ScenarioShiftType.RELATIVE, shiftList);
   ValueProperties properties = ValueProperties.with(ValuePropertyNames.FUNCTION, "bar").get();
   ValueSpecification spec =
       new ValueSpecification("foo", ComputationTargetSpecification.NULL, properties);
   VolatilitySurface shiftedSurface =
       shifts.execute(new VolatilitySurface(surface), spec, new FunctionExecutionContext());
   assertEquals(1.0, shiftedSurface.getVolatility(1.1, 10), DELTA);
   assertEquals(2.2, shiftedSurface.getVolatility(1.2, 10), DELTA);
   assertEquals(3.3, shiftedSurface.getVolatility(1.2, 20), DELTA);
   assertEquals(4.8, shiftedSurface.getVolatility(1.3, 10), DELTA);
   assertEquals(6.0, shiftedSurface.getVolatility(1.3, 20), DELTA);
   assertEquals(7.2, shiftedSurface.getVolatility(1.3, 30), DELTA);
 }
/** Tests the implementation of watched jobs. */
@Test
public class WatchedJobTest {

  private final ComputationTargetSpecification TARGET = new ComputationTargetSpecification("Foo");
  private final ValueSpecification VS_A =
      new ValueSpecification(
          "A", TARGET, ValueProperties.with(ValuePropertyNames.FUNCTION, "A").get());
  private final ValueSpecification VS_B =
      new ValueSpecification(
          "B", TARGET, ValueProperties.with(ValuePropertyNames.FUNCTION, "B").get());
  private final ValueSpecification VS_C =
      new ValueSpecification(
          "C", TARGET, ValueProperties.with(ValuePropertyNames.FUNCTION, "C").get());
  private final ValueSpecification VS_D =
      new ValueSpecification(
          "D", TARGET, ValueProperties.with(ValuePropertyNames.FUNCTION, "D").get());
  private final CalculationJobItem JOB_ITEM_A =
      new CalculationJobItem(
          "A",
          new EmptyFunctionParameters(),
          TARGET,
          Collections.<ValueSpecification>emptySet(),
          Arrays.asList(VS_A),
          ExecutionLogMode.INDICATORS);
  private final CalculationJobItem JOB_ITEM_AB =
      new CalculationJobItem(
          "B",
          new EmptyFunctionParameters(),
          TARGET,
          Arrays.asList(VS_A),
          Arrays.asList(VS_B),
          ExecutionLogMode.INDICATORS);
  private final CalculationJobItem JOB_ITEM_BC =
      new CalculationJobItem(
          "C",
          new EmptyFunctionParameters(),
          TARGET,
          Arrays.asList(VS_B),
          Arrays.asList(VS_C),
          ExecutionLogMode.INDICATORS);
  private final CalculationJobItem JOB_ITEM_AC =
      new CalculationJobItem(
          "C",
          new EmptyFunctionParameters(),
          TARGET,
          Arrays.asList(VS_A),
          Arrays.asList(VS_C),
          ExecutionLogMode.INDICATORS);
  private final CalculationJobItem JOB_ITEM_BCD =
      new CalculationJobItem(
          "D",
          new EmptyFunctionParameters(),
          TARGET,
          Arrays.asList(VS_B, VS_C),
          Arrays.asList(VS_D),
          ExecutionLogMode.INDICATORS);

  private static CalculationJobSpecification createJobSpecification() {
    return new CalculationJobSpecification(
        UniqueId.of("Cycle", "1"), "Default", Instant.now(), JobIdSource.getId());
  }

  public void testStandardJob_createWatchedJob_singleItem() {
    final JobDispatcher dispatcher = new JobDispatcher();
    final FunctionBlacklistMaintainer blacklist = Mockito.mock(FunctionBlacklistMaintainer.class);
    dispatcher.setFunctionBlacklistMaintainer(blacklist);
    final CalculationJob job =
        new CalculationJob(
            createJobSpecification(),
            0,
            null,
            Arrays.asList(JOB_ITEM_A),
            CacheSelectHint.allShared());
    final StandardJob standard =
        new StandardJob(dispatcher, job, Mockito.mock(JobResultReceiver.class));
    final WatchedJob watched = standard.createWatchedJob();
    assertNull(watched);
    Mockito.verify(blacklist).failedJobItem(JOB_ITEM_A);
  }

  public void testStandardJob_createWatchedJob_noTail() {
    final JobDispatcher dispatcher = new JobDispatcher();
    final CalculationJob job =
        new CalculationJob(
            createJobSpecification(),
            0,
            null,
            Arrays.asList(JOB_ITEM_AB, JOB_ITEM_BC),
            CacheSelectHint.allShared());
    final StandardJob standard =
        new StandardJob(dispatcher, job, Mockito.mock(JobResultReceiver.class));
    final WatchedJob watched = standard.createWatchedJob();
    assertTrue(watched instanceof WatchedJob.Whole);
    watched.getJob().equals(job);
  }

  public void testStandardJob_createWatchedJob_rewrite() {
    final JobDispatcher dispatcher = new JobDispatcher();
    final CalculationJob job1 =
        new CalculationJob(
            createJobSpecification(),
            0,
            null,
            Arrays.asList(JOB_ITEM_AB),
            CacheSelectHint.privateValues(Arrays.asList(VS_B)));
    final CalculationJob job2 =
        new CalculationJob(
            createJobSpecification(),
            0,
            new long[] {job1.getSpecification().getJobId()},
            Arrays.asList(JOB_ITEM_BC),
            CacheSelectHint.privateValues(Arrays.asList(VS_B)));
    job1.addTail(job2);
    final StandardJob standard =
        new StandardJob(dispatcher, job1, Mockito.mock(JobResultReceiver.class));
    final WatchedJob watched = standard.createWatchedJob();
    assertTrue(watched instanceof WholeWatchedJob);
    assertFalse(watched.getJob().getCacheSelectHint().isPrivateValue(VS_B));
    assertNull(watched.getJob().getTail());
  }

  public void testStandardJob_adjustCacheHints() {
    final CalculationJob job1 =
        new CalculationJob(
            createJobSpecification(),
            0,
            null,
            Arrays.asList(JOB_ITEM_A, JOB_ITEM_AB),
            CacheSelectHint.allPrivate());
    final CalculationJob job2 =
        new CalculationJob(
            createJobSpecification(),
            0,
            new long[] {job1.getSpecification().getJobId()},
            Arrays.asList(JOB_ITEM_BC),
            CacheSelectHint.privateValues(Arrays.asList(VS_B)));
    job1.addTail(job2);
    final CalculationJob adj1 =
        StandardJob.adjustCacheHints(
            job1,
            new HashMap<
                ValueSpecification,
                Triple<
                    CalculationJob,
                    ? extends Set<ValueSpecification>,
                    ? extends Set<ValueSpecification>>>());
    assertNotNull(adj1.getTail());
    final CalculationJob adj2 = adj1.getTail().iterator().next();
    assertEquals(adj1.getJobItems(), job1.getJobItems());
    assertEquals(adj2.getJobItems(), job2.getJobItems());
    assertTrue(adj1.getCacheSelectHint().isPrivateValue(VS_A));
    assertFalse(adj1.getCacheSelectHint().isPrivateValue(VS_B));
    assertFalse(adj2.getCacheSelectHint().isPrivateValue(VS_B));
    assertFalse(adj2.getCacheSelectHint().isPrivateValue(VS_C));
  }

  public void testStandardJob_WholeWatchedJob() {
    final CalculationJob job1 =
        new CalculationJob(
            createJobSpecification(),
            0,
            null,
            Arrays.asList(JOB_ITEM_A),
            CacheSelectHint.allShared());
    final CalculationJob job2 =
        new CalculationJob(
            createJobSpecification(),
            0,
            new long[] {job1.getSpecification().getJobId()},
            Arrays.asList(JOB_ITEM_AB),
            CacheSelectHint.allShared());
    job1.addTail(job2);
    final CalculationJob job3 =
        new CalculationJob(
            createJobSpecification(),
            0,
            new long[] {job1.getSpecification().getJobId()},
            Arrays.asList(JOB_ITEM_AC),
            CacheSelectHint.allShared());
    job1.addTail(job3);
    final CalculationJob job4 =
        new CalculationJob(
            createJobSpecification(),
            0,
            new long[] {job2.getSpecification().getJobId(), job3.getSpecification().getJobId()},
            Arrays.asList(JOB_ITEM_BCD),
            CacheSelectHint.allShared());
    job3.addTail(job4);
    final JobResultReceiver receiver = Mockito.mock(JobResultReceiver.class);
    final Queue<DispatchableJob> dispatched = new LinkedList<DispatchableJob>();
    final JobDispatcher dispatcher =
        new JobDispatcher() {
          @Override
          protected void dispatchJobImpl(final DispatchableJob job) {
            dispatched.add(job);
          }
        };
    final StandardJob parent = new StandardJob(dispatcher, job1, receiver);
    final WholeWatchedJob wjob1 = parent.createWholeWatchedJob(job1);
    final CalculationJobResult result1 =
        new CalculationJobResult(
            job1.getSpecification(), 0, Arrays.asList(CalculationJobResultItem.success()), "Test");
    wjob1.getResultReceiver(result1).resultReceived(result1);
    Mockito.verify(receiver).resultReceived(result1);
    Mockito.reset();
    assertEquals(dispatched.size(), 2);
    final WholeWatchedJob wjob2 = (WholeWatchedJob) dispatched.poll();
    final WholeWatchedJob wjob3 = (WholeWatchedJob) dispatched.poll();
    final CalculationJobResult result2 =
        new CalculationJobResult(
            job2.getSpecification(), 0, Arrays.asList(CalculationJobResultItem.success()), "Test");
    final CalculationJobResult result3 =
        new CalculationJobResult(
            job3.getSpecification(), 0, Arrays.asList(CalculationJobResultItem.success()), "Test");
    wjob3.getResultReceiver(result3).resultReceived(result3);
    Mockito.verify(receiver).resultReceived(result3);
    Mockito.reset();
    assertEquals(dispatched.size(), 0);
    wjob2.getResultReceiver(result2).resultReceived(result2);
    Mockito.verify(receiver).resultReceived(result2);
    Mockito.reset();
    assertEquals(dispatched.size(), 1);
    final WholeWatchedJob wjob4 = (WholeWatchedJob) dispatched.poll();
    final CalculationJobResult result4 =
        new CalculationJobResult(
            job4.getSpecification(), 0, Arrays.asList(CalculationJobResultItem.success()), "Test");
    wjob4.getResultReceiver(result4).resultReceived(result4);
    Mockito.verify(receiver).resultReceived(result4);
    Mockito.reset();
  }

  public void testWatchedJob_prepareRetryJob_singleItem() {
    final JobDispatcher dispatcher = new JobDispatcher();
    final FunctionBlacklistMaintainer blacklist = Mockito.mock(FunctionBlacklistMaintainer.class);
    dispatcher.setFunctionBlacklistMaintainer(blacklist);
    final CalculationJob job =
        new CalculationJob(
            createJobSpecification(),
            0,
            null,
            Arrays.asList(JOB_ITEM_A),
            CacheSelectHint.allShared());
    final JobResultReceiver receiver = Mockito.mock(JobResultReceiver.class);
    final StandardJob standard = new StandardJob(dispatcher, job, receiver);
    final WatchedJob watched = new WatchedJob.Whole(standard, job, receiver);
    watched.prepareRetryJob(null);
    Mockito.verify(blacklist).failedJobItem(JOB_ITEM_A);
  }

  public void testWatchedJob_prepareRetryJob_split_one() {
    final Queue<DispatchableJob> dispatched = new LinkedList<DispatchableJob>();
    final JobDispatcher dispatcher =
        new JobDispatcher() {
          @Override
          protected void dispatchJobImpl(final DispatchableJob job) {
            dispatched.add(job);
          }
        };
    final CalculationJob job =
        new CalculationJob(
            createJobSpecification(),
            0,
            null,
            Arrays.asList(JOB_ITEM_A, JOB_ITEM_AB),
            CacheSelectHint.privateValues(Arrays.asList(VS_A)));
    final JobResultReceiver receiver = Mockito.mock(JobResultReceiver.class);
    final StandardJob standard = new StandardJob(dispatcher, job, receiver);
    final WatchedJob watched = new WatchedJob.Whole(standard, job, receiver);
    final DispatchableJob split = watched.prepareRetryJob(null);
    final CalculationJob job1 = split.getJob();
    assertEquals(job1.getJobItems(), Arrays.asList(JOB_ITEM_A));
    assertFalse(job1.getCacheSelectHint().isPrivateValue(VS_A));
    final CalculationJobResult result1 =
        new CalculationJobResult(
            job1.getSpecification(), 0, Arrays.asList(CalculationJobResultItem.success()), "Test");
    split.getResultReceiver(result1).resultReceived(result1);
    Mockito.verifyZeroInteractions(receiver);
    assertEquals(dispatched.size(), 1);
    final DispatchableJob next = dispatched.poll();
    final CalculationJob job2 = next.getJob();
    assertEquals(job2.getJobItems(), Arrays.asList(JOB_ITEM_AB));
    assertFalse(job2.getCacheSelectHint().isPrivateValue(VS_A));
    final CalculationJobResult result2 =
        new CalculationJobResult(
            job2.getSpecification(),
            0,
            Arrays.asList(CalculationJobResultItem.failure("Foo", "Bar")),
            "Test");
    next.getResultReceiver(result2).resultReceived(result2);
    Mockito.verify(receiver)
        .resultReceived(
            new CalculationJobResult(
                job.getSpecification(),
                0,
                Arrays.asList(
                    CalculationJobResultItem.success(),
                    CalculationJobResultItem.failure("Foo", "Bar")),
                "Test"));
    assertTrue(job1.getSpecification().getJobId() != job2.getSpecification().getJobId());
    assertTrue(job2.getSpecification().getJobId() == job.getSpecification().getJobId());
  }

  public void testWatchedJob_prepareRetryJob_split_two() {
    final Queue<DispatchableJob> dispatched = new LinkedList<DispatchableJob>();
    final JobDispatcher dispatcher =
        new JobDispatcher() {
          @Override
          protected void dispatchJobImpl(final DispatchableJob job) {
            dispatched.add(job);
          }
        };
    final CalculationJob job =
        new CalculationJob(
            createJobSpecification(),
            0,
            null,
            Arrays.asList(JOB_ITEM_A, JOB_ITEM_AB, JOB_ITEM_BC, JOB_ITEM_BCD),
            CacheSelectHint.sharedValues(Arrays.asList(VS_D)));
    final JobResultReceiver receiver = Mockito.mock(JobResultReceiver.class);
    final StandardJob standard = new StandardJob(dispatcher, job, receiver);
    final WatchedJob watched = new WatchedJob.Whole(standard, job, receiver);
    final DispatchableJob split = watched.prepareRetryJob(null);
    final CalculationJob job1 = split.getJob();
    assertEquals(job1.getJobItems(), Arrays.asList(JOB_ITEM_A, JOB_ITEM_AB));
    assertTrue(job1.getCacheSelectHint().isPrivateValue(VS_A));
    assertFalse(job1.getCacheSelectHint().isPrivateValue(VS_B));
    final CalculationJobResult result1 =
        new CalculationJobResult(
            job1.getSpecification(),
            0,
            Arrays.asList(CalculationJobResultItem.success(), CalculationJobResultItem.success()),
            "1");
    split.getResultReceiver(result1).resultReceived(result1);
    Mockito.verifyZeroInteractions(receiver);
    assertEquals(dispatched.size(), 1);
    final DispatchableJob next = dispatched.poll();
    final CalculationJob job2 = next.getJob();
    assertEquals(job2.getJobItems(), Arrays.asList(JOB_ITEM_BC, JOB_ITEM_BCD));
    assertFalse(job2.getCacheSelectHint().isPrivateValue(VS_B));
    assertTrue(job2.getCacheSelectHint().isPrivateValue(VS_C));
    assertFalse(job2.getCacheSelectHint().isPrivateValue(VS_D));
    final CalculationJobResult result2 =
        new CalculationJobResult(
            job2.getSpecification(),
            0,
            Arrays.asList(
                CalculationJobResultItem.failure("Foo", "Bar"), CalculationJobResultItem.success()),
            "2");
    next.getResultReceiver(result2).resultReceived(result2);
    Mockito.verify(receiver)
        .resultReceived(
            new CalculationJobResult(
                job.getSpecification(),
                0,
                Arrays.asList(
                    CalculationJobResultItem.success(),
                    CalculationJobResultItem.success(),
                    CalculationJobResultItem.failure("Foo", "Bar"),
                    CalculationJobResultItem.success()),
                "1, 2"));
    assertTrue(job1.getSpecification().getJobId() != job2.getSpecification().getJobId());
    assertTrue(job2.getSpecification().getJobId() == job.getSpecification().getJobId());
  }
}