Skip to content

Commit

Permalink
Added Event Log Data Collector for Windows OS (microsoft#1002)
Browse files Browse the repository at this point in the history
* Initial commit for Event Log Data Collector.

* Added Tests.

* Saving state.

* Added Tests.

* Added E2E tests.

* Added localized resources.

* Added entry for Microsoft.TestPlatform.Extensions.EventLogCollector.dll for signing

* Removed System.Diagnostics.Debugger.Launch();

* Minor changes.

* PR feedback.

* PR feedback

* PR feedback.

* PR feedback.

* Merged EventLogContainerContextData and DataCollectorContainer.

* PR feedback.

* Changed code to have only one EventLog per eventLogName configured.

* Added Filter for EventLogEnteries.

* Added verification for test case level "Event Log.xml" file.

* Fixed failing tests.

* PR feedback.

* Added more tests, minor changes.

* Added logging for EventLogs handling.
  • Loading branch information
harshjain2 authored Sep 7, 2017
1 parent cffd8a8 commit 468d4b2
Show file tree
Hide file tree
Showing 46 changed files with 3,622 additions and 19 deletions.
56 changes: 55 additions & 1 deletion TestPlatform.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26507.0
VisualStudioVersion = 15.0.26703.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{ED0C35EB-7F31-4841-A24F-8EB708FFA959}"
EndProject
Expand Down Expand Up @@ -159,6 +159,16 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlameUnitTestProject", "tes
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleProjectWithOldTestHost", "test\TestAssets\SampleProjectWithOldTestHost\SampleProjectWithOldTestHost.csproj", "{DFF82C76-9498-4E8B-8B5E-D12E2B92FA46}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DataCollectors", "DataCollectors", "{B705537C-B82C-4A30-AFA5-6244D9A7DAEB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TestPlatform.Extensions.EventLogCollector", "src\DataCollectors\Microsoft.TestPlatform.Extensions.EventLogCollector\Microsoft.TestPlatform.Extensions.EventLogCollector.csproj", "{65A25D6E-C9CC-4F45-8925-04087AC82634}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DataCollectors", "DataCollectors", "{D9A30E32-D466-4EC5-B4F2-62E17562279B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TestPlatform.Extensions.EventLogCollector.UnitTests", "test\DataCollectors\Microsoft.TestPlatform.Extensions.EventLogCollector.UnitTests\Microsoft.TestPlatform.Extensions.EventLogCollector.UnitTests.csproj", "{21DB138B-85B7-479E-91FE-01E0F972EC56}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EventLogUnitTestProject", "test\TestAssets\EventLogUnitTestProject\EventLogUnitTestProject.csproj", "{826CD5AF-44FA-40F6-B731-3980CADED8C0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -841,6 +851,42 @@ Global
{DFF82C76-9498-4E8B-8B5E-D12E2B92FA46}.Release|x64.Build.0 = Release|Any CPU
{DFF82C76-9498-4E8B-8B5E-D12E2B92FA46}.Release|x86.ActiveCfg = Release|Any CPU
{DFF82C76-9498-4E8B-8B5E-D12E2B92FA46}.Release|x86.Build.0 = Release|Any CPU
{65A25D6E-C9CC-4F45-8925-04087AC82634}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{65A25D6E-C9CC-4F45-8925-04087AC82634}.Debug|Any CPU.Build.0 = Debug|Any CPU
{65A25D6E-C9CC-4F45-8925-04087AC82634}.Debug|x64.ActiveCfg = Debug|Any CPU
{65A25D6E-C9CC-4F45-8925-04087AC82634}.Debug|x64.Build.0 = Debug|Any CPU
{65A25D6E-C9CC-4F45-8925-04087AC82634}.Debug|x86.ActiveCfg = Debug|Any CPU
{65A25D6E-C9CC-4F45-8925-04087AC82634}.Debug|x86.Build.0 = Debug|Any CPU
{65A25D6E-C9CC-4F45-8925-04087AC82634}.Release|Any CPU.ActiveCfg = Release|Any CPU
{65A25D6E-C9CC-4F45-8925-04087AC82634}.Release|Any CPU.Build.0 = Release|Any CPU
{65A25D6E-C9CC-4F45-8925-04087AC82634}.Release|x64.ActiveCfg = Release|Any CPU
{65A25D6E-C9CC-4F45-8925-04087AC82634}.Release|x64.Build.0 = Release|Any CPU
{65A25D6E-C9CC-4F45-8925-04087AC82634}.Release|x86.ActiveCfg = Release|Any CPU
{65A25D6E-C9CC-4F45-8925-04087AC82634}.Release|x86.Build.0 = Release|Any CPU
{21DB138B-85B7-479E-91FE-01E0F972EC56}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{21DB138B-85B7-479E-91FE-01E0F972EC56}.Debug|Any CPU.Build.0 = Debug|Any CPU
{21DB138B-85B7-479E-91FE-01E0F972EC56}.Debug|x64.ActiveCfg = Debug|Any CPU
{21DB138B-85B7-479E-91FE-01E0F972EC56}.Debug|x64.Build.0 = Debug|Any CPU
{21DB138B-85B7-479E-91FE-01E0F972EC56}.Debug|x86.ActiveCfg = Debug|Any CPU
{21DB138B-85B7-479E-91FE-01E0F972EC56}.Debug|x86.Build.0 = Debug|Any CPU
{21DB138B-85B7-479E-91FE-01E0F972EC56}.Release|Any CPU.ActiveCfg = Release|Any CPU
{21DB138B-85B7-479E-91FE-01E0F972EC56}.Release|Any CPU.Build.0 = Release|Any CPU
{21DB138B-85B7-479E-91FE-01E0F972EC56}.Release|x64.ActiveCfg = Release|Any CPU
{21DB138B-85B7-479E-91FE-01E0F972EC56}.Release|x64.Build.0 = Release|Any CPU
{21DB138B-85B7-479E-91FE-01E0F972EC56}.Release|x86.ActiveCfg = Release|Any CPU
{21DB138B-85B7-479E-91FE-01E0F972EC56}.Release|x86.Build.0 = Release|Any CPU
{826CD5AF-44FA-40F6-B731-3980CADED8C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{826CD5AF-44FA-40F6-B731-3980CADED8C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{826CD5AF-44FA-40F6-B731-3980CADED8C0}.Debug|x64.ActiveCfg = Debug|Any CPU
{826CD5AF-44FA-40F6-B731-3980CADED8C0}.Debug|x64.Build.0 = Debug|Any CPU
{826CD5AF-44FA-40F6-B731-3980CADED8C0}.Debug|x86.ActiveCfg = Debug|Any CPU
{826CD5AF-44FA-40F6-B731-3980CADED8C0}.Debug|x86.Build.0 = Debug|Any CPU
{826CD5AF-44FA-40F6-B731-3980CADED8C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{826CD5AF-44FA-40F6-B731-3980CADED8C0}.Release|Any CPU.Build.0 = Release|Any CPU
{826CD5AF-44FA-40F6-B731-3980CADED8C0}.Release|x64.ActiveCfg = Release|Any CPU
{826CD5AF-44FA-40F6-B731-3980CADED8C0}.Release|x64.Build.0 = Release|Any CPU
{826CD5AF-44FA-40F6-B731-3980CADED8C0}.Release|x86.ActiveCfg = Release|Any CPU
{826CD5AF-44FA-40F6-B731-3980CADED8C0}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -911,5 +957,13 @@ Global
{488675EC-C8BB-40E0-AD4F-91F623D548B3} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6}
{6B2B841C-CCFF-469A-9939-EB07EA0401AE} = {8DA7CBD9-F17E-41B6-90C4-CFF55848A25A}
{DFF82C76-9498-4E8B-8B5E-D12E2B92FA46} = {8DA7CBD9-F17E-41B6-90C4-CFF55848A25A}
{B705537C-B82C-4A30-AFA5-6244D9A7DAEB} = {ED0C35EB-7F31-4841-A24F-8EB708FFA959}
{65A25D6E-C9CC-4F45-8925-04087AC82634} = {B705537C-B82C-4A30-AFA5-6244D9A7DAEB}
{D9A30E32-D466-4EC5-B4F2-62E17562279B} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6}
{21DB138B-85B7-479E-91FE-01E0F972EC56} = {D9A30E32-D466-4EC5-B4F2-62E17562279B}
{826CD5AF-44FA-40F6-B731-3980CADED8C0} = {8DA7CBD9-F17E-41B6-90C4-CFF55848A25A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0541B30C-FF51-4E28-B172-83F5F3934BCD}
EndGlobalSection
EndGlobal
10 changes: 9 additions & 1 deletion scripts/build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,15 @@ function Publish-Package
Copy-Item $blameDataCollectorNetFull\Microsoft.TestPlatform.Extensions.BlameDataCollector.pdb $fullCLRExtensionsDir -Force
Copy-Item $blameDataCollectorNetStandard\Microsoft.TestPlatform.Extensions.BlameDataCollector.dll $coreCLRExtensionsDir -Force
Copy-Item $blameDataCollectorNetStandard\Microsoft.TestPlatform.Extensions.BlameDataCollector.pdb $coreCLRExtensionsDir -Force


# Copy Event Log Datacollector to Extensions folder.
$eventLogDataCollector = Join-Path $env:TP_ROOT_DIR "src\DataCollectors\Microsoft.TestPlatform.Extensions.EventLogCollector\bin\$TPB_Configuration"
$eventLogDataCollectorNetFull = Join-Path $eventLogDataCollector $TPB_TargetFramework
Copy-Item $eventLogDataCollectorNetFull\Microsoft.TestPlatform.Extensions.EventLogCollector.dll $fullCLRExtensionsDir -Force
Copy-Item $eventLogDataCollectorNetFull\Microsoft.TestPlatform.Extensions.EventLogCollector.pdb $fullCLRExtensionsDir -Force
Copy-Item $eventLogDataCollectorNetFull\Microsoft.TestPlatform.Extensions.EventLogCollector.dll $coreCLRExtensionsDir -Force
Copy-Item $eventLogDataCollectorNetFull\Microsoft.TestPlatform.Extensions.EventLogCollector.pdb $coreCLRExtensionsDir -Force

# Note Note: If there are some dependencies for the TestHostRuntimeProvider assemblies, those need to be moved too.
$runtimeproviders = @("Microsoft.TestPlatform.TestHostRuntimeProvider.dll", "Microsoft.TestPlatform.TestHostRuntimeProvider.pdb")
foreach($file in $runtimeproviders) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Microsoft.TestPlatform.Extensions.EventLogCollector
{
using System.Collections.Generic;
using System.Xml;
using Microsoft.VisualStudio.TestPlatform.ObjectModel;

/// <summary>
/// Utility class that collectors can use to read name/value configuration information from
/// the XML element sent to them
/// </summary>
internal class CollectorNameValueConfigurationManager
{
#region Private constants
// Configuration XML constants
private const string SettingNameAttributeName = "name";

private const string SettingValueAttributeName = "value";

#endregion

#region Private fields

/// <summary>
/// The name/value pairs loaded from the configuration XML element
/// </summary>
private IDictionary<string, string> nameValuePairs = new Dictionary<string, string>();

#endregion

#region Constructor

/// <summary>
/// Initializes a new instance of the <see cref="CollectorNameValueConfigurationManager"/> class.
/// Loads the configuration name/value information from the provided XML element into a dictionary
/// </summary>
/// <param name="configurationElement">
/// XML element containing the configuration
/// </param>
public CollectorNameValueConfigurationManager(XmlElement configurationElement)
{
if (configurationElement == null)
{
// There is no configuration
return;
}

// Iterate through top-level XML elements within the configuration element and store
// name/value information for elements that have name/value attributes.
foreach (XmlNode settingNode in configurationElement.ChildNodes)
{
// Skip all non-elements
var settingElement = settingNode as XmlElement;
if (settingElement == null)
{
continue;
}

// Get the setting name
string settingName = settingElement.GetAttribute(SettingNameAttributeName);
if (string.IsNullOrWhiteSpace(settingName))
{
if (EqtTrace.IsWarningEnabled)
{
EqtTrace.Warning("Skipping configuration setting due to missing setting name");
}

continue;
}

// Get the setting value
string settingValue = settingElement.GetAttribute(SettingValueAttributeName);
if (string.IsNullOrWhiteSpace(settingValue))
{
if (EqtTrace.IsWarningEnabled)
{
EqtTrace.Warning("Skipping configuration setting '{0}' due to missing value", settingName);
}

continue;
}

// Save the name/value pair in the dictionary. Note that duplicate settings are
// overwritten with the last occurrance's value.
if (this.nameValuePairs.ContainsKey(settingName))
{
if (EqtTrace.IsVerboseEnabled)
{
EqtTrace.Verbose(
"Duplicate configuration setting found for '{0}'. Using the last setting.",
settingName);
}
}

this.nameValuePairs[settingName] = settingValue;
}
}

#endregion

#region Public properties

internal IDictionary<string, string> NameValuePairs => this.nameValuePairs;

/// <summary>
/// Gets the value of the setting specified by name, or null if it was not found
/// </summary>
/// <param name="name">The setting name</param>
/// <returns>The setting value, or null if the setting was not found</returns>
public string this[string name]
{
get
{
if (name == null)
{
return null;
}

string settingValue;
this.nameValuePairs.TryGetValue(name, out settingValue);
return settingValue;
}

set => this.nameValuePairs[name] = value;
}
#endregion
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Microsoft.TestPlatform.Extensions.EventLogCollector
{
using System;

/// <summary>
/// Private Exception class used for event log exceptions
/// </summary>
internal class EventLogCollectorException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="EventLogCollectorException"/> class.
/// </summary>
/// <param name="localizedMessage">the localized exception message</param>
/// <param name="innerException">the inner exception</param>
public EventLogCollectorException(string localizedMessage, Exception innerException)
: base(localizedMessage, innerException)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Microsoft.TestPlatform.Extensions.EventLogCollector
{
/// <summary>
/// Constants used by Event Log Data Collector.
/// </summary>
internal static class EventLogConstants
{
// Supported configuration setting names
public const string SettingEventLogs = "EventLogs";
public const string SettingEventSources = "EventSources";
public const string SettingEntryTypes = "EntryTypes";
public const string SettingMaxEntries = "MaxEventLogEntriesToCollect";

// default values
public const int DefaultMaxEntries = 50000;

public const int TypeColumnMaxLength = 64;
public const int SourceColumnMaxLength = 212;
}
}
Loading

0 comments on commit 468d4b2

Please sign in to comment.