From cf54dbfe308c0811dcaa0853fbb4f4809be1b1b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Wed, 21 Dec 2022 17:53:26 +0100 Subject: [PATCH] Fix issue cannot load Microsoft.TestPlatform.CoreUtilities When setuping DeploymentEnabled, MSTest fails with `An exception occurred while invoking executor 'executor://mstestadapter/v2': Could not load file or assembly 'Microsoft.TestPlatform.CoreUtilities, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.`. After investigation, it seems related to a chage introduced in 2.2.7 where some logs were added, adding a dependency to this dll which cannot be resolved by the custom assembly resolver. The special appdomain and resolver are meant to isolate and detect dll coming from the user bin folder to enable automatic copy of these dlls so we cannot easily fix the resolver as it could lead to conflicts or missing dlls copied. Simplest solution is to remove the log steps for this class. --- .../Deployment/AssemblyLoadWorker.cs | 33 ++++++------------- .../Utilities/AppDomainUtilities.cs | 9 ++++- 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Deployment/AssemblyLoadWorker.cs b/src/Adapter/MSTestAdapter.PlatformServices/Deployment/AssemblyLoadWorker.cs index d1e83ac8c7..d6486b1343 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Deployment/AssemblyLoadWorker.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Deployment/AssemblyLoadWorker.cs @@ -10,11 +10,16 @@ using System.Reflection; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; -using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment; +/* + * /!\ WARNING /!\ + * DO NOT USE EQTTRACE IN THIS CLASS AS IT WILL CAUSE LOAD ISSUE BECAUSE OF THE APPDOMAIN + * ASSEMBLY RESOLVER SETUP. + */ + /// /// Utility function for Assembly related info /// The caller is supposed to create AppDomain and create instance of given class in there. @@ -49,16 +54,11 @@ public string[] GetFullPathToDependentAssemblies(string assemblyPath, out IList< Assembly? assembly; try { - EqtTrace.Verbose($"AssemblyLoadWorker.GetFullPathToDependentAssemblies: Reflection loading {assemblyPath}."); - // First time we load in LoadFromContext to avoid issues. assembly = _assemblyUtility.ReflectionOnlyLoadFrom(assemblyPath); } catch (Exception ex) { - EqtTrace.Error($"AssemblyLoadWorker.GetFullPathToDependentAssemblies: Reflection loading of {assemblyPath} failed:"); - EqtTrace.Error(ex); - warnings.Add(ex.Message); return Array.Empty(); // Otherwise just return no dependencies. } @@ -91,8 +91,9 @@ public string[] GetFullPathToDependentAssemblies(string assemblyPath, out IList< /// /// Path of the assembly file. /// String representation of the target dotNet framework e.g. .NETFramework,Version=v4.0. - internal string GetTargetFrameworkVersionStringFromPath(string path) + internal string GetTargetFrameworkVersionStringFromPath(string path, out string? errorMessage) { + errorMessage = null; if (!File.Exists(path)) { return string.Empty; @@ -105,17 +106,11 @@ internal string GetTargetFrameworkVersionStringFromPath(string path) } catch (BadImageFormatException) { - if (EqtTrace.IsErrorEnabled) - { - EqtTrace.Error("AssemblyHelper:GetTargetFrameworkVersionString() caught BadImageFormatException. Falling to native binary."); - } + errorMessage = "AssemblyHelper:GetTargetFrameworkVersionString() caught BadImageFormatException. Falling to native binary."; } catch (Exception ex) { - if (EqtTrace.IsErrorEnabled) - { - EqtTrace.Error("AssemblyHelper:GetTargetFrameworkVersionString() Returning default. Unhandled exception: {0}.", ex); - } + errorMessage = $"AssemblyHelper:GetTargetFrameworkVersionString() Returning default. Unhandled exception: {ex}."; } return string.Empty; @@ -168,7 +163,6 @@ private void ProcessChildren(Assembly assembly, IList result, ISet result, ISet(); try { - EqtTrace.Verbose($"AssemblyLoadWorker.GetFullPathToDependentAssemblies: Getting modules of {assembly.FullName}."); modules = assembly.GetModules(); } catch (FileNotFoundException e) @@ -249,8 +242,6 @@ private void GetDependentAssembliesInternal(string assemblyString, IList Assembly? assembly; try { - EqtTrace.Verbose($"AssemblyLoadWorker.GetDependentAssembliesInternal: Reflection loading {assemblyString}."); - string postPolicyAssembly = AppDomain.CurrentDomain.ApplyPolicy(assemblyString); DebugEx.Assert(!StringEx.IsNullOrEmpty(postPolicyAssembly), "postPolicyAssembly"); @@ -259,15 +250,11 @@ private void GetDependentAssembliesInternal(string assemblyString, IList } catch (Exception ex) { - EqtTrace.Error($"AssemblyLoadWorker.GetDependentAssembliesInternal: Reflection loading {assemblyString} failed:."); - EqtTrace.Error(ex); - string warning = string.Format(CultureInfo.CurrentCulture, Resource.MissingDeploymentDependency, assemblyString, ex.Message); warnings.Add(warning); return; } - EqtTrace.Verbose($"AssemblyLoadWorker.GetDependentAssembliesInternal: Assembly {assemblyString} was added as dependency."); result.Add(assembly.Location); ProcessChildren(assembly, result, visitedAssemblies, warnings); diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/AppDomainUtilities.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/AppDomainUtilities.cs index a9bc05ec9b..c4a8d11425 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/AppDomainUtilities.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/AppDomainUtilities.cs @@ -118,7 +118,14 @@ internal static string GetTargetFrameworkVersionString(string testSourcePath) typeof(AssemblyLoadWorker), null); - return assemblyLoadWorker.GetTargetFrameworkVersionStringFromPath(testSourcePath); + var targetFramework = assemblyLoadWorker.GetTargetFrameworkVersionStringFromPath(testSourcePath, out var errorMessage); + + if (errorMessage is not null) + { + EqtTrace.Error(errorMessage); + } + + return targetFramework; } catch (Exception exception) {