diff --git a/WindowsDevicePortalWrapper/MockDataGenerator/Program.cs b/WindowsDevicePortalWrapper/MockDataGenerator/Program.cs
index fdf35088..a86be83a 100644
--- a/WindowsDevicePortalWrapper/MockDataGenerator/Program.cs
+++ b/WindowsDevicePortalWrapper/MockDataGenerator/Program.cs
@@ -40,8 +40,11 @@ public class Program
new Endpoint(HttpMethods.Get, DevicePortal.IpConfigApi),
new Endpoint(HttpMethods.Get, DevicePortal.SystemPerfApi),
new Endpoint(HttpMethods.Get, DevicePortal.RunningProcessApi),
+ new Endpoint(HttpMethods.Get, DevicePortal.CustomEtwProvidersApi),
+ new Endpoint(HttpMethods.Get, DevicePortal.EtwProvidersApi),
new Endpoint(HttpMethods.WebSocket, DevicePortal.SystemPerfApi),
new Endpoint(HttpMethods.WebSocket, DevicePortal.RunningProcessApi),
+ new Endpoint(HttpMethods.WebSocket, DevicePortal.RealtimeEtwSessionApi),
// HoloLens specific endpoints
new Endpoint(HttpMethods.Get, DevicePortal.HolographicIpdApi),
diff --git a/WindowsDevicePortalWrapper/UnitTestProject/Core/EtwTests.cs b/WindowsDevicePortalWrapper/UnitTestProject/Core/EtwTests.cs
new file mode 100644
index 00000000..c168141e
--- /dev/null
+++ b/WindowsDevicePortalWrapper/UnitTestProject/Core/EtwTests.cs
@@ -0,0 +1,112 @@
+//----------------------------------------------------------------------------------------------
+//
+// Licensed under the MIT License. See LICENSE.TXT in the project root license information.
+//
+//----------------------------------------------------------------------------------------------
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using static Microsoft.Tools.WindowsDevicePortal.DevicePortal;
+
+namespace Microsoft.Tools.WindowsDevicePortal.Tests.Core
+{
+ ///
+ /// Test class for ETW APIs.
+ ///
+ [TestClass]
+ public class EtwTests : BaseTests
+ {
+ ///
+ /// Basic test of GET method for getting a list of custom registered ETW providers.
+ ///
+ [TestMethod]
+ public void GetCustomEtwProvidersTest()
+ {
+ TestHelpers.MockHttpResponder.AddMockResponse(DevicePortal.CustomEtwProvidersApi, HttpMethods.Get);
+
+ Task getCustomEtwProvidersTask = TestHelpers.Portal.GetCustomEtwProvidersAsync();
+ getCustomEtwProvidersTask.Wait();
+
+ Assert.AreEqual(TaskStatus.RanToCompletion, getCustomEtwProvidersTask.Status);
+
+ ValidateEtwProviders(getCustomEtwProvidersTask.Result);
+ }
+
+ ///
+ /// Basic test of GET method for getting a list of registered ETW providers.
+ ///
+ [TestMethod]
+ public void GetEtwProvidersTest()
+ {
+ TestHelpers.MockHttpResponder.AddMockResponse(DevicePortal.EtwProvidersApi, HttpMethods.Get);
+
+ Task getEtwProvidersTask = TestHelpers.Portal.GetEtwProvidersAsync();
+ getEtwProvidersTask.Wait();
+
+ Assert.AreEqual(TaskStatus.RanToCompletion, getEtwProvidersTask.Status);
+
+ ValidateEtwProviders(getEtwProvidersTask.Result);
+ }
+
+ [TestMethod]
+ public void GetEtwEventsTest()
+ {
+ TestHelpers.MockHttpResponder.AddMockResponse(DevicePortal.RealtimeEtwSessionApi, HttpMethods.WebSocket);
+
+ ManualResetEvent etwEventsReceived = new ManualResetEvent(false);
+ EtwEvents etwEvents = null;
+
+ WindowsDevicePortal.WebSocketMessageReceivedEventHandler etwEventsReceivedHandler =
+ delegate (DevicePortal sender, WebSocketMessageReceivedEventArgs args)
+ {
+ if (args.Message != null)
+ {
+ etwEvents = args.Message;
+ etwEventsReceived.Set();
+ }
+ };
+
+ TestHelpers.Portal.RealtimeEventsMessageReceived += etwEventsReceivedHandler;
+
+ Task startListeningForEtwEventsTask = TestHelpers.Portal.StartListeningForEtwEventsAsync();
+ startListeningForEtwEventsTask.Wait();
+ Assert.AreEqual(TaskStatus.RanToCompletion, startListeningForEtwEventsTask.Status);
+
+ etwEventsReceived.WaitOne();
+
+ Task stopListeningForEtwEventsTask = TestHelpers.Portal.StopListeningForEtwEventsAsync();
+ stopListeningForEtwEventsTask.Wait();
+ Assert.AreEqual(TaskStatus.RanToCompletion, stopListeningForEtwEventsTask.Status);
+
+ TestHelpers.Portal.RealtimeEventsMessageReceived -= etwEventsReceivedHandler;
+
+ ValidateEtwEvents(etwEvents);
+ }
+
+ ///
+ /// Validate the returned from the tests.
+ ///
+ /// The to validate.
+ private static void ValidateEtwEvents(EtwEvents etwEvents)
+ {
+ Assert.IsNotNull(etwEvents);
+ }
+
+ ///
+ /// Validate the returned from the tests.
+ ///
+ /// The to validate.
+ private static void ValidateEtwProviders(EtwProviders etw)
+ {
+ Guid result;
+ Assert.IsTrue(etw.Providers.Count > 0);
+ Assert.IsTrue(etw.Providers.All(etwProvider =>
+ Guid.TryParse(etwProvider.GUID, out result) &&
+ !string.IsNullOrEmpty(etwProvider.Name)));
+ }
+ }
+}
diff --git a/WindowsDevicePortalWrapper/UnitTestProject/MockData/Defaults/WebSocket_api_etw_session_realtime_Default.dat b/WindowsDevicePortalWrapper/UnitTestProject/MockData/Defaults/WebSocket_api_etw_session_realtime_Default.dat
new file mode 100644
index 00000000..f7bcb871
--- /dev/null
+++ b/WindowsDevicePortalWrapper/UnitTestProject/MockData/Defaults/WebSocket_api_etw_session_realtime_Default.dat
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/WindowsDevicePortalWrapper/UnitTestProject/MockData/Defaults/api_etw_customproviders_Default.dat b/WindowsDevicePortalWrapper/UnitTestProject/MockData/Defaults/api_etw_customproviders_Default.dat
new file mode 100644
index 00000000..d332e2d4
--- /dev/null
+++ b/WindowsDevicePortalWrapper/UnitTestProject/MockData/Defaults/api_etw_customproviders_Default.dat
@@ -0,0 +1 @@
+{"Providers" : [{"GUID" : "3A43D90E-530E-41E5-A897-B555516070E2", "Name" : "Provider.One"},{"GUID" : "52B1715B-5AB6-4B48-A61A-A93EE8D4B5CD", "Name" : "Provider-Two"},{"GUID" : "698F02FF-2B63-4CBB-AB06-FEB88011347E", "Name" : "Provider.Three"}]}
\ No newline at end of file
diff --git a/WindowsDevicePortalWrapper/UnitTestProject/MockData/Defaults/api_etw_providers_Default.dat b/WindowsDevicePortalWrapper/UnitTestProject/MockData/Defaults/api_etw_providers_Default.dat
new file mode 100644
index 00000000..d332e2d4
--- /dev/null
+++ b/WindowsDevicePortalWrapper/UnitTestProject/MockData/Defaults/api_etw_providers_Default.dat
@@ -0,0 +1 @@
+{"Providers" : [{"GUID" : "3A43D90E-530E-41E5-A897-B555516070E2", "Name" : "Provider.One"},{"GUID" : "52B1715B-5AB6-4B48-A61A-A93EE8D4B5CD", "Name" : "Provider-Two"},{"GUID" : "698F02FF-2B63-4CBB-AB06-FEB88011347E", "Name" : "Provider.Three"}]}
\ No newline at end of file
diff --git a/WindowsDevicePortalWrapper/UnitTestProject/UnitTestProject.csproj b/WindowsDevicePortalWrapper/UnitTestProject/UnitTestProject.csproj
index 5f96bccb..7ff5def3 100644
--- a/WindowsDevicePortalWrapper/UnitTestProject/UnitTestProject.csproj
+++ b/WindowsDevicePortalWrapper/UnitTestProject/UnitTestProject.csproj
@@ -62,6 +62,7 @@
+
@@ -85,9 +86,18 @@
+
+ PreserveNewest
+
+
+ PreserveNewest
+
PreserveNewest
+
+ PreserveNewest
+
PreserveNewest
diff --git a/WindowsDevicePortalWrapper/UnitTestProject/WDPMockImplementations/WebSocket.cs b/WindowsDevicePortalWrapper/UnitTestProject/WDPMockImplementations/WebSocket.cs
index 8a499e7c..2973898e 100644
--- a/WindowsDevicePortalWrapper/UnitTestProject/WDPMockImplementations/WebSocket.cs
+++ b/WindowsDevicePortalWrapper/UnitTestProject/WDPMockImplementations/WebSocket.cs
@@ -36,6 +36,11 @@ internal partial class WebSocket
///
private Func