Merge pull request #1786 from livarcocc/tests_as_client

Modifying the reporting channels to make the AdapterChannel a client
This commit is contained in:
Livar 2016-03-15 16:37:26 -07:00
commit 1c9803d980
22 changed files with 536 additions and 84 deletions

View file

@ -1,6 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25020.0
VisualStudioVersion = 14.0.25029.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{ED2FE3E2-F7E7-4389-8231-B65123F2076F}"
EndProject
@ -76,6 +77,8 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.TestFramew
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "dotnet-test.UnitTests", "test\dotnet-test.UnitTests\dotnet-test.UnitTests.xproj", "{857274AC-E741-4266-A7FD-14DEE0C1CC96}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "dotnet-test.Tests", "test\dotnet-test.Tests\dotnet-test.Tests.xproj", "{60C33D0A-A5D8-4AB0-9956-1F804654DF05}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -472,22 +475,6 @@ Global
{0745410A-6629-47EB-AAB5-08D6288CAD72}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{0745410A-6629-47EB-AAB5-08D6288CAD72}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{0745410A-6629-47EB-AAB5-08D6288CAD72}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.Debug|x64.ActiveCfg = Debug|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.Debug|x64.Build.0 = Debug|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.Release|Any CPU.Build.0 = Release|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.Release|x64.ActiveCfg = Release|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.Release|x64.Build.0 = Release|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
{0B31C336-149D-471A-B7B1-27B0F1E80F83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0B31C336-149D-471A-B7B1-27B0F1E80F83}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0B31C336-149D-471A-B7B1-27B0F1E80F83}.Debug|x64.ActiveCfg = Debug|Any CPU
@ -504,22 +491,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
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.Debug|x64.ActiveCfg = Debug|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.Debug|x64.Build.0 = Debug|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.Release|Any CPU.Build.0 = Release|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.Release|x64.ActiveCfg = Release|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.Release|x64.Build.0 = Release|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{4A4711D8-4312-49FC-87B5-4F183F4C6A51}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
{0724ED7C-56E3-4604-9970-25E600611383}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0724ED7C-56E3-4604-9970-25E600611383}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0724ED7C-56E3-4604-9970-25E600611383}.Debug|x64.ActiveCfg = Debug|Any CPU
@ -536,6 +523,38 @@ Global
{0724ED7C-56E3-4604-9970-25E600611383}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{0724ED7C-56E3-4604-9970-25E600611383}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{0724ED7C-56E3-4604-9970-25E600611383}.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
{60C33D0A-A5D8-4AB0-9956-1F804654DF05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{60C33D0A-A5D8-4AB0-9956-1F804654DF05}.Debug|Any CPU.Build.0 = Debug|Any CPU
{60C33D0A-A5D8-4AB0-9956-1F804654DF05}.Debug|x64.ActiveCfg = Debug|Any CPU
{60C33D0A-A5D8-4AB0-9956-1F804654DF05}.Debug|x64.Build.0 = Debug|Any CPU
{60C33D0A-A5D8-4AB0-9956-1F804654DF05}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
{60C33D0A-A5D8-4AB0-9956-1F804654DF05}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
{60C33D0A-A5D8-4AB0-9956-1F804654DF05}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{60C33D0A-A5D8-4AB0-9956-1F804654DF05}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{60C33D0A-A5D8-4AB0-9956-1F804654DF05}.Release|Any CPU.ActiveCfg = Release|Any CPU
{60C33D0A-A5D8-4AB0-9956-1F804654DF05}.Release|Any CPU.Build.0 = Release|Any CPU
{60C33D0A-A5D8-4AB0-9956-1F804654DF05}.Release|x64.ActiveCfg = Release|Any CPU
{60C33D0A-A5D8-4AB0-9956-1F804654DF05}.Release|x64.Build.0 = Release|Any CPU
{60C33D0A-A5D8-4AB0-9956-1F804654DF05}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
{60C33D0A-A5D8-4AB0-9956-1F804654DF05}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{60C33D0A-A5D8-4AB0-9956-1F804654DF05}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{60C33D0A-A5D8-4AB0-9956-1F804654DF05}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -565,11 +584,12 @@ Global
{DA8E0E9E-A6D6-4583-864C-8F40465E3A48} = {713CBFBB-5392-438D-B766-A9A585EF1BB8}
{0138CB8F-4AA9-4029-A21E-C07C30F425BA} = {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}
{4A4711D8-4312-49FC-87B5-4F183F4C6A51} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
{0724ED7C-56E3-4604-9970-25E600611383} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F}
{857274AC-E741-4266-A7FD-14DEE0C1CC96} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
{60C33D0A-A5D8-4AB0-9956-1F804654DF05} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,22 @@
// 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 Xunit;
namespace FakeTests
{
public class GivenThatIWantSomeFakeTests
{
[Fact]
public void It_succeeds()
{
Assert.True(true);
}
[Fact]
public void It_fails()
{
Assert.True(false);
}
}
}

View file

@ -0,0 +1,21 @@
{
"version": "1.0.0-*",
"dependencies": {
"NETStandard.Library": "1.5.0-rc2-23911",
"xunit": "2.1.0",
"dotnet-test-xunit": "1.0.0-dev-91790-12"
},
"frameworks": {
"netstandardapp1.5": {
"imports": [
"dnxcore50",
"portable-net45+win8"
]
}
},
"testRunner": "xunit"
}

View file

@ -36,7 +36,8 @@ namespace Microsoft.DotNet.Cli.Build
"Microsoft.DotNet.ProjectModel.Tests",
"Microsoft.Extensions.DependencyModel.Tests",
"ArgumentForwardingTests",
"dotnet-test.UnitTests"
"dotnet-test.UnitTests",
"dotnet-test.Tests"
};
[Target(nameof(PrepareTargets.Init), nameof(SetupTests), nameof(RestoreTests), nameof(BuildTests), nameof(RunTests), nameof(ValidateDependencies))]

View file

@ -41,7 +41,7 @@ namespace Microsoft.DotNet.Tools.Test
dotnetTest.StartListeningTo(testRunnerChannel);
testRunnerChannel.Accept();
testRunnerChannel.Connect();
var testRunner = _testRunnerFactory.CreateTestRunner(
new RunTestsArgumentsBuilder(dotnetTest.PathToAssemblyUnderTest, testRunnerChannel.Port, message));

View file

@ -55,7 +55,7 @@ namespace Microsoft.DotNet.Cli.Tools.Test
dotnetTest.StartListeningTo(testRunnerChannel);
testRunnerChannel.Accept();
testRunnerChannel.Connect();
var testRunner = _testRunnerFactory.CreateTestRunner(
new DiscoverTestsArgumentsBuilder(dotnetTest.PathToAssemblyUnderTest, testRunnerChannel.Port));

View file

@ -11,6 +11,7 @@ namespace Microsoft.DotNet.Tools.Test
public const string TestRunnerTestStarted = "TestExecution.TestStarted";
public const string TestRunnerTestCompleted = "TestRunner.TestCompleted";
public const string TestRunnerTestFound = "TestDiscovery.TestFound";
public const string TestSessionConnected = "TestSession.Connected";
public const string TestSessionTerminate = "TestSession.Terminate";
public const string VersionCheck = "ProtocolVersion";
public const string TestDiscoveryStart = "TestDiscovery.Start";

View file

@ -183,7 +183,7 @@ namespace Microsoft.DotNet.Tools.Test
dotnetTest.StartListeningTo(adapterChannel);
adapterChannel.Accept();
adapterChannel.Connect();
dotnetTest.StartHandlingMessages();
}

View file

@ -0,0 +1,43 @@
// 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.Net;
using System.Net.Sockets;
namespace Microsoft.DotNet.Tools.Test
{
public class AdapterReportingChannel : ReportingChannel
{
private readonly IPEndPoint _ipEndPoint;
public static AdapterReportingChannel ConnectTo(int port)
{
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
var ipEndPoint = new IPEndPoint(IPAddress.Loopback, port);
return new AdapterReportingChannel(socket, ipEndPoint);
}
private AdapterReportingChannel(Socket connectSocket, IPEndPoint ipEndPoint)
: base(connectSocket, ipEndPoint.Port)
{
_ipEndPoint = ipEndPoint;
}
public override void Connect()
{
Socket = ConnectSocket;
Socket.Connect(_ipEndPoint);
StartReadingMessages();
Send(new Message
{
MessageType = TestMessageTypes.TestSessionConnected
});
}
}
}

View file

@ -13,7 +13,7 @@ namespace Microsoft.DotNet.Tools.Test
int Port { get; }
void Accept();
void Connect();
void Send(Message message);

View file

@ -14,52 +14,26 @@ using Newtonsoft.Json.Linq;
namespace Microsoft.DotNet.Tools.Test
{
public class ReportingChannel : IReportingChannel
public abstract class ReportingChannel : IReportingChannel
{
public static ReportingChannel ListenOn(int port)
{
// This fixes the mono incompatibility but ties it to ipv4 connections
var listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listenSocket.Bind(new IPEndPoint(IPAddress.Loopback, port));
listenSocket.Listen(10);
return new ReportingChannel(listenSocket);
}
private BinaryWriter _writer;
private BinaryReader _reader;
private Socket _listenSocket;
private ReportingChannel(Socket listenSocket)
protected ReportingChannel(Socket connectSocket, int port)
{
_listenSocket = listenSocket;
Port = ((IPEndPoint)listenSocket.LocalEndPoint).Port;
ConnectSocket = connectSocket;
Port = port;
}
protected Socket Socket { get; set; }
public event EventHandler<Message> MessageReceived;
public Socket Socket { get; private set; }
public Socket ConnectSocket { get; }
public int Port { get; }
public void Accept()
{
new Thread(() =>
{
using (_listenSocket)
{
Socket = _listenSocket.Accept();
var stream = new NetworkStream(Socket);
_writer = new BinaryWriter(stream);
_reader = new BinaryReader(stream);
// Read incoming messages on the background thread
new Thread(ReadMessages) { IsBackground = true }.Start();
}
}) { IsBackground = true }.Start();
}
public abstract void Connect();
public void Send(Message message)
{
@ -104,6 +78,16 @@ namespace Microsoft.DotNet.Tools.Test
SendError(ex.ToString());
}
protected void StartReadingMessages()
{
var stream = new NetworkStream(Socket);
_writer = new BinaryWriter(stream);
_reader = new BinaryReader(stream);
// Read incoming messages on the background thread
new Thread(ReadMessages) { IsBackground = true }.Start();
}
private void ReadMessages()
{
while (true)
@ -140,10 +124,7 @@ namespace Microsoft.DotNet.Tools.Test
public void Dispose()
{
if (Socket != null)
{
Socket.Dispose();
}
Socket?.Dispose();
}
}
}

View file

@ -11,7 +11,7 @@ namespace Microsoft.DotNet.Tools.Test
public IReportingChannel CreateTestRunnerChannel()
{
var testRunnerChannel = ReportingChannel.ListenOn(0);
var testRunnerChannel = TestRunnerReportingChannel.ListenOn(0);
TestRunnerChannelCreated?.Invoke(this, testRunnerChannel);
@ -20,7 +20,7 @@ namespace Microsoft.DotNet.Tools.Test
public IReportingChannel CreateAdapterChannel(int port)
{
return ReportingChannel.ListenOn(port);
return AdapterReportingChannel.ConnectTo(port);
}
}
}

View file

@ -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 System.Net;
using System.Net.Sockets;
using System.Threading;
namespace Microsoft.DotNet.Tools.Test
{
public class TestRunnerReportingChannel : ReportingChannel
{
public static ReportingChannel ListenOn(int port)
{
// This fixes the mono incompatibility but ties it to ipv4 connections
var listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listenSocket.Bind(new IPEndPoint(IPAddress.Loopback, port));
listenSocket.Listen(10);
return new TestRunnerReportingChannel(listenSocket, ((IPEndPoint)listenSocket.LocalEndPoint));
}
private TestRunnerReportingChannel(Socket connectSocket, IPEndPoint ipEndPoint)
: base(connectSocket, ipEndPoint.Port)
{
}
public override void Connect()
{
new Thread(() =>
{
using (ConnectSocket)
{
Socket = ConnectSocket.Accept();
StartReadingMessages();
}
})
{ IsBackground = true }.Start();
}
}
}

View file

@ -58,7 +58,8 @@
"Microsoft.Win32.Registry": {
"version": "4.0.0-rc2-23911",
"exclude": "Compile"
}
},
"System.Net.NameResolution": "4.0.0-rc2-23911"
},
"frameworks": {
"netstandardapp1.5": {

View file

@ -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 Microsoft.DotNet.Cli.Utils;
namespace Microsoft.DotNet.Tools.Test.Utilities
{
public class DotnetTestCommand : TestCommand
{
public DotnetTestCommand() : base("dotnet")
{
}
public override CommandResult Execute(string args = "")
{
args = $"test {args}";
return base.Execute(args);
}
}
}

View file

@ -0,0 +1,177 @@
// 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.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.Extensions.Testing.Abstractions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Diagnostics;
namespace Microsoft.Dotnet.Tools.Test.Tests
{
public class Adapter : IDisposable
{
private readonly string _startMessage;
private BinaryWriter _writer;
private BinaryReader _reader;
private Socket _socket;
private Socket _listenSocket;
public IDictionary<string, List<Message>> Messages { get; }
public int Port { get; private set; }
public Adapter(string startMessage)
{
_startMessage = startMessage;
Messages = new Dictionary<string, List<Message>>();
_listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
var endpoint = new IPEndPoint(IPAddress.Loopback, 0);
_listenSocket.Bind(endpoint);
Port = ((IPEndPoint)_listenSocket.LocalEndPoint).Port;
}
public void Listen()
{
var listenThread = new Thread(() =>
{
using (_listenSocket)
{
_listenSocket.Listen(1);
_socket = _listenSocket.Accept();
}
var stream = new NetworkStream(_socket);
_writer = new BinaryWriter(stream);
_reader = new BinaryReader(stream);
ReadMessages();
})
{
IsBackground = true
};
listenThread.Start();
}
public void Send(string messageType)
{
lock (_writer)
{
_writer.Write(JsonConvert.SerializeObject(new
{
MessageType = messageType,
PayLoad = JToken.FromObject(new
{
})
}));
}
}
private void ReadMessages()
{
while (true)
{
try
{
var message = GetMessage();
StoreMessage(message);
if (HandleMessage(message))
{
break;
}
}
catch (Exception)
{
throw;
}
}
}
private void StoreMessage(Message message)
{
if (!Messages.ContainsKey(message.MessageType))
{
Messages.Add(message.MessageType, new List<Message>());
}
Messages[message.MessageType].Add(message);
}
private bool HandleMessage(Message message)
{
if (message.MessageType == "TestSession.Connected")
{
Send(_startMessage);
}
if (message.MessageType == "TestExecution.TestRunnerProcessStartInfo")
{
StartTestRunner(message.Payload.ToObject<TestStartInfo>());
}
if (message.MessageType == "TestDiscovery.Completed")
{
Send("TestSession.Terminate");
return true;
}
if (message.MessageType == "TestExecution.Completed")
{
Send("TestSession.Terminate");
return true;
}
return false;
}
private static void StartTestRunner(TestStartInfo testPsiInfo)
{
var testPsi = new ProcessStartInfo(testPsiInfo.FileName, testPsiInfo.Arguments);
testPsi.RedirectStandardOutput = true;
testPsi.UseShellExecute = false;
var testProcess = new Process
{
StartInfo = testPsi
};
var testProcessThread = new Thread(() => { testProcess.Start(); })
{
IsBackground = true
};
testProcessThread.Start();
}
private Message GetMessage()
{
var rawMessage = _reader.ReadString();
Console.WriteLine("\nRECEIVING MESSAGE:");
Console.WriteLine($"{rawMessage}");
Console.WriteLine($"==============================\n");
var message = JsonConvert.DeserializeObject<Message>(rawMessage);
return message;
}
public void Dispose()
{
_socket?.Dispose();
}
private class TestStartInfo
{
public string FileName { get; set; }
public string Arguments { get; set; }
}
}
}

View file

@ -0,0 +1,72 @@
// 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.ProjectModel;
using Microsoft.DotNet.Tools.Test.Utilities;
using System.IO;
using FluentAssertions;
using Xunit;
using Microsoft.Extensions.PlatformAbstractions;
using System.Linq;
namespace Microsoft.Dotnet.Tools.Test.Tests
{
public class GivenThatWeWantToUseDotnetTestE2EInDesignTime : TestBase
{
private string _projectFilePath;
private string _outputPath;
public GivenThatWeWantToUseDotnetTestE2EInDesignTime()
{
var testInstance = TestAssetsManager.CreateTestInstance("ProjectWithTests").WithLockFiles();
_projectFilePath = Path.Combine(testInstance.TestRoot, "project.json");
var contexts = ProjectContext.CreateContextForEachFramework(
_projectFilePath,
null,
PlatformServices.Default.Runtime.GetAllCandidateRuntimeIdentifiers());
var runtime = contexts.FirstOrDefault(c => !string.IsNullOrEmpty(c.RuntimeIdentifier))?.RuntimeIdentifier;
_outputPath = Path.Combine(testInstance.TestRoot, "bin", "Debug", DefaultFramework, runtime);
var buildCommand = new BuildCommand(_projectFilePath);
var result = buildCommand.Execute();
result.Should().Pass();
}
[WindowsOnlyFact]
public void It_discovers_two_tests_for_the_ProjectWithTests()
{
using (var adapter = new Adapter("TestDiscovery.Start"))
{
adapter.Listen();
var testCommand = new DotnetTestCommand();
var result = testCommand.Execute($"{_projectFilePath} -o {_outputPath} --port {adapter.Port}");
result.Should().Pass();
adapter.Messages["TestSession.Connected"].Count.Should().Be(1);
adapter.Messages["TestDiscovery.TestFound"].Count.Should().Be(2);
adapter.Messages["TestDiscovery.Completed"].Count.Should().Be(1);
}
}
[Fact]
public void It_runs_two_tests_for_the_ProjectWithTests()
{
using (var adapter = new Adapter("TestExecution.GetTestRunnerProcessStartInfo"))
{
adapter.Listen();
var testCommand = new DotnetTestCommand();
var result = testCommand.Execute($"{_projectFilePath} -o {_outputPath} --port {adapter.Port}");
result.Should().Pass();
adapter.Messages["TestSession.Connected"].Count.Should().Be(1);
adapter.Messages["TestExecution.TestRunnerProcessStartInfo"].Count.Should().Be(1);
adapter.Messages["TestExecution.TestStarted"].Count.Should().Be(2);
adapter.Messages["TestExecution.TestResult"].Count.Should().Be(2);
adapter.Messages["TestExecution.Completed"].Count.Should().Be(1);
}
}
}
}

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>60c33d0a-a5d8-4ab0-9956-1f804654df05</ProjectGuid>
<RootNamespace>Microsoft.Dotnet.Tools.Test.Tests</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

View file

@ -0,0 +1,33 @@
{
"version": "1.0.0-*",
"dependencies": {
"Newtonsoft.Json": "7.0.1",
"NETStandard.Library": "1.5.0-rc2-23911",
"Microsoft.DotNet.Tools.Tests.Utilities": { "target": "project" },
"Microsoft.DotNet.TestFramework": { "target": "project" },
"Microsoft.DotNet.ProjectModel": { "target": "project" },
"Microsoft.Extensions.Testing.Abstractions": { "target": "project" },
"System.Net.NameResolution": "4.0.0-rc2-23911",
"System.Net.Sockets": "4.1.0-rc2-23911",
"System.Runtime.Serialization.Primitives": "4.1.1-rc2-23911",
"xunit": "2.1.0",
"dotnet-test-xunit": "1.0.0-dev-91790-12"
},
"frameworks": {
"netstandardapp1.5": {
"imports": [
"dnxcore50",
"portable-net45+win8"
]
}
},
"content": [
"../../TestAssets/TestProjects/ProjectWithTests/**/*",
"../../TestAssets/TestProjects/global.json"
],
"testRunner": "xunit"
}

View file

@ -141,7 +141,7 @@ namespace Microsoft.Dotnet.Tools.Test.Tests
_dotnetTestMock.Object,
_validMessage);
_testRunnerChannelMock.Verify(t => t.Accept(), Times.Once);
_testRunnerChannelMock.Verify(t => t.Connect(), Times.Once);
}
[Fact]

View file

@ -161,7 +161,7 @@ namespace Microsoft.Dotnet.Tools.Test.Tests
_dotnetTestMock.Object,
_validMessage);
_testRunnerChannelMock.Verify(t => t.Accept(), Times.Once);
_testRunnerChannelMock.Verify(t => t.Connect(), Times.Once);
}
[Fact]