示例#1
0
        public static void AssertEquality(ComplexEntity a, ComplexEntity b)
        {
            Assert.AreEqual(a.String, b.String);
            Assert.AreEqual(a.Int64, b.Int64);
            Assert.AreEqual(a.LongPrimitive, b.LongPrimitive);
            Assert.AreEqual(a.Int32, b.Int32);
            Assert.AreEqual(a.IntegerPrimitive, b.IntegerPrimitive);
            Assert.AreEqual(a.Guid, b.Guid);
            Assert.AreEqual(a.Double, b.Double);
            Assert.AreEqual(a.DoublePrimitive, b.DoublePrimitive);
            Assert.AreEqual(a.BinaryPrimitive, b.BinaryPrimitive);
            Assert.AreEqual(a.Binary, b.Binary);
            Assert.AreEqual(a.BoolPrimitive, b.BoolPrimitive);
            Assert.AreEqual(a.Bool, b.Bool);
            Assert.AreEqual(a.DateTime, b.DateTime);

            Assert.AreEqual(a.PartitionKey, b.PartitionKey);
            Assert.AreEqual(a.RowKey, b.RowKey);
        }
        public static void AssertEquality(ComplexEntity a, ComplexEntity b)
        {
            Assert.AreEqual(a.String, b.String);
            Assert.AreEqual(a.Int64, b.Int64);
            Assert.AreEqual(a.LongPrimitive, b.LongPrimitive);
            Assert.AreEqual(a.Int32, b.Int32);
            Assert.AreEqual(a.IntegerPrimitive, b.IntegerPrimitive);
            Assert.AreEqual(a.Guid, b.Guid);
            Assert.AreEqual(a.Double, b.Double);
            Assert.AreEqual(a.DoublePrimitive, b.DoublePrimitive);
            Assert.AreEqual(a.BinaryPrimitive, b.BinaryPrimitive);
            Assert.AreEqual(a.Binary, b.Binary);
            Assert.AreEqual(a.BoolPrimitive, b.BoolPrimitive);
            Assert.AreEqual(a.Bool, b.Bool);
            Assert.AreEqual(a.DateTime, b.DateTime);

            Assert.AreEqual(a.PartitionKey, b.PartitionKey);
            Assert.AreEqual(a.RowKey, b.RowKey);
        }
        public void TableTestSaveChangesCancellationNonBatch()
        {
            CloudTableClient tableClient = GenerateCloudTableClient();
            TableServiceContext ctx = tableClient.GetTableServiceContext();

            for (int m = 0; m < 100; m++)
            {
                // Insert Entity
                ComplexEntity insertEntity = new ComplexEntity("insert test", m.ToString());
                ctx.AddObject(currentTable.Name, insertEntity);
            }

            TestHelper.ExecuteAPMMethodWithCancellation(4000,
                new[] { DelayBehaviors.DelayAllRequestsIf(4000 * 3, XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName)) },
                (options, opContext, callback, state) => ctx.BeginSaveChangesWithRetries(SaveChangesOptions.None, (TableRequestOptions)options, opContext, callback, state),
                (res) => ctx.EndSaveChangesWithRetries(res));
        }
        public void TableTestSegmentedQueryCancellation()
        {
            CloudTableClient tableClient = GenerateCloudTableClient();
            TableServiceContext ctx = tableClient.GetTableServiceContext();

            for (int m = 0; m < 100; m++)
            {
                // Insert Entity
                ComplexEntity insertEntity = new ComplexEntity("insert test", m.ToString());
                ctx.AddObject(currentTable.Name, insertEntity);
            }
            ctx.SaveChangesWithRetries();

            TableServiceQuery<BaseEntity> query = (from ent in ctx.CreateQuery<BaseEntity>(currentTable.Name)
                                                   select ent).AsTableServiceQuery(ctx);


            TestHelper.ExecuteAPMMethodWithCancellation(4000,
                new[] { DelayBehaviors.DelayAllRequestsIf(4000 * 3, XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName)) },
                (options, opContext, callback, state) => query.BeginExecuteSegmented(null, (TableRequestOptions)options, opContext, callback, state),
                (res) => query.EndExecuteSegmented(res));
        }
        public void BatchInsertAPM()
        {
            CloudTableClient tableClient = GenerateCloudTableClient();
            TableServiceContext ctx = tableClient.GetTableServiceContext();

            // Insert Entities
            SortedDictionary<string, ComplexEntity> entities = new SortedDictionary<string, ComplexEntity>();
            for (int i = 0; i < 100; i++)
            {
                ComplexEntity insertEntity = new ComplexEntity("insert test", "foo" + i);
                entities.Add(insertEntity.RowKey, insertEntity);
                ctx.AddObject(currentTable.Name, insertEntity);
            }

            DataServiceResponse response;
            using (ManualResetEvent evt = new ManualResetEvent(false))
            {
                IAsyncResult asyncRes = null;
                ctx.BeginSaveChangesWithRetries(SaveChangesOptions.Batch, (res) =>
                {
                    asyncRes = res;
                    evt.Set();
                }, null);
                evt.WaitOne();

                response = ctx.EndSaveChangesWithRetries(asyncRes);
            }

            Assert.AreEqual((int)HttpStatusCode.Accepted, response.BatchStatusCode);

            // Retrieve Entities
            List<ComplexEntity> retrievedEntities = (from ent in ctx.CreateQuery<ComplexEntity>(currentTable.Name)
                                                     where ent.PartitionKey == entities.First().Value.PartitionKey
                                                     select ent).AsTableServiceQuery(ctx).Execute().ToList();

            Assert.AreEqual(entities.Count, retrievedEntities.Count);

            foreach (ComplexEntity retrievedEntity in retrievedEntities)
            {
                ComplexEntity.AssertEquality(entities[retrievedEntity.RowKey], retrievedEntity);
                entities.Remove(retrievedEntity.RowKey);
            }

            Assert.AreEqual(0, entities.Count);
        }
        private void DoBatchInsert(TablePayloadFormat format)
        {
            CloudTableClient tableClient = GenerateCloudTableClient();
            TableServiceContext ctx = tableClient.GetTableServiceContext();
            SetPayloadFormatOnDataServiceContext(ctx, format, tableClient);

            // Insert Entities
            SortedDictionary<string, ComplexEntity> entities = new SortedDictionary<string, ComplexEntity>();
            for (int i = 0; i < 100; i++)
            {
                ComplexEntity insertEntity = new ComplexEntity("insert test" + format.ToString(), "foo" + format.ToString() + i);
                entities.Add(insertEntity.RowKey, insertEntity);
                ctx.AddObject(currentTable.Name, insertEntity);
            }

            DataServiceResponse response = ctx.SaveChangesWithRetries(SaveChangesOptions.Batch);
            Assert.AreEqual((int)HttpStatusCode.Accepted, response.BatchStatusCode);

            // Retrieve Entities
            List<ComplexEntity> retrievedEntities = (from ent in ctx.CreateQuery<ComplexEntity>(currentTable.Name)
                                                     where ent.PartitionKey == entities.First().Value.PartitionKey
                                                     select ent).AsTableServiceQuery(ctx).Execute().ToList();

            Assert.AreEqual(entities.Count, retrievedEntities.Count);

            foreach (ComplexEntity retrievedEntity in retrievedEntities)
            {
                ComplexEntity.AssertEquality(entities[retrievedEntity.RowKey], retrievedEntity);
                entities.Remove(retrievedEntity.RowKey);
            }

            Assert.AreEqual(0, entities.Count);
        }
        private void DoSingleEntityInsertDeleteFail(TablePayloadFormat format)
        {
            CloudTableClient tableClient = GenerateCloudTableClient();
            TableServiceContext ctx = tableClient.GetTableServiceContext();
            SetPayloadFormatOnDataServiceContext(ctx, format, tableClient);

            // Delete Entity that does not exits
            ComplexEntity deleteEntity = new ComplexEntity("insert test", "foo" + format.ToString());
            ctx.AttachTo(currentTable.Name, deleteEntity, "*");
            ctx.DeleteObject(deleteEntity);
            OperationContext opContext = new OperationContext();

            try
            {
                ctx.SaveChangesWithRetries(SaveChangesOptions.None, null, opContext);
                Assert.Fail();
            }
            catch (StorageException)
            {
                TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.NotFound, new string[] { "ResourceNotFound" }, "The specified resource does not exist.");
            }


            ctx = tableClient.GetTableServiceContext();
            TableServiceContext ctx2 = tableClient.GetTableServiceContext();
            SetPayloadFormatOnDataServiceContext(ctx2, format, tableClient);

            // Insert Entity
            ComplexEntity insertEntity = new ComplexEntity("insert test", "foo" + format.ToString());
            ctx.AddObject(currentTable.Name, insertEntity);
            ctx.SaveChangesWithRetries();

            // Update Entity
            ComplexEntity retrievedEntity = (from ent in ctx2.CreateQuery<ComplexEntity>(currentTable.Name)
                                             where ent.PartitionKey == insertEntity.PartitionKey
                                             && ent.RowKey == insertEntity.RowKey
                                             select ent).AsTableServiceQuery(ctx2).Execute().FirstOrDefault();

            retrievedEntity.String = "updated value";

            ctx2.UpdateObject(retrievedEntity);
            ctx2.SaveChangesWithRetries();

            // Now delete old reference with stale etag and validate exception
            ctx.DeleteObject(insertEntity);

            opContext = new OperationContext();
            try
            {
                ctx.SaveChangesWithRetries(SaveChangesOptions.None, null, opContext);
                Assert.Fail();
            }
            catch (StorageException)
            {
                TestHelper.ValidateResponse(opContext,
                    1,
                    (int)HttpStatusCode.PreconditionFailed,
                    new string[] { "UpdateConditionNotSatisfied", "ConditionNotMet" },
                    new string[] { "The update condition specified in the request was not satisfied.", "The condition specified using HTTP conditional header(s) is not met." });
            }
        }
        private void DoSingleEntityDelete(TablePayloadFormat format)
        {
            CloudTableClient tableClient = GenerateCloudTableClient();
            TableServiceContext ctx = tableClient.GetTableServiceContext();
            SetPayloadFormatOnDataServiceContext(ctx, format, tableClient);

            // Insert Entity
            ComplexEntity insertEntity = new ComplexEntity("insert test", "foo");
            ctx.AddObject(currentTable.Name, insertEntity);
            ctx.SaveChangesWithRetries();

            // Retrieve Entity

            ComplexEntity retrievedEntity = (from ent in ctx.CreateQuery<ComplexEntity>(currentTable.Name)
                                             where ent.PartitionKey == insertEntity.PartitionKey
                                             && ent.RowKey == insertEntity.RowKey
                                             select ent).AsTableServiceQuery(ctx).Execute().FirstOrDefault();
            Assert.IsNotNull(retrievedEntity);
            ctx.DeleteObject(retrievedEntity);
            ctx.SaveChangesWithRetries();

            try
            {
                // Retrieve Entity
                retrievedEntity = (from ent in ctx.CreateQuery<ComplexEntity>(currentTable.Name)
                                   where ent.PartitionKey == insertEntity.PartitionKey
                                   && ent.RowKey == insertEntity.RowKey
                                   select ent).AsTableServiceQuery(ctx).Execute().FirstOrDefault();
                Assert.Fail();
            }
            catch (StorageException ex)
            {
                Assert.AreEqual(ex.RequestInformation.HttpStatusCode, (int)HttpStatusCode.NotFound);
            }
        }
        private void DoSingleEntityInsertConflict(TablePayloadFormat format)
        {
            CloudTableClient tableClient = GenerateCloudTableClient();
            TableServiceContext ctx = tableClient.GetTableServiceContext();
            SetPayloadFormatOnDataServiceContext(ctx, format, tableClient);

            // Insert Entity
            ComplexEntity insertEntity = new ComplexEntity("insert test", "foo" + format.ToString());
            ctx.AddObject(currentTable.Name, insertEntity);
            ctx.SaveChangesWithRetries();


            // Attempt Insert Conflict Entity
            TableServiceContext ctx2 = tableClient.GetTableServiceContext();
            ComplexEntity conflictEntity = new ComplexEntity("insert test", "foo" + format.ToString());
            ctx2.AddObject(currentTable.Name, insertEntity);
            OperationContext opContext = new OperationContext();

            try
            {
                ctx2.SaveChangesWithRetries(SaveChangesOptions.None, null, opContext);
                Assert.Fail();
            }
            catch (StorageException)
            {
                TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.Conflict, new string[] { "EntityAlreadyExists" }, "The specified entity already exists");
            }
        }
        public void SingleEntityInsertTask()
        {
            CloudTableClient tableClient = GenerateCloudTableClient();
            TableServiceContext ctx = tableClient.GetTableServiceContext();

            // Insert Entity
            ComplexEntity insertEntity = new ComplexEntity("insert test", "foo");
            ctx.AddObject(currentTable.Name, insertEntity);
            ctx.SaveChangesWithRetriesAsync().Wait();

            // Retrieve Entity
            ComplexEntity retrievedEntity = (from ent in ctx.CreateQuery<ComplexEntity>(currentTable.Name)
                                             where ent.PartitionKey == insertEntity.PartitionKey
                                             && ent.RowKey == insertEntity.RowKey
                                             select ent).AsTableServiceQuery(ctx).Execute().FirstOrDefault();

            Assert.IsNotNull(retrievedEntity);
            ComplexEntity.AssertEquality(insertEntity, retrievedEntity);
        }
        private void DoSingleEntityInsertEntityOver1MB(TablePayloadFormat format)
        {
            CloudTableClient tableClient = GenerateCloudTableClient();
            TableServiceContext ctx = tableClient.GetTableServiceContext();
            SetPayloadFormatOnDataServiceContext(ctx, format, tableClient);

            // Insert Entity
            ComplexEntity insertEntity = new ComplexEntity("insert test", "foo");
            insertEntity.Binary = new byte[1024 * 1024];
            ctx.AddObject(currentTable.Name, insertEntity);
            OperationContext opContext = new OperationContext();

            try
            {
                ctx.SaveChangesWithRetries(SaveChangesOptions.None, null, opContext);
                Assert.Fail();
            }
            catch (StorageException)
            {
                TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "EntityTooLarge" }, "The entity is larger than the maximum allowed size (1MB).");
            }
        }
        private void DoSingleEntityInsert(TablePayloadFormat format)
        {
            CloudTableClient tableClient = GenerateCloudTableClient();
            TableServiceContext ctx = tableClient.GetTableServiceContext();
            SetPayloadFormatOnDataServiceContext(ctx, format, tableClient);

            // Insert Entity
            ComplexEntity insertEntity = new ComplexEntity("insert test", "foo" + format.ToString());
            ctx.AddObject(currentTable.Name, insertEntity);
            ctx.SaveChangesWithRetries();

            // Retrieve Entity
            ComplexEntity retrievedEntity = (from ent in ctx.CreateQuery<ComplexEntity>(currentTable.Name)
                                             where ent.PartitionKey == insertEntity.PartitionKey
                                             && ent.RowKey == insertEntity.RowKey
                                             select ent).AsTableServiceQuery(ctx).Execute().FirstOrDefault();

            Assert.IsNotNull(retrievedEntity);
            ComplexEntity.AssertEquality(insertEntity, retrievedEntity);
        }
        public void TableServiceContextSaveChangesRetryAPM()
        {
            CloudTableClient tableClient = GenerateCloudTableClient();
            TableServiceContext ctx = tableClient.GetTableServiceContext();

            for (int m = 0; m < 100; m++)
            {
                // Insert Entity
                ComplexEntity insertEntity = new ComplexEntity("insert test", m.ToString());
                insertEntity.Binary = new byte[20 * 1024];
                ctx.AddObject(currentTable.Name, insertEntity);
            }

            TestHelper.ExecuteAPMMethodWithRetry(3,
                 new[] {
                    //Insert upstream network delay to prevent upload to server @ 1000ms / kb
                    PerformanceBehaviors.InsertUpstreamNetworkDelay(10000,
                                                                    XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName),
                                                                    new BehaviorOptions(2)),
                    // After 500 ms return throttle message
                    DelayedActionBehaviors.ExecuteAfter(Actions.ThrottleTableRequest,
                                                            100,
                                                            XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName),
                                                            new BehaviorOptions(2))                    
                 },
            (options, opContext, callback, state) => ctx.BeginSaveChangesWithRetries(SaveChangesOptions.Batch, (TableRequestOptions)options, opContext, callback, state),
            (res) => ctx.EndSaveChangesWithRetries(res));
        }
        public void TableSaveChangesConflictDoesNotRetry()
        {
            CloudTableClient tableClient = GenerateCloudTableClient();
            TableServiceContext ctx = tableClient.GetTableServiceContext();

            ComplexEntity insertEntity = new ComplexEntity("insert test", "conflict");
            ctx.AddObject(currentTable.Name, insertEntity);
            ctx.SaveChangesWithRetries();


            OperationContext opContext = new OperationContext();
            try
            {
                TableServiceContext ctx2 = tableClient.GetTableServiceContext();
                ctx2.AddObject(currentTable.Name, insertEntity);
                ctx2.SaveChangesWithRetries(SaveChangesOptions.None, null, opContext);
                Assert.Fail();
            }
            catch (StorageException)
            {
                TestHelper.AssertNAttempts(opContext, 1);
            }
            catch (Exception)
            {
                Assert.Fail();
            }
        }
        public void TableServiceQueryEntityTypeMismatchNotRetryableSync()
        {
            CloudTableClient tableClient = GenerateCloudTableClient();
            TableServiceContext ctx = tableClient.GetTableServiceContext();

            for (int m = 0; m < 10; m++)
            {
                // Insert Entity
                ComplexEntity insertEntity = new ComplexEntity("insert test", m.ToString());
                ctx.AddObject(currentTable.Name, insertEntity);
            }

            ctx.SaveChangesWithRetries(SaveChangesOptions.Batch);

            OperationContext opContext = new OperationContext();
            try
            {
                //This query will throw since it is of a different type then the tracked entities in the context
                List<BaseEntity> query = (from ent in ctx.CreateQuery<BaseEntity>(currentTable.Name)
                                          select ent).AsTableServiceQuery(ctx).Execute(null, opContext).ToList();
                Assert.Fail();
            }
            catch (StorageException)
            {
                TestHelper.AssertNAttempts(opContext, 1);
            }
            catch (Exception)
            {
                Assert.Fail();
            }
        }
        public void TableServiceQueryWithRetryAPM()
        {
            CloudTableClient tableClient = GenerateCloudTableClient();
            TableServiceContext ctx = tableClient.GetTableServiceContext();

            for (int m = 0; m < 1000; m++)
            {
                // Insert Entity
                ComplexEntity insertEntity = new ComplexEntity("insert test", m.ToString());
                ctx.AddObject(currentTable.Name, insertEntity);

                if ((m + 1) % 100 == 0)
                {
                    ctx.SaveChangesWithRetries(SaveChangesOptions.Batch);
                }
            }

            TableServiceQuery<ComplexEntity> query = (from ent in ctx.CreateQuery<ComplexEntity>(currentTable.Name)
                                                      select ent).AsTableServiceQuery(ctx);

            TestHelper.ExecuteAPMMethodWithRetry(
               2, // 1 failure, one success
                new[] {
                    //Insert upstream network delay to prevent upload to server @ 1000ms / kb
                    PerformanceBehaviors.InsertDownstreamNetworkDelay(10000,
                                                                    XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName).Alternating(true)),
                    // After 100 ms return throttle message
                    DelayedActionBehaviors.ExecuteAfter(Actions.ThrottleTableRequest,
                                                            100,
                                                            XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName).Alternating(true))                    
                 },
               (options, opContext, callback, state) => query.BeginExecuteSegmented(null, (TableRequestOptions)options, opContext, callback, state),
               query.EndExecuteSegmented);
        }