Browse Source

Report deduplicated reference count, deflake EventSource schema tests

TypeSystemInitStop now reports the size of the final reference set passed
to Init() instead of the raw resolve count, which included same-name
duplicates that the version dedup later drops. The schema smoke tests
asserted exact global event counts, but the providers are process-wide
and the decompiler fixtures run in parallel, so unrelated decompilations
could inflate the counts; every string payload now carries a unique
marker (and the string-less snapshot events a sentinel count) that the
assertions filter on.

Assisted-by: Claude:claude-fable-5:Claude Code
pull/3906/head
Christoph Wille 2 months ago
parent
commit
2e617a38c0
  1. 36
      ICSharpCode.Decompiler.Tests/Instrumentation/DecompilerEventSourceTests.cs
  2. 7
      ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs
  3. 48
      ILSpy.Tests/Instrumentation/ILSpyXEventSourceTests.cs

36
ICSharpCode.Decompiler.Tests/Instrumentation/DecompilerEventSourceTests.cs

@ -121,22 +121,25 @@ namespace ICSharpCode.Decompiler.Tests.Instrumentation @@ -121,22 +121,25 @@ namespace ICSharpCode.Decompiler.Tests.Instrumentation
[Test]
public void FiringEveryEventProducesNoEventSourceErrors()
{
// The provider is process-wide and other fixtures decompile in parallel, so every
// string payload carries this marker and the count assertions filter on it.
const string marker = "SchemaSmokeTest.";
using var listener = new RecordingListener(EventLevel.Verbose, EventKeywords.All);
var log = DecompilerEventSource.Log;
log.DecompileTypeStart("T");
log.DecompileTypeStop("T");
log.DecompileMemberStart("T.M", 0x06000001, (int)DecompiledMemberKind.Method, 42);
log.DecompileMemberStop("T.M", 0x06000001, (int)DecompiledMemberKind.Method);
log.TypeSystemInitStart("module");
log.TypeSystemInitStop("module", 3);
log.AssemblyResolveStart("System.Runtime");
log.AssemblyResolveStop("System.Runtime", "/path/System.Runtime.dll", true);
log.ProjectDecompilationStart("module");
log.ProjectDecompilationStop("module", 10, 2);
log.ProjectFileStart("File.cs", 5);
log.ProjectFileStop("File.cs");
log.ILTransformExecuted("ILInlining", 0x06000001, 0.5);
log.AstTransformExecuted("PatternStatementTransform", 1.5);
log.DecompileTypeStart(marker + "Type");
log.DecompileTypeStop(marker + "Type");
log.DecompileMemberStart(marker + "Type.M", 0x06000001, (int)DecompiledMemberKind.Method, 42);
log.DecompileMemberStop(marker + "Type.M", 0x06000001, (int)DecompiledMemberKind.Method);
log.TypeSystemInitStart(marker + "module");
log.TypeSystemInitStop(marker + "module", 3);
log.AssemblyResolveStart(marker + "Reference");
log.AssemblyResolveStop(marker + "Reference", marker + "Reference.dll", true);
log.ProjectDecompilationStart(marker + "module");
log.ProjectDecompilationStop(marker + "module", 10, 2);
log.ProjectFileStart(marker + "File.cs", 5);
log.ProjectFileStop(marker + "File.cs");
log.ILTransformExecuted(marker + "ILInlining", 0x06000001, 0.5);
log.AstTransformExecuted(marker + "PatternStatementTransform", 1.5);
// A mismatch between an [Event] method's signature and its WriteEvent call surfaces
// as an "EventSourceMessage" error event on the same provider.
@ -153,7 +156,10 @@ namespace ICSharpCode.Decompiler.Tests.Instrumentation @@ -153,7 +156,10 @@ namespace ICSharpCode.Decompiler.Tests.Instrumentation
};
foreach (string eventName in expected)
{
Assert.That(listener.EventsNamed(eventName), Has.Count.EqualTo(1), eventName);
var markedEvents = listener.EventsNamed(eventName)
.Where(p => p.Values.OfType<string>().Any(v => v.StartsWith(marker, StringComparison.Ordinal)))
.ToList();
Assert.That(markedEvents, Has.Count.EqualTo(1), eventName);
}
}

7
ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs

@ -287,8 +287,9 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -287,8 +287,9 @@ namespace ICSharpCode.Decompiler.TypeSystem
}
}
/// <returns>The number of referenced assemblies (including transitively pulled-in
/// type-forwarder targets) that were successfully resolved.</returns>
/// <returns>The number of references in the final set passed to Init(): distinct
/// resolved assemblies (same-name lower-version duplicates dropped) plus resolved
/// non-assembly modules.</returns>
private async Task<int> InitializeCoreAsync(MetadataFile mainModule, IAssemblyResolver assemblyResolver)
{
// Load referenced assemblies and type-forwarder references.
@ -415,7 +416,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -415,7 +416,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
Init(mainModuleWithOptions, referencedAssembliesWithOptions);
}
this.mainModule = (MetadataModule)base.MainModule;
return referencedAssemblies.Count;
return referencedAssembliesWithOptions.Count;
void AddToQueue(bool isAssembly, MetadataFile mainModule, object reference)
{

48
ILSpy.Tests/Instrumentation/ILSpyXEventSourceTests.cs

@ -87,22 +87,28 @@ public class ILSpyXEventSourceTests @@ -87,22 +87,28 @@ public class ILSpyXEventSourceTests
[Test]
public void FiringEveryEventProducesNoEventSourceErrors()
{
// The provider is process-wide and other tests load/search assemblies concurrently,
// so every string payload carries this marker and the count assertions filter on it.
// SnapshotLookupBuildStart/Stop have no string payload; their sentinel assemblyCount
// is distinctive enough (real snapshots in these tests stay far below it).
const string marker = "SchemaSmokeTest.";
const int lookupSentinel = 987654;
using var listener = new RecordingListener(EventLevel.Verbose, EventKeywords.All);
var log = ILSpyXEventSource.Log;
log.AssemblyLoadStart("test.dll");
log.AssemblyLoadStop("test.dll", "PEFileLoader", true);
log.AssemblyResolveStart("System.Runtime");
log.AssemblyResolveStop("System.Runtime", (int)AssemblyResolveOutcome.FoundInList);
log.SnapshotLookupBuildStart(10);
log.SnapshotLookupBuildStop(10);
log.DebugInfoLoadStart("test.dll");
log.DebugInfoLoadStop("test.dll", "PortableDebugInfoProvider");
log.SearchModuleStart("TestModule", "MemberSearchStrategy");
log.SearchModuleStop("TestModule", "MemberSearchStrategy");
log.AnalyzerScopeStart("MyNamespace.MyType");
log.AnalyzerScopeStop("MyNamespace.MyType", 3);
log.PackageOpened("app.zip", "zip", 12);
log.PackageEntryExtracted("lib/test.dll", 4096L, 0.5);
log.AssemblyLoadStart(marker + "test.dll");
log.AssemblyLoadStop(marker + "test.dll", "PEFileLoader", true);
log.AssemblyResolveStart(marker + "Reference");
log.AssemblyResolveStop(marker + "Reference", (int)AssemblyResolveOutcome.FoundInList);
log.SnapshotLookupBuildStart(lookupSentinel);
log.SnapshotLookupBuildStop(lookupSentinel);
log.DebugInfoLoadStart(marker + "test.dll");
log.DebugInfoLoadStop(marker + "test.dll", "PortableDebugInfoProvider");
log.SearchModuleStart(marker + "TestModule", "MemberSearchStrategy");
log.SearchModuleStop(marker + "TestModule", "MemberSearchStrategy");
log.AnalyzerScopeStart(marker + "MyType");
log.AnalyzerScopeStop(marker + "MyType", 3);
log.PackageOpened(marker + "app.zip", "zip", 12);
log.PackageEntryExtracted(marker + "lib/test.dll", 4096L, 0.5);
// A mismatch between an [Event] method's signature and its WriteEvent call surfaces
// as an "EventSourceMessage" error event on the same provider.
@ -111,7 +117,6 @@ public class ILSpyXEventSourceTests @@ -111,7 +117,6 @@ public class ILSpyXEventSourceTests
string[] expected = {
"AssemblyLoadStart", "AssemblyLoadStop",
"AssemblyResolveStart", "AssemblyResolveStop",
"SnapshotLookupBuildStart", "SnapshotLookupBuildStop",
"DebugInfoLoadStart", "DebugInfoLoadStop",
"SearchModuleStart", "SearchModuleStop",
"AnalyzerScopeStart", "AnalyzerScopeStop",
@ -120,7 +125,18 @@ public class ILSpyXEventSourceTests @@ -120,7 +125,18 @@ public class ILSpyXEventSourceTests
};
foreach (string eventName in expected)
{
Assert.That(listener.EventsNamed(eventName), Has.Count.EqualTo(1), eventName);
var markedEvents = listener.EventsNamed(eventName)
.Where(p => p.Values.OfType<string>().Any(v => v.StartsWith(marker, StringComparison.Ordinal)))
.ToList();
Assert.That(markedEvents, Has.Count.EqualTo(1), eventName);
}
foreach (string eventName in new[] { "SnapshotLookupBuildStart", "SnapshotLookupBuildStop" })
{
var markedEvents = listener.EventsNamed(eventName)
.Where(p => (int)p["assemblyCount"]! == lookupSentinel)
.ToList();
Assert.That(markedEvents, Has.Count.EqualTo(1), eventName);
}
}

Loading…
Cancel
Save