@Test
public void testOffSwitchScheduling() throws Exception {

  // Setup queue configs
  setupSingleLevelQueues(csConf);
  
  Map<String, CSQueue> queues = new HashMap<String, CSQueue>();
  CSQueue root = 
      CapacityScheduler.parseQueue(csContext, csConf, null, 
          CapacitySchedulerConfiguration.ROOT, queues, queues, 
          TestUtils.spyHook);
  // Setup some nodes
  final int memoryPerNode = 10;
  final int coresPerNode = 16;
  final int numNodes = 2;
  
  FiCaSchedulerNode node_0 = 
      TestUtils.getMockNode("host_0", DEFAULT_RACK, 0, memoryPerNode*GB);
  FiCaSchedulerNode node_1 = 
      TestUtils.getMockNode("host_1", DEFAULT_RACK, 0, memoryPerNode*GB);
  
  final Resource clusterResource = 
      Resources.createResource(numNodes * (memoryPerNode*GB), 
          numNodes * coresPerNode);
  when(csContext.getNumClusterNodes()).thenReturn(numNodes);
  // Start testing
  LeafQueue a = (LeafQueue)queues.get(A);
  LeafQueue b = (LeafQueue)queues.get(B);
  
  // Simulate B returning a container on node_0
  stubQueueAllocation(a, clusterResource, node_0, 0*GB, NodeType.OFF_SWITCH);
  stubQueueAllocation(b, clusterResource, node_0, 1*GB, NodeType.OFF_SWITCH);
  root.assignContainers(clusterResource, node_0, false);
  verifyQueueMetrics(a, 0*GB, clusterResource);
  verifyQueueMetrics(b, 1*GB, clusterResource);
  
  // Now, A should get the scheduling opportunity since A=0G/6G, B=1G/14G
  // also, B gets a scheduling opportunity since A allocates RACK_LOCAL
  stubQueueAllocation(a, clusterResource, node_1, 2*GB, NodeType.RACK_LOCAL);
  stubQueueAllocation(b, clusterResource, node_1, 1*GB, NodeType.OFF_SWITCH);
  root.assignContainers(clusterResource, node_1, false);
  InOrder allocationOrder = inOrder(a, b);
  allocationOrder.verify(a).assignContainers(eq(clusterResource), 
      any(FiCaSchedulerNode.class), anyBoolean());
  allocationOrder.verify(b).assignContainers(eq(clusterResource), 
      any(FiCaSchedulerNode.class), anyBoolean());
  verifyQueueMetrics(a, 2*GB, clusterResource);
  verifyQueueMetrics(b, 2*GB, clusterResource);
  
  // Now, B should get the scheduling opportunity 
  // since A has 2/6G while B has 2/14G, 
  // However, since B returns off-switch, A won't get an opportunity
  stubQueueAllocation(a, clusterResource, node_0, 1*GB, NodeType.NODE_LOCAL);
  stubQueueAllocation(b, clusterResource, node_0, 2*GB, NodeType.OFF_SWITCH);
  root.assignContainers(clusterResource, node_0, false);
  allocationOrder = inOrder(b, a);
  allocationOrder.verify(b).assignContainers(eq(clusterResource), 
      any(FiCaSchedulerNode.class), anyBoolean());
  allocationOrder.verify(a).assignContainers(eq(clusterResource), 
      any(FiCaSchedulerNode.class), anyBoolean());
  verifyQueueMetrics(a, 2*GB, clusterResource);
  verifyQueueMetrics(b, 4*GB, clusterResource);
}