Add Tests for incrementality

This commit is contained in:
Mihai Codoban 2016-01-14 11:52:54 -08:00
parent 68d46fefad
commit 3a8ef0f5e9
33 changed files with 712 additions and 82 deletions

View file

@ -87,6 +87,10 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Tools.Publ
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TestLibrary", "test\TestProjects\TestLibrary\TestLibrary.xproj", "{947DD232-8D9B-4B78-9C6A-94F807D2DD58}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Tools.Builder.Tests", "test\Microsoft.DotNet.Tools.Builder.Tests\Microsoft.DotNet.Tools.Builder.Tests.xproj", "{833FFEE1-7EED-4F51-8DFD-946D48833333}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TestProjectToProjectDependencies", "test\TestProjects\TestProjectToProjectDependencies\TestProjectToProjectDependencies.xproj", "{947DD232-8D9B-4B78-9C6A-94F807D22222}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -659,6 +663,38 @@ Global
{947DD232-8D9B-4B78-9C6A-94F807D2DD58}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{947DD232-8D9B-4B78-9C6A-94F807D2DD58}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{947DD232-8D9B-4B78-9C6A-94F807D2DD58}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
{833FFEE1-7EED-4F51-8DFD-946D48833333}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{833FFEE1-7EED-4F51-8DFD-946D48833333}.Debug|Any CPU.Build.0 = Debug|Any CPU
{833FFEE1-7EED-4F51-8DFD-946D48833333}.Debug|x64.ActiveCfg = Debug|Any CPU
{833FFEE1-7EED-4F51-8DFD-946D48833333}.Debug|x64.Build.0 = Debug|Any CPU
{833FFEE1-7EED-4F51-8DFD-946D48833333}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
{833FFEE1-7EED-4F51-8DFD-946D48833333}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
{833FFEE1-7EED-4F51-8DFD-946D48833333}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{833FFEE1-7EED-4F51-8DFD-946D48833333}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{833FFEE1-7EED-4F51-8DFD-946D48833333}.Release|Any CPU.ActiveCfg = Release|Any CPU
{833FFEE1-7EED-4F51-8DFD-946D48833333}.Release|Any CPU.Build.0 = Release|Any CPU
{833FFEE1-7EED-4F51-8DFD-946D48833333}.Release|x64.ActiveCfg = Release|Any CPU
{833FFEE1-7EED-4F51-8DFD-946D48833333}.Release|x64.Build.0 = Release|Any CPU
{833FFEE1-7EED-4F51-8DFD-946D48833333}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
{833FFEE1-7EED-4F51-8DFD-946D48833333}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{833FFEE1-7EED-4F51-8DFD-946D48833333}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{833FFEE1-7EED-4F51-8DFD-946D48833333}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
{947DD232-8D9B-4B78-9C6A-94F807D22222}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{947DD232-8D9B-4B78-9C6A-94F807D22222}.Debug|Any CPU.Build.0 = Debug|Any CPU
{947DD232-8D9B-4B78-9C6A-94F807D22222}.Debug|x64.ActiveCfg = Debug|Any CPU
{947DD232-8D9B-4B78-9C6A-94F807D22222}.Debug|x64.Build.0 = Debug|Any CPU
{947DD232-8D9B-4B78-9C6A-94F807D22222}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
{947DD232-8D9B-4B78-9C6A-94F807D22222}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
{947DD232-8D9B-4B78-9C6A-94F807D22222}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{947DD232-8D9B-4B78-9C6A-94F807D22222}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{947DD232-8D9B-4B78-9C6A-94F807D22222}.Release|Any CPU.ActiveCfg = Release|Any CPU
{947DD232-8D9B-4B78-9C6A-94F807D22222}.Release|Any CPU.Build.0 = Release|Any CPU
{947DD232-8D9B-4B78-9C6A-94F807D22222}.Release|x64.ActiveCfg = Release|Any CPU
{947DD232-8D9B-4B78-9C6A-94F807D22222}.Release|x64.Build.0 = Release|Any CPU
{947DD232-8D9B-4B78-9C6A-94F807D22222}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
{947DD232-8D9B-4B78-9C6A-94F807D22222}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{947DD232-8D9B-4B78-9C6A-94F807D22222}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{947DD232-8D9B-4B78-9C6A-94F807D22222}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -700,5 +736,7 @@ Global
{833FFEE1-7EED-4F51-8DFD-946D48893D6E} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
{386D412C-003C-47B1-8258-0E35865CB7C4} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
{947DD232-8D9B-4B78-9C6A-94F807D2DD58} = {713CBFBB-5392-438D-B766-A9A585EF1BB8}
{833FFEE1-7EED-4F51-8DFD-946D48833333} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
{947DD232-8D9B-4B78-9C6A-94F807D22222} = {713CBFBB-5392-438D-B766-A9A585EF1BB8}
EndGlobalSection
EndGlobal

View file

@ -11,9 +11,10 @@ $TestBinRoot = "$RepoRoot\artifacts\tests"
$TestProjects = @(
"E2E",
"StreamForwarderTests"
"Microsoft.DotNet.Tools.Publish.Tests"
"Microsoft.DotNet.Tools.Compiler.Tests"
"StreamForwarderTests",
"Microsoft.DotNet.Tools.Publish.Tests",
"Microsoft.DotNet.Tools.Compiler.Tests",
"Microsoft.DotNet.Tools.Builder.Tests"
)
# Publish each test project

View file

@ -24,6 +24,7 @@ TestProjects=( \
StreamForwarderTests \
Microsoft.DotNet.Tools.Publish.Tests \
Microsoft.DotNet.Tools.Compiler.Tests \
Microsoft.DotNet.Tools.Builder.Tests \
)
for project in ${TestProjects[@]}

View file

@ -45,7 +45,7 @@ namespace Microsoft.DotNet.Tests.EndToEnd
buildCommand.Execute().Should().Pass();
TestOutputExecutable(OutputDirectory, buildCommand.GetOutputExecutableName());
TestOutputExecutable(OutputDirectory, buildCommand.GetOutputExecutableName(), s_expectedOutput);
}
[Fact]
@ -56,13 +56,13 @@ namespace Microsoft.DotNet.Tests.EndToEnd
// first build
var buildCommand = new BuildCommand(TestProject, output: OutputDirectory);
buildCommand.Execute().Should().Pass();
TestOutputExecutable(OutputDirectory, buildCommand.GetOutputExecutableName());
TestOutputExecutable(OutputDirectory, buildCommand.GetOutputExecutableName(), s_expectedOutput);
var latestWriteTimeFirstBuild = GetLastWriteTimeOfDirectoryFiles(OutputDirectory);
// second build; should get skipped (incremental because no inputs changed)
buildCommand.Execute().Should().Pass();
TestOutputExecutable(OutputDirectory, buildCommand.GetOutputExecutableName());
TestOutputExecutable(OutputDirectory, buildCommand.GetOutputExecutableName(), s_expectedOutput);
var latestWriteTimeSecondBuild = GetLastWriteTimeOfDirectoryFiles(OutputDirectory);
Assert.Equal(latestWriteTimeFirstBuild, latestWriteTimeSecondBuild);
@ -71,68 +71,12 @@ namespace Microsoft.DotNet.Tests.EndToEnd
// third build; should get compiled because the source file got touched
buildCommand.Execute().Should().Pass();
TestOutputExecutable(OutputDirectory, buildCommand.GetOutputExecutableName());
TestOutputExecutable(OutputDirectory, buildCommand.GetOutputExecutableName(), s_expectedOutput);
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);
}
[Fact]
[ActiveIssue(712, PlatformID.Windows | PlatformID.OSX | PlatformID.Linux)]
public void TestDotnetBuildNativeRyuJit()
@ -148,7 +92,7 @@ namespace Microsoft.DotNet.Tests.EndToEnd
buildCommand.Execute().Should().Pass();
var nativeOut = Path.Combine(OutputDirectory, "native");
TestOutputExecutable(nativeOut, buildCommand.GetOutputExecutableName());
TestOutputExecutable(nativeOut, buildCommand.GetOutputExecutableName(), s_expectedOutput);
}
[Fact]
@ -165,7 +109,7 @@ namespace Microsoft.DotNet.Tests.EndToEnd
buildCommand.Execute().Should().Pass();
var nativeOut = Path.Combine(OutputDirectory, "native");
TestOutputExecutable(nativeOut, buildCommand.GetOutputExecutableName());
TestOutputExecutable(nativeOut, buildCommand.GetOutputExecutableName(), s_expectedOutput);
}
[Fact]
@ -182,13 +126,13 @@ namespace Microsoft.DotNet.Tests.EndToEnd
// first build
var buildCommand = new BuildCommand(TestProject, output: OutputDirectory, native: true, nativeCppMode: true);
buildCommand.Execute().Should().Pass();
TestOutputExecutable(nativeOut, buildCommand.GetOutputExecutableName());
TestOutputExecutable(nativeOut, buildCommand.GetOutputExecutableName(), s_expectedOutput);
var latestWriteTimeFirstBuild = GetLastWriteTimeOfDirectoryFiles(OutputDirectory);
// second build; should be skipped because nothing changed
buildCommand.Execute().Should().Pass();
TestOutputExecutable(nativeOut, buildCommand.GetOutputExecutableName());
TestOutputExecutable(nativeOut, buildCommand.GetOutputExecutableName(), s_expectedOutput);
var latestWriteTimeSecondBuild = GetLastWriteTimeOfDirectoryFiles(OutputDirectory);
Assert.Equal(latestWriteTimeFirstBuild, latestWriteTimeSecondBuild);
@ -220,7 +164,7 @@ namespace Microsoft.DotNet.Tests.EndToEnd
var publishCommand = new PublishCommand(TestProject, output: OutputDirectory);
publishCommand.Execute().Should().Pass();
TestOutputExecutable(OutputDirectory, publishCommand.GetOutputExecutable());
TestOutputExecutable(OutputDirectory, publishCommand.GetOutputExecutable(), s_expectedOutput);
}
private void TestSetup()
@ -245,19 +189,6 @@ namespace Microsoft.DotNet.Tests.EndToEnd
Directory.SetCurrentDirectory(currentDirectory);
}
private void TestOutputExecutable(string outputDir, string executableName)
{
var executablePath = Path.Combine(outputDir, executableName);
var executableCommand = new TestCommand(executablePath);
var result = executableCommand.ExecuteWithCapturedOutput("");
result.Should().HaveStdOut(s_expectedOutput);
result.Should().NotHaveStdErr();
result.Should().Pass();
}
private bool IsCentOS()
{
if(RuntimeInformation.IsOSPlatform(OSPlatform.Linux))

View file

@ -0,0 +1,81 @@
// 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.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.Test.Utilities;
using Xunit;
namespace Microsoft.DotNet.Tools.Builder.Tests
{
public class ProjectToProjectDependenciesIncrementalTest : IncrementalTestBase
{
private string[] _projects = new[] { "L0", "L11", "L12", "L21", "L22" };
private string _testProjectsRoot = @"TestProjects";
private string _testProject = "TestProjectToProjectDependencies";
private TempDirectory tempProjectRoot;
public ProjectToProjectDependenciesIncrementalTest() : base(
Path.Combine("TestProjects", "TestProjectToProjectDependencies"),
"L0",
"L0 L11 L12 L22 L21 L12 L22 " + Environment.NewLine)
{
}
[Theory,
InlineData("L0", new[] { "L0" }),
InlineData("L11", new[] { "L0", "L11" }),
InlineData("L12", new[] { "L0", "L11", "L12" }),
InlineData("L22", new[] { "L0", "L11", "L12", "L22" }),
InlineData("L21", new[] { "L0", "L11", "L21" })
]
public void TestIncrementalBuildOfDependencyGraph(string projectToTouch, string[] expectedRebuiltProjects)
{
// first clean build; all projects required compilation
var result1 = BuildProject();
AssertRebuilt(result1, _projects);
// second build; nothing changed; no project required compilation
var result2 = BuildProject();
AssertRebuilt(result2, Array.Empty<string>());
//modify the source code of a project
TouchSourcesOfProject(projectToTouch);
// third build; all projects on the paths from touched project to root project need to be rebuilt
var result3 = BuildProject();
AssertRebuilt(result3, expectedRebuiltProjects);
}
// compute A - B
private T[] SetDifference<T>(T[] A, T[] B)
{
var setA = new HashSet<T>(A);
setA.ExceptWith(B);
return setA.ToArray();
}
private void AssertRebuilt(CommandResult buildResult, string[] expectedRebuilt)
{
foreach (var rebuiltProject in expectedRebuilt)
{
AssertProjectCompiled(rebuiltProject, buildResult);
}
foreach (var skippedProject in SetDifference(_projects, expectedRebuilt))
{
AssertProjectSkipped(skippedProject, buildResult);
}
}
protected override string GetProjectDirectory(string projectName)
{
return Path.Combine(_tempProjectRoot.Path, "src", projectName);
}
}
}

View file

@ -0,0 +1,117 @@
// 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.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.Test.Utilities;
using Xunit;
namespace Microsoft.DotNet.Tools.Builder.Tests
{
public class IncrementalTestBase : TestBase
{
protected readonly TempDirectory _tempProjectRoot;
private readonly string _testProjectsRoot;
protected readonly string _mainProject;
protected readonly string _expectedOutput;
public IncrementalTestBase(string testProjectsRoot, string mainProject, string expectedOutput)
{
_testProjectsRoot = testProjectsRoot;
_mainProject = mainProject;
_expectedOutput = expectedOutput;
// create unique directories in the 'temp' folder
var root = Temp.CreateDirectory();
// recursively copy projects to the temp dir and restore them
_tempProjectRoot = root.CopyDirectory(testProjectsRoot);
RunRestore(_tempProjectRoot.Path);
}
protected void TouchSourcesOfProject()
{
TouchSourcesOfProject(_mainProject);
}
protected void TouchSourcesOfProject(string projectToTouch)
{
foreach (var sourceFile in GetSourceFilesForProject(projectToTouch))
{
TouchFile(sourceFile);
}
}
protected static void TouchFile(string file)
{
File.SetLastWriteTimeUtc(file, DateTime.UtcNow);
}
protected CommandResult BuildProject(bool forceIncrementalUnsafe = false, bool expectBuildFailure = false)
{
var outputDir = GetBinDirectory();
var mainProject = GetProjectFile(_mainProject);
var buildCommand = new BuildCommand(mainProject, output: outputDir, forceIncrementalUnsafe : forceIncrementalUnsafe);
var result = buildCommand.ExecuteWithCapturedOutput();
if (!expectBuildFailure)
{
result.Should().Pass();
TestOutputExecutable(outputDir, buildCommand.GetOutputExecutableName(), _expectedOutput);
}
else
{
result.Should().Fail();
}
return result;
}
protected static void AssertProjectSkipped(string skippedProject, CommandResult buildResult)
{
Assert.Contains($"Project {skippedProject} was previoulsy compiled. Skipping compilation.", buildResult.StdOut);
}
protected static void AssertProjectCompiled(string rebuiltProject, CommandResult buildResult)
{
Assert.Contains($"Project {rebuiltProject} will be compiled", buildResult.StdOut, StringComparison.OrdinalIgnoreCase);
}
protected string GetBinDirectory()
{
return Path.Combine(_tempProjectRoot.Path, "bin");
}
protected virtual string GetProjectDirectory(string projectName)
{
return Path.Combine(_tempProjectRoot.Path);
}
protected string GetProjectFile(string projectName)
{
return Path.Combine(GetProjectDirectory(projectName), "project.json");
}
private string GetOutputFileForProject(string projectName)
{
return Path.Combine(GetBinDirectory(), projectName + ".dll");
}
private IEnumerable<string> GetSourceFilesForProject(string projectName)
{
return Directory.EnumerateFiles(GetProjectDirectory(projectName)).
Where(f => f.EndsWith(".cs"));
}
private void RunRestore(string args)
{
var restoreCommand = new RestoreCommand();
restoreCommand.Execute($"--quiet {args}").Should().Pass();
}
}
}

View file

@ -0,0 +1,130 @@
// 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.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.Test.Utilities;
using Xunit;
namespace Microsoft.DotNet.Tools.Builder.Tests
{
public class IncrementalTests : IncrementalTestBase
{
private string _testProjectsRoot = @"TestProjects";
private string _testProject = "TestProjectToProjectDependencies";
private TempDirectory tempProjectRoot;
public IncrementalTests() : base(
Path.Combine("TestProjects", "TestSimpleIncrementalApp"),
"TestSimpleIncrementalApp",
"Hello World!" + Environment.NewLine)
{
}
[Fact]
public void TestForceIncrementalUnsafe()
{
var buildResult = BuildProject();
AssertProjectCompiled(_mainProject, buildResult);
buildResult = BuildProject(forceIncrementalUnsafe: true);
Assert.Contains("[Forced Unsafe]", buildResult.StdOut);
}
[Fact]
public void TestRebuildMissingPdb()
{
TestDeleteOutputWithExtension("pdb");
}
[Fact]
public void TestRebuildMissingDll()
{
TestDeleteOutputWithExtension("dll");
}
[Fact]
public void TestRebuildMissingXml()
{
TestDeleteOutputWithExtension("xml");
}
[Fact]
public void TestNoLockFile()
{
var buildResult = BuildProject();
AssertProjectCompiled(_mainProject, buildResult);
var lockFile = Path.Combine(_tempProjectRoot.Path, "project.lock.json");
Assert.True(File.Exists(lockFile));
File.Delete(lockFile);
Assert.False(File.Exists(lockFile));
buildResult = BuildProject(expectBuildFailure : true);
Assert.Contains("does not have a lock file", buildResult.StdErr);
}
[Fact]
public void TestRebuildChangedLockFile()
{
var buildResult = BuildProject();
AssertProjectCompiled(_mainProject, buildResult);
var lockFile = Path.Combine(_tempProjectRoot.Path, "project.lock.json");
TouchFile(lockFile);
buildResult = BuildProject();
AssertProjectCompiled(_mainProject, buildResult);
}
[Fact]
public void TestRebuildChangedProjectFile()
{
var buildResult = BuildProject();
AssertProjectCompiled(_mainProject, buildResult);
TouchFile(GetProjectFile(_mainProject));
buildResult = BuildProject();
AssertProjectCompiled(_mainProject, buildResult);
}
private void TestDeleteOutputWithExtension(string extension)
{
var buildResult = BuildProject();
AssertProjectCompiled(_mainProject, buildResult);
Reporter.Verbose.WriteLine($"Files in {GetBinDirectory()}");
foreach (var file in Directory.EnumerateFiles(GetBinDirectory()))
{
Reporter.Verbose.Write($"\t {file}");
}
// delete output files with extensions
foreach (var outputFile in Directory.EnumerateFiles(GetBinDirectory()).Where(f =>
{
var fileName = Path.GetFileName(f);
return fileName.StartsWith(_mainProject, StringComparison.OrdinalIgnoreCase) &&
fileName.EndsWith(extension, StringComparison.OrdinalIgnoreCase);
}))
{
Reporter.Output.WriteLine($"Deleted {outputFile}");
File.Delete(outputFile);
Assert.False(File.Exists(outputFile));
}
// second build; should get rebuilt since we deleted an output item
buildResult = BuildProject();
AssertProjectCompiled(_mainProject, buildResult);
}
}
}

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0.23107" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.23107</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>833ffee1-7eed-4f51-8dfd-946d48833333</ProjectGuid>
<RootNamespace>Microsoft.DotNet.Tools.Builder.Tests</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

View file

@ -0,0 +1,23 @@
{
"version": "1.0.0-*",
"dependencies": {
"NETStandard.Library": "1.0.0-rc2-23704",
"Microsoft.NETCore.TestHost" : "1.0.0-*",
"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.Tools.Tests.Utilities": { "target": "project" },
"Microsoft.DotNet.Cli.Utils": {
"target": "project",
"type": "build"
}
},
"frameworks": {
"dnxcore50": { }
}
}

View file

@ -201,7 +201,7 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
public override CommandResult ExecuteWithCapturedOutput(string args = "")
{
args = $"build {BuildArgs()} {args}";
args = $"--verbose build {BuildArgs()} {args}";
return base.ExecuteWithCapturedOutput(args);
}

View file

@ -69,6 +69,31 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
File.Copy(originalPath, filePath);
return _root.AddFile(new DisposableFile(filePath));
}
/// <summary>
/// Recursively copy the provided directory into this TempDirectory.
/// Does not handle links.
/// </summary>
/// <param name="sourceDirectory"></param>
/// <returns></returns>
public TempDirectory CopyDirectory(string sourceDirectory)
{
Debug.Assert(Directory.Exists(sourceDirectory));
var tempCopy = CreateDirectory(new DirectoryInfo(sourceDirectory).Name);
foreach(var file in Directory.EnumerateFiles(sourceDirectory))
{
tempCopy.CopyFile(file);
}
foreach(var directory in Directory.EnumerateDirectories(sourceDirectory))
{
tempCopy.CopyDirectory(directory);
}
return tempCopy;
}
/// <summary>
/// Creates a subdirectory in this directory.

View file

@ -3,8 +3,10 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.DotNet.Cli.Utils;
namespace Microsoft.DotNet.Tools.Test.Utilities
{
@ -55,5 +57,18 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
string.Equals("1", val, StringComparison.OrdinalIgnoreCase) ||
string.Equals("on", val, StringComparison.OrdinalIgnoreCase));
}
protected void TestOutputExecutable(string outputDir, string executableName, string expectedOutput)
{
var executablePath = Path.Combine(outputDir, executableName);
var executableCommand = new TestCommand(executablePath);
var result = executableCommand.ExecuteWithCapturedOutput("");
result.Should().HaveStdOut(expectedOutput);
result.Should().NotHaveStdErr();
result.Should().Pass();
}
}
}

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>947dd232-8d9b-4b78-9c6a-94f807d22222</ProjectGuid>
<RootNamespace>TestProjectToProjectDependencies</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

View file

@ -0,0 +1,3 @@
{
"projects": [ "src" ]
}

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<!--To inherit the global NuGet package sources remove the <clear/> line below -->
<clear />
<add key="dotnet-core" value="https://www.myget.org/F/dotnet-core/api/v3/index.json" />
<add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>

View file

@ -0,0 +1,12 @@
using System;
namespace ConsoleApplication
{
public class L0
{
public static void Main(string[] args)
{
Console.WriteLine("L0 " + L11.Value() + L12.Value());
}
}
}

View file

@ -0,0 +1,17 @@
{
"version": "1.0.0-*",
"compilationOptions": {
"emitEntryPoint": true
},
"dependencies": {
"L11": "1.0.0-*",
"L12": "1.0.0-*",
"NETStandard.Library": "1.0.0-rc2-23704"
},
"frameworks": {
"dnxcore50": { }
}
}

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<!--To inherit the global NuGet package sources remove the <clear/> line below -->
<clear />
<add key="dotnet-core" value="https://www.myget.org/F/dotnet-core/api/v3/index.json" />
<add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>

View file

@ -0,0 +1,12 @@
using System;
namespace ConsoleApplication
{
public class L11
{
public static string Value()
{
return "L11 " + L12.Value() + L21.Value();
}
}
}

View file

@ -0,0 +1,14 @@
{
"version": "1.0.0-*",
"dependencies": {
"L12": "1.0.0-*",
"L21": "1.0.0-*",
"NETStandard.Library": "1.0.0-rc2-23704"
},
"frameworks": {
"dnxcore50": { }
}
}

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<!--To inherit the global NuGet package sources remove the <clear/> line below -->
<clear />
<add key="dotnet-core" value="https://www.myget.org/F/dotnet-core/api/v3/index.json" />
<add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>

View file

@ -0,0 +1,12 @@
using System;
namespace ConsoleApplication
{
public class L12
{
public static string Value()
{
return "L12 " + L22.Value();
}
}
}

View file

@ -0,0 +1,13 @@
{
"version": "1.0.0-*",
"dependencies": {
"L22": "1.0.0-*",
"NETStandard.Library": "1.0.0-rc2-23704"
},
"frameworks": {
"dnxcore50": { }
}
}

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<!--To inherit the global NuGet package sources remove the <clear/> line below -->
<clear />
<add key="dotnet-core" value="https://www.myget.org/F/dotnet-core/api/v3/index.json" />
<add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>

View file

@ -0,0 +1,12 @@
using System;
namespace ConsoleApplication
{
public class L21
{
public static string Value()
{
return "L21 ";
}
}
}

View file

@ -0,0 +1,11 @@
{
"version": "1.0.0-*",
"dependencies": {
"NETStandard.Library": "1.0.0-rc2-23704"
},
"frameworks": {
"dnxcore50": { }
}
}

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<!--To inherit the global NuGet package sources remove the <clear/> line below -->
<clear />
<add key="dotnet-core" value="https://www.myget.org/F/dotnet-core/api/v3/index.json" />
<add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>

View file

@ -0,0 +1,12 @@
using System;
namespace ConsoleApplication
{
public class L22
{
public static string Value()
{
return "L22 ";
}
}
}

View file

@ -0,0 +1,11 @@
{
"version": "1.0.0-*",
"dependencies": {
"NETStandard.Library": "1.0.0-rc2-23704"
},
"frameworks": {
"dnxcore50": { }
}
}

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<!--To inherit the global NuGet package sources remove the <clear/> line below -->
<clear />
<add key="dotnet-core" value="https://www.myget.org/F/dotnet-core/api/v3/index.json" />
<add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>

View file

@ -0,0 +1,12 @@
using System;
namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>58808bbc-371e-47d6-a3d0-4902145edaaa</ProjectGuid>
<RootNamespace>TestSimpleIncrementalApp</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

View file

@ -0,0 +1,15 @@
{
"version": "1.0.0-*",
"compilationOptions": {
"emitEntryPoint": true,
"xmlDoc": true
},
"dependencies": {
"NETStandard.Library": "1.0.0-rc2-23704"
},
"frameworks": {
"dnxcore50": { }
}
}