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

Added unit tests to cover passing nullable types to System.Diagnostics.Tracing #32777

Merged
merged 21 commits into from
Oct 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
428c505
Add unit tests that pass nullable types to EventSource
jbhensley Oct 11, 2018
428024f
Add unit tests that pass nullable types to EventSource
jbhensley Oct 11, 2018
709cce7
Merge branch 'issue-32606' of https://github.com/jbhensley/corefx int…
jbhensley Oct 11, 2018
e483942
Remove unnecessary test executed outside of the main harness
jbhensley Oct 12, 2018
6dac9e2
Add tests with nullable args for EventListener
jbhensley Oct 12, 2018
35686a9
Remove nullable tests from non-self-describing EventSource
jbhensley Oct 19, 2018
3691f5e
Modify eventName due to test fail on CI that is not happening locally
jbhensley Oct 20, 2018
efe702d
More CI fails that do no repro locally
jbhensley Oct 20, 2018
0e3d349
Change to see if CI will pass nullableInt == 12 test with cast to int…
jbhensley Oct 21, 2018
89b724e
Change to see which line CI tosses on
jbhensley Oct 21, 2018
e4ead86
Add console dump of eventNullableInt type name
jbhensley Oct 21, 2018
9e0cb73
Add xUnit output to trace eventNullableInt type in CI test
jbhensley Oct 21, 2018
722f87c
Conditional method call to get type info through stacktrace
jbhensley Oct 21, 2018
ff4e373
Event payload as Dictionary
jbhensley Oct 21, 2018
e9b94ba
Event payload as IDictionary
jbhensley Oct 21, 2018
8388346
Nullable test event payload as IDictionary
jbhensley Oct 21, 2018
8756cad
Change to get payload type namespace and name
jbhensley Oct 22, 2018
a40a3cf
Attempt to make tests work both locally and on CI
jbhensley Oct 22, 2018
c4be58c
Attempt to handle payload as several different types
jbhensley Oct 23, 2018
52e0971
Modify tests to properly unwrap nullable from event payload
jbhensley Oct 24, 2018
b695ff7
Properly unwrap nullables for self describing ETW tests
jbhensley Oct 24, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System.Diagnostics;
using Xunit;
using System;
using System.Collections.Generic;

namespace BasicEventSourceTests
{
Expand Down Expand Up @@ -47,5 +48,35 @@ public static void CheckNoEventSourcesRunning(string message = "")
Debug.WriteLine(message);
Assert.Equal("", eventSourceNames);
}

/// <summary>
/// Unwraps a nullable returned from either ETW or EventListener
/// </summary>
/// <typeparam name="T">The type to unwrap</typeparam>
/// <param name="wrappedValue">Value returned from event payload</param>
/// <returns></returns>
public static T? UnwrapNullable<T>(object wrappedValue) where T : struct
{
// ETW will return a collection of key/value pairs
if (wrappedValue is IDictionary<string, object> dict)
{
Assert.True(dict.ContainsKey("HasValue"));
Assert.True(dict.ContainsKey("Value"));

if ((bool)dict["HasValue"])
{
return (T)dict["Value"];
}
}
// EventListener will return the boxed value of the nullable, which will either be a value or null object reference
else if (wrappedValue != null)
{
Assert.IsType(typeof(T), wrappedValue);
return (T?)wrappedValue;
}

// wrappedValue is null or wrappedValue is IDictionary, but HasValue is false
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ internal enum ColorUInt64 : ulong { Red, Blue, Green };

public partial class TestsWrite
{

[EventData]
private struct PartB_UserInfo
{
Expand Down Expand Up @@ -127,6 +128,66 @@ private void Test_Write_T(Listener listener)
Array.Equals(eventArray, byteArray);
}));
/*************************************************************************/
int? nullableInt = 12;
tests.Add(new SubTest("Write/Basic/int?/12",
delegate ()
{
logger.Write("Int12", new { nInteger = nullableInt });
},
delegate (Event evt)
{
Assert.Equal(logger.Name, evt.ProviderName);
Assert.Equal("Int12", evt.EventName);

var payload = evt.PayloadValue(0, "nInteger");
Assert.Equal(nullableInt, TestUtilities.UnwrapNullable<int>(payload));
}));
/*************************************************************************/
int? nullableInt2 = null;
tests.Add(new SubTest("Write/Basic/int?/null",
delegate ()
{
logger.Write("IntNull", new { nInteger = nullableInt2 });
},
delegate (Event evt)
{
Assert.Equal(logger.Name, evt.ProviderName);
Assert.Equal("IntNull", evt.EventName);

var payload = evt.PayloadValue(0, "nInteger");
Assert.Equal(nullableInt2, TestUtilities.UnwrapNullable<int>(payload));
}));
///*************************************************************************/
DateTime? nullableDate = DateTime.Now;
tests.Add(new SubTest("Write/Basic/DateTime?/Now",
delegate ()
{
logger.Write("DateTimeNow", new { nowTime = nullableDate });
},
delegate (Event evt)
{
Assert.Equal(logger.Name, evt.ProviderName);
Assert.Equal("DateTimeNow", evt.EventName);

var payload = evt.PayloadValue(0, "nowTime");
Assert.Equal(nullableDate, TestUtilities.UnwrapNullable<DateTime>(payload));
}));
/*************************************************************************/
DateTime? nullableDate2 = null;
tests.Add(new SubTest("Write/Basic/DateTime?/Null",
delegate ()
{
logger.Write("DateTimeNull", new { nowTime = nullableDate2 });
},
delegate (Event evt)
{
Assert.Equal(logger.Name, evt.ProviderName);
Assert.Equal("DateTimeNull", evt.EventName);

var payload = evt.PayloadValue(0, "nowTime");
Assert.Equal(nullableDate2, TestUtilities.UnwrapNullable<DateTime>(payload));
}));
/*************************************************************************/
tests.Add(new SubTest("Write/Basic/PartBOnly",
delegate ()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,71 @@ private void Test_WriteEvent_ComplexData_SelfDescribing(Listener listener)
Assert.Equal(5, evt.PayloadValue(1, "anInt"));
}));


int? nullableInt = 12;
tests.Add(new SubTest("WriteEvent/SelfDescribingOnly/Int12",
delegate ()
{
logger.EventNullableIntInt(nullableInt, 5);
},
delegate (Event evt)
{
Assert.Equal(logger.Name, evt.ProviderName);
Assert.Equal("EventNullableIntInt", evt.EventName);

var payload = evt.PayloadValue(0, "nullableInt");
Assert.Equal(nullableInt, TestUtilities.UnwrapNullable<int>(payload));
Assert.Equal(5, evt.PayloadValue(1, "anInt"));
}));

int? nullableInt2 = null;
tests.Add(new SubTest("WriteEvent/SelfDescribingOnly/IntNull",
delegate ()
{
logger.EventNullableIntInt(nullableInt2, 5);
},
delegate (Event evt)
{
Assert.Equal(logger.Name, evt.ProviderName);
Assert.Equal("EventNullableIntInt", evt.EventName);

var payload = evt.PayloadValue(0, "nullableInt");
Assert.Equal(nullableInt2, TestUtilities.UnwrapNullable<int>(payload));
Assert.Equal(5, evt.PayloadValue(1, "anInt"));
}));

DateTime? nullableDate = DateTime.Now;
tests.Add(new SubTest("WriteEvent/SelfDescribingOnly/DateTimeNow",
delegate ()
{
logger.EventNullableDateTimeInt(nullableDate, 5);
},
delegate (Event evt)
{
Assert.Equal(logger.Name, evt.ProviderName);
Assert.Equal("EventNullableDateTimeInt", evt.EventName);

var payload = evt.PayloadValue(0, "nullableDate");
Assert.Equal(nullableDate, TestUtilities.UnwrapNullable<DateTime>(payload));
Assert.Equal(5, evt.PayloadValue(1, "anInt"));
}));

DateTime? nullableDate2 = null;
tests.Add(new SubTest("WriteEvent/SelfDescribingOnly/DateTimeNull",
delegate ()
{
logger.EventNullableDateTimeInt(nullableDate2, 5);
},
delegate (Event evt)
{
Assert.Equal(logger.Name, evt.ProviderName);
Assert.Equal("EventNullableDateTimeInt", evt.EventName);

var payload = evt.PayloadValue(0, "nullableDate");
Assert.Equal(nullableDate2, TestUtilities.UnwrapNullable<DateTime>(nullableDate2));
Assert.Equal(5, evt.PayloadValue(1, "anInt"));
}));

// If you only wish to run one or several of the tests you can filter them here by
// Uncommenting the following line.
// tests = tests.FindAll(test => Regex.IsMatch(test.Name, "ventWithByteArray"));
Expand Down Expand Up @@ -621,6 +686,8 @@ public sealed class EventSourceTestSelfDescribingOnly : EventSource
public EventSourceTestSelfDescribingOnly() : base(EventSourceSettings.EtwSelfDescribingEventFormat) { }
public void EventByteArrayInt(byte[] array, int anInt) { WriteEvent(1, array, anInt); }
public void EventUserDataInt(UserData aClass, int anInt) { WriteEvent(2, aClass, anInt); }
public void EventNullableIntInt(int? nullableInt, int anInt) { WriteEvent(3, nullableInt, anInt); }
public void EventNullableDateTimeInt(DateTime? nullableDate, int anInt) { WriteEvent(4, nullableDate, anInt); }
}

public sealed class EventSourceTestByteArray : EventSource
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ namespace SdtEventSources
/// <summary>
/// A sample Event source. The Guid and Name attributes are "idempotent", i.e. they
/// don't change the default computed by EventSource; they're specified here just to
/// increase the code coverage.
/// increase the code coverage.
///
/// Also, this EventSource uses manifest-based ETW and is not self-describing. That means
/// it does not support complex data types, including nullables, as event arguments.
/// </summary>
[EventSource(Guid = "69e2aa3e-083b-5014-cad4-3e511a0b94cf", Name = "EventSourceTest")]
public sealed class EventSourceTest : EventSource
Expand Down