Example #1
0
        private async Task AbortPushDuringSync(SyncAbortLocation whereToAbort)
        {
            await ClearStore();

            SyncAbortLocation abortLocation = whereToAbort;
            DateTime          now           = DateTime.UtcNow;
            int seed = now.Year * 10000 + now.Month * 100 + now.Day;

            Log("Using random seed: {0}", seed);
            Random rndGen = new Random(seed);

            var offlineReadyClient = CreateClient();

            var items = Enumerable.Range(0, 10).Select(_ => new OfflineReadyItem(rndGen)).ToArray();

            foreach (var item in items)
            {
                item.Id = Guid.NewGuid().ToString("D");
            }

            int abortIndex = abortLocation == SyncAbortLocation.Start ? 0 :
                             (abortLocation == SyncAbortLocation.End ? items.Length - 1 : rndGen.Next(1, items.Length - 1));
            var idToAbort = items[abortIndex].Id;

            Log("Will send {0} items, aborting when id = {1}", items.Length, idToAbort);

            var localStore = new MobileServiceSQLiteStore(StoreFileName);

            Log("Defined the table on the local store");
            localStore.DefineTable <OfflineReadyItem>();

            var syncHandler = new AbortingSyncHandler(this, id => id == idToAbort);
            await offlineReadyClient.SyncContext.InitializeAsync(localStore, syncHandler);

            Log("Initialized the store and sync context");

            var localTable  = offlineReadyClient.GetSyncTable <OfflineReadyItem>();
            var remoteTable = offlineReadyClient.GetTable <OfflineReadyItem>();

            try
            {
                foreach (var item in items)
                {
                    await localTable.InsertAsync(item);
                }

                Log("Inserted {0} items in the local table. Now pushing those");

                try
                {
                    await offlineReadyClient.SyncContext.PushAsync();

                    Assert.Fail("Error, push call should have failed");
                }
                catch (MobileServicePushFailedException ex)
                {
                    Log("Caught (expected) exception: {0}", ex);
                }

                var expectedOperationQueueSize = items.Length - abortIndex;
                Log("Current operation queue size: {0}", offlineReadyClient.SyncContext.PendingOperations);
                if (expectedOperationQueueSize != offlineReadyClient.SyncContext.PendingOperations)
                {
                    Assert.Fail(string.Format("Error, expected {0} items in the queue", expectedOperationQueueSize));
                }

                foreach (var allItemsPushed in new bool[] { false, true })
                {
                    HashSet <OfflineReadyItem> itemsInServer, itemsNotInServer;
                    if (allItemsPushed)
                    {
                        itemsInServer    = new HashSet <OfflineReadyItem>(items.ToArray());
                        itemsNotInServer = new HashSet <OfflineReadyItem>(Enumerable.Empty <OfflineReadyItem>());
                    }
                    else
                    {
                        itemsInServer    = new HashSet <OfflineReadyItem>(items.Where((item, index) => index < abortIndex));
                        itemsNotInServer = new HashSet <OfflineReadyItem>(items.Where((item, index) => index >= abortIndex));
                    }

                    foreach (var item in items)
                    {
                        var itemFromServer = (await remoteTable.Where(i => i.Id == item.Id).Take(1).ToEnumerableAsync()).FirstOrDefault();
                        Log("Item with id = {0} from server: {1}", item.Id,
                            itemFromServer == null ? "<<null>>" : itemFromServer.ToString());
                        if (itemsInServer.Contains(item) && itemFromServer == null)
                        {
                            Assert.Fail(string.Format("Error, the item {0} should have made to the server", item.Id));
                        }
                        else if (itemsNotInServer.Contains(item) && itemFromServer != null)
                        {
                            Assert.Fail(string.Format("Error, the item {0} should not have made to the server", item.Id));
                        }
                    }

                    if (!allItemsPushed)
                    {
                        Log("Changing the handler so that it doesn't abort anymore.");
                        syncHandler.AbortCondition = _ => false;
                        Log("Pushing again");
                        await offlineReadyClient.SyncContext.PushAsync();

                        Log("Finished pushing all elements");
                    }
                }

                Log("Changing the handler so that it doesn't abort anymore.");
                syncHandler.AbortCondition = _ => false;

                Log("Cleaning up");
                foreach (var item in items)
                {
                    await localTable.DeleteAsync(item);
                }

                await offlineReadyClient.SyncContext.PushAsync();

                Log("Done");
            }
            finally
            {
                localStore.Dispose();
                ClearStore().Wait();
            }
        }
        private async Task AbortPushDuringSync(SyncAbortLocation whereToAbort)
        {
            ClearStore();
            SyncAbortLocation abortLocation = whereToAbort;
            DateTime          now           = DateTime.UtcNow;
            int    seed   = now.Year * 10000 + now.Month * 100 + now.Day;
            Random rndGen = new Random(seed);

            var offlineReadyClient = CreateClient();

            var items = Enumerable.Range(0, 10).Select(_ => new OfflineReadyItem(rndGen)).ToArray();

            foreach (var item in items)
            {
                item.Id = Guid.NewGuid().ToString("D");
            }

            int abortIndex = abortLocation == SyncAbortLocation.Start ? 0 :
                             (abortLocation == SyncAbortLocation.End ? items.Length - 1 : rndGen.Next(1, items.Length - 1));
            var idToAbort = items[abortIndex].Id;

            var localStore = new MobileServiceSQLiteStore(StoreFileName);

            localStore.DefineTable <OfflineReadyItem>();

            var syncHandler = new AbortingSyncHandler(this, id => id == idToAbort);
            await offlineReadyClient.SyncContext.InitializeAsync(localStore, syncHandler);

            var localTable  = offlineReadyClient.GetSyncTable <OfflineReadyItem>();
            var remoteTable = offlineReadyClient.GetTable <OfflineReadyItem>();

            try
            {
                foreach (var item in items)
                {
                    await localTable.InsertAsync(item);
                }

                await Assert.ThrowsAsync <MobileServicePushFailedException>(() => offlineReadyClient.SyncContext.PushAsync());

                var expectedOperationQueueSize = items.Length - abortIndex;
                Assert.False(expectedOperationQueueSize != offlineReadyClient.SyncContext.PendingOperations);

                foreach (var allItemsPushed in new bool[] { false, true })
                {
                    HashSet <OfflineReadyItem> itemsInServer, itemsNotInServer;
                    if (allItemsPushed)
                    {
                        itemsInServer    = new HashSet <OfflineReadyItem>(items.ToArray());
                        itemsNotInServer = new HashSet <OfflineReadyItem>(Enumerable.Empty <OfflineReadyItem>());
                    }
                    else
                    {
                        itemsInServer    = new HashSet <OfflineReadyItem>(items.Where((item, index) => index < abortIndex));
                        itemsNotInServer = new HashSet <OfflineReadyItem>(items.Where((item, index) => index >= abortIndex));
                    }

                    foreach (var item in items)
                    {
                        var itemFromServer = (await remoteTable.Where(i => i.Id == item.Id).Take(1).ToEnumerableAsync()).FirstOrDefault();
                        Assert.False(itemsInServer.Contains(item) && itemFromServer == null);
                        Assert.False(itemsNotInServer.Contains(item) && itemFromServer != null);
                    }

                    if (!allItemsPushed)
                    {
                        syncHandler.AbortCondition = _ => false;
                        await offlineReadyClient.SyncContext.PushAsync();
                    }
                }

                syncHandler.AbortCondition = _ => false;

                foreach (var item in items)
                {
                    await localTable.DeleteAsync(item);
                }

                await offlineReadyClient.SyncContext.PushAsync();
            }
            finally
            {
                localStore.Dispose();
                ClearStore();
            }
        }