/// <summary> /// Test point queries entities inside and outside the given range. /// </summary> /// <param name="testClient">The table client to test.</param> /// <param name="tableName">The name of the table to test.</param> /// <param name="accessPermissions">The access permissions of the table client.</param> /// <param name="startPk">The start partition key range.</param> /// <param name="startRk">The start row key range.</param> /// <param name="endPk">The end partition key range.</param> /// <param name="endRk">The end row key range.</param> private void TestPointQuery( CloudTableClient testClient, string tableName, SharedAccessTablePermissions accessPermissions, string startPk, string startRk, string endPk, string endRk) { Action<BaseEntity> queryDelegate = (tableEntity) => { TableServiceContext context = testClient.GetTableServiceContext(); TableServiceQuery<BaseEntity> query = (from entity in context.CreateQuery<BaseEntity>(tableName) where entity.PartitionKey == tableEntity.PartitionKey && entity.RowKey == tableEntity.RowKey select entity).AsTableServiceQuery(context); IEnumerable<BaseEntity> list = query.Execute().ToList(); Assert.AreEqual(1, list.Count()); BaseEntity e = list.Single(); }; bool expectSuccess = (accessPermissions & SharedAccessTablePermissions.Query) != 0; // Perform test TestOperationWithRange( tableName, startPk, startRk, endPk, endRk, queryDelegate, "point query", expectSuccess, expectSuccess ? HttpStatusCode.OK : HttpStatusCode.NotFound); }
/// <summary> /// Test update (merge) on entities inside and outside the given range. /// </summary> /// <param name="testClient">The table client to test.</param> /// <param name="tableName">The name of the table to test.</param> /// <param name="accessPermissions">The access permissions of the table client.</param> /// <param name="startPk">The start partition key range.</param> /// <param name="startRk">The start row key range.</param> /// <param name="endPk">The end partition key range.</param> /// <param name="endRk">The end row key range.</param> private void TestUpdateMerge( CloudTableClient testClient, string tableName, SharedAccessTablePermissions accessPermissions, string startPk, string startRk, string endPk, string endRk) { Action<BaseEntity> updateDelegate = (tableEntity) => { TableServiceContext context = testClient.GetTableServiceContext(); // Merge entity tableEntity.A = "10"; context.AttachTo(tableName, tableEntity, "*"); context.UpdateObject(tableEntity); context.SaveChangesWithRetries(); }; bool expectSuccess = (accessPermissions & SharedAccessTablePermissions.Update) != 0; // Perform test TestOperationWithRange( tableName, startPk, startRk, endPk, endRk, updateDelegate, "update merge", expectSuccess, expectSuccess ? HttpStatusCode.NoContent : HttpStatusCode.NotFound); }
/// <summary> /// Test upsert (insert or replace) on entities inside and outside the given range. /// </summary> /// <param name="testClient">The table client to test.</param> /// <param name="tableName">The name of the table to test.</param> /// <param name="accessPermissions">The access permissions of the table client.</param> /// <param name="startPk">The start partition key range.</param> /// <param name="startRk">The start row key range.</param> /// <param name="endPk">The end partition key range.</param> /// <param name="endRk">The end row key range.</param> private void TestUpsertReplace( CloudTableClient testClient, string tableName, SharedAccessTablePermissions accessPermissions, string startPk, string startRk, string endPk, string endRk) { Action<BaseEntity> upsertDelegate = (tableEntity) => { TableServiceContext context = testClient.GetTableServiceContext(); // Replace entity tableEntity.A = "10"; context.AttachTo(tableName, tableEntity); context.UpdateObject(tableEntity); context.SaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate); }; SharedAccessTablePermissions upsertPermissions = (SharedAccessTablePermissions.Update | SharedAccessTablePermissions.Add); bool expectSuccess = (accessPermissions & upsertPermissions) == upsertPermissions; // Perform test TestOperationWithRange( tableName, startPk, startRk, endPk, endRk, upsertDelegate, "upsert replace", expectSuccess, expectSuccess ? HttpStatusCode.NoContent : HttpStatusCode.NotFound); }
public void TableSASConstructors() { CloudTableClient tableClient = GenerateCloudTableClient(); CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); try { table.Create(); TableServiceContext context = tableClient.GetTableServiceContext(); context.AddObject(table.Name, new BaseEntity("PK", "RK")); context.SaveChangesWithRetries(); // Prepare SAS authentication with full permissions string sasToken = table.GetSharedAccessSignature( new SharedAccessTablePolicy { Permissions = SharedAccessTablePermissions.Add | SharedAccessTablePermissions.Delete | SharedAccessTablePermissions.Query, SharedAccessExpiryTime = DateTimeOffset.Now.AddMinutes(30) }, null /* accessPolicyIdentifier */, null /* startPk */, null /* startRk */, null /* endPk */, null /* endRk */); CloudStorageAccount sasAccount; StorageCredentials sasCreds; CloudTableClient sasClient; CloudTable sasTable; TableServiceContext sasContext; Uri baseUri = new Uri(TestBase.TargetTenantConfig.TableServiceEndpoint); int count; // SAS via connection string parse sasAccount = CloudStorageAccount.Parse(string.Format("TableEndpoint={0};SharedAccessSignature={1}", baseUri.AbsoluteUri, sasToken)); sasClient = sasAccount.CreateCloudTableClient(); sasTable = sasClient.GetTableReference(table.Name); sasContext = sasClient.GetTableServiceContext(); count = sasContext.CreateQuery<BaseEntity>(sasTable.Name).AsTableServiceQuery(sasContext).Execute().Count(); Assert.AreEqual(1, count); // SAS via account constructor sasCreds = new StorageCredentials(sasToken); sasAccount = new CloudStorageAccount(sasCreds, null, null, baseUri, null); sasClient = sasAccount.CreateCloudTableClient(); sasTable = sasClient.GetTableReference(table.Name); sasContext = sasClient.GetTableServiceContext(); count = sasContext.CreateQuery<BaseEntity>(sasTable.Name).AsTableServiceQuery(sasContext).Execute().Count(); Assert.AreEqual(1, count); // SAS via client constructor URI + Creds sasCreds = new StorageCredentials(sasToken); sasClient = new CloudTableClient(baseUri, sasCreds); sasContext = sasClient.GetTableServiceContext(); count = sasContext.CreateQuery<BaseEntity>(sasTable.Name).AsTableServiceQuery(sasContext).Execute().Count(); Assert.AreEqual(1, count); } finally { table.DeleteIfExists(); } }
/// <summary> /// Test deleting entities inside and outside the given range. /// </summary> /// <param name="testClient">The table client to test.</param> /// <param name="tableName">The name of the table to test.</param> /// <param name="accessPermissions">The access permissions of the table client.</param> /// <param name="startPk">The start partition key range.</param> /// <param name="startRk">The start row key range.</param> /// <param name="endPk">The end partition key range.</param> /// <param name="endRk">The end row key range.</param> private void TestDelete( CloudTableClient testClient, string tableName, SharedAccessTablePermissions accessPermissions, string startPk, string startRk, string endPk, string endRk) { TableServiceContext referenceContext = testClient.GetTableServiceContext(); Action<BaseEntity> deleteDelegate = (tableEntity) => { TableServiceContext context = testClient.GetTableServiceContext(); context.AttachTo(tableName, tableEntity, "*"); context.DeleteObject(tableEntity); context.SaveChangesWithRetries(); context.Detach(tableEntity); }; bool expectSuccess = (accessPermissions & SharedAccessTablePermissions.Delete) != 0; // Perform test TestOperationWithRange( tableName, startPk, startRk, endPk, endRk, deleteDelegate, "delete", expectSuccess, expectSuccess ? HttpStatusCode.NoContent : HttpStatusCode.Forbidden); }
/// <summary> /// Test adding entities inside and outside the given range. /// </summary> /// <param name="testClient">The table client to test.</param> /// <param name="tableName">The name of the table to test.</param> /// <param name="accessPermissions">The access permissions of the table client.</param> /// <param name="startPk">The start partition key range.</param> /// <param name="startRk">The start row key range.</param> /// <param name="endPk">The end partition key range.</param> /// <param name="endRk">The end row key range.</param> private void TestAdd( CloudTableClient testClient, string tableName, SharedAccessTablePermissions accessPermissions, string startPk, string startRk, string endPk, string endRk) { TableServiceContext referenceContext = testClient.GetTableServiceContext(); Action<BaseEntity> addDelegate = (tableEntity) => { TableServiceContext context = testClient.GetTableServiceContext(); context.AddObject(tableName, tableEntity); context.SaveChangesWithRetries(); }; bool expectSuccess = (accessPermissions & SharedAccessTablePermissions.Add) != 0; // Perform test TestOperationWithRange( tableName, startPk, startRk, endPk, endRk, addDelegate, "add", expectSuccess, expectSuccess ? HttpStatusCode.Created : HttpStatusCode.NotFound); }
public void SingleEntityInsertOrReplaceAPM() { CloudTableClient tableClient = GenerateCloudTableClient(); TableServiceContext ctx = tableClient.GetTableServiceContext(); TableServiceContext queryContext = tableClient.GetTableServiceContext(); queryContext.MergeOption = MergeOption.NoTracking; // Insert Entity BaseEntity baseEntity = new BaseEntity("insert test", "foo"); // Insert Or Merge with no pre-existing entity MergeEntity insertOrReplaceEntity = new MergeEntity(baseEntity.PartitionKey, baseEntity.RowKey); insertOrReplaceEntity.Randomize(); ctx.AttachTo(currentTable.Name, insertOrReplaceEntity, null); ctx.UpdateObject(insertOrReplaceEntity); using (ManualResetEvent evt = new ManualResetEvent(false)) { IAsyncResult asyncRes = null; ctx.BeginSaveChangesWithRetries( SaveChangesOptions.ReplaceOnUpdate, (res) => { asyncRes = res; evt.Set(); }, null); evt.WaitOne(); ctx.EndSaveChangesWithRetries(asyncRes); } ctx.Detach(insertOrReplaceEntity); // Retrieve Entity & Verify Contents UnionEnitity retrievedEntity = (from ent in queryContext.CreateQuery <UnionEnitity>(currentTable.Name) where ent.PartitionKey == baseEntity.PartitionKey && ent.RowKey == baseEntity.RowKey select ent).AsTableServiceQuery(queryContext).Execute().FirstOrDefault(); Assert.IsNotNull(retrievedEntity); Assert.AreEqual(null, retrievedEntity.A); Assert.AreEqual(null, retrievedEntity.B); Assert.AreEqual(null, retrievedEntity.C); Assert.AreEqual(insertOrReplaceEntity.D, retrievedEntity.D); Assert.AreEqual(insertOrReplaceEntity.E, retrievedEntity.E); Assert.AreEqual(insertOrReplaceEntity.F, retrievedEntity.F); BaseEntity replacedEntity = new BaseEntity("insert test", "foo"); replacedEntity.Randomize(); ctx.AttachTo(currentTable.Name, replacedEntity, null); ctx.UpdateObject(replacedEntity); using (ManualResetEvent evt = new ManualResetEvent(false)) { IAsyncResult asyncRes = null; ctx.BeginSaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate, (res) => { asyncRes = res; evt.Set(); }, null); evt.WaitOne(); ctx.EndSaveChangesWithRetries(asyncRes); } // Retrieve Entity & Verify retrievedEntity = (from ent in queryContext.CreateQuery <UnionEnitity>(currentTable.Name) where ent.PartitionKey == baseEntity.PartitionKey && ent.RowKey == baseEntity.RowKey select ent).AsTableServiceQuery(queryContext).Execute().FirstOrDefault(); Assert.IsNotNull(retrievedEntity); Assert.AreEqual(replacedEntity.A, retrievedEntity.A); Assert.AreEqual(replacedEntity.B, retrievedEntity.B); Assert.AreEqual(replacedEntity.C, retrievedEntity.C); Assert.AreEqual(null, retrievedEntity.D); Assert.AreEqual(null, retrievedEntity.E); Assert.AreEqual(null, retrievedEntity.F); }
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." }); } }
public void TableServiceContextConcurrencyAllowsOnlySingleOperationAtOnce() { CloudTableClient tableClient = GenerateCloudTableClient(); TableServiceContext tableContext = tableClient.GetTableServiceContext(); // insert entities to query against for (int i = 0; i < 5; i++) { for (int m = 0; m < 100; m++) { BaseEntity ent = new BaseEntity("testpartition" + i, m.ToString()); ent.Randomize(); ent.A = ent.RowKey; tableContext.AddObject(currentTable.Name, ent); } tableContext.SaveChangesWithRetries(SaveChangesOptions.Batch); } List <OperationContext> opContexts = new List <OperationContext>(); object lockerObj = new object(); DateTime start = DateTime.Now; int threadsRunning = 0; Exception lastEx = null; // Start 10 simultaneous threads to query entities associated with same context. for (int j = 0; j < 10; j++) { opContexts.Add(new OperationContext()); Thread newThread = new Thread((arg) => { Interlocked.Increment(ref threadsRunning); try { lock (lockerObj) { Monitor.Wait(lockerObj); } TableServiceQuery <BaseEntity> query = (from ent in tableContext.CreateQuery <BaseEntity>(currentTable.Name) select ent).AsTableServiceQuery(tableContext); Debug.WriteLine(String.Format("Thread {0} start operation @ {1}", Thread.CurrentThread.ManagedThreadId, (DateTime.Now - start).TotalMilliseconds)); try { query.Execute(null, arg as OperationContext).ToList(); } catch (Exception) { // no op, expected to have some exceptions } Debug.WriteLine(String.Format("Thread {0} end operation @ {1}", Thread.CurrentThread.ManagedThreadId, (DateTime.Now - start).TotalMilliseconds)); } catch (Exception ex) { lastEx = ex; } finally { Interlocked.Decrement(ref threadsRunning); } }); newThread.Start(opContexts[j]); } // Wait for all threads to start while (Interlocked.CompareExchange(ref threadsRunning, 10, 10) < 10) { Thread.Sleep(200); } // pulse all threads lock (lockerObj) { Monitor.PulseAll(lockerObj); } // Wait for all threads to complete while (Interlocked.CompareExchange(ref threadsRunning, -1, 0) > -1) { Thread.Sleep(200); } if (lastEx != null) { throw lastEx; } foreach (OperationContext opContext in opContexts) { if (opContext.LastResult == null || opContext.LastResult.StartTime == null || opContext.LastResult.EndTime == null) { continue; } TestHelper.AssertNAttempts(opContext, 1); RequestResult currRes = opContext.LastResult; // Make sure this results start time does not occur in between any other results start & end time IEnumerable <RequestResult> overlappingResults = (from ctx in opContexts where ctx.LastResult != null && ctx.LastResult != currRes && ctx.LastResult.StartTime != null && ctx.LastResult.EndTime != null && ctx.LastResult.StartTime.Ticks <currRes.StartTime.Ticks && ctx.LastResult.EndTime.Ticks> currRes.StartTime.Ticks select ctx.LastResult); Assert.AreEqual(overlappingResults.Count(), 0, "Detected overlapping query"); } }
public void TableGetSetPermissionTest() { CloudTableClient tableClient = GenerateCloudTableClient(); CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); try { table.Create(); TableServiceContext context = tableClient.GetTableServiceContext(); context.AddObject(table.Name, new BaseEntity("PK", "RK")); context.SaveChangesWithRetries(); TablePermissions expectedPermissions; TablePermissions testPermissions; // Test new table permissions. expectedPermissions = new TablePermissions(); testPermissions = table.GetPermissions(); AssertPermissionsEqual(expectedPermissions, testPermissions); // Test setting empty permissions. table.SetPermissions(expectedPermissions); Thread.Sleep(30 * 1000); testPermissions = table.GetPermissions(); AssertPermissionsEqual(expectedPermissions, testPermissions); // Add a policy, check setting and getting. expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy { Permissions = SharedAccessTablePermissions.Query, SharedAccessStartTime = DateTimeOffset.Now - TimeSpan.FromHours(1), SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromHours(1) }); table.SetPermissions(expectedPermissions); Thread.Sleep(30 * 1000); testPermissions = table.GetPermissions(); AssertPermissionsEqual(expectedPermissions, testPermissions); // Add a policy, check setting and getting. expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy { Permissions = SharedAccessTablePermissions.Delete | SharedAccessTablePermissions.Add, SharedAccessStartTime = DateTimeOffset.Now + TimeSpan.FromHours(1), SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromDays(1) }); table.SetPermissions(expectedPermissions); Thread.Sleep(30 * 1000); testPermissions = table.GetPermissions(); AssertPermissionsEqual(expectedPermissions, testPermissions); // Add a null policy, check setting and getting. expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy { Permissions = SharedAccessTablePermissions.None, }); table.SetPermissions(expectedPermissions); Thread.Sleep(30 * 1000); testPermissions = table.GetPermissions(); AssertPermissionsEqual(expectedPermissions, testPermissions); // Add a policy, check setting and getting. expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy { Permissions = SharedAccessTablePermissions.Add | SharedAccessTablePermissions.Query | SharedAccessTablePermissions.Update | SharedAccessTablePermissions.Delete, SharedAccessStartTime = DateTimeOffset.Now + TimeSpan.FromDays(0.5), SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromDays(1) }); table.SetPermissions(expectedPermissions); Thread.Sleep(30 * 1000); testPermissions = table.GetPermissions(); AssertPermissionsEqual(expectedPermissions, testPermissions); // Add a policy, check setting and getting. expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy { Permissions = SharedAccessTablePermissions.Update, SharedAccessStartTime = DateTimeOffset.Now + TimeSpan.FromHours(6), SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromHours(6.5) }); table.SetPermissions(expectedPermissions); Thread.Sleep(30 * 1000); testPermissions = table.GetPermissions(); AssertPermissionsEqual(expectedPermissions, testPermissions); } finally { table.DeleteIfExists(); } }
public void TableSASConstructors() { CloudTableClient tableClient = GenerateCloudTableClient(); CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); try { table.Create(); TableServiceContext context = tableClient.GetTableServiceContext(); context.AddObject(table.Name, new BaseEntity("PK", "RK")); context.SaveChangesWithRetries(); // Prepare SAS authentication with full permissions string sasToken = table.GetSharedAccessSignature( new SharedAccessTablePolicy { Permissions = SharedAccessTablePermissions.Add | SharedAccessTablePermissions.Delete | SharedAccessTablePermissions.Query, SharedAccessExpiryTime = DateTimeOffset.Now.AddMinutes(30) }, null /* accessPolicyIdentifier */, null /* startPk */, null /* startRk */, null /* endPk */, null /* endRk */); CloudStorageAccount sasAccount; StorageCredentials sasCreds; CloudTableClient sasClient; CloudTable sasTable; TableServiceContext sasContext; Uri baseUri = new Uri(TestBase.TargetTenantConfig.TableServiceEndpoint); int count; // SAS via connection string parse sasAccount = CloudStorageAccount.Parse(string.Format("TableEndpoint={0};SharedAccessSignature={1}", baseUri.AbsoluteUri, sasToken)); sasClient = sasAccount.CreateCloudTableClient(); sasTable = sasClient.GetTableReference(table.Name); sasContext = sasClient.GetTableServiceContext(); count = sasContext.CreateQuery <BaseEntity>(sasTable.Name).AsTableServiceQuery(sasContext).Execute().Count(); Assert.AreEqual(1, count); // SAS via account constructor sasCreds = new StorageCredentials(sasToken); sasAccount = new CloudStorageAccount(sasCreds, null, null, baseUri); sasClient = sasAccount.CreateCloudTableClient(); sasTable = sasClient.GetTableReference(table.Name); sasContext = sasClient.GetTableServiceContext(); count = sasContext.CreateQuery <BaseEntity>(sasTable.Name).AsTableServiceQuery(sasContext).Execute().Count(); Assert.AreEqual(1, count); // SAS via client constructor URI + Creds sasCreds = new StorageCredentials(sasToken); sasClient = new CloudTableClient(baseUri, sasCreds); sasContext = sasClient.GetTableServiceContext(); count = sasContext.CreateQuery <BaseEntity>(sasTable.Name).AsTableServiceQuery(sasContext).Execute().Count(); Assert.AreEqual(1, count); // SAS via CloudTable constructor Uri + Client sasCreds = new StorageCredentials(sasToken); sasTable = new CloudTable(table.Uri, tableClient); sasClient = sasTable.ServiceClient; sasContext = sasClient.GetTableServiceContext(); count = sasContext.CreateQuery <BaseEntity>(sasTable.Name).AsTableServiceQuery(sasContext).Execute().Count(); Assert.AreEqual(1, count); } finally { table.DeleteIfExists(); } }
/// <summary> /// Test a table operation on entities inside and outside the given range. /// </summary> /// <param name="tableName">The name of the table to test.</param> /// <param name="startPk">The start partition key range.</param> /// <param name="startRk">The start row key range.</param> /// <param name="endPk">The end partition key range.</param> /// <param name="endRk">The end row key range.</param> /// <param name="runOperationDelegate">A delegate with the table operation to test.</param> /// <param name="opName">The name of the operation being tested.</param> /// <param name="expectSuccess">Whether the operation should succeed on entities within the range.</param> private void TestOperationWithRange( string tableName, string startPk, string startRk, string endPk, string endRk, Action <BaseEntity> runOperationDelegate, string opName, bool expectSuccess, HttpStatusCode expectedStatusCode, bool isRangeQuery) { CloudTableClient referenceClient = GenerateCloudTableClient(); TableServiceContext referenceContext = referenceClient.GetTableServiceContext(); string partitionKey = startPk ?? endPk ?? "M"; string rowKey = startRk ?? endRk ?? "S"; // if we expect a success for creation - avoid inserting duplicate entities BaseEntity tableEntity = new BaseEntity(partitionKey, rowKey); if (expectedStatusCode == HttpStatusCode.Created) { referenceContext.AttachTo(tableName, tableEntity, "*"); referenceContext.DeleteObject(tableEntity); try { referenceContext.SaveChangesWithRetries(); } catch (Exception) { } } else { // only for add we should not be adding the entity referenceContext.AttachTo(tableName, tableEntity); referenceContext.UpdateObject(tableEntity); referenceContext.SaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate); } if (expectSuccess) { runOperationDelegate(tableEntity); } else { TestHelper.ExpectedException( () => runOperationDelegate(tableEntity), string.Format("{0} without appropriate permission.", opName), HttpStatusCode.NotFound); } if (startPk != null) { tableEntity.PartitionKey = "A"; if (startPk.CompareTo(tableEntity.PartitionKey) <= 0) { Assert.Inconclusive("Test error: partition key for this test must not be less than or equal to \"A\""); } TestHelper.ExpectedException( () => runOperationDelegate(tableEntity), string.Format("{0} before allowed partition key range", opName), HttpStatusCode.NotFound); tableEntity.PartitionKey = partitionKey; } if (endPk != null) { tableEntity.PartitionKey = "Z"; if (endPk.CompareTo(tableEntity.PartitionKey) >= 0) { Assert.Inconclusive("Test error: partition key for this test must not be greater than or equal to \"Z\""); } TestHelper.ExpectedException( () => runOperationDelegate(tableEntity), string.Format("{0} after allowed partition key range", opName), HttpStatusCode.NotFound); tableEntity.PartitionKey = partitionKey; } if (startRk != null) { if (isRangeQuery || startPk != null) { tableEntity.PartitionKey = startPk; tableEntity.RowKey = "A"; if (startRk.CompareTo(tableEntity.RowKey) <= 0) { Assert.Inconclusive("Test error: row key for this test must not be less than or equal to \"A\""); } TestHelper.ExpectedException( () => runOperationDelegate(tableEntity), string.Format("{0} before allowed row key range", opName), HttpStatusCode.NotFound); tableEntity.RowKey = rowKey; } } if (endRk != null) { if (isRangeQuery || endPk != null) { tableEntity.PartitionKey = endPk; tableEntity.RowKey = "Z"; if (endRk.CompareTo(tableEntity.RowKey) >= 0) { Assert.Inconclusive("Test error: row key for this test must not be greater than or equal to \"Z\""); } TestHelper.ExpectedException( () => runOperationDelegate(tableEntity), string.Format("{0} after allowed row key range", opName), HttpStatusCode.NotFound); tableEntity.RowKey = rowKey; } } }
public void TableSetGetPermissionsAPM() { CloudTableClient tableClient = GenerateCloudTableClient(); CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); try { table.Create(); TableServiceContext context = tableClient.GetTableServiceContext(); context.AddObject(table.Name, new BaseEntity("PK", "RK")); context.SaveChangesWithRetries(); TablePermissions expectedPermissions = new TablePermissions(); TablePermissions testPermissions = table.GetPermissions(); AssertPermissionsEqual(expectedPermissions, testPermissions); // Add a policy, check setting and getting. expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy { Permissions = SharedAccessTablePermissions.Query, SharedAccessStartTime = DateTimeOffset.Now - TimeSpan.FromHours(1), SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromHours(1) }); using (ManualResetEvent evt = new ManualResetEvent(false)) { IAsyncResult result = null; table.BeginSetPermissions(expectedPermissions, (res) => { result = res; evt.Set(); }, null); evt.WaitOne(); table.EndSetPermissions(result); } Thread.Sleep(30 * 1000); using (ManualResetEvent evt = new ManualResetEvent(false)) { IAsyncResult result = null; table.BeginGetPermissions((res) => { result = res; evt.Set(); }, null); evt.WaitOne(); testPermissions = table.EndGetPermissions(result); } AssertPermissionsEqual(expectedPermissions, testPermissions); } finally { table.DeleteIfExists(); } }