private async Task CreateAndDeleteHierarchyTest(IRingMasterRequestHandler ringMaster, ConfigurationSection config, CancellationToken cancellationToken)
        {
            try
            {
                string testPath           = config.GetStringValue("CreateAndDeleteHierarchy.TestPath");
                int    maxNodes           = config.GetIntValue("CreateAndDeleteHierarchy.MaxNodes");
                bool   useScheduledDelete = config.GetBoolValue("CreateAndDeleteHierarchy.UseScheduledDelete");

                await ringMaster.Create(testPath, null, null, CreateMode.PersistentAllowPathCreation, throwIfNodeExists : false);

                while (!cancellationToken.IsCancellationRequested)
                {
                    var createInstrumentation      = new CreatePerformanceInstrumentation(this.MetricsFactory);
                    int maxConcurrentCreateBatches = config.GetIntValue("Create.MaxConcurrentBatches");
                    int createBatchLength          = config.GetIntValue("Create.BatchLength");

                    var createPerformanceTest = new CreatePerformance(createInstrumentation, maxConcurrentCreateBatches, cancellationToken);
                    createPerformanceTest.MinChildrenCountPerNode = config.GetIntValue("Create.MinChildrenCountPerNode");
                    createPerformanceTest.MaxChildrenCountPerNode = config.GetIntValue("Create.MaxChildrenCountPerNode");
                    createPerformanceTest.MinDataSizePerNode      = config.GetIntValue("Create.MinDataSizePerNode");
                    createPerformanceTest.MaxDataSizePerNode      = config.GetIntValue("Create.MaxDataSizePerNode");
                    createPerformanceTest.MaxNodeNameLength       = config.GetIntValue("Create.MaxNodeNameLength");

                    PopulationStressServiceEventSource.Log.CreateAndDeleteHierarchyCreateStarted(testPath, maxNodes, createBatchLength);

                    createPerformanceTest.CreateHierarchy(ringMaster, testPath, createBatchLength, maxNodes);

                    int maxConcurrentDeleteBatches = config.GetIntValue("Delete.MaxConcurrentBatches");
                    int deleteBatchLength          = config.GetIntValue("Delete.BatchLength");

                    var deleteInstrumentation = new DeletePerformanceInstrumentation(this.MetricsFactory);
                    var deletePerformanceTest = new DeletePerformance(deleteInstrumentation, maxConcurrentDeleteBatches, cancellationToken);

                    PopulationStressServiceEventSource.Log.CreateAndDeleteHierarchyDeleteStarted(testPath, maxNodes, deleteBatchLength, useScheduledDelete);

                    if (useScheduledDelete)
                    {
                        deletePerformanceTest.ScheduledDelete(ringMaster, testPath);
                    }
                    else
                    {
                        await deletePerformanceTest.LoadNodes(ringMaster, testPath, maxNodes);

                        deletePerformanceTest.QueueDeletes(ringMaster, deleteBatchLength);
                    }
                }

                PopulationStressServiceEventSource.Log.CreateAndDeleteHierarchyTestCompleted();
            }
            catch (Exception ex)
            {
                PopulationStressServiceEventSource.Log.CreateAndDeleteHierarchyTestFailed(ex.ToString());
            }
        }
        /// <summary>
        /// Measures the performance of scheduled delete operation.
        /// </summary>
        /// <param name="ringMaster">RingMaster client</param>
        private void ScheduledDeletePerformanceTest(IRingMasterRequestHandler ringMaster)
        {
            var instrumentation       = new DeletePerformanceInstrumentation();
            var deletePerformanceTest = new DeletePerformance(instrumentation, this.MaxConcurrency, CancellationToken.None);

            Trace.TraceInformation($"Scheduled Delete performance test path={this.TestPath}");

            var task = Task.Run(() => deletePerformanceTest.ScheduledDelete(ringMaster, this.TestPath));

            var totalTime = Stopwatch.StartNew();
            var timer     = Stopwatch.StartNew();

            while (!task.Wait(5000))
            {
                timer.Stop();
                Trace.TraceInformation($"Scheduled Delete ElapsedMilliseconds={totalTime.ElapsedMilliseconds}");
                timer.Restart();
            }
        }
        /// <summary>
        /// Measures the performance of delete requests.
        /// </summary>
        /// <param name="ringMaster">RingMaster client</param>
        /// <returns>Task that tracks execution of this test</returns>
        private async Task DeletePerformanceTest(IRingMasterRequestHandler ringMaster)
        {
            var instrumentation       = new DeletePerformanceInstrumentation();
            var deletePerformanceTest = new DeletePerformance(instrumentation, this.MaxConcurrency, CancellationToken.None);

            Trace.TraceInformation($"Delete performance test path={this.TestPath}");

            await deletePerformanceTest.LoadNodes(ringMaster, this.TestPath, this.MaxNodes, this.MaxGetChildrenEnumerationCount);

            var task = Task.Run(() => deletePerformanceTest.QueueDeletes(ringMaster, this.BatchLength));

            long lastSuccessCount = 0;
            var  timer            = Stopwatch.StartNew();

            while (!task.Wait(5000))
            {
                timer.Stop();
                long rate = (long)((instrumentation.Success - lastSuccessCount) * 1000) / timer.ElapsedMilliseconds;
                Trace.TraceInformation($"Delete success={instrumentation.Success}, failure={instrumentation.Failure}, rate={rate}");
                timer.Restart();
                lastSuccessCount = instrumentation.Success;
            }
        }