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); }