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 29 commits
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
87 changes: 80 additions & 7 deletions src/Microsoft.TestPlatform.Client/DesignMode/DesignModeClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ namespace Microsoft.VisualStudio.TestPlatform.Client.DesignMode
using System.Net;
using System.Threading;
using System.Threading.Tasks;

using Microsoft.VisualStudio.TestPlatform.Client;
using Microsoft.VisualStudio.TestPlatform.Client.TestRunAttachmentsProcessing;
using Microsoft.VisualStudio.TestPlatform.Client.RequestHelper;
using Microsoft.VisualStudio.TestPlatform.Common.Logging;
Expand All @@ -17,11 +19,14 @@ namespace Microsoft.VisualStudio.TestPlatform.Client.DesignMode
using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Interfaces;
using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel;
using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Helpers;
using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine;
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Payloads;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;
using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions;
using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces;

using CommunicationUtilitiesResources = CommunicationUtilities.Resources.Resources;

/// <summary>
Expand All @@ -32,7 +37,7 @@ public class DesignModeClient : IDesignModeClient
private readonly ICommunicationManager communicationManager;
private readonly IDataSerializer dataSerializer;

private ProtocolConfig protocolConfig = Constants.DefaultProtocolConfig;
private ProtocolConfig protocolConfig = ObjectModel.Constants.DefaultProtocolConfig;
private IEnvironment platformEnvironment;
private TestSessionMessageLogger testSessionMessageLogger;
private object lockObject = new object();
Expand Down Expand Up @@ -170,6 +175,20 @@ private void ProcessRequests(ITestRequestManager testRequestManager)
break;
}

case MessageType.StartTestSession:
{
var testSessionPayload = this.communicationManager.DeserializePayload<StartTestSessionPayload>(message);
this.StartTestSession(testSessionPayload, testRequestManager);
break;
}

case MessageType.StopTestSession:
{
var testSessionInfo = this.communicationManager.DeserializePayload<TestSessionInfo>(message);
this.StopTestSession(testSessionInfo);
break;
}

case MessageType.StartDiscovery:
{
var discoveryPayload = this.dataSerializer.DeserializePayload<DiscoveryRequestPayload>(message);
Expand All @@ -183,7 +202,7 @@ private void ProcessRequests(ITestRequestManager testRequestManager)
var testRunPayload =
this.communicationManager.DeserializePayload<TestRunRequestPayload>(
message);
this.StartTestRun(testRunPayload, testRequestManager, skipTestHostLaunch: true);
this.StartTestRun(testRunPayload, testRequestManager, shouldLaunchTesthost: true);
cvpoienaru marked this conversation as resolved.
Show resolved Hide resolved
break;
}

Expand All @@ -193,7 +212,7 @@ private void ProcessRequests(ITestRequestManager testRequestManager)
var testRunPayload =
this.communicationManager.DeserializePayload<TestRunRequestPayload>(
message);
this.StartTestRun(testRunPayload, testRequestManager, skipTestHostLaunch: false);
this.StartTestRun(testRunPayload, testRequestManager, shouldLaunchTesthost: false);
break;
}

Expand Down Expand Up @@ -322,7 +341,7 @@ public bool AttachDebuggerToProcess(int pid, CancellationToken cancellationToken
// If an attach request is issued but there is no support for attaching on the other
// side of the communication channel, we simply return and let the caller know the
// request failed.
if (this.protocolConfig.Version < Constants.MinimumProtocolVersionWithDebugSupport)
if (this.protocolConfig.Version < ObjectModel.Constants.MinimumProtocolVersionWithDebugSupport)
{
return false;
}
Expand Down Expand Up @@ -408,7 +427,7 @@ public void TestRunMessageHandler(object sender, TestRunMessageEventArgs e)
}
}

private void StartTestRun(TestRunRequestPayload testRunPayload, ITestRequestManager testRequestManager, bool skipTestHostLaunch)
private void StartTestRun(TestRunRequestPayload testRunPayload, ITestRequestManager testRequestManager, bool shouldLaunchTesthost)
{
Task.Run(
() =>
Expand All @@ -417,8 +436,15 @@ private void StartTestRun(TestRunRequestPayload testRunPayload, ITestRequestMana
{
testRequestManager.ResetOptions();

var customLauncher = skipTestHostLaunch ?
DesignModeTestHostLauncherFactory.GetCustomHostLauncherForTestRun(this, testRunPayload) : null;
// We must avoid re-launching the test host if the test run payload already
// contains test session info. Test session info being present is an indicative
// of an already running test host spawned by a start test session call.
var customLauncher =
shouldLaunchTesthost && testRunPayload.TestSessionInfo == null
? DesignModeTestHostLauncherFactory.GetCustomHostLauncherForTestRun(
this,
testRunPayload.DebuggingEnabled)
: null;

testRequestManager.RunTests(testRunPayload, customLauncher, new DesignModeTestEventsRegistrar(this), this.protocolConfig);
}
Expand Down Expand Up @@ -497,6 +523,53 @@ private void StartTestRunAttachmentsProcessing(TestRunAttachmentsProcessingPaylo
});
}

private void StartTestSession(StartTestSessionPayload payload, ITestRequestManager requestManager)
{
Task.Run(() =>
{
var eventsHandler = new TestSessionEventsHandler(this.communicationManager);

try
{
var customLauncher = payload.HasCustomHostLauncher
? DesignModeTestHostLauncherFactory.GetCustomHostLauncherForTestRun(this, payload.IsDebuggingEnabled)
: null;

requestManager.ResetOptions();
requestManager.StartTestSession(payload, customLauncher, eventsHandler, this.protocolConfig);
}
catch (Exception ex)
{
EqtTrace.Error("DesignModeClient: Exception in StartTestSession: " + ex);

eventsHandler.HandleLogMessage(TestMessageLevel.Error, ex.ToString());
eventsHandler.HandleStartTestSessionComplete(null);
}
});
}

private void StopTestSession(TestSessionInfo testSessionInfo)
{
Task.Run(() =>
{
var eventsHandler = new TestSessionEventsHandler(this.communicationManager);

try
{
var stopped = TestSessionPool.Instance.RemoveSession(testSessionInfo);
cvpoienaru marked this conversation as resolved.
Show resolved Hide resolved

eventsHandler.HandleStopTestSessionComplete(stopped);
}
catch (Exception ex)
{
EqtTrace.Error("DesignModeClient: Exception in StopTestSession: " + ex);

eventsHandler.HandleLogMessage(TestMessageLevel.Error, ex.ToString());
eventsHandler.HandleStopTestSessionComplete(false);
}
});
}

#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 @@ -14,11 +14,11 @@ public static class DesignModeTestHostLauncherFactory
private static ITestHostLauncher defaultLauncher;
private static ITestHostLauncher debugLauncher;

public static ITestHostLauncher GetCustomHostLauncherForTestRun(IDesignModeClient designModeClient, TestRunRequestPayload testRunRequestPayload)
public static ITestHostLauncher GetCustomHostLauncherForTestRun(IDesignModeClient designModeClient, bool debuggingEnabled)
{
ITestHostLauncher testHostLauncher = null;

if (!testRunRequestPayload.DebuggingEnabled)
if (!debuggingEnabled)
{
testHostLauncher = defaultLauncher = defaultLauncher ?? new DesignModeTestHostLauncher(designModeClient);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,69 +5,105 @@ namespace Microsoft.VisualStudio.TestPlatform.Client.RequestHelper
{
using System;
using System.Collections.Generic;

using Microsoft.VisualStudio.TestPlatform.Client;
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
/// Defines the contract for running various requests.
/// </summary>
public interface ITestRequestManager : IDisposable
{
/// <summary>
/// Initializes the extensions while probing additional paths
/// Initializes the extensions while probing additional paths.
/// </summary>
/// <param name="pathToAdditionalExtensions">Paths to Additional extensions</param>
/// <param name="skipExtensionFilters">Skip extension filtering by name (if true)</param>
void InitializeExtensions(IEnumerable<string> pathToAdditionalExtensions, bool skipExtensionFilters);
///
/// <param name="pathToAdditionalExtensions">Paths to additional extensions.</param>
/// <param name="skipExtensionFilters">Skip extension filtering by name if true.</param>
void InitializeExtensions(
IEnumerable<string> pathToAdditionalExtensions,
bool skipExtensionFilters);

/// <summary>
/// Resets Vstest.console.exe Options
/// Resets vstest.console.exe options.
/// </summary>
void ResetOptions();

/// <summary>
/// Discover Tests given a list of sources, runsettings
/// Discovers tests given a list of sources and some run settings.
/// </summary>
///
/// <param name="discoveryPayload">Discovery payload.</param>
/// <param name="disoveryEventsRegistrar">Discovery events registrar.</param>
/// <param name="protocolConfig">Protocol related information.</param>
void DiscoverTests(
DiscoveryRequestPayload discoveryPayload,
ITestDiscoveryEventsRegistrar disoveryEventsRegistrar,
ProtocolConfig protocolConfig);

/// <summary>
/// Runs tests given a list of sources and some run settings.
/// </summary>
/// <param name="discoveryPayload">Discovery payload</param>
/// <param name="disoveryEventsRegistrar">Discovery events registrar - registers and unregisters discovery events</param>
/// <param name="protocolConfig">Protocol related information</param>
void DiscoverTests(DiscoveryRequestPayload discoveryPayload, ITestDiscoveryEventsRegistrar disoveryEventsRegistrar, ProtocolConfig protocolConfig);
///
/// <param name="testRunRequestPayLoad">Test run request payload.</param>
/// <param name="customTestHostLauncher">Custom test host launcher for the run.</param>
/// <param name="testRunEventsRegistrar">Run events registrar.</param>
/// <param name="protocolConfig">Protocol related information.</param>
void RunTests(
TestRunRequestPayload testRunRequestPayLoad,
ITestHostLauncher customTestHostLauncher,
ITestRunEventsRegistrar testRunEventsRegistrar,
ProtocolConfig protocolConfig);

/// <summary>
/// Run Tests with given a test of sources
/// Processes test run attachments.
/// </summary>
/// <param name="testRunRequestPayLoad">Test Run Request payload</param>
/// <param name="customTestHostLauncher">Custom testHostLauncher for the run</param>
/// <param name="testRunEventsRegistrar">RunEvents registrar</param>
/// <param name="protocolConfig">Protocol related information</param>
void RunTests(TestRunRequestPayload testRunRequestPayLoad, ITestHostLauncher customTestHostLauncher, ITestRunEventsRegistrar testRunEventsRegistrar, ProtocolConfig protocolConfig);
///
/// <param name="testRunAttachmentsProcessingPayload">
/// Test run attachments processing payload.
/// </param>
/// <param name="testRunAttachmentsProcessingEventsHandler">
/// Test run attachments processing events handler.
/// </param>
/// <param name="protocolConfig">Protocol related information.</param>
void ProcessTestRunAttachments(
TestRunAttachmentsProcessingPayload testRunAttachmentsProcessingPayload,
ITestRunAttachmentsProcessingEventsHandler testRunAttachmentsProcessingEventsHandler,
ProtocolConfig protocolConfig);

/// <summary>
/// Processes test run attachments
/// Starts a test session.
/// </summary>
/// <param name="testRunAttachmentsProcessingPayload">Test run attachments processing payload</param>
/// <param name="testRunAttachmentsProcessingEventsHandler">Test run attachments processing events handler</param>
void ProcessTestRunAttachments(TestRunAttachmentsProcessingPayload testRunAttachmentsProcessingPayload, ITestRunAttachmentsProcessingEventsHandler testRunAttachmentsProcessingEventsHandler, ProtocolConfig protocolConfig);
///
/// <param name="payload">The start test session payload.</param>
/// <param name="testHostLauncher">The custom test host launcher.</param>
/// <param name="eventsHandler">The events handler.</param>
/// <param name="protocolConfig">Protocol related information.</param>
void StartTestSession(
StartTestSessionPayload payload,
ITestHostLauncher testHostLauncher,
ITestSessionEventsHandler eventsHandler,
ProtocolConfig protocolConfig);

/// <summary>
/// Cancel the current TestRun request
/// Cancel the current test run request.
/// </summary>
void CancelTestRun();

/// <summary>
/// Abort the current TestRun
/// Abort the current test run.
/// </summary>
void AbortTestRun();

/// <summary>
/// Cancels the current discovery request
/// Cancels the current discovery request.
/// </summary>
void CancelDiscovery();

/// <summary>
/// Cancels the current test run attachments processing request
/// Cancels the current test run attachments processing request.
/// </summary>
void CancelTestRunAttachmentsProcessing();
}
Expand Down
Loading