diff --git a/scripts/compile.ps1 b/scripts/compile.ps1 index bf40d967f..a3e6e91ff 100644 --- a/scripts/compile.ps1 +++ b/scripts/compile.ps1 @@ -132,7 +132,6 @@ Download it from https://www.cmake.org Exit 1 } - # Smoke test stage2 $env:DOTNET_HOME = "$Stage2Dir" & "$PSScriptRoot\test\smoke-test.ps1" @@ -141,6 +140,13 @@ Download it from https://www.cmake.org Exit 1 } + # E2E Test of stage2 + & "$PSScriptRoot\test\e2e-test.ps1" + if (!$?) { + Write-Host "Command failed: $PSScriptRoot\test\e2e-test.ps1" + Exit 1 + } + } finally { $env:PATH = $StartPath $env:DOTNET_HOME = $StartDotNetHome diff --git a/scripts/compile.sh b/scripts/compile.sh index 1ca402213..3c7a05761 100755 --- a/scripts/compile.sh +++ b/scripts/compile.sh @@ -117,3 +117,7 @@ echo $COMMIT_ID > $STAGE2_DIR/.commit # Smoke-test the output header "Testing stage2 ..." DOTNET_HOME=$STAGE2_DIR DOTNET_TOOLS=$STAGE2_DIR $DIR/test/smoke-test.sh + +# E2E test on the output +header "Testing stage2 End to End ..." +DOTNET_HOME=$STAGE2_DIR DOTNET_TOOLS=$STAGE2_DIR $DIR/test/e2e-test.sh diff --git a/scripts/test/e2e-test.ps1 b/scripts/test/e2e-test.ps1 new file mode 100644 index 000000000..aa6503004 --- /dev/null +++ b/scripts/test/e2e-test.ps1 @@ -0,0 +1,44 @@ +# +# 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. +# + +. "$PSScriptRoot\..\_common.ps1" + +# Restore and compile the test app +dotnet restore "$RepoRoot\test\E2E" --runtime "osx.10.10-x64" --runtime "ubuntu.14.04-x64" --runtime "win7-x64" +if (!$?) { + Write-Host "Command failed: dotnet restore" + Exit 1 +} + +dotnet publish --framework dnxcore50 --runtime "$Rid" --output "$RepoRoot\artifacts\$Rid\e2etest" "$RepoRoot\test\E2E" +if (!$?) { + Write-Host "Command failed: dotnet publish" + Exit 1 +} + +## Temporary Workaround for Native Compilation +## Need x64 Native Tools Dev Prompt Env Vars +## Tracked Here: https://github.com/dotnet/cli/issues/301 +pushd "$env:VS140COMNTOOLS\..\..\VC" +cmd /c "vcvarsall.bat x64&set" | +foreach { + if ($_ -match "=") { + $v = $_.split("="); set-item -force -path "ENV:\$($v[0])" -value "$($v[1])" + } +} +popd + +# Run the app and check the exit code +pushd "$RepoRoot\artifacts\$Rid\e2etest" +mv E2E.exe corehost.exe +& "corehost.exe" "xunit.console.netcore.exe" "E2E.dll" -xml ..\..\e2etest.xml +if (!$?) { + Write-Host "E2E Test Failure" + popd + Exit 1 +} +else { + popd +} diff --git a/scripts/test/e2e-test.sh b/scripts/test/e2e-test.sh new file mode 100755 index 000000000..b5dc8d295 --- /dev/null +++ b/scripts/test/e2e-test.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# +# 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. +# + +set -e + +SOURCE="${BASH_SOURCE[0]}" +while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink + DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" + SOURCE="$(readlink "$SOURCE")" + [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located +done +DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" +REPOROOT="$( cd -P "$DIR/../.." && pwd )" + +source "$DIR/../_common.sh" + +rm "$REPOROOT/test/E2E/project.lock.json" +dotnet restore "$REPOROOT/test/E2E" --runtime "osx.10.10-x64" --runtime "ubuntu.14.04-x64" --runtime "win7-x64" +dotnet publish --framework dnxcore50 --runtime "$RID" --output "$REPOROOT/artifacts/$RID/e2etest" "$REPOROOT/test/E2E" + +# set -e will abort if the exit code of this is non-zero +pushd "$REPOROOT/artifacts/$RID/e2etest" +mv ./E2E ./corehost +./corehost xunit.console.netcore.exe E2E.dll +popd diff --git a/src/Microsoft.DotNet.Cli.Utils/AnsiConsole.cs b/src/Microsoft.DotNet.Cli.Utils/AnsiConsole.cs index c47e877d1..513d548d9 100644 --- a/src/Microsoft.DotNet.Cli.Utils/AnsiConsole.cs +++ b/src/Microsoft.DotNet.Cli.Utils/AnsiConsole.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; diff --git a/test/E2E/E2ETest.cs b/test/E2E/E2ETest.cs new file mode 100644 index 000000000..e6f3beb5c --- /dev/null +++ b/test/E2E/E2ETest.cs @@ -0,0 +1,167 @@ +// 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 System.IO; +using System.Runtime.InteropServices; +using Xunit; +using Microsoft.DotNet.Cli.Utils; +using Microsoft.DotNet.ProjectModel; + +namespace ConsoleApplication +{ + public class E2ETest + { + 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 string Rid { get; set; } + + public static void Main() + { + Console.WriteLine("Dummy Entrypoint."); + } + + public E2ETest() + { + if (RootPath == null) + { + RootPath = Directory.GetCurrentDirectory(); + } + + TestDirectory = Path.Combine(RootPath, TESTDIR_NAME); + OutputDirectory = Path.Combine(RootPath, OUTPUTDIR_NAME); + + Rid = RuntimeIdentifier.Current; + } + + [Fact] + public void TestDotnetCompile() + { + TestSetup(); + + TestRunCommand("dotnet", $"compile -o {OutputDirectory}"); + TestOutputExecutable(OutputDirectory); + } + + [Fact] + public void TestDotnetCompileNativeRyuJit() + { + // Skip this test on mac + if(SkipForOS(OSPlatform.OSX, "https://github.com/dotnet/cli/issues/246")) + { + return; + } + + TestSetup(); + + TestRunCommand("dotnet", $"compile --native -o {OutputDirectory}"); + + var nativeOut = Path.Combine(OutputDirectory, "native"); + TestOutputExecutable(nativeOut); + } + + [Fact] + public void TestDotnetCompileNativeCpp() + { + // Skip this test on windows + if(SkipForOS(OSPlatform.Windows, "https://github.com/dotnet/cli/issues/335")) + { + return; + } + + TestSetup(); + + TestRunCommand("dotnet", $"compile --native --cpp -o {OutputDirectory}"); + + var nativeOut = Path.Combine(OutputDirectory, "native"); + TestOutputExecutable(nativeOut); + } + + [Fact] + public void TestDotnetRun() + { + TestSetup(); + + TestRunCommand("dotnet", $"run"); + } + + [Fact(Skip="https://github.com/dotnet/cli/issues/333")] + public void TestDotnetPack() + { + TestSetup(); + + TestRunCommand("dotnet", $"pack"); + } + + [Fact] + public void TestDotnetPublish() + { + TestSetup(); + + TestRunCommand("dotnet", $"publish --framework dnxcore50 --runtime {Rid} -o {OutputDirectory}"); + TestOutputExecutable(OutputDirectory); + } + + private void TestSetup() + { + Directory.SetCurrentDirectory(RootPath); + + CleanOrCreateDirectory(TestDirectory); + CleanOrCreateDirectory(OutputDirectory); + + Directory.SetCurrentDirectory(TestDirectory); + + TestRunCommand("dotnet", "init"); + TestRunCommand("dotnet", "restore"); + } + + private bool SkipForOS(OSPlatform os, string reason) + { + 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 outText = result.StdOut; + Assert.Equal(EXPECTED_OUTPUT, outText); + } + + private void CleanOrCreateDirectory(string path) + { + if (Directory.Exists(path)) + { + Directory.Delete(path, true); + } + Directory.CreateDirectory(path); + } + } +} diff --git a/test/E2E/project.json b/test/E2E/project.json new file mode 100644 index 000000000..e21cac468 --- /dev/null +++ b/test/E2E/project.json @@ -0,0 +1,28 @@ +{ + "version": "1.0.0-*", + "compilationOptions": { + "emitEntryPoint": true + }, + + "dependencies": { + "Microsoft.NETCore.Platforms":"1.0.1-beta-*", + "Microsoft.NETCore.Runtime": "1.0.1-beta-*", + "System.Console": "4.0.0-beta-*", + "System.Runtime": "4.0.21-beta-*", + "System.AppContext": "4.0.1-beta-*", + + "xunit": "2.1.0", + "xunit.console.netcore": "1.0.2-prerelease-00101", + "xunit.runner.utility": "2.1.0", + + "Microsoft.DotNet.ProjectModel": { "target": "project" }, + "Microsoft.DotNet.Cli.Utils": { + "type": "build", + "version": "1.0.0-*" + }, + }, + + "frameworks": { + "dnxcore50": { } + } +}