Exemplo n.º 1
0
        public void B00ThrottleDeleteRowInnerTest()
        {
            this.rtableWrapper = RTableWrapperForSampleRTableEntity.GetRTableWrapper(this.repTable);

            string entityPartitionKey = "jobType-ThrottleDeleteRowInnerTest";
            string entityRowKey       = "jobId-ThrottleDeleteRowInnerTest";

            this.ForceDeleteEntryFromStorageTablesDirectly(entityPartitionKey, entityRowKey);

            int targetStorageAccount = 1;
            TargetRTableWrapperApi <SampleRTableEntity> targetApi = this.rtableWrapper.DeleteRow;
            bool targetApiExpectedToFail        = true;
            bool checkOriginalEntityUnchanged   = true;
            bool checkStorageAccountsConsistent = false;

            DateTime httpManglerStartTime;

            this.SetupAndRunThrottleTableBehavior(
                entityPartitionKey,
                entityRowKey,
                targetStorageAccount,
                targetApi,
                targetApiExpectedToFail,
                checkOriginalEntityUnchanged,
                checkStorageAccountsConsistent,
                out httpManglerStartTime);

            if (targetApiExpectedToFail)
            {
                // After recovery from throttling, sleep some time to wait for entity to be unlocked, confirm that we can delete the row.
                this.SleepUntilRowLockHasExpired(httpManglerStartTime);

                this.ExecuteDeleteRowAndValidate(entityPartitionKey, entityRowKey);
            }
            else
            {
                // After recovery from throttling, confirm the entity is gone
                this.ExecuteReadRowAndValidateNotExist(entityPartitionKey, entityRowKey);
            }
            // Confirm we can create entity using the same partition and row keys again.
            this.ExecuteCreateRowAndValidate(entityPartitionKey, entityRowKey);
        }
Exemplo n.º 2
0
        public void A00TamperSkipDeleteRowHeadTest()
        {
            this.rtableWrapper = RTableWrapperForSampleRTableEntity.GetRTableWrapper(this.repTable);

            string entityPartitionKey = "jobType-TamperSkipDeleteRowHeadTest";
            string entityRowKey       = "jobId-TamperSkipDeleteRowHeadTest";

            this.ForceDeleteEntryFromStorageTablesDirectly(entityPartitionKey, entityRowKey);

            int targetStorageAccount = 0;
            TargetRTableWrapperApi <SampleRTableEntity> targetApi = this.rtableWrapper.DeleteRow;
            bool targetApiExpectedToFail        = true;
            bool checkOriginalEntityUnchanged   = false;
            bool checkStorageAccountsConsistent = false;
            int  skipInitialiSessions           = 2;

            this.SetupAndRunTamperTableBehavior(
                entityPartitionKey,
                entityRowKey,
                targetStorageAccount,
                targetApi,
                targetApiExpectedToFail,
                checkOriginalEntityUnchanged,
                checkStorageAccountsConsistent,
                skipInitialiSessions);

            if (targetApiExpectedToFail)
            {
                // After recovery from outage, confirm that we can delete the row.
                this.ExecuteDeleteRowAndValidate(entityPartitionKey, entityRowKey);
            }
            else
            {
                // After recovery from outage, confirm the entity is gone.
                this.ExecuteReadRowAndValidateNotExist(entityPartitionKey, entityRowKey);
            }
            // Confirm we can create entity using the same partition and row keys again.
            this.ExecuteCreateRowAndValidate(entityPartitionKey, entityRowKey);
        }
Exemplo n.º 3
0
        public void C00DelayDeleteRowTailTest()
        {
            this.rtableWrapper = RTableWrapperForSampleRTableEntity.GetRTableWrapper(this.repTable);

            string entityPartitionKey = "jobType-DelayDeleteRowTailTest";
            string entityRowKey       = "jobId-DelayDeleteRowTailTest";


            this.ForceDeleteEntryFromStorageTablesDirectly(entityPartitionKey, entityRowKey);

            int targetStorageAccount = this.actualStorageAccountsUsed.Count - 1;
            TargetRTableWrapperApi <SampleRTableEntity> targetApi = this.rtableWrapper.DeleteRow;
            bool targetApiExpectedToFail = false;
            int  delayInMs = 3000;

            this.SetupAndRunDelayTableBehavior(
                entityPartitionKey,
                entityRowKey,
                targetStorageAccount,
                delayInMs,
                targetApi,
                targetApiExpectedToFail);

            if (targetApiExpectedToFail)
            {
                // After recovery from delay, confirm that we can delete the row.
                this.ExecuteDeleteRowAndValidate(entityPartitionKey, entityRowKey);
            }
            else
            {
                // After recovery from delay, confirm the entity is gone.
                this.ExecuteReadRowAndValidateNotExist(entityPartitionKey, entityRowKey);
            }
            // Confirm we can create entity using the same partition and row keys again.
            this.ExecuteCreateRowAndValidate(entityPartitionKey, entityRowKey);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Helper function to set up an original entity and then run the **Throttle** Behavior against the specified storage account.
        /// </summary>
        /// <param name="entityPartitionKey"></param>
        /// <param name="entityRowKey"></param>
        /// <param name="targetStorageAccount">Specify which storage account to tamper with. 0 = Head; Count-1 = Tail</param>
        /// <param name="targetApi">Will call this RTable API while HttpMangler is enabled</param>
        /// <param name="targetApiExpectedToFail">True means the targetAPi is expected to fail when HttpMangler is enabled</param>
        /// <param name="checkOriginalEntityUnchanged">True means verify that the original entity (via GetRow()) is unchanged after this function.</param>
        /// <param name="checkStorageAccountsConsistent">True means verify that the individual storage accounts are consistent.</param>
        /// <param name="skipInitialSessions">Skip this many initial sessions. (Let them go through without being tampered)</param>
        protected void SetupAndRunDelayTableBehavior(
            string entityPartitionKey,
            string entityRowKey,
            int targetStorageAccount,
            TargetRTableWrapperApi<SampleRTableEntity> targetApi,
            bool targetApiExpectedToFail,
            bool checkOriginalEntityUnchanged,
            bool checkStorageAccountsConsistent,
            out DateTime httpManglerStartTime,
            int skipInitialSessions = 0)
        {
            Assert.IsTrue(0 <= targetStorageAccount && targetStorageAccount < this.actualStorageAccountsUsed.Count,
                    "SetupAndRunDelayTableBehavior() is called with out-of-range targetStorageAccount={0}", targetStorageAccount);
            int index = this.actualStorageAccountsUsed[targetStorageAccount];
            string accountNameToTamper = this.rtableTestConfiguration.StorageInformation.AccountNames[index];
            Console.WriteLine("SetupAndRunDelayTableBehavior(): accountNameToTamper={0} skipInitialSessions={1}",
                accountNameToTamper, skipInitialSessions);

            // Throttle behavior
            ProxyBehavior[] behaviors = new[]
            {
                TamperBehaviors.TamperAllResponsesIf(
                        DelayResponse,
                        AzureStorageSelectors.TableTraffic().IfUrlContains(repTable.TableName))
            };

            //
            // Arrange and Act:
            //
            SampleRTableEntity originalEntity = this.SetupAndRunHttpManglerBehaviorHelper(
                                                        entityPartitionKey,
                                                        entityRowKey,
                                                        behaviors,
                                                        targetApi,
                                                        targetApiExpectedToFail,
                                                        out httpManglerStartTime);

            //
            // Assert: 
            //      
            if (checkOriginalEntityUnchanged)
            {
                // Validate originalEntity remain unchanged.
                this.ExecuteReadRowAndValidate(entityPartitionKey, entityRowKey, originalEntity);
            }

            // For debug purposes: read from the Head and Tail accounts, and check for consistency
            this.ReadFromIndividualAccountsDirectly(entityPartitionKey, entityRowKey, checkStorageAccountsConsistent);
        }
Exemplo n.º 5
0
 protected void SetupAndRunThrottleTableBehavior(
     string entityPartitionKey,
     string entityRowKey,
     int targetStorageAccount,
     TargetRTableWrapperApi<SampleRTableEntity> targetApi,
     bool targetApiExpectedToFail,
     bool checkOriginalEntityUnchanged,
     bool checkStorageAccountsConsistent,
     int skipInitialSessions = 0)
 {
     DateTime httpManglerStartTime;
     this.SetupAndRunThrottleTableBehavior(
         entityPartitionKey,
         entityRowKey,
         targetStorageAccount,
         targetApi,
         targetApiExpectedToFail,
         checkOriginalEntityUnchanged,
         checkStorageAccountsConsistent,
         out httpManglerStartTime,
         skipInitialSessions);
 }
Exemplo n.º 6
0
        /// <summary>
        /// Helper function to set up an original entity and then run the **Delay** Behavior against the specified storage account.
        /// </summary>
        /// <param name="entityPartitionKey"></param>
        /// <param name="entityRowKey"></param>
        /// <param name="targetStorageAccount">Specify which storage account to tamper with. 0 = Head; Count-1 = Tail</param>
        /// <param name="delayInMs">This much delay will be introduced to transmissions to the specified storage account.</param>
        /// <param name="targetApi">Will call this RTable API while HttpMangler is enabled</param>
        /// <param name="targetApiExpectedToFail">True means the targetAPi is expected to fail when HttpMangler is enabled</param>
        protected void SetupAndRunDelayTableBehavior(
            string entityPartitionKey, 
            string entityRowKey, 
            int targetStorageAccount, 
            int delayInMs,
            TargetRTableWrapperApi<SampleRTableEntity> targetApi,
            bool targetApiExpectedToFail)
        {
            Assert.IsTrue(0 <= targetStorageAccount && targetStorageAccount < this.actualStorageAccountsUsed.Count,
                    "SetupAndRunDelayTableBehavior() is called with out-of-range targetStorageAccount={0}", targetStorageAccount);
            int index = this.actualStorageAccountsUsed[targetStorageAccount];
            string accountNameToTamper = this.rtableTestConfiguration.StorageInformation.AccountNames[index];
            Console.WriteLine("SetupAndRunDelayTableBehavior(): accountNameToTamper={0}", accountNameToTamper);

            // Delay bahavior
            ProxyBehavior[] behaviors = new[]
                {
                    DelayBehaviors.DelayAllRequestsIf(
                            delayInMs,
                            AzureStorageSelectors.TableTraffic().IfHostNameContains(accountNameToTamper + "."))
                };

            //
            // Arrange and Act:
            //            
            DateTime httpManglerStartTime;
            SampleRTableEntity originalEntity = this.SetupAndRunHttpManglerBehaviorHelper(
                                                        entityPartitionKey,
                                                        entityRowKey,
                                                        behaviors,
                                                        targetApi,
                                                        targetApiExpectedToFail,
                                                        out httpManglerStartTime);

            //
            // Assert: 
            //      
            if (targetApiExpectedToFail)
            {
                // targetApi is expected to fail, so originalEntity should be untouched.
                this.ExecuteReadRowAndValidate(entityPartitionKey, entityRowKey, originalEntity);
            }
            else
            {
                // For debug purposes: read from the Head and Tail accounts, and check for consistency
                this.ReadFromIndividualAccountsDirectly(entityPartitionKey, entityRowKey, true);
            }            
        }
Exemplo n.º 7
0
        /// <summary>
        /// Run the specified HttpMangler proxy behaviors for the specified Api.
        /// </summary>
        /// <param name="originalEntity"></param>
        /// <param name="behaviors"></param>
        /// <param name="targetApi"></param>
        /// <param name="targetApiExpectedToFail"></param>
        /// <param name="httpManglerStartTime"></param>
        protected void RunHttpManglerBehaviorHelper(
            SampleRTableEntity originalEntity,
            ProxyBehavior[] behaviors,
            TargetRTableWrapperApi<SampleRTableEntity> targetApi,
            bool targetApiExpectedToFail,
            out DateTime httpManglerStartTime)
        {          
            //
            // Act
            //
            // Call targetApi(entity1) and tamper the request
            httpManglerStartTime = DateTime.UtcNow;

            Console.WriteLine("\nRunHttpManglerBehaviorHelper(): Call targetApi(entity1) with HttpMangler enabled...");
            originalEntity.Message = SampleRTableEntity.GenerateRandomMessage();
            bool abortTest = false;
            try
            {
                using (HttpMangler proxy = new HttpMangler(false, behaviors))
                {
                    Console.WriteLine("Calling targetApi(entity1)");
                    targetApi(originalEntity);
                    if (targetApiExpectedToFail)
                    {
                        // if targetApi is expected to fail, and we are here, that means something is wrong.
                        abortTest = true;
                        throw new Exception("RunHttpManglerBehaviorHelper(): Should not reach here. HttpMangler allowed an targetApi() to go through UNEXPECTEDLY.");
                    }
                }
            }
            catch (Exception ex)
            {
                if (targetApiExpectedToFail == false)
                {
                    // if targetApi is NOT expected to fail, and we are here, that means something is wrong.
                    throw new Exception(
                        string.Format("RunHttpManglerBehaviorHelper(): targetApi() is NOT unexpected to throw an exception. Got this exception: {0}",
                        ex.ToString()));
                }

                if (abortTest)
                {
                    throw;
                }
                else
                {
                    Console.WriteLine("\nException is Expected. targetApi(entity1) threw an exception: {0}\n", ex.ToString());
                }
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Helper function to set up an original entity and then run the specified HttpMangler Behavior. 
        /// It will return the original entity created.
        /// Step (1): Make sure "entity1" with the specified partitionKey and rowKey exists. If not create it. Read "entity1".
        /// Step (2): Read "entity1" from individual storage tables directly for debugging.
        /// Step (3): Turn on HttpMangler and the specified behavior and call the specified RTable API to operate on "entity1". 
        /// </summary>
        /// <param name="entityPartitionKey"></param>
        /// <param name="entityRowKey"></param>
        /// <param name="behaviors">HttpMangler behaviors</param>
        /// <param name="targetApi">Will call this RTable API while HttpMangler is enabled</param>
        /// <param name="targetApiExpectedToFail">True means the targetAPi is expected to fail when HttpMangler is enabled</param>
        /// <param name="httpManglerStartTime">Output: time at which HttpMangler was enabled.</param>
        /// <returns>Original entity created</returns>        
        private SampleRTableEntity SetupAndRunHttpManglerBehaviorHelper(
            string entityPartitionKey,
            string entityRowKey,
            ProxyBehavior[] behaviors,
            TargetRTableWrapperApi<SampleRTableEntity> targetApi,
            bool targetApiExpectedToFail,
            out DateTime httpManglerStartTime)
        {
            SampleRTableEntity originalEntity = new SampleRTableEntity();

            // "entity1":
            string jobType = entityPartitionKey;
            string jobId = entityRowKey;
            string referenceMessage = SampleRTableEntity.GenerateRandomMessage();

            //
            // Arrange
            //            
            // Make sure an entity exists with the specified partitionKey and rowKey    
            Console.WriteLine("\nMaking sure entity1 exists...");
            SampleRTableEntity entity1 = this.rtableWrapper.ReadEntity(jobType, jobId);
            if (entity1 == null)
            {
                SampleRTableEntity createEntity1 = new SampleRTableEntity(jobType, jobId, referenceMessage);
                this.rtableWrapper.InsertRow(createEntity1);
                entity1 = this.rtableWrapper.ReadEntity(jobType, jobId);
            }
            else
            {
                // entity1 already exists. Save the value of its Message for later use
                referenceMessage = entity1.Message;
            }

            Assert.IsNotNull(entity1, "entity1 is null UNEXPECTEDLY.");
            Console.WriteLine("entity1:\n{0}", entity1.ToString());
            Assert.IsTrue(entity1.JobType == jobType, "entity.JobType is incorrect.");
            Assert.IsTrue(entity1.JobId == jobId, "entity.JobId is incorrect.");

            originalEntity = entity1.Clone();

            // Read from Storage Accounts directly for debugging. Check for consistency of different accounts.
            this.ReadFromIndividualAccountsDirectly(jobType, jobId, true);

            this.RunHttpManglerBehaviorHelper(
                entity1,
                behaviors,
                targetApi,
                targetApiExpectedToFail,
                out httpManglerStartTime);

            return originalEntity;
        }