Beispiel #1
0
        public async static Task Main(string[] args)
        {
            int durationInHours = 72;

            if (args.Length == 0)
            {
                args = new[] { "./.env" };
            }

            if (args.Length == 1)
            {
                args = ArgumentFileReader.Read(args[0])?.ToArray() ?? Array.Empty <string>();
            }

            if (args.Length < 2)
            {
                Console.WriteLine("There should be at least 2 arguments: connection string and event hub name.");
                return;
            }

            string connectionString = args[0];
            string eventHubName     = args[1];

            Console.WriteLine($"Using connection string: '{ connectionString }'");
            Console.WriteLine($"Using event hub name: '{ eventHubName }'");

            if (args.Length > 2 && Int32.TryParse(args[2], out var result))
            {
                durationInHours = result;
            }

            var test = new StressTest();
            await test.Run(connectionString, eventHubName, TimeSpan.FromHours(durationInHours));
        }
        public static async Task Main(string[] args)
        {
            if (args.Length == 0)
            {
                args = new[] { "./.env" };
            }

            if (args.Length == 1)
            {
                args = ArgumentFileReader.Read(args[0])?.ToArray() ?? Array.Empty <string>();
            }

            var runArgs      = ParseAndPromptForArguments(args);
            var runDuration  = DefaultRunDuration;
            var errorLogPath = DefaultErrorLogPath;

            // If not provided or malformed, use the default.

            if ((!string.IsNullOrEmpty(runArgs.RunDurationHours)) && (int.TryParse(runArgs.RunDurationHours, out var hours)))
            {
                runDuration = TimeSpan.FromHours(hours);
            }

            if (!string.IsNullOrEmpty(runArgs.LogPath))
            {
                errorLogPath = runArgs.LogPath;
            }

            using var cancellationSource = new CancellationTokenSource();
            using var errorWriter        = new StreamWriter(File.Open(errorLogPath, FileMode.Create, FileAccess.Write, FileShare.Read));
            using var metricsWriter      = Console.Out;
            using var azureEventListener = ListenForEventSourceErrors(errorWriter);

            try
            {
                var message = $"{ Environment.NewLine }{ Environment.NewLine }=============================={ Environment.NewLine }  Run Starting{ Environment.NewLine }=============================={ Environment.NewLine }";
                metricsWriter.WriteLine(message);
                errorWriter.WriteLine(message);

                cancellationSource.CancelAfter(runDuration);

                var testRun = new TestRun(new TestConfiguration
                {
                    EventHubsConnectionString = runArgs.EventHubsConnectionString,
                    EventHub = runArgs.EventHub,
                    StorageConnectionString = runArgs.StorageConnectionString,
                    BlobContainer           = runArgs.BlobContainer
                });

                var testRunTask = testRun.Start(cancellationSource.Token);

                // Make an initial metrics report now that the run is taking place.

                await(Task.Delay(TimeSpan.FromSeconds(1)));
                await ReportMetricsAsync(metricsWriter, testRun.Metrics, runDuration);

                // Allow the run to take place, periodically reporting.

                while (!cancellationSource.IsCancellationRequested)
                {
                    try
                    {
                        await Task.Delay(DefaultProcessReportInterval, cancellationSource.Token);
                    }
                    catch (TaskCanceledException)
                    {
                        message = $"{ Environment.NewLine }{ Environment.NewLine }------------------------------------------------------------{ Environment.NewLine }  The run is ending.  Waiting for clean-up and final reporting...{ Environment.NewLine }------------------------------------------------------------";
                        metricsWriter.WriteLine(message);
                        errorWriter.WriteLine(message);
                    }

                    await Task.WhenAll
                    (
                        ReportMetricsAsync(metricsWriter, testRun.Metrics, runDuration),
                        ReportErrorsAsync(errorWriter, testRun.ErrorsObserved)
                    );
                }

                // Allow the run to complete and then perform a final pas on reporting
                // to ensure that any straggling operations are captures.

                await testRunTask;
                Interlocked.Exchange(ref testRun.Metrics.RunDurationMilliseconds, runDuration.TotalMilliseconds);

                await Task.WhenAll
                (
                    ReportMetricsAsync(metricsWriter, testRun.Metrics, runDuration),
                    ReportErrorsAsync(errorWriter, testRun.ErrorsObserved)
                );

                message = $"{ Environment.NewLine }{ Environment.NewLine }=============================={ Environment.NewLine }  Run Complete{ Environment.NewLine }==============================";
                metricsWriter.WriteLine(message);
                errorWriter.WriteLine(message);
            }
            catch (Exception ex) when
                (ex is OutOfMemoryException ||
                ex is StackOverflowException ||
                ex is ThreadAbortException)
            {
                Environment.FailFast(ex.Message);
            }
            catch (Exception ex)
            {
                var message = $"{ Environment.NewLine }{ Environment.NewLine }=============================={ Environment.NewLine }  Error in the main loop.  Run aborting.  Message: [{ ex.Message }]{ Environment.NewLine }==============================";
                metricsWriter.WriteLine(message);
                errorWriter.WriteLine(message);
            }
            finally
            {
                errorWriter.Close();
            }
        }