Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
Add test project for binder tracing tests
Browse files Browse the repository at this point in the history
Add event listener for tests
  • Loading branch information
elinor-fung committed Oct 24, 2019
1 parent abf0381 commit 453ee01
Show file tree
Hide file tree
Showing 3 changed files with 182 additions and 0 deletions.
104 changes: 104 additions & 0 deletions tests/src/Loader/binding/tracing/BinderEventListener.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Diagnostics.Tracing;
using System.Linq;
using System.Threading;
using System.Reflection;
using Xunit;

using Assert = Xunit.Assert;

namespace BinderTracingTests
{
internal class BindEvent
{
internal AssemblyName AssemblyName;
internal bool Success;

internal Guid ActivityId;
internal Guid ParentActivityId;

internal bool Completed;
internal bool Nested;
}

internal sealed class BinderEventListener : EventListener
{
public Dictionary<Guid, BindEvent> BindEvents = new Dictionary<Guid, BindEvent>();

private const EventKeywords TasksFlowActivityIds = (EventKeywords)0x80;
private const EventKeywords BinderKeyword = (EventKeywords)0x4;

private object eventsLock = new object();

public BindEvent[] WaitAndGetEventsForAssembly(string simpleName, int waitTimeoutInMs = 10000)
{
const int waitIntervalInMs = 50;
int timeWaitedInMs = 0;
do
{
lock (eventsLock)
{
var events = BindEvents.Values.Where(e => e.Completed && e.AssemblyName.Name == simpleName && !e.Nested);
if (events.Any())
{
return events.ToArray();
}
}

Thread.Sleep(waitIntervalInMs);
timeWaitedInMs += waitIntervalInMs;
} while (timeWaitedInMs < waitTimeoutInMs);

throw new TimeoutException($"Timed out waiting for bind events for {simpleName}");
}

protected override void OnEventSourceCreated(EventSource eventSource)
{
if (eventSource.Name == "Microsoft-Windows-DotNETRuntime")
{
EnableEvents(eventSource, EventLevel.Verbose, BinderKeyword);
}
else if (eventSource.Name == "System.Threading.Tasks.TplEventSource")
{
EnableEvents(eventSource, EventLevel.Verbose, TasksFlowActivityIds);
}
}

protected override void OnEventWritten(EventWrittenEventArgs data)
{
if (data.EventSource.Name != "Microsoft-Windows-DotNETRuntime")
return;

object GetData(string name) => data.Payload[data.PayloadNames.IndexOf(name)];
string GetDataString(string name) => GetData(name).ToString();

lock (eventsLock)
{
switch (data.EventName)
{
case "AssemblyBindStart":
Assert.True(!BindEvents.ContainsKey(data.ActivityId), "AssemblyBindStart should not exist for same activity ID ");
var bindEvent = new BindEvent()
{
AssemblyName = new AssemblyName(GetDataString("AssemblyName")),
ActivityId = data.ActivityId,
ParentActivityId = data.RelatedActivityId,
Nested = BindEvents.ContainsKey(data.RelatedActivityId)
};
BindEvents.Add(data.ActivityId, bindEvent);
break;
case "AssemblyBindStop":
Assert.True(BindEvents.ContainsKey(data.ActivityId), "AssemblyBindStop should have a matching AssemblyBindStart");
BindEvents[data.ActivityId].Success = (bool)GetData("Success");
BindEvents[data.ActivityId].Completed = true;
break;
}
}
}
}
}
66 changes: 66 additions & 0 deletions tests/src/Loader/binding/tracing/BinderTracingTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;

using Assert = Xunit.Assert;

namespace BinderTracingTests
{
class BinderTracingTest
{
public static void PlatformAssembly_DefaultALC()
{
Console.WriteLine($"Running {nameof(PlatformAssembly_DefaultALC)}...");
using (var listener = new BinderEventListener())
{
string assemblyName = "System.Xml";
Assembly asm = Assembly.Load(assemblyName);

BindEvent[] events = listener.WaitAndGetEventsForAssembly(assemblyName);
Assert.True(events.Length == 1, $"Bind event count for {assemblyName} - expected: 1, actual: {events.Length}");
BindEvent bindEvent = events[0];
Assert.True(bindEvent.Success, $"Expected bind for {assemblyName} to succeed");
}
}

public static void NonExistentAssembly_DefaultALC()
{
Console.WriteLine($"Running {nameof(NonExistentAssembly_DefaultALC)}...");
using (var listener = new BinderEventListener())
{
string assemblyName = "DoesNotExist";
try
{
Assembly.Load(assemblyName);
}
catch { }

BindEvent[] events = listener.WaitAndGetEventsForAssembly(assemblyName);
Assert.True(events.Length == 1, $"Bind event count for {assemblyName} - expected: 1, actual: {events.Length}");
BindEvent bindEvent = events[0];
Assert.False(bindEvent.Success, $"Expected bind for {assemblyName} to fail");
}
}

public static int Main(string[] unused)
{
try
{
PlatformAssembly_DefaultALC();
NonExistentAssembly_DefaultALC();
}
catch (Exception e)
{
Console.WriteLine($"Test Failure: {e}");
return 101;
}

return 100;
}
}
}
12 changes: 12 additions & 0 deletions tests/src/Loader/binding/tracing/BinderTracingTest.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
</PropertyGroup>
<ItemGroup>
<Compile Include="BinderTracingTest.cs" />
<Compile Include="BinderEventListener.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(SourceDir)Common/CoreCLRTestLibrary/CoreCLRTestLibrary.csproj" />
</ItemGroup>
</Project>

0 comments on commit 453ee01

Please sign in to comment.