Пример #1
0
        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);
        }
Пример #2
0
        private async Task TestPlayerPrefsFromBackgroundThreadTasks()
        {
            var myKey1      = "myKey1";
            var myVal1      = "myVal1";
            var myFallback1 = "myFallback1";

            var innerStore = new ExceptionWrapperKeyValueStore(new PlayerPrefsStore());
            await innerStore.Remove(myKey1); // Cleanup prefs from previous tests

            var outerStore = new InMemoryKeyValueStore().WithFallbackStore(innerStore);

            var task = TaskRunner.instance.RunInBackground(async(cancel) => {
                cancel.ThrowIfCancellationRequested();
                Assert.IsFalse(MainThread.isMainThread);

                var innerStoreThrewAnError = false;
                // Set and Get from a background thread will throw an exception in the innerStore
                innerStore.onError = (e) => { innerStoreThrewAnError = true; };
                // So only the outerStore will be updated when calling Set and Get from the background:
                await outerStore.Set(myKey1, myVal1);
                Assert.IsTrue(innerStoreThrewAnError);
                var x = await outerStore.Get(myKey1, myFallback1);
                // The value returned by Get was cached in the outer store so it will be correct:
                Assert.AreEqual(myVal1, x);
                // Check that the Set request never reached the real pref. store:
                Assert.AreEqual(myFallback1, await innerStore.Get(myKey1, myFallback1));
            }).task;
            await task;

            Assert.IsTrue(task.IsCompleted);
            Assert.IsNull(task.Exception);

            Assert.IsTrue(MainThread.isMainThread);
            // There should not be any errors when working on the main thread so
            // throw any errors that happen in the inner store:
            innerStore.onError = (e) => { throw e; };
            // In the main thread Set and Get will not throw errors:
            await outerStore.Set(myKey1, myVal1);

            Assert.AreEqual(myVal1, await outerStore.Get(myKey1, myFallback1));
            // Check that the Set request never reached the real pref. store:
            Assert.AreEqual(myVal1, await innerStore.Get(myKey1, myFallback1));
        }
Пример #3
0
        public async Task ExampleUsage3()
        {
            // Simulate the DB on the server
            var simulatedDb = new InMemoryKeyValueStore();
            // Simulate the connection (with a delay) to the server:
            var simulatedRemoteConnection = new MockDelayKeyValueStore(simulatedDb);

            // The connection to the server is wrapped by a automatic retry for failing requests:
            var requestRetry = new RetryKeyValueStore(simulatedRemoteConnection, maxNrOfRetries: 5);
            // Any errors in the inner layers like connection errors, DB errors are catched by default:
            var errorHandler = new ExceptionWrapperKeyValueStore(requestRetry);
            // The outer store is a local in memory cache and the main point of contact:
            var outerStore = new InMemoryKeyValueStore().WithFallbackStore(errorHandler);

            var key1      = "key1";
            var value1    = "value1";
            var fallback1 = "fallback1";
            await outerStore.Set(key1, value1);

            Assert.Equal(value1, await outerStore.Get(key1, fallback1));
            Assert.Equal(value1, await simulatedDb.Get(key1, fallback1));

            // Simmulate connection problems to the remote DB:
            simulatedRemoteConnection.throwTimeoutError = true;

            var key2      = "key2";
            var value2    = "value2";
            var fallback2 = "fallback2";
            // Awaiting a set will take some time since there will be 5 retries:
            await outerStore.Set(key2, value2);

            // The outer store has the set value cached:
            Assert.Equal(value2, await outerStore.Get(key2, fallback2));
            // But the request never reached the simulated DB:
            Assert.False(await simulatedDb.ContainsKey(key2));
        }
Пример #4
0
        public async Task TestExceptionCatching()
        {
            var    myKey1          = "key1";
            int    myValue1        = 1;
            string myDefaultString = "myDefaultValue";

            var innerStore     = new InMemoryKeyValueStore();
            var exHandlerStore = new ExceptionWrapperKeyValueStore(innerStore, new HashSet <Type>());

            await innerStore.Set(myKey1, myValue1);

            // Cause an InvalidCastException:
            await Assert.ThrowsAsync <InvalidCastException>(() => innerStore.Get <string>(myKey1, myDefaultString));

            // Cause an InvalidCastException which is then catched and instead the default is returned:
            string x = await exHandlerStore.Get <string>(myKey1, myDefaultString);

            Assert.Equal(myDefaultString, x);

            // Add the InvalidCastException to the list of errors that should not be ignored:
            exHandlerStore.errorTypeBlackList.Add(typeof(InvalidCastException));
            // Now the same Get request passes the InvalidCastException on:
            await Assert.ThrowsAsync <InvalidCastException>(() => exHandlerStore.Get <string>(myKey1, myDefaultString));
        }
Пример #5
0
        /// <summary>
        /// THe default store uses a Dictionary for memory caching and an exception layer to catch
        /// and errors that might happen e.g. when the PlayerPrefs are accessed from a background task
        /// </summary>
        private static IKeyValueStore newDefaultSettingsPipeline()
        {
            var wrappedPlayerPrefs = new ExceptionWrapperKeyValueStore(new PlayerPrefsStore());

            return(new InMemoryKeyValueStore().WithFallbackStore(wrappedPlayerPrefs));
        }