Package com.opengamma.core.position.impl

Source Code of com.opengamma.core.position.impl.PortfolioNodeTraverserTest$Callback

/**
* Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.core.position.impl;

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.atomic.AtomicInteger;

import org.testng.annotations.Test;

import com.opengamma.core.position.PortfolioNode;
import com.opengamma.core.position.Position;
import com.opengamma.id.UniqueId;
import com.opengamma.id.UniqueIdentifiable;
import com.opengamma.util.PoolExecutor;
import com.opengamma.util.test.TestGroup;

/**
* Test {@link PortfolioNodeTraverser}.
*/
public class PortfolioNodeTraverserTest {

  /* Test tree =

                                       N0
                N1              N10               P19 P20
         N2    N5  P8 P9    N11     N14   P17 P18
       P3 P4 P6 P7        P12 P13 P15 P16
  
   */

  private Position createTestPosition(final AtomicInteger nextId) {
    final SimplePosition position = new SimplePosition();
    position.setUniqueId(UniqueId.of("Test", Integer.toString(nextId.getAndIncrement())));
    return position;
  }

  private PortfolioNode createTestPortfolioNode(final AtomicInteger nextId, final int depth) {
    final SimplePortfolioNode node = new SimplePortfolioNode();
    node.setUniqueId(UniqueId.of("Test", Integer.toString(nextId.getAndIncrement())));
    if (depth > 0) {
      node.addChildNode(createTestPortfolioNode(nextId, depth - 1));
      node.addChildNode(createTestPortfolioNode(nextId, depth - 1));
    }
    node.addPosition(createTestPosition(nextId));
    node.addPosition(createTestPosition(nextId));
    return node;
  }

  private static final int NODE_PRE = 0;
  private static final int NODE_POST = 1;
  private static final int POSITION_PRE = 2;
  private static final int POSITION_POST = 3;

  private static class Callback implements PortfolioNodeTraversalCallback {

    private final Queue<Integer> _visited = new LinkedList<Integer>();

    protected void visit(final int type, final UniqueIdentifiable uniqueId) {
      _visited.add(type);
      _visited.add(Integer.parseInt(uniqueId.getUniqueId().getValue()));
    }

    @Override
    public void postOrderOperation(final PortfolioNode portfolioNode) {
      visit(NODE_POST, portfolioNode);
    }

    @Override
    public void postOrderOperation(final PortfolioNode parentNode, final Position position) {
      visit(POSITION_POST, position);
    }

    @Override
    public void preOrderOperation(final PortfolioNode portfolioNode) {
      visit(NODE_PRE, portfolioNode);
    }

    @Override
    public void preOrderOperation(final PortfolioNode parentNode, final Position position) {
      visit(POSITION_PRE, position);
    }

    private void assertVisit(final int type, final int... identifiers) {
      for (int identifier : identifiers) {
        assertEquals(_visited.remove().intValue(), type);
        assertEquals(_visited.remove().intValue(), identifier);
      }
    }

    private void assertVisitBefore(final int t1, final int i1, final int t2, final int i2) {
      final Iterator<Integer> itr = _visited.iterator();
      while (itr.hasNext()) {
        int t = itr.next();
        int i = itr.next();
        if ((t == t1) && (i == i1)) {
          while (itr.hasNext()) {
            t = itr.next();
            i = itr.next();
            if ((t == t2) && (i == i2)) {
              return;
            }
          }
          fail("Expected " + t1 + "/" + i1 + " before " + t2 + "/" + i2);
        }
      }
    }

    private void assertVisitAfter(final int t1, final int i1, final int t2, final int i2) {
      assertVisitBefore(t2, i2, t1, i1);
    }

    private void assertVisitCount() {
      // four values for each of the 21 node/position entries in the graph
      assertEquals(_visited.size(), 84);
    }
  }

  //-------------------------------------------------------------------------
  @Test(groups = TestGroup.UNIT)
  public void testDepthFirst() {
    final Callback cb = new Callback();
    PortfolioNodeTraverser.depthFirst(cb).traverse(createTestPortfolioNode(new AtomicInteger(), 2));
    cb.assertVisitCount();
    cb.assertVisit(NODE_PRE, 0);
    cb.assertVisit(POSITION_PRE, 19, 20);
    cb.assertVisit(NODE_PRE, 1);
    cb.assertVisit(POSITION_PRE, 8, 9);
    cb.assertVisit(NODE_PRE, 2);
    cb.assertVisit(POSITION_PRE, 3, 4);
    cb.assertVisit(POSITION_POST, 3, 4);
    cb.assertVisit(NODE_POST, 2);
    cb.assertVisit(NODE_PRE, 5);
    cb.assertVisit(POSITION_PRE, 6, 7);
    cb.assertVisit(POSITION_POST, 6, 7);
    cb.assertVisit(NODE_POST, 5);
    cb.assertVisit(POSITION_POST, 8, 9);
    cb.assertVisit(NODE_POST, 1);
    cb.assertVisit(NODE_PRE, 10);
    cb.assertVisit(POSITION_PRE, 17, 18);
    cb.assertVisit(NODE_PRE, 11);
    cb.assertVisit(POSITION_PRE, 12, 13);
    cb.assertVisit(POSITION_POST, 12, 13);
    cb.assertVisit(NODE_POST, 11);
    cb.assertVisit(NODE_PRE, 14);
    cb.assertVisit(POSITION_PRE, 15, 16);
    cb.assertVisit(POSITION_POST, 15, 16);
    cb.assertVisit(NODE_POST, 14);
    cb.assertVisit(POSITION_POST, 17, 18);
    cb.assertVisit(NODE_POST, 10);
    cb.assertVisit(POSITION_POST, 19, 20);
    cb.assertVisit(NODE_POST, 0);
  }

  @Test(groups = TestGroup.UNIT, enabled = false)
  public void testBreadthFirst() {
    final Callback cb = new Callback();
    PortfolioNodeTraverser.breadthFirst(cb).traverse(createTestPortfolioNode(new AtomicInteger(), 2));
    cb.assertVisitCount();
    // Is this the desired order for a "breadth-first" search??
    cb.assertVisit(NODE_PRE, 0);
    cb.assertVisit(POSITION_PRE, 19, 20);
    cb.assertVisit(NODE_PRE, 1, 10);
    cb.assertVisit(POSITION_PRE, 8, 9, 17, 18);
    cb.assertVisit(NODE_PRE, 2, 5, 11, 14);
    cb.assertVisit(POSITION_PRE, 3, 4, 6, 7, 12, 13, 15, 16);
    cb.assertVisit(POSITION_POST, 3, 4, 6, 7, 12, 13, 15, 16);
    cb.assertVisit(NODE_POST, 2, 5, 11, 14);
    cb.assertVisit(POSITION_POST, 8, 9, 17, 18);
    cb.assertVisit(NODE_POST, 1, 10);
    cb.assertVisit(POSITION_POST, 19, 20);
    cb.assertVisit(NODE_POST, 0);
  }

  @Test(groups = TestGroup.UNIT, expectedExceptions = UnsupportedOperationException.class)
  public void testBreadthFirstBroken() {
    final Callback cb = new Callback();
    PortfolioNodeTraverser.breadthFirst(cb).traverse(createTestPortfolioNode(new AtomicInteger(), 2));
  }

  private void assertParallelOrder(final Callback cb) {
    cb.assertVisitCount();
    // Exact ordering can't be predicted but make sure some thing happened before or after others
    cb.assertVisitBefore(NODE_PRE, 0, NODE_PRE, 1);
    cb.assertVisitBefore(NODE_PRE, 0, NODE_PRE, 10);
    cb.assertVisitBefore(NODE_PRE, 0, POSITION_PRE, 19);
    cb.assertVisitBefore(NODE_PRE, 0, POSITION_PRE, 20);
    cb.assertVisitAfter(NODE_POST, 0, NODE_POST, 1);
    cb.assertVisitAfter(NODE_POST, 0, NODE_POST, 10);
    cb.assertVisitAfter(NODE_POST, 0, POSITION_POST, 19);
    cb.assertVisitAfter(NODE_POST, 0, POSITION_POST, 20);
    cb.assertVisitBefore(NODE_PRE, 1, NODE_PRE, 2);
    cb.assertVisitBefore(NODE_PRE, 1, NODE_PRE, 5);
    cb.assertVisitBefore(NODE_PRE, 1, POSITION_PRE, 8);
    cb.assertVisitBefore(NODE_PRE, 1, POSITION_PRE, 9);
    cb.assertVisitBefore(NODE_PRE, 2, POSITION_PRE, 3);
    cb.assertVisitBefore(NODE_PRE, 2, POSITION_PRE, 4);
    cb.assertVisitBefore(POSITION_PRE, 3, POSITION_POST, 4);
    cb.assertVisitBefore(POSITION_PRE, 4, POSITION_POST, 4);
    cb.assertVisitAfter(NODE_POST, 2, POSITION_POST, 3);
    cb.assertVisitAfter(NODE_POST, 2, POSITION_POST, 4);
    cb.assertVisitAfter(POSITION_POST, 8, POSITION_POST, 3);
    cb.assertVisitAfter(POSITION_POST, 8, POSITION_POST, 4);
    cb.assertVisitAfter(POSITION_POST, 9, POSITION_POST, 3);
    cb.assertVisitAfter(POSITION_POST, 9, POSITION_POST, 4);
  }

  @Test(groups = TestGroup.UNIT)
  public void testParallelNoSlaveThreads() {
    final Callback cb = new Callback();
    PortfolioNodeTraverser.parallel(cb, new PoolExecutor(0, getClass().getSimpleName())).traverse(createTestPortfolioNode(new AtomicInteger(), 2));
    // With a single thread (the caller) should be depth first
    assertParallelOrder(cb);
  }

  @Test(groups = TestGroup.UNIT_SLOW)
  public void testParallelSlaveThreads() {
    final Callback cb = new Callback() {
      @Override
      protected synchronized void visit(final int type, final UniqueIdentifiable uniqueId) {
        try {
          Thread.sleep(100);
        } catch (InterruptedException e) {
        }
        super.visit(type, uniqueId);
      }
    };
    PortfolioNodeTraverser.parallel(cb, new PoolExecutor(8, getClass().getSimpleName())).traverse(createTestPortfolioNode(new AtomicInteger(), 2));
    assertParallelOrder(cb);
  }

}
TOP

Related Classes of com.opengamma.core.position.impl.PortfolioNodeTraverserTest$Callback

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.