Skip to content

Commit 79342c4

Browse files
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
1 parent 7cbcad9 commit 79342c4

3 files changed

Lines changed: 57 additions & 34 deletions

File tree

ICSharpCode.Decompiler.Tests/Instrumentation/DecompilerEventSourceTests.cs

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -121,22 +121,25 @@ public void ManifestIsValid()
121121
[Test]
122122
public void FiringEveryEventProducesNoEventSourceErrors()
123123
{
124+
// The provider is process-wide and other fixtures decompile in parallel, so every
125+
// string payload carries this marker and the count assertions filter on it.
126+
const string marker = "SchemaSmokeTest.";
124127
using var listener = new RecordingListener(EventLevel.Verbose, EventKeywords.All);
125128
var log = DecompilerEventSource.Log;
126-
log.DecompileTypeStart("T");
127-
log.DecompileTypeStop("T");
128-
log.DecompileMemberStart("T.M", 0x06000001, (int)DecompiledMemberKind.Method, 42);
129-
log.DecompileMemberStop("T.M", 0x06000001, (int)DecompiledMemberKind.Method);
130-
log.TypeSystemInitStart("module");
131-
log.TypeSystemInitStop("module", 3);
132-
log.AssemblyResolveStart("System.Runtime");
133-
log.AssemblyResolveStop("System.Runtime", "/path/System.Runtime.dll", true);
134-
log.ProjectDecompilationStart("module");
135-
log.ProjectDecompilationStop("module", 10, 2);
136-
log.ProjectFileStart("File.cs", 5);
137-
log.ProjectFileStop("File.cs");
138-
log.ILTransformExecuted("ILInlining", 0x06000001, 0.5);
139-
log.AstTransformExecuted("PatternStatementTransform", 1.5);
129+
log.DecompileTypeStart(marker + "Type");
130+
log.DecompileTypeStop(marker + "Type");
131+
log.DecompileMemberStart(marker + "Type.M", 0x06000001, (int)DecompiledMemberKind.Method, 42);
132+
log.DecompileMemberStop(marker + "Type.M", 0x06000001, (int)DecompiledMemberKind.Method);
133+
log.TypeSystemInitStart(marker + "module");
134+
log.TypeSystemInitStop(marker + "module", 3);
135+
log.AssemblyResolveStart(marker + "Reference");
136+
log.AssemblyResolveStop(marker + "Reference", marker + "Reference.dll", true);
137+
log.ProjectDecompilationStart(marker + "module");
138+
log.ProjectDecompilationStop(marker + "module", 10, 2);
139+
log.ProjectFileStart(marker + "File.cs", 5);
140+
log.ProjectFileStop(marker + "File.cs");
141+
log.ILTransformExecuted(marker + "ILInlining", 0x06000001, 0.5);
142+
log.AstTransformExecuted(marker + "PatternStatementTransform", 1.5);
140143

141144
// A mismatch between an [Event] method's signature and its WriteEvent call surfaces
142145
// as an "EventSourceMessage" error event on the same provider.
@@ -153,7 +156,10 @@ public void FiringEveryEventProducesNoEventSourceErrors()
153156
};
154157
foreach (string eventName in expected)
155158
{
156-
Assert.That(listener.EventsNamed(eventName), Has.Count.EqualTo(1), eventName);
159+
var markedEvents = listener.EventsNamed(eventName)
160+
.Where(p => p.Values.OfType<string>().Any(v => v.StartsWith(marker, StringComparison.Ordinal)))
161+
.ToList();
162+
Assert.That(markedEvents, Has.Count.EqualTo(1), eventName);
157163
}
158164
}
159165

ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -287,8 +287,9 @@ private async Task InitializeAsync(MetadataFile mainModule, IAssemblyResolver as
287287
}
288288
}
289289

290-
/// <returns>The number of referenced assemblies (including transitively pulled-in
291-
/// type-forwarder targets) that were successfully resolved.</returns>
290+
/// <returns>The number of references in the final set passed to Init(): distinct
291+
/// resolved assemblies (same-name lower-version duplicates dropped) plus resolved
292+
/// non-assembly modules.</returns>
292293
private async Task<int> InitializeCoreAsync(MetadataFile mainModule, IAssemblyResolver assemblyResolver)
293294
{
294295
// Load referenced assemblies and type-forwarder references.
@@ -415,7 +416,7 @@ private async Task<int> InitializeCoreAsync(MetadataFile mainModule, IAssemblyRe
415416
Init(mainModuleWithOptions, referencedAssembliesWithOptions);
416417
}
417418
this.mainModule = (MetadataModule)base.MainModule;
418-
return referencedAssemblies.Count;
419+
return referencedAssembliesWithOptions.Count;
419420

420421
void AddToQueue(bool isAssembly, MetadataFile mainModule, object reference)
421422
{

ILSpy.Tests/Instrumentation/ILSpyXEventSourceTests.cs

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -87,22 +87,28 @@ public void ManifestIsValid()
8787
[Test]
8888
public void FiringEveryEventProducesNoEventSourceErrors()
8989
{
90+
// The provider is process-wide and other tests load/search assemblies concurrently,
91+
// so every string payload carries this marker and the count assertions filter on it.
92+
// SnapshotLookupBuildStart/Stop have no string payload; their sentinel assemblyCount
93+
// is distinctive enough (real snapshots in these tests stay far below it).
94+
const string marker = "SchemaSmokeTest.";
95+
const int lookupSentinel = 987654;
9096
using var listener = new RecordingListener(EventLevel.Verbose, EventKeywords.All);
9197
var log = ILSpyXEventSource.Log;
92-
log.AssemblyLoadStart("test.dll");
93-
log.AssemblyLoadStop("test.dll", "PEFileLoader", true);
94-
log.AssemblyResolveStart("System.Runtime");
95-
log.AssemblyResolveStop("System.Runtime", (int)AssemblyResolveOutcome.FoundInList);
96-
log.SnapshotLookupBuildStart(10);
97-
log.SnapshotLookupBuildStop(10);
98-
log.DebugInfoLoadStart("test.dll");
99-
log.DebugInfoLoadStop("test.dll", "PortableDebugInfoProvider");
100-
log.SearchModuleStart("TestModule", "MemberSearchStrategy");
101-
log.SearchModuleStop("TestModule", "MemberSearchStrategy");
102-
log.AnalyzerScopeStart("MyNamespace.MyType");
103-
log.AnalyzerScopeStop("MyNamespace.MyType", 3);
104-
log.PackageOpened("app.zip", "zip", 12);
105-
log.PackageEntryExtracted("lib/test.dll", 4096L, 0.5);
98+
log.AssemblyLoadStart(marker + "test.dll");
99+
log.AssemblyLoadStop(marker + "test.dll", "PEFileLoader", true);
100+
log.AssemblyResolveStart(marker + "Reference");
101+
log.AssemblyResolveStop(marker + "Reference", (int)AssemblyResolveOutcome.FoundInList);
102+
log.SnapshotLookupBuildStart(lookupSentinel);
103+
log.SnapshotLookupBuildStop(lookupSentinel);
104+
log.DebugInfoLoadStart(marker + "test.dll");
105+
log.DebugInfoLoadStop(marker + "test.dll", "PortableDebugInfoProvider");
106+
log.SearchModuleStart(marker + "TestModule", "MemberSearchStrategy");
107+
log.SearchModuleStop(marker + "TestModule", "MemberSearchStrategy");
108+
log.AnalyzerScopeStart(marker + "MyType");
109+
log.AnalyzerScopeStop(marker + "MyType", 3);
110+
log.PackageOpened(marker + "app.zip", "zip", 12);
111+
log.PackageEntryExtracted(marker + "lib/test.dll", 4096L, 0.5);
106112

107113
// A mismatch between an [Event] method's signature and its WriteEvent call surfaces
108114
// as an "EventSourceMessage" error event on the same provider.
@@ -111,7 +117,6 @@ public void FiringEveryEventProducesNoEventSourceErrors()
111117
string[] expected = {
112118
"AssemblyLoadStart", "AssemblyLoadStop",
113119
"AssemblyResolveStart", "AssemblyResolveStop",
114-
"SnapshotLookupBuildStart", "SnapshotLookupBuildStop",
115120
"DebugInfoLoadStart", "DebugInfoLoadStop",
116121
"SearchModuleStart", "SearchModuleStop",
117122
"AnalyzerScopeStart", "AnalyzerScopeStop",
@@ -120,7 +125,18 @@ public void FiringEveryEventProducesNoEventSourceErrors()
120125
};
121126
foreach (string eventName in expected)
122127
{
123-
Assert.That(listener.EventsNamed(eventName), Has.Count.EqualTo(1), eventName);
128+
var markedEvents = listener.EventsNamed(eventName)
129+
.Where(p => p.Values.OfType<string>().Any(v => v.StartsWith(marker, StringComparison.Ordinal)))
130+
.ToList();
131+
Assert.That(markedEvents, Has.Count.EqualTo(1), eventName);
132+
}
133+
134+
foreach (string eventName in new[] { "SnapshotLookupBuildStart", "SnapshotLookupBuildStop" })
135+
{
136+
var markedEvents = listener.EventsNamed(eventName)
137+
.Where(p => (int)p["assemblyCount"]! == lookupSentinel)
138+
.ToList();
139+
Assert.That(markedEvents, Has.Count.EqualTo(1), eventName);
124140
}
125141
}
126142

0 commit comments

Comments
 (0)