Skip to content

Commit

Permalink
Truly Dynamic Event (#4274)
Browse files Browse the repository at this point in the history
Changes
- Upgrade TraceEvent dependencies from 3.1.7 to 3.1.9
- Allow using custom TraceEvent library, built some support for using it
- Parse DynamicEvent and allow them to be accessed in the Notebooks.

Cleanup
- Run dotnet-format on the source code
- Ignore xlf files
- Deleted unwanted (and failing) outputs from Notebook examples.

---------

Co-authored-by: Mukund Raghav Sharma (Moko) <68247673+mrsharm@users.noreply.github.com>
  • Loading branch information
cshung and mrsharm committed Jul 9, 2024
1 parent d8f4165 commit 252ebaa
Show file tree
Hide file tree
Showing 67 changed files with 1,481 additions and 712 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ ClientBin/
*.jfm
*.publishsettings
orleans.codegen.cs
*.xlf

# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,323 @@
using FluentAssertions;
using Microsoft.Diagnostics.Tracing.Analysis.GC;
using Microsoft.Diagnostics.Tracing.Parsers.GCDynamic;
using GC.Analysis.API.DynamicEvents;
using System.Reflection;

namespace GC.Analysis.API.UnitTests
{
[TestClass]
public class DynamicEventTests
{
[TestMethod]
public void TestDuplicatedSchema()
{
Action test = () =>
{
DynamicEventSchema.Set(
new List<DynamicEventSchema>
{
new DynamicEventSchema
{
DynamicEventName = "SampleEventName",
Fields = new List<KeyValuePair<string, Type>>
{
new KeyValuePair<string, Type>("version", typeof(ushort)),
new KeyValuePair<string, Type>("Number", typeof(ulong)),
}
},
new DynamicEventSchema
{
DynamicEventName = "SampleEventName",
Fields = new List<KeyValuePair<string, Type>>
{
new KeyValuePair<string, Type>("version", typeof(ushort)),
new KeyValuePair<string, Type>("Number", typeof(ulong)),
}
}
}
);
};
test.Should().Throw<Exception>();
}

[TestMethod]
public void TestDuplicatedFields()
{
Action test = () =>
{
DynamicEventSchema.Set(
new List<DynamicEventSchema>
{
new DynamicEventSchema
{
DynamicEventName = "SampleEventName",
Fields = new List<KeyValuePair<string, Type>>
{
new KeyValuePair<string, Type>("version", typeof(ushort)),
new KeyValuePair<string, Type>("version", typeof(ulong)),
}
},
}
);
};
test.Should().Throw<Exception>();
}

[TestMethod]
public void TestUnsupportedType()
{
Action test = () =>
{
DynamicEventSchema.Set(
new List<DynamicEventSchema>
{
new DynamicEventSchema
{
DynamicEventName = "SampleEventName",
Fields = new List<KeyValuePair<string, Type>>
{
new KeyValuePair<string, Type>("version", typeof(DateTime)),
}
},
}
);
};
test.Should().Throw<Exception>();
}

[TestMethod]
public void TestNegativeMinOccurrence()
{
Action test = () =>
{
DynamicEventSchema.Set(
new List<DynamicEventSchema>
{
new DynamicEventSchema
{
DynamicEventName = "SampleEventName",
MinOccurrence = -1,
Fields = new List<KeyValuePair<string, Type>>
{
new KeyValuePair<string, Type>("version", typeof(ushort)),
}
},
}
);
};
test.Should().Throw<Exception>();
}

[TestMethod]
public void TestSmallerMaxOccurrence()
{
Action test = () =>
{
DynamicEventSchema.Set(
new List<DynamicEventSchema>
{
new DynamicEventSchema
{
DynamicEventName = "SampleEventName",
MinOccurrence = 1,
MaxOccurrence = 0,
Fields = new List<KeyValuePair<string, Type>>
{
new KeyValuePair<string, Type>("version", typeof(ushort)),
}
},
}
);
};
test.Should().Throw<Exception>();
}

private List<DynamicEventSchema> correctSingleSchema = new List<DynamicEventSchema>
{
new DynamicEventSchema
{
DynamicEventName = "SampleEventName",
MinOccurrence = 1,
Fields = new List<KeyValuePair<string, Type>>
{
new KeyValuePair<string, Type>("version", typeof(ushort)),
new KeyValuePair<string, Type>("Number", typeof(ulong)),
}
},
};

private DynamicEvent sampleEvent = new DynamicEvent(
"SampleEventName",
DateTime.Now,
new byte[] { 1, 0, 2, 0, 0, 0, 0, 0, 0, 0 }
);

private DynamicEvent unknownEvent = new DynamicEvent(
"UnknownEventName",
DateTime.Now,
new byte[] { 1, 0, 2, 0, 0, 0, 0, 0, 0, 0 }
);

[TestMethod]
public void TestMissedSingleEvent()
{
DynamicEventSchema.Set(correctSingleSchema);
List<DynamicEvent> dynamicEvents = new List<DynamicEvent>();
Action test = () =>
{
dynamic index = new DynamicIndex(dynamicEvents);
};
test.Should().Throw<Exception>();
}

[TestMethod]
public void TestDuplicatedSingleEvent()
{
DynamicEventSchema.Set(correctSingleSchema);
List<DynamicEvent> dynamicEvents = new List<DynamicEvent>
{
sampleEvent,
sampleEvent
};
Action test = () =>
{
dynamic index = new DynamicIndex(dynamicEvents);
};
test.Should().Throw<Exception>();
}

[TestMethod]
public void TestSingleEvent()
{
DynamicEventSchema.Set(correctSingleSchema);
List<DynamicEvent> dynamicEvents = new List<DynamicEvent>
{
sampleEvent
};
dynamic index = new DynamicIndex(dynamicEvents);

((int)index.SampleEventName.version).Should().Be(1);
((int)index.SampleEventName.Number).Should().Be(2);
string pattern = @"
SampleEventName
version : 1
Number : 2
TimeStamp : *
".Trim();
((string)index.SampleEventName.ToString()).Should().Match(pattern);
}

private List<DynamicEventSchema> correctMultipleSchema = new List<DynamicEventSchema>
{
new DynamicEventSchema
{
DynamicEventName = "SampleEventName",
MinOccurrence = 1,
MaxOccurrence = 2,
Fields = new List<KeyValuePair<string, Type>>
{
new KeyValuePair<string, Type>("version", typeof(ushort)),
new KeyValuePair<string, Type>("Number", typeof(ulong)),
}
},
};

[TestMethod]
public void TestMissedMultipleEvent()
{
DynamicEventSchema.Set(correctMultipleSchema);
List<DynamicEvent> dynamicEvents = new List<DynamicEvent>();
Action test = () =>
{
dynamic index = new DynamicIndex(dynamicEvents);
};
test.Should().Throw<Exception>();
}

[TestMethod]
public void TestTooManyMultipleEvents()
{
DynamicEventSchema.Set(correctMultipleSchema);
List<DynamicEvent> dynamicEvents = new List<DynamicEvent>
{
sampleEvent,
sampleEvent,
sampleEvent,
};
Action test = () =>
{
dynamic index = new DynamicIndex(dynamicEvents);
};
test.Should().Throw<Exception>();
}

[TestMethod]
public void TestMultipleEvents()
{
DynamicEventSchema.Set(correctMultipleSchema);
List<DynamicEvent> dynamicEvents = new List<DynamicEvent>
{
sampleEvent,
sampleEvent,
};
dynamic index = new DynamicIndex(dynamicEvents);

((int)index.SampleEventName[0].version).Should().Be(1);
((int)index.SampleEventName[0].Number).Should().Be(2);
((int)index.SampleEventName[1].version).Should().Be(1);
((int)index.SampleEventName[1].Number).Should().Be(2);
}

[TestMethod]
public void TestOptionalEvent()
{
DynamicEventSchema.Set(
new List<DynamicEventSchema>
{
new DynamicEventSchema
{
DynamicEventName = "SampleEventName",
Fields = new List<KeyValuePair<string, Type>>
{
new KeyValuePair<string, Type>("version", typeof(ushort)),
new KeyValuePair<string, Type>("Number", typeof(ulong)),
}
},
}
);
List<DynamicEvent> dynamicEvents = new List<DynamicEvent>();
dynamic index = new DynamicIndex(dynamicEvents);
((bool)(index.SampleEventName == null)).Should().Be(true);
}

[TestMethod]
public void TestForgivingUnknownEvent()
{
DynamicEventSchema.Set(correctSingleSchema);
List<DynamicEvent> dynamicEvents = new List<DynamicEvent>
{
sampleEvent,
unknownEvent
};
dynamic index = new DynamicIndex(dynamicEvents);
// As long as we don't throw exception, this is forgiving.
}

[TestMethod]
public void TestReportingUnknownEvent()
{
DynamicEventSchema.Set(correctSingleSchema, false);
List<DynamicEvent> dynamicEvents = new List<DynamicEvent>
{
sampleEvent,
unknownEvent
};
Action test = () =>
{
dynamic index = new DynamicIndex(dynamicEvents);
};
test.Should().Throw<Exception>();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>
<IsPackable>false</IsPackable>
</PropertyGroup>

<Import Project="../Versions.props" />

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.0.0-beta0003" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Condition="'$(CustomTraceEvent)' != 'true'" Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="3.1.9" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.8" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.8" />
<PackageReference Include="coverlet.collector" Version="3.1.2" />
</ItemGroup>

<ItemGroup Condition="'$(CustomTraceEvent)' == 'true'">
<Reference Include="Microsoft.Diagnostics.FastSerialization.dll">
<HintPath>$(PerfViewPath)\src\FastSerialization\bin\Release\netstandard2.0\Microsoft.Diagnostics.FastSerialization.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Diagnostics.Tracing.TraceEvent">
<HintPath>$(PerfViewPath)\src\TraceEvent\bin\Release\netstandard2.0\Microsoft.Diagnostics.Tracing.TraceEvent.dll</HintPath>
</Reference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\GC.Analysis.API\GC.Analysis.API.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
global using Microsoft.VisualStudio.TestTools.UnitTesting;
8 changes: 7 additions & 1 deletion src/benchmarks/gc/GC.Infrastructure/GC.Analysis.API.sln
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GC.Infrastructure.Core", "G
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GC.Infrastructure.Core.UnitTests", "GC.Infrastructure.Core.UnitTests\GC.Infrastructure.Core.UnitTests.csproj", "{61F3DF76-A933-44AE-B5FF-B7909ED21999}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GC.Infrastructure", "GC.Infrastructure\GC.Infrastructure.csproj", "{7B2B6934-0DBD-45E0-9563-AE9DC8EBD538}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GC.Infrastructure", "GC.Infrastructure\GC.Infrastructure.csproj", "{7B2B6934-0DBD-45E0-9563-AE9DC8EBD538}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GC.Analysis.API.UnitTests", "GC.Analysis.API.UnitTests\GC.Analysis.API.UnitTests.csproj", "{A7D40245-CF5C-437E-B7E7-278AEA02954D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -33,6 +35,10 @@ Global
{7B2B6934-0DBD-45E0-9563-AE9DC8EBD538}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7B2B6934-0DBD-45E0-9563-AE9DC8EBD538}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7B2B6934-0DBD-45E0-9563-AE9DC8EBD538}.Release|Any CPU.Build.0 = Release|Any CPU
{A7D40245-CF5C-437E-B7E7-278AEA02954D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A7D40245-CF5C-437E-B7E7-278AEA02954D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A7D40245-CF5C-437E-B7E7-278AEA02954D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A7D40245-CF5C-437E-B7E7-278AEA02954D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Loading

0 comments on commit 252ebaa

Please sign in to comment.