@Test public void checkpointRestoreWithPendingWindowSliding() { try { final int factor = 4; final int windowSlide = 50; final int windowSize = factor * windowSlide; TestTimeServiceProvider timerService = new TestTimeServiceProvider(); // sliding window (200 msecs) every 50 msecs AccumulatingProcessingTimeWindowOperator<Integer, Integer, Integer> op = new AccumulatingProcessingTimeWindowOperator<>( validatingIdentityFunction, identitySelector, IntSerializer.INSTANCE, IntSerializer.INSTANCE, windowSize, windowSlide); OneInputStreamOperatorTestHarness<Integer, Integer> testHarness = new OneInputStreamOperatorTestHarness<>(op, new ExecutionConfig(), timerService); timerService.setCurrentTime(0); testHarness.setup(); testHarness.open(); // inject some elements final int numElements = 1000; final int numElementsFirst = 700; for (int i = 0; i < numElementsFirst; i++) { testHarness.processElement(new StreamRecord<>(i)); } // draw a snapshot List<Integer> resultAtSnapshot = extractFromStreamRecords(testHarness.getOutput()); int beforeSnapShot = testHarness.getOutput().size(); StreamStateHandle state = testHarness.snapshot(1L, System.currentTimeMillis()); int afterSnapShot = testHarness.getOutput().size(); assertEquals("operator performed computation during snapshot", beforeSnapShot, afterSnapShot); assertTrue(resultAtSnapshot.size() <= factor * numElementsFirst); // inject the remaining elements - these should not influence the snapshot for (int i = numElementsFirst; i < numElements; i++) { testHarness.processElement(new StreamRecord<>(i)); } op.dispose(); // re-create the operator and restore the state op = new AccumulatingProcessingTimeWindowOperator<>( validatingIdentityFunction, identitySelector, IntSerializer.INSTANCE, IntSerializer.INSTANCE, windowSize, windowSlide); testHarness = new OneInputStreamOperatorTestHarness<>(op, new ExecutionConfig(), timerService); testHarness.setup(); testHarness.restore(state); testHarness.open(); // inject again the remaining elements for (int i = numElementsFirst; i < numElements; i++) { testHarness.processElement(new StreamRecord<>(i)); } timerService.setCurrentTime(50); timerService.setCurrentTime(100); timerService.setCurrentTime(150); timerService.setCurrentTime(200); timerService.setCurrentTime(250); timerService.setCurrentTime(300); timerService.setCurrentTime(350); testHarness.close(); op.dispose(); // get and verify the result List<Integer> finalResult = new ArrayList<>(resultAtSnapshot); List<Integer> finalPartialResult = extractFromStreamRecords(testHarness.getOutput()); finalResult.addAll(finalPartialResult); assertEquals(factor * numElements, finalResult.size()); Collections.sort(finalResult); for (int i = 0; i < factor * numElements; i++) { assertEquals(i / factor, finalResult.get(i).intValue()); } } catch (Exception e) { e.printStackTrace(); fail(e.getMessage()); } }
@Test public void checkpointRestoreWithPendingWindowTumbling() { try { final int windowSize = 200; // tumbling window that triggers every 200 milliseconds AccumulatingProcessingTimeWindowOperator<Integer, Integer, Integer> op = new AccumulatingProcessingTimeWindowOperator<>( validatingIdentityFunction, identitySelector, IntSerializer.INSTANCE, IntSerializer.INSTANCE, windowSize, windowSize); TestTimeServiceProvider timerService = new TestTimeServiceProvider(); OneInputStreamOperatorTestHarness<Integer, Integer> testHarness = new OneInputStreamOperatorTestHarness<>(op, new ExecutionConfig(), timerService); testHarness.setup(); testHarness.open(); timerService.setCurrentTime(0); // inject some elements final int numElementsFirst = 700; final int numElements = 1000; for (int i = 0; i < numElementsFirst; i++) { testHarness.processElement(new StreamRecord<>(i)); } // draw a snapshot and dispose the window System.out.println("GOT: " + testHarness.getOutput()); int beforeSnapShot = testHarness.getOutput().size(); StreamStateHandle state = testHarness.snapshot(1L, System.currentTimeMillis()); List<Integer> resultAtSnapshot = extractFromStreamRecords(testHarness.getOutput()); int afterSnapShot = testHarness.getOutput().size(); assertEquals("operator performed computation during snapshot", beforeSnapShot, afterSnapShot); assertTrue(afterSnapShot <= numElementsFirst); // inject some random elements, which should not show up in the state for (int i = 0; i < 300; i++) { testHarness.processElement(new StreamRecord<>(i + numElementsFirst)); } op.dispose(); // re-create the operator and restore the state op = new AccumulatingProcessingTimeWindowOperator<>( validatingIdentityFunction, identitySelector, IntSerializer.INSTANCE, IntSerializer.INSTANCE, windowSize, windowSize); testHarness = new OneInputStreamOperatorTestHarness<>(op, new ExecutionConfig(), timerService); testHarness.setup(); testHarness.restore(state); testHarness.open(); // inject some more elements for (int i = numElementsFirst; i < numElements; i++) { testHarness.processElement(new StreamRecord<>(i)); } timerService.setCurrentTime(400); // get and verify the result List<Integer> finalResult = new ArrayList<>(); finalResult.addAll(resultAtSnapshot); List<Integer> finalPartialResult = extractFromStreamRecords(testHarness.getOutput()); finalResult.addAll(finalPartialResult); assertEquals(numElements, finalResult.size()); Collections.sort(finalResult); for (int i = 0; i < numElements; i++) { assertEquals(i, finalResult.get(i).intValue()); } } catch (Exception e) { e.printStackTrace(); fail(e.getMessage()); } }