Maintain test artifacts

Improved test diagnostics
Providing diagnostics about failed process.
Workaround for https://github.com/NuGet/Home/issues/1977
get past crossgen errors!
This commit is contained in:
piotrp 2016-01-24 01:04:39 -08:00
parent 066bebcc6c
commit a66546d8fb
24 changed files with 81 additions and 49 deletions

View file

@ -3,4 +3,7 @@
REM Copyright (c) .NET Foundation and contributors. All rights reserved. REM Copyright (c) .NET Foundation and contributors. All rights reserved.
REM Licensed under the MIT license. See LICENSE file in the project root for full license information. REM Licensed under the MIT license. See LICENSE file in the project root for full license information.
REM Crossgen Workaround
set ComPlus_ReadyToRun=0
powershell -NoProfile -NoLogo -Command "%~dp0scripts\build\build.ps1 %*; exit $LastExitCode;" powershell -NoProfile -NoLogo -Command "%~dp0scripts\build\build.ps1 %*; exit $LastExitCode;"

View file

@ -7,7 +7,7 @@
$Rid = "win7-x64" $Rid = "win7-x64"
$Tfm = "dnxcore50" $Tfm = "dnxcore50"
$RepoRoot = Convert-Path "$PSScriptRoot\..\.." $RepoRoot = Resolve-Path "$PSScriptRoot\..\.."
$OutputDir = "$RepoRoot\artifacts\$Rid" $OutputDir = "$RepoRoot\artifacts\$Rid"
$DnxDir = "$OutputDir\dnx" $DnxDir = "$OutputDir\dnx"
$DnxRoot = "$DnxDir\bin" $DnxRoot = "$DnxDir\bin"
@ -19,6 +19,8 @@ $HostDir = "$OutputDir\corehost"
$PackageDir = "$RepoRoot\artifacts\packages\dnvm" $PackageDir = "$RepoRoot\artifacts\packages\dnvm"
$env:ReleaseSuffix = "beta" $env:ReleaseSuffix = "beta"
$env:Channel = "$env:ReleaseSuffix" $env:Channel = "$env:ReleaseSuffix"
$env:TEST_ROOT = "$OutputDir\tests"
$env:TEST_ARTIFACTS = "$env:TEST_ROOT\artifacts"
# Set reasonable defaults for unset variables # Set reasonable defaults for unset variables
setEnvIfDefault "DOTNET_INSTALL_DIR" "$(Convert-Path "$PSScriptRoot\..")\.dotnet_stage0\win7-x64" setEnvIfDefault "DOTNET_INSTALL_DIR" "$(Convert-Path "$PSScriptRoot\..")\.dotnet_stage0\win7-x64"

View file

@ -103,6 +103,7 @@ namespace Microsoft.DotNet.Cli.Utils
#endif #endif
return new CommandResult( return new CommandResult(
this._process.StartInfo,
exitCode, exitCode,
_stdOut.GetCapturedOutput(), _stdOut.GetCapturedOutput(),
_stdErr.GetCapturedOutput()); _stdErr.GetCapturedOutput());

View file

@ -1,18 +1,22 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved. // Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information. // Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System.Diagnostics;
namespace Microsoft.DotNet.Cli.Utils namespace Microsoft.DotNet.Cli.Utils
{ {
public struct CommandResult public struct CommandResult
{ {
public static readonly CommandResult Empty = new CommandResult(); public static readonly CommandResult Empty = new CommandResult();
public ProcessStartInfo StartInfo { get; }
public int ExitCode { get; } public int ExitCode { get; }
public string StdOut { get; } public string StdOut { get; }
public string StdErr { get; } public string StdErr { get; }
public CommandResult(int exitCode, string stdOut, string stdErr) public CommandResult(ProcessStartInfo startInfo, int exitCode, string stdOut, string stdErr)
{ {
StartInfo = startInfo;
ExitCode = exitCode; ExitCode = exitCode;
StdOut = stdOut; StdOut = stdOut;
StdErr = stdErr; StdErr = stdErr;

View file

@ -5,7 +5,7 @@
"emitEntryPoint": true "emitEntryPoint": true
}, },
"dependencies": { "dependencies": {
"Microsoft.NETCore.Platforms": "1.0.1-rc2-23704", "NETStandard.Library": "1.0.0-rc3-23722",
"Microsoft.DotNet.AppDep":"1.0.4-*" "Microsoft.DotNet.AppDep":"1.0.4-*"
}, },
"frameworks": { "frameworks": {

View file

@ -303,7 +303,7 @@ namespace Microsoft.DotNet.Tools.Compiler
}; };
RunScripts(context, ScriptNames.PreCompile, contextVariables); RunScripts(context, ScriptNames.PreCompile, contextVariables);
var result = Command.Create($"dotnet-compile-{compilerName}", new string[] {"@" + $"{rsp}" }) var result = Command.Create($"dotnet-compile-{compilerName}", new [] {"@" + $"{rsp}" })
.OnErrorLine(line => .OnErrorLine(line =>
{ {
var diagnostic = ParseDiagnostic(context.ProjectDirectory, line); var diagnostic = ParseDiagnostic(context.ProjectDirectory, line);
@ -335,6 +335,11 @@ namespace Microsoft.DotNet.Tools.Compiler
var success = result.ExitCode == 0; var success = result.ExitCode == 0;
if (!success)
{
Reporter.Error.WriteLine($"{result.StartInfo.FileName} {result.StartInfo.Arguments} returned Exit Code {result.ExitCode}");
}
if (success) if (success)
{ {
success &= GenerateCultureResourceAssemblies(context.ProjectFile, dependencies, outputPath); success &= GenerateCultureResourceAssemblies(context.ProjectFile, dependencies, outputPath);

View file

@ -5,7 +5,7 @@
}, },
"dependencies": { "dependencies": {
"NETStandard.Library": "1.0.0-rc2-23704" "NETStandard.Library": "1.0.0-rc3-23722"
}, },
"frameworks": { "frameworks": {

View file

@ -15,7 +15,7 @@
} }
}, },
"compileExclude": [ "CSharp_Console/**", "FSharp_Console/**" ], "compileExclude": [ "CSharp_Console/**", "FSharp_Console/**" ],
"resource": [ "CSharp_Console/**", "FSharp_Console/**" ], "resource": [ "CSharp_Console/NuGet.Config", "CSharp_Console/Program.cs", "CSharp_Console/project.json", "FSharp_Console/NuGet.config, "FSharp_Console/Program.fs", "FSharp_Console/project.json"],
"frameworks": { "frameworks": {
"dnxcore50": { "dnxcore50": {
"imports": "portable-net451+win8" "imports": "portable-net451+win8"

View file

@ -13,7 +13,7 @@
"Newtonsoft.Json": "7.0.1", "Newtonsoft.Json": "7.0.1",
"Microsoft.DotNet.ProjectModel": "1.0.0-*", "Microsoft.DotNet.ProjectModel": "1.0.0-*",
"Microsoft.Extensions.Logging.Abstractions": "1.0.0-rc2-15935", "Microsoft.Extensions.Logging.Abstractions": "1.0.0-rc2-15935",
"NETStandard.Library": "1.0.0-rc2-23704", "NETStandard.Library": "1.0.0-rc3-23722",
"System.Resources.ResourceManager": "4.0.1-rc3-23722", "System.Resources.ResourceManager": "4.0.1-rc3-23722",
"System.Runtime.Serialization.Primitives": "4.1.0-rc3-23722" "System.Runtime.Serialization.Primitives": "4.1.0-rc3-23722"
}, },

View file

@ -5,8 +5,8 @@
}, },
"dependencies": { "dependencies": {
"NETStandard.Library" : "1.0.0-rc2-23714", "NETStandard.Library" : "1.0.0-rc3-23722",
"Microsoft.NETCore.TestHost": "1.0.0-rc2-23714", "Microsoft.NETCore.TestHost": "1.0.0-rc3-23722",
"xunit": "2.1.0", "xunit": "2.1.0",
"xunit.console.netcore": "1.0.2-prerelease-00101", "xunit.console.netcore": "1.0.2-prerelease-00101",
@ -19,6 +19,8 @@
}, },
"frameworks": { "frameworks": {
"dnxcore50": { } "dnxcore50": {
"imports": "portable-net451+win8"
}
} }
} }

View file

@ -5,8 +5,8 @@
}, },
"dependencies": { "dependencies": {
"NETStandard.Library" : "1.0.0-rc2-23706", "NETStandard.Library" : "1.0.0-rc3-23722",
"Microsoft.NETCore.TestHost": "1.0.0-rc2-23706", "Microsoft.NETCore.TestHost": "1.0.0-rc3-23722",
"xunit": "2.1.0", "xunit": "2.1.0",
"xunit.console.netcore": "1.0.2-prerelease-00101", "xunit.console.netcore": "1.0.2-prerelease-00101",
@ -19,6 +19,8 @@
}, },
"frameworks": { "frameworks": {
"dnxcore50": { } "dnxcore50": {
"imports": "portable-net451+win8"
}
} }
} }

View file

@ -4,7 +4,6 @@
"dependencies": { "dependencies": {
"NETStandard.Library": "1.0.0-rc3-23722", "NETStandard.Library": "1.0.0-rc3-23722",
"Microsoft.NETCore.TestHost": "1.0.0-rc2-*", "Microsoft.NETCore.TestHost": "1.0.0-rc2-*",
"System.Text.RegularExpressions": "4.0.11-*",
"xunit": "2.1.0", "xunit": "2.1.0",
"xunit.console.netcore": "1.0.2-prerelease-00101", "xunit.console.netcore": "1.0.2-prerelease-00101",

View file

@ -21,64 +21,74 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
public AndConstraint<CommandResultAssertions> ExitWith(int expectedExitCode) public AndConstraint<CommandResultAssertions> ExitWith(int expectedExitCode)
{ {
Execute.Assertion.ForCondition(_commandResult.ExitCode == expectedExitCode) Execute.Assertion.ForCondition(_commandResult.ExitCode == expectedExitCode)
.FailWith("Expected command to exit with {0} but it exited with {1}.", expectedExitCode, _commandResult.ExitCode); .FailWith(AppendDiagnosticsTo($"Expected command to exit with {expectedExitCode} but it did not."));
return new AndConstraint<CommandResultAssertions>(this); return new AndConstraint<CommandResultAssertions>(this);
} }
public AndConstraint<CommandResultAssertions> Pass() public AndConstraint<CommandResultAssertions> Pass()
{ {
Execute.Assertion.ForCondition(_commandResult.ExitCode == 0) Execute.Assertion.ForCondition(_commandResult.ExitCode == 0)
.FailWith("Expected command to pass but it exited with {0}.", _commandResult.ExitCode); .FailWith(AppendDiagnosticsTo($"Expected command to pass but it did not."));
return new AndConstraint<CommandResultAssertions>(this); return new AndConstraint<CommandResultAssertions>(this);
} }
public AndConstraint<CommandResultAssertions> Fail() public AndConstraint<CommandResultAssertions> Fail()
{ {
Execute.Assertion.ForCondition(_commandResult.ExitCode != 0) Execute.Assertion.ForCondition(_commandResult.ExitCode != 0)
.FailWith("Expected command to fail but it exited with {0}.", _commandResult.ExitCode); .FailWith(AppendDiagnosticsTo($"Expected command to fail but it did not."));
return new AndConstraint<CommandResultAssertions>(this); return new AndConstraint<CommandResultAssertions>(this);
} }
public AndConstraint<CommandResultAssertions> HaveStdOut() public AndConstraint<CommandResultAssertions> HaveStdOut()
{ {
Execute.Assertion.ForCondition(!string.IsNullOrEmpty(_commandResult.StdOut)) Execute.Assertion.ForCondition(!string.IsNullOrEmpty(_commandResult.StdOut))
.FailWith("Command did not output anything to stdout"); .FailWith(AppendDiagnosticsTo("Command did not output anything to stdout"));
return new AndConstraint<CommandResultAssertions>(this); return new AndConstraint<CommandResultAssertions>(this);
} }
public AndConstraint<CommandResultAssertions> HaveStdOut(string expectedOutput) public AndConstraint<CommandResultAssertions> HaveStdOut(string expectedOutput)
{ {
Execute.Assertion.ForCondition(_commandResult.StdOut.Equals(expectedOutput, StringComparison.Ordinal)) Execute.Assertion.ForCondition(_commandResult.StdOut.Equals(expectedOutput, StringComparison.Ordinal))
.FailWith($"Command did not output with Expected Output. Expected: {expectedOutput} Actual: {_commandResult.StdOut}"); .FailWith(AppendDiagnosticsTo($"Command did not output with Expected Output. Expected: {expectedOutput}"));
return new AndConstraint<CommandResultAssertions>(this); return new AndConstraint<CommandResultAssertions>(this);
} }
public AndConstraint<CommandResultAssertions> StdOutMatchPattern(string pattern, RegexOptions options = RegexOptions.None) public AndConstraint<CommandResultAssertions> StdOutMatchPattern(string pattern, RegexOptions options = RegexOptions.None)
{ {
Execute.Assertion.ForCondition(Regex.Match(_commandResult.StdOut, pattern, options).Success) Execute.Assertion.ForCondition(Regex.Match(_commandResult.StdOut, pattern, options).Success)
.FailWith($"Matching the command output failed. Pattern: {pattern}{Environment.NewLine} input: {_commandResult.StdOut}"); .FailWith(AppendDiagnosticsTo($"Matching the command output failed. Pattern: {pattern}{Environment.NewLine}"));
return new AndConstraint<CommandResultAssertions>(this); return new AndConstraint<CommandResultAssertions>(this);
} }
public AndConstraint<CommandResultAssertions> HaveStdErr() public AndConstraint<CommandResultAssertions> HaveStdErr()
{ {
Execute.Assertion.ForCondition(!string.IsNullOrEmpty(_commandResult.StdErr)) Execute.Assertion.ForCondition(!string.IsNullOrEmpty(_commandResult.StdErr))
.FailWith("Command did not output anything to stderr"); .FailWith(AppendDiagnosticsTo("Command did not output anything to stderr."));
return new AndConstraint<CommandResultAssertions>(this); return new AndConstraint<CommandResultAssertions>(this);
} }
public AndConstraint<CommandResultAssertions> NotHaveStdOut() public AndConstraint<CommandResultAssertions> NotHaveStdOut()
{ {
Execute.Assertion.ForCondition(string.IsNullOrEmpty(_commandResult.StdOut)) Execute.Assertion.ForCondition(string.IsNullOrEmpty(_commandResult.StdOut))
.FailWith("Expected command to not output to stdout but found - {0}{1}", Environment.NewLine, _commandResult.StdOut); .FailWith(AppendDiagnosticsTo($"Expected command to not output to stdout but it was not:"));
return new AndConstraint<CommandResultAssertions>(this); return new AndConstraint<CommandResultAssertions>(this);
} }
public AndConstraint<CommandResultAssertions> NotHaveStdErr() public AndConstraint<CommandResultAssertions> NotHaveStdErr()
{ {
Execute.Assertion.ForCondition(string.IsNullOrEmpty(_commandResult.StdErr)) Execute.Assertion.ForCondition(string.IsNullOrEmpty(_commandResult.StdErr))
.FailWith("Expected command to not output to stderr but found - {0}{1}", Environment.NewLine, _commandResult.StdErr); .FailWith(AppendDiagnosticsTo("Expected command to not output to stderr but it was not:"));
return new AndConstraint<CommandResultAssertions>(this); return new AndConstraint<CommandResultAssertions>(this);
} }
private string AppendDiagnosticsTo(string s)
{
return s + $"{Environment.NewLine}" +
$"File Name: {_commandResult.StartInfo.FileName}{Environment.NewLine}" +
$"Arguments: {_commandResult.StartInfo.Arguments}{Environment.NewLine}" +
$"Exit Code: {_commandResult.ExitCode}{Environment.NewLine}" +
$"StdOut:{Environment.NewLine}{_commandResult.StdOut}{Environment.NewLine}" +
$"StdErr:{Environment.NewLine}{_commandResult.StdErr}{Environment.NewLine}"; ;
}
} }
} }

View file

@ -80,6 +80,7 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
threadErr.Join(); threadErr.Join();
var result = new CommandResult( var result = new CommandResult(
process.StartInfo,
process.ExitCode, process.ExitCode,
stdOut.GetCapturedOutput(), stdOut.GetCapturedOutput(),
stdErr.GetCapturedOutput()); stdErr.GetCapturedOutput());

View file

@ -10,22 +10,34 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
{ {
public sealed class TempRoot : IDisposable public sealed class TempRoot : IDisposable
{ {
private static readonly bool DoDispose;
private readonly List<IDisposable> _temps = new List<IDisposable>(); private readonly List<IDisposable> _temps = new List<IDisposable>();
public static readonly string Root; public static readonly string Root;
static TempRoot() static TempRoot()
{ {
Root = Path.Combine(Path.GetTempPath(), "DotnetCLITests"); var persistedRoot = Environment.GetEnvironmentVariable("TEST_ARTIFACTS");
if (string.IsNullOrWhiteSpace(persistedRoot))
{
Root = Path.Combine(Path.GetTempPath(), "DotnetCLITests");
DoDispose = true;
}
else
{
Root = persistedRoot;
DoDispose = false;
}
Directory.CreateDirectory(Root); Directory.CreateDirectory(Root);
} }
public void Dispose() public void Dispose()
{ {
if (_temps != null) if (!DoDispose || _temps == null) return;
{
DisposeAll(_temps); DisposeAll(_temps);
_temps.Clear(); _temps.Clear();
}
} }
private static void DisposeAll(IEnumerable<IDisposable> temps) private static void DisposeAll(IEnumerable<IDisposable> temps)
@ -34,10 +46,7 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
{ {
try try
{ {
if (temp != null) temp?.Dispose();
{
temp.Dispose();
}
} }
catch catch
{ {

View file

@ -3,14 +3,8 @@
"description": "Microsoft.DotNet.Tools.Tests.Utilities Class Library", "description": "Microsoft.DotNet.Tools.Tests.Utilities Class Library",
"dependencies": { "dependencies": {
"System.Collections": "4.0.11-rc3-23722", "NETStandard.Library": "1.0.0-rc3-23722",
"System.Collections.Immutable": "1.2.0-rc3-23722", "System.Collections.Immutable": "1.2.0-rc3-23722",
"System.Linq": "4.0.1-rc3-23722",
"System.Threading": "4.0.11-rc3-23722",
"System.IO.FileSystem": "4.0.1-rc3-23722",
"System.IO": "4.0.11-rc3-23722",
"System.Runtime.InteropServices": "4.0.21-rc3-23722",
"System.Text.RegularExpressions": "4.0.11-rc3-23722",
"FluentAssertions": "4.0.0", "FluentAssertions": "4.0.0",
"xunit": "2.1.0", "xunit": "2.1.0",

View file

@ -3,7 +3,7 @@
"testRunner": "xunit", "testRunner": "xunit",
"dependencies": { "dependencies": {
"Microsoft.Extensions.DependencyModel": "1.0.0-*", "Microsoft.Extensions.DependencyModel": "1.0.0-*",
"Newtonsoft.Json": "6.0.0", "Newtonsoft.Json": "6.0.0"
}, },
"frameworks": { "frameworks": {
@ -11,7 +11,7 @@
"dnxcore50": { "dnxcore50": {
"imports" : "portable-net45+wp80+win8", "imports" : "portable-net45+wp80+win8",
"dependencies": { "dependencies": {
"NETStandard.Library": "1.0.0-rc2-23704" "NETStandard.Library": "1.0.0-rc3-23722"
} }
} }
} }

View file

@ -8,7 +8,7 @@
"L11": "1.0.0-*", "L11": "1.0.0-*",
"L12": "1.0.0-*", "L12": "1.0.0-*",
"NETStandard.Library": "1.0.0-rc2-23704" "NETStandard.Library": "1.0.0-rc3-23722"
}, },
"frameworks": { "frameworks": {

View file

@ -5,7 +5,7 @@
"L12": "1.0.0-*", "L12": "1.0.0-*",
"L21": "1.0.0-*", "L21": "1.0.0-*",
"NETStandard.Library": "1.0.0-rc2-23704" "NETStandard.Library": "1.0.0-rc3-23722"
}, },
"frameworks": { "frameworks": {

View file

@ -4,7 +4,7 @@
"dependencies": { "dependencies": {
"L22": "1.0.0-*", "L22": "1.0.0-*",
"NETStandard.Library": "1.0.0-rc2-23704" "NETStandard.Library": "1.0.0-rc3-23722"
}, },
"frameworks": { "frameworks": {

View file

@ -2,7 +2,7 @@
"version": "1.0.0-*", "version": "1.0.0-*",
"dependencies": { "dependencies": {
"NETStandard.Library": "1.0.0-rc2-23704" "NETStandard.Library": "1.0.0-rc3-23722"
}, },
"frameworks": { "frameworks": {

View file

@ -2,7 +2,7 @@
"version": "1.0.0-*", "version": "1.0.0-*",
"dependencies": { "dependencies": {
"NETStandard.Library": "1.0.0-rc2-23704" "NETStandard.Library": "1.0.0-rc3-23722"
}, },
"frameworks": { "frameworks": {

View file

@ -3,7 +3,7 @@
"frameworks": { "frameworks": {
"dnxcore50": { "dnxcore50": {
"dependencies": { "dependencies": {
"NETStandard.Library": "1.0.0-rc2-23704", "NETStandard.Library": "1.0.0-rc3-23722",
} }
}, },
"dnx451": { } "dnx451": { }

View file

@ -6,7 +6,7 @@
}, },
"dependencies": { "dependencies": {
"NETStandard.Library": "1.0.0-rc2-23704", "NETStandard.Library": "1.0.0-rc3-23722",
"Microsoft.DotNet.ProjectModel": "1.0.0-*", "Microsoft.DotNet.ProjectModel": "1.0.0-*",
"Microsoft.DotNet.Cli.Utils": "1.0.0-*" "Microsoft.DotNet.Cli.Utils": "1.0.0-*"
}, },