public async Task TestReplaceAndRemove() { var key1 = "key1"; var value1 = "value1"; var fallback1 = "fallback1"; var s1 = new InMemoryKeyValueStore(); var s2 = NewFileBasedKeyValueStore("TestReplaceAndRemoveDir").WithFallbackStore(s1); var s3 = new InMemoryKeyValueStore().WithFallbackStore(s2); await s1.Set(key1, value1); // Test that replace with same value via s3 returns the old value (which is also value1): Assert.Equal(value1, await s3.Set(key1, value1)); // s3 will ask s2 which will ask s1 so the value will be returned correctly: Assert.Equal(value1, await s3.Get(key1, fallback1)); Assert.Single(await s3.GetAllKeys()); Assert.True(await s3.Remove(key1)); // Setting it again will return null since it was removed from all stores: Assert.Null(await s3.Set(key1, value1)); Assert.True(await s1.Remove(key1)); // Remove it only from s1 Assert.Equal(value1, await s3.Get(key1, fallback1)); // Still cached in s3 and s2 // s1 had the key already removed, so the combined remove result will be false: Assert.False(await s3.Remove(key1)); }
public async Task TestDualStore() { var firstStore = new InMemoryKeyValueStore(); var secondStor = new InMemoryKeyValueStore(); var dualStore = new DualStore(firstStore, secondStor); var key1 = "key1"; var key2 = "key2"; var value1 = "v1"; var fallb1 = "f1"; Assert.False(await dualStore.ContainsKey(key1)); Assert.Null(await dualStore.Set(key1, value1)); Assert.True(await dualStore.ContainsKey(key1)); Assert.True(await firstStore.ContainsKey(key1)); Assert.False(await secondStor.ContainsKey(key1)); Assert.Single(await dualStore.GetAllKeys()); Assert.Single(await firstStore.GetAllKeys()); Assert.Empty(await secondStor.GetAllKeys()); Assert.Equal(value1, await dualStore.Get(key1, fallb1)); Assert.Equal(value1, await firstStore.Get(key1, fallb1)); Assert.Equal(fallb1, await secondStor.Get(key1, fallb1)); Assert.Equal(fallb1, await dualStore.Get(key2, fallb1)); Assert.True(await dualStore.Remove(key1)); Assert.Equal(fallb1, await dualStore.Get(key1, fallb1)); Assert.Equal(fallb1, await firstStore.Get(key1, fallb1)); Assert.False(await dualStore.Remove(key2)); }
public async Task TestStoreWithDelay() { // Simulates the DB on the server: var innerStore = new InMemoryKeyValueStore(); // Simulates the connection to the server: var simulatedDelayStore = new MockDelayKeyValueStore(innerStore); // Handles connection problems to the server: var exWrapperStore = new ExceptionWrapperKeyValueStore(simulatedDelayStore); // Represents the local cache in case the server cant be reached: var outerStore = new InMemoryKeyValueStore().WithFallbackStore(exWrapperStore); var key1 = "key1"; var value1 = "value1"; var key2 = "key2"; var value2 = "value2"; { await outerStore.Set(key1, value1); Assert.Equal(value1, await outerStore.Get(key1, "")); Assert.Equal(value1, await innerStore.Get(key1, "")); } simulatedDelayStore.throwTimeoutError = true; var simulatedErrorCatched = false; exWrapperStore.onError = (Exception e) => { simulatedErrorCatched = true; }; { await outerStore.Set(key2, value2); // This will cause a timeout error in the "delayed" store Assert.True(simulatedErrorCatched); Assert.Contains(key2, await outerStore.GetAllKeys()); // In the outer store the value was set Assert.False(await innerStore.ContainsKey(key2)); // The inner store never got the update Assert.False(await exWrapperStore.ContainsKey(key2)); // The exc. wrapper returns false if an error is thrown Assert.Null(await exWrapperStore.GetAllKeys()); // Will throw another error and return null } Log.d("innerStore " + innerStore.latestFallbackGetTimingInMs); Log.d("simulatedDelayStore " + simulatedDelayStore.latestFallbackGetTimingInMs); Log.d("exWrapperStore " + exWrapperStore.latestFallbackGetTimingInMs); Log.d("outerStore " + outerStore.latestFallbackGetTimingInMs); Assert.Equal(0, innerStore.latestFallbackGetTimingInMs); Assert.NotEqual(0, exWrapperStore.latestFallbackGetTimingInMs); Assert.NotEqual(0, outerStore.latestFallbackGetTimingInMs); }