-
Notifications
You must be signed in to change notification settings - Fork 323
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enable nullable for EventLogCollector #3674
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ | |
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using System.Diagnostics.CodeAnalysis; | ||
using System.Globalization; | ||
using System.IO; | ||
using System.Linq; | ||
|
@@ -16,8 +17,6 @@ | |
|
||
using Resource = Microsoft.TestPlatform.Extensions.EventLogCollector.Resources.Resources; | ||
|
||
#nullable disable | ||
|
||
namespace Microsoft.TestPlatform.Extensions.EventLogCollector; | ||
|
||
/// <summary> | ||
|
@@ -65,22 +64,22 @@ public class EventLogDataCollector : DataCollector | |
/// <summary> | ||
/// Object containing the execution events the data collector registers for | ||
/// </summary> | ||
private DataCollectionEvents _events; | ||
private DataCollectionEvents? _events; | ||
|
||
/// <summary> | ||
/// The sink used by the data collector to send its data | ||
/// </summary> | ||
private DataCollectionSink _dataSink; | ||
private DataCollectionSink? _dataSink; | ||
|
||
/// <summary> | ||
/// The data collector context. | ||
/// </summary> | ||
private DataCollectionContext _dataCollectorContext; | ||
private DataCollectionContext? _dataCollectorContext; | ||
|
||
/// <summary> | ||
/// Used by the data collector to send warnings, errors, or other messages | ||
/// </summary> | ||
private DataCollectionLogger _logger; | ||
private DataCollectionLogger? _logger; | ||
|
||
/// <summary> | ||
/// The file helper. | ||
|
@@ -120,18 +119,17 @@ internal EventLogDataCollector(IFileHelper fileHelper) | |
|
||
internal int MaxEntries { get; private set; } | ||
|
||
internal ISet<string> EventSources { get; private set; } | ||
internal ISet<string>? EventSources { get; private set; } | ||
|
||
internal ISet<EventLogEntryType> EntryTypes { get; private set; } | ||
internal ISet<EventLogEntryType>? EntryTypes { get; private set; } | ||
|
||
internal ISet<string> EventLogNames { get; private set; } | ||
internal ISet<string>? EventLogNames { get; private set; } | ||
|
||
/// <summary> | ||
/// Gets the context data. | ||
/// </summary> | ||
internal Dictionary<DataCollectionContext, EventLogSessionContext> ContextMap { get; } | ||
|
||
|
||
#region DataCollector Members | ||
|
||
/// <summary> | ||
|
@@ -149,12 +147,13 @@ internal EventLogDataCollector(IFileHelper fileHelper) | |
/// Used by the data collector to send warnings, errors, or other messages | ||
/// </param> | ||
/// <param name="dataCollectionEnvironmentContext">Provides contextual information about the agent environment</param> | ||
[MemberNotNull(nameof(_events), nameof(_dataSink), nameof(_logger))] | ||
public override void Initialize( | ||
XmlElement configurationElement, | ||
XmlElement? configurationElement, | ||
DataCollectionEvents events!!, | ||
DataCollectionSink dataSink!!, | ||
DataCollectionLogger logger!!, | ||
DataCollectionEnvironmentContext dataCollectionEnvironmentContext) | ||
DataCollectionEnvironmentContext dataCollectionEnvironmentContext!!) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a change of behavior but we weren't doing null check so if |
||
{ | ||
_events = events; | ||
_dataSink = dataSink; | ||
|
@@ -224,7 +223,7 @@ internal string WriteEventLogs(List<EventLogEntry> eventLogEntries, int maxLogEn | |
{ | ||
for (int i = 1; !unusedFilenameFound; i++) | ||
{ | ||
eventLogPath = eventLogBasePath + "-" + i.ToString(CultureInfo.InvariantCulture) + ".xml"; | ||
eventLogPath = $"{eventLogBasePath}-{i.ToString(CultureInfo.InvariantCulture)}.xml"; | ||
|
||
if (!_fileHelper.Exists(eventLogPath)) | ||
{ | ||
|
@@ -267,6 +266,7 @@ internal string WriteEventLogs(List<EventLogEntry> eventLogEntries, int maxLogEn | |
// Write the event log file | ||
FileTransferInformation fileTransferInformation = | ||
new(dataCollectionContext, eventLogPath, true, _fileHelper); | ||
TPDebug.Assert(_dataSink != null, "Initialize should have been called."); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We cannot use the initialize pattern we were talking about because this method is called from within the |
||
_dataSink.SendFileAsync(fileTransferInformation); | ||
|
||
EqtTrace.Verbose( | ||
|
@@ -287,10 +287,13 @@ protected override void Dispose(bool disposing) | |
base.Dispose(disposing); | ||
|
||
// Unregister events | ||
_events.SessionStart -= _sessionStartEventHandler; | ||
_events.SessionEnd -= _sessionEndEventHandler; | ||
_events.TestCaseStart -= _testCaseStartEventHandler; | ||
_events.TestCaseEnd -= _testCaseEndEventHandler; | ||
if (_events != null) | ||
{ | ||
_events.SessionStart -= _sessionStartEventHandler; | ||
_events.SessionEnd -= _sessionEndEventHandler; | ||
_events.TestCaseStart -= _testCaseStartEventHandler; | ||
_events.TestCaseEnd -= _testCaseEndEventHandler; | ||
} | ||
|
||
// Unregister EventLogEntry Written. | ||
foreach (var eventLogContainer in _eventLogContainerMap.Values) | ||
|
@@ -352,7 +355,7 @@ private void OnTestCaseStart(object sender, TestCaseStartEventArgs e!!) | |
private void OnTestCaseEnd(object sender, TestCaseEndEventArgs e!!) | ||
{ | ||
Debug.Assert(e.Context != null, "Context is null"); | ||
Debug.Assert(e.Context.HasTestCase, "Context is not for a test case"); | ||
Debug.Assert(e.Context!.HasTestCase, "Context is not for a test case"); | ||
|
||
EqtTrace.Verbose( | ||
"EventLogDataCollector: TestCaseEnd received for test '{0}' with Test Outcome: {1}.", | ||
|
@@ -402,13 +405,15 @@ private void WriteCollectedEventLogEntries( | |
kvp.Value.EventLog.EnableRaisingEvents = false; | ||
} | ||
|
||
// REVIEW ME: We are initializing | ||
for (int i = context.EventLogContainerStartIndexMap[kvp.Key]; i <= context.EventLogContainerEndIndexMap[kvp.Key]; i++) | ||
{ | ||
eventLogEntries.Add(kvp.Value.EventLogEntries[i]); | ||
} | ||
} | ||
catch (Exception e) | ||
{ | ||
TPDebug.Assert(_logger != null, "Initialize should have been called."); | ||
_logger.LogWarning( | ||
dataCollectionContext, | ||
string.Format( | ||
|
@@ -430,15 +435,16 @@ private void WriteCollectedEventLogEntries( | |
} | ||
} | ||
|
||
[MemberNotNull(nameof(EventLogNames))] | ||
private void ConfigureEventLogNames(CollectorNameValueConfigurationManager collectorNameValueConfigurationManager) | ||
{ | ||
EventLogNames = new HashSet<string>(); | ||
string eventLogs = collectorNameValueConfigurationManager[EventLogConstants.SettingEventLogs]; | ||
string? eventLogs = collectorNameValueConfigurationManager[EventLogConstants.SettingEventLogs]; | ||
if (eventLogs != null) | ||
{ | ||
EventLogNames = ParseCommaSeparatedList(eventLogs); | ||
EqtTrace.Verbose( | ||
"EventLogDataCollector configuration: " + EventLogConstants.SettingEventLogs + "=" + eventLogs); | ||
$"EventLogDataCollector configuration: {EventLogConstants.SettingEventLogs}={eventLogs}"); | ||
} | ||
else | ||
{ | ||
|
@@ -447,6 +453,8 @@ private void ConfigureEventLogNames(CollectorNameValueConfigurationManager colle | |
EventLogNames.Add("Application"); | ||
} | ||
|
||
TPDebug.Assert(_logger != null && EntryTypes != null, "Initialize should have been called."); | ||
|
||
foreach (string eventLogName in EventLogNames) | ||
{ | ||
try | ||
|
@@ -470,27 +478,27 @@ private void ConfigureEventLogNames(CollectorNameValueConfigurationManager colle | |
{ | ||
_logger.LogError( | ||
_dataCollectorContext, | ||
new EventLogCollectorException(string.Format(CultureInfo.InvariantCulture, Resource.ReadError, eventLogName, Environment.MachineName), ex)); | ||
new EventLogCollectorException(string.Format(CultureInfo.CurrentCulture, Resource.ReadError, eventLogName, Environment.MachineName), ex)); | ||
} | ||
} | ||
} | ||
|
||
private void ConfigureEventSources(CollectorNameValueConfigurationManager collectorNameValueConfigurationManager) | ||
{ | ||
string eventSourcesStr = collectorNameValueConfigurationManager[EventLogConstants.SettingEventSources]; | ||
string? eventSourcesStr = collectorNameValueConfigurationManager[EventLogConstants.SettingEventSources]; | ||
if (!string.IsNullOrEmpty(eventSourcesStr)) | ||
{ | ||
EventSources = ParseCommaSeparatedList(eventSourcesStr); | ||
EventSources = ParseCommaSeparatedList(eventSourcesStr!); | ||
EqtTrace.Verbose( | ||
"EventLogDataCollector configuration: " + EventLogConstants.SettingEventSources + "=" | ||
+ EventSources); | ||
$"EventLogDataCollector configuration: {EventLogConstants.SettingEventSources}={EventSources}"); | ||
} | ||
} | ||
|
||
[MemberNotNull(nameof(EntryTypes))] | ||
private void ConfigureEntryTypes(CollectorNameValueConfigurationManager collectorNameValueConfigurationManager) | ||
{ | ||
EntryTypes = new HashSet<EventLogEntryType>(); | ||
string entryTypesStr = collectorNameValueConfigurationManager[EventLogConstants.SettingEntryTypes]; | ||
string? entryTypesStr = collectorNameValueConfigurationManager[EventLogConstants.SettingEntryTypes]; | ||
if (entryTypesStr != null) | ||
{ | ||
foreach (string entryTypestring in ParseCommaSeparatedList(entryTypesStr)) | ||
|
@@ -500,8 +508,7 @@ private void ConfigureEntryTypes(CollectorNameValueConfigurationManager collecto | |
} | ||
|
||
EqtTrace.Verbose( | ||
"EventLogDataCollector configuration: " + EventLogConstants.SettingEntryTypes + "=" | ||
+ EntryTypes); | ||
$"EventLogDataCollector configuration: {EventLogConstants.SettingEntryTypes}={EntryTypes}"); | ||
} | ||
else | ||
{ | ||
|
@@ -513,7 +520,7 @@ private void ConfigureEntryTypes(CollectorNameValueConfigurationManager collecto | |
|
||
private void ConfigureMaxEntries(CollectorNameValueConfigurationManager collectorNameValueConfigurationManager) | ||
{ | ||
string maxEntriesstring = collectorNameValueConfigurationManager[EventLogConstants.SettingMaxEntries]; | ||
string? maxEntriesstring = collectorNameValueConfigurationManager[EventLogConstants.SettingMaxEntries]; | ||
if (maxEntriesstring != null) | ||
{ | ||
try | ||
|
@@ -532,8 +539,7 @@ private void ConfigureMaxEntries(CollectorNameValueConfigurationManager collecto | |
} | ||
|
||
EqtTrace.Verbose( | ||
"EventLogDataCollector configuration: " + EventLogConstants.SettingMaxEntries + "=" | ||
+ MaxEntries); | ||
$"EventLogDataCollector configuration: {EventLogConstants.SettingMaxEntries}={MaxEntries}"); | ||
} | ||
else | ||
{ | ||
|
@@ -553,7 +559,7 @@ private EventLogSessionContext GetEventLogSessionContext(DataCollectionContext d | |
if (!eventLogContainerFound) | ||
{ | ||
string msg = string.Format( | ||
CultureInfo.InvariantCulture, | ||
CultureInfo.CurrentCulture, | ||
Resource.ContextNotFoundException, | ||
dataCollectionContext.ToString()); | ||
throw new EventLogCollectorException(msg, null); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Functionally we should accept only non-null but that would be a change of behavior so I decided to allow null.