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

Early testhost startup performance work #2584

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
4c4ee43
Protocol augmentation for early testhost startup
cvpoienaru Sep 29, 2020
4b789f7
Early testhost startup POC working
cvpoienaru Oct 5, 2020
ab5caae
Parallelized testhost startup process
cvpoienaru Oct 6, 2020
33c32dd
Refactoring to facilitate adding EndSession call
cvpoienaru Oct 8, 2020
84bd529
Enabled custom host launcher for session start
cvpoienaru Oct 9, 2020
1208b3a
Reverted TestPlatform class to old visibility level
cvpoienaru Oct 9, 2020
1d1b959
Public API changes & data collection support
cvpoienaru Oct 23, 2020
ea03fa5
Synchronized test session proxy operations
cvpoienaru Oct 26, 2020
a6351ae
Changes to make sure debugging still works
cvpoienaru Oct 29, 2020
be2f335
Merge branch 'master' into copoiena/tp-testhost-early-start
cvpoienaru Oct 29, 2020
0a99e8e
Fixed build crash (hopefully)
cvpoienaru Oct 29, 2020
add7800
Fixed unit tests
cvpoienaru Oct 30, 2020
5d6260e
Incremental updates
cvpoienaru Oct 30, 2020
282ef6a
Removed unnecessary using directive
cvpoienaru Oct 30, 2020
a52efd9
Added test platform options to the start test session call
cvpoienaru Oct 30, 2020
40b5e7a
Added some more documentation
cvpoienaru Oct 30, 2020
b4a1759
Fixed build crash
cvpoienaru Oct 30, 2020
9354e1f
Changes for proxies
cvpoienaru Oct 30, 2020
cb1a38e
Fixed documentation issues
cvpoienaru Oct 30, 2020
b9751d5
Added more documentation changes
cvpoienaru Nov 2, 2020
19d1de5
Corrected typo
cvpoienaru Nov 2, 2020
95805cf
Updated test request manager
cvpoienaru Nov 2, 2020
e0de31a
Merge branch 'master' into copoiena/tp-testhost-early-start
cvpoienaru Nov 3, 2020
85bc7b4
Polished public API
cvpoienaru Nov 4, 2020
72076dd
Updated public API
cvpoienaru Nov 5, 2020
658130d
Fixed build crash
cvpoienaru Nov 5, 2020
bab9567
Added naive test discovery on the test session object
cvpoienaru Nov 5, 2020
ec922bb
Merge branch 'master' into copoiena/tp-testhost-early-start
cvpoienaru Nov 25, 2020
cb3899f
Fixed compilation issues
cvpoienaru Nov 25, 2020
5be44dd
Fixed acceptance tests
cvpoienaru Nov 27, 2020
bff2729
Fixed code review comments
cvpoienaru Dec 3, 2020
f396cc0
Fixed compat issue
cvpoienaru Dec 11, 2020
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
72 changes: 53 additions & 19 deletions src/Microsoft.TestPlatform.Client/DesignMode/DesignModeClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ namespace Microsoft.VisualStudio.TestPlatform.Client.DesignMode
using CommunicationUtilitiesResources = Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Resources.Resources;
using CoreUtilitiesConstants = Microsoft.VisualStudio.TestPlatform.CoreUtilities.Constants;
using ObjectModelConstants = Microsoft.VisualStudio.TestPlatform.ObjectModel.Constants;
using Microsoft.VisualStudio.TestPlatform.Client.StartTestRunner;

/// <summary>
/// The design mode client.
Expand Down Expand Up @@ -151,6 +152,15 @@ private void ProcessRequests(ITestRequestManager testRequestManager)
{
var message = this.communicationManager.ReceiveMessage();

/*if (!System.Diagnostics.Debugger.IsAttached)
{
System.Diagnostics.Debugger.Launch();
}
else
{
System.Diagnostics.Debugger.Break();
}*/

if (EqtTrace.IsInfoEnabled)
{
EqtTrace.Info("DesignModeClient.ProcessRequests: Processing Message: {0}", message);
Expand All @@ -177,7 +187,7 @@ private void ProcessRequests(ITestRequestManager testRequestManager)
case MessageType.StartTestRunner:
{
var testRunnerPayload = this.communicationManager.DeserializePayload<StartTestRunnerPayload>(message);
this.StartTestRunner(testRunnerPayload);
this.StartTestRunner(testRunnerPayload, testRequestManager);
break;
}

Expand Down Expand Up @@ -365,24 +375,6 @@ public bool AttachDebuggerToProcess(int pid, CancellationToken cancellationToken
}
}

/// <inheritdoc/>
public void StartTestRunner(StartTestRunnerPayload payload)
{
// Here we do the work of initializing the runner.
this.SendTestRunnerId(-1);
}

/// <inheritdoc/>
public void SendTestRunnerId(int pid)
{
if (this.protocolConfig.Version < ObjectModelConstants.MinimumProtocolVersionWithTestRunnerStartSupport)
{
return;
}

this.communicationManager.SendMessage(MessageType.StartTestRunnerCallback, pid);
}

/// <summary>
/// Send the raw messages to IDE
/// </summary>
Expand Down Expand Up @@ -526,6 +518,48 @@ private void StartTestRunAttachmentsProcessing(TestRunAttachmentsProcessingPaylo
});
}

/// <summary>
///
/// </summary>
/// <param name="payload"></param>
/// <param name="testRequestManager"></param>
private void StartTestRunner(StartTestRunnerPayload payload, ITestRequestManager testRequestManager)
{
Task.Run(
delegate
cvpoienaru marked this conversation as resolved.
Show resolved Hide resolved
{
var eventsHandler = new StartTestRunnerEventsHandler(this.communicationManager);

try
{
testRequestManager.ResetOptions();
testRequestManager.StartTestRunner(payload, eventsHandler, this.protocolConfig);
}
catch (Exception ex)
{
EqtTrace.Error("DesignModeClient: Exception in StartTestRunner: " + ex);

// TODO: Better signal the error.
eventsHandler.HandleStartTestRunnerComplete(null);

/*var testMessagePayload = new TestMessagePayload { MessageLevel = TestMessageLevel.Error, Message = ex.ToString() };
this.communicationManager.SendMessage(MessageType.TestMessage, testMessagePayload);

var payload = new DiscoveryCompletePayload()
{
IsAborted = true,
LastDiscoveredTests = null,
TotalTests = -1
};

// Send run complete to translation layer
this.communicationManager.SendMessage(MessageType.DiscoveryComplete, payload);*/
}
});

// Here we do the work of initializing the runner.
}

#region IDisposable Support

private bool disposedValue = false; // To detect redundant calls
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,6 @@ public interface IDesignModeClient : IDisposable
/// <returns><see cref="true"/> if the debugger was successfully attached to the requested process, <see cref="false"/> otherwise.</returns>
bool AttachDebuggerToProcess(int pid, CancellationToken cancellationToken);

void StartTestRunner(StartTestRunnerPayload payload);

void SendTestRunnerId(int pid);

/// <summary>
/// Handles parent process exit
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ namespace Microsoft.VisualStudio.TestPlatform.Client.RequestHelper
{
using System;
using System.Collections.Generic;

using Microsoft.VisualStudio.TestPlatform.Client.StartTestRunner;
using Microsoft.VisualStudio.TestPlatform.Common.Interfaces;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Interfaces;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Payloads;

/// <summary>
/// Defines the contract that command line
Expand Down Expand Up @@ -51,6 +52,14 @@ public interface ITestRequestManager : IDisposable
/// <param name="testRunAttachmentsProcessingEventsHandler">Test run attachments processing events handler</param>
void ProcessTestRunAttachments(TestRunAttachmentsProcessingPayload testRunAttachmentsProcessingPayload, ITestRunAttachmentsProcessingEventsHandler testRunAttachmentsProcessingEventsHandler, ProtocolConfig protocolConfig);

/// <summary>
///
/// </summary>
/// <param name="payload"></param>
/// <param name="eventsHandler"></param>
/// <param name="protocolConfig"></param>
void StartTestRunner(StartTestRunnerPayload payload, IStartTestRunnerEventsHandler eventsHandler, ProtocolConfig protocolConfig);

/// <summary>
/// Cancel the current TestRun request
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// 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.VisualStudio.TestPlatform.Client.StartTestRunner
{
using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Interfaces;
using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Payloads;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;

/// <summary>
///
/// </summary>
public class StartTestRunnerEventsHandler : IStartTestRunnerEventsHandler
{
private readonly ICommunicationManager communicationManager;

/// <summary>
///
/// </summary>
/// <param name="communicationManager"></param>
public StartTestRunnerEventsHandler(ICommunicationManager communicationManager)
{
this.communicationManager = communicationManager;
}

/// <inheritdoc />
public void HandleStartTestRunnerComplete(Session session)
{
var ackPayload = new StartTestRunnerAckPayload()
{
Session = session
};

this.communicationManager.SendMessage(MessageType.StartTestRunnerCallback, ackPayload);
}

/// <inheritdoc />
public void HandleLogMessage(TestMessageLevel level, string message)
{
// No-op.
}

/// <inheritdoc />
public void HandleRawMessage(string rawMessage)
{
// No-op.
}
}
}
40 changes: 39 additions & 1 deletion src/Microsoft.TestPlatform.Client/TestPlatform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ namespace Microsoft.VisualStudio.TestPlatform.Client
using Microsoft.VisualStudio.TestPlatform.Common;
using Microsoft.VisualStudio.TestPlatform.Common.ExtensionFramework;
using Microsoft.VisualStudio.TestPlatform.Common.Hosting;
using Microsoft.VisualStudio.TestPlatform.Common.Interfaces.Engine.TesthostProtocol;
using Microsoft.VisualStudio.TestPlatform.Common.Logging;
using Microsoft.VisualStudio.TestPlatform.Common.Utilities;
using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine;
Expand All @@ -31,7 +32,7 @@ namespace Microsoft.VisualStudio.TestPlatform.Client
/// <summary>
/// Implementation for TestPlatform
/// </summary>
internal class TestPlatform : ITestPlatform
public class TestPlatform : ITestPlatform
cvpoienaru marked this conversation as resolved.
Show resolved Hide resolved
{
private readonly TestRuntimeProviderManager testHostProviderManager;

Expand Down Expand Up @@ -71,6 +72,14 @@ protected TestPlatform(ITestEngine testEngine, IFileHelper filehelper, TestRunti
this.testHostProviderManager = testHostProviderManager;
}

public TestRuntimeProviderManager TestHostProviderManager
{
get
{
return this.testHostProviderManager;
}
}

/// <summary>
/// Gets or sets Test Engine instance
/// </summary>
Expand Down Expand Up @@ -161,6 +170,35 @@ public ITestRunRequest CreateTestRunRequest(IRequestData requestData, TestRunCri
return new TestRunRequest(requestData, testRunCriteria, executionManager, loggerManager);
}

public void CreateStartTestRunnerRequest(IRequestData requestData, StartTestRunnerCriteria startTestRunnerCriteria, IStartTestRunnerEventsHandler eventsHandler)
{
if (startTestRunnerCriteria == null)
{
throw new ArgumentNullException(nameof(startTestRunnerCriteria));
}

// Initialize loggers
var loggerManager = this.TestEngine.GetLoggerManager(requestData);
loggerManager.Initialize(startTestRunnerCriteria.RunSettings);

var testHostManager = this.testHostProviderManager.GetTestHostManagerByRunConfiguration(startTestRunnerCriteria.RunSettings);
ThrowExceptionIfTestHostManagerIsNull(testHostManager, startTestRunnerCriteria.RunSettings);

testHostManager.Initialize(TestSessionMessageLogger.Instance, startTestRunnerCriteria.RunSettings);

if (startTestRunnerCriteria.TestHostLauncher != null)
{
testHostManager.SetCustomLauncher(startTestRunnerCriteria.TestHostLauncher);
}

var startTestRunnerManager = this.TestEngine.GetStartTestRunnerManager(requestData, testHostManager, startTestRunnerCriteria);

// TODO: What should happen on initialization ?
startTestRunnerManager.Initialize(false);

startTestRunnerManager.StartTestRunner(startTestRunnerCriteria, eventsHandler);
}

/// <summary>
/// The dispose.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

namespace Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine
{
using Microsoft.VisualStudio.TestPlatform.Common.Interfaces.Engine.TesthostProtocol;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Host;

Expand Down Expand Up @@ -31,6 +32,8 @@ public interface ITestEngine
/// <returns>ITestExecutionManager object that can do execution</returns>
IProxyExecutionManager GetExecutionManager(IRequestData requestData, ITestRuntimeProvider testHostManager, TestRunCriteria testRunCriteria);

IProxyStartTestRunnerManager GetStartTestRunnerManager(IRequestData requestData, ITestRuntimeProvider testHostManager, StartTestRunnerCriteria testRunCriteria);

/// <summary>
/// Fetches the extension manager for this engine. This manager would provide extensibility
/// features that this engine supports.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// 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.VisualStudio.TestPlatform.Common.Interfaces.Engine.TesthostProtocol
{
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client;

/// <summary>
///
/// </summary>
public interface IProxyStartTestRunnerManager
{
/// <summary>
///
/// </summary>
/// <param name="skipDefaultAdapters"></param>
void Initialize(bool skipDefaultAdapters);

/// <summary>
///
/// </summary>
/// <param name="criteria"></param>
/// <param name="eventsHandler"></param>
void StartTestRunner(StartTestRunnerCriteria criteria, IStartTestRunnerEventsHandler eventsHandler);

/// <summary>
///
/// </summary>
void Abort();

/// <summary>
///
/// </summary>
void Close();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ public static class TelemetryDataConstants

public static string ParallelEnabledDuringDiscovery = "VS.TestDiscovery.ParallelEnabled";

public static string ParallelEnabledDuringStartTestRunner = "VS.StartTestRunner.ParallelEnabled";

// All the times are in sec
public static string TimeTakenInSecForDiscovery = "VS.TestDiscovery.TotalTimeTakenInSec";

Expand Down Expand Up @@ -104,5 +106,7 @@ public static class TelemetryDataConstants
public static string TestExecutionCompleteEvent = "vs/testplatform/testrunsession";

public static string TestAttachmentsProcessingCompleteEvent = "vs/testplatform/testattachmentsprocessingsession";

public static string StartTestRunnerCompleteEvent = "vs/testplatform/starttestrunnersession";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -218,5 +218,9 @@ public interface ITestPlatformEventSource
/// Mark the completion of translation layer test run attachments processing request.
/// </summary>
void TranslationLayerTestRunAttachmentsProcessingStop();

void StartTestRunnerStart();

void StartTestRunnerStop();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -279,5 +279,15 @@ public void TranslationLayerTestRunAttachmentsProcessingStop()
{
this.WriteEvent(TestPlatformInstrumentationEvents.TranslationLayerTestRunAttachmentsProcessingStopEventId);
}

public void StartTestRunnerStart()
{
this.WriteEvent(TestPlatformInstrumentationEvents.StartTestRunnerStartEventId);
}

public void StartTestRunnerStop()
{
this.WriteEvent(TestPlatformInstrumentationEvents.StartTestRunnerStopEventId);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -187,5 +187,15 @@ internal class TestPlatformInstrumentationEvents
/// Events fired on session attachments processing complete in translation layer.
/// </summary>
public const int TranslationLayerTestRunAttachmentsProcessingStopEventId = 0x45;

/// <summary>
/// The start test runner request start event id.
/// </summary>
public const int StartTestRunnerStartEventId = 0x46;

/// <summary>
/// The start test runner request stop event id.
/// </summary>
public const int StartTestRunnerStopEventId = 0x47;
}
}
Loading