diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 9a6fcf9ff5..476c3c585f 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -337,6 +337,20 @@ function Publish-Package Publish-PackageInternal $testHostx86Project $TPB_TargetFramework $testhostFullPackageDir Publish-PackageWithRuntimeInternal $testHostx86Project $TPB_TargetFrameworkCore20 $TPB_X86_Runtime false $testhostCorePackageTempX86Dir + # Copy the .NET multitarget testhost exes to destination folder (except for net451 which is the default) + foreach ($tfm in "net452;net46;net461;net462;net47;net471;net472;net48" -split ";") { + Copy-Item "$(Split-Path $testHostProject)\bin\$TPB_Configuration\$tfm\$TPB_X64_Runtime\testhost.exe" $testhostFullPackageDir\testhost.$tfm.exe -Force + Copy-Item "$(Split-Path $testHostProject)\bin\$TPB_Configuration\$tfm\$TPB_X64_Runtime\testhost.pdb" $testhostFullPackageDir\testhost.$tfm.pdb -Force + Copy-Item "$(Split-Path $testHostProject)\bin\$TPB_Configuration\$tfm\$TPB_X64_Runtime\testhost.exe.config" $testhostFullPackageDir\testhost.$tfm.exe.config -Force + } + + # Copy the .NET multitarget testhost.x86 exes to destination folder (except for net451 which is the default) + foreach ($tfm in "net452;net46;net461;net462;net47;net471;net472;net48" -split ";") { + Copy-Item "$(Split-Path $testHostx86Project)\bin\$TPB_Configuration\$tfm\$TPB_X86_Runtime\testhost.x86.exe" $testhostFullPackageDir\testhost.$tfm.x86.exe -Force + Copy-Item "$(Split-Path $testHostx86Project)\bin\$TPB_Configuration\$tfm\$TPB_X86_Runtime\testhost.x86.pdb" $testhostFullPackageDir\testhost.$tfm.x86.pdb -Force + Copy-Item "$(Split-Path $testHostx86Project)\bin\$TPB_Configuration\$tfm\$TPB_X86_Runtime\testhost.x86.exe.config" $testhostFullPackageDir\testhost.$tfm.x86.exe.config -Force + } + # Copy the .NET core x86 and x64 testhost exes from tempPublish to required folder New-Item -ItemType directory -Path $testhostCorePackageX64Dir -Force | Out-Null Copy-Item $testhostCorePackageTempX64Dir\testhost* $testhostCorePackageX64Dir -Force -recurse diff --git a/scripts/verify-nupkgs.ps1 b/scripts/verify-nupkgs.ps1 index fa76cc696e..ca37e0fffb 100644 --- a/scripts/verify-nupkgs.ps1 +++ b/scripts/verify-nupkgs.ps1 @@ -14,12 +14,12 @@ function Verify-Nuget-Packages($packageDirectory) Write-Log "Starting Verify-Nuget-Packages." $expectedNumOfFiles = @{"Microsoft.CodeCoverage" = 29; "Microsoft.NET.Test.Sdk" = 13; - "Microsoft.TestPlatform" = 437; + "Microsoft.TestPlatform" = 469; "Microsoft.TestPlatform.Build" = 19; - "Microsoft.TestPlatform.CLI" = 318; + "Microsoft.TestPlatform.CLI" = 350; "Microsoft.TestPlatform.Extensions.TrxLogger" = 33; "Microsoft.TestPlatform.ObjectModel" = 62; - "Microsoft.TestPlatform.Portable" = 502; + "Microsoft.TestPlatform.Portable" = 566; "Microsoft.TestPlatform.TestHost" = 145; "Microsoft.TestPlatform.TranslationLayer" = 121} diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyOperationManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyOperationManager.cs index d184f521ee..aa0c7a40a0 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyOperationManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyOperationManager.cs @@ -105,6 +105,7 @@ public virtual bool SetupChannel(IEnumerable sources, string runSettings { this.testHostProcessStdError = string.Empty; TestHostConnectionInfo testHostConnectionInfo = this.testHostManager.GetTestHostConnectionInfo(); + var portNumber = 0; if (testHostConnectionInfo.Role == ConnectionRole.Client) diff --git a/src/Microsoft.TestPlatform.TestHostProvider/Hosting/DefaultTestHostManager.cs b/src/Microsoft.TestPlatform.TestHostProvider/Hosting/DefaultTestHostManager.cs index eec25101ae..db60124fd1 100644 --- a/src/Microsoft.TestPlatform.TestHostProvider/Hosting/DefaultTestHostManager.cs +++ b/src/Microsoft.TestPlatform.TestHostProvider/Hosting/DefaultTestHostManager.cs @@ -39,15 +39,15 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Hosting [FriendlyName(DefaultTestHostFriendlyName)] public class DefaultTestHostManager : ITestRuntimeProvider2 { - private const string X64TestHostProcessName = "testhost.exe"; - private const string X86TestHostProcessName = "testhost.x86.exe"; + private const string X64TestHostProcessName = "testhost{0}.exe"; + private const string X86TestHostProcessName = "testhost{0}.x86.exe"; private const string DefaultTestHostUri = "HostProvider://DefaultTestHost"; private const string DefaultTestHostFriendlyName = "DefaultTestHost"; private const string TestAdapterEndsWithPattern = @"TestAdapter.dll"; private Architecture architecture; - + private Framework targetFramework; private IProcessHelper processHelper; private IFileHelper fileHelper; private IEnvironment environment; @@ -136,8 +136,25 @@ public virtual TestProcessStartInfo GetTestHostProcessStartInfo( IDictionary environmentVariables, TestRunnerConnectionInfo connectionInfo) { - // Default test host manager supports shared test sources - var testHostProcessName = (this.architecture == Architecture.X86) ? X86TestHostProcessName : X64TestHostProcessName; + string testHostProcessName; + if (this.targetFramework.Name.StartsWith(".NETFramework,Version=v")) + { + var targetFrameworkMoniker = "net" + this.targetFramework.Name.Replace(".NETFramework,Version=v", string.Empty).Replace(".", string.Empty); + + // Net451 or older will use the default testhost.exe that is compiled against net451. + var isSupportedNetTarget = new[] { "net452", "net46", "net461", "net462", "net47", "net471", "net472", "net48" }.Contains(targetFrameworkMoniker); + var targetFrameworkSuffix = isSupportedNetTarget ? $".{targetFrameworkMoniker}" : string.Empty; + + // Default test host manager supports shared test sources + testHostProcessName = string.Format(this.architecture == Architecture.X86 ? X86TestHostProcessName : X64TestHostProcessName, targetFrameworkSuffix); + } + else + { + // This path is probably happening only in our tests, because otherwise we are first running CanExecuteCurrentRunConfiguration + // which would disqualify anything that is not netframework. + testHostProcessName = string.Format(this.architecture == Architecture.X86 ? X86TestHostProcessName : X64TestHostProcessName, string.Empty); + } + var currentWorkingDirectory = Path.Combine(Path.GetDirectoryName(typeof(DefaultTestHostManager).GetTypeInfo().Assembly.Location), "..//"); var argumentsString = " " + connectionInfo.ToCommandLineOptions(); @@ -239,6 +256,7 @@ public void Initialize(IMessageLogger logger, string runsettingsXml) this.messageLogger = logger; this.architecture = runConfiguration.TargetPlatform; + this.targetFramework = runConfiguration.TargetFramework; this.testHostProcess = null; this.Shared = !runConfiguration.DisableAppDomain; diff --git a/src/package/nuspec/Microsoft.TestPlatform.Portable.nuspec b/src/package/nuspec/Microsoft.TestPlatform.Portable.nuspec index 287b34f826..8fe99cdf03 100644 --- a/src/package/nuspec/Microsoft.TestPlatform.Portable.nuspec +++ b/src/package/nuspec/Microsoft.TestPlatform.Portable.nuspec @@ -40,8 +40,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -401,8 +433,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/package/nuspec/Microsoft.TestPlatform.nuspec b/src/package/nuspec/Microsoft.TestPlatform.nuspec index 0b1e015931..c473e1bcd5 100644 --- a/src/package/nuspec/Microsoft.TestPlatform.nuspec +++ b/src/package/nuspec/Microsoft.TestPlatform.nuspec @@ -168,9 +168,41 @@ - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/testhost.x86/testhost.x86.csproj b/src/testhost.x86/testhost.x86.csproj index d35578cbfb..244737eb76 100644 --- a/src/testhost.x86/testhost.x86.csproj +++ b/src/testhost.x86/testhost.x86.csproj @@ -6,7 +6,7 @@ testhost.x86 - netcoreapp2.1;net451 + netcoreapp2.1;net451;net452;net46;net461;net462;net47;net471;net472;net48 netcoreapp2.1 true AnyCPU diff --git a/src/testhost/testhost.csproj b/src/testhost/testhost.csproj index 66928e9c0f..494fcb5ab6 100644 --- a/src/testhost/testhost.csproj +++ b/src/testhost/testhost.csproj @@ -6,12 +6,12 @@ testhost - netcoreapp2.1;net451 + netcoreapp2.1;net451;net452;net46;net461;net462;net47;net471;net472;net48 netcoreapp2.1 Exe app.manifest - + win7-x64 false diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/AcceptanceTestBase.cs b/test/Microsoft.TestPlatform.AcceptanceTests/AcceptanceTestBase.cs index 772a971866..df0d013624 100644 --- a/test/Microsoft.TestPlatform.AcceptanceTests/AcceptanceTestBase.cs +++ b/test/Microsoft.TestPlatform.AcceptanceTests/AcceptanceTestBase.cs @@ -9,13 +9,32 @@ namespace Microsoft.TestPlatform.AcceptanceTests public class AcceptanceTestBase : IntegrationTestBase { + public const string Net451TargetFramework = "net451"; + public const string Net452TargetFramework = "net452"; + public const string Net46TargetFramework = "net46"; + public const string Net461TargetFramework = "net461"; + public const string Net462TargetFramework = "net462"; + public const string Net47TargetFramework = "net47"; + public const string Net471TargetFramework = "net471"; + public const string Net472TargetFramework = "net472"; + public const string Net48TargetFramework = "net48"; public const string DesktopTargetFramework = "net451"; public const string Core21TargetFramework = "netcoreapp2.1"; public const string Core31TargetFramework = "netcoreapp3.1"; + public const string DesktopFrameworkArgValue = ".NETFramework,Version=v4.5.1"; + public const string Net451FrameworkArgValue = ".NETFramework,Version=v4.5.1"; + public const string Net452FrameworkArgValue = ".NETFramework,Version=v4.5.2"; + public const string Net46FrameworkArgValue = ".NETFramework,Version=v4.6"; + public const string Net461FrameworkArgValue = ".NETFramework,Version=v4.6.1"; + public const string Net462FrameworkArgValue = ".NETFramework,Version=v4.6.2"; + public const string Net47FrameworkArgValue = ".NETFramework,Version=v4.7"; + public const string Net471FrameworkArgValue = ".NETFramework,Version=v4.7.1"; + public const string Net472FrameworkArgValue = ".NETFramework,Version=v4.7.2"; + public const string Net48FrameworkArgValue = ".NETFramework,Version=v4.8"; + public const string Core21FrameworkArgValue = ".NETCoreApp,Version=v2.1"; public const string Core31FrameworkArgValue = ".NETCoreApp,Version=v3.1"; - public const string DesktopFrameworkArgValue = ".NETFramework,Version=v4.5.1"; public const string DesktopRunnerTargetRuntime = "win7-x64"; public const string CoreRunnerTargetRuntime = ""; public const string InIsolation = "/InIsolation"; @@ -37,8 +56,24 @@ protected static string DeriveFrameworkArgValue(IntegrationTestEnvironment testE return Core21FrameworkArgValue; case Core31TargetFramework: return Core31FrameworkArgValue; - case DesktopTargetFramework: - return DesktopFrameworkArgValue; + case Net451TargetFramework: + return Net451FrameworkArgValue; + case Net452TargetFramework: + return Net452FrameworkArgValue; + case Net46TargetFramework: + return Net46FrameworkArgValue; + case Net461TargetFramework: + return Net461FrameworkArgValue; + case Net462TargetFramework: + return Net462FrameworkArgValue; + case Net47TargetFramework: + return Net47FrameworkArgValue; + case Net471TargetFramework: + return Net471FrameworkArgValue; + case Net472TargetFramework: + return Net472FrameworkArgValue; + case Net48TargetFramework: + return Net48FrameworkArgValue; default: throw new NotSupportedException($"{testEnvironment.TargetFramework} is not supported TargetFramework value."); } diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/Extension/NetCoreTargetFrameworkDataSource.cs b/test/Microsoft.TestPlatform.AcceptanceTests/Extension/NetCoreTargetFrameworkDataSource.cs index d17feb364d..a87b0af6b3 100644 --- a/test/Microsoft.TestPlatform.AcceptanceTests/Extension/NetCoreTargetFrameworkDataSource.cs +++ b/test/Microsoft.TestPlatform.AcceptanceTests/Extension/NetCoreTargetFrameworkDataSource.cs @@ -63,6 +63,18 @@ public NetCoreTargetFrameworkDataSource( } } + /// + /// Initializes a new instance of the class. + /// + /// To run tests with desktop runner(vstest.console.exe), use AcceptanceTestBase.Net452TargetFramework or alike values. + public NetCoreTargetFrameworkDataSource(string[] targetFrameworks) + { + foreach (var fmw in targetFrameworks) + { + this.AddRunnerDataRow(IntegrationTestBase.CoreRunnerFramework, fmw); + } + } + private void AddRunnerDataRow(string runnerFramework, string targetFramework) { var runnerInfo = new RunnerInfo(runnerFramework, targetFramework); diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/Extension/NetFullTargetFrameworkDataSource.cs b/test/Microsoft.TestPlatform.AcceptanceTests/Extension/NetFullTargetFrameworkDataSource.cs index c02c40a2c0..928531e501 100644 --- a/test/Microsoft.TestPlatform.AcceptanceTests/Extension/NetFullTargetFrameworkDataSource.cs +++ b/test/Microsoft.TestPlatform.AcceptanceTests/Extension/NetFullTargetFrameworkDataSource.cs @@ -48,10 +48,33 @@ public NetFullTargetFrameworkDataSource(bool inIsolation = true, bool inProcess } } + /// + /// Initializes a new instance of the class. + /// + /// To run tests with desktop runner(vstest.console.exe), use AcceptanceTestBase.Net452TargetFramework or alike values. + public NetFullTargetFrameworkDataSource(string[] targetFrameworks, bool inIsolation = true, bool inProcess = false) + { + if (inIsolation) + { + foreach (var fmw in targetFrameworks) + { + this.dataRows.Add(new object[] { new RunnerInfo(IntegrationTestBase.DesktopRunnerFramework, fmw, AcceptanceTestBase.InIsolation) }); + } + } + + if (inProcess) + { + foreach (var fmw in targetFrameworks) + { + this.dataRows.Add(new object[] { new RunnerInfo(IntegrationTestBase.DesktopRunnerFramework, fmw) }); + } + } + } + /// /// Gets or sets the data rows. /// - private List dataRows; + private List dataRows = new List(); public IEnumerable GetData(MethodInfo methodInfo) { diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/FrameworkTests.cs b/test/Microsoft.TestPlatform.AcceptanceTests/FrameworkTests.cs index 69bf2cb06f..dd8426a279 100644 --- a/test/Microsoft.TestPlatform.AcceptanceTests/FrameworkTests.cs +++ b/test/Microsoft.TestPlatform.AcceptanceTests/FrameworkTests.cs @@ -16,7 +16,7 @@ public void FrameworkArgumentShouldWork(RunnerInfo runnerInfo) { AcceptanceTestBase.SetTestEnvironment(this.testEnvironment, runnerInfo); - var arguments = PrepareArguments(GetSampleTestAssembly(), string.Empty, string.Empty, this.FrameworkArgValue); + var arguments = PrepareArguments(GetSampleTestAssembly(), string.Empty, string.Empty, string.Empty); arguments = string.Concat(arguments, " ", $"/Framework:{this.FrameworkArgValue}"); this.InvokeVsTest(arguments); @@ -30,7 +30,7 @@ public void FrameworkShortNameArgumentShouldWork(RunnerInfo runnerInfo) { AcceptanceTestBase.SetTestEnvironment(this.testEnvironment, runnerInfo); - var arguments = PrepareArguments(GetSampleTestAssembly(), string.Empty, string.Empty, this.testEnvironment.TargetFramework); + var arguments = PrepareArguments(GetSampleTestAssembly(), string.Empty, string.Empty, string.Empty); arguments = string.Concat(arguments, " ", $"/Framework:{this.testEnvironment.TargetFramework}"); this.InvokeVsTest(arguments); @@ -44,7 +44,7 @@ public void OnWrongFrameworkPassedTestRunShouldNotRun(RunnerInfo runnerInfo) { AcceptanceTestBase.SetTestEnvironment(this.testEnvironment, runnerInfo); - var arguments = PrepareArguments(GetSampleTestAssembly(), string.Empty, string.Empty, this.FrameworkArgValue); + var arguments = PrepareArguments(GetSampleTestAssembly(), string.Empty, string.Empty, string.Empty); if (runnerInfo.TargetFramework.Contains("netcore")) { arguments = string.Concat(arguments, " ", "/Framework:Framework45"); @@ -72,7 +72,7 @@ public void RunSpecificTestsShouldWorkWithFrameworkInCompatibleWarning(RunnerInf { AcceptanceTestBase.SetTestEnvironment(this.testEnvironment, runnerInfo); - var arguments = PrepareArguments(GetSampleTestAssembly(), string.Empty, string.Empty, this.FrameworkArgValue); + var arguments = PrepareArguments(GetSampleTestAssembly(), string.Empty, string.Empty, string.Empty); arguments = string.Concat(arguments, " ", "/tests:PassingTest"); arguments = string.Concat(arguments, " ", "/Framework:Framework40"); diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/MultitargetingTestHostTests.cs b/test/Microsoft.TestPlatform.AcceptanceTests/MultitargetingTestHostTests.cs new file mode 100644 index 0000000000..c560a23cfe --- /dev/null +++ b/test/Microsoft.TestPlatform.AcceptanceTests/MultitargetingTestHostTests.cs @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.TestPlatform.AcceptanceTests +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + using System; + using static AcceptanceTestBase; + + [TestClass] + public class MultitargetingTestHostTests : AcceptanceTestBase + { + [TestMethod] + // the underlying test is using xUnit to avoid AppDomain enhancements in MSTest that make this pass even without multitargetting + // xUnit supports net452 onwards, so that is why this starts at net452, I also don't test all framework versions + [NetCoreTargetFrameworkDataSource(targetFrameworks: new string[] { Net452TargetFramework, Net461TargetFramework, Net472TargetFramework, Net48TargetFramework })] + [NetFullTargetFrameworkDataSource(targetFrameworks: new string[] { Net452TargetFramework, Net461TargetFramework, Net472TargetFramework, Net48TargetFramework })] + public void RunningTestWithAFailingDebugAssertDoesNotCrashTheHostingProcess(RunnerInfo runnerInfo) + { + AcceptanceTestBase.SetTestEnvironment(this.testEnvironment, runnerInfo); + + var assemblyPath = this.BuildMultipleAssemblyPath("MultitargetedNetFrameworkProject.dll").Trim('\"'); + var arguments = PrepareArguments(assemblyPath, null, null, this.FrameworkArgValue, runnerInfo.InIsolationValue); + this.InvokeVsTest(arguments); + + this.ValidateSummaryStatus(passedTestsCount: 1, failedTestsCount: 0, 0); + } + } +} \ No newline at end of file diff --git a/test/Microsoft.TestPlatform.TestHostProvider.UnitTests/Hosting/DefaultTestHostManagerTests.cs b/test/Microsoft.TestPlatform.TestHostProvider.UnitTests/Hosting/DefaultTestHostManagerTests.cs index e287a340bd..4e1f1eb0b6 100644 --- a/test/Microsoft.TestPlatform.TestHostProvider.UnitTests/Hosting/DefaultTestHostManagerTests.cs +++ b/test/Microsoft.TestPlatform.TestHostProvider.UnitTests/Hosting/DefaultTestHostManagerTests.cs @@ -172,7 +172,7 @@ public void GetTestHostProcessStartInfoShouldNotUseMonoAsHostOnNonWindowsIfStart this.mockProcessHelper.Setup(p => p.GetCurrentProcessFileName()).Returns("/usr/bin/mono"); this.mockEnvironment.Setup(e => e.OperatingSystem).Returns(PlatformOperatingSystem.Unix); this.mockDotnetHostHelper.Setup(d => d.GetMonoPath()).Returns("/usr/bin/mono"); - var source = "C:\temp\a.dll"; + var source = @"C:\temp\a.dll"; var info = this.testHostManager.GetTestHostProcessStartInfo( new List() { source }, diff --git a/test/Microsoft.TestPlatform.TestUtilities/IntegrationTestBase.cs b/test/Microsoft.TestPlatform.TestUtilities/IntegrationTestBase.cs index 83d29a2137..8dd3b2aa1a 100644 --- a/test/Microsoft.TestPlatform.TestUtilities/IntegrationTestBase.cs +++ b/test/Microsoft.TestPlatform.TestUtilities/IntegrationTestBase.cs @@ -84,6 +84,12 @@ public static string PrepareArguments(string testAssembly, string testAdapterPat arguments = string.Concat(arguments, " /settings:", runSettings.AddDoubleQuote()); } + if (!string.IsNullOrWhiteSpace(framework)) + { + // Append run settings + arguments = string.Concat(arguments, " /framework:", framework.AddDoubleQuote()); + } + arguments = string.Concat(arguments, " /logger:", "console;verbosity=normal".AddDoubleQuote()); if (!string.IsNullOrWhiteSpace(inIsolation)) diff --git a/test/TestAssets/MultitargetedNetFrameworkProject/MultitargetedNetFrameworkProject.csproj b/test/TestAssets/MultitargetedNetFrameworkProject/MultitargetedNetFrameworkProject.csproj new file mode 100644 index 0000000000..558f07b7d5 Binary files /dev/null and b/test/TestAssets/MultitargetedNetFrameworkProject/MultitargetedNetFrameworkProject.csproj differ diff --git a/test/TestAssets/MultitargetedNetFrameworkProject/UnitTest1.cs b/test/TestAssets/MultitargetedNetFrameworkProject/UnitTest1.cs new file mode 100644 index 0000000000..a7b364d9a0 --- /dev/null +++ b/test/TestAssets/MultitargetedNetFrameworkProject/UnitTest1.cs @@ -0,0 +1,85 @@ +using System; +using System.IO; +using System.Net.Security; +using System.Security.Authentication; +using Xunit; + +namespace MultitargetedNetFrameworkProject +{ + public class UnitTest1 + { + +#if NET451 + public string TargetFramework { get; } = "NET451"; +#endif + +#if NET452 + public string TargetFramework { get; } = "NET452"; +#endif + +#if NET46 + public string TargetFramework { get; } = "NET46"; +#endif + +#if NET461 + public string TargetFramework { get; } = "NET461"; +#endif + +#if NET462 + public string TargetFramework { get; } = "NET462"; +#endif + +#if NET47 + public string TargetFramework { get; } = "NET47"; +#endif + +#if NET471 + public string TargetFramework { get; } = "NET471"; +#endif + +#if NET472 + public string TargetFramework { get; } = "NET472"; +#endif + +#if NET48 + public string TargetFramework { get; } = "NET48"; +#endif + // Using xUnit here because MSTest uses AppDomains by default and fixes this problem for us + // as long as the appdomains are enabled and modern .NET Framework is installed. + [Fact] + public void FailsUntilNet462ButPassesOnNewerNetFramework() + { + Exception exception = null; + try + { + MemoryStream stream = new MemoryStream(); + SslStream sslStream = new SslStream(stream); + + // this throws SSLException on net451-net462, on net471 onwards it passes so we can use it to test that we target correctly + sslStream.BeginAuthenticateAsClient("microsoft.com", null, SslProtocols.None, false, new AsyncCallback(ProcessInformation), null); + } + catch (Exception ex) + { + exception = ex; + } + + switch (this.TargetFramework) + { + case "NET451": + case "NET452": + case "NET46": + case "NET461": + case "NET462": + Assert.NotNull(exception); + break; + default: + Assert.Null(exception); + break; + } + } + + static void ProcessInformation(IAsyncResult result) + { + } + } +} diff --git a/test/TestAssets/TestAssets.sln/TestAssets.sln b/test/TestAssets/TestAssets.sln/TestAssets.sln index 325d36db55..0be52ca562 100644 --- a/test/TestAssets/TestAssets.sln/TestAssets.sln +++ b/test/TestAssets/TestAssets.sln/TestAssets.sln @@ -74,6 +74,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CoverletCoverageTestProject EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CodeCoverageTest", "..\CodeCoverageTest\CodeCoverageTest.csproj", "{23790570-66D2-4CD5-9CD0-F8787C5B61BF}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MultitargetedNetFrameworkProject", "..\MultitargetedNetFrameworkProject\MultitargetedNetFrameworkProject.csproj", "{E2F1E03B-002A-4A3E-BAFC-8F2F0AB5B86F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -480,6 +482,18 @@ Global {23790570-66D2-4CD5-9CD0-F8787C5B61BF}.Release|x64.Build.0 = Release|Any CPU {23790570-66D2-4CD5-9CD0-F8787C5B61BF}.Release|x86.ActiveCfg = Release|Any CPU {23790570-66D2-4CD5-9CD0-F8787C5B61BF}.Release|x86.Build.0 = Release|Any CPU + {E2F1E03B-002A-4A3E-BAFC-8F2F0AB5B86F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E2F1E03B-002A-4A3E-BAFC-8F2F0AB5B86F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E2F1E03B-002A-4A3E-BAFC-8F2F0AB5B86F}.Debug|x64.ActiveCfg = Debug|Any CPU + {E2F1E03B-002A-4A3E-BAFC-8F2F0AB5B86F}.Debug|x64.Build.0 = Debug|Any CPU + {E2F1E03B-002A-4A3E-BAFC-8F2F0AB5B86F}.Debug|x86.ActiveCfg = Debug|Any CPU + {E2F1E03B-002A-4A3E-BAFC-8F2F0AB5B86F}.Debug|x86.Build.0 = Debug|Any CPU + {E2F1E03B-002A-4A3E-BAFC-8F2F0AB5B86F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E2F1E03B-002A-4A3E-BAFC-8F2F0AB5B86F}.Release|Any CPU.Build.0 = Release|Any CPU + {E2F1E03B-002A-4A3E-BAFC-8F2F0AB5B86F}.Release|x64.ActiveCfg = Release|Any CPU + {E2F1E03B-002A-4A3E-BAFC-8F2F0AB5B86F}.Release|x64.Build.0 = Release|Any CPU + {E2F1E03B-002A-4A3E-BAFC-8F2F0AB5B86F}.Release|x86.ActiveCfg = Release|Any CPU + {E2F1E03B-002A-4A3E-BAFC-8F2F0AB5B86F}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE