Skip to content

Commit f875b0a

Browse files
Fix satellite resolution for Microsoft.TestPlatform.Common (#4147)
Fix satellite resolution for Microsoft.TestPlatform.Common
1 parent a61ec90 commit f875b0a

File tree

2 files changed

+10
-64
lines changed

2 files changed

+10
-64
lines changed

src/Microsoft.TestPlatform.Common/ExtensionFramework/TestPluginCache.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,15 @@ private Dictionary<string, TPluginInfo> GetTestExtensions<TPluginInfo, TExtensio
463463

464464
protected void SetupAssemblyResolver(string? extensionAssembly)
465465
{
466+
// If we don't load the resource for Microsoft.TestPlatform.Common before
467+
// to set the assembly resolver we won't be able to use the resources.
468+
// This should be the algorithm followed during the satellite assembly resolution
469+
// https://learn.microsoft.com/dotnet/core/extensions/package-and-deploy-resources#net-framework-resource-fallback-process
470+
// BUT for some unknown reason the point 10 is not working as explained.
471+
// Satellite resolution should fallback to the NeutralResourcesLanguageAttribute
472+
// that we set to en-US but don't and we fail with FileNotFoundException.
473+
_ = Resources.Resources.FailedToLoadAdapaterFile;
474+
466475
IList<string> resolutionPaths = extensionAssembly.IsNullOrEmpty()
467476
? GetDefaultResolutionPaths()
468477
: GetResolutionPaths(extensionAssembly);

src/Microsoft.TestPlatform.Common/Utilities/AssemblyResolver.cs

Lines changed: 1 addition & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -123,71 +123,8 @@ internal void AddSearchDirectories(IEnumerable<string> directories)
123123

124124
TPDebug.Assert(requestedName != null && !requestedName.Name.IsNullOrEmpty(), "AssemblyResolver.OnResolve: requested is null or name is empty!");
125125

126-
// Workaround: adding expected folder for the satellite assembly related to the current CurrentThread.CurrentUICulture relative to the current assembly location.
127-
// After the move to the net461 the runtime doesn't resolve anymore the satellite assembly correctly.
128-
// The expected workflow should be https://learn.microsoft.com/en-us/dotnet/core/extensions/package-and-deploy-resources#net-framework-resource-fallback-process
129-
// But the resolution never fallback to the CultureInfo.Parent folder and fusion log return a failure like:
130-
// ...
131-
// LOG: The same bind was seen before, and was failed with hr = 0x80070002.
132-
// ERR: Unrecoverable error occurred during pre - download check(hr = 0x80070002).
133-
// ...
134-
// The bizarre thing is that as a result we're failing caller task like discovery and when for reporting reason
135-
// we're accessing again to the resource it works.
136-
// Looks like a loading timing issue but we're not in control of the assembly loader order.
137126
var isResource = requestedName.Name.EndsWith(".resources");
138-
string[]? satelliteLocation = null;
139-
140-
// We help to resolve only test platform resources to be less invasive as possible with the default/expected behavior
141-
if (isResource && requestedName.Name.StartsWith("Microsoft.VisualStudio.TestPlatform"))
142-
{
143-
try
144-
{
145-
string? currentAssemblyLocation = null;
146-
try
147-
{
148-
currentAssemblyLocation = Assembly.GetExecutingAssembly().Location;
149-
// In .NET 5 and later versions, for bundled assemblies, the value returned is an empty string.
150-
currentAssemblyLocation = currentAssemblyLocation == string.Empty ? null : Path.GetDirectoryName(currentAssemblyLocation);
151-
}
152-
catch (NotSupportedException)
153-
{
154-
// https://learn.microsoft.com/en-us/dotnet/api/system.reflection.assembly.location
155-
}
156-
157-
if (currentAssemblyLocation is not null)
158-
{
159-
List<string> satelliteLocations = new();
160-
161-
// We mimic the satellite workflow and we add CurrentUICulture and CurrentUICulture.Parent folder in order
162-
string? currentUICulture = Thread.CurrentThread.CurrentUICulture?.Name;
163-
if (currentUICulture is not null)
164-
{
165-
satelliteLocations.Add(Path.Combine(currentAssemblyLocation, currentUICulture));
166-
}
167-
168-
// CurrentUICulture.Parent
169-
string? parentCultureInfo = Thread.CurrentThread.CurrentUICulture?.Parent?.Name;
170-
if (parentCultureInfo is not null)
171-
{
172-
satelliteLocations.Add(Path.Combine(currentAssemblyLocation, parentCultureInfo));
173-
}
174-
175-
if (satelliteLocations.Count > 0)
176-
{
177-
satelliteLocation = satelliteLocations.ToArray();
178-
}
179-
}
180-
}
181-
catch (Exception ex)
182-
{
183-
// We catch here because this is a workaround, we're trying to substitute the expected workflow of the runtime
184-
// and this shouldn't be needed, but if we fail we want to log what's happened and give a chance to the in place
185-
// resolution workflow
186-
EqtTrace.Error($"AssemblyResolver.OnResolve: Exception during the custom satellite resolution\n{ex}");
187-
}
188-
}
189-
190-
foreach (var dir in (satelliteLocation is not null) ? _searchDirectories.Union(satelliteLocation) : _searchDirectories)
127+
foreach (var dir in _searchDirectories)
191128
{
192129
if (dir.IsNullOrEmpty())
193130
{

0 commit comments

Comments
 (0)