diff --git a/test/E2E/E2ETest.xproj b/test/E2E/E2ETest.xproj new file mode 100644 index 000000000..4115d2b19 --- /dev/null +++ b/test/E2E/E2ETest.xproj @@ -0,0 +1,19 @@ + + + + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + 386d412c-003c-47b1-8258-0e35865cb7c4 + E2ETest + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin\$(MSBuildProjectName)\ + + + 2.0 + + + + \ No newline at end of file diff --git a/test/E2E/E2ETest.cs b/test/E2E/EndToEndTest.cs similarity index 61% rename from test/E2E/E2ETest.cs rename to test/E2E/EndToEndTest.cs index ea102e8bb..dd0e2464d 100644 --- a/test/E2E/E2ETest.cs +++ b/test/E2E/EndToEndTest.cs @@ -9,157 +9,128 @@ using System.Text; using Xunit; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.ProjectModel; +using Microsoft.DotNet.Tools.Test.Utilities; -namespace ConsoleApplication +namespace Microsoft.DotNet.Tests.EndToEnd { - public class E2ETest + public class EndToEndTest : TestBase { - private static readonly string EXPECTED_OUTPUT = "Hello World!" + Environment.NewLine; - private static readonly string TESTDIR_NAME = "hellotest"; - private static readonly string OUTPUTDIR_NAME = "testbin"; - - private static string RootPath { get; set; } - private string TestDirectory { get; set; } - private string OutputDirectory { get; set; } + private static readonly string s_expectedOutput = "Hello World!" + Environment.NewLine; + private static readonly string s_testdirName = "e2etestroot"; + private static readonly string s_outputdirName = "testbin"; + private string Rid { get; set; } + private string TestDirectory { get; set; } + private string TestProject { get; set; } + private string OutputDirectory { get; set; } public static void Main() { Console.WriteLine("Dummy Entrypoint."); } - public E2ETest() + public EndToEndTest() { - if (RootPath == null) - { - RootPath = Directory.GetCurrentDirectory(); - } - - TestDirectory = Path.Combine(RootPath, TESTDIR_NAME); - OutputDirectory = Path.Combine(RootPath, OUTPUTDIR_NAME); + TestSetup(); Rid = RuntimeIdentifier.Current; } [Fact] - public void TestDotnetCompile() + public void TestDotnetBuild() { - TestSetup(); + var buildCommand = new BuildCommand(TestProject, output: OutputDirectory); - TestRunCommand("dotnet", $"build -o {OutputDirectory}"); - TestOutputExecutable(OutputDirectory); + buildCommand.Execute().Should().Pass(); + + TestOutputExecutable(OutputDirectory, buildCommand.GetOutputExecutableName()); } [Fact] - public void TestDotnetCompileNativeRyuJit() + [ActiveIssue(712, PlatformID.Windows | PlatformID.OSX | PlatformID.Linux)] + public void TestDotnetBuildNativeRyuJit() { - if(SkipForOS(OSPlatform.Linux, "https://github.com/dotnet/cli/issues/527")) - { - return; - } + var buildCommand = new BuildCommand(TestProject, output: OutputDirectory, native: true); - TestSetup(); - - TestRunCommand("dotnet", $"build --native -o {OutputDirectory}"); + buildCommand.Execute().Should().Pass(); var nativeOut = Path.Combine(OutputDirectory, "native"); - TestOutputExecutable(nativeOut); + TestOutputExecutable(nativeOut, buildCommand.GetOutputExecutableName()); } [Fact] - public void TestDotnetCompileNativeCpp() + public void TestDotnetBuildNativeCpp() { - TestSetup(); + var buildCommand = new BuildCommand(TestProject, output: OutputDirectory, native: true, nativeCppMode: true); + + buildCommand.Execute().Should().Pass(); - TestRunCommand("dotnet", $"build --native --cpp -o {OutputDirectory}"); - var nativeOut = Path.Combine(OutputDirectory, "native"); - TestOutputExecutable(nativeOut); + TestOutputExecutable(nativeOut, buildCommand.GetOutputExecutableName()); } [Fact] public void TestDotnetRun() { - TestSetup(); + var runCommand = new RunCommand(TestProject); - TestRunCommand("dotnet", $"run"); + runCommand.Execute() + .Should() + .Pass(); } [Fact] public void TestDotnetPack() { - TestSetup(); + var packCommand = new PackCommand(TestDirectory, output: OutputDirectory); - TestRunCommand("dotnet", $"pack"); + packCommand.Execute() + .Should() + .Pass(); } [Fact] public void TestDotnetPublish() { - TestSetup(); + var publishCommand = new PublishCommand(TestProject, output: OutputDirectory); + publishCommand.Execute().Should().Pass(); - TestRunCommand("dotnet", $"publish --framework dnxcore50 --runtime {Rid} -o {OutputDirectory}"); - TestOutputExecutable(OutputDirectory); + TestOutputExecutable(OutputDirectory, publishCommand.GetOutputExecutable()); } private void TestSetup() { - Directory.SetCurrentDirectory(RootPath); + var root = Temp.CreateDirectory(); - CleanOrCreateDirectory(TestDirectory); - CleanOrCreateDirectory(OutputDirectory); + TestDirectory = root.CreateDirectory(s_testdirName).Path; + TestProject = Path.Combine(TestDirectory, "project.json"); + OutputDirectory = Path.Combine(TestDirectory, s_outputdirName); + InitializeTestDirectory(); + } + + private void InitializeTestDirectory() + { + var currentDirectory = Directory.GetCurrentDirectory(); Directory.SetCurrentDirectory(TestDirectory); - TestRunCommand("dotnet", "new"); - TestRunCommand("dotnet", "restore --quiet"); + new NewCommand().Execute().Should().Pass(); + new RestoreCommand().Execute("--quiet").Should().Pass(); + + Directory.SetCurrentDirectory(currentDirectory); } - private bool SkipForOS(OSPlatform os, string reason) + private void TestOutputExecutable(string outputDir, string executableName) { - if (RuntimeInformation.IsOSPlatform(os)) - { - Console.WriteLine("Skipping Test for reason: " + reason); - return true; - } - return false; - } - - private void TestRunCommand(string command, string args) - { - var result = Command.Create(command, args) - .ForwardStdErr() - .ForwardStdOut() - .Execute(); - - Assert.Equal(0, result.ExitCode); - } - - private void TestOutputExecutable(string outputDir) - { - var executableName = TESTDIR_NAME + Constants.ExeSuffix; - var executablePath = Path.Combine(outputDir, executableName); - var result = Command.Create(executablePath, "") - .CaptureStdErr() - .CaptureStdOut() - .Execute(); + var executableCommand = new TestCommand(executablePath); - var outText = result.StdOut; - var errText = result.StdErr; - - Assert.Equal("", errText); - Assert.Equal(EXPECTED_OUTPUT, outText); - } + var result = executableCommand.ExecuteWithCapturedOutput(""); - private void CleanOrCreateDirectory(string path) - { - if (Directory.Exists(path)) - { - Directory.Delete(path, true); - } - Directory.CreateDirectory(path); + result.Should().HaveStdOut(s_expectedOutput); + result.Should().NotHaveStdErr(); + result.Should().Pass(); } } } diff --git a/test/E2E/project.json b/test/E2E/project.json index c9614b23d..12710ea75 100644 --- a/test/E2E/project.json +++ b/test/E2E/project.json @@ -9,13 +9,13 @@ "xunit": "2.1.0", "xunit.console.netcore": "1.0.2-prerelease-00101", + "xunit.netcore.extensions": "1.0.0-prerelease-*", "xunit.runner.utility": "2.1.0", "Microsoft.DotNet.ProjectModel": { "target": "project" }, - "Microsoft.DotNet.Cli.Utils": { - "type": "build", - "version": "1.0.0-*" - }, + "Microsoft.DotNet.Cli.Utils": { "target": "project" }, + + "Microsoft.DotNet.Tools.Tests.Utilities": { "target": "project" } }, "frameworks": { diff --git a/test/Microsoft.DotNet.Tools.Tests.Utilities/Assertions/CommandResultAssertions.cs b/test/Microsoft.DotNet.Tools.Tests.Utilities/Assertions/CommandResultAssertions.cs index aa2508146..dd2864419 100644 --- a/test/Microsoft.DotNet.Tools.Tests.Utilities/Assertions/CommandResultAssertions.cs +++ b/test/Microsoft.DotNet.Tools.Tests.Utilities/Assertions/CommandResultAssertions.cs @@ -48,6 +48,13 @@ namespace Microsoft.DotNet.Tools.Test.Utilities return new AndConstraint(this); } + public AndConstraint HaveStdOut(string expectedOutput) + { + Execute.Assertion.ForCondition(_commandResult.StdOut.Equals(expectedOutput, StringComparison.Ordinal)) + .FailWith($"Command did not output with Expected Output. Expected: {expectedOutput} Actual: {_commandResult.StdOut}"); + return new AndConstraint(this); + } + public AndConstraint HaveStdErr() { Execute.Assertion.ForCondition(!string.IsNullOrEmpty(_commandResult.StdErr)) diff --git a/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/BuildCommand.cs b/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/BuildCommand.cs new file mode 100644 index 000000000..3a6b1da3c --- /dev/null +++ b/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/BuildCommand.cs @@ -0,0 +1,189 @@ +// 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. + +using System; +using Microsoft.DotNet.Cli.Utils; +using System.Runtime.InteropServices; +using Microsoft.DotNet.ProjectModel; + +namespace Microsoft.DotNet.Tools.Test.Utilities +{ + public sealed class BuildCommand : TestCommand + { + private Project _project; + private string _projectPath; + private string _outputDirectory; + private string _tempOutputDirectory; + private string _configuration; + private bool _noHost; + private bool _native; + private string _architecture; + private string _ilcArgs; + private string _ilcPath; + private string _appDepSDKPath; + private bool _nativeCppMode; + private string _cppCompilerFlags; + + private string OutputOption + { + get + { + return _outputDirectory == string.Empty ? + "" : + $"-o {_outputDirectory}"; + } + } + + private string TempOutputOption + { + get + { + return _tempOutputDirectory == string.Empty ? + "" : + $"-t {_tempOutputDirectory}"; + } + } + + private string ConfigurationOption + { + get + { + return _configuration == string.Empty ? + "" : + $"-c {_configuration}"; + } + } + + private string NoHostOption + { + get + { + return _noHost ? + "--no-host" : + ""; + } + } + + private string NativeOption + { + get + { + return _native ? + "--native" : + ""; + } + } + + private string ArchitectureOption + { + get + { + return _architecture == string.Empty ? + "" : + $"--arch {_architecture}"; + } + } + + private string IlcArgsOption + { + get + { + return _ilcArgs == string.Empty ? + "" : + $"--ilcargs {_ilcArgs}"; + } + } + + private string IlcPathOption + { + get + { + return _ilcPath == string.Empty ? + "" : + $"--ilcpath {_ilcPath}"; + } + } + + private string AppDepSDKPathOption + { + get + { + return _appDepSDKPath == string.Empty ? + "" : + $"--appdepsdkpath {_appDepSDKPath}"; + } + } + + private string NativeCppModeOption + { + get + { + return _nativeCppMode ? + "--cpp" : + ""; + } + } + + private string CppCompilerFlagsOption + { + get + { + return _cppCompilerFlags == string.Empty ? + "" : + $"--cppcompilerflags {_cppCompilerFlags}"; + } + } + + public BuildCommand( + string projectPath, + string output="", + string tempOutput="", + string configuration="", + bool noHost=false, + bool native=false, + string architecture="", + string ilcArgs="", + string ilcPath="", + string appDepSDKPath="", + bool nativeCppMode=false, + string cppCompilerFlags="" + ) + : base("dotnet") + { + + _projectPath = projectPath; + _project = ProjectReader.GetProject(projectPath); + + _outputDirectory = output; + _tempOutputDirectory = tempOutput; + _configuration = configuration; + _noHost = noHost; + _native = native; + _architecture = architecture; + _ilcArgs = ilcArgs; + _ilcPath = ilcPath; + _appDepSDKPath = appDepSDKPath; + _nativeCppMode = nativeCppMode; + _cppCompilerFlags = cppCompilerFlags; + + } + + public override CommandResult Execute(string args = "") + { + args = $"build {BuildArgs()} {args}"; + return base.Execute(args); + } + + public string GetOutputExecutableName() + { + var result = _project.Name; + result += RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : ""; + return result; + } + + private string BuildArgs() + { + return $"{_projectPath} {OutputOption} {TempOutputOption} {ConfigurationOption} {NoHostOption} {NativeOption} {ArchitectureOption} {IlcArgsOption} {IlcPathOption} {AppDepSDKPathOption} {NativeCppModeOption} {CppCompilerFlagsOption}"; + } + } +} diff --git a/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/NewCommand.cs b/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/NewCommand.cs new file mode 100644 index 000000000..35bb30ccd --- /dev/null +++ b/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/NewCommand.cs @@ -0,0 +1,22 @@ +// 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. + +using Microsoft.DotNet.Cli.Utils; + +namespace Microsoft.DotNet.Tools.Test.Utilities +{ + public sealed class NewCommand : TestCommand + { + public NewCommand() + : base("dotnet") + { + + } + + public override CommandResult Execute(string args = "") + { + args = $"new {args}"; + return base.Execute(args); + } + } +} diff --git a/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/PackCommand.cs b/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/PackCommand.cs new file mode 100644 index 000000000..2bb9007b7 --- /dev/null +++ b/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/PackCommand.cs @@ -0,0 +1,83 @@ +// 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. + +using System; +using Microsoft.DotNet.Cli.Utils; + +namespace Microsoft.DotNet.Tools.Test.Utilities +{ + public sealed class PackCommand : TestCommand + { + private string _projectPath; + private string _outputDirectory; + private string _tempOutputDirectory; + private string _configuration; + private string _versionSuffix; + + private string OutputOption + { + get + { + return _outputDirectory == string.Empty ? + "" : + $"-o {_outputDirectory}"; + } + } + + private string TempOutputOption + { + get + { + return _tempOutputDirectory == string.Empty ? + "" : + $"-t {_tempOutputDirectory}"; + } + } + + private string ConfigurationOption + { + get + { + return _configuration == string.Empty ? + "" : + $"-c {_configuration}"; + } + } + + private string VersionSuffixOption + { + get + { + return _versionSuffix == string.Empty ? + "" : + $"--version-suffix {_versionSuffix}"; + } + } + + public PackCommand( + string projectPath, + string output="", + string tempOutput="", + string configuration="", + string versionSuffix="") + : base("dotnet") + { + _projectPath = projectPath; + _outputDirectory = output; + _tempOutputDirectory = tempOutput; + _configuration = configuration; + _versionSuffix = versionSuffix; + } + + public override CommandResult Execute(string args = "") + { + args = $"pack {BuildArgs()} {args}"; + return base.Execute(args); + } + + private string BuildArgs() + { + return $"{_projectPath} {OutputOption} {TempOutputOption} {ConfigurationOption} {VersionSuffixOption}"; + } + } +} diff --git a/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/PublishCommand.cs b/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/PublishCommand.cs index 90cdd5310..089583a79 100644 --- a/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/PublishCommand.cs +++ b/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/PublishCommand.cs @@ -11,7 +11,7 @@ using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.ProjectModel; using Microsoft.DotNet.Tools.Test.Utilities; -namespace Microsoft.DotNet.Tools.Publish.Tests +namespace Microsoft.DotNet.Tools.Test.Utilities { public sealed class PublishCommand : TestCommand { diff --git a/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/RestoreCommand.cs b/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/RestoreCommand.cs index 00aa96d09..03b62d448 100644 --- a/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/RestoreCommand.cs +++ b/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/RestoreCommand.cs @@ -2,9 +2,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using Microsoft.DotNet.Cli.Utils; -using Microsoft.DotNet.Tools.Test.Utilities; -namespace Microsoft.DotNet.Tools.Publish.Tests +namespace Microsoft.DotNet.Tools.Test.Utilities { public sealed class RestoreCommand : TestCommand { diff --git a/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/RunCommand.cs b/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/RunCommand.cs new file mode 100644 index 000000000..e67f30534 --- /dev/null +++ b/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/RunCommand.cs @@ -0,0 +1,87 @@ +// 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. + +using Microsoft.DotNet.Cli.Utils; + +namespace Microsoft.DotNet.Tools.Test.Utilities +{ + public sealed class RunCommand : TestCommand + { + private string _projectPath; + private string _framework; + private string _configuration; + private bool _preserveTemporary; + private string _appArgs; + + private string ProjectPathOption + { + get + { + return _projectPath == string.Empty ? + "" : + $"-p {_projectPath}"; + } + } + + private string FrameworkOption + { + get + { + return _framework == string.Empty ? + "" : + $"-f {_framework}"; + } + } + + private string ConfigurationOption + { + get + { + return _configuration == string.Empty ? + "" : + $"-c {_configuration}"; + } + } + + private string PreserveTemporaryOption + { + get + { + return _preserveTemporary ? + $"-t {_projectPath}" : + ""; + } + } + + private string AppArgsArgument + { + get { return _appArgs; } + } + + public RunCommand( + string projectPath, + string framework="", + string configuration="", + bool preserveTemporary=false, + string appArgs="") + : base("dotnet") + { + _projectPath = projectPath; + _framework = framework; + _configuration = configuration; + _preserveTemporary = preserveTemporary; + _appArgs = appArgs; + } + + public override CommandResult Execute(string args = "") + { + args = $"run {BuildArgs()} {args}"; + return base.Execute(args); + } + + private string BuildArgs() + { + return $"{ProjectPathOption} {FrameworkOption} {ConfigurationOption} {PreserveTemporaryOption} {AppArgsArgument}"; + } + } +} diff --git a/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/TestCommand.cs b/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/TestCommand.cs index c0b3a9cc4..60a00d76e 100644 --- a/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/TestCommand.cs +++ b/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/TestCommand.cs @@ -26,5 +26,16 @@ namespace Microsoft.DotNet.Tools.Test.Utilities return commandResult; } + + public virtual CommandResult ExecuteWithCapturedOutput(string args) + { + Console.WriteLine($"Executing (Captured Output) - {_command} {args}"); + var commandResult = Command.Create(_command, args) + .CaptureStdErr() + .CaptureStdOut() + .Execute(); + + return commandResult; + } } }