<commit_before>﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading;

namespace LoadTestToolbox
{
    public class Program
    {
        public static void Main(string[] args)
        {
            if (args.Length != 5)
            {
                showUsage();
                return;
            }

            var tool = args[0].ToLower();
            var outputFileName = args[4];

            var results = getResults(tool, args);

            if (results == null)
            {
                showUsage();
                return;
            }

            var visualizer = new Visualizer(Environment.GetEnvironmentVariable("VISUALIZER_FILES") ?? ".");
            var output = new FileStream(outputFileName, FileMode.OpenOrCreate, FileAccess.Write);
            visualizer.SaveChart(results, output);
        }

        private static IDictionary<int, double> getResults(string tool, string[] args)
        {
            var url = new Uri(args[1], UriKind.Absolute);
            switch (tool)
            {
                case "hammer":
                    {
                        var min = Convert.ToInt32(args[2]);
                        var max = Convert.ToInt32(args[3]);

                        return getHammerResults(min, max, url);
                    }
                case "drill":
                    {
                        var requestsPerSecond = Convert.ToInt32(args[2]);
                        var duration = Convert.ToInt32(args[3]);

                        return getDrillResults(requestsPerSecond, duration, url);
                    }
                default:
                    return null;
            }
        }

        private static void showUsage()
        {
            Console.WriteLine("Usage:");
            Console.WriteLine("dotnet run drill {site} {req/sec} {duration} {graph output filename}");
            Console.WriteLine("or");
            Console.WriteLine("Usage: dotnet run hammer {site} {min hammers} {max hammers} {graph output filename}");
        }

        private static IDictionary<int, double> getHammerResults(int min, int max, Uri url)
        {
            var hammers = HardwareStore.GetHammers(min, max);

            var results = new Dictionary<int, double>();
            foreach (var x in hammers)
            {
                var hammer = new Hammer(new HttpClient(), url, x);
                new Thread(hammer.Run).Start();
                while (!hammer.Complete())
                    Thread.Sleep(100);

                results.Add(x, hammer.Average);
                Console.WriteLine(x + ": " + Math.Round(hammer.Average, 2) + " ms");
            }
            return results;
        }

        private static IDictionary<int, double> getDrillResults(int requestsPerSecond, int duration, Uri url)
        {
            var delay = TimeSpan.TicksPerSecond / requestsPerSecond;
            var totalRequests = requestsPerSecond * duration;

            var started = DateTime.UtcNow;
            var previewed = 0;

            var drill = new Drill(new HttpClient(), url, totalRequests, delay);
            new Thread(drill.Run).Start();

            while (!drill.Complete())
            {
                if (DateTime.UtcNow.Subtract(started).Seconds > previewed && drill.Results.Any())
                {
                    var lastSecondOfResults = drill.Results.Reverse().Take(requestsPerSecond);
                    var average = lastSecondOfResults.Average();
                    Console.WriteLine(++previewed + ": " + Math.Round(average, 2) + " ms");
                }
                Thread.Sleep(100);
            }

            var index = 0;
            var results = drill.Results.ToDictionary(r => ++index, r => r);
            return results;
        }
    }
}<commit_msg>Added formatting function in the console response to print with the corresponding unit This function checks if the value is less than 1 ms and if so outputs mu or ms in the console<commit_after>﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading;

namespace LoadTestToolbox
{
    public class Program
    {
        public static void Main(string[] args)
        {
            if (args.Length != 5)
            {
                showUsage();
                return;
            }

            var tool = args[0].ToLower();
            var outputFileName = args[4];

            var results = getResults(tool, args);

            if (results == null)
            {
                showUsage();
                return;
            }

            var visualizer = new Visualizer(Environment.GetEnvironmentVariable("VISUALIZER_FILES") ?? ".");
            var output = new FileStream(outputFileName, FileMode.OpenOrCreate, FileAccess.Write);
            visualizer.SaveChart(results, output);
        }

        private static IDictionary<int, double> getResults(string tool, string[] args)
        {
            var url = new Uri(args[1], UriKind.Absolute);
            switch (tool)
            {
                case "hammer":
                    {
                        var min = Convert.ToInt32(args[2]);
                        var max = Convert.ToInt32(args[3]);

                        return getHammerResults(min, max, url);
                    }
                case "drill":
                    {
                        var requestsPerSecond = Convert.ToInt32(args[2]);
                        var duration = Convert.ToInt32(args[3]);

                        return getDrillResults(requestsPerSecond, duration, url);
                    }
                default:
                    return null;
            }
        }

        private static void showUsage()
        {
            Console.WriteLine("Usage:");
            Console.WriteLine("dotnet run drill {site} {req/sec} {duration} {graph output filename}");
            Console.WriteLine("or");
            Console.WriteLine("Usage: dotnet run hammer {site} {min hammers} {max hammers} {graph output filename}");
        }

        private static IDictionary<int, double> getHammerResults(int min, int max, Uri url)
        {
            var hammers = HardwareStore.GetHammers(min, max);

            var results = new Dictionary<int, double>();
            foreach (var x in hammers)
            {
                var hammer = new Hammer(new HttpClient(), url, x);
                new Thread(hammer.Run).Start();
                while (!hammer.Complete())
                    Thread.Sleep(100);

                results.Add(x, hammer.Average);
                FormatTimeAndPrintInConsole(x, hammer.Average);
                //Console.WriteLine(x + ": " + Math.Round(hammer.Average, 2) + " ms");
            }
            return results;
        }

        /// <summary>
        /// This function checks if the value is less than 1 ms and if so outputs mu or ms in the console
        /// </summary>
        private static Action<int, double> FormatTimeAndPrintInConsole = (iteration, averageTime) =>
        {
            var roundedOff = Math.Round(averageTime, 2);
            Console.OutputEncoding = System.Text.Encoding.Unicode;

            string response = $"{iteration} : ";

            if (roundedOff < 1)
                response += $"{roundedOff} \u03BC{"s"}";
            else
                response += $"{roundedOff} ms";

            Console.WriteLine(response);
        };

        private static IDictionary<int, double> getDrillResults(int requestsPerSecond, int duration, Uri url)
        {
            var delay = TimeSpan.TicksPerSecond / requestsPerSecond;
            var totalRequests = requestsPerSecond * duration;

            var started = DateTime.UtcNow;
            var previewed = 0;

            var drill = new Drill(new HttpClient(), url, totalRequests, delay);
            new Thread(drill.Run).Start();

            while (!drill.Complete())
            {
                if (DateTime.UtcNow.Subtract(started).Seconds > previewed && drill.Results.Any())
                {
                    var lastSecondOfResults = drill.Results.Reverse().Take(requestsPerSecond);
                    var average = lastSecondOfResults.Average();
                    FormatTimeAndPrintInConsole(++previewed, average);
                    //Console.WriteLine(++previewed + ": " + Math.Round(average, 2) + " ms");
                }
                Thread.Sleep(100);
            }

            var index = 0;
            var results = drill.Results.ToDictionary(r => ++index, r => r);
            return results;
        }
    }
}
{'fraction_non_alphanumeric': 0.10227666705188952, 'fraction_numerical': 0.006702877614700104, 'mean_word_length': 1.546042953809944, 'pattern_counts': {'":': 8, '<': 15, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6836492', 'n_tokens_mistral': 2267, 'n_tokens_neox': 2075, 'n_words': 545}