private VersionedType(VersionedType other)
 {
     this.Id = other.Id;
     this.Name = other.Name;
     this.Number = other.Number;
     this.Version = other.Version;
     this.CreatedAt = other.CreatedAt;
     this.UpdatedAt = other.UpdatedAt;
 }
 private VersionedType(VersionedType other)
 {
     this.Id        = other.Id;
     this.Name      = other.Name;
     this.Number    = other.Number;
     this.Version   = other.Version;
     this.CreatedAt = other.CreatedAt;
     this.UpdatedAt = other.UpdatedAt;
 }
Exemplo n.º 3
0
        private async Task CreateOptimisticConcurrencyWithServerConflictsTest(string testName, bool clientWins)
        {
            var      client = this.GetClient();
            var      table  = client.GetTable <VersionedType>();
            DateTime now    = DateTime.UtcNow;
            int      seed   = now.Year * 10000 + now.Month * 100 + now.Day;
            Random   rndGen = new Random(seed);
            var      item   = new VersionedType(rndGen);
            await table.InsertAsync(item);

            var client2 = new MobileServiceClient(client.MobileAppUri);
            var table2  = client.GetTable <VersionedType>();
            var item2   = await table2.LookupAsync(item.Id);

            item2.Name   = Utilities.CreateSimpleRandomString(rndGen, 20);
            item2.Number = rndGen.Next(100000);
            await table2.UpdateAsync(item2);

            string oldName = item2.Name;
            string newName = Utilities.CreateSimpleRandomString(rndGen, 20);

            item.Name = newName;
            await table.UpdateAsync(item, new Dictionary <string, string> {
                { "conflictPolicy", clientWins ? "clientWins" : "serverWins" }
            });

            await table2.RefreshAsync(item2);

            if (clientWins)
            {
                Assert.False(item.Name != newName || item2.Name != newName);
            }
            else
            {
                Assert.False(item.Name != oldName || item2.Name != oldName);
            }

            await table.DeleteAsync(item);
        }
Exemplo n.º 4
0
        private async Task CreateOptimisticConcurrencyTest(string testName, Func <VersionedType, VersionedType, VersionedType> mergingPolicy)
        {
            var      client = this.GetClient();
            var      table  = client.GetTable <VersionedType>();
            DateTime now    = DateTime.UtcNow;
            int      seed   = now.Year * 10000 + now.Month * 100 + now.Day;
            Random   rndGen = new Random(seed);
            var      item   = new VersionedType(rndGen);
            await table.InsertAsync(item);

            var client2 = new MobileServiceClient(client.MobileAppUri);
            var table2  = client.GetTable <VersionedType>();
            var item2   = await table2.LookupAsync(item.Id);

            item2.Name   = Utilities.CreateSimpleRandomString(rndGen, 20);
            item2.Number = rndGen.Next(100000);
            await table2.UpdateAsync(item2);

            var ex = await Assert.ThrowsAsync <MobileServicePreconditionFailedException <VersionedType> >(async() =>
            {
                item.Name = Utilities.CreateSimpleRandomString(rndGen, 20);
                await table.UpdateAsync(item);
            });

            var serverItem = ex.Item;

            Assert.Equal(serverItem.Version, item2.Version);

            var cachedMergedItem = mergingPolicy(item, serverItem);
            var mergedItem       = mergingPolicy(item, serverItem);

            await table.UpdateAsync(mergedItem);

            Assert.Equal(cachedMergedItem, mergedItem);
            await table2.RefreshAsync(item2);

            Assert.Equal(item2, mergedItem);
        }
        private async Task CreateOptimisticConcurrencyWithServerConflictsTest(string testName, bool clientWins)
        {
            Log("### " + testName);

            var client = this.GetClient();
            var table = client.GetTable<VersionedType>();
            DateTime now = DateTime.UtcNow;
            int seed = now.Year * 10000 + now.Month * 100 + now.Day;
            Log("Using seed: {0}", seed);
            Random rndGen = new Random(seed);
            var item = new VersionedType(rndGen);
            await table.InsertAsync(item);
            Log("[client 1] Inserted item: {0}", item);

            var client2 = new MobileServiceClient(client.MobileAppUri);
            var table2 = client.GetTable<VersionedType>();
            var item2 = await table2.LookupAsync(item.Id);
            Log("[client 2] Retrieved the item");
            item2.Name = Utilities.CreateSimpleRandomString(rndGen, 20);
            item2.Number = rndGen.Next(100000);
            Log("[client 2] Updated the item, will update on the server now");
            await table2.UpdateAsync(item2);
            Log("[client 2] Item has been updated: {0}", item2);

            Log("[client 1] Will try to update - using policy that data on {0} wins", clientWins ? "client" : "server");
            string oldName = item2.Name;
            string newName = Utilities.CreateSimpleRandomString(rndGen, 20);
            item.Name = newName;
            await table.UpdateAsync(item, new Dictionary<string, string> { { "conflictPolicy", clientWins ? "clientWins" : "serverWins" } });
            Log("[client 1] Updated the item: {0}", item);

            Log("[client 2] Now refreshing the second item");
            await table2.RefreshAsync(item2);
            Log("[client 2] Refreshed: {0}", item2);
            if (clientWins)
            {
                // The name should be the new one
                if (item.Name != newName || item2.Name != newName)
                {
                    Assert.Fail("Error, name wasn't updated in a 'client wins' policy");
                }
            }
            else
            {
                // The name should have remained the old one
                if (item.Name != oldName || item2.Name != oldName)
                {
                    Assert.Fail("Error, name was updated in a 'server wins' policy");
                }
            }

            Log("Table operations behaved as expected. Cleaning up...");
            await table.DeleteAsync(item);
            Log("...done");
        }
        private async Task CreateOptimisticConcurrencyTest(string testName, Func<VersionedType, VersionedType, VersionedType> mergingPolicy)
        {
            Log("### " + testName);
            var client = this.GetClient();
            var table = client.GetTable<VersionedType>();
            DateTime now = DateTime.UtcNow;
            int seed = now.Year * 10000 + now.Month * 100 + now.Day;
            Log("Using seed: {0}", seed);
            Random rndGen = new Random(seed);
            var item = new VersionedType(rndGen);
            await table.InsertAsync(item);
            Log("[client 1] Inserted item: {0}", item);

            var client2 = new MobileServiceClient(client.MobileAppUri);
            var table2 = client.GetTable<VersionedType>();
            var item2 = await table2.LookupAsync(item.Id);
            Log("[client 2] Retrieved the item");
            item2.Name = Utilities.CreateSimpleRandomString(rndGen, 20);
            item2.Number = rndGen.Next(100000);
            Log("[client 2] Updated the item, will update on the server now");
            await table2.UpdateAsync(item2);
            Log("[client 2] Item has been updated: {0}", item2);

            Log("[client 1] Will try to update; should fail");
            MobileServicePreconditionFailedException<VersionedType> ex = null;
            try
            {
                item.Name = Utilities.CreateSimpleRandomString(rndGen, 20);
                await table.UpdateAsync(item);
                Assert.Fail(string.Format("[client 1] Error, the update succeeded, but it should have failed. Item = {0}", item));
            }
            catch (MobileServicePreconditionFailedException<VersionedType> e)
            {
                Log("[client 1] Received expected exception; server item = {0}", e.Item);
                ex = e;
            }

            var serverItem = ex.Item;
            if (serverItem.Version != item2.Version)
            {
                Assert.Fail("[client 1] Error, server item's version is not the same as the second item version");
            }

            var cachedMergedItem = mergingPolicy(item, serverItem);
            var mergedItem = mergingPolicy(item, serverItem);
            Log("[client 1] Merged item: {0}", mergedItem);
            Log("[client 1] Trying to update it again, should succeed this time");

            await table.UpdateAsync(mergedItem);
            Log("[client 1] Updated the item: {0}", mergedItem);

            if (!cachedMergedItem.Equals(mergedItem))
            {
                Assert.Fail("[client 1] Error, the server version of the merged item doesn't match the client one");
            }

            Log("[client 2] Refreshing the item");
            await table2.RefreshAsync(item2);
            Log("[client 2] Refreshed the item: {0}", item2);

            if (!item2.Equals(mergedItem))
            {
                Assert.Fail("[client] Error, item is different than the item from the client 1");
            }
        }
        private async Task CreateSystemPropertiesTest(bool useTypedTable)
        {
            Log("### System properties in " + (useTypedTable ? "" : "un") + "typed tables");

            var client = this.GetClient();
            var typedTable = client.GetTable<VersionedType>();
            var untypedTable = client.GetTable("RoundTripTable");
 
            DateTime now = DateTime.UtcNow;
            int seed = now.Year * 10000 + now.Month * 100 + now.Day;
            Log("Using seed: {0}", seed);
            Random rndGen = new Random(seed);
            VersionedType item = null;
            JObject untypedItem = null;
            DateTime createdAt, updatedAt;
            string id;
            if (useTypedTable)
            {
                item = new VersionedType(rndGen);
                await typedTable.InsertAsync(item);
                Log("Inserted: {0}", item);
                id = item.Id;
                createdAt = item.CreatedAt;
                updatedAt = item.UpdatedAt;
            }
            else
            {
                untypedItem = new JObject();
                untypedItem.Add("name", "unused");
                untypedItem = (JObject)(await untypedTable.InsertAsync(untypedItem));
                Log("Inserted: {0}", untypedItem);
                id = (string)untypedItem["id"];
                createdAt = untypedItem["createdAt"].ToObject<DateTime>();
                updatedAt = untypedItem["updatedAt"].ToObject<DateTime>();
            }

            Log("Now adding a new item");
            DateTime otherCreatedAt, otherUpdatedAt;
            string otherId;
            if (useTypedTable)
            {
                item = new VersionedType(rndGen);
                await typedTable.InsertAsync(item);
                Log("Inserted: {0}", item);
                otherId = item.Id;
                otherCreatedAt = item.CreatedAt;
                otherUpdatedAt = item.UpdatedAt;
            }
            else
            {
                untypedItem = new JObject();
                untypedItem.Add("name", "unused");
                untypedItem = (JObject)(await untypedTable.InsertAsync(untypedItem));
                Log("Inserted: {0}", untypedItem);
                otherId = (string)untypedItem["id"];
                otherCreatedAt = untypedItem["createdAt"].ToObject<DateTime>();
                otherUpdatedAt = untypedItem["updatedAt"].ToObject<DateTime>();
            }

            if (createdAt >= otherCreatedAt)
            {
                Assert.Fail("Error, first createdAt value is not smaller than second one");
            }

            if (updatedAt >= otherUpdatedAt)
            {
                Assert.Fail("Error, first updatedAt value is not smaller than second one");
            }

            createdAt = otherCreatedAt;
            updatedAt = otherUpdatedAt;

            Log("Now updating the item");
            if (useTypedTable)
            {
                item = new VersionedType(rndGen) { Id = otherId };
                await typedTable.UpdateAsync(item);
                Log("Updated: {0}", item);
                otherUpdatedAt = item.UpdatedAt;
                otherCreatedAt = item.CreatedAt;
            }
            else
            {
                untypedItem = new JObject(new JProperty("id", otherId), new JProperty("name", "other name"));
                untypedItem = (JObject)(await untypedTable.UpdateAsync(untypedItem));
                Log("Updated: {0}", untypedItem);
                otherCreatedAt = untypedItem["createdAt"].ToObject<DateTime>();
                otherUpdatedAt = untypedItem["updatedAt"].ToObject<DateTime>();
            }

            if (createdAt != otherCreatedAt)
            {
                Assert.Fail("Error, update changed the value of the createdAt property");
            }

            if (otherUpdatedAt <= updatedAt)
            {
                Assert.Fail("Error, update did not change the updatedAt property to a later value");
            }

            Log("Cleanup: deleting items");
            await untypedTable.DeleteAsync(new JObject(new JProperty("id", id)));
            await untypedTable.DeleteAsync(new JObject(new JProperty("id", otherId)));
        }
Exemplo n.º 8
0
        private static ZumoTest CreateSystemPropertiesTest(bool useTypedTable)
        {
            return(new ZumoTest("System properties in " + (useTypedTable ? "" : "un") + "typed tables", async delegate(ZumoTest test)
            {
                var client = ZumoTestGlobals.Instance.Client;
                var typedTable = client.GetTable <VersionedType>();
                var untypedTable = client.GetTable(ZumoTestGlobals.StringIdRoundTripTableName);
                untypedTable.SystemProperties =
                    MobileServiceSystemProperties.CreatedAt |
                    MobileServiceSystemProperties.UpdatedAt |
                    MobileServiceSystemProperties.Version;
                DateTime now = DateTime.UtcNow;
                int seed = now.Year * 10000 + now.Month * 100 + now.Day;
                test.AddLog("Using seed: {0}", seed);
                Random rndGen = new Random(seed);
                VersionedType item = null;
                JObject untypedItem = null;
                DateTime createdAt, updatedAt;
                string id;
                if (useTypedTable)
                {
                    item = new VersionedType(rndGen);
                    await typedTable.InsertAsync(item);
                    test.AddLog("Inserted: {0}", item);
                    id = item.Id;
                    createdAt = item.CreatedAt;
                    updatedAt = item.UpdatedAt;
                }
                else
                {
                    untypedItem = new JObject();
                    untypedItem.Add("name", "unused");
                    untypedItem = (JObject)(await untypedTable.InsertAsync(untypedItem));
                    test.AddLog("Inserted: {0}", untypedItem);
                    id = (string)untypedItem["id"];
                    createdAt = untypedItem["__createdAt"].ToObject <DateTime>();
                    updatedAt = untypedItem["__updatedAt"].ToObject <DateTime>();
                }

                test.AddLog("Now adding a new item");
                DateTime otherCreatedAt, otherUpdatedAt;
                string otherId;
                if (useTypedTable)
                {
                    item = new VersionedType(rndGen);
                    await typedTable.InsertAsync(item);
                    test.AddLog("Inserted: {0}", item);
                    otherId = item.Id;
                    otherCreatedAt = item.CreatedAt;
                    otherUpdatedAt = item.UpdatedAt;
                }
                else
                {
                    untypedItem = new JObject();
                    untypedItem.Add("name", "unused");
                    untypedItem = (JObject)(await untypedTable.InsertAsync(untypedItem));
                    test.AddLog("Inserted: {0}", untypedItem);
                    otherId = (string)untypedItem["id"];
                    otherCreatedAt = untypedItem["__createdAt"].ToObject <DateTime>();
                    otherUpdatedAt = untypedItem["__updatedAt"].ToObject <DateTime>();
                }

                if (createdAt >= otherCreatedAt)
                {
                    test.AddLog("Error, first __createdAt value is not smaller than second one");
                    return false;
                }

                if (updatedAt >= otherUpdatedAt)
                {
                    test.AddLog("Error, first __updatedAt value is not smaller than second one");
                    return false;
                }

                createdAt = otherCreatedAt;
                updatedAt = otherUpdatedAt;

                test.AddLog("Now updating the item");
                if (useTypedTable)
                {
                    item = new VersionedType(rndGen)
                    {
                        Id = otherId
                    };
                    await typedTable.UpdateAsync(item);
                    test.AddLog("Updated: {0}", item);
                    otherUpdatedAt = item.UpdatedAt;
                    otherCreatedAt = item.CreatedAt;
                }
                else
                {
                    untypedItem = new JObject(new JProperty("id", otherId), new JProperty("name", "other name"));
                    untypedItem = (JObject)(await untypedTable.UpdateAsync(untypedItem));
                    test.AddLog("Updated: {0}", untypedItem);
                    otherCreatedAt = untypedItem["__createdAt"].ToObject <DateTime>();
                    otherUpdatedAt = untypedItem["__updatedAt"].ToObject <DateTime>();
                }

                if (createdAt != otherCreatedAt)
                {
                    test.AddLog("Error, update changed the value of the __createdAt property");
                    return false;
                }

                if (otherUpdatedAt <= updatedAt)
                {
                    test.AddLog("Error, update did not change the __updatedAt property to a later value");
                    return false;
                }

                test.AddLog("Cleanup: deleting items");
                await untypedTable.DeleteAsync(new JObject(new JProperty("id", id)));
                await untypedTable.DeleteAsync(new JObject(new JProperty("id", otherId)));
                return true;
            }));
        }
Exemplo n.º 9
0
        private static ZumoTest CreateOptimisticConcurrencyWithServerConflictsTest(string testName, bool clientWins)
        {
            return(new ZumoTest(testName, async delegate(ZumoTest test)
            {
                var client = ZumoTestGlobals.Instance.Client;
                var table = client.GetTable <VersionedType>();
                DateTime now = DateTime.UtcNow;
                int seed = now.Year * 10000 + now.Month * 100 + now.Day;
                test.AddLog("Using seed: {0}", seed);
                Random rndGen = new Random(seed);
                var item = new VersionedType(rndGen);
                await table.InsertAsync(item);
                test.AddLog("[client 1] Inserted item: {0}", item);

                var client2 = new MobileServiceClient(client.ApplicationUri, client.ApplicationKey);
                var table2 = client.GetTable <VersionedType>();
                var item2 = await table2.LookupAsync(item.Id);
                test.AddLog("[client 2] Retrieved the item");
                item2.Name = Util.CreateSimpleRandomString(rndGen, 20);
                item2.Number = rndGen.Next(100000);
                test.AddLog("[client 2] Updated the item, will update on the server now");
                await table2.UpdateAsync(item2);
                test.AddLog("[client 2] Item has been updated: {0}", item2);

                test.AddLog("[client 1] Will try to update - using policy that data on {0} wins", clientWins ? "client" : "server");
                string oldName = item2.Name;
                string newName = Util.CreateSimpleRandomString(rndGen, 20);
                item.Name = newName;
                await table.UpdateAsync(item, new Dictionary <string, string> {
                    { "conflictPolicy", clientWins ? "clientWins" : "serverWins" }
                });
                test.AddLog("[client 1] Updated the item: {0}", item);

                test.AddLog("[client 2] Now refreshing the second item");
                await table2.RefreshAsync(item2);
                test.AddLog("[client 2] Refreshed: {0}", item2);
                if (clientWins)
                {
                    // The name should be the new one
                    if (item.Name != newName || item2.Name != newName)
                    {
                        test.AddLog("Error, name wasn't updated in a 'client wins' policy");
                        return false;
                    }
                }
                else
                {
                    // The name should have remained the old one
                    if (item.Name != oldName || item2.Name != oldName)
                    {
                        test.AddLog("Error, name was updated in a 'server wins' policy");
                        return false;
                    }
                }

                test.AddLog("Table operations behaved as expected. Cleaning up...");
                await table.DeleteAsync(item);
                test.AddLog("...done");
                return true;
            }));
        }
Exemplo n.º 10
0
        private static ZumoTest CreateOptimisticConcurrencyTest(string testName, Func <VersionedType, VersionedType, VersionedType> mergingPolicy)
        {
            return(new ZumoTest(testName, async delegate(ZumoTest test)
            {
                var client = ZumoTestGlobals.Instance.Client;
                var table = client.GetTable <VersionedType>();
                DateTime now = DateTime.UtcNow;
                int seed = now.Year * 10000 + now.Month * 100 + now.Day;
                test.AddLog("Using seed: {0}", seed);
                Random rndGen = new Random(seed);
                var item = new VersionedType(rndGen);
                await table.InsertAsync(item);
                test.AddLog("[client 1] Inserted item: {0}", item);

                var client2 = new MobileServiceClient(client.ApplicationUri, client.ApplicationKey);
                var table2 = client.GetTable <VersionedType>();
                var item2 = await table2.LookupAsync(item.Id);
                test.AddLog("[client 2] Retrieved the item");
                item2.Name = Util.CreateSimpleRandomString(rndGen, 20);
                item2.Number = rndGen.Next(100000);
                test.AddLog("[client 2] Updated the item, will update on the server now");
                await table2.UpdateAsync(item2);
                test.AddLog("[client 2] Item has been updated: {0}", item2);

                test.AddLog("[client 1] Will try to update; should fail");
                MobileServicePreconditionFailedException <VersionedType> ex = null;
                try
                {
                    item.Name = Util.CreateSimpleRandomString(rndGen, 20);
                    await table.UpdateAsync(item);
                    test.AddLog("[client 1] Error, the update succeeded, but it should have failed. Item = {0}", item);
                    return false;
                }
                catch (MobileServicePreconditionFailedException <VersionedType> e)
                {
                    test.AddLog("[client 1] Received expected exception; server item = {0}", e.Item);
                    ex = e;
                }

                var serverItem = ex.Item;
                if (serverItem.Version != item2.Version)
                {
                    test.AddLog("[client 1] Error, server item's version is not the same as the second item version");
                    return false;
                }

                var cachedMergedItem = mergingPolicy(item, serverItem);
                var mergedItem = mergingPolicy(item, serverItem);
                test.AddLog("[client 1] Merged item: {0}", mergedItem);
                test.AddLog("[client 1] Trying to update it again, should succeed this time");

                await table.UpdateAsync(mergedItem);
                test.AddLog("[client 1] Updated the item: {0}", mergedItem);

                if (!cachedMergedItem.Equals(mergedItem))
                {
                    test.AddLog("[client 1] Error, the server version of the merged item doesn't match the client one");
                    return false;
                }

                test.AddLog("[client 2] Refreshing the item");
                await table2.RefreshAsync(item2);
                test.AddLog("[client 2] Refreshed the item: {0}", item2);

                if (!item2.Equals(mergedItem))
                {
                    test.AddLog("[client] Error, item is different than the item from the client 1");
                    return false;
                }

                return true;
            }));
        }
Exemplo n.º 11
0
        public void GetTypeInfo_FindsById()
        {
            VersionedType result = sut.GetTypeInfo <ITestType>(new VersionedTypeId("TestTypeB", 2));

            result.Should().Be(allTypes.Single(x => x.ClrType == typeof(TestTypeBV2)));
        }
Exemplo n.º 12
0
        public void GetTypeInfo_FindsByClrType()
        {
            VersionedType result = sut.GetTypeInfo <ITestType>(typeof(TestTypeA));

            result.Should().Be(allTypes.Single(x => x.ClrType == typeof(TestTypeA)));
        }
Exemplo n.º 13
0
        private async Task CreateSystemPropertiesTest(bool useTypedTable)
        {
            var client       = this.GetClient();
            var typedTable   = client.GetTable <VersionedType>();
            var untypedTable = client.GetTable("RoundTripTable");

            DateTime      now = DateTime.UtcNow;
            int           seed = now.Year * 10000 + now.Month * 100 + now.Day;
            Random        rndGen = new Random(seed);
            VersionedType item = null;
            JObject       untypedItem = null;
            DateTime      createdAt, updatedAt;
            string        id;

            if (useTypedTable)
            {
                item = new VersionedType(rndGen);
                await typedTable.InsertAsync(item);

                id        = item.Id;
                createdAt = item.CreatedAt;
                updatedAt = item.UpdatedAt;
            }
            else
            {
                untypedItem = new JObject();
                untypedItem.Add("name", "unused");
                untypedItem = (JObject)(await untypedTable.InsertAsync(untypedItem));
                id          = (string)untypedItem["id"];
                createdAt   = untypedItem["createdAt"].ToObject <DateTime>();
                updatedAt   = untypedItem["updatedAt"].ToObject <DateTime>();
            }

            DateTime otherCreatedAt, otherUpdatedAt;
            string   otherId;

            if (useTypedTable)
            {
                item = new VersionedType(rndGen);
                await typedTable.InsertAsync(item);

                otherId        = item.Id;
                otherCreatedAt = item.CreatedAt;
                otherUpdatedAt = item.UpdatedAt;
            }
            else
            {
                untypedItem = new JObject();
                untypedItem.Add("name", "unused");
                untypedItem    = (JObject)(await untypedTable.InsertAsync(untypedItem));
                otherId        = (string)untypedItem["id"];
                otherCreatedAt = untypedItem["createdAt"].ToObject <DateTime>();
                otherUpdatedAt = untypedItem["updatedAt"].ToObject <DateTime>();
            }

            Assert.True(createdAt < otherCreatedAt);
            Assert.True(updatedAt < otherUpdatedAt);

            createdAt = otherCreatedAt;
            updatedAt = otherUpdatedAt;

            if (useTypedTable)
            {
                item = new VersionedType(rndGen)
                {
                    Id = otherId
                };
                await typedTable.UpdateAsync(item);

                otherUpdatedAt = item.UpdatedAt;
                otherCreatedAt = item.CreatedAt;
            }
            else
            {
                untypedItem    = new JObject(new JProperty("id", otherId), new JProperty("name", "other name"));
                untypedItem    = (JObject)(await untypedTable.UpdateAsync(untypedItem));
                otherCreatedAt = untypedItem["createdAt"].ToObject <DateTime>();
                otherUpdatedAt = untypedItem["updatedAt"].ToObject <DateTime>();
            }

            Assert.Equal(createdAt, otherCreatedAt);
            Assert.False(otherUpdatedAt <= updatedAt);

            await untypedTable.DeleteAsync(new JObject(new JProperty("id", id)));

            await untypedTable.DeleteAsync(new JObject(new JProperty("id", otherId)));
        }
        private async Task CreateSystemPropertiesTest(bool useTypedTable)
        {
            Log("### System properties in " + (useTypedTable ? "" : "un") + "typed tables");

            var client       = this.GetClient();
            var typedTable   = client.GetTable <VersionedType>();
            var untypedTable = client.GetTable("RoundTripTable");

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

            Log("Using seed: {0}", seed);
            Random        rndGen = new Random(seed);
            VersionedType item = null;
            JObject       untypedItem = null;
            DateTime      createdAt, updatedAt;
            string        id;

            if (useTypedTable)
            {
                item = new VersionedType(rndGen);
                await typedTable.InsertAsync(item);

                Log("Inserted: {0}", item);
                id        = item.Id;
                createdAt = item.CreatedAt;
                updatedAt = item.UpdatedAt;
            }
            else
            {
                untypedItem = new JObject();
                untypedItem.Add("name", "unused");
                untypedItem = (JObject)(await untypedTable.InsertAsync(untypedItem));
                Log("Inserted: {0}", untypedItem);
                id        = (string)untypedItem["id"];
                createdAt = untypedItem["createdAt"].ToObject <DateTime>();
                updatedAt = untypedItem["updatedAt"].ToObject <DateTime>();
            }

            Log("Now adding a new item");
            DateTime otherCreatedAt, otherUpdatedAt;
            string   otherId;

            if (useTypedTable)
            {
                item = new VersionedType(rndGen);
                await typedTable.InsertAsync(item);

                Log("Inserted: {0}", item);
                otherId        = item.Id;
                otherCreatedAt = item.CreatedAt;
                otherUpdatedAt = item.UpdatedAt;
            }
            else
            {
                untypedItem = new JObject();
                untypedItem.Add("name", "unused");
                untypedItem = (JObject)(await untypedTable.InsertAsync(untypedItem));
                Log("Inserted: {0}", untypedItem);
                otherId        = (string)untypedItem["id"];
                otherCreatedAt = untypedItem["createdAt"].ToObject <DateTime>();
                otherUpdatedAt = untypedItem["updatedAt"].ToObject <DateTime>();
            }

            if (createdAt >= otherCreatedAt)
            {
                Assert.Fail("Error, first createdAt value is not smaller than second one");
            }

            if (updatedAt >= otherUpdatedAt)
            {
                Assert.Fail("Error, first updatedAt value is not smaller than second one");
            }

            createdAt = otherCreatedAt;
            updatedAt = otherUpdatedAt;

            Log("Now updating the item");
            if (useTypedTable)
            {
                item = new VersionedType(rndGen)
                {
                    Id = otherId
                };
                await typedTable.UpdateAsync(item);

                Log("Updated: {0}", item);
                otherUpdatedAt = item.UpdatedAt;
                otherCreatedAt = item.CreatedAt;
            }
            else
            {
                untypedItem = new JObject(new JProperty("id", otherId), new JProperty("name", "other name"));
                untypedItem = (JObject)(await untypedTable.UpdateAsync(untypedItem));
                Log("Updated: {0}", untypedItem);
                otherCreatedAt = untypedItem["createdAt"].ToObject <DateTime>();
                otherUpdatedAt = untypedItem["updatedAt"].ToObject <DateTime>();
            }

            if (createdAt != otherCreatedAt)
            {
                Assert.Fail("Error, update changed the value of the createdAt property");
            }

            if (otherUpdatedAt <= updatedAt)
            {
                Assert.Fail("Error, update did not change the updatedAt property to a later value");
            }

            Log("Cleanup: deleting items");
            await untypedTable.DeleteAsync(new JObject(new JProperty("id", id)));

            await untypedTable.DeleteAsync(new JObject(new JProperty("id", otherId)));
        }