Fix EventSource to stop ignoring EventCommand.SendManifest (#848)
authorSung Yoon Whang <suwhang@microsoft.com>
Wed, 18 Dec 2019 22:57:33 +0000 (14:57 -0800)
committerGitHub <noreply@github.com>
Wed, 18 Dec 2019 22:57:33 +0000 (14:57 -0800)
* Dont ignore EventCommand.SendManifest command in EventSource

* Add ETW manifest generation test

* Mark the ETW ManifestGeneration tests as privileged only

* Define IsProcessElevatedAndNotWindowsNanoServer

* Change undefined file path

src/libraries/System.Diagnostics.Tracing/tests/BasicEventSourceTest/TestsManifestGeneration.Etw.cs [new file with mode: 0644]
src/libraries/System.Diagnostics.Tracing/tests/BasicEventSourceTest/TestsManifestGeneration.cs
src/libraries/System.Diagnostics.Tracing/tests/CustomEventSources/SimpleEventSource.cs
src/libraries/System.Diagnostics.Tracing/tests/System.Diagnostics.Tracing.Tests.csproj
src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs

diff --git a/src/libraries/System.Diagnostics.Tracing/tests/BasicEventSourceTest/TestsManifestGeneration.Etw.cs b/src/libraries/System.Diagnostics.Tracing/tests/BasicEventSourceTest/TestsManifestGeneration.Etw.cs
new file mode 100644 (file)
index 0000000..9855762
--- /dev/null
@@ -0,0 +1,125 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+#if USE_MDT_EVENTSOURCE
+using Microsoft.Diagnostics.Tracing;
+#else
+using System.Diagnostics.Tracing;
+#endif
+using Xunit;
+
+using SdtEventSources;
+using System.Diagnostics;
+using System.Threading;
+using Microsoft.Diagnostics.Tracing.Session;
+using Microsoft.DotNet.RemoteExecutor;
+using Microsoft.Diagnostics.Tracing;
+
+namespace BasicEventSourceTests
+{
+    public partial class TestsManifestGeneration
+    {
+        // Specifies whether the process is elevated or not.
+        private static readonly Lazy<bool> s_isElevated = new Lazy<bool>(AdminHelpers.IsProcessElevated);
+        private static bool IsProcessElevated => s_isElevated.Value;
+        private static bool IsProcessElevatedAndNotWindowsNanoServer =>
+            IsProcessElevated && PlatformDetection.IsNotWindowsNanoServer;
+
+        /// ETW only works with elevated process
+        [ConditionalFact(nameof(IsProcessElevatedAndNotWindowsNanoServer))]
+        public void Test_EventSource_EtwManifestGeneration()
+        {
+            RemoteExecutor.Invoke(() =>
+            {
+                using (RemoteInvokeHandle handle = RemoteExecutor.Invoke(() =>
+                {
+                    var es = new SimpleEventSource();
+                    for (var i = 0; i < 100; i++)
+                    {
+                        es.WriteSimpleInt(i);
+                        Thread.Sleep(100);
+                    }
+                }))
+                {
+                    var etlFileName = @"file.etl";
+                    var tracesession = new TraceEventSession("testname", etlFileName);
+
+                    tracesession.EnableProvider("SimpleEventSource");
+
+                    Thread.Sleep(TimeSpan.FromSeconds(5));
+
+                    tracesession.Flush();
+                    tracesession.DisableProvider("SimpleEventSource");
+                    tracesession.Dispose();
+
+                    Assert.True(VerifyManifestAndRemoveFile(etlFileName));
+                }
+            }).Dispose();
+        }
+
+        [ConditionalFact(nameof(IsProcessElevatedAndNotWindowsNanoServer))]
+        public void Test_EventSource_EtwManifestGenerationRollover()
+        {
+            RemoteExecutor.Invoke(() =>
+            {
+                using (RemoteInvokeHandle handle = RemoteExecutor.Invoke(() =>
+                {
+                    var es = new SimpleEventSource();
+                    for (var i = 0; i < 100; i++)
+                    {
+                        es.WriteSimpleInt(i);
+                        Thread.Sleep(100);
+                    }
+                }))
+                {
+                    var initialFileName = @"initialFile.etl";
+                    var rolloverFile = @"rolloverFile.etl";
+                    var tracesession = new TraceEventSession("testname", initialFileName);
+
+                    tracesession.EnableProvider("SimpleEventSource");
+
+                    Thread.Sleep(TimeSpan.FromSeconds(5));
+
+                    tracesession.Flush();
+
+                    tracesession.SetFileName(rolloverFile);
+
+                    Thread.Sleep(TimeSpan.FromSeconds(5));
+
+                    tracesession.Flush();
+
+                    tracesession.DisableProvider("SimpleEventSource");
+                    tracesession.Dispose();
+
+                    Assert.True(VerifyManifestAndRemoveFile(initialFileName));
+                    Assert.True(VerifyManifestAndRemoveFile(rolloverFile));
+                }
+            }).Dispose();
+        }
+
+        private bool VerifyManifestAndRemoveFile(string fileName)
+        {
+            Assert.True(File.Exists(fileName));
+
+            ETWTraceEventSource source = new ETWTraceEventSource(fileName);
+
+            var sawManifestData = false;
+            source.Dynamic.All += (eventData) =>
+            {
+                if (eventData.ProviderName.Equals("SimpleEventSource") && eventData.EventName.Equals("ManifestData"))
+                {
+                    sawManifestData = true;
+                }
+            };
+            source.Process();
+            //File.Delete(fileName);
+            return sawManifestData;
+        }
+    }
+}
index 927deb0..83c61a2 100644 (file)
@@ -22,7 +22,7 @@ using System.Text.RegularExpressions;
 
 namespace BasicEventSourceTests
 {
-    public class TestsManifestGeneration
+    public partial class TestsManifestGeneration
     {
         /// <summary>
         /// EventSource would fail when an EventSource was named "EventSource".
index 3edda31..8927455 100644 (file)
@@ -58,6 +58,12 @@ namespace SdtEventSources
             WriteEvent(2, msg);
         }
 
+        [Event(3)]
+        public void WriteSimpleInt(int n)
+        {
+            WriteEvent(3, n);
+        }
+
         #region Keywords / Tasks /Opcodes / Channels
         /// <summary>
         /// The keyword definitions for the ETW manifest.
index ff9cc20..64190fd 100644 (file)
@@ -3,6 +3,7 @@
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <Configurations>$(NetCoreAppCurrent)-Unix-Debug;$(NetCoreAppCurrent)-Unix-Release;$(NetCoreAppCurrent)-Windows_NT-Debug;$(NetCoreAppCurrent)-Windows_NT-Release</Configurations>
     <TestRuntime>true</TestRuntime>
+    <IncludeRemoteExecutor>true</IncludeRemoteExecutor>
   </PropertyGroup>
   <!--Windows only files -->
   <ItemGroup Condition="'$(TargetsNetCoreApp)' == 'true' and '$(TargetsWindows)' == 'true'">
@@ -13,6 +14,7 @@
     <Compile Include="BasicEventSourceTest\TestsWriteEvent.Etw.cs" />
     <Compile Include="BasicEventSourceTest\FuzzyTests.Etw.cs" />
     <Compile Include="BasicEventSourceTest\TestsWriteEventToListener.Etw.cs" />
+    <Compile Include="BasicEventSourceTest\TestsManifestGeneration.Etw.cs" />
   </ItemGroup>
   <ItemGroup>
     <Compile Include="BasicEventSourceTest\Harness\EventTestHarness.cs" />
index e639f7c..fa21262 100644 (file)
@@ -2773,14 +2773,12 @@ namespace System.Diagnostics.Tracing
                 }
                 else
                 {
-#if !FEATURE_PERFTRACING
                     if (commandArgs.Command == EventCommand.SendManifest)
                     {
                         // TODO: should we generate the manifest here if we hadn't already?
                         if (m_rawManifest != null)
                             SendManifest(m_rawManifest);
                     }
-#endif
 
                     // These are not used for non-update commands and thus should always be 'default' values
                     // Debug.Assert(enable == true);