diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Helpers/FileHelper.cs b/src/Microsoft.TestPlatform.CoreUtilities/Helpers/FileHelper.cs
index ba0070cae9..10ea025a47 100644
--- a/src/Microsoft.TestPlatform.CoreUtilities/Helpers/FileHelper.cs
+++ b/src/Microsoft.TestPlatform.CoreUtilities/Helpers/FileHelper.cs
@@ -5,6 +5,7 @@ namespace Microsoft.VisualStudio.TestPlatform.Utilities.Helpers
{
using System;
using System.Collections.Generic;
+ using System.Diagnostics;
using System.IO;
using System.Linq;
@@ -15,6 +16,8 @@ namespace Microsoft.VisualStudio.TestPlatform.Utilities.Helpers
///
public class FileHelper : IFileHelper
{
+ private static readonly Version DefaultFileVersion = new Version(0, 0);
+
///
public DirectoryInfo CreateDirectory(string path)
{
@@ -69,6 +72,13 @@ public FileAttributes GetFileAttributes(string path)
return new FileInfo(path).Attributes;
}
+ ///
+ public Version GetFileVersion(string path)
+ {
+ var currentFileVersion = FileVersionInfo.GetVersionInfo(path)?.FileVersion;
+ return Version.TryParse(currentFileVersion, out var currentVersion) ? currentVersion : DefaultFileVersion;
+ }
+
///
public void CopyFile(string sourcePath, string destinationPath)
{
diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Helpers/Interfaces/IFileHelper.cs b/src/Microsoft.TestPlatform.CoreUtilities/Helpers/Interfaces/IFileHelper.cs
index 8127237c83..5c9631ed67 100644
--- a/src/Microsoft.TestPlatform.CoreUtilities/Helpers/Interfaces/IFileHelper.cs
+++ b/src/Microsoft.TestPlatform.CoreUtilities/Helpers/Interfaces/IFileHelper.cs
@@ -3,7 +3,9 @@
namespace Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces
{
+ using System;
using System.Collections.Generic;
+ using System.Diagnostics;
using System.IO;
///
@@ -63,6 +65,13 @@ public interface IFileHelper
/// Attributes of the file.
FileAttributes GetFileAttributes(string path);
+ ///
+ /// Gets the version information of the file.
+ ///
+ /// Full path to the file.
+ /// File Version information of the file.
+ Version GetFileVersion(string path);
+
///
/// Copy a file in the file system.
///
diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Microsoft.TestPlatform.CoreUtilities.csproj b/src/Microsoft.TestPlatform.CoreUtilities/Microsoft.TestPlatform.CoreUtilities.csproj
index e369d739e8..b51c04cd12 100644
--- a/src/Microsoft.TestPlatform.CoreUtilities/Microsoft.TestPlatform.CoreUtilities.csproj
+++ b/src/Microsoft.TestPlatform.CoreUtilities/Microsoft.TestPlatform.CoreUtilities.csproj
@@ -9,7 +9,7 @@
netstandard1.4;net451
-
+
@@ -19,6 +19,11 @@
+
+
+ 4.3.0
+
+ True
diff --git a/src/Microsoft.TestPlatform.ObjectModel/Microsoft.TestPlatform.ObjectModel.csproj b/src/Microsoft.TestPlatform.ObjectModel/Microsoft.TestPlatform.ObjectModel.csproj
index fd454c6acf..67806f0b60 100644
Binary files a/src/Microsoft.TestPlatform.ObjectModel/Microsoft.TestPlatform.ObjectModel.csproj and b/src/Microsoft.TestPlatform.ObjectModel/Microsoft.TestPlatform.ObjectModel.csproj differ
diff --git a/src/Microsoft.TestPlatform.TestHostProvider/Hosting/DefaultTestHostManager.cs b/src/Microsoft.TestPlatform.TestHostProvider/Hosting/DefaultTestHostManager.cs
index cc7f30a153..0e0527d6ad 100644
--- a/src/Microsoft.TestPlatform.TestHostProvider/Hosting/DefaultTestHostManager.cs
+++ b/src/Microsoft.TestPlatform.TestHostProvider/Hosting/DefaultTestHostManager.cs
@@ -6,14 +6,15 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Hosting
using System;
using System.Collections.Generic;
using System.Diagnostics;
+ using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
-
using Microsoft.TestPlatform.TestHostProvider.Hosting;
+ using Microsoft.TestPlatform.TestHostProvider.Resources;
using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Extensions;
using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Helpers;
using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Helpers.Interfaces;
@@ -194,6 +195,8 @@ public IEnumerable GetTestPlatformExtensions(IEnumerable sources
extensions = extensions.Concat(sources.SelectMany(s => this.fileHelper.EnumerateFiles(Path.GetDirectoryName(s), SearchOption.TopDirectoryOnly, TestAdapterEndsWithPattern)));
}
+ extensions = this.FilterExtensionsBasedOnVersion(extensions);
+
return extensions;
}
@@ -250,6 +253,82 @@ public Task CleanTestHostAsync(CancellationToken cancellationToken)
return Task.FromResult(true);
}
+ ///
+ /// Filter duplicate extensions, include only the highest versioned extension
+ ///
+ /// Entire list of extensions
+ /// Filtered list of extensions
+ private IEnumerable FilterExtensionsBasedOnVersion(IEnumerable extensions)
+ {
+ Dictionary selectedExtensions = new Dictionary();
+ Dictionary highestFileVersions = new Dictionary();
+ Dictionary conflictingExtensions = new Dictionary();
+
+ foreach (var extensionFullPath in extensions)
+ {
+ // assemblyName is the key
+ var extensionAssemblyName = Path.GetFileNameWithoutExtension(extensionFullPath);
+
+ if (selectedExtensions.TryGetValue(extensionAssemblyName, out var oldExtensionPath))
+ {
+ // This extension is duplicate
+ var currentVersion = this.GetAndLogFileVersion(extensionFullPath);
+
+ var oldVersionFound = highestFileVersions.TryGetValue(extensionAssemblyName, out var oldVersion);
+ if (!oldVersionFound)
+ {
+ oldVersion = this.GetAndLogFileVersion(oldExtensionPath);
+ }
+
+ // If the version of current file is higher than the one in the map
+ // replace the older with the current file
+ if (currentVersion > oldVersion)
+ {
+ highestFileVersions[extensionAssemblyName] = currentVersion;
+ conflictingExtensions[extensionAssemblyName] = currentVersion;
+ selectedExtensions[extensionAssemblyName] = extensionFullPath;
+ }
+ else
+ {
+ if (currentVersion < oldVersion)
+ {
+ conflictingExtensions[extensionAssemblyName] = oldVersion;
+ }
+
+ if (!oldVersionFound)
+ {
+ highestFileVersions.Add(extensionAssemblyName, oldVersion);
+ }
+ }
+ }
+ else
+ {
+ selectedExtensions.Add(extensionAssemblyName, extensionFullPath);
+ }
+ }
+
+ // Log warning if conflicting version extensions are found
+ if (conflictingExtensions.Any())
+ {
+ var extensionsString = string.Join("\n", conflictingExtensions.Select(kv => string.Format(" {0} : {1}", kv.Key, kv.Value)));
+ string message = string.Format(CultureInfo.CurrentCulture, Resources.MultipleFileVersions, extensionsString);
+ this.messageLogger.SendMessage(TestMessageLevel.Warning, message);
+ }
+
+ return selectedExtensions.Values;
+ }
+
+ private Version GetAndLogFileVersion(string path)
+ {
+ var fileVersion = this.fileHelper.GetFileVersion(path);
+ if (EqtTrace.IsVerboseEnabled)
+ {
+ EqtTrace.Verbose("FileVersion for {0} : {1}", path, fileVersion);
+ }
+
+ return fileVersion;
+ }
+
///
/// Raises HostLaunched event
///
diff --git a/src/Microsoft.TestPlatform.TestHostProvider/Hosting/DotnetTestHostManager.cs b/src/Microsoft.TestPlatform.TestHostProvider/Hosting/DotnetTestHostManager.cs
index 791fdc848b..8d260b3ce0 100644
--- a/src/Microsoft.TestPlatform.TestHostProvider/Hosting/DotnetTestHostManager.cs
+++ b/src/Microsoft.TestPlatform.TestHostProvider/Hosting/DotnetTestHostManager.cs
@@ -6,12 +6,12 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Hosting
using System;
using System.Collections.Generic;
using System.Diagnostics;
+ using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
-
using Microsoft.Extensions.DependencyModel;
using Microsoft.TestPlatform.TestHostProvider.Hosting;
using Microsoft.TestPlatform.TestHostProvider.Resources;
@@ -28,7 +28,6 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Hosting
using Microsoft.VisualStudio.TestPlatform.Utilities;
using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers;
using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces;
-
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -227,7 +226,7 @@ public virtual TestProcessStartInfo GetTestHostProcessStartInfo(
}
else
{
- string message = string.Format(Resources.NoTestHostFileExist, sourcePath);
+ string message = string.Format(CultureInfo.CurrentCulture, Resources.NoTestHostFileExist, sourcePath);
EqtTrace.Verbose("DotnetTestHostmanager: " + message);
throw new FileNotFoundException(message);
}
diff --git a/src/Microsoft.TestPlatform.TestHostProvider/Resources/Resources.Designer.cs b/src/Microsoft.TestPlatform.TestHostProvider/Resources/Resources.Designer.cs
index 1e232de908..30df3ba2ba 100644
--- a/src/Microsoft.TestPlatform.TestHostProvider/Resources/Resources.Designer.cs
+++ b/src/Microsoft.TestPlatform.TestHostProvider/Resources/Resources.Designer.cs
@@ -20,7 +20,7 @@ namespace Microsoft.TestPlatform.TestHostProvider.Resources {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
@@ -61,6 +61,16 @@ internal Resources() {
}
}
+ ///
+ /// Looks up a localized string similar to Multiple versions of same extension found. Selecting the highest version.
+ ///{0}.
+ ///
+ internal static string MultipleFileVersions {
+ get {
+ return ResourceManager.GetString("MultipleFileVersions", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to No test is available in {0}. Make sure test project has a nuget reference of package "Microsoft.NET.Test.Sdk" and framework version settings are appropriate and try again..
///
diff --git a/src/Microsoft.TestPlatform.TestHostProvider/Resources/Resources.resx b/src/Microsoft.TestPlatform.TestHostProvider/Resources/Resources.resx
index f8f036cc75..bfe9ef97c9 100644
--- a/src/Microsoft.TestPlatform.TestHostProvider/Resources/Resources.resx
+++ b/src/Microsoft.TestPlatform.TestHostProvider/Resources/Resources.resx
@@ -117,6 +117,10 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ Multiple versions of same extension found. Selecting the highest version.
+{0}
+
No test is available in {0}. Make sure test project has a nuget reference of package "Microsoft.NET.Test.Sdk" and framework version settings are appropriate and try again.
diff --git a/src/Microsoft.TestPlatform.TestHostProvider/Resources/xlf/Resources.cs.xlf b/src/Microsoft.TestPlatform.TestHostProvider/Resources/xlf/Resources.cs.xlf
index 08f6303091..9a2e4c3eb5 100644
--- a/src/Microsoft.TestPlatform.TestHostProvider/Resources/xlf/Resources.cs.xlf
+++ b/src/Microsoft.TestPlatform.TestHostProvider/Resources/xlf/Resources.cs.xlf
@@ -7,6 +7,13 @@
V {0} není k dispozici žádný test. Ověřte, jestli má testovací projekt odkaz na balíček nuget Microsoft.NET.Test.Sdk a jestli je nastavení verze rozhraní správné. Pak to zkuste znovu.
+
+ Multiple versions of same extension found. Selecting the highest version.
+{0}
+ Multiple extensions with different file versions found. Selected extensions with version:
+{0}
+
+