Add Binding redirects tests

This commit is contained in:
Sridhar Periyasamy 2016-04-21 13:41:22 -07:00
parent 4ccd88d00e
commit c82d3cc08d
25 changed files with 645 additions and 55 deletions

View file

@ -266,7 +266,11 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
public string GetExecutableExtension()
{
#if NET451
return ".exe";
#else
return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : "";
#endif
}
private string BuildArgs()

View file

@ -104,7 +104,11 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
public string GetExecutableExtension()
{
#if NET451
return ".exe";
#else
return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : "";
#endif
}
private string BuildArgs()

View file

@ -14,6 +14,8 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
public class TestCommand
{
protected string _command;
private string _baseDirectory;
public string WorkingDirectory { get; set; }
@ -24,6 +26,11 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
public TestCommand(string command)
{
_command = command;
#if NET451
_baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
#else
_baseDirectory = AppContext.BaseDirectory;
#endif
}
public virtual CommandResult Execute(string args = "")
@ -63,7 +70,7 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
var command = _command;
ResolveCommand(ref command, ref args);
var commandPath = Env.GetCommandPath(command, ".exe", ".cmd", "") ??
Env.GetCommandPathFromRootPath(AppContext.BaseDirectory, command, ".exe", ".cmd", "");
Env.GetCommandPathFromRootPath(_baseDirectory, command, ".exe", ".cmd", "");
Console.WriteLine($"Executing (Captured Output) - {commandPath} {args}");
@ -102,7 +109,7 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
if (!Path.IsPathRooted(executable))
{
executable = Env.GetCommandPath(executable) ??
Env.GetCommandPathFromRootPath(AppContext.BaseDirectory, executable);
Env.GetCommandPathFromRootPath(_baseDirectory, executable);
}
}
@ -153,12 +160,17 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
Arguments = args,
RedirectStandardError = true,
RedirectStandardOutput = true,
RedirectStandardInput = true
RedirectStandardInput = true,
UseShellExecute = false
};
foreach (var item in Environment)
{
#if NET451
psi.EnvironmentVariables[item.Key] = item.Value;
#else
psi.Environment[item.Key] = item.Value;
#endif
}
if (!string.IsNullOrWhiteSpace(WorkingDirectory))

View file

@ -8,7 +8,11 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
{
internal static class ProcessExtensions
{
#if NET451
private static readonly bool _isWindows = true;
#else
private static readonly bool _isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
#endif
private static readonly TimeSpan _defaultTimeout = TimeSpan.FromSeconds(30);
public static void KillTree(this Process process)

View file

@ -33,7 +33,11 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
return s_repoRoot;
}
string directory = AppContext.BaseDirectory;
#if NET451
string directory = AppDomain.CurrentDomain.BaseDirectory;
#else
string directory = AppContext.BaseDirectory;
#endif
while (!Directory.Exists(Path.Combine(directory, ".git")) && directory != null)
{

View file

@ -5,13 +5,6 @@
"keyFile": "../../tools/Key.snk"
},
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0-rc2-*"
},
"System.Runtime.Serialization.Primitives": "4.1.1-rc2-24022",
"System.Collections.Immutable": "1.2.0-rc2-24022",
"System.Net.NetworkInformation": "4.1.0-rc2-24022",
"FluentAssertions": "4.0.0",
"xunit": "2.1.0",
"dotnet-test-xunit": "1.0.0-rc2-162081-13",
@ -27,8 +20,22 @@
"netcoreapp1.0": {
"imports": [
"dotnet5.4",
"portable-net451+win8"
]
"portable-net451+win8"
],
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0-rc2-*"
},
"System.Runtime.Serialization.Primitives": "4.1.1-rc2-24022",
"System.Collections.Immutable": "1.2.0-rc2-24022",
"System.Net.NetworkInformation": "4.1.0-rc2-24022"
},
"net451": {
"frameworkAssemblies": {
"System.Runtime": {
"type": "build"
}
}
}
}
}

View file

@ -0,0 +1,287 @@
// 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.Configuration;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Xml.Linq;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.Test.Utilities;
using Microsoft.DotNet.TestFramework;
using Microsoft.Extensions.PlatformAbstractions;
using Xunit;
using FluentAssertions;
namespace Microsoft.DotNet.Tests
{
public class TestSetupFixture : TestBase
{
private const string Framework = "net451";
private const string Config = "Debug";
private const string AppWithConfig = "AppWithRedirectsAndConfig";
private const string AppWithoutConfig = "AppWithRedirectsNoConfig";
private string _Runtime = PlatformServices.Default.Runtime.GetLegacyRestoreRuntimeIdentifier();
private string _desktopProjectsRoot = Path.Combine(RepoRoot, "TestAssets", "DesktopTestProjects");
private string _buildRelativePath;
private string _appWithConfigBuildDir;
private string _appWithConfigPublishDir;
private string _appWithoutConfigBuildDir;
private string _appWithoutConfigPublishDir;
private TestInstance _testInstance;
public string AppWithConfigBuildOutput { get; }
public string AppWithConfigPublishOutput { get; }
public string AppWithoutConfigBuildOutput { get; }
public string AppWithoutConfigPublishOutput { get; }
public TestSetupFixture()
{
_buildRelativePath = Path.Combine("bin", Config, Framework, _Runtime);
var testAssetsMgr = new TestAssetsManager(_desktopProjectsRoot);
_testInstance = testAssetsMgr.CreateTestInstance("BindingRedirectSample")
.WithLockFiles();
Setup(AppWithConfig, ref _appWithConfigBuildDir, ref _appWithConfigPublishDir);
Setup(AppWithoutConfig, ref _appWithoutConfigBuildDir, ref _appWithoutConfigPublishDir);
AppWithConfigBuildOutput = Path.Combine(_appWithConfigBuildDir, AppWithConfig + ".exe");
AppWithConfigPublishOutput = Path.Combine(_appWithConfigPublishDir, AppWithConfig + ".exe");
AppWithoutConfigBuildOutput = Path.Combine(_appWithoutConfigBuildDir, AppWithoutConfig + ".exe");
AppWithoutConfigPublishOutput = Path.Combine(_appWithoutConfigPublishDir, AppWithoutConfig + ".exe");
}
private void Setup(string project, ref string buildDir, ref string publishDir)
{
string projectRoot = Path.Combine(_testInstance.TestRoot, project);
buildDir = Path.Combine(projectRoot, _buildRelativePath);
publishDir = Path.Combine(projectRoot, "publish");
var buildCommand = new BuildCommand(projectRoot, framework: Framework, runtime: _Runtime);
buildCommand.Execute().Should().Pass();
var publishCommand = new PublishCommand(projectRoot, output: publishDir, framework: Framework, runtime: _Runtime);
publishCommand.Execute().Should().Pass();
}
}
public class GivenAnAppWithRedirectsAndExecutableDependency : TestBase, IClassFixture<TestSetupFixture>
{
private const string ExecutableDependency = "dotnet-desktop-binding-redirects.exe";
private TestSetupFixture _testSetup;
private string _appWithConfigBuildOutput;
private string _appWithoutConfigBuildOutput;
private string _appWithConfigPublishOutput;
private string _appWithoutConfigPublishOutput;
private string _executableDependencyBuildOutput;
private string _executableDependencyPublishOutput;
public GivenAnAppWithRedirectsAndExecutableDependency(TestSetupFixture testSetup)
{
_testSetup = testSetup;
_appWithConfigBuildOutput = _testSetup.AppWithConfigBuildOutput;
_appWithConfigPublishOutput = _testSetup.AppWithConfigPublishOutput;
_appWithoutConfigBuildOutput = _testSetup.AppWithoutConfigBuildOutput;
_appWithoutConfigPublishOutput = _testSetup.AppWithoutConfigPublishOutput;
_executableDependencyBuildOutput = Path.Combine(Path.GetDirectoryName(_appWithConfigBuildOutput), ExecutableDependency);
_executableDependencyPublishOutput = Path.Combine(Path.GetDirectoryName(_appWithConfigPublishOutput), ExecutableDependency);
}
private static List<string> BindingsAppNoConfig
{
get
{
List<string> bindings = new List<string>()
{
@"<dependentAssembly xmlns=""urn:schemas-microsoft-com:asm.v1"">
<assemblyIdentity name=""Newtonsoft.Json"" publicKeyToken=""30ad4fe6b2a6aeed"" culture=""neutral"" />
<bindingRedirect oldVersion=""4.5.0.0"" newVersion=""8.0.0.0"" />
<bindingRedirect oldVersion=""6.0.0.0"" newVersion=""8.0.0.0"" />
</dependentAssembly>",
@"<dependentAssembly xmlns=""urn:schemas-microsoft-com:asm.v1"">
<assemblyIdentity name=""System.Web.Mvc"" publicKeyToken=""31bf3856ad364e35"" culture=""neutral"" />
<bindingRedirect oldVersion=""4.0.0.0"" newVersion=""3.0.0.1"" />
</dependentAssembly>"
};
return bindings;
}
}
private static List<string> BindingsAppWithConfig
{
get
{
List<string> bindings = new List<string>()
{
@"<dependentAssembly xmlns=""urn:schemas-microsoft-com:asm.v1"">
<assemblyIdentity name=""Newtonsoft.Json"" publicKeyToken=""30ad4fe6b2a6aeed"" culture=""neutral"" />
<bindingRedirect oldVersion=""3.5.0.0"" newVersion=""8.0.0.0"" />
<bindingRedirect oldVersion=""4.5.0.0"" newVersion=""8.0.0.0"" />
<bindingRedirect oldVersion=""6.0.0.0"" newVersion=""8.0.0.0"" />
</dependentAssembly>",
@"<dependentAssembly xmlns=""urn:schemas-microsoft-com:asm.v1"">
<assemblyIdentity name=""Some.Foo.Assembly"" publicKeyToken=""814f48568d36eed5"" culture=""neutral"" />
<bindingRedirect oldVersion=""3.0.0.0"" newVersion=""5.5.5.1"" />
</dependentAssembly>",
@"<dependentAssembly xmlns=""urn:schemas-microsoft-com:asm.v1"">
<assemblyIdentity name=""System.Web.Mvc"" publicKeyToken=""31bf3856ad364e35"" culture=""neutral"" />
<bindingRedirect oldVersion=""4.0.0.0"" newVersion=""3.0.0.1"" />
</dependentAssembly>"
};
return bindings;
}
}
private static List<XElement> ExpectedBindingsAppNoConfig
{
get
{
List<XElement> bindingElements = new List<XElement>();
foreach (var binding in BindingsAppNoConfig)
{
bindingElements.Add(XElement.Parse(binding));
}
return bindingElements;
}
}
private static List<XElement> ExpectedBindingsAppWithConfig
{
get
{
List<XElement> bindingElements = new List<XElement>();
foreach (var binding in BindingsAppWithConfig)
{
bindingElements.Add(XElement.Parse(binding));
}
return bindingElements;
}
}
private static Dictionary<string, string> ExpectedAppSettings
{
get
{
Dictionary<string, string> appSettings = new Dictionary<string, string>()
{
{"Setting1", "Hello"},
{"Setting2", "World"}
};
return appSettings;
}
}
private IEnumerable<XElement> GetRedirects(string exePath)
{
var configFile = exePath + ".config";
File.Exists(configFile).Should().BeTrue($"Config file not found - {configFile}");
var config = ConfigurationManager.OpenExeConfiguration(exePath);
var runtimeSectionXml = config.Sections["runtime"].SectionInformation.GetRawXml();
var runtimeSectionElement = XElement.Parse(runtimeSectionXml);
var redirects = runtimeSectionElement.Elements()
.Where(e => e.Name.LocalName == "assemblyBinding").Elements()
.Where(e => e.Name.LocalName == "dependentAssembly");
return redirects;
}
private void VerifyRedirects(IEnumerable<XElement> redirects, IEnumerable<XElement> generatedBindings)
{
foreach (var binding in generatedBindings)
{
var redirect = redirects.SingleOrDefault(r => /*XNode.DeepEquals(r, binding)*/ r.ToString() == binding.ToString());
redirect.Should().NotBeNull($"Binding not found in runtime section : {Environment.NewLine}{binding}");
}
}
private void VerifyAppSettings(string exePath)
{
var configFile = ConfigurationManager.OpenExeConfiguration(exePath);
foreach (var appSetting in ExpectedAppSettings)
{
var value = configFile.AppSettings.Settings[appSetting.Key];
value.Should().NotBeNull($"AppSetting with key '{appSetting.Key}' not found in config file.");
value.Value.Should().Be(appSetting.Value, $"For AppSetting '{appSetting.Key}' - Expected Value '{appSetting.Value}', Actual '{ value.Value}'");
}
}
[WindowsOnlyFact]
public void Build_Generates_Redirects_For_App_Without_Config()
{
var redirects = GetRedirects(_appWithoutConfigBuildOutput);
VerifyRedirects(redirects, ExpectedBindingsAppNoConfig);
var commandResult = new TestCommand(_appWithoutConfigBuildOutput)
.Execute();
commandResult.Should().Pass();
}
[WindowsOnlyFact]
public void Publish_Generates_Redirects_For_App_Without_Config()
{
var redirects = GetRedirects(_appWithoutConfigPublishOutput);
VerifyRedirects(redirects, ExpectedBindingsAppNoConfig);
var commandResult = new TestCommand(_appWithoutConfigPublishOutput)
.Execute();
commandResult.Should().Pass();
}
[WindowsOnlyFact]
public void Build_Generates_Redirects_For_Executable_Dependency()
{
var redirects = GetRedirects(_executableDependencyBuildOutput);
VerifyRedirects(redirects, ExpectedBindingsAppNoConfig);
var commandResult = new TestCommand(_executableDependencyBuildOutput)
.Execute();
commandResult.Should().Pass();
}
//[WindowsOnlyFact]
public void Publish_Generates_Redirects_For_Executable_Dependency()
{
var redirects = GetRedirects(_executableDependencyPublishOutput);
VerifyRedirects(redirects, ExpectedBindingsAppNoConfig);
var commandResult = new TestCommand(_executableDependencyPublishOutput)
.Execute();
commandResult.Should().Pass();
}
[WindowsOnlyFact]
public void Build_Generates_Redirects_For_App_With_Config()
{
var redirects = GetRedirects(_appWithConfigBuildOutput);
VerifyRedirects(redirects, ExpectedBindingsAppWithConfig);
VerifyAppSettings(_appWithConfigBuildOutput);
var commandResult = new TestCommand(_appWithConfigBuildOutput)
.Execute();
commandResult.Should().Pass();
}
[WindowsOnlyFact]
public void Publish_Generates_Redirects_For_App_With_Config()
{
var redirects = GetRedirects(_appWithConfigPublishOutput);
VerifyRedirects(redirects, ExpectedBindingsAppWithConfig);
VerifyAppSettings(_appWithConfigPublishOutput);
var commandResult = new TestCommand(_appWithConfigPublishOutput)
.Execute();
commandResult.Should().Pass();
}
}
}

View file

@ -0,0 +1,21 @@
<?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>27dbf851-f2e3-4fd5-bf4d-a73c81933283</ProjectGuid>
<RootNamespace>binding-redirects.Tests</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<ItemGroup>
<Service Include="{9b56c4a1-b027-48c1-8050-e344f0630b98}" />
</ItemGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

View file

@ -0,0 +1,23 @@
{
"version": "1.0.0-*",
"dependencies": {
"xunit": "2.1.0",
"dotnet-test-xunit": "1.0.0-rc2-157751-46",
"Microsoft.NETCore.Platforms": "1.0.1-*",
"Microsoft.DotNet.Tools.Tests.Utilities": {
"target": "project"
}
},
"frameworks": {
"net451": {
"frameworkAssemblies": {
"System.Configuration": ""
}
}
},
"runtimes": {
"win7-x64": {},
"win7-x86": {}
},
"testRunner": "xunit"
}