Imported Upstream version 5.4.0.167

Former-commit-id: 5624ac747d633e885131e8349322922b6a59baaa
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2017-08-21 15:34:15 +00:00
parent e49d6f06c0
commit 536cd135cc
12856 changed files with 563812 additions and 223249 deletions

View File

@@ -0,0 +1,41 @@
using System;
using System.IO;
using Xunit;
using Xunit.Abstractions;
namespace ILLink.Tests
{
public class HelloWorldTest : IntegrationTestBase
{
public HelloWorldTest(ITestOutputHelper output) : base(output) {}
public string SetupProject()
{
string projectRoot = "helloworld";
if (Directory.Exists(projectRoot)) {
Directory.Delete(projectRoot, true);
}
Directory.CreateDirectory(projectRoot);
int ret = Dotnet("new console", projectRoot);
if (ret != 0) {
output.WriteLine("dotnet new failed");
Assert.True(false);
}
string csproj = Path.Combine(projectRoot, $"{projectRoot}.csproj");
return csproj;
}
[Fact]
public void RunHelloWorld()
{
string csproj = SetupProject();
AddLinkerReference(csproj);
BuildAndLink(csproj, null);
}
}
}

View File

@@ -0,0 +1,147 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Xunit;
using Xunit.Abstractions;
namespace ILLink.Tests
{
public class IntegrationTestBase
{
protected readonly ITestOutputHelper output;
protected readonly TestContext context;
public IntegrationTestBase(ITestOutputHelper output)
{
this.output = output;
// This sets up the context with some values specific to
// the setup of the linker repository. A different context
// should be used in order to run tests in a different
// environment.
this.context = TestContext.CreateDefaultContext();
}
protected int Dotnet(string args, string workingDir, string additionalPath = null)
{
return RunCommand(context.DotnetToolPath, args, workingDir, additionalPath);
}
protected int RunCommand(string command, string args, string workingDir, string additionalPath = null)
{
output.WriteLine($"{command} {args}");
if (workingDir != null)
output.WriteLine($"working directory: {workingDir}");
var psi = new ProcessStartInfo
{
FileName = command,
Arguments = args,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
WorkingDirectory = workingDir,
};
if (additionalPath != null) {
string path = psi.Environment["PATH"];
psi.Environment["PATH"] = path + ";" + additionalPath;
}
var process = new Process
{
StartInfo = psi,
};
process.Start();
string capturedOutput = process.StandardOutput.ReadToEnd();
output.WriteLine(capturedOutput);
string capturedError = process.StandardError.ReadToEnd();
output.WriteLine(capturedError);
process.WaitForExit();
return process.ExitCode;
}
/// <summary>
/// Run the linker on the specified project. This assumes
/// that the project already contains a reference to the
/// linker task package.
/// Optionally takes a list of root descriptor files.
/// </summary>
public void BuildAndLink(string csproj, List<string> rootFiles = null)
{
string rid = context.RuntimeIdentifier;
string config = context.Configuration;
string demoRoot = Path.GetDirectoryName(csproj);
int ret = Dotnet($"restore -r {rid}", demoRoot);
if (ret != 0) {
output.WriteLine("restore failed");
Assert.True(false);
return;
}
string publishArgs = $"publish -r {rid} -c {config} /v:n /p:ShowLinkerSizeComparison=true";
string rootFilesStr;
if (rootFiles != null && rootFiles.Any()) {
rootFilesStr = String.Join(";", rootFiles);
publishArgs += $" /p:LinkerRootDescriptors={rootFilesStr}";
}
ret = Dotnet(publishArgs, demoRoot);
if (ret != 0) {
output.WriteLine("publish failed");
Assert.True(false);
return;
}
}
protected void AddLinkerReference(string csproj)
{
var xdoc = XDocument.Load(csproj);
var ns = xdoc.Root.GetDefaultNamespace();
bool added = false;
foreach (var el in xdoc.Root.Elements(ns + "ItemGroup")) {
if (el.Elements(ns + "PackageReference").Any()) {
el.Add(new XElement(ns+"PackageReference",
new XAttribute("Include", context.TasksPackageName),
new XAttribute("Version", context.TasksPackageVersion)));
added = true;
break;
}
}
if (!added) {
xdoc.Root.Add(new XElement(ns + "ItemGroup",
new XElement(ns + "PackageReference",
new XAttribute("Include", context.TasksPackageName),
new XAttribute("Version", context.TasksPackageVersion))));
added= true;
}
using (var fs = new FileStream(csproj, FileMode.Create)) {
xdoc.Save(fs);
}
}
static void AddLinkerRoots(string csproj, List<string> rootFiles)
{
var xdoc = XDocument.Load(csproj);
var ns = xdoc.Root.GetDefaultNamespace();
var rootsItemGroup = new XElement(ns+"ItemGroup");
foreach (var rootFile in rootFiles) {
rootsItemGroup.Add(new XElement(ns+"LinkerRootFiles",
new XAttribute("Include", rootFile)));
}
var propertyGroup = xdoc.Root.Elements(ns + "PropertyGroup").First();
propertyGroup.AddAfterSelf(rootsItemGroup);
using (var fs = new FileStream(csproj, FileMode.Create)) {
xdoc.Save(fs);
}
}
}
}

View File

@@ -0,0 +1,20 @@
<linker>
<!--- Called by Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions:.cctor -->
<assembly fullname="System.Linq.Queryable">
<type fullname="System.Linq.Queryable" required="true" />
</assembly>
<!--- Called by System.Linq.Expressions.Expression:CreateLambda -->
<assembly fullname="System.Linq.Expressions">
<type fullname="System.Linq.Expressions.Expression`1" required="true" />
</assembly>
<assembly fullname="System.Dynamic.Runtime">
<!--- Called by [System.Dynamic.Runtime]System.Runtime.CompilerServices.CallSite<>.CreateCustomNoMatchDelegate and [System.Dynamic.Runtime]System.Runtime.CompilerServices.CallSite<>.CreateCustomUpdateDelegate-->
<type fullname="System.Runtime.CompilerServices.CallSiteOps" required="true" />
<!--- Called by [System.Dynamic.Runtime]System.Runtime.CompilerServices.CallSiteBinder.Stitch -->
<type fullname="System.Runtime.CompilerServices.CallSite" required="true" />
<!--- Called by [System.Dynamic.Runtime]System.Runtime.CompilerServices.CallSiteBinder.Stitch -->
<type fullname="System.Runtime.CompilerServices.CallSite`1" required="true" />
</assembly>
</linker>

View File

@@ -0,0 +1,94 @@
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Xunit;
using Xunit.Abstractions; // ITestOutputHelper
namespace ILLink.Tests
{
public class MusicStoreTest : IntegrationTestBase
{
public MusicStoreTest(ITestOutputHelper output) : base(output) {}
private static List<string> rootFiles = new List<string> { "MusicStoreReflection.xml" };
[Fact]
public void RunMusicStore()
{
string csproj = SetupProject();
// Copy root files into the project directory
string demoRoot= Path.GetDirectoryName(csproj);
CopyRootFiles(demoRoot);
// This is necessary because JitBench comes with a
// NuGet.Config that has a <clear /> line, preventing
// NuGet.Config sources defined in outer directories from
// applying.
string nugetConfig = Path.Combine("JitBench", "NuGet.config");
AddLocalNugetFeedAfterClear(nugetConfig);
AddLinkerReference(csproj);
BuildAndLink(csproj, rootFiles);
}
// returns path to .csproj project file
string SetupProject()
{
string gitRepo = "http://github.com/aspnet/JitBench";
string repoName = "JitBench";
string gitBranch = "dev";
string demoRoot = Path.Combine("JitBench", Path.Combine("src", "MusicStore"));
int ret;
if (Directory.Exists(repoName)) {
Directory.Delete(repoName, true);
}
ret = RunCommand("git", $"clone {gitRepo}", null, null);
if (ret != 0) {
output.WriteLine("git failed");
Assert.True(false);
}
if (!Directory.Exists(demoRoot)) {
output.WriteLine($"{demoRoot} does not exist");
Assert.True(false);
}
ret = RunCommand("git", $"checkout {gitBranch}", demoRoot, null);
if (ret != 0) {
output.WriteLine($"problem checking out branch {gitBranch}");
Assert.True(false);
}
string csproj = Path.Combine(demoRoot, "MusicStore.csproj");
return csproj;
}
static void CopyRootFiles(string demoRoot)
{
foreach (var rf in rootFiles) {
File.Copy(rf, Path.Combine(demoRoot, rf));
}
}
private void AddLocalNugetFeedAfterClear(string nugetConfig)
{
string localPackagePath = Path.GetFullPath(context.PackageSource);
var xdoc = XDocument.Load(nugetConfig);
var ns = xdoc.Root.GetDefaultNamespace();
var clear = xdoc.Root.Element(ns+"packageSources").Element(ns+"clear");
clear.Parent.Add(new XElement(ns+"add",
new XAttribute("key", "local linker feed"),
new XAttribute("value", localPackagePath)));
using (var fs = new FileStream(nugetConfig, FileMode.Create)) {
xdoc.Save(fs);
}
}
}
}

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="dotnet-core" value="https://dotnet.myget.org/F/dotnet-core/api/v3/index.json" />
<!-- When the tests are run from the repo's test bin directory,
this NuGet.config should be read to find the local package
directory. -->
<add key="local linker packages" value="../nupkgs" />
</packageSources>
</configuration>

View File

@@ -0,0 +1,96 @@
using System;
using System.IO;
using System.Linq;
using Microsoft.DotNet.PlatformAbstractions;
namespace ILLink.Tests
{
public class TestContext
{
/// <summary>
/// The name of the tasks package to add to the integration
/// projects.
/// </summary>
public string TasksPackageName { get; private set; }
/// <summary>
/// The version of the tasks package to add to the
/// integration projects.
/// </summary>
public string TasksPackageVersion { get; private set; }
/// <summary>
/// The path of the directory from which to get the linker
/// package.
/// </summary>
public string PackageSource { get; private set; }
/// <summary>
/// The path to the dotnet tool to use to run the
/// integration tests.
/// </summary>
public string DotnetToolPath { get; private set; }
/// <summary>
/// The RID to use when restoring, building, and linking the
/// integration test projects.
/// </summary>
public string RuntimeIdentifier { get; private set; }
/// <summary>
/// The configuration to use to build the integration test
/// projects.
/// </summary>
public string Configuration { get; private set; }
/// <summary>
/// This is the context from which tests will be run in the
/// linker repo. The local directory that contains the
/// linker integration packages (hard-coded here) is
/// searched for the tasks package. This assumes that only
/// one version of the package is present, and uses it to
/// unambiguously determine which pacakge to use in the tests.
/// </summary>
public static TestContext CreateDefaultContext()
{
var packageName = "ILLink.Tasks";
var packageSource = "../../../../nupkgs";
var tasksPackages = Directory.GetFiles(packageSource)
.Where(p => Path.GetExtension(p) == ".nupkg")
.Select(p => Path.GetFileNameWithoutExtension(p))
.Where(p => p.StartsWith(packageName));
var nPackages = tasksPackages.Count();
if (nPackages > 1) {
throw new Exception($"duplicate {packageName} packages in {packageSource}");
} else if (nPackages == 0) {
throw new Exception($"{packageName} package not found in {packageSource}");
}
var tasksPackage = tasksPackages.Single();
var version = tasksPackage.Remove(0, packageName.Length + 1);
var dotnetDir = "../../../../../../corebuild/Tools/dotnetcli";
var dotnetToolNames = Directory.GetFiles(dotnetDir)
.Select(p => Path.GetFileName(p))
.Where(p => p.Contains("dotnet"));
var nTools = dotnetToolNames.Count();
if (nTools > 1) {
throw new Exception($"multiple dotnet tools in {dotnetDir}");
} else if (nTools == 0) {
throw new Exception($"no dotnet tool found in {dotnetDir}");
}
var dotnetToolName = dotnetToolNames.Single();
var dotnetToolPath = Path.Combine(dotnetDir, dotnetToolName);
var context = new TestContext();
context.PackageSource = packageSource;
context.TasksPackageName = packageName;
context.TasksPackageVersion = version;
context.DotnetToolPath = dotnetToolPath;
// This sets the RID to the RID of the currently-executing system.
context.RuntimeIdentifier = RuntimeEnvironment.GetRuntimeIdentifier();
// We want to build and link integration projects in the
// release configuration.
context.Configuration = "Release";
return context;
}
}
}

View File

@@ -0,0 +1,63 @@
using System;
using System.IO;
using System.Xml.Linq;
using Xunit;
using Xunit.Abstractions;
namespace ILLink.Tests
{
public class WebApiTest : IntegrationTestBase
{
public WebApiTest(ITestOutputHelper output) : base(output) {}
public string SetupProject()
{
string projectRoot = "webapi";
if (Directory.Exists(projectRoot)) {
Directory.Delete(projectRoot, true);
}
Directory.CreateDirectory(projectRoot);
int ret = Dotnet("new webapi", projectRoot);
if (ret != 0) {
output.WriteLine("dotnet new failed");
Assert.True(false);
}
string csproj = Path.Combine(projectRoot, $"{projectRoot}.csproj");
return csproj;
}
// TODO: Remove this once we figure out what to do about apps
// that have the publish output filtered by a manifest
// file. It looks like aspnet has made this the default. See
// the bug at https://github.com/dotnet/sdk/issues/1160.
private void PreventPublishFiltering(string csproj) {
var xdoc = XDocument.Load(csproj);
var ns = xdoc.Root.GetDefaultNamespace();
var propertygroup = xdoc.Root.Element(ns + "PropertyGroup");
output.WriteLine("setting PublishWithAspNetCoreTargetManifest=false");
propertygroup.Add(new XElement(ns + "PublishWithAspNetCoreTargetManifest",
"false"));
using (var fs = new FileStream(csproj, FileMode.Create)) {
xdoc.Save(fs);
}
}
[Fact]
public void RunWebApi()
{
string csproj = SetupProject();
PreventPublishFiltering(csproj);
AddLinkerReference(csproj);
BuildAndLink(csproj);
}
}
}

View File

@@ -0,0 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<IsPackable>false</IsPackable>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
</PropertyGroup>
<ItemGroup>
<Content Include="MusicStoreReflection.xml">
<!-- It doesn't seem to get copied unless we specify this
explicitly. -->
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Compile Include="IntegrationTestBase.cs" />
<Compile Include="TestContext.cs" />
<Compile Include="MusicStoreTest.cs" />
<Compile Include="HelloWorldTest.cs" />
<Compile Include="WebApiTest.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.0-beta1-build3642" />
</ItemGroup>
</Project>