예제 #1
0
        /// <summary>
        /// Helper function to retrieve the set of entities for the specified set of jobType and jobId.
        /// Validate that entity.Message matches "entityMessage")
        /// </summary>
        /// <param name="jobType"></param>
        /// <param name="jobId"></param>
        /// <param name="entityMessage"></param>
        /// <param name="checkViewId">True means validate _rtable_ViewId of the entity</param>
        protected void PerformRetrieveOperationAndValidate(string jobType, string jobId, string entityMessage, bool checkViewId = true)
        {
            Console.WriteLine("\nValidating Retrieve operation...");
            for (int i = 0; i < this.numberOfPartitions; i++)
            {
                List <string> rowKeys = new List <string>(); // list of rowKey for the given paritionKey
                string        partitionKey;
                string        rowKey;
                SampleRTableEntity.GenerateKeys(this.GenerateJobType(jobType, i), "don't care", out partitionKey, out rowKey);
                //
                // GetAllRows()
                //
                Console.WriteLine("Calling GetAllRows() for partition {0}", i);
                IEnumerable <SampleRTableEntity> allRows = this.rtableWrapper.GetAllRows(partitionKey);
                int j = 0; // counting the number of rows per partition
                foreach (var retrievedEntity in allRows)
                {
                    this.ValidateRetrievedRTableEntity(retrievedEntity, jobType, jobId, entityMessage, i, j, checkViewId);
                    rowKeys.Add(retrievedEntity.RowKey);
                    j++;
                }
                Assert.AreEqual(this.numberOfRowsPerPartition, j, "Partition {0} only has {1} rows. Expected {2} rows", i, j, this.numberOfRowsPerPartition);

                //
                // FindRow()
                //
                Console.WriteLine("Calling FindRow() for partitionKey={0}", partitionKey);
                for (j = 0; j < rowKeys.Count; j++)
                {
                    SampleRTableEntity retrievedEntity = this.rtableWrapper.FindRow(partitionKey, rowKeys[j]);
                    this.ValidateRetrievedRTableEntity(retrievedEntity, jobType, jobId, entityMessage, i, j, checkViewId);
                }
            }
            Console.WriteLine("Passed Retrieve validation.\n");
        }
예제 #2
0
 /// <summary>
 /// Helper function to validate the specified entries do not exist.
 /// </summary>
 /// <param name="jobType"></param>
 /// <param name="jobId"></param>
 protected void ValidateRetrieveNotFound(string jobType, string jobId)
 {
     Console.WriteLine("\nValidating Retrieve NotFound operation jobType={0} jobId={1}...", jobType, jobId);
     for (int i = 0; i < this.numberOfPartitions; i++)
     {
         List <string> rowKeys = new List <string>(); // list of rowKey for the given paritionKey
         string        partitionKey;
         string        rowKey;
         SampleRTableEntity.GenerateKeys(this.GenerateJobType(jobType, i), "don't care", out partitionKey, out rowKey);
         //
         // GetAllRows()
         //
         Console.WriteLine("Calling GetAllRows() for partition {0}", i);
         IEnumerable <SampleRTableEntity> allRows = this.rtableWrapper.GetAllRows(partitionKey);
         int count = 0; // counting the number of rows per partition
         List <SampleRTableEntity> allRetrievedEntities = new List <SampleRTableEntity>();
         foreach (var retrievedEntity in allRows)
         {
             allRetrievedEntities.Add(retrievedEntity);
             count++;
         }
         Assert.AreEqual(0, count, "GetAllRows() should return 0 entries.");
     }
     Console.WriteLine("Passed Retrieve validation.\n");
 }
예제 #3
0
        /// <summary>
        /// Helper function to insert the specified set of jobType and jobId and validate the results.
        /// Make sure there are no existing entries for the jobType and jobId before calling this function.
        /// </summary>
        /// <param name="jobType"></param>
        /// <param name="jobId"></param>
        /// <param name="entityMessage"></param>
        protected void PerformInsertOperationAndValidate(string jobType, string jobId, string entityMessage)
        {
            Console.WriteLine("\nValidating Insert operation...");
            for (int i = 0; i < this.numberOfPartitions; i++)
            {
                List <string> rowKeys = new List <string>(); // list of rowKey for the given paritionKey
                string        partitionKey;
                string        rowKey;
                SampleRTableEntity.GenerateKeys(this.GenerateJobType(jobType, i), "don't care", out partitionKey, out rowKey);
                //
                // GetAllRows() to confirm nothing exists and then call InsertRow()
                //
                Console.WriteLine("Calling GetAllRows() for partition {0}, expecting 0 rows...", i);
                IEnumerable <SampleRTableEntity> allRows = this.rtableWrapper.GetAllRows(partitionKey);
                Assert.AreEqual(0, allRows.Count(), "Partition {0} should have 0 rows in order for InsertRow() to work.", i);

                for (int j = 0; j < this.numberOfRowsPerPartition; j++)
                {
                    SampleRTableEntity sampleRtableEntity = new SampleRTableEntity(
                        this.GenerateJobType(jobType, i),
                        this.GenerateJobId(jobId, i, j),
                        this.GenerateMessage(entityMessage, i, j));

                    int  attempts = 1;
                    bool passed   = true;
                    while (attempts < 3)
                    {
                        try
                        {
                            Console.WriteLine("attempts={0}. partitionKey={1} rowKey={2}. Calling InsertRow API...",
                                              attempts, partitionKey, sampleRtableEntity.RowKey);
                            this.rtableWrapper.InsertRow(sampleRtableEntity);
                            passed = true;
                            break; // get out of while(attempts) if no RTableConflictException
                        }
                        catch (RTableConflictException)
                        {
                            passed = false;
                            Console.WriteLine("Got RTableConflictException. attempts={0}", attempts);
                            attempts++;
                            System.Threading.Thread.Sleep(1000);
                        }
                    }
                    Assert.IsTrue(passed, "Keep getting RTableConflictException when calling InsertRow API");
                }

                //
                // FindRow()
                //
                Console.WriteLine("Calling FindRow() for partitionKey={0}", partitionKey);
                for (int j = 0; j < rowKeys.Count; j++)
                {
                    SampleRTableEntity retrievedEntity = this.rtableWrapper.FindRow(partitionKey, rowKeys[j]);
                    this.ValidateRetrievedRTableEntity(retrievedEntity, jobType, jobId, entityMessage, i, j);
                }
            }
            Console.WriteLine("Passed Insert validation.\n");
        }
예제 #4
0
        public void RandomTableOperationTest()
        {
            const int partitionIndex = 0;
            // Insert some entries.

            //Key = RowNumber, Value = RowKey
            var currentEntities = new Dictionary <int, String>();

            for (int i = 0; i < this.numberOfRowsPerPartition; i++)
            {
                currentEntities.Add(i, GenerateJobId(JobId, partitionIndex, i));
            }

            //Key = RowNumber, Value = RowKey
            var deletedEntities = new Dictionary <int, String>();

            var random = new Random();

            for (int i = 0; i < NumberOfOperations; i++)
            {
                int operation = random.Next(0, Enum.GetNames(typeof(TableOperationType)).Count());
                int randomRow = random.Next(0, NumberofEntities);

                if ((TableOperationType)operation == TableOperationType.Insert)
                {
                    if (deletedEntities.Count == 0)
                    {
                        //Ignore insertion if there is nothing to be inserted
                        continue;
                    }
                    randomRow = deletedEntities.First().Key;
                    deletedEntities.Remove(randomRow);
                }

                if (deletedEntities.ContainsKey(randomRow))
                {
                    continue;
                }

                Console.WriteLine("Operation# {0}, {1} on row {2}", i, (TableOperationType)operation, randomRow);
                PerformIndividualOperationAndValidate((TableOperationType)operation, JobType, JobId, partitionIndex, randomRow, OriginalMessage);

                if ((TableOperationType)operation == TableOperationType.Delete)
                {
                    deletedEntities.Add(randomRow, GenerateJobId(JobId, partitionIndex, randomRow));
                }
            }

            string rowKey;
            string partitionKey;

            SampleRTableEntity.GenerateKeys(this.GenerateJobType(JobType, partitionIndex), "don't care", out partitionKey, out rowKey);

            //Validations
            Console.WriteLine("Performing replica validations");
            PerformInvariantChecks(partitionKey, HeadReplicaAccountIndex, TailReplicaAccountIndex);
            Console.WriteLine("DONE. Test passed.");
        }
예제 #5
0
        /// <summary>
        /// Helper function to insert the specified set of jobType and jobId. It is expected that InsertRow() will fail.
        /// </summary>
        /// <param name="jobType"></param>
        /// <param name="jobId"></param>
        /// <param name="entityMessage"></param>
        protected void PerformInsertOperationAndExpectToFail(string jobType, string jobId, string entityMessage)
        {
            Console.WriteLine("\nValidating Insert operation will fail. jobType={0} jobId={1}...", jobType, jobId);
            for (int i = 0; i < this.numberOfPartitions; i++)
            {
                List <string> rowKeys = new List <string>(); // list of rowKey for the given paritionKey
                string        partitionKey;
                string        rowKey;
                SampleRTableEntity.GenerateKeys(this.GenerateJobType(jobType, i), "don't care", out partitionKey, out rowKey);

                for (int j = 0; j < this.numberOfRowsPerPartition; j++)
                {
                    SampleRTableEntity sampleRtableEntity = new SampleRTableEntity(
                        this.GenerateJobType(jobType, i),
                        this.GenerateJobId(jobId, i, j),
                        this.GenerateMessage(entityMessage, i, j));

                    int  attempts = 1;
                    bool failed   = false;
                    while (attempts < 3)
                    {
                        try
                        {
                            Console.WriteLine("attempts={0}. partitionKey={1} rowKey={2}. Calling InsertRow API...",
                                              attempts, partitionKey, sampleRtableEntity.RowKey);
                            this.rtableWrapper.InsertRow(sampleRtableEntity);
                            failed = false;
                            break; // get out of while(attempts) if no RTableConflictException
                        }
                        catch (RTableConflictException)
                        {
                            failed = true;
                            Console.WriteLine("Got RTableConflictException. attempts={0}", attempts);
                            attempts++;
                            System.Threading.Thread.Sleep(1000);
                        }
                    }
                    Assert.IsTrue(failed, "InsertRow() actually passed when we expect it to fail!");
                }
            }
            Console.WriteLine("Passed 'Insert will fail' validation.\n");
        }
예제 #6
0
        /// <summary>
        /// Helper function to perform Delete, InsertOrReplace, Merge, or Replace operation for the specified set of jobType and jobId.
        /// And validate the results.
        /// </summary>
        /// <param name="opType"></param>
        /// <param name="jobType"></param>
        /// <param name="jobId"></param>
        /// <param name="partition"></param>
        /// <param name="row"></param>
        /// <param name="originalMessage"></param>
        /// <param name="updatedMessage"></param>
        protected void PerformIndividualOperationAndValidate(
            TableOperationType opType,
            string jobType,
            string jobId,
            int partition,
            int row,
            string originalMessage,
            string updatedMessage = "")
        {
            Console.WriteLine("\nValidating {0} operation: updatedEntityMessage={1}...", opType, message);

            string partitionKey;
            string rowKey;

            SampleRTableEntity.GenerateKeys(this.GenerateJobType(jobType, partition), this.GenerateJobId(jobId, partition, row), out partitionKey, out rowKey);

            Console.WriteLine("PartitionKey = {0}, RowKey = {1}", partitionKey, rowKey);

            int  attempts = 1;
            bool passed   = true;
            bool resetRow = false;

            SampleRTableEntity retrievedEntity = null;

            while (attempts < 3)
            {
                try
                {
                    if (opType != TableOperationType.Insert)
                    {
                        retrievedEntity = this.rtableWrapper.FindRow(partitionKey, rowKey);
                    }

                    Console.WriteLine("attempts={0}. partitionKey={1} rowKey={2}. Calling {3} API...", attempts, partitionKey, rowKey, opType);
                    switch (opType)
                    {
                    case TableOperationType.Delete:
                    {
                        this.rtableWrapper.DeleteRow(retrievedEntity);

                        //Validate
                        try
                        {
                            retrievedEntity = this.rtableWrapper.FindRow(partitionKey, rowKey);
                            Assert.Fail("After DeleteRow() was called, FindRow() did not throw RTableResourceNotFoundException");
                        }
                        catch (RTableResourceNotFoundException)
                        {
                        }
                    }
                    break;

                    case TableOperationType.Insert:
                    {
                        SampleRTableEntity sampleRtableEntity = new SampleRTableEntity(
                            this.GenerateJobType(jobType, partition),
                            this.GenerateJobId(jobId, partition, row),
                            this.GenerateMessage(originalMessage, partition, row));
                        this.rtableWrapper.InsertRow(sampleRtableEntity);

                        //Validate
                        try
                        {
                            retrievedEntity = this.rtableWrapper.FindRow(partitionKey, rowKey);
                        }
                        catch (RTableResourceNotFoundException)
                        {
                            Assert.Fail("After InsertRow() was called, FindRow() threw RTableResourceNotFoundException");
                        }
                    }
                    break;

                    case TableOperationType.InsertOrMerge:
                    {
                        retrievedEntity.Message = this.GenerateMessage(updatedMessage, partition, row);
                        this.rtableWrapper.InsertOrMergeRow(retrievedEntity);

                        retrievedEntity = this.rtableWrapper.FindRow(partitionKey, rowKey);
                        this.ValidateRetrievedRTableEntity(retrievedEntity, jobType, jobId, updatedMessage, partition, row);
                    }
                    break;

                    case TableOperationType.InsertOrReplace:
                    {
                        retrievedEntity.Message = this.GenerateMessage(updatedMessage, partition, row);
                        this.rtableWrapper.InsertOrReplaceRow(retrievedEntity);

                        retrievedEntity = this.rtableWrapper.FindRow(partitionKey, rowKey);
                        this.ValidateRetrievedRTableEntity(retrievedEntity, jobType, jobId, updatedMessage, partition, row);
                        resetRow = true;
                    }
                    break;

                    case TableOperationType.Merge:
                    {
                        retrievedEntity.Message = this.GenerateMessage(updatedMessage, partition, row);
                        this.rtableWrapper.MergeRow(retrievedEntity);

                        retrievedEntity = this.rtableWrapper.FindRow(partitionKey, rowKey);
                        this.ValidateRetrievedRTableEntity(retrievedEntity, jobType, jobId, updatedMessage, partition, row);
                    }
                    break;

                    case TableOperationType.Replace:
                    {
                        retrievedEntity.Message = this.GenerateMessage(updatedMessage, partition, row);
                        this.rtableWrapper.ReplaceRow(retrievedEntity);

                        retrievedEntity = this.rtableWrapper.FindRow(partitionKey, rowKey);
                        this.ValidateRetrievedRTableEntity(retrievedEntity, jobType, jobId, updatedMessage, partition, row);
                        resetRow = true;
                    }
                    break;

                    case TableOperationType.Retrieve:
                    {
                        this.rtableWrapper.FindRow(partitionKey, rowKey);
                    }
                    break;

                    default:
                    {
                        throw new InvalidOperationException(string.Format("opType={0} is NOT supported", opType));
                    }
                    }
                    passed = true;
                    break; // get out of while(attempts) if no RTableConflictException
                }
                catch (RTableConflictException)
                {
                    passed = false;
                    Console.WriteLine("Got RTableConflictException. attempts={0}", attempts);
                    attempts++;
                    System.Threading.Thread.Sleep(1000);
                }
            }
            Assert.IsTrue(passed, "Keep getting RTableConflictException when calling {0} API", opType);

            Console.WriteLine("Passed {0} validation.\n", opType);

            //Reset row to original values so subsequent updates on the same row get validated correctly
            if (resetRow == true)
            {
                Console.WriteLine("Resetting row to original values");
                retrievedEntity.Message = this.GenerateMessage(originalMessage, partition, row);
                this.rtableWrapper.ReplaceRow(retrievedEntity);
            }
        }
예제 #7
0
        /// <summary>
        /// Helper function to perform Delete, InsertOrReplace, Merge, or Replace operation for the specified set of jobType and jobId.
        /// And validate the results.
        /// </summary>
        /// <param name="opType"></param>
        /// <param name="jobType"></param>
        /// <param name="jobId"></param>
        /// <param name="updatedEntityMessage"></param>
        protected void PerformOperationAndValidate(
            TableOperationType opType,
            string jobType,
            string jobId,
            string updatedEntityMessage = "")
        {
            Console.WriteLine("\nValidating {0} operation: updatedEntityMessage={1}...", opType, updatedEntityMessage);
            for (int i = 0; i < this.numberOfPartitions; i++)
            {
                List <string> rowKeys = new List <string>(); // list of rowKey for the given paritionKey
                string        partitionKey;
                string        rowKey;
                SampleRTableEntity.GenerateKeys(this.GenerateJobType(jobType, i), "don't care", out partitionKey, out rowKey);
                //
                // GetAllRows()
                //
                Console.WriteLine("Calling GetAllRows() and then ReplaceRow() for partition {0}", i);
                IEnumerable <SampleRTableEntity> allRows = this.rtableWrapper.GetAllRows(partitionKey);
                int j = 0; // counting the number of rows per partition
                List <SampleRTableEntity> allRetrievedEntities = new List <SampleRTableEntity>();
                foreach (var retrievedEntity in allRows)
                {
                    allRetrievedEntities.Add(retrievedEntity);
                    j++;
                }
                Assert.AreEqual(this.numberOfRowsPerPartition, j, "Partition {0} only has {1} rows. Expected {2} rows", i, j, this.numberOfRowsPerPartition);

                j = 0;
                foreach (var oneEntry in allRetrievedEntities)
                {
                    int  attempts = 1;
                    bool passed   = true;
                    while (attempts < 3)
                    {
                        try
                        {
                            SampleRTableEntity retrievedEntity = oneEntry;
                            Console.WriteLine("attempts={0}. partitionKey={1} rowKey={2}. Calling {3} API...",
                                              attempts, partitionKey, retrievedEntity.RowKey, opType);
                            switch (opType)
                            {
                            case TableOperationType.Delete:
                            {
                                this.rtableWrapper.DeleteRow(retrievedEntity);
                            }
                            break;

                            case TableOperationType.InsertOrReplace:
                            {
                                retrievedEntity.Message = this.GenerateMessage(updatedEntityMessage, i, j);
                                this.rtableWrapper.InsertOrReplaceRow(retrievedEntity);
                                rowKeys.Add(retrievedEntity.RowKey);
                            }
                            break;

                            case TableOperationType.Merge:
                            {
                                retrievedEntity.Message = this.GenerateMessage(updatedEntityMessage, i, j);
                                this.rtableWrapper.MergeRow(retrievedEntity);
                                rowKeys.Add(retrievedEntity.RowKey);
                            }
                            break;

                            case TableOperationType.Replace:
                            {
                                retrievedEntity.Message = this.GenerateMessage(updatedEntityMessage, i, j);
                                this.rtableWrapper.ReplaceRow(retrievedEntity);
                                rowKeys.Add(retrievedEntity.RowKey);
                            }
                            break;

                            default:
                            {
                                throw new InvalidOperationException(string.Format("opType={0} is NOT supported", opType));
                            }
                            }
                            passed = true;
                            break; // get out of while(attempts) if no RTableConflictException
                        }
                        catch (RTableConflictException)
                        {
                            passed = false;
                            Console.WriteLine("Got RTableConflictException. attempts={0}", attempts);
                            attempts++;
                            System.Threading.Thread.Sleep(1000);
                        }
                    }
                    Assert.IsTrue(passed, "Keep getting RTableConflictException when calling {0} API", opType);
                    j++;
                }
                Assert.AreEqual(this.numberOfRowsPerPartition, j, "Partition {0} only has {1} rows. Expected {2} rows", i, j, this.numberOfRowsPerPartition);

                //
                // FindRow()
                //
                Console.WriteLine("Calling FindRow() for partitionKey={0}", partitionKey);
                for (j = 0; j < rowKeys.Count; j++)
                {
                    if (opType == TableOperationType.Delete)
                    {
                        try
                        {
                            SampleRTableEntity retrievedEntity = this.rtableWrapper.FindRow(partitionKey, rowKeys[j]);
                            Assert.Fail("After DeleteRow() was called, FindRow() did not throw RTableResourceNotFoundException");
                        }
                        catch (RTableResourceNotFoundException)
                        {
                        }
                    }
                    else
                    {
                        SampleRTableEntity retrievedEntity = this.rtableWrapper.FindRow(partitionKey, rowKeys[j]);
                        this.ValidateRetrievedRTableEntity(retrievedEntity, jobType, jobId, updatedEntityMessage, i, j);
                    }
                }
            }
            Console.WriteLine("Passed {0} validation.\n", opType);
        }