dotnet-installer/test/dotnet-build.Tests/BuildProjectToProjectTests.cs
Andrew Stanton-Nurse 7cc90d9ad1 Update dotnet-build to produce portable layout
dotnet-build will produce a deps file for portable builds, and will now
create "runnable" outputs for RID-less targets

the outputs won't actually be runnable today because we need corehost
changes and to generate a deps.json file for corehost to use.
2016-03-08 11:46:15 -08:00

140 lines
No EOL
5.1 KiB
C#

// 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 FluentAssertions;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.Test.Utilities;
using Xunit;
using System.Runtime.InteropServices;
namespace Microsoft.DotNet.Tools.Builder.Tests
{
public class ProjectToProjectDependenciesIncrementalTest : IncrementalTestBase
{
private readonly string[] _projects = new[] { "L0", "L11", "L12", "L21", "L22" };
private string MainProjectExe
{
get
{
return MainProject + (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : "");
}
}
public ProjectToProjectDependenciesIncrementalTest()
{
MainProject = "L0";
ExpectedOutput = "L0 L11 L12 L22 L21 L12 L22 " + Environment.NewLine;
}
[Theory,
InlineData("1", "L0", new[] { "L0" }),
InlineData("2", "L11", new[] { "L0", "L11" }),
InlineData("3", "L12", new[] { "L0", "L11", "L12" }),
InlineData("4", "L22", new[] { "L0", "L11", "L12", "L22" }),
InlineData("5", "L21", new[] { "L0", "L11", "L21" })
]
public void TestIncrementalBuildOfDependencyGraph(string testIdentifer, string projectToTouch, string[] expectedRebuiltProjects)
{
var testInstance = TestAssetsManager.CreateTestInstance("TestProjectToProjectDependencies", identifier: testIdentifer)
.WithLockFiles()
.WithBuildArtifacts();
TestProjectRoot = testInstance.TestRoot;
// 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);
}
[Fact]
public void TestNoDependencyFlag()
{
var testInstance = TestAssetsManager.CreateTestInstance("TestProjectToProjectDependencies")
.WithLockFiles()
.WithBuildArtifacts();
TestProjectRoot = testInstance.TestRoot;
var dependencies = new[] { "L11", "L12", "L21", "L22" };
// modify the source code of a leaf dependency
TouchSourcesOfProject("L22");
// second build with no dependencies and no incremental; only the root rebuilds
var result2 = BuildProject(noDependencies: true, noIncremental: true);
result2.Should().HaveStdOutMatching("Compiling.*L0.*");
AssertResultDoesNotContainStrings(result2, dependencies);
// third build with no dependencies but incremental; nothing rebuilds
var result3 = BuildProject(noDependencies: true);
result3.Should().HaveSkippedProjectCompilation("L0");
AssertResultDoesNotContainStrings(result3, dependencies);
}
private static void AssertResultDoesNotContainStrings(CommandResult commandResult, string[] strings)
{
foreach (var s in strings)
{
commandResult.StdOut.Should().NotContain(s);
}
}
// 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)
{
buildResult.Should().HaveCompiledProject(rebuiltProject);
}
foreach (var skippedProject in SetDifference(_projects, expectedRebuilt))
{
buildResult.Should().HaveSkippedProjectCompilation(skippedProject);
}
}
protected override string GetProjectDirectory(string projectName)
{
return Path.Combine(TestProjectRoot, "src", projectName);
}
protected override string GetOutputDir()
{
return "";
}
protected override string GetOutputExePath()
{
var outputExe = Directory.GetFiles(TestProjectRoot, MainProjectExe, SearchOption.AllDirectories)
.FirstOrDefault();
if (string.IsNullOrEmpty(outputExe))
{
throw new FileNotFoundException($"Unable to find {outputExe} in {TestProjectRoot} or its subdirectories");
}
return Path.GetDirectoryName(outputExe);
}
}
}