Merge pull request #1516 from livarcocc/debug_tests
Modifying dotnet test to handle the new design for debug and making it unit testable
This commit is contained in:
commit
7407a898e0
52 changed files with 2581 additions and 228 deletions
|
@ -22,8 +22,6 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Compiler.C
|
|||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.ProjectModel.Workspaces", "src\Microsoft.DotNet.ProjectModel.Workspaces\Microsoft.DotNet.ProjectModel.Workspaces.xproj", "{BD7833F8-3209-4682-BF75-B4BCA883E279}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Runtime", "src\Microsoft.DotNet.Runtime\Microsoft.DotNet.Runtime.xproj", "{DB29F219-DC92-4AF7-A2EE-E89FFBB3F5F0}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.Extensions.Testing.Abstractions", "src\Microsoft.Extensions.Testing.Abstractions\Microsoft.Extensions.Testing.Abstractions.xproj", "{DCDFE282-03DE-4DBC-B90C-CC3CE3EC8162}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.ProjectModel.Loader", "src\Microsoft.DotNet.ProjectModel.Loader\Microsoft.DotNet.ProjectModel.Loader.xproj", "{C7AF0290-EF0D-44DC-9EDC-600803B664F8}"
|
||||
|
@ -64,14 +62,10 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Cli.Build.
|
|||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "dotnet-compile.UnitTests", "test\dotnet-compile.UnitTests\dotnet-compile.UnitTests.xproj", "{920B71D8-62DA-4F5E-8A26-926C113F1D97}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TestApp", "TestAssets\TestProjects\TestApp\TestApp.xproj", "{58808BBC-371E-47D6-A3D0-4902145EDA4E}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TestAppWithArgs", "TestAssets\TestProjects\TestAppWithArgs\TestAppWithArgs.xproj", "{DA8E0E9E-A6D6-4583-864C-8F40465E3A48}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TestAppWithContents", "TestAssets\TestProjects\TestAppWithContents\TestAppWithContents.xproj", "{0138CB8F-4AA9-4029-A21E-C07C30F425BA}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TestLibrary", "TestAssets\TestProjects\TestLibrary\TestLibrary.xproj", "{947DD232-8D9B-4B78-9C6A-94F807D2DD58}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TestProjectToProjectDependencies", "TestAssets\TestProjects\TestProjectToProjectDependencies\TestProjectToProjectDependencies.xproj", "{947DD232-8D9B-4B78-9C6A-94F807D22222}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.InternalAbstractions", "src\Microsoft.DotNet.InternalAbstractions\Microsoft.DotNet.InternalAbstractions.xproj", "{BD4F0750-4E81-4AD2-90B5-E470881792C3}"
|
||||
|
@ -84,6 +78,8 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Cli.Msi.Te
|
|||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.Extensions.DependencyModel.Tests", "..\cli1\test\Microsoft.Extensions.DependencyModel.Tests\Microsoft.Extensions.DependencyModel.Tests.xproj", "{4A4711D8-4312-49FC-87B5-4F183F4C6A51}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "dotnet-test.UnitTests", "test\dotnet-test.UnitTests\dotnet-test.UnitTests.xproj", "{857274AC-E741-4266-A7FD-14DEE0C1CC96}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -160,22 +156,6 @@ Global
|
|||
{BD7833F8-3209-4682-BF75-B4BCA883E279}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
|
||||
{BD7833F8-3209-4682-BF75-B4BCA883E279}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
|
||||
{BD7833F8-3209-4682-BF75-B4BCA883E279}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
|
||||
{DB29F219-DC92-4AF7-A2EE-E89FFBB3F5F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DB29F219-DC92-4AF7-A2EE-E89FFBB3F5F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DB29F219-DC92-4AF7-A2EE-E89FFBB3F5F0}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{DB29F219-DC92-4AF7-A2EE-E89FFBB3F5F0}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{DB29F219-DC92-4AF7-A2EE-E89FFBB3F5F0}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DB29F219-DC92-4AF7-A2EE-E89FFBB3F5F0}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DB29F219-DC92-4AF7-A2EE-E89FFBB3F5F0}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
|
||||
{DB29F219-DC92-4AF7-A2EE-E89FFBB3F5F0}.MinSizeRel|x64.Build.0 = Debug|Any CPU
|
||||
{DB29F219-DC92-4AF7-A2EE-E89FFBB3F5F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DB29F219-DC92-4AF7-A2EE-E89FFBB3F5F0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{DB29F219-DC92-4AF7-A2EE-E89FFBB3F5F0}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{DB29F219-DC92-4AF7-A2EE-E89FFBB3F5F0}.Release|x64.Build.0 = Release|Any CPU
|
||||
{DB29F219-DC92-4AF7-A2EE-E89FFBB3F5F0}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DB29F219-DC92-4AF7-A2EE-E89FFBB3F5F0}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
|
||||
{DB29F219-DC92-4AF7-A2EE-E89FFBB3F5F0}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
|
||||
{DB29F219-DC92-4AF7-A2EE-E89FFBB3F5F0}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
|
||||
{DCDFE282-03DE-4DBC-B90C-CC3CE3EC8162}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DCDFE282-03DE-4DBC-B90C-CC3CE3EC8162}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DCDFE282-03DE-4DBC-B90C-CC3CE3EC8162}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
|
@ -432,22 +412,6 @@ Global
|
|||
{920B71D8-62DA-4F5E-8A26-926C113F1D97}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
|
||||
{920B71D8-62DA-4F5E-8A26-926C113F1D97}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
|
||||
{920B71D8-62DA-4F5E-8A26-926C113F1D97}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
|
||||
{58808BBC-371E-47D6-A3D0-4902145EDA4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{58808BBC-371E-47D6-A3D0-4902145EDA4E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{58808BBC-371E-47D6-A3D0-4902145EDA4E}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{58808BBC-371E-47D6-A3D0-4902145EDA4E}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{58808BBC-371E-47D6-A3D0-4902145EDA4E}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{58808BBC-371E-47D6-A3D0-4902145EDA4E}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
|
||||
{58808BBC-371E-47D6-A3D0-4902145EDA4E}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
|
||||
{58808BBC-371E-47D6-A3D0-4902145EDA4E}.MinSizeRel|x64.Build.0 = Debug|Any CPU
|
||||
{58808BBC-371E-47D6-A3D0-4902145EDA4E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{58808BBC-371E-47D6-A3D0-4902145EDA4E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{58808BBC-371E-47D6-A3D0-4902145EDA4E}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{58808BBC-371E-47D6-A3D0-4902145EDA4E}.Release|x64.Build.0 = Release|Any CPU
|
||||
{58808BBC-371E-47D6-A3D0-4902145EDA4E}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{58808BBC-371E-47D6-A3D0-4902145EDA4E}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
|
||||
{58808BBC-371E-47D6-A3D0-4902145EDA4E}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
|
||||
{58808BBC-371E-47D6-A3D0-4902145EDA4E}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
|
||||
{DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
|
@ -480,22 +444,6 @@ Global
|
|||
{0138CB8F-4AA9-4029-A21E-C07C30F425BA}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
|
||||
{0138CB8F-4AA9-4029-A21E-C07C30F425BA}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
|
||||
{0138CB8F-4AA9-4029-A21E-C07C30F425BA}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
|
||||
{947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{947DD232-8D9B-4B78-9C6A-94F807D2DD58}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{947DD232-8D9B-4B78-9C6A-94F807D2DD58}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
|
||||
{947DD232-8D9B-4B78-9C6A-94F807D2DD58}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
|
||||
{947DD232-8D9B-4B78-9C6A-94F807D2DD58}.MinSizeRel|x64.Build.0 = Debug|Any CPU
|
||||
{947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Release|x64.Build.0 = Release|Any CPU
|
||||
{947DD232-8D9B-4B78-9C6A-94F807D2DD58}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{947DD232-8D9B-4B78-9C6A-94F807D2DD58}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
|
||||
{947DD232-8D9B-4B78-9C6A-94F807D2DD58}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
|
||||
{947DD232-8D9B-4B78-9C6A-94F807D2DD58}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
|
||||
{947DD232-8D9B-4B78-9C6A-94F807D22222}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{947DD232-8D9B-4B78-9C6A-94F807D22222}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{947DD232-8D9B-4B78-9C6A-94F807D22222}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
|
@ -560,6 +508,22 @@ Global
|
|||
{0B31C336-149D-471A-B7B1-27B0F1E80F83}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
|
||||
{0B31C336-149D-471A-B7B1-27B0F1E80F83}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
|
||||
{0B31C336-149D-471A-B7B1-27B0F1E80F83}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
|
||||
{857274AC-E741-4266-A7FD-14DEE0C1CC96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{857274AC-E741-4266-A7FD-14DEE0C1CC96}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{857274AC-E741-4266-A7FD-14DEE0C1CC96}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{857274AC-E741-4266-A7FD-14DEE0C1CC96}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{857274AC-E741-4266-A7FD-14DEE0C1CC96}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{857274AC-E741-4266-A7FD-14DEE0C1CC96}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
|
||||
{857274AC-E741-4266-A7FD-14DEE0C1CC96}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
|
||||
{857274AC-E741-4266-A7FD-14DEE0C1CC96}.MinSizeRel|x64.Build.0 = Debug|Any CPU
|
||||
{857274AC-E741-4266-A7FD-14DEE0C1CC96}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{857274AC-E741-4266-A7FD-14DEE0C1CC96}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{857274AC-E741-4266-A7FD-14DEE0C1CC96}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{857274AC-E741-4266-A7FD-14DEE0C1CC96}.Release|x64.Build.0 = Release|Any CPU
|
||||
{857274AC-E741-4266-A7FD-14DEE0C1CC96}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{857274AC-E741-4266-A7FD-14DEE0C1CC96}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
|
||||
{857274AC-E741-4266-A7FD-14DEE0C1CC96}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
|
||||
{857274AC-E741-4266-A7FD-14DEE0C1CC96}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -569,7 +533,6 @@ Global
|
|||
{303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F}
|
||||
{A16958E1-24C7-4F1E-B317-204AD91625DD} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F}
|
||||
{BD7833F8-3209-4682-BF75-B4BCA883E279} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F}
|
||||
{DB29F219-DC92-4AF7-A2EE-E89FFBB3F5F0} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F}
|
||||
{DCDFE282-03DE-4DBC-B90C-CC3CE3EC8162} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F}
|
||||
{C7AF0290-EF0D-44DC-9EDC-600803B664F8} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F}
|
||||
{08A68C6A-86F6-4ED2-89A7-B166D33E9F85} = {0722D325-24C8-4E83-B5AF-0A083E7F0749}
|
||||
|
@ -587,14 +550,14 @@ Global
|
|||
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5} = {88278B81-7649-45DC-8A6A-D3A645C5AFC3}
|
||||
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D} = {88278B81-7649-45DC-8A6A-D3A645C5AFC3}
|
||||
{920B71D8-62DA-4F5E-8A26-926C113F1D97} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
|
||||
{58808BBC-371E-47D6-A3D0-4902145EDA4E} = {713CBFBB-5392-438D-B766-A9A585EF1BB8}
|
||||
{DA8E0E9E-A6D6-4583-864C-8F40465E3A48} = {713CBFBB-5392-438D-B766-A9A585EF1BB8}
|
||||
{0138CB8F-4AA9-4029-A21E-C07C30F425BA} = {713CBFBB-5392-438D-B766-A9A585EF1BB8}
|
||||
{947DD232-8D9B-4B78-9C6A-94F807D2DD58} = {713CBFBB-5392-438D-B766-A9A585EF1BB8}
|
||||
{947DD232-8D9B-4B78-9C6A-94F807D22222} = {713CBFBB-5392-438D-B766-A9A585EF1BB8}
|
||||
{BD4F0750-4E81-4AD2-90B5-E470881792C3} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F}
|
||||
{4A4711D8-4312-49FC-87B5-4F183F4C6A51} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
|
||||
{0745410A-6629-47EB-AAB5-08D6288CAD72} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
|
||||
{0E3300A4-DF54-40BF-87D8-E7658330C288} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
|
||||
{0B31C336-149D-471A-B7B1-27B0F1E80F83} = {0E3300A4-DF54-40BF-87D8-E7658330C288}
|
||||
{857274AC-E741-4266-A7FD-14DEE0C1CC96} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
{
|
||||
"projects": [ "src", "test" ]
|
||||
"projects": [ "src", "test" ],
|
||||
"sdk": {
|
||||
"version": "1.0.0-rc2-16444"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System.Diagnostics;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public static class CommandTestRunnerExtensions
|
||||
{
|
||||
public static ProcessStartInfo ToProcessStartInfo(this ICommand command)
|
||||
{
|
||||
return new ProcessStartInfo(command.CommandName, command.CommandArgs);
|
||||
}
|
||||
}
|
||||
}
|
106
src/dotnet/commands/dotnet-test/DotnetTest.cs
Normal file
106
src/dotnet/commands/dotnet-test/DotnetTest.cs
Normal file
|
@ -0,0 +1,106 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public class DotnetTest : IDotnetTest
|
||||
{
|
||||
private readonly IList<IReportingChannel> _channels;
|
||||
private readonly IList<IDotnetTestMessageHandler> _messageHandlers;
|
||||
private readonly ITestMessagesCollection _messages;
|
||||
|
||||
public IDotnetTestMessageHandler TestSessionTerminateMessageHandler { private get; set; }
|
||||
public IDotnetTestMessageHandler UnknownMessageHandler { private get; set; }
|
||||
|
||||
public DotnetTestState State { get; private set; }
|
||||
|
||||
public string PathToAssemblyUnderTest { get; }
|
||||
|
||||
public DotnetTest(ITestMessagesCollection messages, string pathToAssemblyUnderTest)
|
||||
{
|
||||
PathToAssemblyUnderTest = pathToAssemblyUnderTest;
|
||||
State = DotnetTestState.InitialState;
|
||||
_channels = new List<IReportingChannel>();
|
||||
_messageHandlers = new List<IDotnetTestMessageHandler>();
|
||||
_messages = messages;
|
||||
}
|
||||
|
||||
public DotnetTest AddMessageHandler(IDotnetTestMessageHandler messageHandler)
|
||||
{
|
||||
_messageHandlers.Add(messageHandler);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public void StartHandlingMessages()
|
||||
{
|
||||
Message message;
|
||||
while (_messages.TryTake(out message))
|
||||
{
|
||||
HandleMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
public void StartListeningTo(IReportingChannel reportingChannel)
|
||||
{
|
||||
ValidateSpecialMessageHandlersArePresent();
|
||||
|
||||
_channels.Add(reportingChannel);
|
||||
reportingChannel.MessageReceived += OnMessageReceived;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (var reportingChannel in _channels)
|
||||
{
|
||||
reportingChannel.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private void ValidateSpecialMessageHandlersArePresent()
|
||||
{
|
||||
if (TestSessionTerminateMessageHandler == null)
|
||||
{
|
||||
throw new InvalidOperationException("The TestSession.Terminate message handler needs to be set.");
|
||||
}
|
||||
|
||||
if (UnknownMessageHandler == null)
|
||||
{
|
||||
throw new InvalidOperationException("The unknown message handler needs to be set.");
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleMessage(Message message)
|
||||
{
|
||||
foreach (var messageHandler in _messageHandlers)
|
||||
{
|
||||
var nextState = messageHandler.HandleMessage(this, message);
|
||||
|
||||
if (nextState != DotnetTestState.NoOp)
|
||||
{
|
||||
State = nextState;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
UnknownMessageHandler.HandleMessage(this, message);
|
||||
}
|
||||
|
||||
private void OnMessageReceived(object sender, Message message)
|
||||
{
|
||||
if (!TerminateTestSession(message))
|
||||
{
|
||||
_messages.Add(message);
|
||||
}
|
||||
}
|
||||
|
||||
private bool TerminateTestSession(Message message)
|
||||
{
|
||||
return TestSessionTerminateMessageHandler.HandleMessage(this, message) == DotnetTestState.Terminated;
|
||||
}
|
||||
}
|
||||
}
|
61
src/dotnet/commands/dotnet-test/DotnetTestExtensions.cs
Normal file
61
src/dotnet/commands/dotnet-test/DotnetTestExtensions.cs
Normal file
|
@ -0,0 +1,61 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Microsoft.DotNet.Cli.Tools.Test;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public static class DotnetTestExtensions
|
||||
{
|
||||
public static IDotnetTest AddNonSpecificMessageHandlers(
|
||||
this IDotnetTest dotnetTest,
|
||||
ITestMessagesCollection messages,
|
||||
IReportingChannel adapterChannel)
|
||||
{
|
||||
dotnetTest.TestSessionTerminateMessageHandler = new TestSessionTerminateMessageHandler(messages);
|
||||
dotnetTest.UnknownMessageHandler = new UnknownMessageHandler(adapterChannel);
|
||||
|
||||
dotnetTest.AddMessageHandler(new VersionCheckMessageHandler(adapterChannel));
|
||||
|
||||
return dotnetTest;
|
||||
}
|
||||
|
||||
public static IDotnetTest AddTestDiscoveryMessageHandlers(
|
||||
this IDotnetTest dotnetTest,
|
||||
IReportingChannel adapterChannel,
|
||||
IReportingChannelFactory reportingChannelFactory,
|
||||
ITestRunnerFactory testRunnerFactory)
|
||||
{
|
||||
dotnetTest.AddMessageHandler(
|
||||
new TestDiscoveryStartMessageHandler(testRunnerFactory, adapterChannel, reportingChannelFactory));
|
||||
|
||||
return dotnetTest;
|
||||
}
|
||||
|
||||
public static IDotnetTest AddTestRunMessageHandlers(
|
||||
this IDotnetTest dotnetTest,
|
||||
IReportingChannel adapterChannel,
|
||||
IReportingChannelFactory reportingChannelFactory,
|
||||
ITestRunnerFactory testRunnerFactory)
|
||||
{
|
||||
dotnetTest.AddMessageHandler(new GetTestRunnerProcessStartInfoMessageHandler(
|
||||
testRunnerFactory,
|
||||
adapterChannel,
|
||||
reportingChannelFactory));
|
||||
|
||||
return dotnetTest;
|
||||
}
|
||||
|
||||
public static IDotnetTest AddTestRunnnersMessageHandlers(
|
||||
this IDotnetTest dotnetTest,
|
||||
IReportingChannel adapterChannel)
|
||||
{
|
||||
dotnetTest.AddMessageHandler(new TestRunnerTestStartedMessageHandler(adapterChannel));
|
||||
dotnetTest.AddMessageHandler(new TestRunnerTestResultMessageHandler(adapterChannel));
|
||||
dotnetTest.AddMessageHandler(new TestRunnerTestFoundMessageHandler(adapterChannel));
|
||||
dotnetTest.AddMessageHandler(new TestRunnerTestCompletedMessageHandler(adapterChannel));
|
||||
|
||||
return dotnetTest;
|
||||
}
|
||||
}
|
||||
}
|
18
src/dotnet/commands/dotnet-test/DotnetTestState.cs
Normal file
18
src/dotnet/commands/dotnet-test/DotnetTestState.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public enum DotnetTestState
|
||||
{
|
||||
NoOp,
|
||||
InitialState,
|
||||
VersionCheckCompleted,
|
||||
TestDiscoveryStarted,
|
||||
TestDiscoveryCompleted,
|
||||
TestExecutionSentTestRunnerProcessStartInfo,
|
||||
TestExecutionStarted,
|
||||
TestExecutionCompleted,
|
||||
Terminated
|
||||
}
|
||||
}
|
24
src/dotnet/commands/dotnet-test/IDotnetTest.cs
Normal file
24
src/dotnet/commands/dotnet-test/IDotnetTest.cs
Normal file
|
@ -0,0 +1,24 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public interface IDotnetTest : IDisposable
|
||||
{
|
||||
string PathToAssemblyUnderTest { get; }
|
||||
|
||||
DotnetTestState State { get; }
|
||||
|
||||
DotnetTest AddMessageHandler(IDotnetTestMessageHandler messageHandler);
|
||||
|
||||
IDotnetTestMessageHandler TestSessionTerminateMessageHandler { set; }
|
||||
|
||||
IDotnetTestMessageHandler UnknownMessageHandler { set; }
|
||||
|
||||
void StartHandlingMessages();
|
||||
|
||||
void StartListeningTo(IReportingChannel reportingChannel);
|
||||
}
|
||||
}
|
21
src/dotnet/commands/dotnet-test/IReportingChannel.cs
Normal file
21
src/dotnet/commands/dotnet-test/IReportingChannel.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public interface IReportingChannel : IDisposable
|
||||
{
|
||||
event EventHandler<Message> MessageReceived;
|
||||
|
||||
int Port { get; }
|
||||
|
||||
void Send(Message message);
|
||||
|
||||
void SendError(string error);
|
||||
|
||||
void SendError(Exception ex);
|
||||
}
|
||||
}
|
12
src/dotnet/commands/dotnet-test/IReportingChannelFactory.cs
Normal file
12
src/dotnet/commands/dotnet-test/IReportingChannelFactory.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public interface IReportingChannelFactory
|
||||
{
|
||||
IReportingChannel CreateChannelWithAnyAvailablePort();
|
||||
|
||||
IReportingChannel CreateChannelWithPort(int port);
|
||||
}
|
||||
}
|
17
src/dotnet/commands/dotnet-test/ITestMessagesCollection.cs
Normal file
17
src/dotnet/commands/dotnet-test/ITestMessagesCollection.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public interface ITestMessagesCollection : IDisposable
|
||||
{
|
||||
void Drain();
|
||||
|
||||
void Add(Message message);
|
||||
|
||||
bool TryTake(out Message message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public class GetTestRunnerProcessStartInfoMessageHandler : IDotnetTestMessageHandler
|
||||
{
|
||||
private readonly ITestRunnerFactory _testRunnerFactory;
|
||||
private readonly IReportingChannel _adapterChannel;
|
||||
private readonly IReportingChannelFactory _reportingChannelFactory;
|
||||
|
||||
public GetTestRunnerProcessStartInfoMessageHandler(
|
||||
ITestRunnerFactory testRunnerFactory,
|
||||
IReportingChannel adapterChannel,
|
||||
IReportingChannelFactory reportingChannelFactory)
|
||||
{
|
||||
_testRunnerFactory = testRunnerFactory;
|
||||
_adapterChannel = adapterChannel;
|
||||
_reportingChannelFactory = reportingChannelFactory;
|
||||
}
|
||||
|
||||
public DotnetTestState HandleMessage(IDotnetTest dotnetTest, Message message)
|
||||
{
|
||||
var nextState = DotnetTestState.NoOp;
|
||||
|
||||
if (CanHandleMessage(dotnetTest, message))
|
||||
{
|
||||
DoHandleMessage(dotnetTest, message);
|
||||
nextState = DotnetTestState.TestExecutionSentTestRunnerProcessStartInfo;
|
||||
}
|
||||
|
||||
return nextState;
|
||||
}
|
||||
|
||||
private void DoHandleMessage(IDotnetTest dotnetTest, Message message)
|
||||
{
|
||||
var testRunnerChannel = _reportingChannelFactory.CreateChannelWithAnyAvailablePort();
|
||||
|
||||
dotnetTest.StartListeningTo(testRunnerChannel);
|
||||
|
||||
var testRunner = _testRunnerFactory.CreateTestRunner(
|
||||
new RunTestsArgumentsBuilder(dotnetTest.PathToAssemblyUnderTest, testRunnerChannel.Port, message));
|
||||
|
||||
var processStartInfo = testRunner.GetProcessStartInfo();
|
||||
|
||||
_adapterChannel.Send(new Message
|
||||
{
|
||||
MessageType = TestMessageTypes.TestExecutionTestRunnerProcessStartInfo,
|
||||
Payload = JToken.FromObject(processStartInfo)
|
||||
});
|
||||
}
|
||||
|
||||
private static bool CanHandleMessage(IDotnetTest dotnetTest, Message message)
|
||||
{
|
||||
return dotnetTest.State == DotnetTestState.VersionCheckCompleted &&
|
||||
message.MessageType == TestMessageTypes.TestExecutionGetTestRunnerProcessStartInfo;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public interface IDotnetTestMessageHandler
|
||||
{
|
||||
DotnetTestState HandleMessage(IDotnetTest dotnetTest, Message message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.DotNet.Tools.Test;
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
using NuGet.Protocol.Core.v3;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Tools.Test
|
||||
{
|
||||
public class TestDiscoveryStartMessageHandler : IDotnetTestMessageHandler
|
||||
{
|
||||
private readonly ITestRunnerFactory _testRunnerFactory;
|
||||
private readonly IReportingChannel _adapterChannel;
|
||||
private readonly IReportingChannelFactory _reportingChannelFactory;
|
||||
|
||||
public TestDiscoveryStartMessageHandler(
|
||||
ITestRunnerFactory testRunnerFactory,
|
||||
IReportingChannel adapterChannel,
|
||||
IReportingChannelFactory reportingChannelFactory)
|
||||
{
|
||||
_testRunnerFactory = testRunnerFactory;
|
||||
_adapterChannel = adapterChannel;
|
||||
_reportingChannelFactory = reportingChannelFactory;
|
||||
}
|
||||
|
||||
public DotnetTestState HandleMessage(IDotnetTest dotnetTest, Message message)
|
||||
{
|
||||
var nextState = DotnetTestState.NoOp;
|
||||
if (CanHandleMessage(dotnetTest, message))
|
||||
{
|
||||
HandleMessage(dotnetTest);
|
||||
nextState = DotnetTestState.TestDiscoveryStarted;
|
||||
}
|
||||
|
||||
return nextState;
|
||||
}
|
||||
|
||||
private void HandleMessage(IDotnetTest dotnetTest)
|
||||
{
|
||||
TestHostTracing.Source.TraceInformation("Starting Discovery");
|
||||
|
||||
DiscoverTests(dotnetTest);
|
||||
}
|
||||
|
||||
private void DiscoverTests(IDotnetTest dotnetTest)
|
||||
{
|
||||
var testRunnerResults = Enumerable.Empty<Message>();
|
||||
|
||||
try
|
||||
{
|
||||
var testRunnerChannel = _reportingChannelFactory.CreateChannelWithAnyAvailablePort();
|
||||
|
||||
dotnetTest.StartListeningTo(testRunnerChannel);
|
||||
|
||||
var testRunner = _testRunnerFactory.CreateTestRunner(
|
||||
new DiscoverTestsArgumentsBuilder(dotnetTest.PathToAssemblyUnderTest, testRunnerChannel.Port));
|
||||
|
||||
testRunner.RunTestCommand();
|
||||
}
|
||||
catch (TestRunnerOperationFailedException e)
|
||||
{
|
||||
_adapterChannel.SendError(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool CanHandleMessage(IDotnetTest dotnetTest, Message message)
|
||||
{
|
||||
return dotnetTest.State == DotnetTestState.VersionCheckCompleted &&
|
||||
message.MessageType == TestMessageTypes.TestDiscoveryStart;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public static class TestMessageTypes
|
||||
{
|
||||
public const string TestRunnerTestResult = "TestExecution.TestResult";
|
||||
public const string TestRunnerTestStarted = "TestExecution.TestStarted";
|
||||
public const string TestRunnerTestCompleted = "TestRunner.TestCompleted";
|
||||
public const string TestRunnerTestFound = "TestDiscovery.TestFound";
|
||||
public const string TestSessionTerminate = "TestSession.Terminate";
|
||||
public const string VersionCheck = "ProtocolVersion";
|
||||
public const string TestDiscoveryStart = "TestDiscovery.Start";
|
||||
public const string TestDiscoveryCompleted = "TestDiscovery.Completed";
|
||||
public const string TestDiscoveryTestFound = "TestDiscovery.TestFound";
|
||||
public const string TestExecutionGetTestRunnerProcessStartInfo = "TestExecution.GetTestRunnerProcessStartInfo";
|
||||
public const string TestExecutionTestRunnerProcessStartInfo = "TestExecution.TestRunnerProcessStartInfo";
|
||||
public const string TestExecutionStarted = "TestExecution.TestStarted";
|
||||
public const string TestExecutionTestResult = "TestExecution.TestResult";
|
||||
public const string TestExecutionCompleted = "TestExecution.Completed";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public abstract class TestRunnerResultMessageHandler : IDotnetTestMessageHandler
|
||||
{
|
||||
private readonly IReportingChannel _adapterChannel;
|
||||
private readonly DotnetTestState _nextStateIfHandled;
|
||||
private readonly string _messageIfHandled;
|
||||
|
||||
protected TestRunnerResultMessageHandler(
|
||||
IReportingChannel adapterChannel,
|
||||
DotnetTestState nextStateIfHandled,
|
||||
string messageIfHandled)
|
||||
{
|
||||
_adapterChannel = adapterChannel;
|
||||
_nextStateIfHandled = nextStateIfHandled;
|
||||
_messageIfHandled = messageIfHandled;
|
||||
}
|
||||
|
||||
public DotnetTestState HandleMessage(IDotnetTest dotnetTest, Message message)
|
||||
{
|
||||
var nextState = DotnetTestState.NoOp;
|
||||
if (CanHandleMessage(dotnetTest, message))
|
||||
{
|
||||
HandleMessage(message);
|
||||
nextState = _nextStateIfHandled;
|
||||
}
|
||||
|
||||
return nextState;
|
||||
}
|
||||
|
||||
private void HandleMessage(Message message)
|
||||
{
|
||||
_adapterChannel.Send(new Message
|
||||
{
|
||||
MessageType = _messageIfHandled,
|
||||
Payload = message.Payload
|
||||
});
|
||||
}
|
||||
|
||||
protected abstract bool CanHandleMessage(IDotnetTest dotnetTest, Message message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public class TestRunnerTestCompletedMessageHandler : IDotnetTestMessageHandler
|
||||
{
|
||||
private readonly IReportingChannel _adapterChannel;
|
||||
|
||||
public TestRunnerTestCompletedMessageHandler(IReportingChannel adapterChannel)
|
||||
{
|
||||
_adapterChannel = adapterChannel;
|
||||
}
|
||||
|
||||
public DotnetTestState HandleMessage(IDotnetTest dotnetTest, Message message)
|
||||
{
|
||||
var nextState = DotnetTestState.NoOp;
|
||||
if (CanHandleMessage(dotnetTest, message))
|
||||
{
|
||||
DoHandleMessage(dotnetTest, message);
|
||||
nextState = NextState(dotnetTest);
|
||||
}
|
||||
|
||||
return nextState;
|
||||
}
|
||||
|
||||
private void DoHandleMessage(IDotnetTest dotnetTest, Message message)
|
||||
{
|
||||
_adapterChannel.Send(new Message
|
||||
{
|
||||
MessageType = MessageType(dotnetTest)
|
||||
});
|
||||
}
|
||||
|
||||
private string MessageType(IDotnetTest dotnetTest)
|
||||
{
|
||||
return dotnetTest.State == DotnetTestState.TestDiscoveryStarted
|
||||
? TestMessageTypes.TestDiscoveryCompleted
|
||||
: TestMessageTypes.TestExecutionCompleted;
|
||||
}
|
||||
|
||||
private DotnetTestState NextState(IDotnetTest dotnetTest)
|
||||
{
|
||||
return dotnetTest.State == DotnetTestState.TestDiscoveryStarted
|
||||
? DotnetTestState.TestDiscoveryCompleted
|
||||
: DotnetTestState.TestExecutionCompleted;
|
||||
}
|
||||
|
||||
private bool CanHandleMessage(IDotnetTest dotnetTest, Message message)
|
||||
{
|
||||
return IsAtAnAcceptableState(dotnetTest) && CanAcceptMessage(message);
|
||||
}
|
||||
|
||||
private static bool CanAcceptMessage(Message message)
|
||||
{
|
||||
return message.MessageType == TestMessageTypes.TestRunnerTestCompleted;
|
||||
}
|
||||
|
||||
private static bool IsAtAnAcceptableState(IDotnetTest dotnetTest)
|
||||
{
|
||||
return (dotnetTest.State == DotnetTestState.TestDiscoveryStarted ||
|
||||
dotnetTest.State == DotnetTestState.TestExecutionStarted);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public class TestRunnerTestFoundMessageHandler : TestRunnerResultMessageHandler
|
||||
{
|
||||
public TestRunnerTestFoundMessageHandler(IReportingChannel adapterChannel)
|
||||
: base(adapterChannel, DotnetTestState.TestDiscoveryStarted, TestMessageTypes.TestDiscoveryTestFound)
|
||||
{
|
||||
}
|
||||
|
||||
protected override bool CanHandleMessage(IDotnetTest dotnetTest, Message message)
|
||||
{
|
||||
return dotnetTest.State == DotnetTestState.TestDiscoveryStarted &&
|
||||
message.MessageType == TestMessageTypes.TestRunnerTestFound;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public class TestRunnerTestResultMessageHandler : TestRunnerResultMessageHandler
|
||||
{
|
||||
public TestRunnerTestResultMessageHandler(IReportingChannel adapterChannel)
|
||||
: base(adapterChannel, DotnetTestState.TestExecutionStarted, TestMessageTypes.TestExecutionTestResult)
|
||||
{
|
||||
}
|
||||
|
||||
protected override bool CanHandleMessage(IDotnetTest dotnetTest, Message message)
|
||||
{
|
||||
return dotnetTest.State == DotnetTestState.TestExecutionStarted &&
|
||||
message.MessageType == TestMessageTypes.TestRunnerTestResult;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public class TestRunnerTestStartedMessageHandler : TestRunnerResultMessageHandler
|
||||
{
|
||||
public TestRunnerTestStartedMessageHandler(IReportingChannel adapterChannel)
|
||||
: base(adapterChannel, DotnetTestState.TestExecutionStarted, TestMessageTypes.TestExecutionStarted)
|
||||
{
|
||||
}
|
||||
|
||||
protected override bool CanHandleMessage(IDotnetTest dotnetTest, Message message)
|
||||
{
|
||||
return dotnetTest.State == DotnetTestState.TestExecutionSentTestRunnerProcessStartInfo &&
|
||||
message.MessageType == TestMessageTypes.TestRunnerTestStarted;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public class TestSessionTerminateMessageHandler : IDotnetTestMessageHandler
|
||||
{
|
||||
private readonly ITestMessagesCollection _messages;
|
||||
|
||||
public TestSessionTerminateMessageHandler(ITestMessagesCollection messages)
|
||||
{
|
||||
_messages = messages;
|
||||
}
|
||||
|
||||
public DotnetTestState HandleMessage(IDotnetTest dotnetTest, Message message)
|
||||
{
|
||||
var nextState = DotnetTestState.NoOp;
|
||||
|
||||
if (TestMessageTypes.TestSessionTerminate.Equals(message.MessageType))
|
||||
{
|
||||
nextState = DotnetTestState.Terminated;
|
||||
_messages.Drain();
|
||||
}
|
||||
|
||||
return nextState;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public class UnknownMessageHandler : IDotnetTestMessageHandler
|
||||
{
|
||||
private readonly IReportingChannel _adapterChannel;
|
||||
|
||||
public UnknownMessageHandler(IReportingChannel adapterChannel)
|
||||
{
|
||||
_adapterChannel = adapterChannel;
|
||||
}
|
||||
|
||||
public DotnetTestState HandleMessage(IDotnetTest dotnetTest, Message message)
|
||||
{
|
||||
var error = $"No handler for message '{message.MessageType}' when at state '{dotnetTest.State}'";
|
||||
|
||||
TestHostTracing.Source.TraceEvent(TraceEventType.Error, 0, error);
|
||||
|
||||
_adapterChannel.SendError(error);
|
||||
|
||||
throw new InvalidOperationException(error);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public class VersionCheckMessageHandler : IDotnetTestMessageHandler
|
||||
{
|
||||
private const int SupportedVersion = 1;
|
||||
|
||||
private readonly IReportingChannel _adapterChannel;
|
||||
|
||||
public VersionCheckMessageHandler(IReportingChannel adapterChannel)
|
||||
{
|
||||
_adapterChannel = adapterChannel;
|
||||
}
|
||||
|
||||
public DotnetTestState HandleMessage(IDotnetTest dotnetTest, Message message)
|
||||
{
|
||||
var nextState = DotnetTestState.NoOp;
|
||||
if (CanHandleMessage(dotnetTest, message))
|
||||
{
|
||||
HandleMessage(message);
|
||||
nextState = DotnetTestState.VersionCheckCompleted;
|
||||
}
|
||||
|
||||
return nextState;
|
||||
}
|
||||
|
||||
private void HandleMessage(Message message)
|
||||
{
|
||||
var version = message.Payload?.ToObject<ProtocolVersionMessage>().Version;
|
||||
TestHostTracing.Source.TraceInformation(
|
||||
"[ReportingChannel]: Requested Version: {0} - Using Version: {1}",
|
||||
version,
|
||||
SupportedVersion);
|
||||
|
||||
_adapterChannel.Send(new Message
|
||||
{
|
||||
MessageType = TestMessageTypes.VersionCheck,
|
||||
Payload = JToken.FromObject(new ProtocolVersionMessage
|
||||
{
|
||||
Version = SupportedVersion,
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
private static bool CanHandleMessage(IDotnetTest dotnetTest, Message message)
|
||||
{
|
||||
return dotnetTest.State == DotnetTestState.InitialState &&
|
||||
TestMessageTypes.VersionCheck.Equals(message.MessageType);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,10 +9,6 @@ using System.Linq;
|
|||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.Dnx.Runtime.Common.CommandLine;
|
||||
using Microsoft.DotNet.ProjectModel;
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NuGet.Frameworks;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
|
@ -58,7 +54,7 @@ namespace Microsoft.DotNet.Tools.Test
|
|||
var projectContext = projectContexts.First();
|
||||
|
||||
var testRunner = projectContext.ProjectFile.TestRunner;
|
||||
|
||||
|
||||
var configuration = configurationOption.Value() ?? Constants.DefaultConfiguration;
|
||||
|
||||
if (portOption.HasValue())
|
||||
|
@ -105,154 +101,52 @@ namespace Microsoft.DotNet.Tools.Test
|
|||
.ExitCode;
|
||||
}
|
||||
|
||||
private static int RunDesignTime(int port, ProjectContext projectContext, string testRunner, string configuration)
|
||||
private static int RunDesignTime(
|
||||
int port,
|
||||
ProjectContext
|
||||
projectContext,
|
||||
string testRunner,
|
||||
string configuration)
|
||||
{
|
||||
Console.WriteLine("Listening on port {0}", port);
|
||||
using (var channel = ReportingChannel.ListenOn(port))
|
||||
{
|
||||
Console.WriteLine("Client accepted {0}", channel.Socket.LocalEndPoint);
|
||||
|
||||
HandleDesignTimeMessages(projectContext, testRunner, channel, configuration);
|
||||
HandleDesignTimeMessages(projectContext, testRunner, port, configuration);
|
||||
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static void HandleDesignTimeMessages(ProjectContext projectContext, string testRunner, ReportingChannel channel, string configuration)
|
||||
private static void HandleDesignTimeMessages(
|
||||
ProjectContext projectContext,
|
||||
string testRunner,
|
||||
int port,
|
||||
string configuration)
|
||||
{
|
||||
var reportingChannelFactory = new ReportingChannelFactory();
|
||||
var adapterChannel = reportingChannelFactory.CreateChannelWithPort(port);
|
||||
|
||||
try
|
||||
{
|
||||
var message = channel.ReadQueue.Take();
|
||||
var assemblyUnderTest = projectContext.GetOutputPaths(configuration).CompilationFiles.Assembly;
|
||||
var messages = new TestMessagesCollection();
|
||||
using (var dotnetTest = new DotnetTest(messages, assemblyUnderTest))
|
||||
{
|
||||
var commandFactory = new DotNetCommandFactory();
|
||||
var testRunnerFactory = new TestRunnerFactory(GetCommandName(testRunner), commandFactory);
|
||||
|
||||
if (message.MessageType == "ProtocolVersion")
|
||||
{
|
||||
HandleProtocolVersionMessage(message, channel);
|
||||
dotnetTest
|
||||
.AddNonSpecificMessageHandlers(messages, adapterChannel)
|
||||
.AddTestDiscoveryMessageHandlers(adapterChannel, reportingChannelFactory, testRunnerFactory)
|
||||
.AddTestRunMessageHandlers(adapterChannel, reportingChannelFactory, testRunnerFactory)
|
||||
.AddTestRunnnersMessageHandlers(adapterChannel);
|
||||
|
||||
// Take the next message, which should be the command to execute.
|
||||
message = channel.ReadQueue.Take();
|
||||
}
|
||||
dotnetTest.StartListeningTo(adapterChannel);
|
||||
|
||||
if (message.MessageType == "TestDiscovery.Start")
|
||||
{
|
||||
HandleTestDiscoveryStartMessage(testRunner, channel, projectContext, configuration);
|
||||
}
|
||||
else if (message.MessageType == "TestExecution.Start")
|
||||
{
|
||||
HandleTestExecutionStartMessage(testRunner, message, channel, projectContext, configuration);
|
||||
}
|
||||
else
|
||||
{
|
||||
HandleUnknownMessage(message, channel);
|
||||
dotnetTest.StartHandlingMessages();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
channel.SendError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static void HandleProtocolVersionMessage(Message message, ReportingChannel channel)
|
||||
{
|
||||
var version = message.Payload?.ToObject<ProtocolVersionMessage>().Version;
|
||||
var supportedVersion = 1;
|
||||
TestHostTracing.Source.TraceInformation(
|
||||
"[ReportingChannel]: Requested Version: {0} - Using Version: {1}",
|
||||
version,
|
||||
supportedVersion);
|
||||
|
||||
channel.Send(new Message()
|
||||
{
|
||||
MessageType = "ProtocolVersion",
|
||||
Payload = JToken.FromObject(new ProtocolVersionMessage()
|
||||
{
|
||||
Version = supportedVersion,
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
private static void HandleTestDiscoveryStartMessage(string testRunner, ReportingChannel channel, ProjectContext projectContext, string configuration)
|
||||
{
|
||||
TestHostTracing.Source.TraceInformation("Starting Discovery");
|
||||
|
||||
var commandArgs = new List<string> { projectContext.GetOutputPaths(configuration).CompilationFiles.Assembly };
|
||||
|
||||
commandArgs.AddRange(new[]
|
||||
{
|
||||
"--list",
|
||||
"--designtime"
|
||||
});
|
||||
|
||||
ExecuteRunnerCommand(testRunner, channel, commandArgs);
|
||||
|
||||
channel.Send(new Message()
|
||||
{
|
||||
MessageType = "TestDiscovery.Response",
|
||||
});
|
||||
|
||||
TestHostTracing.Source.TraceInformation("Completed Discovery");
|
||||
}
|
||||
|
||||
private static void HandleTestExecutionStartMessage(string testRunner, Message message, ReportingChannel channel, ProjectContext projectContext, string configuration)
|
||||
{
|
||||
TestHostTracing.Source.TraceInformation("Starting Execution");
|
||||
|
||||
var commandArgs = new List<string> { projectContext.GetOutputPaths(configuration).CompilationFiles.Assembly };
|
||||
|
||||
commandArgs.AddRange(new[]
|
||||
{
|
||||
"--designtime"
|
||||
});
|
||||
|
||||
var tests = message.Payload?.ToObject<RunTestsMessage>().Tests;
|
||||
if (tests != null)
|
||||
{
|
||||
foreach (var test in tests)
|
||||
{
|
||||
commandArgs.Add("--test");
|
||||
commandArgs.Add(test);
|
||||
}
|
||||
}
|
||||
|
||||
ExecuteRunnerCommand(testRunner, channel, commandArgs);
|
||||
|
||||
channel.Send(new Message()
|
||||
{
|
||||
MessageType = "TestExecution.Response",
|
||||
});
|
||||
|
||||
TestHostTracing.Source.TraceInformation("Completed Execution");
|
||||
}
|
||||
|
||||
private static void HandleUnknownMessage(Message message, ReportingChannel channel)
|
||||
{
|
||||
var error = string.Format("Unexpected message type: '{0}'.", message.MessageType);
|
||||
|
||||
TestHostTracing.Source.TraceEvent(TraceEventType.Error, 0, error);
|
||||
|
||||
channel.SendError(error);
|
||||
|
||||
throw new InvalidOperationException(error);
|
||||
}
|
||||
|
||||
private static void ExecuteRunnerCommand(string testRunner, ReportingChannel channel, List<string> commandArgs)
|
||||
{
|
||||
var result = Command.CreateDotNet(GetCommandName(testRunner), commandArgs, new NuGetFramework("DNXCore", Version.Parse("5.0")))
|
||||
.OnOutputLine(line =>
|
||||
{
|
||||
try
|
||||
{
|
||||
channel.Send(JsonConvert.DeserializeObject<Message>(line));
|
||||
}
|
||||
catch
|
||||
{
|
||||
TestHostTracing.Source.TraceInformation(line);
|
||||
}
|
||||
})
|
||||
.Execute();
|
||||
|
||||
if (result.ExitCode != 0)
|
||||
{
|
||||
channel.SendError($"{GetCommandName(testRunner)} returned '{result.ExitCode}'.");
|
||||
adapterChannel.SendError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
|
@ -14,7 +13,7 @@ using Newtonsoft.Json.Linq;
|
|||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public class ReportingChannel : IDisposable
|
||||
public class ReportingChannel : IReportingChannel
|
||||
{
|
||||
public static ReportingChannel ListenOn(int port)
|
||||
{
|
||||
|
@ -32,7 +31,6 @@ namespace Microsoft.DotNet.Tools.Test
|
|||
|
||||
private readonly BinaryWriter _writer;
|
||||
private readonly BinaryReader _reader;
|
||||
private readonly ManualResetEventSlim _ackWaitHandle;
|
||||
|
||||
private ReportingChannel(Socket socket)
|
||||
{
|
||||
|
@ -41,18 +39,17 @@ namespace Microsoft.DotNet.Tools.Test
|
|||
var stream = new NetworkStream(Socket);
|
||||
_writer = new BinaryWriter(stream);
|
||||
_reader = new BinaryReader(stream);
|
||||
_ackWaitHandle = new ManualResetEventSlim();
|
||||
|
||||
ReadQueue = new BlockingCollection<Message>(boundedCapacity: 1);
|
||||
|
||||
// Read incoming messages on the background thread
|
||||
new Thread(ReadMessages) { IsBackground = true }.Start();
|
||||
}
|
||||
|
||||
public BlockingCollection<Message> ReadQueue { get; }
|
||||
public event EventHandler<Message> MessageReceived;
|
||||
|
||||
public Socket Socket { get; private set; }
|
||||
|
||||
public int Port => ((IPEndPoint) Socket.LocalEndPoint).Port;
|
||||
|
||||
public void Send(Message message)
|
||||
{
|
||||
lock (_writer)
|
||||
|
@ -62,7 +59,7 @@ namespace Microsoft.DotNet.Tools.Test
|
|||
TestHostTracing.Source.TraceEvent(
|
||||
TraceEventType.Verbose,
|
||||
0,
|
||||
"[ReportingChannel]: Send({0})",
|
||||
"[ReportingChannel]: Send({0})",
|
||||
message);
|
||||
|
||||
_writer.Write(JsonConvert.SerializeObject(message));
|
||||
|
@ -103,14 +100,8 @@ namespace Microsoft.DotNet.Tools.Test
|
|||
try
|
||||
{
|
||||
var message = JsonConvert.DeserializeObject<Message>(_reader.ReadString());
|
||||
ReadQueue.Add(message);
|
||||
|
||||
if (string.Equals(message.MessageType, "TestHost.Acknowledge"))
|
||||
{
|
||||
_ackWaitHandle.Set();
|
||||
ReadQueue.CompleteAdding();
|
||||
break;
|
||||
}
|
||||
MessageReceived?.Invoke(this, message);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -126,24 +117,6 @@ namespace Microsoft.DotNet.Tools.Test
|
|||
|
||||
public void Dispose()
|
||||
{
|
||||
// Wait for a graceful disconnect - drain the queue until we get an 'ACK'
|
||||
Message message;
|
||||
while (ReadQueue.TryTake(out message, millisecondsTimeout: 1))
|
||||
{
|
||||
}
|
||||
|
||||
if (_ackWaitHandle.Wait(TimeSpan.FromSeconds(10)))
|
||||
{
|
||||
TestHostTracing.Source.TraceInformation("[ReportingChannel]: Received for ack from test host");
|
||||
}
|
||||
else
|
||||
{
|
||||
TestHostTracing.Source.TraceEvent(
|
||||
TraceEventType.Error,
|
||||
0,
|
||||
"[ReportingChannel]: Timed out waiting for ack from test host");
|
||||
}
|
||||
|
||||
Socket.Dispose();
|
||||
}
|
||||
}
|
||||
|
|
18
src/dotnet/commands/dotnet-test/ReportingChannelFactory.cs
Normal file
18
src/dotnet/commands/dotnet-test/ReportingChannelFactory.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public class ReportingChannelFactory : IReportingChannelFactory
|
||||
{
|
||||
public IReportingChannel CreateChannelWithAnyAvailablePort()
|
||||
{
|
||||
return ReportingChannel.ListenOn(0);
|
||||
}
|
||||
|
||||
public IReportingChannel CreateChannelWithPort(int port)
|
||||
{
|
||||
return ReportingChannel.ListenOn(port);
|
||||
}
|
||||
}
|
||||
}
|
73
src/dotnet/commands/dotnet-test/TestMessagesCollection.cs
Normal file
73
src/dotnet/commands/dotnet-test/TestMessagesCollection.cs
Normal file
|
@ -0,0 +1,73 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
using System;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public class TestMessagesCollection : ITestMessagesCollection
|
||||
{
|
||||
private readonly ManualResetEventSlim _terminateWaitHandle;
|
||||
private readonly BlockingCollection<Message> _readQueue;
|
||||
|
||||
public TestMessagesCollection()
|
||||
{
|
||||
_readQueue = new BlockingCollection<Message>(boundedCapacity: 1);
|
||||
_terminateWaitHandle = new ManualResetEventSlim();
|
||||
}
|
||||
|
||||
public void Drain()
|
||||
{
|
||||
_terminateWaitHandle.Set();
|
||||
_readQueue.CompleteAdding();
|
||||
DrainQueue();
|
||||
}
|
||||
|
||||
public void Add(Message message)
|
||||
{
|
||||
_readQueue.Add(message);
|
||||
}
|
||||
|
||||
public bool TryTake(out Message message)
|
||||
{
|
||||
message = null;
|
||||
try
|
||||
{
|
||||
message = _readQueue.Take();
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_terminateWaitHandle.Wait(TimeSpan.FromSeconds(10)))
|
||||
{
|
||||
TestHostTracing.Source.TraceInformation("[ReportingChannel]: Received TestSession:Terminate from test host");
|
||||
}
|
||||
else
|
||||
{
|
||||
TestHostTracing.Source.TraceEvent(
|
||||
TraceEventType.Error,
|
||||
0,
|
||||
"[ReportingChannel]: Timed out waiting for aTestSession:Terminate from test host");
|
||||
}
|
||||
}
|
||||
|
||||
private void DrainQueue()
|
||||
{
|
||||
Message message;
|
||||
while (_readQueue.TryTake(out message, millisecondsTimeout: 1))
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public class DiscoverTestsArgumentsBuilder : ITestRunnerArgumentsBuilder
|
||||
{
|
||||
private readonly string _assemblyUnderTest;
|
||||
private readonly int _port;
|
||||
|
||||
public DiscoverTestsArgumentsBuilder(string assemblyUnderTest, int port)
|
||||
{
|
||||
_assemblyUnderTest = assemblyUnderTest;
|
||||
_port = port;
|
||||
}
|
||||
|
||||
public IEnumerable<string> BuildArguments()
|
||||
{
|
||||
var commandArgs = new List<string>
|
||||
{
|
||||
_assemblyUnderTest,
|
||||
"--list",
|
||||
"--designtime",
|
||||
"--port",
|
||||
$"{_port}"
|
||||
};
|
||||
|
||||
return commandArgs;
|
||||
}
|
||||
}
|
||||
}
|
16
src/dotnet/commands/dotnet-test/TestRunners/ITestRunner.cs
Normal file
16
src/dotnet/commands/dotnet-test/TestRunners/ITestRunner.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public interface ITestRunner
|
||||
{
|
||||
void RunTestCommand();
|
||||
|
||||
ProcessStartInfo GetProcessStartInfo();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public interface ITestRunnerArgumentsBuilder
|
||||
{
|
||||
IEnumerable<string> BuildArguments();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public interface ITestRunnerFactory
|
||||
{
|
||||
ITestRunner CreateTestRunner(ITestRunnerArgumentsBuilder argumentsBuilder);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public class RunTestsArgumentsBuilder : ITestRunnerArgumentsBuilder
|
||||
{
|
||||
private readonly string _assemblyUnderTest;
|
||||
private readonly int _port;
|
||||
private readonly Message _message;
|
||||
|
||||
public RunTestsArgumentsBuilder(string assemblyUnderTest, int port, Message message)
|
||||
{
|
||||
_assemblyUnderTest = assemblyUnderTest;
|
||||
_port = port;
|
||||
_message = message;
|
||||
}
|
||||
|
||||
public IEnumerable<string> BuildArguments()
|
||||
{
|
||||
var commandArgs = new List<string>
|
||||
{
|
||||
_assemblyUnderTest,
|
||||
"--designtime",
|
||||
"--port",
|
||||
$"{_port}"
|
||||
};
|
||||
|
||||
var tests = _message.Payload?.ToObject<RunTestsMessage>().Tests;
|
||||
if (tests != null)
|
||||
{
|
||||
foreach (var test in tests)
|
||||
{
|
||||
commandArgs.Add("--test");
|
||||
commandArgs.Add(test);
|
||||
}
|
||||
}
|
||||
|
||||
return commandArgs;
|
||||
}
|
||||
}
|
||||
}
|
59
src/dotnet/commands/dotnet-test/TestRunners/TestRunner.cs
Normal file
59
src/dotnet/commands/dotnet-test/TestRunners/TestRunner.cs
Normal file
|
@ -0,0 +1,59 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using NuGet.Frameworks;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public class TestRunner : ITestRunner
|
||||
{
|
||||
private readonly string _testRunner;
|
||||
private readonly ICommandFactory _commandFactory;
|
||||
private readonly ITestRunnerArgumentsBuilder _argumentsBuilder;
|
||||
|
||||
public TestRunner(
|
||||
string testRunner,
|
||||
ICommandFactory commandFactory,
|
||||
ITestRunnerArgumentsBuilder argumentsBuilder)
|
||||
{
|
||||
_testRunner = testRunner;
|
||||
_commandFactory = commandFactory;
|
||||
_argumentsBuilder = argumentsBuilder;
|
||||
}
|
||||
|
||||
public void RunTestCommand()
|
||||
{
|
||||
ExecuteRunnerCommand();
|
||||
}
|
||||
|
||||
public ProcessStartInfo GetProcessStartInfo()
|
||||
{
|
||||
var command = CreateTestRunnerCommand();
|
||||
|
||||
return command.ToProcessStartInfo();
|
||||
}
|
||||
|
||||
private void ExecuteRunnerCommand()
|
||||
{
|
||||
var result = CreateTestRunnerCommand().Execute();
|
||||
|
||||
if (result.ExitCode != 0)
|
||||
{
|
||||
throw new TestRunnerOperationFailedException(_testRunner, result.ExitCode);
|
||||
}
|
||||
}
|
||||
|
||||
private ICommand CreateTestRunnerCommand()
|
||||
{
|
||||
var commandArgs = _argumentsBuilder.BuildArguments();
|
||||
|
||||
return _commandFactory.Create(
|
||||
_testRunner,
|
||||
commandArgs,
|
||||
new NuGetFramework("DNXCore", Version.Parse("5.0")));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public class TestRunnerFactory : ITestRunnerFactory
|
||||
{
|
||||
private readonly string _testRunner;
|
||||
private readonly ICommandFactory _commandFactory;
|
||||
|
||||
public TestRunnerFactory(string testRunner, ICommandFactory commandFactory)
|
||||
{
|
||||
_testRunner = testRunner;
|
||||
_commandFactory = commandFactory;
|
||||
}
|
||||
|
||||
public ITestRunner CreateTestRunner(ITestRunnerArgumentsBuilder argumentsBuilder)
|
||||
{
|
||||
return new TestRunner(_testRunner, _commandFactory, argumentsBuilder);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test
|
||||
{
|
||||
public class TestRunnerOperationFailedException : Exception
|
||||
{
|
||||
public string TestRunner { get; set; }
|
||||
public int ExitCode { get; set; }
|
||||
public override string Message => $"'{TestRunner}' returned '{ExitCode}'.";
|
||||
|
||||
public TestRunnerOperationFailedException(string testRunner, int exitCode)
|
||||
{
|
||||
TestRunner = testRunner;
|
||||
ExitCode = exitCode;
|
||||
}
|
||||
}
|
||||
}
|
76
test/dotnet-test.UnitTests/DotnetTestMessageScenario.cs
Normal file
76
test/dotnet-test.UnitTests/DotnetTestMessageScenario.cs
Normal file
|
@ -0,0 +1,76 @@
|
|||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.Tools.Test;
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
using Moq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.Dotnet.Tools.Test.Tests
|
||||
{
|
||||
public class DotnetTestMessageScenario
|
||||
{
|
||||
private TestMessagesCollection _messages;
|
||||
private const string AssemblyUnderTest = "assembly.dll";
|
||||
private const string TestRunner = "testRunner";
|
||||
private const int Port = 1;
|
||||
|
||||
public DotnetTest DotnetTestUnderTest { get; private set; }
|
||||
public Mock<ITestRunner> TestRunnerMock { get; private set; }
|
||||
public Mock<IReportingChannel> AdapterChannelMock { get; private set; }
|
||||
public Mock<IReportingChannel> TestRunnerChannelMock { get; private set; }
|
||||
|
||||
public DotnetTestMessageScenario()
|
||||
{
|
||||
_messages = new TestMessagesCollection();
|
||||
DotnetTestUnderTest = new DotnetTest(_messages, AssemblyUnderTest);
|
||||
TestRunnerChannelMock = new Mock<IReportingChannel>();
|
||||
TestRunnerMock = new Mock<ITestRunner>();
|
||||
AdapterChannelMock = new Mock<IReportingChannel>();
|
||||
}
|
||||
|
||||
public void Run()
|
||||
{
|
||||
var reportingChannelFactoryMock = new Mock<IReportingChannelFactory>();
|
||||
reportingChannelFactoryMock
|
||||
.Setup(r => r.CreateChannelWithAnyAvailablePort())
|
||||
.Returns(TestRunnerChannelMock.Object);
|
||||
|
||||
var commandFactoryMock = new Mock<ICommandFactory>();
|
||||
|
||||
var testRunnerFactoryMock = new Mock<ITestRunnerFactory>();
|
||||
testRunnerFactoryMock
|
||||
.Setup(t => t.CreateTestRunner(It.IsAny<DiscoverTestsArgumentsBuilder>()))
|
||||
.Returns(TestRunnerMock.Object);
|
||||
|
||||
testRunnerFactoryMock
|
||||
.Setup(t => t.CreateTestRunner(It.IsAny<RunTestsArgumentsBuilder>()))
|
||||
.Returns(TestRunnerMock.Object);
|
||||
|
||||
var reportingChannelFactory = reportingChannelFactoryMock.Object;
|
||||
var adapterChannel = AdapterChannelMock.Object;
|
||||
var commandFactory = commandFactoryMock.Object;
|
||||
var testRunnerFactory = testRunnerFactoryMock.Object;
|
||||
|
||||
using (DotnetTestUnderTest)
|
||||
{
|
||||
DotnetTestUnderTest
|
||||
.AddNonSpecificMessageHandlers(_messages, adapterChannel)
|
||||
.AddTestDiscoveryMessageHandlers(adapterChannel, reportingChannelFactory, testRunnerFactory)
|
||||
.AddTestRunMessageHandlers(adapterChannel, reportingChannelFactory, testRunnerFactory)
|
||||
.AddTestRunnnersMessageHandlers(adapterChannel);
|
||||
|
||||
DotnetTestUnderTest.StartListeningTo(adapterChannel);
|
||||
|
||||
AdapterChannelMock.Raise(r => r.MessageReceived += null, DotnetTestUnderTest, new Message
|
||||
{
|
||||
MessageType = TestMessageTypes.VersionCheck,
|
||||
Payload = JToken.FromObject(new ProtocolVersionMessage { Version = 1 })
|
||||
});
|
||||
|
||||
DotnetTestUnderTest.StartHandlingMessages();
|
||||
}
|
||||
|
||||
AdapterChannelMock.Verify();
|
||||
TestRunnerMock.Verify();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using FluentAssertions;
|
||||
using Microsoft.DotNet.Tools.Test;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.Dotnet.Tools.Test.Tests
|
||||
{
|
||||
public class GivenADiscoverTestsArgumentsBuilder
|
||||
{
|
||||
[Fact]
|
||||
public void It_generates_the_right_arguments_for_DiscoverTests()
|
||||
{
|
||||
const int port = 1;
|
||||
const string assembly = "assembly.dll";
|
||||
|
||||
var discoverTestsArgumentsBuilder = new DiscoverTestsArgumentsBuilder(assembly, port);
|
||||
|
||||
var arguments = discoverTestsArgumentsBuilder.BuildArguments();
|
||||
|
||||
arguments.Should().BeEquivalentTo(assembly, "--list", "--designtime", "--port", $"{port}");
|
||||
}
|
||||
}
|
||||
}
|
157
test/dotnet-test.UnitTests/GivenADotnetTestApp.cs
Normal file
157
test/dotnet-test.UnitTests/GivenADotnetTestApp.cs
Normal file
|
@ -0,0 +1,157 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
using FluentAssertions;
|
||||
using Microsoft.DotNet.Tools.Test;
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.Dotnet.Tools.Test.Tests
|
||||
{
|
||||
public class GivenADotnetTestApp
|
||||
{
|
||||
private const string AssemblyUnderTest = "assembly.dll";
|
||||
|
||||
private Mock<IReportingChannel> _reportingChannelMock;
|
||||
private Mock<IDotnetTestMessageHandler> _noOpMessageHandlerMock;
|
||||
private Mock<IDotnetTestMessageHandler> _realMessageHandlerMock;
|
||||
private Mock<IDotnetTestMessageHandler> _unknownMessageHandlerMock;
|
||||
private DotnetTest _dotnetTest;
|
||||
|
||||
public GivenADotnetTestApp()
|
||||
{
|
||||
_noOpMessageHandlerMock = new Mock<IDotnetTestMessageHandler>();
|
||||
_noOpMessageHandlerMock
|
||||
.Setup(mh => mh.HandleMessage(It.IsAny<DotnetTest>(), It.IsAny<Message>()))
|
||||
.Returns(DotnetTestState.NoOp)
|
||||
.Verifiable();
|
||||
|
||||
_realMessageHandlerMock = new Mock<IDotnetTestMessageHandler>();
|
||||
_realMessageHandlerMock
|
||||
.Setup(mh => mh.HandleMessage(It.IsAny<DotnetTest>(), It.Is<Message>(m => m.MessageType == "Test message")))
|
||||
.Returns(DotnetTestState.VersionCheckCompleted).Callback(() =>
|
||||
_reportingChannelMock.Raise(r => r.MessageReceived += null, _dotnetTest, new Message
|
||||
{
|
||||
MessageType = TestMessageTypes.TestSessionTerminate
|
||||
}));
|
||||
|
||||
_reportingChannelMock = new Mock<IReportingChannel>();
|
||||
_unknownMessageHandlerMock = new Mock<IDotnetTestMessageHandler>();
|
||||
_unknownMessageHandlerMock
|
||||
.Setup(mh => mh.HandleMessage(It.IsAny<DotnetTest>(), It.IsAny<Message>()))
|
||||
.Throws<InvalidOperationException>();
|
||||
|
||||
var testMessagesCollection = new TestMessagesCollection();
|
||||
_dotnetTest = new DotnetTest(testMessagesCollection, AssemblyUnderTest)
|
||||
{
|
||||
TestSessionTerminateMessageHandler = new TestSessionTerminateMessageHandler(testMessagesCollection),
|
||||
UnknownMessageHandler = _unknownMessageHandlerMock.Object
|
||||
};
|
||||
|
||||
_dotnetTest.StartListeningTo(_reportingChannelMock.Object);
|
||||
|
||||
_reportingChannelMock.Raise(r => r.MessageReceived += null, _dotnetTest, new Message
|
||||
{
|
||||
MessageType = "Test message"
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DotnetTest_handles_TestSession_Terminate_messages_implicitly()
|
||||
{
|
||||
_reportingChannelMock.Raise(r => r.MessageReceived += null, _dotnetTest, new Message
|
||||
{
|
||||
MessageType = TestMessageTypes.TestSessionTerminate
|
||||
});
|
||||
|
||||
_dotnetTest.StartHandlingMessages();
|
||||
|
||||
//just the fact that we are not hanging means we stopped waiting for messages
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DotnetTest_calls_each_MessageHandler_until_one_returns_a_state_different_from_NoOp()
|
||||
{
|
||||
var secondNoOpMessageHandler = new Mock<IDotnetTestMessageHandler>();
|
||||
|
||||
_dotnetTest
|
||||
.AddMessageHandler(_noOpMessageHandlerMock.Object)
|
||||
.AddMessageHandler(_realMessageHandlerMock.Object)
|
||||
.AddMessageHandler(secondNoOpMessageHandler.Object);
|
||||
|
||||
_dotnetTest.StartHandlingMessages();
|
||||
|
||||
_noOpMessageHandlerMock.Verify();
|
||||
_realMessageHandlerMock.Verify();
|
||||
secondNoOpMessageHandler.Verify(
|
||||
mh => mh.HandleMessage(It.IsAny<DotnetTest>(), It.IsAny<Message>()),
|
||||
Times.Never);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DotnetTest_does_not_send_an_error_when_the_message_gets_handled()
|
||||
{
|
||||
_dotnetTest.AddMessageHandler(_realMessageHandlerMock.Object);
|
||||
|
||||
_dotnetTest.StartHandlingMessages();
|
||||
|
||||
_reportingChannelMock.Verify(r => r.SendError(It.IsAny<string>()), Times.Never);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DotnetTest_calls_the_unknown_message_handler_when_the_message_is_not_handled()
|
||||
{
|
||||
_dotnetTest.AddMessageHandler(_noOpMessageHandlerMock.Object);
|
||||
|
||||
Action action = () => _dotnetTest.StartHandlingMessages();
|
||||
|
||||
action.ShouldThrow<InvalidOperationException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_throws_an_InvalidOperationException_if_StartListening_is_called_without_setting_a_TestSessionTerminateMessageHandler()
|
||||
{
|
||||
var dotnetTest = new DotnetTest(new TestMessagesCollection(), AssemblyUnderTest)
|
||||
{
|
||||
UnknownMessageHandler = new Mock<IDotnetTestMessageHandler>().Object
|
||||
};
|
||||
|
||||
Action action = () => dotnetTest.StartListeningTo(new Mock<IReportingChannel>().Object);
|
||||
|
||||
action.ShouldThrow<InvalidOperationException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_throws_an_InvalidOperationException_if_StartListeningTo_is_called_without_setting_a_UnknownMessageHandler()
|
||||
{
|
||||
var dotnetTest = new DotnetTest(new TestMessagesCollection(), AssemblyUnderTest)
|
||||
{
|
||||
TestSessionTerminateMessageHandler = new Mock<IDotnetTestMessageHandler>().Object
|
||||
};
|
||||
|
||||
Action action = () => dotnetTest.StartListeningTo(new Mock<IReportingChannel>().Object);
|
||||
|
||||
action.ShouldThrow<InvalidOperationException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_disposes_all_reporting_channels_that_it_was_listening_to_when_it_gets_disposed()
|
||||
{
|
||||
var firstReportingChannelMock = new Mock<IReportingChannel>();
|
||||
var secondReportingChannelMock = new Mock<IReportingChannel>();
|
||||
using (var dotnetTest = new DotnetTest(new TestMessagesCollection(), AssemblyUnderTest))
|
||||
{
|
||||
dotnetTest.TestSessionTerminateMessageHandler = new Mock<IDotnetTestMessageHandler>().Object;
|
||||
dotnetTest.UnknownMessageHandler = new Mock<IDotnetTestMessageHandler>().Object;
|
||||
|
||||
dotnetTest.StartListeningTo(firstReportingChannelMock.Object);
|
||||
dotnetTest.StartListeningTo(secondReportingChannelMock.Object);
|
||||
}
|
||||
|
||||
firstReportingChannelMock.Verify(r => r.Dispose(), Times.Once);
|
||||
secondReportingChannelMock.Verify(r => r.Dispose(), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
41
test/dotnet-test.UnitTests/GivenARunTestsArgumentsBuilder.cs
Normal file
41
test/dotnet-test.UnitTests/GivenARunTestsArgumentsBuilder.cs
Normal file
|
@ -0,0 +1,41 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using FluentAssertions;
|
||||
using Microsoft.DotNet.Tools.Test;
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.Dotnet.Tools.Test.Tests
|
||||
{
|
||||
public class GivenARunTestsArgumentsBuilder
|
||||
{
|
||||
[Fact]
|
||||
public void It_generates_the_right_arguments_for_RunTests()
|
||||
{
|
||||
const int port = 1;
|
||||
const string assembly = "assembly.dll";
|
||||
|
||||
var message = new Message
|
||||
{
|
||||
Payload = JToken.FromObject(new RunTestsMessage { Tests = new List<string> { "test1", "test2" } })
|
||||
};
|
||||
|
||||
var runTestsArgumentsBuilder = new RunTestsArgumentsBuilder(assembly, port, message);
|
||||
|
||||
var arguments = runTestsArgumentsBuilder.BuildArguments();
|
||||
|
||||
arguments.Should().BeEquivalentTo(
|
||||
assembly,
|
||||
"--designtime",
|
||||
"--port",
|
||||
$"{port}",
|
||||
"--test",
|
||||
"test1",
|
||||
"--test",
|
||||
"test2");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using FluentAssertions;
|
||||
using Microsoft.DotNet.Cli.Tools.Test;
|
||||
using Microsoft.DotNet.Tools.Test;
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.Dotnet.Tools.Test.Tests
|
||||
{
|
||||
public class GivenATestDiscoveryStartMessageHandler
|
||||
{
|
||||
private const int TestRunnerPort = 1;
|
||||
private const string AssemblyUnderTest = "assembly.dll";
|
||||
|
||||
private TestDiscoveryStartMessageHandler _testDiscoveryStartMessageHandler;
|
||||
private IDotnetTest _dotnetTestAtVersionCheckCompletedState;
|
||||
private Message _validMessage;
|
||||
private Mock<ITestRunnerFactory> _testRunnerFactoryMock;
|
||||
private Mock<ITestRunner> _testRunnerMock;
|
||||
private Mock<IReportingChannel> _adapterChannelMock;
|
||||
private Mock<IReportingChannel> _testRunnerChannelMock;
|
||||
private Mock<IReportingChannelFactory> _reportingChannelFactoryMock;
|
||||
private DiscoverTestsArgumentsBuilder _argumentsBuilder;
|
||||
private Mock<IDotnetTest> _dotnetTestMock;
|
||||
|
||||
public GivenATestDiscoveryStartMessageHandler()
|
||||
{
|
||||
_dotnetTestMock = new Mock<IDotnetTest>();
|
||||
_dotnetTestMock.Setup(d => d.State).Returns(DotnetTestState.VersionCheckCompleted);
|
||||
_dotnetTestMock.Setup(d => d.PathToAssemblyUnderTest).Returns(AssemblyUnderTest);
|
||||
_dotnetTestAtVersionCheckCompletedState = _dotnetTestMock.Object;
|
||||
|
||||
_testRunnerMock = new Mock<ITestRunner>();
|
||||
_testRunnerFactoryMock = new Mock<ITestRunnerFactory>();
|
||||
_testRunnerFactoryMock
|
||||
.Setup(c => c.CreateTestRunner(It.IsAny<DiscoverTestsArgumentsBuilder>()))
|
||||
.Callback<ITestRunnerArgumentsBuilder>(r => _argumentsBuilder = r as DiscoverTestsArgumentsBuilder)
|
||||
.Returns(_testRunnerMock.Object);
|
||||
|
||||
_adapterChannelMock = new Mock<IReportingChannel>();
|
||||
|
||||
_testRunnerChannelMock = new Mock<IReportingChannel>();
|
||||
_testRunnerChannelMock.Setup(t => t.Port).Returns(TestRunnerPort);
|
||||
|
||||
_reportingChannelFactoryMock = new Mock<IReportingChannelFactory>();
|
||||
_reportingChannelFactoryMock.Setup(r =>
|
||||
r.CreateChannelWithAnyAvailablePort()).Returns(_testRunnerChannelMock.Object);
|
||||
|
||||
_testDiscoveryStartMessageHandler = new TestDiscoveryStartMessageHandler(
|
||||
_testRunnerFactoryMock.Object,
|
||||
_adapterChannelMock.Object,
|
||||
_reportingChannelFactoryMock.Object);
|
||||
|
||||
_validMessage = new Message
|
||||
{
|
||||
MessageType = TestMessageTypes.TestDiscoveryStart
|
||||
};
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_returns_NoOp_if_the_dotnet_test_state_is_not_VersionCheckCompleted()
|
||||
{
|
||||
var dotnetTestMock = new Mock<IDotnetTest>();
|
||||
dotnetTestMock.Setup(d => d.State).Returns(DotnetTestState.Terminated);
|
||||
|
||||
var nextState = _testDiscoveryStartMessageHandler.HandleMessage(
|
||||
dotnetTestMock.Object,
|
||||
new Message { MessageType = TestMessageTypes.TestDiscoveryStart });
|
||||
|
||||
nextState.Should().Be(DotnetTestState.NoOp);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_returns_NoOp_if_the_message_is_not_TestDiscoveryStart()
|
||||
{
|
||||
var nextState = _testDiscoveryStartMessageHandler.HandleMessage(
|
||||
_dotnetTestAtVersionCheckCompletedState,
|
||||
new Message { MessageType = "Something different from TestDiscovery.Start" });
|
||||
|
||||
nextState.Should().Be(DotnetTestState.NoOp);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_returns_TestDiscoveryCompleted_when_it_handles_the_message()
|
||||
{
|
||||
var nextState =
|
||||
_testDiscoveryStartMessageHandler.HandleMessage(_dotnetTestAtVersionCheckCompletedState, _validMessage);
|
||||
|
||||
nextState.Should().Be(DotnetTestState.TestDiscoveryStarted);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_uses_the_test_runner_to_discover_tests_when_it_handles_the_message()
|
||||
{
|
||||
_testDiscoveryStartMessageHandler.HandleMessage(_dotnetTestAtVersionCheckCompletedState, _validMessage);
|
||||
|
||||
_testRunnerMock.Verify(t => t.RunTestCommand(), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_sends_an_error_when_the_test_runner_fails()
|
||||
{
|
||||
const string testRunner = "SomeTestRunner";
|
||||
|
||||
_testRunnerMock.Setup(t => t.RunTestCommand()).Throws(new TestRunnerOperationFailedException(testRunner, 1));
|
||||
|
||||
_testDiscoveryStartMessageHandler.HandleMessage(_dotnetTestAtVersionCheckCompletedState, _validMessage);
|
||||
|
||||
_adapterChannelMock.Verify(r => r.SendError($"'{testRunner}' returned '1'."), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_creates_a_new_reporting_channel()
|
||||
{
|
||||
_testDiscoveryStartMessageHandler.HandleMessage(
|
||||
_dotnetTestMock.Object,
|
||||
_validMessage);
|
||||
|
||||
_reportingChannelFactoryMock.Verify(r => r.CreateChannelWithAnyAvailablePort(), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_makes_dotnet_test_listen_on_the_test_runner_port_for_messages_when_it_handles_the_message()
|
||||
{
|
||||
_testDiscoveryStartMessageHandler.HandleMessage(
|
||||
_dotnetTestMock.Object,
|
||||
_validMessage);
|
||||
|
||||
_dotnetTestMock.Verify(d => d.StartListeningTo(_testRunnerChannelMock.Object), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_passes_the_right_arguments_to_the_run_tests_arguments_builder()
|
||||
{
|
||||
_testDiscoveryStartMessageHandler.HandleMessage(
|
||||
_dotnetTestMock.Object,
|
||||
_validMessage);
|
||||
|
||||
_argumentsBuilder.Should().NotBeNull();
|
||||
|
||||
var arguments = _argumentsBuilder.BuildArguments();
|
||||
|
||||
arguments.Should().Contain("--port", $"{TestRunnerPort}");
|
||||
arguments.Should().Contain($"{AssemblyUnderTest}");
|
||||
arguments.Should().Contain("--list");
|
||||
arguments.Should().Contain("--designtime");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,165 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using FluentAssertions;
|
||||
using Microsoft.DotNet.Tools.Test;
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
using Moq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.Dotnet.Tools.Test.Tests
|
||||
{
|
||||
public class GivenATestExecutionGetTestRunnerProcessStartInfoMessageHandler
|
||||
{
|
||||
private const int TestRunnerPort = 1;
|
||||
private const string AssemblyUnderTest = "assembly.dll";
|
||||
|
||||
private GetTestRunnerProcessStartInfoMessageHandler _testGetTestRunnerProcessStartInfoMessageHandler;
|
||||
private Message _validMessage;
|
||||
private ProcessStartInfo _processStartInfo;
|
||||
|
||||
private Mock<ITestRunner> _testRunnerMock;
|
||||
private Mock<ITestRunnerFactory> _testRunnerFactoryMock;
|
||||
private Mock<IReportingChannel> _adapterChannelMock;
|
||||
private Mock<IReportingChannel> _testRunnerChannelMock;
|
||||
private Mock<IReportingChannelFactory> _reportingChannelFactoryMock;
|
||||
private Mock<IDotnetTest> _dotnetTestMock;
|
||||
|
||||
private RunTestsArgumentsBuilder _argumentsBuilder;
|
||||
|
||||
public GivenATestExecutionGetTestRunnerProcessStartInfoMessageHandler()
|
||||
{
|
||||
_validMessage = new Message
|
||||
{
|
||||
MessageType = TestMessageTypes.TestExecutionGetTestRunnerProcessStartInfo,
|
||||
Payload = JToken.FromObject(new RunTestsMessage { Tests = new List<string> { "test1", "test2" } })
|
||||
};
|
||||
|
||||
_dotnetTestMock = new Mock<IDotnetTest>();
|
||||
_dotnetTestMock.Setup(d => d.State).Returns(DotnetTestState.VersionCheckCompleted);
|
||||
_dotnetTestMock.Setup(d => d.PathToAssemblyUnderTest).Returns(AssemblyUnderTest);
|
||||
|
||||
_processStartInfo = new ProcessStartInfo("runner", "arguments");
|
||||
|
||||
_testRunnerMock = new Mock<ITestRunner>();
|
||||
_testRunnerMock.Setup(t => t.GetProcessStartInfo()).Returns(_processStartInfo);
|
||||
|
||||
_testRunnerFactoryMock = new Mock<ITestRunnerFactory>();
|
||||
_testRunnerFactoryMock
|
||||
.Setup(c => c.CreateTestRunner(It.IsAny<RunTestsArgumentsBuilder>()))
|
||||
.Callback<ITestRunnerArgumentsBuilder>(r => _argumentsBuilder = r as RunTestsArgumentsBuilder)
|
||||
.Returns(_testRunnerMock.Object);
|
||||
|
||||
_adapterChannelMock = new Mock<IReportingChannel>();
|
||||
_testRunnerChannelMock = new Mock<IReportingChannel>();
|
||||
_testRunnerChannelMock.Setup(t => t.Port).Returns(TestRunnerPort);
|
||||
|
||||
_reportingChannelFactoryMock = new Mock<IReportingChannelFactory>();
|
||||
_reportingChannelFactoryMock.Setup(r =>
|
||||
r.CreateChannelWithAnyAvailablePort()).Returns(_testRunnerChannelMock.Object);
|
||||
|
||||
_testGetTestRunnerProcessStartInfoMessageHandler = new GetTestRunnerProcessStartInfoMessageHandler(
|
||||
_testRunnerFactoryMock.Object,
|
||||
_adapterChannelMock.Object,
|
||||
_reportingChannelFactoryMock.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_returns_NoOp_if_the_dotnet_test_state_is_not_VersionCheckCompleted()
|
||||
{
|
||||
var dotnetTestMock = new Mock<IDotnetTest>();
|
||||
dotnetTestMock.Setup(d => d.State).Returns(DotnetTestState.Terminated);
|
||||
|
||||
var nextState = _testGetTestRunnerProcessStartInfoMessageHandler.HandleMessage(
|
||||
dotnetTestMock.Object,
|
||||
_validMessage);
|
||||
|
||||
nextState.Should().Be(DotnetTestState.NoOp);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_returns_NoOp_if_the_message_is_not_TestDiscoveryStart()
|
||||
{
|
||||
var nextState = _testGetTestRunnerProcessStartInfoMessageHandler.HandleMessage(
|
||||
_dotnetTestMock.Object,
|
||||
new Message { MessageType = "Something different from TestDiscovery.Start" });
|
||||
|
||||
nextState.Should().Be(DotnetTestState.NoOp);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_returns_TestExecutionSentTestRunnerProcessStartInfo_when_it_handles_the_message()
|
||||
{
|
||||
var nextState = _testGetTestRunnerProcessStartInfoMessageHandler.HandleMessage(
|
||||
_dotnetTestMock.Object,
|
||||
_validMessage);
|
||||
|
||||
nextState.Should().Be(DotnetTestState.TestExecutionSentTestRunnerProcessStartInfo);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_gets_the_process_start_info_from_the_test_runner_when_it_handles_the_message()
|
||||
{
|
||||
_testGetTestRunnerProcessStartInfoMessageHandler.HandleMessage(
|
||||
_dotnetTestMock.Object,
|
||||
_validMessage);
|
||||
|
||||
_testRunnerMock.Verify(t => t.GetProcessStartInfo(), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_sends_the_process_start_info_when_it_handles_the_message()
|
||||
{
|
||||
_adapterChannelMock.Setup(r => r.Send(It.Is<Message>(m =>
|
||||
m.MessageType == TestMessageTypes.TestExecutionTestRunnerProcessStartInfo &&
|
||||
m.Payload.ToObject<ProcessStartInfo>().FileName == _processStartInfo.FileName &&
|
||||
m.Payload.ToObject<ProcessStartInfo>().Arguments == _processStartInfo.Arguments))).Verifiable();
|
||||
|
||||
_testGetTestRunnerProcessStartInfoMessageHandler.HandleMessage(
|
||||
_dotnetTestMock.Object,
|
||||
_validMessage);
|
||||
|
||||
_adapterChannelMock.Verify();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_creates_a_new_reporting_channel()
|
||||
{
|
||||
_testGetTestRunnerProcessStartInfoMessageHandler.HandleMessage(
|
||||
_dotnetTestMock.Object,
|
||||
_validMessage);
|
||||
|
||||
_reportingChannelFactoryMock.Verify(r => r.CreateChannelWithAnyAvailablePort(), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_makes_dotnet_test_listen_on_the_test_runner_port_for_messages_when_it_handles_the_message()
|
||||
{
|
||||
_testGetTestRunnerProcessStartInfoMessageHandler.HandleMessage(
|
||||
_dotnetTestMock.Object,
|
||||
_validMessage);
|
||||
|
||||
_dotnetTestMock.Verify(d => d.StartListeningTo(_testRunnerChannelMock.Object), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_passes_the_right_arguments_to_the_run_tests_arguments_builder()
|
||||
{
|
||||
_testGetTestRunnerProcessStartInfoMessageHandler.HandleMessage(
|
||||
_dotnetTestMock.Object,
|
||||
_validMessage);
|
||||
|
||||
_argumentsBuilder.Should().NotBeNull();
|
||||
|
||||
var arguments = _argumentsBuilder.BuildArguments();
|
||||
|
||||
arguments.Should().Contain("--port", $"{TestRunnerPort}");
|
||||
arguments.Should().Contain($"{AssemblyUnderTest}");
|
||||
arguments.Should().Contain("--test", "test1");
|
||||
arguments.Should().Contain("--test", "test2");
|
||||
}
|
||||
}
|
||||
}
|
106
test/dotnet-test.UnitTests/GivenATestRunner.cs
Normal file
106
test/dotnet-test.UnitTests/GivenATestRunner.cs
Normal file
|
@ -0,0 +1,106 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
using FluentAssertions;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.Tools.Test;
|
||||
using Moq;
|
||||
using NuGet.Frameworks;
|
||||
using Xunit;
|
||||
using Newtonsoft.Json;
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.Dotnet.Tools.Test.Tests
|
||||
{
|
||||
public class GivenATestRunner
|
||||
{
|
||||
private Mock<ICommand> _commandMock;
|
||||
private Mock<ICommandFactory> _commandFactoryMock;
|
||||
private Mock<ITestRunnerArgumentsBuilder> _argumentsBuilderMock;
|
||||
private string _runner = "runner";
|
||||
private string[] _testRunnerArguments;
|
||||
|
||||
public GivenATestRunner()
|
||||
{
|
||||
_testRunnerArguments = new[] {"assembly.dll", "--list", "--designtime"};
|
||||
|
||||
_commandMock = new Mock<ICommand>();
|
||||
_commandMock.Setup(c => c.CommandName).Returns(_runner);
|
||||
_commandMock.Setup(c => c.CommandArgs).Returns(string.Join(" ", _testRunnerArguments));
|
||||
_commandMock.Setup(c => c.OnOutputLine(It.IsAny<Action<string>>())).Returns(_commandMock.Object);
|
||||
|
||||
_argumentsBuilderMock = new Mock<ITestRunnerArgumentsBuilder>();
|
||||
_argumentsBuilderMock.Setup(a => a.BuildArguments())
|
||||
.Returns(_testRunnerArguments);
|
||||
|
||||
_commandFactoryMock = new Mock<ICommandFactory>();
|
||||
_commandFactoryMock.Setup(c => c.Create(
|
||||
_runner,
|
||||
_testRunnerArguments,
|
||||
new NuGetFramework("DNXCore", Version.Parse("5.0")),
|
||||
null)).Returns(_commandMock.Object).Verifiable();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_creates_a_command_using_the_right_parameters()
|
||||
{
|
||||
var testRunner = new TestRunner(_runner, _commandFactoryMock.Object, _argumentsBuilderMock.Object);
|
||||
|
||||
testRunner.RunTestCommand();
|
||||
|
||||
_commandFactoryMock.Verify();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_executes_the_command()
|
||||
{
|
||||
var testRunner = new TestRunner(_runner, _commandFactoryMock.Object, _argumentsBuilderMock.Object);
|
||||
|
||||
testRunner.RunTestCommand();
|
||||
|
||||
_commandMock.Verify(c => c.Execute(), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_throws_TestRunnerOperationFailedException_when_the_returns_return_an_error_code()
|
||||
{
|
||||
_commandMock.Setup(c => c.Execute()).Returns(new CommandResult(null, 1, null, null));
|
||||
|
||||
var testRunner = new TestRunner(_runner, _commandFactoryMock.Object, _argumentsBuilderMock.Object);
|
||||
|
||||
Action action = () => testRunner.RunTestCommand();
|
||||
|
||||
action.ShouldThrow<TestRunnerOperationFailedException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_executes_the_command_when_RunTestCommand_is_called()
|
||||
{
|
||||
var testResult = new Message
|
||||
{
|
||||
MessageType = "Irrelevant",
|
||||
Payload = JToken.FromObject("Irrelevant")
|
||||
};
|
||||
|
||||
var testRunner = new TestRunner(_runner, _commandFactoryMock.Object, _argumentsBuilderMock.Object);
|
||||
|
||||
testRunner.RunTestCommand();
|
||||
|
||||
_commandMock.Verify(c => c.Execute(), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_returns_a_ProcessStartInfo_object_with_the_right_parameters_to_execute_the_test_command()
|
||||
{
|
||||
var testRunner = new TestRunner(_runner, _commandFactoryMock.Object, _argumentsBuilderMock.Object);
|
||||
|
||||
var testCommandProcessStartInfo = testRunner.GetProcessStartInfo();
|
||||
|
||||
testCommandProcessStartInfo.FileName.Should().Be(_runner);
|
||||
testCommandProcessStartInfo.Arguments.Should().Be(string.Join(" ", _testRunnerArguments));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using FluentAssertions;
|
||||
using Microsoft.DotNet.Tools.Test;
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
using Moq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.Dotnet.Tools.Test.Tests
|
||||
{
|
||||
public class GivenATestRunnerTestCompletedMessageHandler
|
||||
{
|
||||
private Mock<IDotnetTest> _dotnetTestAtTestDiscoveryStartedMock;
|
||||
private Mock<IDotnetTest> _dotnetTestAtTestExecutionStartedMock;
|
||||
private Mock<IReportingChannel> _adapterChannelMock;
|
||||
|
||||
private Message _validMessage;
|
||||
private TestRunnerTestCompletedMessageHandler _testRunnerTestCompletedMessageHandler;
|
||||
|
||||
public GivenATestRunnerTestCompletedMessageHandler()
|
||||
{
|
||||
_dotnetTestAtTestDiscoveryStartedMock = new Mock<IDotnetTest>();
|
||||
_dotnetTestAtTestDiscoveryStartedMock.Setup(d => d.State).Returns(DotnetTestState.TestDiscoveryStarted);
|
||||
|
||||
_dotnetTestAtTestExecutionStartedMock = new Mock<IDotnetTest>();
|
||||
_dotnetTestAtTestExecutionStartedMock.Setup(d => d.State).Returns(DotnetTestState.TestExecutionStarted);
|
||||
|
||||
_adapterChannelMock = new Mock<IReportingChannel>();
|
||||
|
||||
_validMessage = new Message
|
||||
{
|
||||
MessageType = TestMessageTypes.TestRunnerTestCompleted
|
||||
};
|
||||
|
||||
_testRunnerTestCompletedMessageHandler =
|
||||
new TestRunnerTestCompletedMessageHandler(_adapterChannelMock.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_returns_NoOp_if_the_dotnet_test_state_is_not_TestDiscoveryStarted_or_TestExecutionStarted()
|
||||
{
|
||||
var dotnetTestMock = new Mock<IDotnetTest>();
|
||||
dotnetTestMock.Setup(d => d.State).Returns(DotnetTestState.Terminated);
|
||||
|
||||
var nextState = _testRunnerTestCompletedMessageHandler.HandleMessage(
|
||||
dotnetTestMock.Object,
|
||||
_validMessage);
|
||||
|
||||
nextState.Should().Be(DotnetTestState.NoOp);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_returns_NoOp_if_the_message_is_not_TestRunnerTestCompleted_when_state_is_TestDiscoveryStarted()
|
||||
{
|
||||
var nextState = _testRunnerTestCompletedMessageHandler.HandleMessage(
|
||||
_dotnetTestAtTestDiscoveryStartedMock.Object,
|
||||
new Message { MessageType = "Something different from TestDiscovery.Start" });
|
||||
|
||||
nextState.Should().Be(DotnetTestState.NoOp);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_returns_NoOp_if_the_message_is_not_TestRunnerTestCompleted_when_state_is_TestExecutionStarted()
|
||||
{
|
||||
var nextState = _testRunnerTestCompletedMessageHandler.HandleMessage(
|
||||
_dotnetTestAtTestExecutionStartedMock.Object,
|
||||
new Message { MessageType = "Something different from TestDiscovery.Start" });
|
||||
|
||||
nextState.Should().Be(DotnetTestState.NoOp);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_returns_TestDiscoveryCompleted_when_it_handles_the_message_and_current_state_is_TestDiscoveryStarted()
|
||||
{
|
||||
var nextState = _testRunnerTestCompletedMessageHandler.HandleMessage(
|
||||
_dotnetTestAtTestDiscoveryStartedMock.Object,
|
||||
_validMessage);
|
||||
|
||||
nextState.Should().Be(DotnetTestState.TestDiscoveryCompleted);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_sends_a_TestDiscoveryCompleted_when_it_handles_the_message_and_current_state_is_TestDiscoveryStarted()
|
||||
{
|
||||
_adapterChannelMock
|
||||
.Setup(a => a.Send(It.Is<Message>(m => m.MessageType == TestMessageTypes.TestDiscoveryCompleted)))
|
||||
.Verifiable();
|
||||
|
||||
_testRunnerTestCompletedMessageHandler.HandleMessage(
|
||||
_dotnetTestAtTestDiscoveryStartedMock.Object,
|
||||
_validMessage);
|
||||
|
||||
_adapterChannelMock.Verify();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_returns_TestExecutionCompleted_when_it_handles_the_message_and_current_state_is_TestExecutionStarted()
|
||||
{
|
||||
var nextState = _testRunnerTestCompletedMessageHandler.HandleMessage(
|
||||
_dotnetTestAtTestExecutionStartedMock.Object,
|
||||
_validMessage);
|
||||
|
||||
nextState.Should().Be(DotnetTestState.TestExecutionCompleted);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_sends_a_TestExecutionCompleted_when_it_handles_the_message_and_current_state_is_TestExecutionStarted()
|
||||
{
|
||||
_adapterChannelMock
|
||||
.Setup(a => a.Send(It.Is<Message>(m => m.MessageType == TestMessageTypes.TestExecutionCompleted)))
|
||||
.Verifiable();
|
||||
|
||||
_testRunnerTestCompletedMessageHandler.HandleMessage(
|
||||
_dotnetTestAtTestExecutionStartedMock.Object,
|
||||
_validMessage);
|
||||
|
||||
_adapterChannelMock.Verify();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using FluentAssertions;
|
||||
using Microsoft.DotNet.Tools.Test;
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
using Moq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.Dotnet.Tools.Test.Tests
|
||||
{
|
||||
public class GivenATestRunnerTestFoundMessageHandler
|
||||
{
|
||||
private Mock<IDotnetTest> _dotnetTestMock;
|
||||
private Mock<IReportingChannel> _adapterChannelMock;
|
||||
|
||||
private Message _validMessage;
|
||||
private TestRunnerTestFoundMessageHandler _testRunnerTestFoundMessageHandler;
|
||||
|
||||
public GivenATestRunnerTestFoundMessageHandler()
|
||||
{
|
||||
_dotnetTestMock = new Mock<IDotnetTest>();
|
||||
_dotnetTestMock.Setup(d => d.State).Returns(DotnetTestState.TestDiscoveryStarted);
|
||||
|
||||
_adapterChannelMock = new Mock<IReportingChannel>();
|
||||
|
||||
_validMessage = new Message
|
||||
{
|
||||
MessageType = TestMessageTypes.TestRunnerTestFound,
|
||||
Payload = JToken.FromObject("testFound")
|
||||
};
|
||||
|
||||
_testRunnerTestFoundMessageHandler = new TestRunnerTestFoundMessageHandler(_adapterChannelMock.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_returns_NoOp_if_the_dotnet_test_state_is_not_TestDiscoveryStarted()
|
||||
{
|
||||
var dotnetTestMock = new Mock<IDotnetTest>();
|
||||
dotnetTestMock.Setup(d => d.State).Returns(DotnetTestState.Terminated);
|
||||
|
||||
var nextState = _testRunnerTestFoundMessageHandler.HandleMessage(
|
||||
dotnetTestMock.Object,
|
||||
_validMessage);
|
||||
|
||||
nextState.Should().Be(DotnetTestState.NoOp);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_returns_NoOp_if_the_message_is_not_TestRunnerTestFound()
|
||||
{
|
||||
var nextState = _testRunnerTestFoundMessageHandler.HandleMessage(
|
||||
_dotnetTestMock.Object,
|
||||
new Message { MessageType = "Something different from TestDiscovery.Start" });
|
||||
|
||||
nextState.Should().Be(DotnetTestState.NoOp);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_returns_TestDiscoveryStarted_when_it_handles_the_message()
|
||||
{
|
||||
var nextState = _testRunnerTestFoundMessageHandler.HandleMessage(
|
||||
_dotnetTestMock.Object,
|
||||
_validMessage);
|
||||
|
||||
nextState.Should().Be(DotnetTestState.TestDiscoveryStarted);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_sends_the_payload_of_the_message_when_it_handles_the_message()
|
||||
{
|
||||
_adapterChannelMock.Setup(a => a.Send(It.Is<Message>(m =>
|
||||
m.MessageType == TestMessageTypes.TestDiscoveryTestFound &&
|
||||
m.Payload.ToObject<string>() == _validMessage.Payload.ToObject<string>()))).Verifiable();
|
||||
|
||||
_testRunnerTestFoundMessageHandler.HandleMessage(
|
||||
_dotnetTestMock.Object,
|
||||
_validMessage);
|
||||
|
||||
_adapterChannelMock.Verify();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using FluentAssertions;
|
||||
using Microsoft.DotNet.Tools.Test;
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
using Moq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.Dotnet.Tools.Test.Tests
|
||||
{
|
||||
public class GivenATestRunnerTestResultMessageHandler
|
||||
{
|
||||
private Mock<IDotnetTest> _dotnetTestMock;
|
||||
private Mock<IReportingChannel> _adapterChannelMock;
|
||||
|
||||
private Message _validMessage;
|
||||
private TestRunnerTestResultMessageHandler _testRunnerTestResultMessageHandler;
|
||||
|
||||
public GivenATestRunnerTestResultMessageHandler()
|
||||
{
|
||||
_dotnetTestMock = new Mock<IDotnetTest>();
|
||||
_dotnetTestMock.Setup(d => d.State).Returns(DotnetTestState.TestExecutionStarted);
|
||||
|
||||
_adapterChannelMock = new Mock<IReportingChannel>();
|
||||
|
||||
_validMessage = new Message
|
||||
{
|
||||
MessageType = TestMessageTypes.TestRunnerTestResult,
|
||||
Payload = JToken.FromObject("testFound")
|
||||
};
|
||||
|
||||
_testRunnerTestResultMessageHandler = new TestRunnerTestResultMessageHandler(_adapterChannelMock.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_returns_NoOp_if_the_dotnet_test_state_is_not_TestExecutionStarted()
|
||||
{
|
||||
var dotnetTestMock = new Mock<IDotnetTest>();
|
||||
dotnetTestMock.Setup(d => d.State).Returns(DotnetTestState.Terminated);
|
||||
|
||||
var nextState = _testRunnerTestResultMessageHandler.HandleMessage(
|
||||
dotnetTestMock.Object,
|
||||
_validMessage);
|
||||
|
||||
nextState.Should().Be(DotnetTestState.NoOp);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_returns_NoOp_if_the_message_is_not_TestRunnerTestResult()
|
||||
{
|
||||
var nextState = _testRunnerTestResultMessageHandler.HandleMessage(
|
||||
_dotnetTestMock.Object,
|
||||
new Message { MessageType = "Something different from TestRunner.TestResult" });
|
||||
|
||||
nextState.Should().Be(DotnetTestState.NoOp);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_returns_TestExecutionStarted_when_it_handles_the_message()
|
||||
{
|
||||
var nextState = _testRunnerTestResultMessageHandler.HandleMessage(
|
||||
_dotnetTestMock.Object,
|
||||
_validMessage);
|
||||
|
||||
nextState.Should().Be(DotnetTestState.TestExecutionStarted);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_sends_the_payload_of_the_message_when_it_handles_the_message()
|
||||
{
|
||||
_adapterChannelMock.Setup(a => a.Send(It.Is<Message>(m =>
|
||||
m.MessageType == TestMessageTypes.TestExecutionTestResult &&
|
||||
m.Payload.ToObject<string>() == _validMessage.Payload.ToObject<string>()))).Verifiable();
|
||||
|
||||
_testRunnerTestResultMessageHandler.HandleMessage(
|
||||
_dotnetTestMock.Object,
|
||||
_validMessage);
|
||||
|
||||
_adapterChannelMock.Verify();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using FluentAssertions;
|
||||
using Microsoft.DotNet.Tools.Test;
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
using Moq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.Dotnet.Tools.Test.Tests
|
||||
{
|
||||
public class GivenATestRunnerTestStartedMessageHandler
|
||||
{
|
||||
private Mock<IDotnetTest> _dotnetTestMock;
|
||||
private Mock<IReportingChannel> _adapterChannelMock;
|
||||
|
||||
private Message _validMessage;
|
||||
private TestRunnerTestStartedMessageHandler _testRunnerTestStartedMessageHandler;
|
||||
|
||||
public GivenATestRunnerTestStartedMessageHandler()
|
||||
{
|
||||
_dotnetTestMock = new Mock<IDotnetTest>();
|
||||
_dotnetTestMock.Setup(d => d.State).Returns(DotnetTestState.TestExecutionSentTestRunnerProcessStartInfo);
|
||||
|
||||
_adapterChannelMock = new Mock<IReportingChannel>();
|
||||
|
||||
_validMessage = new Message
|
||||
{
|
||||
MessageType = TestMessageTypes.TestRunnerTestStarted,
|
||||
Payload = JToken.FromObject("testFound")
|
||||
};
|
||||
|
||||
_testRunnerTestStartedMessageHandler =
|
||||
new TestRunnerTestStartedMessageHandler(_adapterChannelMock.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_returns_NoOp_if_the_dotnet_test_state_is_not_TestExecutionSentTestRunnerProcessStartInfo()
|
||||
{
|
||||
var dotnetTestMock = new Mock<IDotnetTest>();
|
||||
dotnetTestMock.Setup(d => d.State).Returns(DotnetTestState.Terminated);
|
||||
|
||||
var nextState = _testRunnerTestStartedMessageHandler.HandleMessage(
|
||||
dotnetTestMock.Object,
|
||||
_validMessage);
|
||||
|
||||
nextState.Should().Be(DotnetTestState.NoOp);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_returns_NoOp_if_the_message_is_not_TestRunnerTestStarted()
|
||||
{
|
||||
var nextState = _testRunnerTestStartedMessageHandler.HandleMessage(
|
||||
_dotnetTestMock.Object,
|
||||
new Message { MessageType = "Something different from TestRunner.TestStart" });
|
||||
|
||||
nextState.Should().Be(DotnetTestState.NoOp);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_returns_TestExecutionStarted_when_it_handles_the_message()
|
||||
{
|
||||
var nextState = _testRunnerTestStartedMessageHandler.HandleMessage(
|
||||
_dotnetTestMock.Object,
|
||||
_validMessage);
|
||||
|
||||
nextState.Should().Be(DotnetTestState.TestExecutionStarted);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_sends_a_TestExecutionTestStarted_when_it_handles_the_message()
|
||||
{
|
||||
_adapterChannelMock
|
||||
.Setup(a => a.Send(It.Is<Message>(m => m.MessageType == TestMessageTypes.TestExecutionStarted)))
|
||||
.Verifiable();
|
||||
|
||||
_testRunnerTestStartedMessageHandler.HandleMessage(
|
||||
_dotnetTestMock.Object,
|
||||
_validMessage);
|
||||
|
||||
_adapterChannelMock.Verify();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_sends_the_payload_of_the_message_when_it_handles_the_message()
|
||||
{
|
||||
_adapterChannelMock.Setup(a => a.Send(It.Is<Message>(m =>
|
||||
m.MessageType == TestMessageTypes.TestExecutionStarted &&
|
||||
m.Payload.ToObject<string>() == _validMessage.Payload.ToObject<string>()))).Verifiable();
|
||||
|
||||
_testRunnerTestStartedMessageHandler.HandleMessage(
|
||||
_dotnetTestMock.Object,
|
||||
_validMessage);
|
||||
|
||||
_adapterChannelMock.Verify();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using FluentAssertions;
|
||||
using Microsoft.DotNet.Tools.Test;
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.Dotnet.Tools.Test.Tests
|
||||
{
|
||||
public class GivenATestSessionTerminateMessageHandler
|
||||
{
|
||||
private DotnetTestState _nextState;
|
||||
private Mock<ITestMessagesCollection> _testMessagesCollectionMock;
|
||||
|
||||
public GivenATestSessionTerminateMessageHandler()
|
||||
{
|
||||
var reportingChannel = new Mock<IReportingChannel>();
|
||||
_testMessagesCollectionMock = new Mock<ITestMessagesCollection>();
|
||||
var dotnetTestMock = new Mock<IDotnetTest>();
|
||||
var messageHandler = new TestSessionTerminateMessageHandler(_testMessagesCollectionMock.Object);
|
||||
|
||||
_nextState = messageHandler.HandleMessage(dotnetTestMock.Object, new Message
|
||||
{
|
||||
MessageType = TestMessageTypes.TestSessionTerminate
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_always_returns_the_terminated_state_idependent_of_the_state_passed_to_it()
|
||||
{
|
||||
_nextState.Should().Be(DotnetTestState.Terminated);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_calls_drain_on_the_test_messages()
|
||||
{
|
||||
_testMessagesCollectionMock.Verify(tmc => tmc.Drain(), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
37
test/dotnet-test.UnitTests/GivenAUnknownMessageHandler.cs
Normal file
37
test/dotnet-test.UnitTests/GivenAUnknownMessageHandler.cs
Normal file
|
@ -0,0 +1,37 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.DotNet.Tools.Test;
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
using FluentAssertions;
|
||||
|
||||
namespace Microsoft.Dotnet.Tools.Test.Tests
|
||||
{
|
||||
public class GivenAUnknownMessageHandler
|
||||
{
|
||||
[Fact]
|
||||
public void It_throws_InvalidOperationException_and_sends_an_error_when_the_message_is_not_handled()
|
||||
{
|
||||
const string expectedError = "No handler for message 'Test Message' when at state 'InitialState'";
|
||||
|
||||
var dotnetTestMock = new Mock<IDotnetTest>();
|
||||
dotnetTestMock.Setup(d => d.State).Returns(DotnetTestState.InitialState);
|
||||
|
||||
var reportingChannel = new Mock<IReportingChannel>();
|
||||
reportingChannel.Setup(r => r.SendError(expectedError)).Verifiable();
|
||||
|
||||
var unknownMessageHandler = new UnknownMessageHandler(reportingChannel.Object);
|
||||
|
||||
Action action = () => unknownMessageHandler.HandleMessage(
|
||||
dotnetTestMock.Object,
|
||||
new Message { MessageType = "Test Message" });
|
||||
|
||||
action.ShouldThrow<InvalidOperationException>().WithMessage(expectedError);
|
||||
|
||||
reportingChannel.Verify();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using FluentAssertions;
|
||||
using Microsoft.DotNet.Tools.Test;
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
using Moq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.Dotnet.Tools.Test.Tests
|
||||
{
|
||||
public class GivenAVersionCheckMessageHandler
|
||||
{
|
||||
private Mock<IReportingChannel> _reportingChannelMock;
|
||||
private VersionCheckMessageHandler _versionCheckMessageHandler;
|
||||
private Message _validMessage;
|
||||
private IDotnetTest _dotnetTestAtInitialState;
|
||||
|
||||
public GivenAVersionCheckMessageHandler()
|
||||
{
|
||||
_reportingChannelMock = new Mock<IReportingChannel>();
|
||||
_versionCheckMessageHandler = new VersionCheckMessageHandler(_reportingChannelMock.Object);
|
||||
|
||||
_validMessage = new Message
|
||||
{
|
||||
MessageType = TestMessageTypes.VersionCheck,
|
||||
Payload = JToken.FromObject(new ProtocolVersionMessage
|
||||
{
|
||||
Version = 99
|
||||
})
|
||||
};
|
||||
|
||||
var dotnetTestAtInitialStateMock = new Mock<IDotnetTest>();
|
||||
dotnetTestAtInitialStateMock.Setup(d => d.State).Returns(DotnetTestState.InitialState);
|
||||
_dotnetTestAtInitialState = dotnetTestAtInitialStateMock.Object;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_returns_NoOp_if_the_dotnet_test_state_is_not_initial()
|
||||
{
|
||||
var dotnetTestMock = new Mock<IDotnetTest>();
|
||||
dotnetTestMock.Setup(d => d.State).Returns(DotnetTestState.Terminated);
|
||||
|
||||
var nextState = _versionCheckMessageHandler.HandleMessage(
|
||||
dotnetTestMock.Object,
|
||||
new Message {MessageType = TestMessageTypes.VersionCheck});
|
||||
|
||||
nextState.Should().Be(DotnetTestState.NoOp);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_returns_NoOp_if_the_message_is_not_VersionCheck()
|
||||
{
|
||||
var nextState = _versionCheckMessageHandler.HandleMessage(
|
||||
_dotnetTestAtInitialState,
|
||||
new Message { MessageType = "Something different from ProtocolVersion" });
|
||||
|
||||
nextState.Should().Be(DotnetTestState.NoOp);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_returns_VersionCheckCompleted_when_it_handles_the_message()
|
||||
{
|
||||
var nextState = _versionCheckMessageHandler.HandleMessage(_dotnetTestAtInitialState, _validMessage);
|
||||
|
||||
nextState.Should().Be(DotnetTestState.VersionCheckCompleted);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_returns_a_ProtocolVersion_with_the_SupportedVersion_when_it_handles_the_message()
|
||||
{
|
||||
_reportingChannelMock.Setup(r =>
|
||||
r.Send(It.Is<Message>(m =>
|
||||
m.MessageType == TestMessageTypes.VersionCheck &&
|
||||
m.Payload.ToObject<ProtocolVersionMessage>().Version == 1))).Verifiable();
|
||||
|
||||
_versionCheckMessageHandler.HandleMessage(_dotnetTestAtInitialState, _validMessage);
|
||||
|
||||
_reportingChannelMock.Verify();
|
||||
}
|
||||
}
|
||||
}
|
67
test/dotnet-test.UnitTests/GivenThatWeWantToDiscoverTests.cs
Normal file
67
test/dotnet-test.UnitTests/GivenThatWeWantToDiscoverTests.cs
Normal file
|
@ -0,0 +1,67 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Microsoft.DotNet.Tools.Test;
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
using Moq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.Dotnet.Tools.Test.Tests
|
||||
{
|
||||
public class GivenThatWeWantToDiscoverTests
|
||||
{
|
||||
[Fact]
|
||||
public void Dotnet_test_handles_and_sends_all_the_right_messages()
|
||||
{
|
||||
var dotnetTestMessageScenario = new DotnetTestMessageScenario();
|
||||
|
||||
dotnetTestMessageScenario.TestRunnerMock
|
||||
.Setup(t => t.RunTestCommand())
|
||||
.Callback(() => dotnetTestMessageScenario.TestRunnerChannelMock.Raise(
|
||||
t => t.MessageReceived += null,
|
||||
dotnetTestMessageScenario.DotnetTestUnderTest,
|
||||
new Message
|
||||
{
|
||||
MessageType = TestMessageTypes.TestRunnerTestFound,
|
||||
Payload = JToken.FromObject("testFound")
|
||||
}))
|
||||
.Verifiable();
|
||||
|
||||
dotnetTestMessageScenario.AdapterChannelMock
|
||||
.Setup(a => a.Send(It.Is<Message>(m => m.MessageType == TestMessageTypes.VersionCheck)))
|
||||
.Callback(() => dotnetTestMessageScenario.AdapterChannelMock.Raise(
|
||||
r => r.MessageReceived += null,
|
||||
dotnetTestMessageScenario.DotnetTestUnderTest,
|
||||
new Message
|
||||
{
|
||||
MessageType = TestMessageTypes.TestDiscoveryStart
|
||||
}))
|
||||
.Verifiable();
|
||||
|
||||
dotnetTestMessageScenario.AdapterChannelMock
|
||||
.Setup(a => a.Send(It.Is<Message>(m => m.MessageType == TestMessageTypes.TestDiscoveryTestFound)))
|
||||
.Callback(() => dotnetTestMessageScenario.TestRunnerChannelMock.Raise(
|
||||
t => t.MessageReceived += null,
|
||||
dotnetTestMessageScenario.DotnetTestUnderTest,
|
||||
new Message
|
||||
{
|
||||
MessageType = TestMessageTypes.TestRunnerTestCompleted
|
||||
}))
|
||||
.Verifiable();
|
||||
|
||||
dotnetTestMessageScenario.AdapterChannelMock
|
||||
.Setup(a => a.Send(It.Is<Message>(m => m.MessageType == TestMessageTypes.TestDiscoveryCompleted)))
|
||||
.Callback(() => dotnetTestMessageScenario.AdapterChannelMock.Raise(
|
||||
r => r.MessageReceived += null,
|
||||
dotnetTestMessageScenario.DotnetTestUnderTest,
|
||||
new Message
|
||||
{
|
||||
MessageType = TestMessageTypes.TestSessionTerminate
|
||||
}))
|
||||
.Verifiable();
|
||||
|
||||
dotnetTestMessageScenario.Run();
|
||||
}
|
||||
}
|
||||
}
|
86
test/dotnet-test.UnitTests/GivenThatWeWantToRunTests.cs
Normal file
86
test/dotnet-test.UnitTests/GivenThatWeWantToRunTests.cs
Normal file
|
@ -0,0 +1,86 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System.Diagnostics;
|
||||
using Microsoft.DotNet.Tools.Test;
|
||||
using Microsoft.Extensions.Testing.Abstractions;
|
||||
using Moq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.Dotnet.Tools.Test.Tests
|
||||
{
|
||||
public class GivenThatWeWantToRunTests
|
||||
{
|
||||
[Fact]
|
||||
public void Dotnet_test_handles_and_sends_all_the_right_messages()
|
||||
{
|
||||
var dotnetTestMessageScenario = new DotnetTestMessageScenario();
|
||||
|
||||
dotnetTestMessageScenario.TestRunnerMock
|
||||
.Setup(t => t.GetProcessStartInfo())
|
||||
.Returns(new ProcessStartInfo())
|
||||
.Verifiable();
|
||||
|
||||
dotnetTestMessageScenario.AdapterChannelMock
|
||||
.Setup(a => a.Send(It.Is<Message>(m => m.MessageType == TestMessageTypes.VersionCheck)))
|
||||
.Callback(() => dotnetTestMessageScenario.AdapterChannelMock.Raise(
|
||||
r => r.MessageReceived += null,
|
||||
dotnetTestMessageScenario.DotnetTestUnderTest,
|
||||
new Message
|
||||
{
|
||||
MessageType = TestMessageTypes.TestExecutionGetTestRunnerProcessStartInfo
|
||||
}))
|
||||
.Verifiable();
|
||||
|
||||
dotnetTestMessageScenario.AdapterChannelMock
|
||||
.Setup(a => a.Send(
|
||||
It.Is<Message>(m => m.MessageType == TestMessageTypes.TestExecutionTestRunnerProcessStartInfo)))
|
||||
.Callback(() => dotnetTestMessageScenario.TestRunnerChannelMock.Raise(
|
||||
t => t.MessageReceived += null,
|
||||
dotnetTestMessageScenario.DotnetTestUnderTest,
|
||||
new Message
|
||||
{
|
||||
MessageType = TestMessageTypes.TestRunnerTestStarted
|
||||
}))
|
||||
.Verifiable();
|
||||
|
||||
dotnetTestMessageScenario.AdapterChannelMock
|
||||
.Setup(a => a.Send(
|
||||
It.Is<Message>(m => m.MessageType == TestMessageTypes.TestExecutionStarted)))
|
||||
.Callback(() => dotnetTestMessageScenario.TestRunnerChannelMock.Raise(
|
||||
t => t.MessageReceived += null,
|
||||
dotnetTestMessageScenario.DotnetTestUnderTest,
|
||||
new Message
|
||||
{
|
||||
MessageType = TestMessageTypes.TestRunnerTestResult
|
||||
}))
|
||||
.Verifiable();
|
||||
|
||||
dotnetTestMessageScenario.AdapterChannelMock
|
||||
.Setup(a => a.Send(
|
||||
It.Is<Message>(m => m.MessageType == TestMessageTypes.TestExecutionTestResult)))
|
||||
.Callback(() => dotnetTestMessageScenario.TestRunnerChannelMock.Raise(
|
||||
t => t.MessageReceived += null,
|
||||
dotnetTestMessageScenario.DotnetTestUnderTest,
|
||||
new Message
|
||||
{
|
||||
MessageType = TestMessageTypes.TestRunnerTestCompleted
|
||||
}))
|
||||
.Verifiable();
|
||||
|
||||
dotnetTestMessageScenario.AdapterChannelMock
|
||||
.Setup(a => a.Send(It.Is<Message>(m => m.MessageType == TestMessageTypes.TestExecutionCompleted)))
|
||||
.Callback(() => dotnetTestMessageScenario.AdapterChannelMock.Raise(
|
||||
r => r.MessageReceived += null,
|
||||
dotnetTestMessageScenario.DotnetTestUnderTest,
|
||||
new Message
|
||||
{
|
||||
MessageType = TestMessageTypes.TestSessionTerminate
|
||||
}))
|
||||
.Verifiable();
|
||||
|
||||
dotnetTestMessageScenario.Run();
|
||||
}
|
||||
}
|
||||
}
|
18
test/dotnet-test.UnitTests/dotnet-test.UnitTests.xproj
Normal file
18
test/dotnet-test.UnitTests/dotnet-test.UnitTests.xproj
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0.24720" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.24720</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>857274ac-e741-4266-a7fd-14dee0c1cc96</ProjectGuid>
|
||||
<RootNamespace>Microsoft.Dotnet.Tools.Test.Tests</RootNamespace>
|
||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
23
test/dotnet-test.UnitTests/project.json
Normal file
23
test/dotnet-test.UnitTests/project.json
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"version": "1.0.0-*",
|
||||
|
||||
"dependencies": {
|
||||
"Newtonsoft.Json": "7.0.1",
|
||||
"NETStandard.Library": "1.0.0-rc2-23811",
|
||||
|
||||
"dotnet": { "target": "project" },
|
||||
|
||||
"xunit": "2.1.0",
|
||||
"dotnet-test-xunit": "1.0.0-dev-48273-16",
|
||||
"moq.netcore": "4.4.0-beta8",
|
||||
"FluentAssertions": "4.2.2"
|
||||
},
|
||||
|
||||
"frameworks": {
|
||||
"dnxcore50": {
|
||||
"imports": "portable-net45+win8"
|
||||
}
|
||||
},
|
||||
|
||||
"testRunner": "xunit"
|
||||
}
|
Loading…
Reference in a new issue