diff --git a/Directory.Build.targets b/Directory.Build.targets
index f0c700ee2e..7c2399e44e 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -5,6 +5,16 @@
<_NetFrameworkHostedCompilersVersion Condition="'$(_NetFrameworkHostedCompilersVersion)' == ''">4.11.0-3.24280.3
+
+
+ $(MSBuildWarningsAsMessages);MSB3277
+
+
@@ -70,4 +80,5 @@
+
diff --git a/eng/Versions.props b/eng/Versions.props
index db80003e5b..ea2b6c80ff 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -70,7 +70,7 @@
<_MicrosoftVSSDKBuildToolsVersion_>17.14.2119
5.0.0
13.0.3
- 9.0.11
+ 10.0.0
4.6.3
8.0.0
18.0.0-preview-1-10911-061
diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Microsoft.TestPlatform.CoreUtilities.csproj b/src/Microsoft.TestPlatform.CoreUtilities/Microsoft.TestPlatform.CoreUtilities.csproj
index 866225a77c..6776a4de05 100644
--- a/src/Microsoft.TestPlatform.CoreUtilities/Microsoft.TestPlatform.CoreUtilities.csproj
+++ b/src/Microsoft.TestPlatform.CoreUtilities/Microsoft.TestPlatform.CoreUtilities.csproj
@@ -19,6 +19,7 @@
+
diff --git a/src/Microsoft.TestPlatform.ObjectModel/Microsoft.TestPlatform.ObjectModel.csproj b/src/Microsoft.TestPlatform.ObjectModel/Microsoft.TestPlatform.ObjectModel.csproj
index 1675d4cb00..0d20b23a19 100644
--- a/src/Microsoft.TestPlatform.ObjectModel/Microsoft.TestPlatform.ObjectModel.csproj
+++ b/src/Microsoft.TestPlatform.ObjectModel/Microsoft.TestPlatform.ObjectModel.csproj
@@ -37,6 +37,7 @@
+
diff --git a/src/datacollector/app.config b/src/datacollector/app.config
index d464fe4c5d..496f08688e 100644
--- a/src/datacollector/app.config
+++ b/src/datacollector/app.config
@@ -22,11 +22,19 @@
-
+
+
+
+
+
+
+
+
+
-
+
diff --git a/src/package/Microsoft.TestPlatform.CLI/Microsoft.TestPlatform.CLI.csproj b/src/package/Microsoft.TestPlatform.CLI/Microsoft.TestPlatform.CLI.csproj
index 696cb68cbf..f3ad7825d0 100644
--- a/src/package/Microsoft.TestPlatform.CLI/Microsoft.TestPlatform.CLI.csproj
+++ b/src/package/Microsoft.TestPlatform.CLI/Microsoft.TestPlatform.CLI.csproj
@@ -37,7 +37,7 @@
Sometimes NU1702 is not suppressed correctly, so force reducing severity of the warning.
See https://github.com/NuGet/Home/issues/9147
-->
- NU1702
+ $(MSBuildWarningsAsMessages);NU1702
diff --git a/src/package/Microsoft.TestPlatform.Portable/Microsoft.TestPlatform.Portable.csproj b/src/package/Microsoft.TestPlatform.Portable/Microsoft.TestPlatform.Portable.csproj
index 33fde7df1b..f17f680575 100644
--- a/src/package/Microsoft.TestPlatform.Portable/Microsoft.TestPlatform.Portable.csproj
+++ b/src/package/Microsoft.TestPlatform.Portable/Microsoft.TestPlatform.Portable.csproj
@@ -12,7 +12,7 @@
Sometimes NU1702 is not suppressed correctly, so force reducing severity of the warning.
See https://github.com/NuGet/Home/issues/9147
-->
- NU1702
+ $(MSBuildWarningsAsMessages);NU1702
diff --git a/src/package/Microsoft.TestPlatform/Microsoft.TestPlatform.csproj b/src/package/Microsoft.TestPlatform/Microsoft.TestPlatform.csproj
index 540e0910ea..6739984bbd 100644
--- a/src/package/Microsoft.TestPlatform/Microsoft.TestPlatform.csproj
+++ b/src/package/Microsoft.TestPlatform/Microsoft.TestPlatform.csproj
@@ -11,7 +11,7 @@
Sometimes NU1702 is not suppressed correctly, so force reducing severity of the warning.
See https://github.com/NuGet/Home/issues/9147
-->
- NU1702;NETSDK1023
+ $(MSBuildWarningsAsMessages);NU1702;NETSDK1023
diff --git a/src/testhost.x86/app.config b/src/testhost.x86/app.config
index ff5d13c675..6cda344d7d 100644
--- a/src/testhost.x86/app.config
+++ b/src/testhost.x86/app.config
@@ -35,11 +35,19 @@
-
+
+
+
+
+
+
+
+
+
-
+
diff --git a/src/vstest.console/app.config b/src/vstest.console/app.config
index 115518cc51..de2fe51c34 100644
--- a/src/vstest.console/app.config
+++ b/src/vstest.console/app.config
@@ -27,11 +27,11 @@
-
+
-
+
@@ -40,7 +40,12 @@
-
+
+
+
+
+
+
@@ -55,7 +60,7 @@
-
+
diff --git a/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/DiscoveryTests.cs b/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/DiscoveryTests.cs
index 3680b3c9bc..ef1817aeb7 100644
--- a/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/DiscoveryTests.cs
+++ b/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/DiscoveryTests.cs
@@ -6,6 +6,7 @@
using System.IO;
using System.Linq;
using System.Reflection;
+using System.Runtime.Loader;
using Microsoft.TestPlatform.TestUtilities;
using Microsoft.VisualStudio.TestPlatform.Common.Utilities;
@@ -106,15 +107,37 @@ public void TypesToLoadAttributeTests()
}
};
- foreach (var extension in extensionsToVerify.Keys)
+ // Use a custom AssemblyLoadContext so that dependencies (e.g. SCI 10.0.0)
+ // resolve from the extensions directory rather than the test host's runtime.
+ var parentDirectory = Path.GetDirectoryName(extensionsDirectory)!;
+ var alc = new AssemblyLoadContext("ExtensionTest", isCollectible: true);
+ alc.Resolving += (context, name) =>
{
- var assemblyFile = Path.Combine(extensionsDirectory, extension);
- var assembly = Assembly.LoadFrom(assemblyFile);
+ var path = Path.Combine(extensionsDirectory, name.Name + ".dll");
+ if (File.Exists(path))
+ return context.LoadFromAssemblyPath(path);
+ path = Path.Combine(parentDirectory, name.Name + ".dll");
+ if (File.Exists(path))
+ return context.LoadFromAssemblyPath(path);
+ return null;
+ };
+
+ try
+ {
+ foreach (var extension in extensionsToVerify.Keys)
+ {
+ var assemblyFile = Path.Combine(extensionsDirectory, extension);
+ var assembly = alc.LoadFromAssemblyPath(assemblyFile);
- var expected = extensionsToVerify[extension];
- var actual = TypesToLoadUtilities.GetTypesToLoad(assembly).Select(i => i.FullName).ToArray();
+ var expected = extensionsToVerify[extension];
+ var actual = TypesToLoadUtilities.GetTypesToLoad(assembly).Select(i => i.FullName).ToArray();
- CollectionAssert.AreEquivalent(expected, actual, $"Specified types using TypesToLoadAttribute in \"{extension}\" assembly doesn't match the expected.");
+ CollectionAssert.AreEquivalent(expected, actual, $"Specified types using TypesToLoadAttribute in \"{extension}\" assembly doesn't match the expected.");
+ }
+ }
+ finally
+ {
+ alc.Unload();
}
}
diff --git a/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/DistributedTestAgentScenarioTests.cs b/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/DistributedTestAgentScenarioTests.cs
new file mode 100644
index 0000000000..ee21e5e4e5
--- /dev/null
+++ b/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/DistributedTestAgentScenarioTests.cs
@@ -0,0 +1,100 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.IO;
+using System.Linq;
+using System.Reflection.Metadata;
+using System.Reflection.PortableExecutable;
+
+using Microsoft.TestPlatform.TestUtilities;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace Microsoft.TestPlatform.AcceptanceTests;
+
+///
+/// Tests that the DTA (Distributed Test Agent) scenario works: a .NET Framework host
+/// loads Microsoft.VisualStudio.TestPlatform.Common.dll without binding redirects. The shipped
+/// System.Collections.Immutable DLL must match the assembly version referenced by
+/// the compiled product assemblies.
+///
+[TestClass]
+public class DistributedTestAgentScenarioTests : AcceptanceTestBase
+{
+ ///
+ /// Validates that the Microsoft.TestPlatform nupkg layout (used by DTA/VSTest task)
+ /// contains a System.Collections.Immutable whose assembly version matches what
+ /// Common.dll was compiled against.
+ ///
+ [TestMethod]
+ public void NupkgLayout_CommonDll_CanLoadSciWithoutBindingRedirects()
+ {
+ var testPlatformDir = Path.Combine(
+ IntegrationTestEnvironment.PublishDirectory,
+ $"Microsoft.TestPlatform.{IntegrationTestEnvironment.LatestLocallyBuiltNugetVersion}.nupkg",
+ "tools", "net462", "Common7", "IDE", "Extensions", "TestPlatform");
+
+ ValidateDtaScenario(testPlatformDir, "nupkg");
+ }
+
+ ///
+ /// Validates that the V2.CLI VSIX layout also has matching SCI assembly versions.
+ ///
+ [TestMethod]
+ public void VsixLayout_CommonDll_CanLoadSciWithoutBindingRedirects()
+ {
+ var vsixDir = Path.GetDirectoryName(IntegrationTestEnvironment.LocalVsixInsertion);
+ if (vsixDir is null || !Directory.Exists(vsixDir))
+ {
+ Assert.Inconclusive("VSIX directory not found. Build with -pack to produce it.");
+ }
+
+ var vsixExtractDir = Path.Combine(IntegrationTestEnvironment.ArtifactsTempDirectory, "vsix-extracted");
+ if (!Directory.Exists(vsixExtractDir))
+ {
+ System.IO.Compression.ZipFile.ExtractToDirectory(IntegrationTestEnvironment.LocalVsixInsertion, vsixExtractDir);
+ }
+
+ ValidateDtaScenario(vsixExtractDir, "VSIX");
+ }
+
+ private static void ValidateDtaScenario(string testPlatformDir, string layoutName)
+ {
+ Assert.IsTrue(Directory.Exists(testPlatformDir), $"{layoutName} directory not found: {testPlatformDir}");
+
+ var commonDll = Path.Combine(testPlatformDir, "Microsoft.VisualStudio.TestPlatform.Common.dll");
+ var sciDll = Path.Combine(testPlatformDir, "System.Collections.Immutable.dll");
+
+ Assert.IsTrue(File.Exists(commonDll), $"Common.dll not found in {layoutName} layout: {commonDll}");
+ Assert.IsTrue(File.Exists(sciDll), $"System.Collections.Immutable.dll not found in {layoutName} layout: {sciDll}");
+
+ var sciVersion = System.Reflection.AssemblyName.GetAssemblyName(sciDll).Version;
+ var sciRefVersion = GetReferencedAssemblyVersion(commonDll, "System.Collections.Immutable");
+
+ Assert.IsNotNull(sciRefVersion, $"Common.dll in {layoutName} layout does not reference System.Collections.Immutable");
+
+ // For DTA scenario (no binding redirects), these MUST match exactly.
+ Assert.AreEqual(
+ sciRefVersion,
+ sciVersion,
+ $"{layoutName} layout: Common.dll references SCI {sciRefVersion} but shipped DLL is {sciVersion}. " +
+ $"DTA hosts without binding redirects will fail with FileLoadException.");
+ }
+
+ private static Version? GetReferencedAssemblyVersion(string assemblyPath, string referenceName)
+ {
+ using var stream = File.OpenRead(assemblyPath);
+ using var peReader = new PEReader(stream);
+ var mdReader = peReader.GetMetadataReader();
+ foreach (var handle in mdReader.AssemblyReferences)
+ {
+ var asmRef = mdReader.GetAssemblyReference(handle);
+ if (mdReader.GetString(asmRef.Name) == referenceName)
+ {
+ return asmRef.Version;
+ }
+ }
+
+ return null;
+ }
+}