/** * Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.engine.calcnode; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNull; import static org.testng.Assert.assertTrue; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.Queue; import java.util.Set; import org.mockito.Mockito; import org.testng.annotations.Test; import org.threeten.bp.Instant; import com.opengamma.engine.ComputationTargetSpecification; import com.opengamma.engine.cache.CacheSelectHint; import com.opengamma.engine.calcnode.CalculationJob; import com.opengamma.engine.calcnode.CalculationJobItem; import com.opengamma.engine.calcnode.CalculationJobResult; import com.opengamma.engine.calcnode.CalculationJobResultItem; import com.opengamma.engine.calcnode.CalculationJobSpecification; import com.opengamma.engine.calcnode.DispatchableJob; import com.opengamma.engine.calcnode.JobDispatcher; import com.opengamma.engine.calcnode.JobResultReceiver; import com.opengamma.engine.calcnode.StandardJob; import com.opengamma.engine.calcnode.WatchedJob; import com.opengamma.engine.calcnode.StandardJob.WholeWatchedJob; import com.opengamma.engine.exec.JobIdSource; import com.opengamma.engine.function.EmptyFunctionParameters; import com.opengamma.engine.function.blacklist.FunctionBlacklistMaintainer; import com.opengamma.engine.value.ValueProperties; import com.opengamma.engine.value.ValuePropertyNames; import com.opengamma.engine.value.ValueSpecification; import com.opengamma.engine.view.ExecutionLogMode; import com.opengamma.id.UniqueId; import com.opengamma.id.VersionCorrection; import com.opengamma.util.test.TestGroup; import com.opengamma.util.tuple.Triple; /** * Tests the implementation of watched jobs. */ @Test(groups = TestGroup.UNIT) public class WatchedJobTest { private final ValueSpecification VS_A = new ValueSpecification("A", ComputationTargetSpecification.NULL, ValueProperties.with(ValuePropertyNames.FUNCTION, "A").get()); private final ValueSpecification VS_B = new ValueSpecification("B", ComputationTargetSpecification.NULL, ValueProperties.with(ValuePropertyNames.FUNCTION, "B").get()); private final ValueSpecification VS_C = new ValueSpecification("C", ComputationTargetSpecification.NULL, ValueProperties.with(ValuePropertyNames.FUNCTION, "C").get()); private final ValueSpecification VS_D = new ValueSpecification("D", ComputationTargetSpecification.NULL, ValueProperties.with(ValuePropertyNames.FUNCTION, "D").get()); private final CalculationJobItem JOB_ITEM_A = new CalculationJobItem("A", new EmptyFunctionParameters(), ComputationTargetSpecification.NULL, Collections.<ValueSpecification>emptySet(), Arrays.asList(VS_A), ExecutionLogMode.INDICATORS); private final CalculationJobItem JOB_ITEM_AB = new CalculationJobItem("B", new EmptyFunctionParameters(), ComputationTargetSpecification.NULL, Arrays.asList(VS_A), Arrays.asList(VS_B), ExecutionLogMode.INDICATORS); private final CalculationJobItem JOB_ITEM_BC = new CalculationJobItem("C", new EmptyFunctionParameters(), ComputationTargetSpecification.NULL, Arrays.asList(VS_B), Arrays.asList(VS_C), ExecutionLogMode.INDICATORS); private final CalculationJobItem JOB_ITEM_AC = new CalculationJobItem("C", new EmptyFunctionParameters(), ComputationTargetSpecification.NULL, Arrays.asList(VS_A), Arrays.asList(VS_C), ExecutionLogMode.INDICATORS); private final CalculationJobItem JOB_ITEM_BCD = new CalculationJobItem("D", new EmptyFunctionParameters(), ComputationTargetSpecification.NULL, 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, VersionCorrection.LATEST, 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, VersionCorrection.LATEST, 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, VersionCorrection.LATEST, null, Arrays.asList(JOB_ITEM_AB), CacheSelectHint.privateValues(Arrays.asList(VS_B))); final CalculationJob job2 = new CalculationJob(createJobSpecification(), 0, VersionCorrection.LATEST, 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, VersionCorrection.LATEST, null, Arrays.asList(JOB_ITEM_A, JOB_ITEM_AB), CacheSelectHint.allPrivate()); final CalculationJob job2 = new CalculationJob(createJobSpecification(), 0, VersionCorrection.LATEST, 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, VersionCorrection.LATEST, null, Arrays.asList(JOB_ITEM_A), CacheSelectHint.allShared()); final CalculationJob job2 = new CalculationJob(createJobSpecification(), 0, VersionCorrection.LATEST, new long[] {job1.getSpecification().getJobId() }, Arrays.asList(JOB_ITEM_AB), CacheSelectHint.allShared()); job1.addTail(job2); final CalculationJob job3 = new CalculationJob(createJobSpecification(), 0, VersionCorrection.LATEST, new long[] {job1.getSpecification().getJobId() }, Arrays.asList(JOB_ITEM_AC), CacheSelectHint.allShared()); job1.addTail(job3); final CalculationJob job4 = new CalculationJob(createJobSpecification(), 0, VersionCorrection.LATEST, 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, VersionCorrection.LATEST, 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, VersionCorrection.LATEST, 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, VersionCorrection.LATEST, 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()); } }