public void TableServiceQueryExecuteBasic()
        {
            CloudTableClient    tableClient = GenerateCloudTableClient();
            TableServiceContext ctx         = tableClient.GetTableServiceContext();

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

            List <BaseEntity> totalResults = query.Execute().ToList();

            Assert.AreEqual(totalResults.Count, totalTestEntities);
        }
        public void TableServiceQueryExecuteWithTake()
        {
            CloudTableClient    tableClient = GenerateCloudTableClient();
            TableServiceContext ctx         = tableClient.GetTableServiceContext();

            int takeCount = 0;

            IQueryable <BaseEntity> baseQuery = (from ent in ctx.CreateQuery <BaseEntity>(currentTable.Name)
                                                 select ent);

            List <BaseEntity> totalResults = baseQuery.Take(takeCount).AsTableServiceQuery(ctx).Execute().ToList();

            Assert.AreEqual(totalResults.Count, takeCount);

            takeCount    = 10;
            totalResults = baseQuery.Take(takeCount).AsTableServiceQuery(ctx).Execute().ToList();
            Assert.AreEqual(totalResults.Count, Math.Min(takeCount, totalTestEntities));

            takeCount    = 1000;
            totalResults = baseQuery.Take(takeCount).AsTableServiceQuery(ctx).Execute().ToList();
            Assert.AreEqual(totalResults.Count, Math.Min(takeCount, totalTestEntities));



            takeCount = 1001;
            try
            {
                totalResults = baseQuery.Take(takeCount).AsTableServiceQuery(ctx).Execute().ToList();
                Assert.Fail();
            }
            catch (StorageException ex)
            {
                Assert.AreEqual(ex.RequestInformation.HttpStatusCode, (int)HttpStatusCode.BadRequest);
                Assert.AreEqual(ex.Message, "InvalidInput");
                Assert.IsTrue(ex.RequestInformation.ExtendedErrorInformation.ErrorMessage.StartsWith("One of the request inputs is not valid."), ex.RequestInformation.ExtendedErrorInformation.ErrorMessage);
            }


            takeCount = -1;
            try
            {
                totalResults = baseQuery.Take(takeCount).AsTableServiceQuery(ctx).Execute().ToList();
                Assert.Fail();
            }
            catch (StorageException ex)
            {
                Assert.AreEqual(ex.RequestInformation.HttpStatusCode, (int)HttpStatusCode.BadRequest);
                Assert.AreEqual(ex.Message, "InvalidInput");
                Assert.IsTrue(ex.RequestInformation.ExtendedErrorInformation.ErrorMessage.StartsWith("One of the request inputs is not valid."), ex.RequestInformation.ExtendedErrorInformation.ErrorMessage);
            }
        }
Ejemplo n.º 3
0
        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);
            }
        }
        public void TableServiceQueryExecuteSecondary()
        {
            CloudTableClient tableClient = GenerateCloudTableClient();

            tableClient.LocationMode = RetryPolicies.LocationMode.SecondaryOnly;
            TableServiceContext ctx = tableClient.GetTableServiceContext();

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

            TestHelper.ExpectedException <InvalidOperationException>(
                () => query.Execute().ToList(),
                "Even queries cannot be sent to secondary location when using TableServiceContext");
        }
        private void DoTableServiceQueryExecuteBasic(TablePayloadFormat format)
        {
            CloudTableClient    tableClient = GenerateCloudTableClient();
            TableServiceContext ctx         = tableClient.GetTableServiceContext();

            SetPayloadFormatOnDataServiceContext(ctx, format, tableClient);

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

            List <BaseEntity> totalResults = query.Execute().ToList();

            Assert.AreEqual(totalResults.Count, totalTestEntities);
        }
        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 DoTableServiceQueryProjectionWithUpdate(TablePayloadFormat format)
        {
            CloudTableClient    tableClient = GenerateCloudTableClient();
            TableServiceContext ctx         = tableClient.GetTableServiceContext();

            SetPayloadFormatOnDataServiceContext(ctx, format, tableClient);

            // Retrieve Entities
            TableServiceQuery <UnionEnitity> query = (from ent in ctx.CreateQuery <BaseEntity>(currentTable.Name)
                                                      select new UnionEnitity
            {
                A = ent.A,
                B = ent.B
            }).Take(20).AsTableServiceQuery(ctx);



            List <UnionEnitity> totalResults = query.Execute().ToList();

            foreach (UnionEnitity ent in totalResults)
            {
                Assert.IsNotNull(ent.A);
                Assert.IsNotNull(ent.B);
                ent.PartitionKey = string.Empty;
                ent.RowKey       = string.Empty;
                ent.B           += "_updated";
                ctx.UpdateObject(ent);
            }

            ctx.SaveChangesWithRetries(SaveChangesOptions.Batch);

            TableServiceContext queryContext = tableClient.GetTableServiceContext();

            // Verify update
            TableServiceQuery <BaseEntity> secondQuery = (from ent in queryContext.CreateQuery <BaseEntity>(currentTable.Name)
                                                          select ent).Take(20).AsTableServiceQuery(queryContext);

            foreach (BaseEntity ent in secondQuery.Execute())
            {
                Assert.IsTrue(ent.B.EndsWith("_updated"));
            }
        }
        public void SingleEntityInsertTask()
        {
            CloudTableClient    tableClient = GenerateCloudTableClient();
            TableServiceContext ctx         = tableClient.GetTableServiceContext();

            // Insert Entity
            ComplexEntity insertEntity = new ComplexEntity("insert test", "foo");

            ctx.AddObject(currentTable.Name, insertEntity);
            Task.Factory.FromAsync <DataServiceResponse>(ctx.BeginSaveChangesWithRetries, ctx.EndSaveChangesWithRetries, null).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);
        }
        public void TableServiceQueryExecuteSegmentedBasicAPM()
        {
            CloudTableClient    tableClient = GenerateCloudTableClient();
            TableServiceContext ctx         = tableClient.GetTableServiceContext();

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

            List <BaseEntity> totalResults         = new List <BaseEntity>();
            TableQuerySegment <BaseEntity> segment = null;

            do
            {
                using (ManualResetEvent evt = new ManualResetEvent(false))
                {
                    IAsyncResult result = null;
                    query.BeginExecuteSegmented(segment != null ? segment.ContinuationToken : null,
                                                (res) =>
                    {
                        result = res;
                        evt.Set();
                    }, null);
                    evt.WaitOne();

                    segment = query.EndExecuteSegmented(result);
                }

                if (totalResults.Count == 0)
                {
                    // Assert first segment has continuation token

                    Assert.IsNotNull(segment.ContinuationToken);
                }

                totalResults.AddRange(segment);
            }while (segment.ContinuationToken != null);

            Assert.AreEqual(totalResults.Count, totalTestEntities);
        }
Ejemplo n.º 10
0
        private void DoSingleEntityReplace(TablePayloadFormat format)
        {
            CloudTableClient    tableClient  = GenerateCloudTableClient();
            TableServiceContext ctx          = tableClient.GetTableServiceContext();
            TableServiceContext queryContext = tableClient.GetTableServiceContext();

            SetPayloadFormatOnDataServiceContext(ctx, format, tableClient);
            SetPayloadFormatOnDataServiceContext(queryContext, format, tableClient);

            // Insert Entity
            BaseEntity baseEntity = new BaseEntity("insert test", "foo" + format.ToString());

            baseEntity.Randomize();
            ctx.AddObject(currentTable.Name, baseEntity);
            ctx.SaveChangesWithRetries();
            string etag = ctx.Entities.First().ETag;

            ctx.Detach(baseEntity);

            MergeEntity replaceEntity = new MergeEntity(baseEntity.PartitionKey, baseEntity.RowKey);

            replaceEntity.Randomize();
            ctx.AttachTo(currentTable.Name, replaceEntity, etag);
            ctx.UpdateObject(replaceEntity);
            ctx.SaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate);

            // Retrieve Entity
            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(replaceEntity.D, retrievedEntity.D);
            Assert.AreEqual(replaceEntity.E, retrievedEntity.E);
            Assert.AreEqual(replaceEntity.F, retrievedEntity.F);
        }
Ejemplo n.º 11
0
        public void TableServiceQueryWithRetryTask()
        {
            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.SaveChangesWithRetriesAsync(SaveChangesOptions.Batch).Wait();
                }
            }

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

            TestHelper.ExecuteTaskMethodWithRetry(
                2, // 1 failure, one success
                new[]
            {
                //Insert upstream network delay to prevent upload to server @ 1000ms / kb
                PerformanceBehaviors.InsertDownstreamNetworkDelay(
                    10000,
                    AzureStorageSelectors.TableTraffic()
                    .IfHostNameContains(tableClient.Credentials.AccountName)
                    .Alternating(true)),
                // After 100 ms return throttle message
                DelayedActionBehaviors.ExecuteAfter(
                    Actions.ThrottleTableRequest,
                    100,
                    AzureStorageSelectors.TableTraffic()
                    .IfHostNameContains(tableClient.Credentials.AccountName)
                    .Alternating(true))
            },
                (options, opContext) => query.ExecuteSegmentedAsync(null, (TableRequestOptions)options, opContext));
        }
Ejemplo n.º 12
0
        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);
        }
Ejemplo n.º 13
0
        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 SingleEntityMerge()
        {
            CloudTableClient    tableClient  = GenerateCloudTableClient();
            TableServiceContext ctx          = tableClient.GetTableServiceContext();
            TableServiceContext queryContext = tableClient.GetTableServiceContext();

            // Insert Entity
            BaseEntity baseEntity = new BaseEntity("insert test", "foo");

            baseEntity.Randomize();
            ctx.AddObject(currentTable.Name, baseEntity);
            ctx.SaveChangesWithRetries();
            string etag = ctx.Entities.First().ETag;

            ctx.Detach(baseEntity);

            MergeEntity mergeEntity = new MergeEntity(baseEntity.PartitionKey, baseEntity.RowKey);

            mergeEntity.Randomize();
            ctx.AttachTo(currentTable.Name, mergeEntity, etag);
            ctx.UpdateObject(mergeEntity);
            ctx.SaveChangesWithRetries();

            // Retrieve Entity
            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(baseEntity.A, retrievedEntity.A);
            Assert.AreEqual(baseEntity.B, retrievedEntity.B);
            Assert.AreEqual(baseEntity.C, retrievedEntity.C);
            Assert.AreEqual(mergeEntity.D, retrievedEntity.D);
            Assert.AreEqual(mergeEntity.E, retrievedEntity.E);
            Assert.AreEqual(mergeEntity.F, retrievedEntity.F);
        }
Ejemplo n.º 15
0
        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);
        }
        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);
        }
        public void SingleEntityInsertDeleteFail()
        {
            CloudTableClient    tableClient = GenerateCloudTableClient();
            TableServiceContext ctx         = tableClient.GetTableServiceContext();

            // Delete Entity that does not exits
            ComplexEntity deleteEntity = new ComplexEntity("insert test", "foo");

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

            // Insert Entity
            ComplexEntity insertEntity = new ComplexEntity("insert test", "foo");

            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." });
            }
        }
Ejemplo n.º 18
0
        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
                var 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");
            }
        }