Esempio n. 1
0
 internal void AddDistributedTask(BatchPayload batchPayload)
 {
     if (_engine != null && _engine.IsStarted)
     {
         var servers = _loadSet.Root.Element("RemoteServers").Descendants("Server").Where(s => Convert.ToBoolean(s.Attribute("IsEnabled").Value)).Select(s => s.Value).ToArray();
         servers.ForEach(s =>
         {
             AddLog(string.Format("distributing batch load to {0}", s));
         });
         _engine.Distribute(batchPayload, servers);
     }
 }
Esempio n. 2
0
        private byte[] WriteBatchParts <TOperation, TChangeSet>(BatchPayload <TOperation, TChangeSet> batchPayload, string boundary, Encoding encoding, Action <TOperation> writeOperation)
            where TChangeSet : BatchChangeset <TOperation>
            where TOperation : class, IMimePart
        {
            using (this.writer = new StreamWriter(new MemoryStream(), encoding))
            {
                foreach (var batchPart in batchPayload.Parts)
                {
                    this.WriteStartBoundary(boundary);
                    this.WriteHeaders(batchPart);

                    var changeset = batchPart as TChangeSet;
                    if (changeset != null)
                    {
                        foreach (var changesetPart in changeset)
                        {
                            this.WriteStartBoundary(changeset.Boundary);
                            this.WriteHeaders(changesetPart);
                            var requestChangesetPart = changesetPart as MimePartData <TOperation>;
                            ExceptionUtilities.CheckArgumentNotNull(requestChangesetPart, "requestChangeSetPart cannot be null");
                            writeOperation(requestChangesetPart.Body);
                        }

                        // BatchPayloadSerializer does not write end boundaries if no operations/parts exist
                        //             Test triage decided that changesets without parts are enough of an edge case to not fix this.
                        if (changeset.Any())
                        {
                            this.WriteEndBoundary(changeset.Boundary);
                        }
                    }
                    else
                    {
                        // The batch part not a changeSet so write the request or response.
                        var batchOperation = batchPart as MimePartData <TOperation>;
                        ExceptionUtilities.CheckArgumentNotNull(batchOperation, "batchOperation cannot be null");
                        writeOperation(batchOperation.Body);
                    }
                }

                // BatchPayloadSerializer does not write end boundaries if no operations/parts exist
                // Test triage decided that batch payloads without parts are enough of an edge case to not fix this.
                if (batchPayload.Parts.Any())
                {
                    this.WriteEndBoundary(boundary);
                }

                return(((MemoryStream)this.writer.BaseStream).ToArray());
            }
        }
Esempio n. 3
0
        public void Distribute(BatchPayload batchPayload, string[] endpoints)
        {
            var result  = batchPayload.Serialize();
            var content = Encoding.UTF8.GetBytes(result);

            endpoints.ForEach(e =>
            {
                try
                {
                    new WebClient().UploadData(e, content);
                }
                catch (Exception ex)
                {
                    if (DistributedProgress != null)
                    {
                        DistributedProgress(this, new DistributedLoadEventArgs {
                            Load = batchPayload, Url = e, Message = ex.Message
                        });
                    }
                }
            });
        }
Esempio n. 4
0
        private void RunTasks()
        {
            _loadSet.Descendants("Task").Where(t => Convert.ToBoolean(t.Attribute("IsEnabled").Value)).ForEach(t =>
            {
                var loadSize       = Convert.ToInt32(t.Attribute("LoadSize").Value);
                var throughputSize = loadSize / 10;
                var useBatchSet    = Convert.ToBoolean(t.Attribute("UseBatchSet").Value);
                var isDistributed  = t.Attributes().Any(a => a.Name == "IsDistributed") ? Convert.ToBoolean(t.Attribute("IsDistributed").Value) : false;
                int[] batches;
                if (useBatchSet)
                {
                    batches = _loadSet.Root.Element("Batches").Descendants("Batch").Select(b => Convert.ToInt32(b.Value)).ToArray();
                }
                else
                {
                    batches = t.Descendants("Batch").Select(b => Convert.ToInt32(b.Value)).ToArray();
                }

                var requests = new List <HttpRequest>();
                t.Descendants("Request").Where(r => Convert.ToBoolean(r.Attribute("IsEnabled").Value)).ForEach(r =>
                {
                    var request                = t.Element("Request");
                    var requestUrl             = request.Attribute("Url").Value;
                    var requestParameters      = request.Descendants("Parameter").Select(p => new KeyValuePair <string, string>(p.Attribute("Key").Value, p.Value)).ToList();
                    var requestContentEncoding = request.Attribute("ContentEncoding").Value;
                    var requestContentType     = request.Attribute("ContentType").Value.Parse <ContentTypes>();
                    var requestAcceptType      = request.Attribute("AcceptType").Value.Parse <ContentTypes>();
                    var requestIsPost          = Convert.ToBoolean(request.Attribute("IsPost").Value);
                    var requestIsBodyTransport = Convert.ToBoolean(request.Attribute("IsBodyTransport").Value);
                    requests.Add(new HttpRequest {
                        Url = requestUrl, Parameters = requestParameters, ContentEncoding = requestContentEncoding, ContentType = requestContentType, AcceptType = requestAcceptType, IsPost = requestIsPost, IsBodyTransport = requestIsBodyTransport
                    });
                });

                var auth        = t.Element("Auth");
                var authRequest = new HttpRequest
                {
                    Url             = string.Empty,
                    Parameters      = new List <KeyValuePair <string, string> >(),
                    ContentEncoding = Encoding.Default.BodyName,
                    ContentType     = ContentTypes.None,
                    AcceptType      = ContentTypes.None,
                    IsPost          = false,
                    IsBodyTransport = false
                };
                if (auth != null)
                {
                    authRequest.Url = auth.Attributes().Any(a => a.Name == "Url") ? auth.Attribute("Url").Value : string.Empty;
                    if (!string.IsNullOrEmpty(authRequest.Url))
                    {
                        authRequest.Parameters      = auth.Descendants("Parameter").Select(p => new KeyValuePair <string, string>(p.Attribute("Key").Value, p.Value)).ToList();
                        authRequest.ContentEncoding = auth.Attribute("ContentEncoding").Value;
                        authRequest.ContentType     = auth.Attribute("ContentType").Value.Parse <ContentTypes>();
                        authRequest.AcceptType      = auth.Attribute("AcceptType").Value.Parse <ContentTypes>();
                        authRequest.IsPost          = Convert.ToBoolean(auth.Attribute("IsPost").Value);
                        authRequest.IsBodyTransport = Convert.ToBoolean(auth.Attribute("IsBodyTransport").Value);
                    }
                }

                var name         = t.Attribute("Name").Value;
                var batchPayload = new BatchPayload {
                    Name = name, LoadSize = loadSize, Requests = requests, Auth = authRequest, ThroughputSize = throughputSize, BatchSizes = batches
                };

                if (isDistributed)
                {
                    AddDistributedTask(batchPayload);
                }
                TestLoad(batchPayload);
            });
        }
Esempio n. 5
0
        internal void TestLoad(BatchPayload batchPayload)
        {
            if (batchPayload.LoadSize <= 0)
            {
                AddLog("no load specified");
                return;
            }
            if (batchPayload.Requests.Count == 0)
            {
                AddLog("no request specified");
                return;
            }
            if (batchPayload.ThroughputSize <= 0)
            {
                batchPayload.ThroughputSize = 1;
            }

            var grandResults = new List <KeyValuePair <Payload, LoadResult> >();

            var grandReport = new StringBuilder();

            grandReport.AppendLine(new string('*', 80));
            grandReport.AppendLine(string.Format("task: {0}", batchPayload.Name));
            grandReport.AppendLine(string.Format("load: {0}", batchPayload.LoadSize));
            grandReport.AppendLine(string.Format("grand started: {0}", DateTime.Now));
            grandReport.AppendLine(new string('-', 50));
            AddLog(grandReport.ToString());

            batchPayload.BatchSizes.ForEach(batchSize =>
            {
                var load = new Payload
                {
                    LoadSize       = batchPayload.LoadSize,
                    Requests       = batchPayload.Requests,
                    Auth           = batchPayload.Auth,
                    ConcurrentSize = batchSize,
                    ThroughputSize = batchPayload.ThroughputSize
                };

                AddLog("concurrent: " + load.ConcurrentSize);
                AddLog("started: " + DateTime.Now.ToString());

                AddLog("requests: ");
                load.Requests.ForEach(r =>
                {
                    AddLog(string.Format("\t{0}", r.Url));
                });

                var engine       = new LoadEngine(load);
                engine.Progress += (s, e) =>
                {
                    if (e.Completed % e.Load.ThroughputSize == 0)
                    {
                        AddLog(string.Format("current: {0} / {1}", e.Completed, load.LoadSize));
                    }
                };
                engine.Throughput += (s, e) =>
                {
                    AddLog("throughput:");
                    AddLog(string.Format("\tavg: {0} ms/hit, {1} hits/s", e.AvgTime, Math.Round(e.HitsPerSecond, 3)));
                    AddLog(string.Format("\ttotal: {0} KB, {1} KB/hit", e.TotalBytes.ToKB(), e.BytesPerHit.ToKB()));
                };

                var result = engine.Run();
                grandResults.Add(new KeyValuePair <Payload, LoadResult>(load, result));

                var report = new StringBuilder();
                report.AppendLine(string.Format("concurrent: {0}", load.ConcurrentSize));
                report.AppendLine(string.Format("started: {0}", result.StartedTime.ToString()));
                report.AppendLine(string.Format("finished: {0}", result.FinishedTime.ToString()));
                report.AppendLine(string.Format("elapsed: {0}", TimeSpan.FromMilliseconds(result.TotalTime)));
                report.AppendLine(string.Format("completed: {0}", result.Completed));
                report.AppendLine(string.Format("successful: {0}", result.Successful));
                report.AppendLine(string.Format("failed: {0}", result.Failed));
                report.AppendLine("hits:");
                report.AppendLine(string.Format("\tavg: {0} ms/hit, {1} hits/s", result.AvgTime, Math.Round(result.HitsPerSecond, 3)));
                report.AppendLine(string.Format("\tmin: {0} ms/hit, {1} hits/s", result.MinAvgTime, Math.Round(result.MinHitsPerSecond, 3)));
                report.AppendLine(string.Format("\tmax: {0} ms/hit, {1} hits/s", result.MaxAvgTime, Math.Round(result.MaxHitsPerSecond, 3)));
                report.AppendLine(string.Format("\ttotal: {0} KB, {1} KB/hit", result.TotalBytes.ToKB(), result.BytesPerHit.ToKB()));
                report.AppendLine("requests: ");
                var successfulRequests = result.Items.Sum(i => i.Requests.Count(r => r.IsSuccessful));
                var failedRequests     = result.Requests - successfulRequests;
                report.AppendLine(string.Format("\tcompleted: {0}, successful: {1}, failed: {2}", result.Requests, successfulRequests, failedRequests));
                report.AppendLine(string.Format("\tavg: {0} ms/request, {1} requests/s, {2} KB/request", result.AvgRequestTime, Math.Round(result.RequestPerSecond, 3), result.BytesPerRequest.ToKB()));
                report.AppendLine(new string('-', 50));

                AddLog(report.ToString());
            });

            grandReport = new StringBuilder();
            grandReport.AppendLine(string.Format("grand finished: {0}", DateTime.Now));
            var totalTime = grandResults.Sum(r => r.Value.TotalTime);

            grandReport.AppendLine(string.Format("grand elapsed: {0}", TimeSpan.FromMilliseconds(totalTime)));
            var grandCompleted = grandResults.Sum(r => r.Value.Completed);

            grandReport.AppendLine(string.Format("grand completed: {0}", grandCompleted));
            grandReport.AppendLine(string.Format("grand successful: {0}", grandResults.Sum(r => r.Value.Successful)));
            grandReport.AppendLine(string.Format("grand failed: {0}", grandResults.Sum(r => r.Value.Failed)));
            grandReport.AppendLine("grand hits:");
            var avgTime = grandResults.Average(r => r.Value.FinishedTime.Subtract(r.Value.StartedTime).TotalMilliseconds / r.Value.Completed);

            grandReport.AppendLine(string.Format("\tavg: {0} ms/hit, {1} hits/s", Math.Round(avgTime, 1), Math.Round(1000.0 / avgTime, 3)));

            var minAvgTime       = grandResults.Min(r => r.Value.MinAvgTime);
            var minHitsPerSecond = grandResults.Min(r => r.Value.MinHitsPerSecond);

            grandReport.AppendLine(string.Format("\tmin: {0} ms/hit, {1} hits/s", minAvgTime, Math.Round(minHitsPerSecond, 3)));

            var maxAvgTime       = grandResults.Max(r => r.Value.MaxAvgTime);
            var maxHitsPerSecond = grandResults.Max(r => r.Value.MaxHitsPerSecond);

            grandReport.AppendLine(string.Format("\tmax: {0} ms/hit, {1} hits/s", maxAvgTime, Math.Round(maxHitsPerSecond, 3)));

            var totalKB = grandResults.Sum(r => r.Value.TotalBytes / 1024);

            grandReport.AppendLine(string.Format("\ttotal: {0} KB, {1} KB/hit", totalKB, totalKB / grandCompleted));

            grandReport.AppendLine("grand requests:");
            var grandRequests           = grandResults.Sum(r => r.Value.Requests);
            var grandSuccessfulRequests = grandResults.Sum(r => r.Value.Items.Sum(i => i.Requests.Count(e => e.IsSuccessful)));
            var grandFailedRequests     = grandRequests - grandSuccessfulRequests;

            grandReport.AppendLine(string.Format("\tcompleted: {0}, successful: {1}, failed: {2}", grandRequests, grandSuccessfulRequests, grandFailedRequests));
            var grandAvgRequestTime = totalTime / grandRequests;

            grandReport.AppendLine(string.Format("\tavg: {0} ms/request, {1} requests/s, {2} KB/request", Math.Round(grandAvgRequestTime, 1), Math.Round(1000.0 / grandAvgRequestTime, 3), totalKB / grandRequests));

            grandReport.AppendLine(new string('-', 50));
            grandReport.AppendLine("Concurrent Users\tAvg Time(ms)/Hit\tHits/s\tTotal Througput(KB)\tAvg Throughput(KB)");
            grandResults.ForEach(r =>
            {
                grandReport.AppendLine(string.Format("{0}\t{1}\t{2}\t{3}\t{4}KB", r.Key.ConcurrentSize, r.Value.AvgTime, Math.Round(r.Value.HitsPerSecond, 3), r.Value.TotalBytes.ToKB(), r.Value.BytesPerHit.ToKB()));
            });

            AddLog(grandReport.ToString());
        }