public static DotNetCliCommandResult Execute(DotNetCliCommand parameters)
        {
            using (var process = new Process {
                StartInfo = BuildStartInfo(parameters.CliPath, parameters.GenerateResult.ArtifactsPaths.BuildArtifactsDirectoryPath, parameters.Arguments, parameters.EnvironmentVariables)
            })
                using (var outputReader = new AsyncProcessOutputReader(process, parameters.LogOutput, parameters.Logger))
                    using (new ConsoleExitHandler(process, parameters.Logger))
                    {
                        parameters.Logger.WriteLineInfo($"// start {parameters.CliPath ?? "dotnet"} {parameters.Arguments} in {parameters.GenerateResult.ArtifactsPaths.BuildArtifactsDirectoryPath}");

                        var stopwatch = Stopwatch.StartNew();

                        process.Start();
                        outputReader.BeginRead();

                        if (!process.WaitForExit((int)parameters.Timeout.TotalMilliseconds))
                        {
                            parameters.Logger.WriteLineError($"// command took longer than the timeout: {parameters.Timeout.TotalSeconds:0.##}s. Killing the process tree!");

                            outputReader.CancelRead();
                            process.KillTree();

                            return(DotNetCliCommandResult.Failure(stopwatch.Elapsed, $"The configured timeout {parameters.Timeout} was reached!" + outputReader.GetErrorText(), outputReader.GetOutputText()));
                        }

                        stopwatch.Stop();
                        outputReader.StopRead();

                        parameters.Logger.WriteLineInfo($"// command took {stopwatch.Elapsed.TotalSeconds:0.##}s and exited with {process.ExitCode}");

                        return(process.ExitCode <= 0
                    ? DotNetCliCommandResult.Success(stopwatch.Elapsed, outputReader.GetOutputText())
                    : DotNetCliCommandResult.Failure(stopwatch.Elapsed, outputReader.GetOutputText(), outputReader.GetErrorText()));
                    }
        }
Пример #2
0
        public IEnumerable <string> ExportToFiles(Summary summary, ILogger consoleLogger)
        {
            const string scriptFileName = "BuildPlots.R";
            const string logFileName    = "BuildPlots.log";

            yield return(Path.Combine(summary.ResultsDirectoryPath, scriptFileName));

            string csvFullPath    = CsvMeasurementsExporter.Default.GetArtifactFullName(summary);
            string scriptFullPath = Path.Combine(summary.ResultsDirectoryPath, scriptFileName);
            string logFullPath    = Path.Combine(summary.ResultsDirectoryPath, logFileName);
            string script         = ResourceHelper.
                                    LoadTemplate(scriptFileName).
                                    Replace("$BenchmarkDotNetVersion$", BenchmarkDotNetInfo.FullTitle).
                                    Replace("$CsvSeparator$", CsvMeasurementsExporter.Default.Separator);

            lock (BuildScriptLock)
                File.WriteAllText(scriptFullPath, script);

            if (!TryFindRScript(consoleLogger, out string rscriptPath))
            {
                yield break;
            }

            var start = new ProcessStartInfo
            {
                UseShellExecute        = false,
                RedirectStandardOutput = true,
                RedirectStandardError  = true,
                CreateNoWindow         = true,
                FileName         = rscriptPath,
                WorkingDirectory = summary.ResultsDirectoryPath,
                Arguments        = $"\"{scriptFullPath}\" \"{csvFullPath}\""
            };

            using (var process = new Process {
                StartInfo = start
            })
                using (AsyncProcessOutputReader reader = new AsyncProcessOutputReader(process))
                {
                    // When large R scripts are generated then ran, ReadToEnd()
                    // causes the stdout and stderr buffers to become full,
                    // which causes R to hang. To avoid this, use
                    // AsyncProcessOutputReader to cache the log contents
                    // then write to disk rather than Process.Standard*.ReadToEnd().
                    process.Start();
                    reader.BeginRead();
                    process.WaitForExit();
                    reader.StopRead();
                    File.WriteAllLines(logFullPath, reader.GetOutputLines());
                    File.AppendAllLines(logFullPath, reader.GetErrorLines());
                }

            yield return(Path.Combine(summary.ResultsDirectoryPath, $"*{ImageExtension}"));
        }
Пример #3
0
        internal static (int exitCode, ImmutableArray <string> output) RunAndReadOutputLineByLine(string fileName, string arguments = "", string workingDirectory             = "",
                                                                                                  Dictionary <string, string> environmentVariables = null, bool includeErrors = false, ILogger logger = null)
        {
            var processStartInfo = new ProcessStartInfo
            {
                FileName               = fileName,
                WorkingDirectory       = workingDirectory,
                Arguments              = arguments,
                UseShellExecute        = false,
                CreateNoWindow         = true,
                RedirectStandardOutput = true,
                RedirectStandardError  = true
            };

            if (environmentVariables != null)
            {
                foreach (var environmentVariable in environmentVariables)
                {
                    processStartInfo.Environment[environmentVariable.Key] = environmentVariable.Value;
                }
            }

            using (var process = new Process {
                StartInfo = processStartInfo
            })
                using (var outputReader = new AsyncProcessOutputReader(process))
                    using (new ConsoleExitHandler(process, logger ?? NullLogger.Instance))
                    {
                        process.Start();

                        outputReader.BeginRead();

                        process.WaitForExit();

                        outputReader.StopRead();

                        var output = includeErrors ? outputReader.GetOutputAndErrorLines() : outputReader.GetOutputLines();

                        return(process.ExitCode, output);
                    }
        }