Example #1
0
        /// <summary>
        /// Tests basic ringmaster functionality
        /// </summary>
        /// <param name="ringMaster">RingMaster client</param>
        /// <param name="instanceRootPath">Root path that must be used by this instance for creating nodes</param>
        /// <param name="iteration">Current iteration</param>
        /// <returns><c>true</c> if the functionality test passed, <c>false</c> otherwise</returns>
        private async Task <bool> TestRingMasterFunctionality(IRingMasterRequestHandler ringMaster, string instanceRootPath, long iteration)
        {
            var timer = Stopwatch.StartNew();

            try
            {
                var random = new Random();

                string nodePath = string.Format($"{instanceRootPath}/Node");
                RingMasterWatchdogEventSource.Log.Create(iteration, nodePath);
                await ringMaster.Create(nodePath, null, null, CreateMode.PersistentAllowPathCreation, throwIfNodeExists : false);

                RingMasterWatchdogEventSource.Log.Exists(iteration, nodePath);
                var nodeStat = await ringMaster.Exists(nodePath, watcher : null);

                int    nodeDataLength = random.Next(RingMasterWatchdog.DefaultMaxNodeDataLength);
                byte[] nodeData       = new byte[nodeDataLength];
                random.NextBytes(nodeData);

                RingMasterWatchdogEventSource.Log.SetData(iteration, nodePath, nodeData.Length);
                await ringMaster.SetData(nodePath, nodeData, nodeStat.Version);

                RingMasterWatchdogEventSource.Log.GetData(iteration, nodePath);
                var retrievedData = await ringMaster.GetData(nodePath, watcher : null);

                if (retrievedData == null)
                {
                    RingMasterWatchdogEventSource.Log.GetDataFailed_RetrievedDataIsNull(iteration, nodePath, nodeData.Length);
                    throw new InvalidOperationException($"Node {nodePath}: Retrieved data is null. expectedDataLength={nodeData.Length}");
                }

                if (retrievedData.Length != nodeData.Length)
                {
                    RingMasterWatchdogEventSource.Log.GetDataFailed_RetrievedDataLengthMismatch(iteration, nodePath, nodeData.Length, retrievedData.Length);
                    throw new InvalidOperationException($"Node {nodePath}: Retrieved data length mismatch retrievedDataLength={retrievedData.Length} expectedDataLength={nodeData.Length}");
                }

                if (!retrievedData.SequenceEqual(nodeData))
                {
                    RingMasterWatchdogEventSource.Log.GetDataFailed_RetrievedDataIsDifferent(iteration, nodePath, nodeData.Length);
                    throw new InvalidOperationException($"Node {nodePath}: Retrieved data is different");
                }

                RingMasterWatchdogEventSource.Log.Delete(iteration, nodePath, nodeStat.Version);
                await ringMaster.Delete(nodePath, -1);

                RingMasterWatchdogEventSource.Log.TestRingMasterFunctionalitySucceeded(iteration, timer.ElapsedMilliseconds);
                return(true);
            }
            catch (System.Exception ex)
            {
                RingMasterWatchdogEventSource.Log.TestRingMasterFunctionalityFailed(iteration, timer.ElapsedMilliseconds, ex.ToString());
            }

            return(false);
        }
Example #2
0
        /// <summary>
        /// Work load for testing SetNode method
        /// </summary>
        /// <param name="client">RingMasterClient object</param>
        /// <param name="token">Cancellation token</param>
        /// <param name="threadId">Thread sequence number</param>
        /// <returns>Async task</returns>
        private Task SetNodeThread(IRingMasterRequestHandler client, CancellationToken token, int threadId)
        {
            int taskCount = 0;
            var rnd       = new Random();
            var clock     = Stopwatch.StartNew();

            while (!token.IsCancellationRequested)
            {
                while (this.QueuedNodes.TryDequeue(out string path) && !token.IsCancellationRequested)
                {
                    var data = Helpers.MakeRandomData(rnd, rnd.Next(this.MinDataSize, this.MaxDataSize));

                    SpinWait.SpinUntil(() => taskCount < this.AsyncTaskCount || token.IsCancellationRequested);
                    var startTime = clock.Elapsed;
                    var task      = client.SetData(path, data, -1)
                                    .ContinueWith(
                        t =>
                    {
                        Interlocked.Decrement(ref taskCount);

                        if (t.Exception != null)
                        {
                            this.IncrementTotalFailures();
                            this.Log($"Failed to set {path}: {t.Exception.Message}");
                        }
                        else
                        {
                            this.AddTotalDataSize(data.Length);
                            this.IncrementTotalDataCount();

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

                    Interlocked.Increment(ref taskCount);

                    this.QueuedNodes.Enqueue(path);
                }
            }

            SpinWait.SpinUntil(() => taskCount == 0);
            return(Task.FromResult(0));
        }