Пример #1
0
        /// <summary>
        /// Invoked when a timeout occurs and we need to dump all of the test processes and shut down
        /// the runnner.
        /// </summary>
        private static async Task HandleTimeout(Options options, CancellationToken cancellationToken)
        {
            var procDumpFilePath = Path.Combine(options.ProcDumpPath, "procdump.exe");

            async Task DumpProcess(Process targetProcess, string dumpFilePath)
            {
                Console.Write($"Dumping {targetProcess.ProcessName} {targetProcess.Id} to {dumpFilePath} ... ");
                try
                {
                    var args          = $"-accepteula -ma {targetProcess.Id} {dumpFilePath}";
                    var processTask   = ProcessRunner.RunProcessAsync(procDumpFilePath, args, cancellationToken);
                    var processOutput = await processTask;

                    // The exit code for procdump doesn't obey standard windows rules.  It will return non-zero
                    // for succesful cases (possibly returning the count of dumps that were written).  Best
                    // backup is to test for the dump file being present.
                    if (File.Exists(dumpFilePath))
                    {
                        Console.WriteLine("succeeded");
                    }
                    else
                    {
                        Console.WriteLine($"FAILED with {processOutput.ExitCode}");
                        Console.WriteLine($"{procDumpFilePath} {args}");
                        Console.WriteLine(string.Join(Environment.NewLine, processOutput.OutputLines));
                    }
                }
                catch (Exception ex) when(!cancellationToken.IsCancellationRequested)
                {
                    Console.WriteLine("FAILED");
                    Console.WriteLine(ex.Message);
                    Logger.Log("Failed to dump process", ex);
                }
            }

            Console.WriteLine("Roslyn Error: test timeout exceeded, dumping remaining processes");
            if (!string.IsNullOrEmpty(options.ProcDumpPath))
            {
                var dumpDir = options.LogFilePath != null
                    ? Path.GetDirectoryName(options.LogFilePath)
                    : Directory.GetCurrentDirectory();

                Console.WriteLine($"Dump file location is {dumpDir}");

                var counter = 0;
                foreach (var proc in ProcessUtil.GetProcessTree(Process.GetCurrentProcess()).OrderBy(x => x.ProcessName))
                {
                    var dumpFilePath = Path.Combine(dumpDir, $"{proc.ProcessName}-{counter}.dmp");
                    await DumpProcess(proc, dumpFilePath);

                    counter++;
                }
            }
            else
            {
                Console.WriteLine("Could not locate procdump");
            }

            WriteLogFile(options);
        }
Пример #2
0
        private async Task <TestResult> RunTest(string assemblyPath, CancellationToken cancellationToken)
        {
            var assemblyName = Path.GetFileName(assemblyPath);
            var extension    = _useHtml ? ".TestResults.html" : ".TestResults.xml";
            var resultsPath  = Path.Combine(Path.GetDirectoryName(assemblyPath), Path.ChangeExtension(assemblyName, extension));

            DeleteFile(resultsPath);

            var builder = new StringBuilder();

            builder.AppendFormat(@"""{0}""", assemblyPath);
            builder.AppendFormat(@" -{0} ""{1}""", _useHtml ? "html" : "xml", resultsPath);
            builder.Append(" -noshadow");

            var errorOutput   = string.Empty;
            var start         = DateTime.UtcNow;
            var processOutput = await ProcessRunner.RunProcessAsync(
                _xunitConsolePath,
                builder.ToString(),
                lowPriority : false,
                displayWindow : false,
                captureOutput : true,
                cancellationToken : cancellationToken).ConfigureAwait(false);

            var span = DateTime.UtcNow - start;

            if (processOutput.ExitCode != 0)
            {
                // On occasion we get a non-0 output but no actual data in the result file.  Switch to output in this
                // case.
                var all = string.Empty;
                try
                {
                    all = File.ReadAllText(resultsPath).Trim();
                }
                catch
                {
                    // Happens if xunit didn't produce a log file
                }

                if (all.Length == 0)
                {
                    var output = processOutput.OutputLines.Concat(processOutput.ErrorLines).ToArray();
                    File.WriteAllLines(resultsPath, output);
                }

                errorOutput = processOutput.ErrorLines.Any()
                    ? processOutput.ErrorLines.Aggregate((x, y) => x + Environment.NewLine + y)
                    : string.Format("xunit produced no error output but had exit code {0}", processOutput.ExitCode);

                errorOutput = string.Format("Command: {0} {1}", _xunitConsolePath, builder.ToString())
                              + Environment.NewLine
                              + errorOutput;

                Process.Start(resultsPath);
            }

            return(new TestResult(processOutput.ExitCode == 0, assemblyName, span, errorOutput));
        }
Пример #3
0
        private async Task <TestResult> RunTest(string assemblyPath)
        {
            var assemblyName = Path.GetFileName(assemblyPath);
            var resultsPath  = Path.Combine(Path.GetDirectoryName(assemblyPath), Path.ChangeExtension(assemblyName, ".html"));
            var builder      = new StringBuilder();

            builder.AppendFormat(@"""{0}""", assemblyPath);
            builder.AppendFormat(@" -html ""{0}""", resultsPath);
            builder.Append(" -noshadow");

            var errorOutput   = string.Empty;
            var start         = DateTime.UtcNow;
            var processOutput = await ProcessRunner.RunProcessAsync(
                _xunitConsolePath,
                builder.ToString(),
                lowPriority : false,
                displayWindow : false,
                captureOutput : true,
                cancellationToken : CancellationToken.None).ConfigureAwait(false);

            var span = DateTime.UtcNow - start;

            if (processOutput.ExitCode != 0)
            {
                // On occasion we get a non-0 output but no actual data in the result file.  Switch to output in this
                // case.
                var all = File.ReadAllText(resultsPath).Trim();
                if (all.Length == 0)
                {
                    var output = processOutput.OutputLines.Concat(processOutput.ErrorLines).ToArray();
                    File.WriteAllLines(resultsPath, output);
                }

                errorOutput = processOutput.ErrorLines.Aggregate((x, y) => x + Environment.NewLine + y);
                Process.Start(resultsPath);
            }

            return(new TestResult(processOutput.ExitCode == 0, assemblyName, span, errorOutput));
        }
Пример #4
0
        public async Task <TestResult> RunTestAsync(string assemblyPath, CancellationToken cancellationToken)
        {
            try
            {
                var commandLineArguments = GetCommandLineArguments(assemblyPath);
                var resultsFilePath      = GetResultsFilePath(assemblyPath);
                var resultsDir           = Path.GetDirectoryName(resultsFilePath);

                // NOTE: xUnit doesn't always create the log directory
                Directory.CreateDirectory(resultsDir);

                // NOTE: xUnit seems to have an occasional issue creating logs create
                // an empty log just in case, so our runner will still fail.
                File.Create(resultsFilePath).Close();

                var start         = DateTime.UtcNow;
                var xunitPath     = _options.XunitPath;
                var processOutput = await ProcessRunner.RunProcessAsync(
                    xunitPath,
                    commandLineArguments,
                    lowPriority : false,
                    displayWindow : false,
                    captureOutput : true,
                    cancellationToken : cancellationToken).ConfigureAwait(false);

                var span = DateTime.UtcNow - start;

                if (processOutput.ExitCode != 0)
                {
                    // On occasion we get a non-0 output but no actual data in the result file.  The could happen
                    // if xunit manages to crash when running a unit test (a stack overflow could cause this, for instance).
                    // To avoid losing information, write the process output to the console.  In addition, delete the results
                    // file to avoid issues with any tool attempting to interpret the (potentially malformed) text.
                    var resultData = string.Empty;
                    try
                    {
                        resultData = File.ReadAllText(resultsFilePath).Trim();
                    }
                    catch
                    {
                        // Happens if xunit didn't produce a log file
                    }

                    if (resultData.Length == 0)
                    {
                        // Delete the output file.
                        File.Delete(resultsFilePath);
                        resultsFilePath = null;
                    }
                }

                var commandLine    = GetCommandLine(assemblyPath);
                var standardOutput = string.Join(Environment.NewLine, processOutput.OutputLines);
                var errorOutput    = string.Join(Environment.NewLine, processOutput.ErrorLines);

                return(new TestResult(
                           exitCode: processOutput.ExitCode,
                           assemblyPath: assemblyPath,
                           resultDir: resultsDir,
                           resultsFilePath: resultsFilePath,
                           commandLine: commandLine,
                           elapsed: span,
                           standardOutput: standardOutput,
                           errorOutput: errorOutput));
            }
            catch (Exception ex)
            {
                throw new Exception($"Unable to run {assemblyPath} with {_options.XunitPath}. {ex}");
            }
        }
Пример #5
0
        public async Task <TestResult> RunTestAsync(AssemblyInfo assemblyInfo, CancellationToken cancellationToken)
        {
            try
            {
                var commandLineArguments = GetCommandLineArguments(assemblyInfo);
                var resultsFilePath      = GetResultsFilePath(assemblyInfo);
                var resultsDir           = Path.GetDirectoryName(resultsFilePath);

                // NOTE: xUnit doesn't always create the log directory
                Directory.CreateDirectory(resultsDir);

                // NOTE: xUnit seems to have an occasional issue creating logs create
                // an empty log just in case, so our runner will still fail.
                File.Create(resultsFilePath).Close();

                // Define environment variables for processes started via ProcessRunner.
                var environmentVariables = new Dictionary <string, string>();
                _options.ProcDumpInfo?.WriteEnvironmentVariables(environmentVariables);

                // Attach procDump to processes when the are started so we can watch for
                // unexepected crashes.
                void onProcessStart(Process process)
                {
                    if (_options.ProcDumpInfo != null)
                    {
                        ProcDumpUtil.AttachProcDump(_options.ProcDumpInfo.Value, process.Id);
                    }
                }

                var start         = DateTime.UtcNow;
                var xunitPath     = _options.XunitPath;
                var processOutput = await ProcessRunner.RunProcessAsync(
                    xunitPath,
                    commandLineArguments,
                    lowPriority : false,
                    displayWindow : false,
                    captureOutput : true,
                    cancellationToken : cancellationToken,
                    environmentVariables : environmentVariables,
                    onProcessStartHandler : onProcessStart);

                var span = DateTime.UtcNow - start;

                if (processOutput.ExitCode != 0)
                {
                    // On occasion we get a non-0 output but no actual data in the result file.  The could happen
                    // if xunit manages to crash when running a unit test (a stack overflow could cause this, for instance).
                    // To avoid losing information, write the process output to the console.  In addition, delete the results
                    // file to avoid issues with any tool attempting to interpret the (potentially malformed) text.
                    var resultData = string.Empty;
                    try
                    {
                        resultData = File.ReadAllText(resultsFilePath).Trim();
                    }
                    catch
                    {
                        // Happens if xunit didn't produce a log file
                    }

                    if (resultData.Length == 0)
                    {
                        // Delete the output file.
                        File.Delete(resultsFilePath);
                        resultsFilePath = null;
                    }
                }

                var commandLine = GetCommandLine(assemblyInfo);
                Logger.Log($"Command line {assemblyInfo.DisplayName}: {commandLine}");
                var standardOutput = string.Join(Environment.NewLine, processOutput.OutputLines) ?? "";
                var errorOutput    = string.Join(Environment.NewLine, processOutput.ErrorLines) ?? "";
                var testResultInfo = new TestResultInfo(
                    exitCode: processOutput.ExitCode,
                    resultsDirectory: resultsDir,
                    resultsFilePath: resultsFilePath,
                    elapsed: span,
                    standardOutput: standardOutput,
                    errorOutput: errorOutput);

                return(new TestResult(
                           assemblyInfo,
                           testResultInfo,
                           commandLine,
                           isFromCache: false));
            }
            catch (Exception ex)
            {
                throw new Exception($"Unable to run {assemblyInfo.AssemblyPath} with {_options.XunitPath}. {ex}");
            }
        }
Пример #6
0
        public async Task <TestResult> RunTestAsync(string assemblyPath, CancellationToken cancellationToken)
        {
            try
            {
                var assemblyName    = Path.GetFileName(assemblyPath);
                var resultsDir      = Path.Combine(Path.GetDirectoryName(assemblyPath), Constants.ResultsDirectoryName);
                var resultsFilePath = Path.Combine(resultsDir, $"{assemblyName}.{(_options.UseHtml ? "html" : "xml")}");

                // NOTE: xUnit doesn't always create the log directory
                Directory.CreateDirectory(resultsDir);

                // NOTE: xUnit seems to have an occasional issue creating logs create
                // an empty log just in case, so our runner will still fail.
                File.Create(resultsFilePath).Close();

                var builder = new StringBuilder();
                builder.AppendFormat(@"""{0}""", assemblyPath);
                builder.AppendFormat(@" -{0} ""{1}""", _options.UseHtml ? "html" : "xml", resultsFilePath);
                builder.Append(" -noshadow -verbose");

                if (!string.IsNullOrWhiteSpace(_options.Trait))
                {
                    var traits = _options.Trait.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (var trait in traits)
                    {
                        builder.AppendFormat(" -trait {0}", trait);
                    }
                }

                if (!string.IsNullOrWhiteSpace(_options.NoTrait))
                {
                    var traits = _options.NoTrait.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (var trait in traits)
                    {
                        builder.AppendFormat(" -notrait {0}", trait);
                    }
                }

                var start = DateTime.UtcNow;

                var xunitPath     = _options.XunitPath;
                var processOutput = await ProcessRunner.RunProcessAsync(
                    xunitPath,
                    builder.ToString(),
                    lowPriority : false,
                    displayWindow : false,
                    captureOutput : true,
                    cancellationToken : cancellationToken).ConfigureAwait(false);

                var span = DateTime.UtcNow - start;

                if (processOutput.ExitCode != 0)
                {
                    // On occasion we get a non-0 output but no actual data in the result file.  The could happen
                    // if xunit manages to crash when running a unit test (a stack overflow could cause this, for instance).
                    // To avoid losing information, write the process output to the console.  In addition, delete the results
                    // file to avoid issues with any tool attempting to interpret the (potentially malformed) text.
                    var resultData = string.Empty;
                    try
                    {
                        resultData = File.ReadAllText(resultsFilePath).Trim();
                    }
                    catch
                    {
                        // Happens if xunit didn't produce a log file
                    }

                    if (resultData.Length == 0)
                    {
                        // Delete the output file.
                        File.Delete(resultsFilePath);
                        resultsFilePath = null;
                    }
                }

                var commandLine    = $"{xunitPath} {builder.ToString()}";
                var standardOutput = string.Join(Environment.NewLine, processOutput.OutputLines);
                var errorOutput    = string.Join(Environment.NewLine, processOutput.ErrorLines);

                return(new TestResult(
                           exitCode: processOutput.ExitCode,
                           assemblyPath: assemblyPath,
                           resultDir: resultsDir,
                           resultsFilePath: resultsFilePath,
                           commandLine: commandLine,
                           elapsed: span,
                           standardOutput: standardOutput,
                           errorOutput: errorOutput));
            }
            catch (Exception ex)
            {
                throw new Exception($"Unable to run {assemblyPath} with {_options.XunitPath}. {ex}");
            }
        }
Пример #7
0
        private async Task <TestResult> RunTest(string assemblyPath, CancellationToken cancellationToken)
        {
            try
            {
                var assemblyName  = Path.GetFileName(assemblyPath);
                var resultsFile   = Path.Combine(Path.GetDirectoryName(assemblyPath), "xUnitResults", $"{assemblyName}.{(_options.UseHtml ? "html" : "xml")}");
                var resultsDir    = Path.GetDirectoryName(resultsFile);
                var outputLogPath = Path.Combine(resultsDir, $"{assemblyName}.out.log");

                // NOTE: xUnit doesn't always create the log directory
                Directory.CreateDirectory(resultsDir);

                // NOTE: xUnit seems to have an occasional issue creating logs create
                // an empty log just in case, so our runner will still fail.
                File.Create(resultsFile).Close();

                var builder = new StringBuilder();
                builder.AppendFormat(@"""{0}""", assemblyPath);
                builder.AppendFormat(@" -{0} ""{1}""", _options.UseHtml ? "html" : "xml", resultsFile);
                builder.Append(" -noshadow -verbose");

                if (!string.IsNullOrWhiteSpace(_options.Trait))
                {
                    var traits = _options.Trait.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (var trait in traits)
                    {
                        builder.AppendFormat(" -trait {0}", trait);
                    }
                }

                if (!string.IsNullOrWhiteSpace(_options.NoTrait))
                {
                    var traits = _options.NoTrait.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (var trait in traits)
                    {
                        builder.AppendFormat(" -notrait {0}", trait);
                    }
                }

                var errorOutput = new StringBuilder();
                var start       = DateTime.UtcNow;

                var xunitPath     = _options.XunitPath;
                var processOutput = await ProcessRunner.RunProcessAsync(
                    xunitPath,
                    builder.ToString(),
                    lowPriority : false,
                    displayWindow : false,
                    captureOutput : true,
                    cancellationToken : cancellationToken).ConfigureAwait(false);

                var span = DateTime.UtcNow - start;

                if (processOutput.ExitCode != 0)
                {
                    File.WriteAllLines(outputLogPath, processOutput.OutputLines);

                    // On occasion we get a non-0 output but no actual data in the result file.  The could happen
                    // if xunit manages to crash when running a unit test (a stack overflow could cause this, for instance).
                    // To avoid losing information, write the process output to the console.  In addition, delete the results
                    // file to avoid issues with any tool attempting to interpret the (potentially malformed) text.
                    var resultData = string.Empty;
                    try
                    {
                        resultData = File.ReadAllText(resultsFile).Trim();
                    }
                    catch
                    {
                        // Happens if xunit didn't produce a log file
                    }

                    if (resultData.Length == 0)
                    {
                        // Delete the output file.
                        File.Delete(resultsFile);
                    }

                    errorOutput.AppendLine($"Command: {_options.XunitPath} {builder}");
                    errorOutput.AppendLine($"xUnit output: {outputLogPath}");

                    if (processOutput.ErrorLines.Any())
                    {
                        foreach (var line in processOutput.ErrorLines)
                        {
                            errorOutput.AppendLine(line);
                        }
                    }
                    else
                    {
                        errorOutput.AppendLine($"xunit produced no error output but had exit code {processOutput.ExitCode}");
                    }

                    // If the results are html, use Process.Start to open in the browser.

                    if (_options.UseHtml && resultData.Length > 0)
                    {
                        Process.Start(resultsFile);
                    }
                }

                return(new TestResult(processOutput.ExitCode == 0, assemblyName, span, errorOutput.ToString()));
            }
            catch (Exception ex)
            {
                throw new Exception($"Unable to run {assemblyPath} with {_options.XunitPath}. {ex}");
            }
        }
Пример #8
0
        private async Task <TestResult> RunTest(string assemblyPath, CancellationToken cancellationToken)
        {
            var assemblyName = Path.GetFileName(assemblyPath);
            var extension    = _useHtml ? ".TestResults.html" : ".TestResults.xml";
            var resultsPath  = Path.Combine(Path.GetDirectoryName(assemblyPath), Path.ChangeExtension(assemblyName, extension));

            DeleteFile(resultsPath);

            var builder = new StringBuilder();

            builder.AppendFormat(@"""{0}""", assemblyPath);
            builder.AppendFormat(@" -{0} ""{1}""", _useHtml ? "html" : "xml", resultsPath);
            builder.Append(" -noshadow");

            var errorOutput   = string.Empty;
            var start         = DateTime.UtcNow;
            var processOutput = await ProcessRunner.RunProcessAsync(
                _xunitConsolePath,
                builder.ToString(),
                lowPriority : false,
                displayWindow : false,
                captureOutput : true,
                cancellationToken : cancellationToken).ConfigureAwait(false);

            var span = DateTime.UtcNow - start;

            if (processOutput.ExitCode != 0)
            {
                // On occasion we get a non-0 output but no actual data in the result file.  The could happen
                // if xunit manages to crash when running a unit test (a stack overflow could cause this, for instance).
                // To avoid losing information, write the process output to the console.  In addition, delete the results
                // file to avoid issues with any tool attempting to interpret the (potentially malformed) text.
                var all = string.Empty;
                try
                {
                    all = File.ReadAllText(resultsPath).Trim();
                }
                catch
                {
                    // Happens if xunit didn't produce a log file
                }

                bool noResultsData = (all.Length == 0);
                if (noResultsData)
                {
                    var output = processOutput.OutputLines.Concat(processOutput.ErrorLines).ToArray();
                    Console.Write(output);

                    // Delete the output file.
                    File.Delete(resultsPath);
                }

                errorOutput = processOutput.ErrorLines.Any()
                    ? processOutput.ErrorLines.Aggregate((x, y) => x + Environment.NewLine + y)
                    : string.Format("xunit produced no error output but had exit code {0}", processOutput.ExitCode);

                errorOutput = string.Format("Command: {0} {1}", _xunitConsolePath, builder.ToString())
                              + Environment.NewLine
                              + errorOutput;

                // If the results are html, use Process.Start to open in the browser.

                if (_useHtml && !noResultsData)
                {
                    Process.Start(resultsPath);
                }
            }

            return(new TestResult(processOutput.ExitCode == 0, assemblyName, span, errorOutput));
        }