Skip to content

Commit c91e284

Browse files
nohwndEvangelink
andauthored
Use fakes to surround vstest core and test it (#3347)
Co-authored-by: Amaury Levé <[email protected]>
1 parent f8d6b93 commit c91e284

File tree

72 files changed

+3076
-27
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+3076
-27
lines changed

TestPlatform.sln

+45
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MSTest1", "playground\MSTes
179179
EndProject
180180
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AttachmentProcessorDataCollector", "test\TestAssets\AttachmentProcessorDataCollector\AttachmentProcessorDataCollector.csproj", "{B6AF6BCD-64C6-4F4E-ABCA-C8AA2AA66B7B}"
181181
EndProject
182+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "vstest.ProgrammerTests", "test\vstest.ProgrammerTests\vstest.ProgrammerTests.csproj", "{B1F84FD8-6150-4ECA-9AD7-C316E04E17D8}"
183+
EndProject
184+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Intent", "test\Intent\Intent.csproj", "{BFBB35C9-6437-480A-8DCC-AE3700110E7D}"
185+
EndProject
186+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Intent.Primitives", "test\Intent.Primitives\Intent.Primitives.csproj", "{29270853-90DC-4C39-9621-F47AE40A79B6}"
187+
EndProject
182188
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "testhost.arm64", "src\testhost.arm64\testhost.arm64.csproj", "{186069FE-E1E8-4DE1-BEA4-0FF1484D22D1}"
183189
EndProject
184190
Global
@@ -883,6 +889,42 @@ Global
883889
{B6AF6BCD-64C6-4F4E-ABCA-C8AA2AA66B7B}.Release|x64.Build.0 = Release|Any CPU
884890
{B6AF6BCD-64C6-4F4E-ABCA-C8AA2AA66B7B}.Release|x86.ActiveCfg = Release|Any CPU
885891
{B6AF6BCD-64C6-4F4E-ABCA-C8AA2AA66B7B}.Release|x86.Build.0 = Release|Any CPU
892+
{B1F84FD8-6150-4ECA-9AD7-C316E04E17D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
893+
{B1F84FD8-6150-4ECA-9AD7-C316E04E17D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
894+
{B1F84FD8-6150-4ECA-9AD7-C316E04E17D8}.Debug|x64.ActiveCfg = Debug|Any CPU
895+
{B1F84FD8-6150-4ECA-9AD7-C316E04E17D8}.Debug|x64.Build.0 = Debug|Any CPU
896+
{B1F84FD8-6150-4ECA-9AD7-C316E04E17D8}.Debug|x86.ActiveCfg = Debug|Any CPU
897+
{B1F84FD8-6150-4ECA-9AD7-C316E04E17D8}.Debug|x86.Build.0 = Debug|Any CPU
898+
{B1F84FD8-6150-4ECA-9AD7-C316E04E17D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
899+
{B1F84FD8-6150-4ECA-9AD7-C316E04E17D8}.Release|Any CPU.Build.0 = Release|Any CPU
900+
{B1F84FD8-6150-4ECA-9AD7-C316E04E17D8}.Release|x64.ActiveCfg = Release|Any CPU
901+
{B1F84FD8-6150-4ECA-9AD7-C316E04E17D8}.Release|x64.Build.0 = Release|Any CPU
902+
{B1F84FD8-6150-4ECA-9AD7-C316E04E17D8}.Release|x86.ActiveCfg = Release|Any CPU
903+
{B1F84FD8-6150-4ECA-9AD7-C316E04E17D8}.Release|x86.Build.0 = Release|Any CPU
904+
{BFBB35C9-6437-480A-8DCC-AE3700110E7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
905+
{BFBB35C9-6437-480A-8DCC-AE3700110E7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
906+
{BFBB35C9-6437-480A-8DCC-AE3700110E7D}.Debug|x64.ActiveCfg = Debug|Any CPU
907+
{BFBB35C9-6437-480A-8DCC-AE3700110E7D}.Debug|x64.Build.0 = Debug|Any CPU
908+
{BFBB35C9-6437-480A-8DCC-AE3700110E7D}.Debug|x86.ActiveCfg = Debug|Any CPU
909+
{BFBB35C9-6437-480A-8DCC-AE3700110E7D}.Debug|x86.Build.0 = Debug|Any CPU
910+
{BFBB35C9-6437-480A-8DCC-AE3700110E7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
911+
{BFBB35C9-6437-480A-8DCC-AE3700110E7D}.Release|Any CPU.Build.0 = Release|Any CPU
912+
{BFBB35C9-6437-480A-8DCC-AE3700110E7D}.Release|x64.ActiveCfg = Release|Any CPU
913+
{BFBB35C9-6437-480A-8DCC-AE3700110E7D}.Release|x64.Build.0 = Release|Any CPU
914+
{BFBB35C9-6437-480A-8DCC-AE3700110E7D}.Release|x86.ActiveCfg = Release|Any CPU
915+
{BFBB35C9-6437-480A-8DCC-AE3700110E7D}.Release|x86.Build.0 = Release|Any CPU
916+
{29270853-90DC-4C39-9621-F47AE40A79B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
917+
{29270853-90DC-4C39-9621-F47AE40A79B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
918+
{29270853-90DC-4C39-9621-F47AE40A79B6}.Debug|x64.ActiveCfg = Debug|Any CPU
919+
{29270853-90DC-4C39-9621-F47AE40A79B6}.Debug|x64.Build.0 = Debug|Any CPU
920+
{29270853-90DC-4C39-9621-F47AE40A79B6}.Debug|x86.ActiveCfg = Debug|Any CPU
921+
{29270853-90DC-4C39-9621-F47AE40A79B6}.Debug|x86.Build.0 = Debug|Any CPU
922+
{29270853-90DC-4C39-9621-F47AE40A79B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
923+
{29270853-90DC-4C39-9621-F47AE40A79B6}.Release|Any CPU.Build.0 = Release|Any CPU
924+
{29270853-90DC-4C39-9621-F47AE40A79B6}.Release|x64.ActiveCfg = Release|Any CPU
925+
{29270853-90DC-4C39-9621-F47AE40A79B6}.Release|x64.Build.0 = Release|Any CPU
926+
{29270853-90DC-4C39-9621-F47AE40A79B6}.Release|x86.ActiveCfg = Release|Any CPU
927+
{29270853-90DC-4C39-9621-F47AE40A79B6}.Release|x86.Build.0 = Release|Any CPU
886928
{186069FE-E1E8-4DE1-BEA4-0FF1484D22D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
887929
{186069FE-E1E8-4DE1-BEA4-0FF1484D22D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
888930
{186069FE-E1E8-4DE1-BEA4-0FF1484D22D1}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -970,6 +1012,9 @@ Global
9701012
{545A88D3-1AE2-4D39-9B7C-C691768AD17F} = {6CE2F530-582B-4695-A209-41065E103426}
9711013
{57A61A09-10AD-44BE-8DF4-A6FD108F7DF7} = {6CE2F530-582B-4695-A209-41065E103426}
9721014
{B6AF6BCD-64C6-4F4E-ABCA-C8AA2AA66B7B} = {D9A30E32-D466-4EC5-B4F2-62E17562279B}
1015+
{B1F84FD8-6150-4ECA-9AD7-C316E04E17D8} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6}
1016+
{BFBB35C9-6437-480A-8DCC-AE3700110E7D} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6}
1017+
{29270853-90DC-4C39-9621-F47AE40A79B6} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6}
9731018
{186069FE-E1E8-4DE1-BEA4-0FF1484D22D1} = {ED0C35EB-7F31-4841-A24F-8EB708FFA959}
9741019
EndGlobalSection
9751020
GlobalSection(ExtensibilityGlobals) = postSolution

src/Microsoft.TestPlatform.Client/Friends.cs

+1
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@
1010
#region Test Assemblies
1111

1212
[assembly: InternalsVisibleTo("Microsoft.TestPlatform.Client.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")]
13+
[assembly: InternalsVisibleTo("vstest.ProgrammerTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")]
1314

1415
#endregion

src/Microsoft.TestPlatform.Client/TestPlatform.cs

+8-3
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ namespace Microsoft.VisualStudio.TestPlatform.Client;
3636
/// </summary>
3737
internal class TestPlatform : ITestPlatform
3838
{
39-
private readonly TestRuntimeProviderManager _testHostProviderManager;
39+
private readonly ITestRuntimeProviderManager _testHostProviderManager;
4040

4141
private readonly IFileHelper _fileHelper;
4242

@@ -66,10 +66,10 @@ public TestPlatform()
6666
/// <param name="testEngine">The test engine.</param>
6767
/// <param name="filehelper">The file helper.</param>
6868
/// <param name="testHostProviderManager">The data.</param>
69-
protected TestPlatform(
69+
protected internal TestPlatform(
7070
ITestEngine testEngine,
7171
IFileHelper filehelper,
72-
TestRuntimeProviderManager testHostProviderManager)
72+
ITestRuntimeProviderManager testHostProviderManager)
7373
{
7474
TestEngine = testEngine;
7575
_fileHelper = filehelper;
@@ -117,6 +117,11 @@ public ITestRunRequest CreateTestRunRequest(
117117
ITestLoggerManager loggerManager = TestEngine.GetLoggerManager(requestData);
118118
loggerManager.Initialize(testRunCriteria.TestRunSettings);
119119

120+
// TODO: PERF: this will create a testhost manager, and then it will pass that to GetExecutionManager, where it will
121+
// be used only when we will run in-process. If we don't run in process, we will throw away the manager we just
122+
// created and let the proxy parallel callbacks to create a new one. This seems to be very easy to move to the GetExecutionManager,
123+
// and safe as well, so we create the manager only once.
124+
// TODO: Of course TestEngine.GetExecutionManager is public api...
120125
ITestRuntimeProvider testHostManager = _testHostProviderManager.GetTestHostManagerByRunConfiguration(testRunCriteria.TestRunSettings);
121126
TestPlatform.ThrowExceptionIfTestHostManagerIsNull(testHostManager, testRunCriteria.TestRunSettings);
122127

src/Microsoft.TestPlatform.Common/Friends.cs

+2
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,6 @@
2525
[assembly: InternalsVisibleTo("Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")]
2626
[assembly: InternalsVisibleTo("Microsoft.TestPlatform.TestUtilities, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")]
2727
[assembly: InternalsVisibleTo("Microsoft.TestPlatform.AcceptanceTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")]
28+
[assembly: InternalsVisibleTo("vstest.ProgrammerTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")]
29+
2830
#endregion
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
namespace Microsoft.VisualStudio.TestPlatform.Common.Hosting;
5+
6+
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Host;
7+
8+
internal interface ITestRuntimeProviderManager
9+
{
10+
ITestRuntimeProvider GetTestHostManagerByRunConfiguration(string runConfiguration);
11+
ITestRuntimeProvider GetTestHostManagerByUri(string hostUri);
12+
}

src/Microsoft.TestPlatform.Common/Hosting/TestRunTimeProviderManager.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ namespace Microsoft.VisualStudio.TestPlatform.Common.Hosting;
1414
/// <summary>
1515
/// Responsible for managing TestRuntimeProviderManager extensions
1616
/// </summary>
17-
public class TestRuntimeProviderManager
17+
public class TestRuntimeProviderManager : ITestRuntimeProviderManager
1818
{
1919
private static TestRuntimeProviderManager s_testHostManager;
2020

src/Microsoft.TestPlatform.CommunicationUtilities/DataCollectionRequestHandler.cs

+8
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,14 @@ public static DataCollectionRequestHandler Create(
152152
{
153153
ValidateArg.NotNull(communicationManager, nameof(communicationManager));
154154
ValidateArg.NotNull(messageSink, nameof(messageSink));
155+
// TODO: The MessageSink and DataCollectionRequestHandler have circular dependency.
156+
// Message sink is injected into this Create method and then into constructor
157+
// and into the constructor of DataCollectionRequestHandler. Data collection manager
158+
// is then assigned to .Instace (which unlike many other .Instance is not populated
159+
// directly in that property, but is created here). And then MessageSink depends on
160+
// the .Instance. This is a very complicated way of solving the circular dependency,
161+
// and should be replaced by adding a property to Message and assigning it.
162+
// .Instance can then be removed.
155163
if (Instance == null)
156164
{
157165
lock (SyncObject)

src/Microsoft.TestPlatform.CommunicationUtilities/Interfaces/Communication/ConnectedEventArgs.cs

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public class ConnectedEventArgs : EventArgs
1515
/// <summary>
1616
/// Initializes a new instance of the <see cref="ConnectedEventArgs"/> class.
1717
/// </summary>
18+
// TODO: Do we need this constructor?
1819
public ConnectedEventArgs()
1920
{
2021
}

src/Microsoft.TestPlatform.CommunicationUtilities/Interfaces/ICommunicationEndpoint.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public interface ICommunicationEndPoint
1515
event EventHandler<ConnectedEventArgs> Connected;
1616

1717
/// <summary>
18-
/// Event raised when an endPoint is disconnected.
18+
/// Event raised when an endPoint is disconnected on failure. It should not be notified when we are just closing the connection after success.
1919
/// </summary>
2020
event EventHandler<DisconnectedEventArgs> Disconnected;
2121

src/Microsoft.TestPlatform.CommunicationUtilities/Messages/Message.cs

+5
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ public class Message
2121
/// <summary>
2222
/// Gets or sets the payload.
2323
/// </summary>
24+
// TODO: Our public contract says that we should be able to communicate over JSON, but we should not be stopping ourselves from
25+
// negotiating a different protocol. Or using a different serialization library than NewtonsoftJson. Check why this is published as JToken
26+
// and not as a string.
2427
public JToken Payload { get; set; }
2528

2629
/// <summary>
@@ -29,6 +32,8 @@ public class Message
2932
/// <returns> The <see cref="string"/>. </returns>
3033
public override string ToString()
3134
{
35+
// TODO: Review where this is used, we should avoid extensive serialization and deserialization,
36+
// and this might be happening in multiple places that are not the edge of our process.
3237
return "(" + MessageType + ") -> " + (Payload == null ? "null" : Payload.ToString(Formatting.Indented));
3338
}
3439
}

src/Microsoft.TestPlatform.CommunicationUtilities/SocketClient.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -96,17 +96,17 @@ private void OnServerConnected(Task connectAsyncTask)
9696
// Start the message loop
9797
Task.Run(() => _tcpClient.MessageLoopAsync(
9898
_channel,
99-
Stop,
99+
StopOnError,
100100
_cancellation.Token))
101101
.ConfigureAwait(false);
102102
}
103103
}
104104
}
105105

106-
private void Stop(Exception error)
106+
private void StopOnError(Exception error)
107107
{
108108
EqtTrace.Info("SocketClient.PrivateStop: Stop communication from server endpoint: {0}, error:{1}", _endPoint, error);
109-
109+
// This is here to prevent stack overflow.
110110
if (!_stopped)
111111
{
112112
// Do not allow stop to be called multiple times.

src/Microsoft.TestPlatform.CommunicationUtilities/SocketServer.cs

+7-2
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,16 @@ private void OnClientConnected(TcpClient client)
102102
EqtTrace.Verbose("SocketServer.OnClientConnected: Client connected for endPoint: {0}, starting MessageLoopAsync:", _endPoint);
103103

104104
// Start the message loop
105-
Task.Run(() => _tcpClient.MessageLoopAsync(_channel, error => Stop(error), _cancellation.Token)).ConfigureAwait(false);
105+
Task.Run(() => _tcpClient.MessageLoopAsync(_channel, error => StopOnError(error), _cancellation.Token)).ConfigureAwait(false);
106106
}
107107
}
108108

109-
private void Stop(Exception error)
109+
/// <summary>
110+
/// Stop the connection when error was encountered. Dispose all communication, and notify subscribers of Disconnected event
111+
/// that we aborted.
112+
/// </summary>
113+
/// <param name="error"></param>
114+
private void StopOnError(Exception error)
110115
{
111116
EqtTrace.Info("SocketServer.PrivateStop: Stopping server endPoint: {0} error: {1}", _endPoint, error);
112117

0 commit comments

Comments
 (0)