package storm.starter.tools; import static org.fest.assertions.api.Assertions.assertThat; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import backtype.storm.utils.Time; public class NthLastModifiedTimeTrackerTest { private static final int ANY_NUM_TIMES_TO_TRACK = 3; private static final int MILLIS_IN_SEC = 1000; @DataProvider public Object[][] illegalNumTimesData() { return new Object[][] { { -10 }, { -3 }, { -2 }, { -1 }, { 0 } }; } @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "illegalNumTimesData") public void negativeOrZeroNumTimesToTrackShouldThrowIAE(int numTimesToTrack) { new NthLastModifiedTimeTracker(numTimesToTrack); } @DataProvider public Object[][] legalNumTimesData() { return new Object[][] { { 1 }, { 2 }, { 3 }, { 20 } }; } @Test(dataProvider = "legalNumTimesData") public void positiveNumTimesToTrackShouldBeOk(int numTimesToTrack) { new NthLastModifiedTimeTracker(numTimesToTrack); } @DataProvider public Object[][] whenNotYetMarkedAsModifiedData() { return new Object[][] { { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 8 }, { 10 } }; } @Test(dataProvider = "whenNotYetMarkedAsModifiedData") public void shouldReturnCorrectModifiedTimeEvenWhenNotYetMarkedAsModified(int secondsToAdvance) { // given Time.startSimulating(); NthLastModifiedTimeTracker tracker = new NthLastModifiedTimeTracker(ANY_NUM_TIMES_TO_TRACK); // when advanceSimulatedTimeBy(secondsToAdvance); int seconds = tracker.secondsSinceOldestModification(); // then assertThat(seconds).isEqualTo(secondsToAdvance); // cleanup Time.stopSimulating(); } @DataProvider public Object[][] simulatedTrackerIterations() { return new Object[][] { { 1, new int[] { 0, 1 }, new int[] { 0, 0 } }, { 1, new int[] { 0, 2 }, new int[] { 0, 0 } }, { 2, new int[] { 2, 2 }, new int[] { 2, 2 } }, { 2, new int[] { 0, 4 }, new int[] { 0, 4 } }, { 1, new int[] { 1, 1, 1, 1, 1, 1, 1 }, new int[] { 0, 0, 0, 0, 0, 0, 0 } }, { 1, new int[] { 1, 2, 3, 4, 5, 6, 7 }, new int[] { 0, 0, 0, 0, 0, 0, 0 } }, { 2, new int[] { 1, 1, 1, 1, 1, 1, 1 }, new int[] { 1, 1, 1, 1, 1, 1, 1 } }, { 2, new int[] { 2, 2, 2, 2, 2, 2, 2 }, new int[] { 2, 2, 2, 2, 2, 2, 2 } }, { 2, new int[] { 1, 2, 3, 4, 5, 6, 7 }, new int[] { 1, 2, 3, 4, 5, 6, 7 } }, { 3, new int[] { 1, 1, 1, 1, 1, 1, 1 }, new int[] { 1, 2, 2, 2, 2, 2, 2 } }, { 3, new int[] { 1, 2, 3, 4, 5, 6, 7 }, new int[] { 1, 3, 5, 7, 9, 11, 13 } }, { 3, new int[] { 2, 2, 2, 2, 2, 2, 2 }, new int[] { 2, 4, 4, 4, 4, 4, 4 } }, { 4, new int[] { 1, 1, 1, 1, 1, 1, 1 }, new int[] { 1, 2, 3, 3, 3, 3, 3 } }, { 4, new int[] { 1, 2, 3, 4, 5, 6, 7 }, new int[] { 1, 3, 6, 9, 12, 15, 18 } }, { 4, new int[] { 2, 2, 2, 2, 2, 2, 2 }, new int[] { 2, 4, 6, 6, 6, 6, 6 } }, { 5, new int[] { 1, 1, 1, 1, 1, 1, 1 }, new int[] { 1, 2, 3, 4, 4, 4, 4 } }, { 5, new int[] { 1, 2, 3, 4, 5, 6, 7 }, new int[] { 1, 3, 6, 10, 14, 18, 22 } }, { 5, new int[] { 2, 2, 2, 2, 2, 2, 2 }, new int[] { 2, 4, 6, 8, 8, 8, 8 } }, { 6, new int[] { 1, 1, 1, 1, 1, 1, 1 }, new int[] { 1, 2, 3, 4, 5, 5, 5 } }, { 6, new int[] { 1, 2, 3, 4, 5, 6, 7 }, new int[] { 1, 3, 6, 10, 15, 20, 25 } }, { 6, new int[] { 2, 2, 2, 2, 2, 2, 2 }, new int[] { 2, 4, 6, 8, 10, 10, 10 } }, { 3, new int[] { 1, 2, 3 }, new int[] { 1, 3, 5 } } }; } @Test(dataProvider = "simulatedTrackerIterations") public void shouldReturnCorrectModifiedTimeWhenMarkedAsModified(int numTimesToTrack, int[] secondsToAdvancePerIteration, int[] expLastModifiedTimes) { // given Time.startSimulating(); NthLastModifiedTimeTracker tracker = new NthLastModifiedTimeTracker(numTimesToTrack); int[] modifiedTimes = new int[expLastModifiedTimes.length]; // when int i = 0; for (int secondsToAdvance : secondsToAdvancePerIteration) { advanceSimulatedTimeBy(secondsToAdvance); tracker.markAsModified(); modifiedTimes[i] = tracker.secondsSinceOldestModification(); i++; } // then assertThat(modifiedTimes).isEqualTo(expLastModifiedTimes); // cleanup Time.stopSimulating(); } private void advanceSimulatedTimeBy(int seconds) { Time.advanceTime(seconds * MILLIS_IN_SEC); } }