public PersistentUpperLimit(TimestampBoundStore boundStore) { this.store = boundStore; this.currentLimit = boundStore.getUpperLimit(); }
@Override public long getUpperLimit() { return delegate.getUpperLimit(); }
@Test public void testTimestampBoundStore() { long upperLimit1 = store.getUpperLimit(); long upperLimit2 = store.getUpperLimit(); Assert.assertEquals(upperLimit1, upperLimit2); store.storeUpperLimit(upperLimit2 + 1); long upperLimit3 = store.getUpperLimit(); Assert.assertEquals(upperLimit3, upperLimit2 + 1); } }
private void assertBoundEquals(long timestampBound) { assertThat(timestampBoundStore.getUpperLimit()).isEqualTo(timestampBound); }
private void assertWeCanReadTimestamp(long expectedTimestamp) { TimestampBoundStore timestampBoundStore = CassandraTimestampBoundStore.create(kv); assertThat(timestampBoundStore.getUpperLimit()).isEqualTo(expectedTimestamp); }
@Before public void setup() { boundStore = mock(TimestampBoundStore.class); when(boundStore.getUpperLimit()).thenReturn(INITIAL_UPPER_LIMIT); upperLimit = new PersistentUpperLimit(boundStore); }
@Test public void shouldStartWithTheCurrentStoredLimit() { when(boundStore.getUpperLimit()).thenReturn(TIMESTAMP); PersistentUpperLimit brandNewUpperLimit = new PersistentUpperLimit(boundStore); assertThat(brandNewUpperLimit.get(), is(TIMESTAMP)); }
private long getBoundAfterTakingOutOneMillionTimestamps() { TimestampBoundStore timestampBoundStore = CassandraTimestampBoundStore.create(kv); long newLimit = timestampBoundStore.getUpperLimit() + ONE_MILLION; timestampBoundStore.storeUpperLimit(newLimit); return newLimit; } }
@Test public void shouldOnlyMakeOneGetCallToTheUnderlyingStore() { upperLimit.get(); upperLimit.get(); verify(boundStore, times(1)).getUpperLimit(); }
@Test public void testBounds() { TimestampBoundStore ts = CassandraTimestampBoundStore.create(kv); long limit = ts.getUpperLimit(); ts.storeUpperLimit(limit + 10); Assert.assertEquals(limit + 10, ts.getUpperLimit()); ts.storeUpperLimit(limit + 20); Assert.assertEquals(limit + 20, ts.getUpperLimit()); ts.storeUpperLimit(limit + 30); Assert.assertEquals(limit + 30, ts.getUpperLimit()); }
@Test public void canBackupAndRestoreTimestampTable() { TimestampBoundStore timestampBoundStore = CassandraTimestampBoundStore.create(kv); long limit = timestampBoundStore.getUpperLimit(); timestampBoundStore.storeUpperLimit(limit + ONE_MILLION); invalidator.backupAndInvalidate(); invalidator.revalidateFromBackup(); assertThat(timestampBoundStore.getUpperLimit()).isEqualTo(limit + ONE_MILLION); }
@Test public void canBackupAlreadyStoredBound() { timestampBoundStore.getUpperLimit(); timestampBoundStore.storeUpperLimit(TIMESTAMP_1); assertThat(backupRunner.backupExistingTimestamp()).isEqualTo(TIMESTAMP_1); }
@Test public void resilientToMultipleStoreUpperLimitBeforeGet() { TimestampBoundStore ts = CassandraTimestampBoundStore.create(kv); long limit = ts.getUpperLimit(); ts.storeUpperLimit(limit + 10); ts.storeUpperLimit(limit + 20); Assert.assertEquals(limit + 20, ts.getUpperLimit()); }
TimestampBoundStore ts = CassandraTimestampBoundStore.create(kv); TimestampBoundStore ts2 = CassandraTimestampBoundStore.create(kv); long limit = ts.getUpperLimit(); Assert.assertEquals(limit, ts2.getUpperLimit()); ts.storeUpperLimit(limit + 10); Assert.assertEquals(limit + 10, ts.getUpperLimit()); Assert.assertEquals(limit + 10, ts2.getUpperLimit()); Assert.assertEquals(limit + 20, ts.getUpperLimit()); Assert.assertEquals(limit + 20, ts2.getUpperLimit()); Assert.assertEquals(limit + 30, ts.getUpperLimit());
@Test public void stateIsWellDefinedEvenUnderConcurrentBackupsAndRestores() { timestampBoundStore.getUpperLimit(); timestampBoundStore.storeUpperLimit(TIMESTAMP_3); CassandraTestTools.executeInParallelOnExecutorService(() -> { CassandraTimestampBackupRunner runner = new CassandraTimestampBackupRunner(kv); try { if (ThreadLocalRandom.current().nextBoolean()) { runner.backupExistingTimestamp(); } else { runner.restoreFromBackup(); } } catch (IllegalStateException exception) { // This is possible under concurrent backup *and* restore. // The point of this test is to ensure that the table is in a well defined state at the end. } }); backupRunner.restoreFromBackup(); assertThat(timestampBoundStore.getUpperLimit()).isEqualTo(TIMESTAMP_3); }
@Test public void ignoresInvalidBackupIfDataAvailable() { timestampBoundStore.getUpperLimit(); timestampBoundStore.storeUpperLimit(TIMESTAMP_3); backupRunner.restoreFromBackup(); assertBoundEquals(TIMESTAMP_3); }
@Test public void backsUpKnownBoundIfExists() { timestampBoundStore.getUpperLimit(); timestampBoundStore.storeUpperLimit(TIMESTAMP_1); backupRunner.backupExistingTimestamp(); backupRunner.restoreFromBackup(); assertBoundEquals(TIMESTAMP_1); }
@Test public void multipleRestoresDoNotMakeUsGoBackInTime() { backupRunner.backupExistingTimestamp(); backupRunner.restoreFromBackup(); timestampBoundStore.getUpperLimit(); timestampBoundStore.storeUpperLimit(TIMESTAMP_2); backupRunner.restoreFromBackup(); assertBoundEquals(TIMESTAMP_2); // in particular, not TIMESTAMP_1 }
@Test public void canBackupAndRestoreMultipleTimes() { timestampBoundStore.getUpperLimit(); timestampBoundStore.storeUpperLimit(TIMESTAMP_1); backupRunner.backupExistingTimestamp(); assertBoundNotReadable(); backupRunner.restoreFromBackup(); assertBoundEquals(TIMESTAMP_1); timestampBoundStore.getUpperLimit(); timestampBoundStore.storeUpperLimit(TIMESTAMP_2); backupRunner.backupExistingTimestamp(); assertBoundNotReadable(); backupRunner.restoreFromBackup(); assertBoundEquals(TIMESTAMP_2); }
@Test public void testTimestampBoundStore() { long upperLimit1 = store.getUpperLimit(); long upperLimit2 = store.getUpperLimit(); Assert.assertEquals(upperLimit1, upperLimit2); store.storeUpperLimit(upperLimit2 + 1); long upperLimit3 = store.getUpperLimit(); Assert.assertEquals(upperLimit3, upperLimit2 + 1); } }