@Test public void testOperatorShutdown() { dag.setAttribute(OperatorContext.STORAGE_AGENT, new MemoryStorageAgent()); GenericTestOperator o1 = dag.addOperator("o1", GenericTestOperator.class); GenericTestOperator o2 = dag.addOperator("o2", GenericTestOperator.class); GenericTestOperator o3 = dag.addOperator("o3", GenericTestOperator.class); dag.addStream("stream1", o1.outport1, o2.inport1); dag.addStream("stream2", o2.outport1, o3.inport1); dag.setAttribute( o2, OperatorContext.PARTITIONER, new StatelessPartitioner<GenericTestOperator>(2)); StreamingContainerManager scm = new StreamingContainerManager(dag); PhysicalPlan physicalPlan = scm.getPhysicalPlan(); Map<PTContainer, MockContainer> mockContainers = new HashMap<>(); for (PTContainer c : physicalPlan.getContainers()) { MockContainer mc = new MockContainer(scm, c); mockContainers.put(c, mc); } // deploy all containers for (Map.Entry<PTContainer, MockContainer> ce : mockContainers.entrySet()) { ce.getValue().deploy(); } for (Map.Entry<PTContainer, MockContainer> ce : mockContainers.entrySet()) { // skip buffer server purge in monitorHeartbeat ce.getKey().bufferServerAddress = null; } PTOperator o1p1 = physicalPlan.getOperators(dag.getMeta(o1)).get(0); MockContainer mc1 = mockContainers.get(o1p1.getContainer()); MockOperatorStats o1p1mos = mc1.stats(o1p1.getId()); o1p1mos.currentWindowId(1).checkpointWindowId(1).deployState(DeployState.ACTIVE); mc1.sendHeartbeat(); PTOperator o2p1 = physicalPlan.getOperators(dag.getMeta(o2)).get(0); MockContainer mc2 = mockContainers.get(o2p1.getContainer()); MockOperatorStats o2p1mos = mc2.stats(o2p1.getId()); o2p1mos.currentWindowId(1).checkpointWindowId(1).deployState(DeployState.ACTIVE); mc2.sendHeartbeat(); Assert.assertEquals("2 partitions", 2, physicalPlan.getOperators(dag.getMeta(o2)).size()); PTOperator o2p2 = physicalPlan.getOperators(dag.getMeta(o2)).get(1); MockContainer mc3 = mockContainers.get(o2p2.getContainer()); MockOperatorStats o2p2mos = mc3.stats(o2p2.getId()); o2p2mos.currentWindowId(1).checkpointWindowId(1).deployState(DeployState.ACTIVE); mc3.sendHeartbeat(); PTOperator o3p1 = physicalPlan.getOperators(dag.getMeta(o3)).get(0); MockContainer mc4 = mockContainers.get(o3p1.getContainer()); MockOperatorStats o3p1mos = mc4.stats(o3p1.getId()); o3p1mos.currentWindowId(1).checkpointWindowId(1).deployState(DeployState.ACTIVE); mc4.sendHeartbeat(); // unifier PTOperator unifier = physicalPlan.getMergeOperators(dag.getMeta(o2)).get(0); MockContainer mc5 = mockContainers.get(unifier.getContainer()); MockOperatorStats unifierp1mos = mc5.stats(unifier.getId()); unifierp1mos.currentWindowId(1).checkpointWindowId(1).deployState(DeployState.ACTIVE); mc5.sendHeartbeat(); o1p1mos.currentWindowId(2).deployState(DeployState.SHUTDOWN); mc1.sendHeartbeat(); scm.monitorHeartbeat(); Assert.assertEquals("committedWindowId", -1, scm.getCommittedWindowId()); scm.monitorHeartbeat(); // committedWindowId updated in next cycle Assert.assertEquals("committedWindowId", 1, scm.getCommittedWindowId()); scm.processEvents(); Assert.assertEquals( "containers at committedWindowId=1", 5, physicalPlan.getContainers().size()); // checkpoint window 2 o1p1mos.checkpointWindowId(2); mc1.sendHeartbeat(); scm.monitorHeartbeat(); Assert.assertEquals("committedWindowId", 1, scm.getCommittedWindowId()); o2p1mos.currentWindowId(2).checkpointWindowId(2); o2p2mos.currentWindowId(2).checkpointWindowId(2); o3p1mos.currentWindowId(2).checkpointWindowId(2); unifierp1mos.currentWindowId(2).checkpointWindowId(2); mc2.sendHeartbeat(); mc3.sendHeartbeat(); mc4.sendHeartbeat(); mc5.sendHeartbeat(); scm.monitorHeartbeat(); // Operators are shutdown when both operators reach window Id 2 Assert.assertEquals(0, o1p1.getContainer().getOperators().size()); Assert.assertEquals(0, o2p1.getContainer().getOperators().size()); Assert.assertEquals(0, physicalPlan.getContainers().size()); }
@Test public void testProcessHeartbeat() throws Exception { TestGeneratorInputOperator o1 = dag.addOperator("o1", TestGeneratorInputOperator.class); dag.setAttribute( o1, OperatorContext.STATS_LISTENERS, Arrays.asList(new StatsListener[] {new PartitioningTest.PartitionLoadWatch()})); dag.setAttribute(OperatorContext.STORAGE_AGENT, new MemoryStorageAgent()); StreamingContainerManager scm = new StreamingContainerManager(dag); PhysicalPlan plan = scm.getPhysicalPlan(); Assert.assertEquals("number required containers", 1, plan.getContainers().size()); PTOperator o1p1 = plan.getOperators(dag.getMeta(o1)).get(0); // assign container String containerId = "container1"; StreamingContainerAgent sca = scm.assignContainer( new ContainerResource(0, containerId, "localhost", 512, 0, null), InetSocketAddress.createUnresolved("localhost", 0)); Assert.assertNotNull(sca); Assert.assertEquals(PTContainer.State.ALLOCATED, o1p1.getContainer().getState()); Assert.assertEquals(PTOperator.State.PENDING_DEPLOY, o1p1.getState()); ContainerStats cstats = new ContainerStats(containerId); ContainerHeartbeat hb = new ContainerHeartbeat(); hb.setContainerStats(cstats); ContainerHeartbeatResponse chr = scm.processHeartbeat(hb); // get deploy request Assert.assertNotNull(chr.deployRequest); Assert.assertEquals("" + chr.deployRequest, 1, chr.deployRequest.size()); Assert.assertEquals(PTContainer.State.ACTIVE, o1p1.getContainer().getState()); Assert.assertEquals("state " + o1p1, PTOperator.State.PENDING_DEPLOY, o1p1.getState()); // first operator heartbeat OperatorHeartbeat ohb = new OperatorHeartbeat(); ohb.setNodeId(o1p1.getId()); ohb.setState(OperatorHeartbeat.DeployState.ACTIVE); OperatorStats stats = new OperatorStats(); stats.checkpoint = new Checkpoint(2, 0, 0); stats.windowId = 3; stats.outputPorts = Lists.newArrayList(); PortStats ps = new PortStats(TestGeneratorInputOperator.OUTPUT_PORT); ps.bufferServerBytes = 101; ps.tupleCount = 1; stats.outputPorts.add(ps); ohb.windowStats = Lists.newArrayList(stats); cstats.operators.add(ohb); scm.processHeartbeat(hb); // activate operator Assert.assertEquals(PTContainer.State.ACTIVE, o1p1.getContainer().getState()); Assert.assertEquals("state " + o1p1, PTOperator.State.ACTIVE, o1p1.getState()); Assert.assertEquals("tuples " + o1p1, 1, o1p1.stats.totalTuplesEmitted.get()); Assert.assertEquals("tuples " + o1p1, 0, o1p1.stats.totalTuplesProcessed.get()); Assert.assertEquals("window " + o1p1, 3, o1p1.stats.currentWindowId.get()); Assert.assertEquals("port stats", 1, o1p1.stats.outputPortStatusList.size()); PortStatus o1p1ps = o1p1.stats.outputPortStatusList.get(TestGeneratorInputOperator.OUTPUT_PORT); Assert.assertNotNull("port stats", o1p1ps); Assert.assertEquals("port stats", 1, o1p1ps.totalTuples); // second operator heartbeat stats = new OperatorStats(); stats.checkpoint = new Checkpoint(2, 0, 0); stats.windowId = 4; stats.outputPorts = Lists.newArrayList(); ps = new PortStats(TestGeneratorInputOperator.OUTPUT_PORT); ps.bufferServerBytes = 1; ps.tupleCount = 1; stats.outputPorts.add(ps); ohb.windowStats = Lists.newArrayList(stats); cstats.operators.clear(); cstats.operators.add(ohb); scm.processHeartbeat(hb); Assert.assertEquals("tuples " + o1p1, 2, o1p1.stats.totalTuplesEmitted.get()); Assert.assertEquals("window " + o1p1, 4, o1p1.stats.currentWindowId.get()); Assert.assertEquals("statsQueue " + o1p1, 2, o1p1.stats.listenerStats.size()); scm.processEvents(); Assert.assertEquals("statsQueue " + o1p1, 0, o1p1.stats.listenerStats.size()); Assert.assertEquals("lastStats " + o1p1, 2, o1p1.stats.lastWindowedStats.size()); }