private readonly object eventsLock = new object();
private readonly Dictionary<Guid, BindOperation> bindOperations = new Dictionary<Guid, BindOperation>();
+ private readonly string[] loadsToTrack;
+
+ public BinderEventListener(string[] loadsToTrack, bool log = false)
+ {
+ this.loadsToTrack = loadsToTrack;
+ }
public BindOperation[] WaitAndGetEventsForAssembly(AssemblyName assemblyName)
{
+ Assert.IsTrue(IsLoadToTrack(assemblyName.Name), $"Waiting for load for untracked name: {assemblyName.Name}. Tracking loads for: {string.Join(", ", loadsToTrack)}");
+
const int waitIntervalInMs = 50;
int waitTimeoutInMs = Environment.GetEnvironmentVariable("COMPlus_GCStress") == null
? 30 * 1000
case "AssemblyLoadStart":
{
BindOperation bindOperation = ParseAssemblyLoadStartEvent(data, GetDataString);
+ if (!IsLoadToTrack(bindOperation.AssemblyName.Name))
+ return;
+
lock (eventsLock)
{
Assert.IsTrue(!bindOperations.ContainsKey(data.ActivityId), "AssemblyLoadStart should not exist for same activity ID ");
}
case "AssemblyLoadStop":
{
+ string assemblyName = GetDataString("AssemblyName");
+ if (!IsLoadToTrack(new AssemblyName(assemblyName).Name))
+ return;
+
bool success = (bool)GetData("Success");
string resultName = GetDataString("ResultAssemblyName");
lock (eventsLock)
case "ResolutionAttempted":
{
ResolutionAttempt attempt = ParseResolutionAttemptedEvent(GetData, GetDataString);
+ if (!IsLoadToTrack(attempt.AssemblyName.Name))
+ return;
+
lock (eventsLock)
{
if (!bindOperations.ContainsKey(data.ActivityId))
case "AssemblyLoadContextResolvingHandlerInvoked":
{
HandlerInvocation handlerInvocation = ParseHandlerInvokedEvent(GetDataString);
+ if (!IsLoadToTrack(handlerInvocation.AssemblyName.Name))
+ return;
+
lock (eventsLock)
{
if (!bindOperations.ContainsKey(data.ActivityId))
case "AppDomainAssemblyResolveHandlerInvoked":
{
HandlerInvocation handlerInvocation = ParseHandlerInvokedEvent(GetDataString);
+ if (!IsLoadToTrack(handlerInvocation.AssemblyName.Name))
+ return;
+
lock (eventsLock)
{
if (!bindOperations.ContainsKey(data.ActivityId))
case "AssemblyLoadFromResolveHandlerInvoked":
{
LoadFromHandlerInvocation loadFrom = ParseLoadFromHandlerInvokedEvent(GetData, GetDataString);
+ if (!IsLoadToTrack(loadFrom.AssemblyName.Name))
+ return;
+
lock (eventsLock)
{
if (!bindOperations.ContainsKey(data.ActivityId))
case "KnownPathProbed":
{
ProbedPath probedPath = ParseKnownPathProbedEvent(GetData, GetDataString);
+ string name = System.IO.Path.GetFileNameWithoutExtension(probedPath.FilePath);
+ if (!IsLoadToTrack(name.EndsWith(".ni") ? name.Remove(name.Length - 3) : name))
+ return;
+
lock (eventsLock)
{
if (!bindOperations.ContainsKey(data.ActivityId))
}
}
+ private bool IsLoadToTrack(string name)
+ {
+ return this.loadsToTrack.Any(n => n.Equals(name, StringComparison.InvariantCultureIgnoreCase));
+ }
+
private string GetMisssingAssemblyBindStartMessage(EventWrittenEventArgs data, string parsedEventAsString)
{
var msg = new System.Text.StringBuilder();
};
}
- [BinderTest(isolate: true)]
+ [BinderTest(isolate: true, additionalLoadsToTrack: new string[] { "System.Xml" })]
public static BindOperation LoadFromAssemblyName()
{
AssemblyName assemblyName = new AssemblyName("System.Xml");
};
}
- [BinderTest(isolate: true)]
+ [BinderTest(isolate: true, additionalLoadsToTrack: new string[] { "System.Xml" })]
public static BindOperation PlatformAssembly()
{
var assemblyName = new AssemblyName("System.Xml");
};
}
- [BinderTest(isolate: true, testSetup: nameof(PlatformAssembly))]
+ [BinderTest(isolate: true, testSetup: nameof(PlatformAssembly), additionalLoadsToTrack: new string[] { "System.Xml" })]
public static BindOperation PlatformAssembly_Cached()
{
BindOperation bind = PlatformAssembly();
// KnownPathProbed : AppPaths (EXE) [COR_E_FILENOTFOUND]
// Note: corerun always sets APP_PATH and APP_NI_PATH. In regular use cases,
// the customer would have to explicitly configure the app to set those.
- [BinderTest]
+ [BinderTest(additionalLoadsToTrack: new string[] { "DoesNotExist" })]
public static BindOperation NonExistentAssembly()
{
string assemblyName = "DoesNotExist";
}
}
- [BinderTest]
+ [BinderTest(additionalLoadsToTrack: new string[] { SubdirectoryAssemblyName + "Mismatch" })]
public static BindOperation AssemblyLoadContextResolving_NameMismatch()
{
var assemblyName = new AssemblyName(SubdirectoryAssemblyName);
public static BindOperation AssemblyLoadContextResolving_MultipleHandlers()
{
var assemblyName = new AssemblyName(SubdirectoryAssemblyName);
- CustomALC alc = new CustomALC(nameof(AssemblyLoadContextResolving_NameMismatch));
+ CustomALC alc = new CustomALC(nameof(AssemblyLoadContextResolving_MultipleHandlers));
using (var handlerNull = new Handlers(HandlerReturn.Null, alc))
using (var handlerLoad = new Handlers(HandlerReturn.RequestedAssembly, alc))
{
}
}
- [BinderTest]
+ [BinderTest(additionalLoadsToTrack: new string[] { SubdirectoryAssemblyName + "Mismatch" })]
public static BindOperation AppDomainAssemblyResolve_NameMismatch()
{
var assemblyName = new AssemblyName(SubdirectoryAssemblyName);
}
}
- [BinderTest(isolate: true)]
+ [BinderTest(isolate: true, additionalLoadsToTrack: new string[] { "AssemblyToLoadDependency" })]
public static BindOperation AssemblyLoadFromResolveHandler_LoadDependency()
{
string assemblyPath = Helpers.GetAssemblyInSubdirectoryPath(SubdirectoryAssemblyName);
};
}
- [BinderTest(isolate: true)]
+ [BinderTest(isolate: true, additionalLoadsToTrack: new string[] { "AssemblyToLoadDependency" })]
public static BindOperation AssemblyLoadFromResolveHandler_MissingDependency()
{
string appPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
// ResolutionAttempted : ApplicationAssemblies (DefaultALC) [MismatchedAssemblyName]
// ResolutionAttempted : AssemblyLoadContextResolvingEvent (DefaultALC) [AssemblyNotFound]
// ResolutionAttempted : AppDomainAssemblyResolveEvent (DefaultALC) [AssemblyNotFound]
- [BinderTest(isolate: true)]
+ [BinderTest(isolate: true, additionalLoadsToTrack: new string[] { DependentAssemblyName + "_Copy" } )]
public static BindOperation ApplicationAssemblies_MismatchedAssemblyName()
{
var assemblyName = new AssemblyName($"{DependentAssemblyName}_Copy, Culture=neutral, PublicKeyToken=null");
// ResolutionAttempted : FindInLoadContext (DefaultALC) [AssemblyNotFound]
// ResolutionAttempted : ApplicationAssemblies (DefaultALC) [Success]
// ResolutionAttempted : DefaultAssemblyLoadContextFallback (CustomALC) [Success]
- [BinderTest(isolate: true)]
+ [BinderTest(isolate: true, additionalLoadsToTrack: new string[] { "System.Xml" })]
public static BindOperation DefaultAssemblyLoadContextFallback()
{
var assemblyName = new AssemblyName("System.Xml");
{
public bool Isolate { get; private set; }
public string TestSetup { get; private set; }
- public BinderTestAttribute(bool isolate = false, string testSetup = null)
+ public string[] AdditionalLoadsToTrack { get; private set; }
+ public BinderTestAttribute(bool isolate = false, string testSetup = null, string[] additionalLoadsToTrack = null)
{
Isolate = isolate;
TestSetup = testSetup;
+ AdditionalLoadsToTrack = additionalLoadsToTrack;
}
}
setupMethod.Invoke(null, new object[0]);
}
+ var loadsToTrack = new string[]
+ {
+ Assembly.GetExecutingAssembly().GetName().Name,
+ DependentAssemblyName,
+ $"{DependentAssemblyName}.resources",
+ SubdirectoryAssemblyName,
+ $"{SubdirectoryAssemblyName}.resources",
+ };
+ if (attribute.AdditionalLoadsToTrack != null)
+ loadsToTrack = loadsToTrack.Union(attribute.AdditionalLoadsToTrack).ToArray();
+
Func<BindOperation> func = (Func<BindOperation>)method.CreateDelegate(typeof(Func<BindOperation>));
- using (var listener = new BinderEventListener())
+ using (var listener = new BinderEventListener(loadsToTrack))
{
BindOperation expected = func();
ValidateSingleBind(listener, expected.AssemblyName, expected);