/** * Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.engine.depgraph; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertSame; import static org.testng.Assert.assertTrue; import java.util.Iterator; import org.testng.annotations.Test; import com.opengamma.engine.ComputationTargetSpecification; import com.opengamma.engine.target.ComputationTargetReference; import com.opengamma.engine.target.ComputationTargetRequirement; import com.opengamma.engine.target.ComputationTargetType; import com.opengamma.engine.value.ValueRequirement; import com.opengamma.id.ExternalId; import com.opengamma.id.UniqueId; import com.opengamma.util.test.TestGroup; /** * Tests the {@link OrderedRunQueue} implementations. Basic add/remove will have been tested as part of {@link RunQueueTest} - this is specifically targeting the sorting algorithm. */ @Test(groups = TestGroup.UNIT) public class OrderedRunQueueTest { private ContextRunnable runnable() { return new ContextRunnable() { @Override public boolean tryRun(final GraphBuildingContext context) { // No-op return true; } }; } private ContextRunnable resolveTask(final ComputationTargetReference target) { return new ResolveTask(new ValueRequirement("Value", target), null, null); } /** * Creates a set of tasks in the expected ordering (lowest to highest priority). They will get added in a haphazard order to test the sorting. */ private ContextRunnable[] createTasks() { return new ContextRunnable[] { /* 0 */resolveTask(new ComputationTargetSpecification(ComputationTargetType.POSITION, UniqueId.of("Position", "1"))), /* 1 */resolveTask(new ComputationTargetSpecification(ComputationTargetType.POSITION, UniqueId.of("Position", "0"))), /* 2 */resolveTask(new ComputationTargetSpecification(ComputationTargetType.TRADE, UniqueId.of("Trade", "1"))), /* 3 */resolveTask(new ComputationTargetSpecification(ComputationTargetType.TRADE, UniqueId.of("Trade", "0"))), /* 4 */resolveTask(new ComputationTargetSpecification(ComputationTargetType.SECURITY, UniqueId.of("Security", "1"))), /* 5 */resolveTask(new ComputationTargetSpecification(ComputationTargetType.SECURITY, UniqueId.of("Security", "0"))), /* 6 */resolveTask(new ComputationTargetRequirement(ComputationTargetType.SECURITY, ExternalId.of("Test", "Foo"))), /* 7 */resolveTask(new ComputationTargetRequirement(ComputationTargetType.SECURITY, ExternalId.of("Test", "Bar"))), /* 8 */resolveTask(new ComputationTargetSpecification(ComputationTargetType.PRIMITIVE, UniqueId.of("Primitive", "1"))), /* 9 */resolveTask(new ComputationTargetSpecification(ComputationTargetType.PRIMITIVE, UniqueId.of("Primitive", "0"))), /* 10 */resolveTask(new ComputationTargetRequirement(ComputationTargetType.PRIMITIVE, ExternalId.of("Test", "Foo"))), /* 11 */resolveTask(new ComputationTargetRequirement(ComputationTargetType.PRIMITIVE, ExternalId.of("Test", "Bar"))), /* 12 */resolveTask(ComputationTargetSpecification.NULL), /* 13 */resolveTask(new ComputationTargetSpecification(ComputationTargetType.PORTFOLIO_NODE, UniqueId.of("Node", "1"))), /* 14 */resolveTask(new ComputationTargetSpecification(ComputationTargetType.PORTFOLIO_NODE, UniqueId.of("Node", "0"))), /* 15 */runnable(), /* 16 */runnable(), /* 17 */runnable() }; } private void assertOrder(final OrderedRunQueue queue, final ContextRunnable[] tasks, final int... expected) { final Iterator<ContextRunnable> itr = queue.iterator(); for (int i = 0; i < expected.length; i++) { assertTrue(itr.hasNext()); final ContextRunnable actual = itr.next(); final ContextRunnable expect = tasks[expected[i]]; assertSame(actual, expect); } assertFalse(itr.hasNext()); } public void testAddAndSort() { final ContextRunnable[] tasks = createTasks(); final OrderedRunQueue queue = new OrderedRunQueue(10, 8); // Fill the queue to its "unsorted" limit (8); expect that order to be kept queue.add(tasks[17]); queue.add(tasks[15]); queue.add(tasks[13]); queue.add(tasks[11]); queue.add(tasks[9]); queue.add(tasks[7]); queue.add(tasks[5]); queue.add(tasks[3]); assertOrder(queue, tasks, 17, 15, 13, 11, 9, 7, 5, 3); // Add one more; the start of the buffer will be sorted queue.add(tasks[1]); assertOrder(queue, tasks, 11, 13, 17, 15, 9, 7, 5, 3, 1); // Fill the unsorted portion queue.add(tasks[16]); queue.add(tasks[14]); queue.add(tasks[12]); assertOrder(queue, tasks, 11, 13, 17, 15, 9, 7, 5, 3, 1, 16, 14, 12); // Add one more; the front of the buffer will be sorted queue.add(tasks[10]); assertOrder(queue, tasks, 3, 5, 7, 9, 11, 13, 17, 15, 1, 16, 14, 12, 10); // Add remainder queue.add(tasks[8]); queue.add(tasks[6]); queue.add(tasks[4]); assertOrder(queue, tasks, 3, 5, 7, 9, 11, 13, 17, 15, 1, 16, 14, 12, 10, 8, 6, 4); queue.add(tasks[2]); assertOrder(queue, tasks, 1, 3, 5, 7, 9, 11, 12, 13, 14, 17, 16, 15, 10, 8, 6, 4, 2); queue.add(tasks[0]); assertOrder(queue, tasks, 1, 3, 5, 7, 9, 11, 12, 13, 14, 17, 16, 15, 10, 8, 6, 4, 2, 0); } // TODO: Test the "take" operation, including reading into the "sorted" section of the array }