Skip to content

Commit bf5b380

Browse files
authored
Add LTTngCds Unit Test that only references LTTngCds (Microsoft.Performance.Toolkit.Plugins.LTTngPlugin) and tests some data with basic cooker including CurrentCpu - equivalent to cpu_id (#105)
1 parent cce4f83 commit bf5b380

File tree

6 files changed

+487
-180
lines changed

6 files changed

+487
-180
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT license.
3+
4+
using System.Collections.Generic;
5+
using System.Threading;
6+
using LTTngCds.CookerData;
7+
using Microsoft.Performance.SDK;
8+
using Microsoft.Performance.SDK.Extensibility;
9+
using Microsoft.Performance.SDK.Extensibility.DataCooking;
10+
using Microsoft.Performance.SDK.Extensibility.DataCooking.SourceDataCooking;
11+
12+
namespace LTTngCdsUnitTest.SourceDataCookers
13+
{
14+
public abstract class LTTngBaseSourceCooker
15+
: CookedDataReflector,
16+
ISourceDataCooker<LTTngEvent, LTTngContext, string>
17+
{
18+
private static readonly HashSet<string> emptyDataKeys = new HashSet<string>();
19+
protected static readonly ReadOnlyHashSet<string> EmptyDataKeys = new ReadOnlyHashSet<string>(emptyDataKeys);
20+
21+
protected LTTngBaseSourceCooker(string cookerId)
22+
: this(DataCookerPath.ForSource(LTTngConstants.SourceId, cookerId))
23+
{
24+
}
25+
26+
protected LTTngBaseSourceCooker(DataCookerPath dataCookerPath)
27+
: base(dataCookerPath)
28+
{
29+
this.Path = dataCookerPath;
30+
}
31+
32+
protected long computeTime = 0;
33+
34+
/// <summary>
35+
/// All source data cookers that inherit from this reference the LTTng source parser.
36+
/// </summary>
37+
public string SourceParserId => Path.SourceParserId;
38+
39+
/// <summary>
40+
/// The data cooker identifier.
41+
/// </summary>
42+
public string DataCookerId => Path.DataCookerId;
43+
44+
/// <summary>
45+
/// Combines the SourceId and the cooker Id.
46+
/// </summary>
47+
public virtual DataCookerPath Path { get; }
48+
49+
/// <summary>
50+
/// No additional options by default.
51+
/// </summary>
52+
public virtual SourceDataCookerOptions Options => SourceDataCookerOptions.None;
53+
54+
/// <summary>
55+
/// Default to no dependencies.
56+
/// </summary>
57+
public virtual IReadOnlyCollection<DataCookerPath> RequiredDataCookers => new HashSet<DataCookerPath>();
58+
59+
/// <summary>
60+
/// Default consumption types - by default.
61+
/// </summary>
62+
public virtual IReadOnlyDictionary<DataCookerPath, DataCookerDependencyType> DependencyTypes =>
63+
new Dictionary<DataCookerPath, DataCookerDependencyType>();
64+
65+
public abstract string Description { get; }
66+
67+
public virtual DataProductionStrategy DataProductionStrategy { get; }
68+
69+
public abstract ReadOnlyHashSet<string> DataKeys { get; }
70+
71+
public virtual void BeginDataCooking(ICookedDataRetrieval dependencyRetrieval, CancellationToken cancellationToken)
72+
{
73+
74+
}
75+
76+
public virtual void EndDataCooking(CancellationToken cancellationToken)
77+
{
78+
}
79+
80+
public abstract DataProcessingResult CookDataElement(
81+
LTTngEvent data,
82+
LTTngContext context,
83+
CancellationToken cancellationToken);
84+
}
85+
}

LTTngCdsUnitTest/LTTngCdsUnitTest.cs

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT license.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.IO;
7+
using LTTngCdsUnitTest.SourceDataCookers;
8+
using Microsoft.Performance.SDK.Extensibility;
9+
using Microsoft.Performance.SDK.Processing;
10+
using Microsoft.Performance.Toolkit.Engine;
11+
using Microsoft.VisualStudio.TestTools.UnitTesting;
12+
13+
namespace LTTngCdsUnitTest
14+
{
15+
[TestClass]
16+
public class LTTngCdsUnitTest
17+
{
18+
public static bool IsTraceProcessed = false;
19+
public static object IsTraceProcessedLock = new object();
20+
21+
private static RuntimeExecutionResults RuntimeExecutionResults;
22+
23+
private static DataCookerPath LTTngEventDataCookerPath;
24+
25+
public static void ProcessTrace()
26+
{
27+
lock (IsTraceProcessedLock)
28+
{
29+
if (!IsTraceProcessed)
30+
{
31+
// Input data
32+
string[] lttngData = { @"..\..\..\..\TestData\LTTng\lttng-kernel-trace.ctf" };
33+
var lttngDataPath = new FileInfo(lttngData[0]);
34+
Assert.IsTrue(lttngDataPath.Exists);
35+
36+
var runtime = Engine.Create(new FileDataSource(lttngDataPath.FullName));
37+
38+
// Enable our various types of data
39+
var lttngDataCooker = new LTTngEventDataCooker();
40+
LTTngEventDataCookerPath = lttngDataCooker.Path;
41+
runtime.EnableCooker(LTTngEventDataCookerPath);
42+
43+
//
44+
// Process our data.
45+
//
46+
47+
RuntimeExecutionResults = runtime.Process();
48+
49+
IsTraceProcessed = true;
50+
}
51+
}
52+
}
53+
54+
[TestMethod]
55+
public void TestLTTngEvent()
56+
{
57+
ProcessTrace();
58+
59+
var eventData = RuntimeExecutionResults.QueryOutput<IReadOnlyList<LTTngEventWithContext>>(
60+
new DataOutputPath(
61+
LTTngEventDataCookerPath,
62+
nameof(LTTngEventDataCooker.Events)));
63+
64+
Assert.IsTrue(eventData.Count == 936356);
65+
66+
var lttngEvent3 = eventData[3];
67+
68+
// Context
69+
Assert.IsTrue(lttngEvent3.LTTngContext.Clocks.Count == 1);
70+
Assert.IsTrue(lttngEvent3.LTTngContext.Clocks["monotonic"].Name == "monotonic");
71+
Assert.IsTrue(lttngEvent3.LTTngContext.Clocks["monotonic"].Frequency == 1000000000);
72+
Assert.IsTrue(lttngEvent3.LTTngContext.Clocks["monotonic"].Offset == 1565905093154690150);
73+
Assert.IsTrue(lttngEvent3.LTTngContext.CurrentCpu == 1);
74+
Assert.IsTrue(lttngEvent3.LTTngContext.Timestamp == 7120199554940);
75+
Assert.IsTrue(lttngEvent3.LTTngContext.TracerMajor == 9 &&
76+
lttngEvent3.LTTngContext.TracerMinor == 10);
77+
78+
// LTTngEvent
79+
Assert.IsTrue(lttngEvent3.LTTngEvent.Id == 1178);
80+
Assert.IsTrue(lttngEvent3.LTTngEvent.Name == "sched_waking");
81+
Assert.IsTrue(lttngEvent3.LTTngEvent.Payload.Fields.Count == 4);
82+
Assert.IsTrue(lttngEvent3.LTTngEvent.StreamDefinedEventContext.Fields.Count == 3);
83+
Assert.IsTrue(lttngEvent3.LTTngEvent.StreamDefinedEventContext.FieldsByName.ContainsKey("_tid"));
84+
Assert.IsTrue(lttngEvent3.LTTngEvent.StreamDefinedEventContext.FieldsByName.ContainsKey("_pid"));
85+
Assert.IsTrue(lttngEvent3.LTTngEvent.StreamDefinedEventContext.FieldsByName.ContainsKey("_procname"));
86+
Assert.IsTrue(lttngEvent3.LTTngEvent.WallClockTime == new DateTime(637015090133542450));
87+
Assert.IsTrue(lttngEvent3.LTTngEvent.Timestamp == new Microsoft.Performance.SDK.Timestamp(7120199554940));
88+
}
89+
}
90+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netcoreapp3.1</TargetFramework>
5+
<Nullable>enable</Nullable>
6+
7+
<IsPackable>false</IsPackable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
12+
<PackageReference Include="Microsoft.Performance.Toolkit.Engine" Version="1.0.16" />
13+
<PackageReference Include="MSTest.TestAdapter" Version="2.2.8" />
14+
<PackageReference Include="MSTest.TestFramework" Version="2.2.8" />
15+
<PackageReference Include="coverlet.collector" Version="3.1.2" />
16+
</ItemGroup>
17+
18+
<ItemGroup>
19+
<ProjectReference Include="..\LTTngCds\LTTngCds.csproj" />
20+
</ItemGroup>
21+
22+
</Project>
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT license.
3+
4+
using System;
5+
using System.Threading;
6+
using System.Collections.Generic;
7+
using CtfPlayback;
8+
using LTTngCds.CookerData;
9+
using Microsoft.Performance.SDK;
10+
using Microsoft.Performance.SDK.Extensibility;
11+
using Microsoft.Performance.SDK.Extensibility.DataCooking;
12+
using Microsoft.Performance.SDK.Extensibility.DataCooking.SourceDataCooking;
13+
using Microsoft.Performance.SDK.Processing;
14+
15+
namespace LTTngCdsUnitTest.SourceDataCookers
16+
{
17+
public class LTTngEventDataCooker
18+
: LTTngBaseSourceCooker
19+
{
20+
public const string Identifier = "LTTngEvents";
21+
22+
public override string Description => "All events reported in the source.";
23+
24+
public LTTngEventDataCooker()
25+
: base(Identifier)
26+
{
27+
this.Events = new ProcessedEventData<LTTngEventWithContext>();
28+
}
29+
30+
/// <summary>
31+
/// No specific data keys for generic events, rather, the ReceiveAllEvents option is set.
32+
/// </summary>
33+
public override ReadOnlyHashSet<string> DataKeys => EmptyDataKeys;
34+
35+
/// <summary>
36+
/// This data cooker receives all data elements.
37+
/// </summary>
38+
public override SourceDataCookerOptions Options => SourceDataCookerOptions.ReceiveAllDataElements;
39+
40+
public override DataProcessingResult CookDataElement(
41+
LTTngEvent data,
42+
LTTngContext context,
43+
CancellationToken cancellationToken)
44+
{
45+
try
46+
{
47+
Events.AddEvent(new LTTngEventWithContext(data, context));
48+
49+
this.MaximumEventFieldCount =
50+
Math.Max(data.Payload.Fields.Count, this.MaximumEventFieldCount);
51+
}
52+
catch (CtfPlaybackException e)
53+
{
54+
Console.Error.WriteLine($"Error consuming event: {e.Message}");
55+
return DataProcessingResult.CorruptData;
56+
}
57+
58+
return DataProcessingResult.Processed;
59+
}
60+
61+
public override void EndDataCooking(CancellationToken cancellationToken)
62+
{
63+
this.Events.FinalizeData();
64+
}
65+
66+
[DataOutput]
67+
public ProcessedEventData<LTTngEventWithContext> Events { get; }
68+
69+
70+
/// <summary>
71+
/// The highest number of fields found in any single event.
72+
/// </summary>
73+
[DataOutput]
74+
public int MaximumEventFieldCount { get; private set; }
75+
}
76+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT license.
3+
4+
using LTTngCds.CookerData;
5+
6+
namespace LTTngCdsUnitTest
7+
{
8+
public class LTTngEventWithContext
9+
{
10+
public LTTngEventWithContext(LTTngEvent lTTngEvent, LTTngContext lTTngContext)
11+
{
12+
LTTngEvent = lTTngEvent;
13+
LTTngContext = lTTngContext;
14+
}
15+
16+
public LTTngEvent LTTngEvent { get; private set; }
17+
public LTTngContext LTTngContext { get; private set; }
18+
}
19+
}

0 commit comments

Comments
 (0)