示例#1
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);
        }
示例#2
0
        /// <summary>
        /// Helper function to set up an original entity and then run the **Tamper** Behavior against the specified storage account.
        /// This function takes a targetApi of this form: Func<string, string, SampleRTableEntity> targetApi
        /// </summary>
        /// <param name="entityPartitionKey"></param>
        /// <param name="entityRowKey"></param>
        /// <param name="targetStorageAccount"></param>
        /// <param name="targetApi"></param>
        /// <param name="targetApiExpectedToFail"></param>
        protected void SetupAndRunTamperTableBehavior(
            string entityPartitionKey,
            string entityRowKey,
            int targetStorageAccount,
            Func<string, string, SampleRTableEntity> targetApi,
            bool targetApiExpectedToFail,
            bool checkOriginalEntityUnchanged,
            bool checkStorageAccountsConsistent)
        {
            Assert.IsTrue(0 <= targetStorageAccount && targetStorageAccount < this.actualStorageAccountsUsed.Count,
                    "SetupAndRunTamperTableBehavior() is called with out-of-range targetStorageAccount={0}", targetStorageAccount);
            int index = this.actualStorageAccountsUsed[targetStorageAccount];
            string accountNameToTamper = this.rtableTestConfiguration.StorageInformation.AccountNames[index];
            Console.WriteLine("SetupAndRunTamperTableBehavior(): accountNameToTamper={0}", accountNameToTamper);

            // Tamper behavior
            ProxyBehavior[] behaviors = new[]
                {
                    TamperBehaviors.TamperAllRequestsIf(
                        Actions.ThrottleTableRequest,
                        AzureStorageSelectors.TableTraffic().IfHostNameContains(accountNameToTamper + "."))
                };

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

            //
            // 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);    
        }
示例#3
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);
            }            
        }
示例#4
0
        /// <summary>
        /// Helper function to create some initial entities and then call the specified batchOperation with HttpMangler enabled.
        /// </summary>
        /// <param name="count"></param>
        /// <param name="jobType"></param>
        /// <param name="jobId"></param>
        /// <param name="targetStorageAccount"></param>
        /// <param name="opTypes"></param>
        /// <param name="targetApiExpectedToFail"></param>
        /// <param name="checkOriginalEntityUnchanged"></param>
        /// <param name="checkStorageAccountsConsistent"></param>
        /// <param name="httpManglerStartTime"></param>
        /// <param name="skipInitialSessions"></param>
        /// <returns>ParitionKey of the initial entities created</returns>
        protected string SetupAndRunTemperBatchOperation(
            int count,
            string jobType,
            string jobId,
            int targetStorageAccount,
            List<TableOperationType> opTypes,
            bool targetApiExpectedToFail,
            bool checkOriginalEntityUnchanged,
            bool checkStorageAccountsConsistent,
            out DateTime httpManglerStartTime,
            int skipInitialSessions = 0)
        {

            Assert.IsTrue(0 <= targetStorageAccount && targetStorageAccount < this.actualStorageAccountsUsed.Count,
                   "SetupAndRunTemperBatchOperation() is called with out-of-range targetStorageAccount={0}", targetStorageAccount);
            int index = this.actualStorageAccountsUsed[targetStorageAccount];
            string accountNameToTamper = this.rtableTestConfiguration.StorageInformation.AccountNames[index];
            Console.WriteLine("SetupAndRunTemperBatchOperation(): accountNameToTamper={0} skipInitialSessions={1}",
                accountNameToTamper, skipInitialSessions);

            Assert.AreEqual(count, opTypes.Count, "count and opTypes.Count should be the same");

            //
            // Tamper behavior
            //
            ProxyBehavior[] behaviors = new[]
                {
                    TamperBehaviors.TamperAllRequestsIf(
                        (session => { session.Abort();}),
                        skipInitialSessions,
                        AzureStorageSelectors.TableTraffic().IfHostNameContains(accountNameToTamper + "."))
                };

            string jobIdTemplate = jobId + "-{0}";
            string messageTemplate = "message-{0}";
            string updatedMessageTemplate = "updated-" + messageTemplate;

            string partitionKey = string.Empty;
            //
            // Insert entities
            //
            for (int i = 0; i < count; i++)
            {
                SampleRTableEntity originalEntity = new SampleRTableEntity(
                    jobType,
                    string.Format(jobIdTemplate, i),
                    string.Format(messageTemplate, i));

                this.repTable.Execute(TableOperation.Insert(originalEntity));
                partitionKey = originalEntity.PartitionKey;
            }

            //
            // Retrieve entities and use them to create batchOperation to Replace or Delete
            //
            IEnumerable<SampleRTableEntity> allEntities = this.rtableWrapper.GetAllRows(partitionKey);
            TableBatchOperation batchOperation = new TableBatchOperation();
            int m = 0;
            foreach (SampleRTableEntity entity in allEntities)
            {
                Console.WriteLine("{0}", entity.ToString());
                Console.WriteLine("---------------------------------------");
                if (opTypes[m] == TableOperationType.Replace)
                {
                    SampleRTableEntity replaceEntity = new SampleRTableEntity(
                        entity.JobType,
                        entity.JobId,
                        string.Format(updatedMessageTemplate, m))
                    {
                        ETag = entity._rtable_Version.ToString()
                    };
                    batchOperation.Replace(replaceEntity);
                }
                else if (opTypes[m] == TableOperationType.Delete)
                {
                    entity.ETag = entity._rtable_Version.ToString();
                    batchOperation.Delete(entity);
                }
                else
                {
                    throw new ArgumentException(
                        string.Format("opType={0} is NOT supported", opTypes[m]),
                        "opType");
                }
                m++;
            }

            //
            // Enable HttpMangler
            // Call this.repTable.ExecuteBatch(batchOperation)
            //
            this.RunHttpManglerBehaviorHelper(
                batchOperation,
                behaviors,
                targetApiExpectedToFail,
                out httpManglerStartTime);

            if (checkOriginalEntityUnchanged)
            {
                Console.WriteLine("Validate originalEntity remain unchanged.");
                allEntities = this.rtableWrapper.GetAllRows(partitionKey);
                batchOperation = new TableBatchOperation();
                m = 0;
                foreach (SampleRTableEntity entity in allEntities)
                {
                    Console.WriteLine("{0}", entity.ToString());
                    Console.WriteLine("---------------------------------------");
                    Assert.AreEqual(string.Format(jobType, m), entity.JobType, "JobType does not match");
                    Assert.AreEqual(string.Format(jobIdTemplate, m), entity.JobId, "JobId does not match");
                    Assert.AreEqual(string.Format(messageTemplate, m), entity.Message, "Message does not match");
                    m++;
                }
                Console.WriteLine("Passed validation");
            }

            //
            // After httpMangler is turned off, read from individual accounts...
            //            
            Console.WriteLine("\nAfter httpMangler is turned off, read from individual accounts...");
            for (int i = 0; i < count; i++)
            {
                this.ReadFromIndividualAccountsDirectly(
                    jobType,
                    string.Format(jobIdTemplate, i),
                    checkStorageAccountsConsistent);
            }

            return partitionKey;
        }