2015-11-24 18:48:31 -08:00
// 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 ;
2015-12-07 14:18:09 -08:00
using System.Collections.Generic ;
2015-11-24 17:47:33 -08:00
using System.IO ;
2015-12-21 10:42:41 -08:00
using System.Linq ;
2015-11-25 19:46:01 -08:00
using System.Runtime.InteropServices ;
2015-12-07 14:18:09 -08:00
using System.Text ;
2015-11-24 17:47:33 -08:00
using Xunit ;
using Microsoft.DotNet.Cli.Utils ;
2015-11-30 11:25:13 -08:00
using Microsoft.DotNet.ProjectModel ;
2015-12-30 17:02:59 -08:00
using Microsoft.DotNet.Tools.Test.Utilities ;
2015-12-18 16:39:43 -08:00
using Microsoft.Extensions.PlatformAbstractions ;
2015-11-24 17:47:33 -08:00
2015-12-30 17:02:59 -08:00
namespace Microsoft.DotNet.Tests.EndToEnd
2015-11-24 17:47:33 -08:00
{
2015-12-30 17:02:59 -08:00
public class EndToEndTest : TestBase
2015-11-24 17:47:33 -08:00
{
2015-12-30 17:02:59 -08:00
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 ; }
2015-11-25 19:46:01 -08:00
private string TestDirectory { get ; set ; }
2015-12-30 17:02:59 -08:00
private string TestProject { get ; set ; }
2015-11-25 19:46:01 -08:00
private string OutputDirectory { get ; set ; }
2015-11-24 17:47:33 -08:00
public static void Main ( )
{
Console . WriteLine ( "Dummy Entrypoint." ) ;
}
2015-11-25 19:46:01 -08:00
2015-12-30 17:02:59 -08:00
public EndToEndTest ( )
2015-11-25 19:46:01 -08:00
{
2015-12-30 17:02:59 -08:00
TestSetup ( ) ;
2015-11-25 19:46:01 -08:00
2015-12-18 16:39:43 -08:00
Rid = PlatformServices . Default . Runtime . GetLegacyRestoreRuntimeIdentifier ( ) ;
2015-11-25 19:46:01 -08:00
}
2015-11-24 17:47:33 -08:00
[Fact]
2015-12-30 17:02:59 -08:00
public void TestDotnetBuild ( )
2015-11-24 17:47:33 -08:00
{
2015-12-30 17:02:59 -08:00
var buildCommand = new BuildCommand ( TestProject , output : OutputDirectory ) ;
buildCommand . Execute ( ) . Should ( ) . Pass ( ) ;
2015-11-24 17:47:33 -08:00
2015-12-30 17:02:59 -08:00
TestOutputExecutable ( OutputDirectory , buildCommand . GetOutputExecutableName ( ) ) ;
2015-11-25 19:46:01 -08:00
}
2015-11-24 17:47:33 -08:00
2015-12-21 10:42:41 -08:00
[Fact]
public void TestDotnetIncrementalBuild ( )
{
TestSetup ( ) ;
// first build
var buildCommand = new BuildCommand ( TestProject , output : OutputDirectory ) ;
buildCommand . Execute ( ) . Should ( ) . Pass ( ) ;
TestOutputExecutable ( OutputDirectory , buildCommand . GetOutputExecutableName ( ) ) ;
var latestWriteTimeFirstBuild = GetLastWriteTimeOfDirectoryFiles ( OutputDirectory ) ;
// second build; should get skipped (incremental because no inputs changed)
buildCommand . Execute ( ) . Should ( ) . Pass ( ) ;
TestOutputExecutable ( OutputDirectory , buildCommand . GetOutputExecutableName ( ) ) ;
var latestWriteTimeSecondBuild = GetLastWriteTimeOfDirectoryFiles ( OutputDirectory ) ;
Assert . Equal ( latestWriteTimeFirstBuild , latestWriteTimeSecondBuild ) ;
TouchSourceFileInDirectory ( TestDirectory ) ;
// third build; should get compiled because the source file got touched
buildCommand . Execute ( ) . Should ( ) . Pass ( ) ;
TestOutputExecutable ( OutputDirectory , buildCommand . GetOutputExecutableName ( ) ) ;
var latestWriteTimeThirdBuild = GetLastWriteTimeOfDirectoryFiles ( OutputDirectory ) ;
Assert . NotEqual ( latestWriteTimeSecondBuild , latestWriteTimeThirdBuild ) ;
}
[Fact]
public void TestDotnetForceIncrementalUnsafe ( )
{
TestSetup ( ) ;
// first build
var buildCommand = new BuildCommand ( TestProject , output : OutputDirectory ) ;
buildCommand . Execute ( ) . Should ( ) . Pass ( ) ;
TestOutputExecutable ( OutputDirectory , buildCommand . GetOutputExecutableName ( ) ) ;
var latestWriteTimeFirstBuild = GetLastWriteTimeOfDirectoryFiles ( OutputDirectory ) ;
// second build; will get recompiled due to force unsafe flag
buildCommand = new BuildCommand ( TestProject , output : OutputDirectory , forceIncrementalUnsafe : true ) ;
buildCommand . Execute ( ) . Should ( ) . Pass ( ) ;
TestOutputExecutable ( OutputDirectory , buildCommand . GetOutputExecutableName ( ) ) ;
var latestWriteTimeSecondBuild = GetLastWriteTimeOfDirectoryFiles ( OutputDirectory ) ;
Assert . NotEqual ( latestWriteTimeFirstBuild , latestWriteTimeSecondBuild ) ;
}
[Fact]
public void TestDotnetIncrementalBuildDeleteOutputFile ( )
{
TestSetup ( ) ;
// first build
var buildCommand = new BuildCommand ( TestProject , output : OutputDirectory ) ;
buildCommand . Execute ( ) . Should ( ) . Pass ( ) ;
TestOutputExecutable ( OutputDirectory , buildCommand . GetOutputExecutableName ( ) ) ;
var latestWriteTimeFirstBuild = GetLastWriteTimeOfDirectoryFiles ( OutputDirectory ) ;
Reporter . Verbose . WriteLine ( $"Files in {OutputDirectory}" ) ;
foreach ( var file in Directory . EnumerateFiles ( OutputDirectory ) )
{
Reporter . Verbose . Write ( $"\t {file}" ) ;
}
// delete output files
foreach ( var outputFile in Directory . EnumerateFiles ( OutputDirectory ) . Where ( f = > Path . GetFileName ( f ) . StartsWith ( s_testdirName , StringComparison . OrdinalIgnoreCase ) ) )
{
Reporter . Verbose . WriteLine ( $"Delete {outputFile}" ) ;
File . Delete ( outputFile ) ;
Assert . False ( File . Exists ( outputFile ) ) ;
}
// second build; should get rebuilt since we deleted output items
buildCommand . Execute ( ) . Should ( ) . Pass ( ) ;
TestOutputExecutable ( OutputDirectory , buildCommand . GetOutputExecutableName ( ) ) ;
var latestWriteTimeSecondBuild = GetLastWriteTimeOfDirectoryFiles ( OutputDirectory ) ;
Assert . NotEqual ( latestWriteTimeFirstBuild , latestWriteTimeSecondBuild ) ;
}
2015-11-25 19:46:01 -08:00
[Fact]
2015-12-30 17:02:59 -08:00
[ActiveIssue(712, PlatformID.Windows | PlatformID.OSX | PlatformID.Linux)]
public void TestDotnetBuildNativeRyuJit ( )
2015-11-25 19:46:01 -08:00
{
2016-01-05 18:11:38 -08:00
if ( IsCentOS ( ) )
{
Console . WriteLine ( "Skipping native compilation tests on CentOS - https://github.com/dotnet/cli/issues/453" ) ;
return ;
}
2015-12-30 17:02:59 -08:00
var buildCommand = new BuildCommand ( TestProject , output : OutputDirectory , native : true ) ;
2015-11-24 17:47:33 -08:00
2015-12-30 17:02:59 -08:00
buildCommand . Execute ( ) . Should ( ) . Pass ( ) ;
2015-11-24 17:47:33 -08:00
2015-11-25 19:46:01 -08:00
var nativeOut = Path . Combine ( OutputDirectory , "native" ) ;
2015-12-30 17:02:59 -08:00
TestOutputExecutable ( nativeOut , buildCommand . GetOutputExecutableName ( ) ) ;
2015-11-25 19:46:01 -08:00
}
2015-11-24 17:47:33 -08:00
2015-11-25 19:46:01 -08:00
[Fact]
2015-12-30 17:02:59 -08:00
public void TestDotnetBuildNativeCpp ( )
2015-11-25 19:46:01 -08:00
{
2016-01-05 18:11:38 -08:00
if ( IsCentOS ( ) )
{
Console . WriteLine ( "Skipping native compilation tests on CentOS - https://github.com/dotnet/cli/issues/453" ) ;
return ;
}
2015-12-30 17:02:59 -08:00
var buildCommand = new BuildCommand ( TestProject , output : OutputDirectory , native : true , nativeCppMode : true ) ;
buildCommand . Execute ( ) . Should ( ) . Pass ( ) ;
2015-11-24 17:47:33 -08:00
2015-11-25 19:46:01 -08:00
var nativeOut = Path . Combine ( OutputDirectory , "native" ) ;
2015-12-30 17:02:59 -08:00
TestOutputExecutable ( nativeOut , buildCommand . GetOutputExecutableName ( ) ) ;
2015-11-25 19:46:01 -08:00
}
2015-11-24 17:47:33 -08:00
2015-12-21 10:42:41 -08:00
[Fact]
public void TestDotnetCompileNativeCppIncremental ( )
{
if ( IsCentOS ( ) )
{
Console . WriteLine ( "Skipping native compilation tests on CentOS - https://github.com/dotnet/cli/issues/453" ) ;
return ;
}
var nativeOut = Path . Combine ( OutputDirectory , "native" ) ;
// first build
var buildCommand = new BuildCommand ( TestProject , output : OutputDirectory , native : true , nativeCppMode : true ) ;
buildCommand . Execute ( ) . Should ( ) . Pass ( ) ;
TestOutputExecutable ( nativeOut , buildCommand . GetOutputExecutableName ( ) ) ;
var latestWriteTimeFirstBuild = GetLastWriteTimeOfDirectoryFiles ( OutputDirectory ) ;
// second build; should be skipped because nothing changed
buildCommand . Execute ( ) . Should ( ) . Pass ( ) ;
TestOutputExecutable ( nativeOut , buildCommand . GetOutputExecutableName ( ) ) ;
var latestWriteTimeSecondBuild = GetLastWriteTimeOfDirectoryFiles ( OutputDirectory ) ;
Assert . Equal ( latestWriteTimeFirstBuild , latestWriteTimeSecondBuild ) ;
}
2015-11-25 19:46:01 -08:00
[Fact]
public void TestDotnetRun ( )
{
2015-12-30 17:02:59 -08:00
var runCommand = new RunCommand ( TestProject ) ;
2015-11-24 17:47:33 -08:00
2015-12-30 17:02:59 -08:00
runCommand . Execute ( )
. Should ( )
. Pass ( ) ;
2015-11-24 17:47:33 -08:00
}
2015-12-18 11:34:55 -08:00
[Fact]
2015-11-25 19:46:01 -08:00
public void TestDotnetPack ( )
{
2015-12-30 17:02:59 -08:00
var packCommand = new PackCommand ( TestDirectory , output : OutputDirectory ) ;
2015-11-25 19:46:01 -08:00
2015-12-30 17:02:59 -08:00
packCommand . Execute ( )
. Should ( )
. Pass ( ) ;
2015-11-25 19:46:01 -08:00
}
[Fact]
public void TestDotnetPublish ( )
{
2015-12-30 17:02:59 -08:00
var publishCommand = new PublishCommand ( TestProject , output : OutputDirectory ) ;
publishCommand . Execute ( ) . Should ( ) . Pass ( ) ;
2015-11-25 19:46:01 -08:00
2015-12-30 17:02:59 -08:00
TestOutputExecutable ( OutputDirectory , publishCommand . GetOutputExecutable ( ) ) ;
2015-11-25 19:46:01 -08:00
}
private void TestSetup ( )
{
2015-12-30 17:02:59 -08:00
var root = Temp . CreateDirectory ( ) ;
TestDirectory = root . CreateDirectory ( s_testdirName ) . Path ;
TestProject = Path . Combine ( TestDirectory , "project.json" ) ;
OutputDirectory = Path . Combine ( TestDirectory , s_outputdirName ) ;
2015-11-25 19:46:01 -08:00
2015-12-30 17:02:59 -08:00
InitializeTestDirectory ( ) ;
}
2015-11-25 19:46:01 -08:00
2015-12-30 17:02:59 -08:00
private void InitializeTestDirectory ( )
{
var currentDirectory = Directory . GetCurrentDirectory ( ) ;
2015-11-25 19:46:01 -08:00
Directory . SetCurrentDirectory ( TestDirectory ) ;
2015-12-30 17:02:59 -08:00
new NewCommand ( ) . Execute ( ) . Should ( ) . Pass ( ) ;
new RestoreCommand ( ) . Execute ( "--quiet" ) . Should ( ) . Pass ( ) ;
Directory . SetCurrentDirectory ( currentDirectory ) ;
2015-11-25 19:46:01 -08:00
}
2015-12-30 17:02:59 -08:00
private void TestOutputExecutable ( string outputDir , string executableName )
2015-11-24 17:47:33 -08:00
{
var executablePath = Path . Combine ( outputDir , executableName ) ;
2015-12-30 17:02:59 -08:00
var executableCommand = new TestCommand ( executablePath ) ;
2015-11-24 17:47:33 -08:00
2015-12-30 17:02:59 -08:00
var result = executableCommand . ExecuteWithCapturedOutput ( "" ) ;
2015-11-24 17:47:33 -08:00
2015-12-30 17:02:59 -08:00
result . Should ( ) . HaveStdOut ( s_expectedOutput ) ;
result . Should ( ) . NotHaveStdErr ( ) ;
result . Should ( ) . Pass ( ) ;
2015-11-24 17:47:33 -08:00
}
2016-01-05 18:11:38 -08:00
private bool IsCentOS ( )
{
if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Linux ) )
{
const string OSIDFILE = "/etc/os-release" ;
if ( File . Exists ( OSIDFILE ) )
{
return File . ReadAllText ( OSIDFILE ) . ToLower ( ) . Contains ( "centos" ) ;
}
}
return false ;
}
2015-12-21 10:42:41 -08:00
private static DateTime GetLastWriteTimeOfDirectoryFiles ( string outputDirectory )
{
return Directory . EnumerateFiles ( outputDirectory ) . Max ( f = > File . GetLastWriteTime ( f ) ) ;
}
private static void TouchSourceFileInDirectory ( string directory )
{
var csFile = Directory . EnumerateFiles ( directory ) . First ( f = > Path . GetExtension ( f ) . Equals ( ".cs" ) ) ;
File . SetLastWriteTimeUtc ( csFile , DateTime . UtcNow ) ;
}
2015-11-24 17:47:33 -08:00
}
2016-01-06 15:30:56 -08:00
}