Skip to content
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

[Port] Fix datacollectors temporary files cleanup. #1506

Merged
merged 1 commit into from
Mar 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion scripts/build/TestPlatform.Settings.targets
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<TestPlatformRoot Condition="$(TestPlatformRoot) == ''">$(MSBuildThisFileDirectory)../../</TestPlatformRoot>
<TPVersionPrefix>15.6.1</TPVersionPrefix>
<TPVersionPrefix>15.6.2</TPVersionPrefix>
</PropertyGroup>
<PropertyGroup>
<!-- Versioning is defined from the build script. Use a default dev build if it's not defined.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -327,12 +327,32 @@ protected virtual void Dispose(bool disposing)
{
if (disposing)
{
CleanupPlugins();
}

this.disposed = true;
}
}

private void CleanupPlugins()
{
EqtTrace.Info("DataCollectionManager.CleanupPlugins: CleanupPlugins called");

if (!this.isDataCollectionEnabled)
{
return;
}

if (EqtTrace.IsVerboseEnabled)
{
EqtTrace.Verbose("DataCollectionManager.CleanupPlugins: Cleaning up {0} plugins", this.RunDataCollectors.Count);
}

RemoveDataCollectors(new List<DataCollectorInformation>(this.RunDataCollectors.Values));

EqtTrace.Info("DataCollectionManager.CleanupPlugins: CleanupPlugins finished");
}

#region Load and Initialize DataCollectors

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,127 +167,24 @@ public void ProcessRequests()
{
var message = this.communicationManager.ReceiveMessage();

if (EqtTrace.IsVerboseEnabled)
if (EqtTrace.IsInfoEnabled)
{
EqtTrace.Verbose("DataCollectionRequestHandler.ProcessRequests : Datacollector received message: {0}", message);
EqtTrace.Info("DataCollectionRequestHandler.ProcessRequests : Datacollector received message: {0}", message);
}

switch (message.MessageType)
{
case MessageType.BeforeTestRunStart:
if (EqtTrace.IsInfoEnabled)
{
EqtTrace.Info("DataCollectionRequestHandler.ProcessRequests : DataCollection starting.");
}

// Initialize datacollectors and get enviornment variables.
var settingXml = this.dataSerializer.DeserializePayload<string>(message);
this.AddExtensionAssemblies(settingXml);

var envVariables = this.dataCollectionManager.InitializeDataCollectors(settingXml);
var areTestCaseLevelEventsRequired = this.dataCollectionManager.SessionStarted();

// Open a socket communication port for test level events.
var testCaseEventsPort = 0;
if (areTestCaseLevelEventsRequired)
{
testCaseEventsPort = this.dataCollectionTestCaseEventHandler.InitializeCommunication();

this.testCaseEventMonitorTask = Task.Factory.StartNew(
() =>
{
try
{
if (
this.dataCollectionTestCaseEventHandler.WaitForRequestHandlerConnection(
DataCollectionCommTimeOut))
{
this.dataCollectionTestCaseEventHandler.ProcessRequests();
}
else
{
if (EqtTrace.IsInfoEnabled)
{
EqtTrace.Info(
"DataCollectionRequestHandler.ProcessRequests: TestCaseEventHandler timed out while connecting to the Sender.");
}

this.dataCollectionTestCaseEventHandler.Close();
throw new TimeoutException();
}
}
catch (Exception e)
{
if (EqtTrace.IsErrorEnabled)
{
EqtTrace.Error(
"DataCollectionRequestHandler.ProcessRequests : Error occured during initialization of TestHost : {0}",
e);
}
}
},
this.cancellationTokenSource.Token);
}

this.communicationManager.SendMessage(
MessageType.BeforeTestRunStartResult,
new BeforeTestRunStartResult(envVariables, testCaseEventsPort));
if (EqtTrace.IsInfoEnabled)
{
EqtTrace.Info("DataCollectionRequestHandler.ProcessRequests : DataCollection started.");
}

this.HandleBeforeTestRunStart(message);
break;

case MessageType.AfterTestRunEnd:
if (EqtTrace.IsInfoEnabled)
{
EqtTrace.Info("DataCollection completing.");
}

var isCancelled = this.dataSerializer.DeserializePayload<bool>(message);

if (isCancelled)
{
this.cancellationTokenSource.Cancel();
}

try
{
this.testCaseEventMonitorTask?.Wait(this.cancellationTokenSource.Token);
this.dataCollectionTestCaseEventHandler.Close();
}
catch (Exception ex)
{
if (EqtTrace.IsErrorEnabled)
{
EqtTrace.Error("DataCollectionRequestHandler.ProcessRequests : {0}", ex.ToString());
}
}

var attachmentsets = this.dataCollectionManager.SessionEnded(isCancelled);
this.communicationManager.SendMessage(MessageType.AfterTestRunEndResult, attachmentsets);
if (EqtTrace.IsInfoEnabled)
{
EqtTrace.Info(
"DataCollectionRequestHandler.ProcessRequests : Session End message received from server. Closing the connection.");
}

this.HandleAfterTestRunEnd(message);
isSessionEnded = true;
this.Close();

if (EqtTrace.IsInfoEnabled)
{
EqtTrace.Info("DataCollectionRequestHandler.ProcessRequests : DataCollection completed");
}

break;
default:
if (EqtTrace.IsInfoEnabled)
{
EqtTrace.Info("DataCollectionRequestHandler.ProcessRequests : Invalid Message types");
}

default:
EqtTrace.Error("DataCollectionRequestHandler.ProcessRequests : Invalid Message types: {0}", message.MessageType);
break;
}
}
Expand All @@ -311,7 +208,6 @@ public void SendDataCollectionMessage(DataCollectionMessageEventArgs args)
public void Dispose()
{
this.communicationManager?.StopClient();
this.dataCollectionManager?.Dispose();
}

/// <summary>
Expand Down Expand Up @@ -371,5 +267,85 @@ private void AddExtensionAssemblies(string runSettings)
}
}
}

private void HandleBeforeTestRunStart(Message message)
{
// Initialize datacollectors and get enviornment variables.
var settingXml = this.dataSerializer.DeserializePayload<string>(message);
this.AddExtensionAssemblies(settingXml);

var envVariables = this.dataCollectionManager.InitializeDataCollectors(settingXml);
var areTestCaseLevelEventsRequired = this.dataCollectionManager.SessionStarted();

// Open a socket communication port for test level events.
var testCaseEventsPort = 0;
if (areTestCaseLevelEventsRequired)
{
testCaseEventsPort = this.dataCollectionTestCaseEventHandler.InitializeCommunication();

this.testCaseEventMonitorTask = Task.Factory.StartNew(
() =>
{
try
{
if (this.dataCollectionTestCaseEventHandler.WaitForRequestHandlerConnection(
DataCollectionCommTimeOut))
{
this.dataCollectionTestCaseEventHandler.ProcessRequests();
}
else
{
EqtTrace.Error("DataCollectionRequestHandler.ProcessRequests: TestCaseEventHandler timed out while connecting to the Sender.");
this.dataCollectionTestCaseEventHandler.Close();
throw new TimeoutException();
}
}
catch (Exception e)
{
EqtTrace.Error("DataCollectionRequestHandler.ProcessRequests : Error occured during initialization of TestHost : {0}", e);
}
},
this.cancellationTokenSource.Token);
}

this.communicationManager.SendMessage(
MessageType.BeforeTestRunStartResult,
new BeforeTestRunStartResult(envVariables, testCaseEventsPort));

EqtTrace.Info("DataCollectionRequestHandler.ProcessRequests : DataCollection started.");
}

private void HandleAfterTestRunEnd(Message message)
{
var isCancelled = this.dataSerializer.DeserializePayload<bool>(message);

if (isCancelled)
{
this.cancellationTokenSource.Cancel();
}

try
{
this.testCaseEventMonitorTask?.Wait(this.cancellationTokenSource.Token);
this.dataCollectionTestCaseEventHandler.Close();
}
catch (Exception ex)
{
EqtTrace.Error("DataCollectionRequestHandler.ProcessRequests : {0}", ex.ToString());
}

var attachmentsets = this.dataCollectionManager.SessionEnded(isCancelled);

// Dispose all datacollectors before sending attachements to vstest.console process.
// As datacollector process exits itself on parent process(vstest.console) exits.
this.dataCollectionManager?.Dispose();

this.communicationManager.SendMessage(MessageType.AfterTestRunEndResult, attachmentsets);
EqtTrace.Info("DataCollectionRequestHandler.ProcessRequests : Session End message received from server. Closing the connection.");

this.Close();

EqtTrace.Info("DataCollectionRequestHandler.ProcessRequests : DataCollection completed");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ private void VaildateDataCollectorOutput()
this.StdOutputContains("Data collector 'SampleDataCollector' message: SessionEnded");
this.StdOutputContains("Data collector 'SampleDataCollector' message: my warning");
this.StdErrorContains("Data collector 'SampleDataCollector' message: Data collector caught an exception of type 'System.Exception': 'my exception'. More details:");
this.StdOutputContains("Data collector 'SampleDataCollector' message: Dispose called.");

// Verify attachments
var isTestRunLevelAttachmentFound = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,16 @@ public void ProcessRequestsShouldProcessRequests()
this.mockCommunicationManager.Verify(x => x.SendMessage(MessageType.AfterTestRunEndResult, It.IsAny<Collection<AttachmentSet>>()), Times.Once);
}

[TestMethod]
public void ProcessRequestsShouldDisposeDataCollectorsOnAfterTestRunEnd()
{
this.mockCommunicationManager.SetupSequence(x => x.ReceiveMessage()).Returns(new Message() { MessageType = MessageType.AfterTestRunEnd, Payload = "false" });

this.requestHandler.ProcessRequests();

this.mockDataCollectionManager.Verify(x => x.Dispose());
}

[TestMethod]
public void ProcessRequestsShouldThrowExceptionIfThrownByCommunicationManager()
{
Expand Down
5 changes: 5 additions & 0 deletions test/TestAssets/OutOfProcDataCollector/SampleDataCollector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,10 @@ public IEnumerable<KeyValuePair<string, string>> GetTestExecutionEnvironmentVari
{
return new List<KeyValuePair<string, string>> { new KeyValuePair<string, string>("key", "value") };
}

protected override void Dispose(bool disposing)
{
this.logger.LogWarning(this.context.SessionDataCollectionContext, "Dispose called.");
}
}
}