示例#1
0
        /// <summary>
        /// Tests create scenario using either batch or multi
        /// </summary>
        /// <param name="batch">true if using batch, false if using multi</param>
        /// <param name="operationType">Type of the operation.</param>
        /// <param name="jobState">the job state</param>
        /// <returns>
        /// Request per second
        /// </returns>
        protected async Task <double> TestBatchOrMultiCreate(bool batch, Test.Helpers.OperationType operationType, JobState jobState)
        {
            var    name = batch ? "Batch" : "Multi";
            Random rnd  = new Random();

            // number of large trees will be a random number between (20, 50)
            this.LargeTreeRoots = Enumerable.Range(0, rnd.Next(20, 50)).Select(x => Guid.NewGuid()).ToList();

            return(await this.TestFlowAsync(
                       $"{name}(Create) node perf test",
                       operationType,
                       async (client, cancellationToken, threadId) =>
            {
                var clock = Stopwatch.StartNew();
                var rootName = $"{this.RootNodeName}_{name}";
                while (!cancellationToken.IsCancellationRequested)
                {
                    var ops = new List <Op>(this.BatchOpCount);
                    var totalSize = 0;

                    int smallTreeNodeCount = rnd.Next(this.BatchOpCount / 2);
                    int bigTreeNodeCount = this.BatchOpCount - smallTreeNodeCount;

                    var smallSubtreeId = Guid.NewGuid();
                    while (smallTreeNodeCount-- > 0)
                    {
                        var data = Helpers.MakeRandomData(rnd, rnd.Next(this.MinDataSize, this.MaxDataSize));
                        totalSize += data.Length;
                        ops.Add(Op.Create($"/{rootName}/vnet{smallSubtreeId}/mappings/v4ca/{Guid.NewGuid()}", data, null, CreateMode.PersistentAllowPathCreation));
                    }

                    while (bigTreeNodeCount-- > 0)
                    {
                        var data = Helpers.MakeRandomData(rnd, rnd.Next(this.MinDataSize, this.MaxDataSize));
                        totalSize += data.Length;
                        int idx = rnd.Next(this.LargeTreeRoots.Count);
                        ops.Add(Op.Create($"/{rootName}/vnet{this.LargeTreeRoots[idx]}/mappings/v4ca/{Guid.NewGuid()}", data, null, CreateMode.PersistentAllowPathCreation));
                    }

                    try
                    {
                        var startTime = clock.Elapsed;
                        if (batch)
                        {
                            await client.Batch(ops).ConfigureAwait(false);
                        }
                        else
                        {
                            await client.Multi(ops).ConfigureAwait(false);
                        }

                        var duration = clock.Elapsed - startTime;
                        MdmHelper.LogOperationDuration((long)duration.TotalMilliseconds, operationType);

                        this.AddTotalDataSize(totalSize);
                        this.IncrementTotalDataCount(ops.Count);
                    }
                    catch (Exception ex)
                    {
                        this.IncrementTotalFailures();
                        this.Log($"Failed to call {name}: {ex.Message}");
                    }
                }
            },
                       jobState,
                       this.TestCaseSeconds));
        }
示例#2
0
        /// <summary>
        /// Main test workflow
        /// </summary>
        /// <param name="testTitle">Title of the test case</param>
        /// <param name="operationType">the operation type</param>
        /// <param name="workload">Workload in each thread</param>
        /// <param name="jobState">the job state</param>
        /// <param name="durationInSeconds">How long the test should run</param>
        /// <returns>Number of operations per second</returns>
        protected async Task <double> TestFlowAsync(
            string testTitle,
            Test.Helpers.OperationType operationType,
            Func <IRingMasterRequestHandler, CancellationToken, int, Task> workload,
            JobState jobState,
            int durationInSeconds)
        {
            this.ResetCounts();

            var cancellation = new CancellationTokenSource();

            this.Log($"Starting test {testTitle} in {this.threadCount} threads");

            var lastCount = Interlocked.Read(ref this.totalDataCount);
            var lastSize  = Interlocked.Read(ref this.totalDataSize);

            var threads = Helpers.StartMultipleThreads(
                this.threadCount,
                (object n) => workload(this.clients[(int)n], cancellation.Token, (int)n).GetAwaiter().GetResult());

            var initialCount = lastCount;
            var initialSize  = lastSize;
            var stopwatch    = Stopwatch.StartNew();

            for (int i = 0; i < durationInSeconds; i++)
            {
                await Task.Delay(TimeSpan.FromSeconds(1));

                long size  = Interlocked.Read(ref this.totalDataSize);
                long delta = size - lastSize;

                long count      = Interlocked.Read(ref this.totalDataCount);
                long deltaCount = count - lastCount;

                this.Log($"{DateTime.Now} - {deltaCount} - {delta}");
                jobState.Status = $"processed data count: {count}, failures: {Interlocked.Read(ref this.totalFailures)}. Queued node count: {this.QueuedNodes.Count()}";
                this.processedDataCounts.Add(deltaCount);

                lastSize  = size;
                lastCount = count;
            }

            stopwatch.Stop();
            var processedCount = Interlocked.Read(ref this.totalDataCount) - initialCount;
            var processedSize  = Interlocked.Read(ref this.totalDataSize) - initialSize;
            var rate           = processedCount / stopwatch.Elapsed.TotalSeconds;

            Helper.LogAndSetJobStatus(this.Log, jobState, $"Stopping test {testTitle}. Data processed {processedSize} bytes in {processedCount} ops. rate: {rate:G4} /sec, Failures = {this.totalFailures}");
            MdmHelper.LogBytesProcessed(processedSize, operationType);

            cancellation.Cancel();

            foreach (var thread in threads)
            {
                thread.Join();
            }

            this.Log($"Stopped {testTitle}.");

            return(rate);
        }