Renamed Socket classes to TcpSocket since that is all it is designed to handle at this point.

Migrated advancements from transport-protocol branch to master.
Added MemoryQueueBufferStream to buffer the stream data without moving it to another buffer.
Added new tools.
Added testing of via travis.
Translated all tests to nunit from xunit.
Removed Closing and Connecting from valid states as it was complicating the process.
Updated protobuf-net to 2.3.2.
Removed Port configuration
Renamed Ip configuration to Address.  Port is integrated into the Address. "IP:PORT".
This commit is contained in:
DJGosnell 2017-10-27 18:04:00 -04:00
Родитель 77aee3211b
Коммит cbdbac5439
60 изменённых файлов: 1164 добавлений и 1189 удалений

Просмотреть файл

@ -1,8 +1,7 @@
language: csharp language: csharp
install:
- nuget install xunit.runners -Version 1.9.2 -OutputDirectory testrunner
before_script: before_script:
- nuget restore ./src/DtronixMessageQueue.sln - nuget restore ./src/DtronixMessageQueue.sln
script: script:
- xbuild /p:Configuration=Release ./src/DtronixMessageQueue/DtronixMessageQueue.csproj - xbuild /p:Configuration=Release ./src/DtronixMessageQueue/DtronixMessageQueue.csproj
- xbuild /p:Configuration=Release ./src/DtronixMessageQueue.Tests/DtronixMessageQueue.Tests.csproj - xbuild /p:Configuration=Release ./src/DtronixMessageQueue.Tests/DtronixMessageQueue.Tests.csproj
- mono ./src/packages/NUnit.ConsoleRunner.3.7.0/tools/nunit3-console.exe ./src/DtronixMessageQueue.Tests/bin/Release/DtronixMessageQueue.Tests.dll

Просмотреть файл

@ -4,7 +4,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using DtronixMessageQueue.Rpc; using DtronixMessageQueue.Rpc;
using DtronixMessageQueue.Socket; using DtronixMessageQueue.TcpSocket;
using DtronixMessageQueue.Tests.Gui.Tests; using DtronixMessageQueue.Tests.Gui.Tests;
using DtronixMessageQueue.Tests.Gui.Tests.Connection; using DtronixMessageQueue.Tests.Gui.Tests.Connection;
using DtronixMessageQueue.Tests.Gui.Tests.Echo; using DtronixMessageQueue.Tests.Gui.Tests.Echo;
@ -32,9 +32,9 @@ namespace DtronixMessageQueue.Tests.Gui.Services
public void ClientReady() public void ClientReady()
{ {
if (Session.BaseSocket.Mode == SocketMode.Server && _server == null) if (Session.SocketHandler.Mode == TcpSocketMode.Server && _server == null)
{ {
_server = (RpcServer<ControllerSession, RpcConfig>) this.Session.BaseSocket; _server = (RpcServer<ControllerSession, RpcConfig>) this.Session.SocketHandler;
} }
} }

Просмотреть файл

@ -2,7 +2,6 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Controls; using System.Windows.Controls;
using DtronixMessageQueue.Rpc; using DtronixMessageQueue.Rpc;
using DtronixMessageQueue.Socket;
using DtronixMessageQueue.Tests.Gui.Services; using DtronixMessageQueue.Tests.Gui.Services;
namespace DtronixMessageQueue.Tests.Gui.Tests.Connection namespace DtronixMessageQueue.Tests.Gui.Tests.Connection
@ -33,8 +32,7 @@ namespace DtronixMessageQueue.Tests.Gui.Tests.Connection
{ {
_testServer = new MqServer<ConnectionPerformanceTestSession, MqConfig>(new MqConfig _testServer = new MqServer<ConnectionPerformanceTestSession, MqConfig>(new MqConfig
{ {
Ip = "0.0.0.0", Address = "0.0.0.0:2121",
Port = 2121,
PingTimeout = 1000, PingTimeout = 1000,
MaxConnections = 2000 MaxConnections = 2000
@ -66,8 +64,7 @@ namespace DtronixMessageQueue.Tests.Gui.Tests.Connection
{ {
var client = new MqClient<ConnectionPerformanceTestSession, MqConfig>(new MqConfig var client = new MqClient<ConnectionPerformanceTestSession, MqConfig>(new MqConfig
{ {
Ip = TestController.ControllClient.Config.Ip, Address = TestController.ControllClient.Config.Address + ":2121",
Port = 2121,
PingFrequency = 500 PingFrequency = 500
}); });

Просмотреть файл

@ -1,6 +1,6 @@
using System; using System;
using System.Threading; using System.Threading;
using DtronixMessageQueue.Socket; using DtronixMessageQueue.TcpSocket;
namespace DtronixMessageQueue.Tests.Gui.Tests.Connection namespace DtronixMessageQueue.Tests.Gui.Tests.Connection
{ {
@ -42,7 +42,7 @@ namespace DtronixMessageQueue.Tests.Gui.Tests.Connection
} }
public override void Close(SocketCloseReason reason) public override void Close(CloseReason reason)
{ {
if (ResponseTimer != null) if (ResponseTimer != null)
{ {

Просмотреть файл

@ -2,7 +2,6 @@
using System.Threading; using System.Threading;
using System.Windows.Controls; using System.Windows.Controls;
using DtronixMessageQueue.Rpc; using DtronixMessageQueue.Rpc;
using DtronixMessageQueue.Socket;
using DtronixMessageQueue.Tests.Gui.Services; using DtronixMessageQueue.Tests.Gui.Services;
namespace DtronixMessageQueue.Tests.Gui.Tests.Echo namespace DtronixMessageQueue.Tests.Gui.Tests.Echo
@ -33,8 +32,7 @@ namespace DtronixMessageQueue.Tests.Gui.Tests.Echo
{ {
_testServer = new MqServer<EchoPerformanceTestSession, MqConfig>(new MqConfig _testServer = new MqServer<EchoPerformanceTestSession, MqConfig>(new MqConfig
{ {
Ip = "0.0.0.0", Address = "0.0.0.0:2121",
Port = 2121,
PingTimeout = 8000, PingTimeout = 8000,
MaxConnections = 1000 MaxConnections = 1000
@ -63,8 +61,7 @@ namespace DtronixMessageQueue.Tests.Gui.Tests.Echo
{ {
var client = new MqClient<EchoPerformanceTestSession, MqConfig>(new MqConfig var client = new MqClient<EchoPerformanceTestSession, MqConfig>(new MqConfig
{ {
Ip = TestController.ControllClient.Config.Ip, Address = TestController.ControllClient.Config.Address + ":2121",
Port = 2121,
PingFrequency = 500 PingFrequency = 500
}); });

Просмотреть файл

@ -2,7 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using DtronixMessageQueue.Socket; using DtronixMessageQueue.TcpSocket;
namespace DtronixMessageQueue.Tests.Gui.Tests.Echo namespace DtronixMessageQueue.Tests.Gui.Tests.Echo
{ {
@ -58,7 +58,7 @@ namespace DtronixMessageQueue.Tests.Gui.Tests.Echo
} }
public override void Close(SocketCloseReason reason) public override void Close(CloseReason reason)
{ {
if (ResponseTimer != null) if (ResponseTimer != null)
{ {

Просмотреть файл

@ -2,7 +2,6 @@
using System.Threading; using System.Threading;
using System.Windows.Controls; using System.Windows.Controls;
using DtronixMessageQueue.Rpc; using DtronixMessageQueue.Rpc;
using DtronixMessageQueue.Socket;
using DtronixMessageQueue.Tests.Gui.Services; using DtronixMessageQueue.Tests.Gui.Services;
namespace DtronixMessageQueue.Tests.Gui.Tests.MaxThroughput namespace DtronixMessageQueue.Tests.Gui.Tests.MaxThroughput
@ -34,8 +33,7 @@ namespace DtronixMessageQueue.Tests.Gui.Tests.MaxThroughput
{ {
_testServer = new MqServer<MaxThroughputPerformanceTestSession, MqConfig>(new MqConfig _testServer = new MqServer<MaxThroughputPerformanceTestSession, MqConfig>(new MqConfig
{ {
Ip = "0.0.0.0", Address = "0.0.0.0:2121",
Port = 2121,
PingTimeout = 8000, PingTimeout = 8000,
MaxConnections = 1000 MaxConnections = 1000
@ -65,8 +63,7 @@ namespace DtronixMessageQueue.Tests.Gui.Tests.MaxThroughput
{ {
var client = new MqClient<MaxThroughputPerformanceTestSession, MqConfig>(new MqConfig var client = new MqClient<MaxThroughputPerformanceTestSession, MqConfig>(new MqConfig
{ {
Ip = TestController.ControllClient.Config.Ip, Address = TestController.ControllClient.Config.Address + ":2121",
Port = 2121,
PingFrequency = 500 PingFrequency = 500
}); });

Просмотреть файл

@ -1,6 +1,6 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using DtronixMessageQueue.Socket; using DtronixMessageQueue.TcpSocket;
namespace DtronixMessageQueue.Tests.Gui.Tests.MaxThroughput namespace DtronixMessageQueue.Tests.Gui.Tests.MaxThroughput
{ {
@ -39,7 +39,7 @@ namespace DtronixMessageQueue.Tests.Gui.Tests.MaxThroughput
} }
public override void Close(SocketCloseReason reason) public override void Close(CloseReason reason)
{ {
if (ResponseTimer != null) if (ResponseTimer != null)
{ {

Просмотреть файл

@ -2,7 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Threading; using System.Threading;
using DtronixMessageQueue.Socket; using DtronixMessageQueue.TcpSocket;
namespace DtronixMessageQueue.Tests.Gui.Tests namespace DtronixMessageQueue.Tests.Gui.Tests
{ {
@ -45,7 +45,7 @@ namespace DtronixMessageQueue.Tests.Gui.Tests
Reader = new MqMessageReader(); Reader = new MqMessageReader();
Writer = new MqMessageWriter(Config); Writer = new MqMessageWriter(Config);
IsServer = BaseSocket.Mode == SocketMode.Server; IsServer = SocketHandler.Mode == TcpSocketMode.Server;
} }

Просмотреть файл

@ -2,7 +2,7 @@
using System.Threading; using System.Threading;
using System.Windows.Controls; using System.Windows.Controls;
using DtronixMessageQueue.Rpc; using DtronixMessageQueue.Rpc;
using DtronixMessageQueue.Socket; using DtronixMessageQueue.TcpSocket;
using DtronixMessageQueue.Tests.Gui.Services; using DtronixMessageQueue.Tests.Gui.Services;
namespace DtronixMessageQueue.Tests.Gui.Tests namespace DtronixMessageQueue.Tests.Gui.Tests
@ -33,10 +33,10 @@ namespace DtronixMessageQueue.Tests.Gui.Tests
Interlocked.Increment(ref TotalConnections); Interlocked.Increment(ref TotalConnections);
} }
protected void ConnectionRemoved(SocketCloseReason reason) protected void ConnectionRemoved(CloseReason reason)
{ {
TestController.Log($"Test client connection closed. Reason: {reason}"); TestController.Log($"Test client connection closed. Reason: {reason}");
if (reason != SocketCloseReason.ConnectionRefused) if (reason != CloseReason.ConnectionRefused)
Interlocked.Decrement(ref TotalConnections); Interlocked.Decrement(ref TotalConnections);
} }

Просмотреть файл

@ -4,7 +4,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using DtronixMessageQueue.Rpc; using DtronixMessageQueue.Rpc;
using DtronixMessageQueue.Socket; using DtronixMessageQueue.TcpSocket;
using DtronixMessageQueue.Tests.Gui.Services; using DtronixMessageQueue.Tests.Gui.Services;
namespace DtronixMessageQueue.Tests.Gui.Tests namespace DtronixMessageQueue.Tests.Gui.Tests
@ -43,8 +43,7 @@ namespace DtronixMessageQueue.Tests.Gui.Tests
Log("Starting Test Control Client"); Log("Starting Test Control Client");
ControllClient = new RpcClient<ControllerSession, RpcConfig>(new RpcConfig ControllClient = new RpcClient<ControllerSession, RpcConfig>(new RpcConfig
{ {
Ip = ip, Address = ip + ":2120",
Port = 2120,
RequireAuthentication = false, RequireAuthentication = false,
PingFrequency = 800 PingFrequency = 800
}); });
@ -68,8 +67,7 @@ namespace DtronixMessageQueue.Tests.Gui.Tests
Log("Starting Controlling Control Server"); Log("Starting Controlling Control Server");
ControlServer = new RpcServer<ControllerSession, RpcConfig>(new RpcConfig ControlServer = new RpcServer<ControllerSession, RpcConfig>(new RpcConfig
{ {
Ip = "0.0.0.0", Address = "0.0.0.0:2120",
Port = 2120,
RequireAuthentication = false, RequireAuthentication = false,
PingTimeout = 1000 PingTimeout = 1000
}); });

Просмотреть файл

@ -35,8 +35,8 @@
<OutputPath>bin\Nuget\</OutputPath> <OutputPath>bin\Nuget\</OutputPath>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="protobuf-net, Version=2.3.0.0, Culture=neutral, PublicKeyToken=257b51d87d2e4d67, processorArchitecture=MSIL"> <Reference Include="protobuf-net, Version=2.3.2.0, Culture=neutral, PublicKeyToken=257b51d87d2e4d67, processorArchitecture=MSIL">
<HintPath>..\packages\protobuf-net.2.3.0\lib\net40\protobuf-net.dll</HintPath> <HintPath>..\packages\protobuf-net.2.3.2\lib\net40\protobuf-net.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Configuration" /> <Reference Include="System.Configuration" />

Просмотреть файл

@ -32,8 +32,7 @@ namespace DtronixMessageQueue.Tests.Performance
_config = new MqConfig _config = new MqConfig
{ {
Ip = "127.0.0.1", Address = "127.0.0.1:2828",
Port = 2828
}; };
_smallMessage = new MqMessage _smallMessage = new MqMessage
@ -126,16 +125,17 @@ namespace DtronixMessageQueue.Tests.Performance
_server.Stop(); _server.Stop();
_client.Close(); _client.Close();
_testCompleteSemaphore.Release();
}; };
_client.Connect(); _client.Connect();
_server.Stopped += (sender, args) => _testCompleteSemaphore.Release();
_testCompleteSemaphore.WaitOne(30000); _testCompleteSemaphore.WaitOne(30000);
} }
public void SendMessages(SimpleMqSession client, MqMessage message, int totalMessages, int timeout) public void SendMessages(SimpleMqSession client, MqMessage message, int totalMessages, int timeout)

Просмотреть файл

@ -16,8 +16,7 @@ namespace DtronixMessageQueue.Tests.Performance
{ {
var config = new RpcConfig var config = new RpcConfig
{ {
Ip = "127.0.0.1", Address = "127.0.0.1:2828",
Port = 2828
}; };
//RpcSingleProcessTest(20, 4, config, RpcTestType.LngBlock); //RpcSingleProcessTest(20, 4, config, RpcTestType.LngBlock);

Просмотреть файл

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="protobuf-net" version="2.3.0" targetFramework="net45" /> <package id="protobuf-net" version="2.3.2" targetFramework="net45" />
</packages> </packages>

Просмотреть файл

@ -4,20 +4,15 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Xunit; using NUnit.Framework;
using Xunit.Abstractions;
namespace DtronixMessageQueue.Tests namespace DtronixMessageQueue.Tests
{ {
public class ActionProcessorTests public class ActionProcessorTests
{ {
private readonly ITestOutputHelper _output; private ManualResetEventSlim completeEvent;
private ManualResetEventSlim completeEvent = new ManualResetEventSlim(false);
public ActionProcessorTests(ITestOutputHelper output)
{
_output = output;
}
private ActionProcessor<Guid> CreateProcessor(int threads, bool start, Action<ActionProcessor<Guid>> complete = null, int rebalanceTime = 10000) private ActionProcessor<Guid> CreateProcessor(int threads, bool start, Action<ActionProcessor<Guid>> complete = null, int rebalanceTime = 10000)
{ {
@ -34,29 +29,35 @@ namespace DtronixMessageQueue.Tests
return processor; return processor;
} }
[Fact] [SetUp]
public void Init()
{
completeEvent = new ManualResetEventSlim(false);
}
[Test]
public void Processor_adds_threads() public void Processor_adds_threads()
{ {
var processor = CreateProcessor(1, false); var processor = CreateProcessor(1, false);
Assert.Equal(processor.ThreadCount, 1); Assert.AreEqual(processor.ThreadCount, 1);
processor.AddThread(2); processor.AddThread(2);
Assert.Equal(processor.ThreadCount, 3); Assert.AreEqual(processor.ThreadCount, 3);
} }
[Fact] [Test]
public void Processor_removes_thread() public void Processor_removes_thread()
{ {
var processor = CreateProcessor(2, true); var processor = CreateProcessor(2, true);
Assert.Equal(processor.ThreadCount, 2); Assert.AreEqual(processor.ThreadCount, 2);
processor.RemoveThread(1); processor.RemoveThread(1);
Assert.Equal(processor.ThreadCount, 1); Assert.AreEqual(processor.ThreadCount, 1);
} }
[Fact] [Test]
public void Processor_throws_on_non_started_processor() public void Processor_throws_on_non_started_processor()
{ {
var processor = CreateProcessor(1, false); var processor = CreateProcessor(1, false);
@ -67,7 +68,7 @@ namespace DtronixMessageQueue.Tests
} }
[Fact] [Test]
public void Processor_throws_on_too_few_threads() public void Processor_throws_on_too_few_threads()
{ {
var processor = CreateProcessor(1, true); var processor = CreateProcessor(1, true);
@ -92,7 +93,7 @@ namespace DtronixMessageQueue.Tests
return processor.GetActionById(id); return processor.GetActionById(id);
} }
[Fact] [Test]
public void Processor_balances_on_registration() public void Processor_balances_on_registration()
{ {
var processor = CreateProcessor(3, true); var processor = CreateProcessor(3, true);
@ -102,15 +103,15 @@ namespace DtronixMessageQueue.Tests
var thirdRegisteredAction = RegisterQueueGet(processor, () => Thread.Sleep(50)); var thirdRegisteredAction = RegisterQueueGet(processor, () => Thread.Sleep(50));
Assert.NotEqual(firstRegisteredAction.ProcessorThread, secondRegisteredAction.ProcessorThread); Assert.AreNotEqual(firstRegisteredAction.ProcessorThread, secondRegisteredAction.ProcessorThread);
Assert.NotEqual(firstRegisteredAction.ProcessorThread, secondRegisteredAction.ProcessorThread); Assert.AreNotEqual(firstRegisteredAction.ProcessorThread, secondRegisteredAction.ProcessorThread);
Assert.NotEqual(secondRegisteredAction.ProcessorThread, thirdRegisteredAction.ProcessorThread); Assert.AreNotEqual(secondRegisteredAction.ProcessorThread, thirdRegisteredAction.ProcessorThread);
Assert.NotEqual(firstRegisteredAction.ProcessorThread, thirdRegisteredAction.ProcessorThread); Assert.AreNotEqual(firstRegisteredAction.ProcessorThread, thirdRegisteredAction.ProcessorThread);
} }
[Fact] [Test]
public void Processor_adds_to_least_used_thread() public void Processor_adds_to_least_used_thread()
{ {
var processor = CreateProcessor(2, true); var processor = CreateProcessor(2, true);
@ -120,13 +121,13 @@ namespace DtronixMessageQueue.Tests
var thirdRegisteredAction = RegisterGet(processor, () => Thread.Sleep(50)); var thirdRegisteredAction = RegisterGet(processor, () => Thread.Sleep(50));
Assert.NotEqual(firstRegisteredAction.ProcessorThread, secondRegisteredAction.ProcessorThread); Assert.AreNotEqual(firstRegisteredAction.ProcessorThread, secondRegisteredAction.ProcessorThread);
Assert.NotEqual(firstRegisteredAction.ProcessorThread, secondRegisteredAction.ProcessorThread); Assert.AreNotEqual(firstRegisteredAction.ProcessorThread, secondRegisteredAction.ProcessorThread);
Assert.Equal(firstRegisteredAction.ProcessorThread, thirdRegisteredAction.ProcessorThread); Assert.AreEqual(firstRegisteredAction.ProcessorThread, thirdRegisteredAction.ProcessorThread);
} }
[Fact] [Test]
public void Processor_queues_once() public void Processor_queues_once()
{ {
var processor = CreateProcessor(1, true); var processor = CreateProcessor(1, true);
@ -136,10 +137,10 @@ namespace DtronixMessageQueue.Tests
processor.QueueOnce(firstRegisteredAction.Id); processor.QueueOnce(firstRegisteredAction.Id);
processor.QueueOnce(firstRegisteredAction.Id); processor.QueueOnce(firstRegisteredAction.Id);
Assert.Equal(1, firstRegisteredAction.ProcessorThread.Queued); Assert.AreEqual(1, firstRegisteredAction.ProcessorThread.Queued);
} }
[Fact] [Test]
public void Processor_queues_multiple() public void Processor_queues_multiple()
{ {
var processor = CreateProcessor(1, true); var processor = CreateProcessor(1, true);
@ -153,10 +154,10 @@ namespace DtronixMessageQueue.Tests
// Wait a period of time for the processor to pickup the call. // Wait a period of time for the processor to pickup the call.
Thread.Sleep(50); Thread.Sleep(50);
Assert.Equal(2, firstRegisteredAction.ProcessorThread.Queued); Assert.AreEqual(2, firstRegisteredAction.ProcessorThread.Queued);
} }
[Fact] [Test]
public void Processor_balances_on_removed_thread() public void Processor_balances_on_removed_thread()
{ {
Action<ActionProcessor<Guid>> complete = ap => completeEvent.Set(); Action<ActionProcessor<Guid>> complete = ap => completeEvent.Set();
@ -188,12 +189,12 @@ namespace DtronixMessageQueue.Tests
Assert.True(completeEvent.Wait(2000)); Assert.True(completeEvent.Wait(2000));
Assert.Equal(totalLoops * 2, interlockedInt); Assert.AreEqual(totalLoops * 2, interlockedInt);
Assert.Equal(3, thirdRegisteredAction.ProcessorThread.RegisteredActionsCount); Assert.AreEqual(3, thirdRegisteredAction.ProcessorThread.RegisteredActionsCount);
} }
[Fact] [Test]
public void Processor_balances_on_added_thread() public void Processor_balances_on_added_thread()
{ {
Action<ActionProcessor<Guid>> complete = ap => completeEvent.Set(); Action<ActionProcessor<Guid>> complete = ap => completeEvent.Set();
@ -225,11 +226,13 @@ namespace DtronixMessageQueue.Tests
Assert.True(completeEvent.Wait(2000)); Assert.True(completeEvent.Wait(2000));
Assert.Equal(totalLoops * 2, interlockedInt); Assert.AreEqual(totalLoops * 2, interlockedInt);
Assert.Equal(1, firstRegisteredAction.ProcessorThread.RegisteredActionsCount); Assert.AreEqual(1, firstRegisteredAction.ProcessorThread.RegisteredActionsCount);
Assert.Equal(1, secondRegisteredAction.ProcessorThread.RegisteredActionsCount); Assert.AreEqual(1, secondRegisteredAction.ProcessorThread.RegisteredActionsCount);
Assert.Equal(1, thirdRegisteredAction.ProcessorThread.RegisteredActionsCount); Assert.AreEqual(1, thirdRegisteredAction.ProcessorThread.RegisteredActionsCount);
} }
} }
} }

Просмотреть файл

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\xunit.runner.visualstudio.2.2.0-beta2-build1149\build\net20\xunit.runner.visualstudio.props" Condition="Exists('..\packages\xunit.runner.visualstudio.2.2.0-beta2-build1149\build\net20\xunit.runner.visualstudio.props')" /> <Import Project="..\packages\NUnit3TestAdapter.3.8.0\build\net35\NUnit3TestAdapter.props" Condition="Exists('..\packages\NUnit3TestAdapter.3.8.0\build\net35\NUnit3TestAdapter.props')" />
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@ -41,24 +41,11 @@
<OutputPath>bin\Nuget\</OutputPath> <OutputPath>bin\Nuget\</OutputPath>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="nunit.framework, Version=3.8.1.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>..\packages\NUnit.3.8.1\lib\net45\nunit.framework.dll</HintPath>
</Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Configuration" /> <Reference Include="System.Configuration" />
<Reference Include="xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="xunit.assert, Version=2.2.0.3300, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\packages\xunit.assert.2.2.0-beta2-build3300\lib\netstandard1.0\xunit.assert.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="xunit.core, Version=2.2.0.3300, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\packages\xunit.extensibility.core.2.2.0-beta2-build3300\lib\net45\xunit.core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="xunit.execution.desktop, Version=2.2.0.3300, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\packages\xunit.extensibility.execution.2.2.0-beta2-build3300\lib\net45\xunit.execution.desktop.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup> </ItemGroup>
<Choose> <Choose>
<When Condition="('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'"> <When Condition="('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'">
@ -75,15 +62,14 @@
<Compile Include="Mq\MqServerTests.cs" /> <Compile Include="Mq\MqServerTests.cs" />
<Compile Include="Mq\MqMessageWriterReaderTests.cs" /> <Compile Include="Mq\MqMessageWriterReaderTests.cs" />
<Compile Include="Mq\MqTestsBase.cs" /> <Compile Include="Mq\MqTestsBase.cs" />
<Compile Include="PerformanceTests.cs" />
<Compile Include="Mq\MqClientTests.cs" /> <Compile Include="Mq\MqClientTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RepeatAttribute.cs" />
<Compile Include="Rpc\RpcClientTests.cs" /> <Compile Include="Rpc\RpcClientTests.cs" />
<Compile Include="Rpc\RpcTestsBase.cs" /> <Compile Include="Rpc\RpcTestsBase.cs" />
<Compile Include="Rpc\Services\Server\CalculatorService.cs" /> <Compile Include="Rpc\Services\Server\CalculatorService.cs" />
<Compile Include="Mq\SimpleMqSession.cs" /> <Compile Include="Mq\SimpleMqSession.cs" />
<Compile Include="Rpc\SimpleRpcSession.cs" /> <Compile Include="Rpc\SimpleRpcSession.cs" />
<Compile Include="TestBase.cs" />
<Compile Include="Utilities.cs" /> <Compile Include="Utilities.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -120,7 +106,7 @@
<PropertyGroup> <PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup> </PropertyGroup>
<Error Condition="!Exists('..\packages\xunit.runner.visualstudio.2.2.0-beta2-build1149\build\net20\xunit.runner.visualstudio.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\xunit.runner.visualstudio.2.2.0-beta2-build1149\build\net20\xunit.runner.visualstudio.props'))" /> <Error Condition="!Exists('..\packages\NUnit3TestAdapter.3.8.0\build\net35\NUnit3TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit3TestAdapter.3.8.0\build\net35\NUnit3TestAdapter.props'))" />
</Target> </Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.

Просмотреть файл

@ -1,22 +1,17 @@
using System; using System;
using System.Threading; using System.Threading;
using DtronixMessageQueue.Socket; using DtronixMessageQueue.TcpSocket;
using Xunit; using NUnit.Framework;
using Xunit.Abstractions;
namespace DtronixMessageQueue.Tests.Mq namespace DtronixMessageQueue.Tests.Mq
{ {
public class MqClientTests : MqTestsBase public class MqClientTests : MqTestsBase
{ {
public MqClientTests(ITestOutputHelper output) : base(output)
{
}
[Theory] [TestCase(1, false)]
[InlineData(1, false)] [TestCase(1, true)]
[InlineData(1, true)] [TestCase(100, true)]
[InlineData(100, true)] [TestCase(1000, true)]
[InlineData(1000, true)]
public void Client_should_send_data_to_server(int number, bool validate) public void Client_should_send_data_to_server(int number, bool validate)
{ {
var messageSource = GenerateRandomMessage(4, 50); var messageSource = GenerateRandomMessage(4, 50);
@ -46,7 +41,7 @@ namespace DtronixMessageQueue.Tests.Mq
if (receivedMessages == number) if (receivedMessages == number)
{ {
TestStatus.Set(); TestComplete.Set();
} }
}; };
@ -54,7 +49,7 @@ namespace DtronixMessageQueue.Tests.Mq
} }
[Fact] [Test]
public void Client_does_not_send_empty_message() public void Client_does_not_send_empty_message()
{ {
var messageSource = GenerateRandomMessage(2, 50); var messageSource = GenerateRandomMessage(2, 50);
@ -76,141 +71,128 @@ namespace DtronixMessageQueue.Tests.Mq
{ {
LastException = new Exception("Server received an empty message."); LastException = new Exception("Server received an empty message.");
} }
TestStatus.Set(); TestComplete.Set();
} }
}; };
StartAndWait(); StartAndWait();
} }
[Fact] [Test]
public void Client_does_not_notify_on_command_frame() public void Client_does_not_notify_on_command_frame()
{ {
var commandFrame = new MqFrame(new byte[21], MqFrameType.Command, Config); var commandFrame = new MqFrame(new byte[21], MqFrameType.Command, ClientConfig);
Client.Connected += (sender, args) => { Client.Send(commandFrame); }; Client.Connected += (sender, args) => { Client.Send(commandFrame); };
Server.IncomingMessage += (sender, args) => { TestStatus.Set(); }; Server.IncomingMessage += (sender, args) => { TestComplete.Set(); };
StartAndWait(false, 500); StartAndWait(false, 500);
if (TestStatus.IsSet) if (TestComplete.IsSet)
{ {
throw new Exception("Server read command frame."); throw new Exception("Server read command frame.");
} }
} }
[Fact] [Test]
public void Client_does_not_notify_on_ping_frame() public void Client_does_not_notify_on_ping_frame()
{ {
var commandFrame = new MqFrame(null, MqFrameType.Ping, Config); var commandFrame = new MqFrame(null, MqFrameType.Ping, ClientConfig);
Client.Connected += (sender, args) => { Client.Send(commandFrame); }; Client.Connected += (sender, args) => { Client.Send(commandFrame); };
Server.IncomingMessage += (sender, args) => { TestStatus.Set(); }; Server.IncomingMessage += (sender, args) => { TestComplete.Set(); };
StartAndWait(false, 500); StartAndWait(false, 500);
if (TestStatus.IsSet) if (TestComplete.IsSet)
{ {
throw new Exception("Server read command frame."); throw new Exception("Server read command frame.");
} }
} }
[Fact] [Test]
public void Client_connects_to_server() public void Client_connects_to_server()
{ {
Client.Connected += (sender, args) => TestStatus.Set(); Client.Connected += (sender, args) => TestComplete.Set();
StartAndWait(); StartAndWait();
} }
[Fact] [Test]
public void Client_disconects_from_server() public void Client_disconects_from_server()
{ {
Client.Connected += (sender, args) => { Client.Close(); }; Client.Connected += (sender, args) => { Client.Close(); };
Client.Closed += (sender, args) => TestStatus.Set(); Client.Closed += (sender, args) => TestComplete.Set();
StartAndWait(true, 500000); StartAndWait(true, 500000);
} }
[Fact] [Test]
public void Client_notified_server_stopping() public void Client_notified_server_stopping()
{ {
Server.Connected += (sender, session) => Server.Stop(); Server.Connected += (sender, session) => Server.Stop();
Client.Closed += (sender, args) => TestStatus.Set(); Client.Closed += (sender, args) => TestComplete.Set();
StartAndWait(); StartAndWait();
} }
[Fact] [Test]
public void Client_closes_self() public void Client_closes_self()
{ {
Client.Connected += (sender, args) => Client.Close(); Client.Connected += (sender, args) => Client.Close();
Client.Closed += (sender, args) => TestStatus.Set(); Client.Closed += (sender, args) => TestComplete.Set();
StartAndWait(); StartAndWait();
} }
[Fact] [Test]
public void Client_notified_server_session_closed() public void Client_notified_server_session_closed()
{ {
Server.Connected += (sender, session) => Server.Connected += (sender, session) =>
{ {
//Thread.Sleep(1000); session.Session.Close(CloseReason.ApplicationError);
//session.Session.Send(new MqMessage(new MqFrame(new byte[24], MqFrameType.Last)));
session.Session.Close(SocketCloseReason.ApplicationError);
}; };
Client.Closed += (sender, args) => Client.Closed += (sender, args) =>
{ {
if (args.CloseReason != SocketCloseReason.ApplicationError) if (args.CloseReason != CloseReason.ApplicationError && !IsMono)
{ {
LastException = new InvalidOperationException("Server did not return proper close reason."); LastException = new InvalidOperationException("Server did not return proper close reason.");
} }
TestStatus.Set(); TestComplete.Set();
}; };
StartAndWait(); StartAndWait();
} }
[Fact] [Test]
public void Client_notifies_server_closing_session() public void Client_notifies_server_closing_session()
{ {
Client.Connected += (sender, args) => Client.Close(); Client.Connected += (sender, args) => Client.Close();
Server.Closed += (sender, args) => TestStatus.Set(); Server.Closed += (sender, args) => TestComplete.Set();
StartAndWait(); StartAndWait();
} }
[Fact] [Test]
public void Client_times_out() public void Client_times_out()
{ {
var clientConfig = new MqConfig ClientConfig.PingFrequency = 60000;
{ ServerConfig.PingTimeout = 500;
Ip = Config.Ip,
Port = Config.Port,
PingFrequency = 60000
};
Client = new MqClient<SimpleMqSession, MqConfig>(clientConfig);
Config.PingTimeout = 500;
Server = new MqServer<SimpleMqSession, MqConfig>(Config);
Client.Closed += (sender, args) => Client.Closed += (sender, args) =>
{ {
if (args.CloseReason == SocketCloseReason.TimeOut) if (args.CloseReason == CloseReason.TimeOut || IsMono)
{ {
TestStatus.Set(); TestComplete.Set();
} }
else else
{ {
@ -220,34 +202,24 @@ namespace DtronixMessageQueue.Tests.Mq
StartAndWait(false, 2000); StartAndWait(false, 2000);
if (TestStatus.IsSet == false) if (TestComplete.IsSet == false)
{ {
throw new Exception("Socket did not timeout."); throw new Exception("Socket did not timeout.");
} }
} }
[Fact] [Test]
public void Client_prevents_times_out() public void Client_prevents_times_out()
{ {
var clientConfig = new MqConfig ClientConfig.PingFrequency = 50;
{ ServerConfig.PingTimeout = 100;
Ip = Config.Ip,
Port = Config.Port,
PingFrequency = 100
};
Client = new MqClient<SimpleMqSession, MqConfig>(clientConfig);
Config.PingTimeout = 200;
Server = new MqServer<SimpleMqSession, MqConfig>(Config);
Client.Closed += (sender, args) => Client.Closed += (sender, args) =>
{ {
if (args.CloseReason == SocketCloseReason.TimeOut) if (args.CloseReason == CloseReason.TimeOut)
{ {
TestStatus.Set(); LastException = new Exception("Client timed out.");
} }
else else
{ {
@ -255,31 +227,21 @@ namespace DtronixMessageQueue.Tests.Mq
} }
}; };
StartAndWait(false, 1500); StartAndWait(false, 500);
if (TestStatus.IsSet)
{
throw new Exception("Client timed out.");
}
} }
[Fact] [Test]
public void Client_times_out_after_server_dropped_session() public void Client_times_out_after_server_dropped_session()
{ {
Config.PingTimeout = 500; ClientConfig.PingTimeout = 500;
Client = new MqClient<SimpleMqSession, MqConfig>(Config);
Server = new MqServer<SimpleMqSession, MqConfig>(Config);
Server.Connected += (sender, args) => { args.Session.Socket.Close(); }; Server.Connected += (sender, args) => { args.Session.Socket.Close(); };
Client.Closed += (sender, args) => Client.Closed += (sender, args) =>
{ {
if (args.CloseReason == SocketCloseReason.TimeOut) if (args.CloseReason == CloseReason.Closing)
{ {
TestStatus.Set(); TestComplete.Set();
} }
else else
{ {
@ -289,26 +251,22 @@ namespace DtronixMessageQueue.Tests.Mq
StartAndWait(false, 1000); StartAndWait(false, 1000);
if (TestStatus.IsSet == false) if (TestComplete.IsSet == false)
{ {
throw new Exception("Socket did not timeout."); throw new Exception("Socket did not timeout.");
} }
} }
[Fact] [Test]
public void Client_times_out_while_connecting_for_too_long() public void Client_times_out_while_connecting_for_too_long()
{ {
Config.ConnectionTimeout = 100; ClientConfig.ConnectionTimeout = 200;
Client = new MqClient<SimpleMqSession, MqConfig>(Config);
Server.Connected += (sender, args) => { args.Session.Socket.Close(); };
Client.Closed += (sender, args) => Client.Closed += (sender, args) =>
{ {
if (args.CloseReason == SocketCloseReason.TimeOut) if (args.CloseReason == CloseReason.TimeOut)
{ {
TestStatus.Set(); TestComplete.Set();
} }
else else
{ {
@ -318,13 +276,13 @@ namespace DtronixMessageQueue.Tests.Mq
StartAndWait(false, 10000, false); StartAndWait(false, 10000, false);
if (TestStatus.IsSet == false) if (TestComplete.IsSet == false)
{ {
throw new Exception("Socket did not timeout."); throw new Exception("Socket did not timeout.");
} }
} }
[Fact] [Test]
public void Client_reconnects_after_close() public void Client_reconnects_after_close()
{ {
int connected_times = 0; int connected_times = 0;
@ -334,7 +292,7 @@ namespace DtronixMessageQueue.Tests.Mq
{ {
if (++connected_times == 2) if (++connected_times == 2)
{ {
TestStatus.Set(); TestComplete.Set();
} }
Client.Close(); Client.Close();
@ -351,9 +309,9 @@ namespace DtronixMessageQueue.Tests.Mq
TestStatus.Wait(new TimeSpan(0, 0, 0, 0, 2000)); TestComplete.Wait(new TimeSpan(0, 0, 0, 0, 2000));
if (TestStatus.IsSet == false) if (TestComplete.IsSet == false)
{ {
throw new TimeoutException("Test timed out."); throw new TimeoutException("Test timed out.");
} }

Просмотреть файл

@ -1,10 +1,11 @@
using System; using System;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Xunit; using NUnit.Framework;
namespace DtronixMessageQueue.Tests.Mq namespace DtronixMessageQueue.Tests.Mq
{ {
[TestFixture]
public class MqFrameBuilderTests public class MqFrameBuilderTests
{ {
private MqFrame _emptyLastFrame; private MqFrame _emptyLastFrame;
@ -17,75 +18,81 @@ namespace DtronixMessageQueue.Tests.Mq
private MqFrame _pingFrame; private MqFrame _pingFrame;
public MqFrameBuilderTests() public MqFrameBuilderTests()
{
}
[SetUp]
public void Init()
{ {
_frameBuilder = new MqFrameBuilder(_config); _frameBuilder = new MqFrameBuilder(_config);
_emptyLastFrame = new MqFrame(null, MqFrameType.EmptyLast, _config); _emptyLastFrame = new MqFrame(null, MqFrameType.EmptyLast, _config);
_emptyFrame = new MqFrame(null, MqFrameType.Empty, _config); _emptyFrame = new MqFrame(null, MqFrameType.Empty, _config);
_lastFrame = new MqFrame(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, MqFrameType.Last, _config); _lastFrame = new MqFrame(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }, MqFrameType.Last, _config);
_moreFrame = new MqFrame(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, MqFrameType.More, _config); _moreFrame = new MqFrame(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }, MqFrameType.More, _config);
_commandFrame = new MqFrame(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, MqFrameType.Command, _config); _commandFrame = new MqFrame(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }, MqFrameType.Command, _config);
_pingFrame = new MqFrame(null, MqFrameType.Ping, _config); _pingFrame = new MqFrame(null, MqFrameType.Ping, _config);
} }
[Fact] [Test]
public void FrameBuilder_parses_empty_frame() public void FrameBuilder_parses_empty_frame()
{ {
_frameBuilder.Write(_emptyFrame.RawFrame(), 0, _emptyFrame.FrameSize); _frameBuilder.Write(_emptyFrame.RawFrame());
var parsedFrame = _frameBuilder.Frames.Dequeue(); var parsedFrame = _frameBuilder.Frames.Dequeue();
Utilities.CompareFrame(_emptyFrame, parsedFrame); Utilities.CompareFrame(_emptyFrame, parsedFrame);
} }
[Fact] [Test]
public void FrameBuilder_parses_empty_last_frame() public void FrameBuilder_parses_empty_last_frame()
{ {
_frameBuilder.Write(_emptyLastFrame.RawFrame(), 0, _emptyFrame.FrameSize); _frameBuilder.Write(_emptyLastFrame.RawFrame());
var parsedFrame = _frameBuilder.Frames.Dequeue(); var parsedFrame = _frameBuilder.Frames.Dequeue();
Utilities.CompareFrame(_emptyLastFrame, parsedFrame); Utilities.CompareFrame(_emptyLastFrame, parsedFrame);
} }
[Fact] [Test]
public void FrameBuilder_parses_last_frame() public void FrameBuilder_parses_last_frame()
{ {
_frameBuilder.Write(_lastFrame.RawFrame(), 0, _lastFrame.FrameSize); _frameBuilder.Write(_lastFrame.RawFrame());
var parsedFrame = _frameBuilder.Frames.Dequeue(); var parsedFrame = _frameBuilder.Frames.Dequeue();
Utilities.CompareFrame(_lastFrame, parsedFrame); Utilities.CompareFrame(_lastFrame, parsedFrame);
} }
[Fact] [Test]
public void FrameBuilder_parses_more_frame() public void FrameBuilder_parses_more_frame()
{ {
_frameBuilder.Write(_moreFrame.RawFrame(), 0, _moreFrame.FrameSize); _frameBuilder.Write(_moreFrame.RawFrame());
var parsedFrame = _frameBuilder.Frames.Dequeue(); var parsedFrame = _frameBuilder.Frames.Dequeue();
Utilities.CompareFrame(_moreFrame, parsedFrame); Utilities.CompareFrame(_moreFrame, parsedFrame);
} }
[Fact] [Test]
public void FrameBuilder_parses_command_frame() public void FrameBuilder_parses_command_frame()
{ {
_frameBuilder.Write(_commandFrame.RawFrame(), 0, _commandFrame.FrameSize); _frameBuilder.Write(_commandFrame.RawFrame());
var parsedFrame = _frameBuilder.Frames.Dequeue(); var parsedFrame = _frameBuilder.Frames.Dequeue();
Utilities.CompareFrame(_commandFrame, parsedFrame); Utilities.CompareFrame(_commandFrame, parsedFrame);
} }
[Fact] [Test]
public void FrameBuilder_parses_ping_frame() public void FrameBuilder_parses_ping_frame()
{ {
_frameBuilder.Write(_pingFrame.RawFrame(), 0, _pingFrame.FrameSize); _frameBuilder.Write(_pingFrame.RawFrame());
var parsedFrame = _frameBuilder.Frames.Dequeue(); var parsedFrame = _frameBuilder.Frames.Dequeue();
Utilities.CompareFrame(_pingFrame, parsedFrame); Utilities.CompareFrame(_pingFrame, parsedFrame);
} }
[Fact] [Test]
public void FrameBuilder_parses_multiple_frames() public void FrameBuilder_parses_multiple_frames()
{ {
_frameBuilder.Write(_moreFrame.RawFrame(), 0, _moreFrame.FrameSize); _frameBuilder.Write(_moreFrame.RawFrame());
_frameBuilder.Write(_moreFrame.RawFrame(), 0, _moreFrame.FrameSize); _frameBuilder.Write(_moreFrame.RawFrame());
while (_frameBuilder.Frames.Count > 0) while (_frameBuilder.Frames.Count > 0)
{ {
@ -94,54 +101,54 @@ namespace DtronixMessageQueue.Tests.Mq
} }
} }
[Fact] [Test]
public void FrameBuilder_parses_frames_in_parts() public void FrameBuilder_parses_frames_in_parts()
{ {
var frameBytes = _lastFrame.RawFrame(); var frameBytes = _lastFrame.RawFrame();
for (int i = 0; i < frameBytes.Length; i++) for (int i = 0; i < frameBytes.Length; i++)
{ {
_frameBuilder.Write(new[] {frameBytes[i]}, 0, 1); _frameBuilder.Write(new[] {frameBytes[i]});
} }
var parsedFrame = _frameBuilder.Frames.Dequeue(); var parsedFrame = _frameBuilder.Frames.Dequeue();
Utilities.CompareFrame(_lastFrame, parsedFrame); Utilities.CompareFrame(_lastFrame, parsedFrame);
} }
[Fact] [Test]
public void FrameBuilder_throws_passed_buffer_too_large() public void FrameBuilder_throws_passed_buffer_too_large()
{ {
Assert.Throws<InvalidDataException>( Assert.Throws<InvalidDataException>(
() => { _frameBuilder.Write(new byte[_config.FrameBufferSize + 1], 0, _config.FrameBufferSize + 1); }); () => { _frameBuilder.Write(new byte[_config.FrameBufferSize + 1]); });
} }
[Fact] [Test]
public void FrameBuilder_throws_frame_zero_length() public void FrameBuilder_throws_frame_zero_length()
{ {
Assert.Throws<InvalidDataException>(() => { _frameBuilder.Write(new byte[] {2, 0, 0, 1}, 0, 4); }); Assert.Throws<InvalidDataException>(() => { _frameBuilder.Write(new byte[] {2, 0, 0, 1}); });
} }
[Fact] [Test]
public void FrameBuilder_throws_frame_specified_length_too_large() public void FrameBuilder_throws_frame_specified_length_too_large()
{ {
Assert.Throws<InvalidDataException>(() => { _frameBuilder.Write(new byte[] {2, 255, 255, 1}, 0, 4); }); Assert.Throws<InvalidDataException>(() => { _frameBuilder.Write(new byte[] {2, 255, 255, 1}); });
} }
[Fact] [Test]
public void FrameBuilder_throws_frame_type_out_of_range() public void FrameBuilder_throws_frame_type_out_of_range()
{ {
var maxTypeEnum = Enum.GetValues(typeof(MqFrameType)).Cast<byte>().Max() + 1; var maxTypeEnum = Enum.GetValues(typeof(MqFrameType)).Cast<byte>().Max() + 1;
Assert.Throws<InvalidDataException>(() => { _frameBuilder.Write(new byte[] {(byte) maxTypeEnum}, 0, 1); }); Assert.Throws<InvalidDataException>(() => { _frameBuilder.Write(new byte[] {(byte) maxTypeEnum}); });
} }
[Fact] [Test]
public void FrameBuilder_parsed_frame_data() public void FrameBuilder_parsed_frame_data()
{ {
_frameBuilder.Write(new byte[] {2, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, 0, 13); _frameBuilder.Write(new byte[] {2, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0});
var parsedFrame = _frameBuilder.Frames.Dequeue(); var parsedFrame = _frameBuilder.Frames.Dequeue();
Assert.Equal(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, parsedFrame.Buffer); Assert.AreEqual(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, parsedFrame.Buffer);
} }
} }

Просмотреть файл

@ -1,8 +1,9 @@
using System; using System;
using Xunit; using NUnit.Framework;
namespace DtronixMessageQueue.Tests.Mq namespace DtronixMessageQueue.Tests.Mq
{ {
[TestFixture]
public class MqFrameTests public class MqFrameTests
{ {
private MqFrame _actualFrame; private MqFrame _actualFrame;
@ -14,89 +15,95 @@ namespace DtronixMessageQueue.Tests.Mq
{ {
} }
[Fact] [SetUp]
public void Init()
{
}
[Test]
public void Frame_creates_empty_frame() public void Frame_creates_empty_frame()
{ {
_expectedBytes = new byte[] {1}; _expectedBytes = new byte[] {1};
_actualFrame = new MqFrame(null, MqFrameType.Empty, _config); _actualFrame = new MqFrame(null, MqFrameType.Empty, _config);
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_empty_frame_throws_on_bytes() public void Frame_empty_frame_throws_on_bytes()
{ {
Assert.Throws<ArgumentException>(() => new MqFrame(new byte[] {1}, MqFrameType.Empty, _config)); Assert.Throws<ArgumentException>(() => new MqFrame(new byte[] {1}, MqFrameType.Empty, _config));
} }
[Fact] [Test]
public void Frame_empty_frame_accepts_empty_array() public void Frame_empty_frame_accepts_empty_array()
{ {
_expectedBytes = new byte[] {1}; _expectedBytes = new byte[] {1};
_actualFrame = new MqFrame(new byte[] {}, MqFrameType.Empty, _config); _actualFrame = new MqFrame(new byte[] {}, MqFrameType.Empty, _config);
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_creates_empty_last_frame() public void Frame_creates_empty_last_frame()
{ {
_expectedBytes = new byte[] {4}; _expectedBytes = new byte[] {4};
_actualFrame = new MqFrame(null, MqFrameType.EmptyLast, _config); _actualFrame = new MqFrame(null, MqFrameType.EmptyLast, _config);
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_creates_command_frame() public void Frame_creates_command_frame()
{ {
_expectedBytes = new byte[] {5, 1, 0, 1}; _expectedBytes = new byte[] {5, 1, 0, 1};
_actualFrame = new MqFrame(new byte[] {1}, MqFrameType.Command, _config); _actualFrame = new MqFrame(new byte[] {1}, MqFrameType.Command, _config);
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_creates_ping_frame() public void Frame_creates_ping_frame()
{ {
_expectedBytes = new byte[] {6}; _expectedBytes = new byte[] {6};
_actualFrame = new MqFrame(null, MqFrameType.Ping, _config); _actualFrame = new MqFrame(null, MqFrameType.Ping, _config);
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_empty_last_frame_throws_on_bytes() public void Frame_empty_last_frame_throws_on_bytes()
{ {
Assert.Throws<ArgumentException>(() => new MqFrame(new byte[] {1}, MqFrameType.EmptyLast, _config)); Assert.Throws<ArgumentException>(() => new MqFrame(new byte[] {1}, MqFrameType.EmptyLast, _config));
} }
[Fact] [Test]
public void Frame_creates_more_frame_bytes() public void Frame_creates_more_frame_bytes()
{ {
_expectedBytes = new byte[] {2, 5, 0, 1, 2, 3, 4, 5}; _expectedBytes = new byte[] {2, 5, 0, 1, 2, 3, 4, 5};
_actualFrame = new MqFrame(new byte[] {1, 2, 3, 4, 5}, MqFrameType.More, _config); _actualFrame = new MqFrame(new byte[] {1, 2, 3, 4, 5}, MqFrameType.More, _config);
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_creates_last_frame_bytes() public void Frame_creates_last_frame_bytes()
{ {
_expectedBytes = new byte[] {3, 5, 0, 1, 2, 3, 4, 5}; _expectedBytes = new byte[] {3, 5, 0, 1, 2, 3, 4, 5};
_actualFrame = new MqFrame(new byte[] {1, 2, 3, 4, 5}, MqFrameType.Last, _config); _actualFrame = new MqFrame(new byte[] {1, 2, 3, 4, 5}, MqFrameType.Last, _config);
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_writes_byte_array_full() public void Frame_writes_byte_array_full()
{ {
_expectedBytes = new byte[] {3, 5, 0, 1, 2, 3, 4, 241}; _expectedBytes = new byte[] {3, 5, 0, 1, 2, 3, 4, 241};
@ -104,10 +111,10 @@ namespace DtronixMessageQueue.Tests.Mq
_actualFrame.Write(0, new byte[] {1, 2, 3, 4, 241}, 0, 5); _actualFrame.Write(0, new byte[] {1, 2, 3, 4, 241}, 0, 5);
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_writes_byte_array_offset() public void Frame_writes_byte_array_offset()
{ {
_expectedBytes = new byte[] {3, 3, 0, 3, 4, 241}; _expectedBytes = new byte[] {3, 3, 0, 3, 4, 241};
@ -115,10 +122,10 @@ namespace DtronixMessageQueue.Tests.Mq
_actualFrame.Write(0, new byte[] {1, 2, 3, 4, 241}, 2, 3); _actualFrame.Write(0, new byte[] {1, 2, 3, 4, 241}, 2, 3);
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_writes_byte_array_offset_length() public void Frame_writes_byte_array_offset_length()
{ {
_expectedBytes = new byte[] {3, 2, 0, 3, 4}; _expectedBytes = new byte[] {3, 2, 0, 3, 4};
@ -126,10 +133,10 @@ namespace DtronixMessageQueue.Tests.Mq
_actualFrame.Write(0, new byte[] {1, 2, 3, 4, 241}, 2, 2); _actualFrame.Write(0, new byte[] {1, 2, 3, 4, 241}, 2, 2);
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_writes_byte_array_offset_length_position() public void Frame_writes_byte_array_offset_length_position()
{ {
_expectedBytes = new byte[] {3, 3, 0, 0, 3, 4}; _expectedBytes = new byte[] {3, 3, 0, 0, 3, 4};
@ -137,10 +144,10 @@ namespace DtronixMessageQueue.Tests.Mq
_actualFrame.Write(1, new byte[] {1, 2, 3, 4, 241}, 2, 2); _actualFrame.Write(1, new byte[] {1, 2, 3, 4, 241}, 2, 2);
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_reads_byte_array() public void Frame_reads_byte_array()
{ {
_expectedBytes = new byte[] {1, 2, 3, 4, 5}; _expectedBytes = new byte[] {1, 2, 3, 4, 5};
@ -148,10 +155,10 @@ namespace DtronixMessageQueue.Tests.Mq
_actualBytes = new byte[5]; _actualBytes = new byte[5];
_actualFrame.Read(0, _actualBytes, 0, 5); _actualFrame.Read(0, _actualBytes, 0, 5);
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_writes_bool_true() public void Frame_writes_bool_true()
{ {
_expectedBytes = new byte[] {3, 1, 0, 1}; _expectedBytes = new byte[] {3, 1, 0, 1};
@ -159,10 +166,10 @@ namespace DtronixMessageQueue.Tests.Mq
_actualFrame.Write(0, true); _actualFrame.Write(0, true);
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_writes_bool_false() public void Frame_writes_bool_false()
{ {
_expectedBytes = new byte[] {3, 2, 0, 0, 0}; _expectedBytes = new byte[] {3, 2, 0, 0, 0};
@ -170,10 +177,10 @@ namespace DtronixMessageQueue.Tests.Mq
_actualFrame.Write(0, false); _actualFrame.Write(0, false);
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_writes_bool_position() public void Frame_writes_bool_position()
{ {
_expectedBytes = new byte[] {3, 2, 0, 0, 1}; _expectedBytes = new byte[] {3, 2, 0, 0, 1};
@ -181,19 +188,19 @@ namespace DtronixMessageQueue.Tests.Mq
_actualFrame.Write(1, true); _actualFrame.Write(1, true);
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_reads_bool() public void Frame_reads_bool()
{ {
_actualFrame = new MqFrame(new byte[1], MqFrameType.Last, _config); _actualFrame = new MqFrame(new byte[1], MqFrameType.Last, _config);
_actualFrame.Write(0, true); _actualFrame.Write(0, true);
Assert.Equal(true, _actualFrame.ReadBoolean(0)); Assert.AreEqual(true, _actualFrame.ReadBoolean(0));
} }
[Fact] [Test]
public void Frame_writes_byte() public void Frame_writes_byte()
{ {
_expectedBytes = new byte[] {3, 1, 0, 231}; _expectedBytes = new byte[] {3, 1, 0, 231};
@ -201,10 +208,10 @@ namespace DtronixMessageQueue.Tests.Mq
_actualFrame.Write(0, (byte) 231); _actualFrame.Write(0, (byte) 231);
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_writes_byte_position() public void Frame_writes_byte_position()
{ {
_expectedBytes = new byte[] {3, 2, 0, 0, 231}; _expectedBytes = new byte[] {3, 2, 0, 0, 231};
@ -212,10 +219,10 @@ namespace DtronixMessageQueue.Tests.Mq
_actualFrame.Write(1, (byte) 231); _actualFrame.Write(1, (byte) 231);
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_writes_sbyte_negative() public void Frame_writes_sbyte_negative()
{ {
_expectedBytes = new byte[] {3, 1, 0, 155}; _expectedBytes = new byte[] {3, 1, 0, 155};
@ -224,10 +231,10 @@ namespace DtronixMessageQueue.Tests.Mq
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_writes_sbyte_position() public void Frame_writes_sbyte_position()
{ {
_expectedBytes = new byte[] {3, 2, 0, 0, 101}; _expectedBytes = new byte[] {3, 2, 0, 0, 101};
@ -236,31 +243,31 @@ namespace DtronixMessageQueue.Tests.Mq
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_reads_sbyte() public void Frame_reads_sbyte()
{ {
var value = (sbyte) 101; var value = (sbyte) 101;
_actualFrame = new MqFrame(new byte[1], MqFrameType.Last, _config); _actualFrame = new MqFrame(new byte[1], MqFrameType.Last, _config);
_actualFrame.Write(0, value); _actualFrame.Write(0, value);
Assert.Equal(value, _actualFrame.ReadSByte(0)); Assert.AreEqual(value, _actualFrame.ReadSByte(0));
} }
[Fact] [Test]
public void Frame_reads_sbyte_position() public void Frame_reads_sbyte_position()
{ {
var value = (sbyte) 101; var value = (sbyte) 101;
_actualFrame = new MqFrame(new byte[2], MqFrameType.Last, _config); _actualFrame = new MqFrame(new byte[2], MqFrameType.Last, _config);
_actualFrame.Write(1, value); _actualFrame.Write(1, value);
Assert.Equal(value, _actualFrame.ReadSByte(1)); Assert.AreEqual(value, _actualFrame.ReadSByte(1));
} }
[Fact] [Test]
public void Frame_writes_char() public void Frame_writes_char()
{ {
_expectedBytes = new byte[] {3, 1, 0, 68}; _expectedBytes = new byte[] {3, 1, 0, 68};
@ -269,10 +276,10 @@ namespace DtronixMessageQueue.Tests.Mq
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_writes_char_position() public void Frame_writes_char_position()
{ {
_expectedBytes = new byte[] {3, 2, 0, 0, 68}; _expectedBytes = new byte[] {3, 2, 0, 0, 68};
@ -281,30 +288,30 @@ namespace DtronixMessageQueue.Tests.Mq
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_reads_char() public void Frame_reads_char()
{ {
var value = (char) 'D'; var value = (char) 'D';
_actualFrame = new MqFrame(new byte[1], MqFrameType.Last, _config); _actualFrame = new MqFrame(new byte[1], MqFrameType.Last, _config);
_actualFrame.Write(0, value); _actualFrame.Write(0, value);
Assert.Equal(value, _actualFrame.ReadChar(0)); Assert.AreEqual(value, _actualFrame.ReadChar(0));
} }
[Fact] [Test]
public void Frame_reads_char_position() public void Frame_reads_char_position()
{ {
var value = (char) 'D'; var value = (char) 'D';
_actualFrame = new MqFrame(new byte[2], MqFrameType.Last, _config); _actualFrame = new MqFrame(new byte[2], MqFrameType.Last, _config);
_actualFrame.Write(1, value); _actualFrame.Write(1, value);
Assert.Equal(value, _actualFrame.ReadChar(1)); Assert.AreEqual(value, _actualFrame.ReadChar(1));
} }
[Fact] [Test]
public void Frame_writes_short_positive() public void Frame_writes_short_positive()
{ {
_expectedBytes = new byte[] {3, 2, 0, 93, 94}; _expectedBytes = new byte[] {3, 2, 0, 93, 94};
@ -312,10 +319,10 @@ namespace DtronixMessageQueue.Tests.Mq
_actualFrame.Write(0, (short) 24157); _actualFrame.Write(0, (short) 24157);
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_writes_short_negative() public void Frame_writes_short_negative()
{ {
_expectedBytes = new byte[] {3, 2, 0, 163, 161}; _expectedBytes = new byte[] {3, 2, 0, 163, 161};
@ -323,10 +330,10 @@ namespace DtronixMessageQueue.Tests.Mq
_actualFrame.Write(0, (short) -24157); _actualFrame.Write(0, (short) -24157);
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_writes_short_position() public void Frame_writes_short_position()
{ {
_expectedBytes = new byte[] {3, 3, 0, 0, 93, 94}; _expectedBytes = new byte[] {3, 3, 0, 0, 93, 94};
@ -334,31 +341,31 @@ namespace DtronixMessageQueue.Tests.Mq
_actualFrame.Write(1, (short) 24157); _actualFrame.Write(1, (short) 24157);
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_reads_short() public void Frame_reads_short()
{ {
var value = (short) 24157; var value = (short) 24157;
_actualFrame = new MqFrame(new byte[2], MqFrameType.Last, _config); _actualFrame = new MqFrame(new byte[2], MqFrameType.Last, _config);
_actualFrame.Write(0, value); _actualFrame.Write(0, value);
Assert.Equal(value, _actualFrame.ReadInt16(0)); Assert.AreEqual(value, _actualFrame.ReadInt16(0));
} }
[Fact] [Test]
public void Frame_reads_short_position() public void Frame_reads_short_position()
{ {
var value = (short) 24157; var value = (short) 24157;
_actualFrame = new MqFrame(new byte[3], MqFrameType.Last, _config); _actualFrame = new MqFrame(new byte[3], MqFrameType.Last, _config);
_actualFrame.Write(1, value); _actualFrame.Write(1, value);
Assert.Equal(value, _actualFrame.ReadInt16(1)); Assert.AreEqual(value, _actualFrame.ReadInt16(1));
} }
[Fact] [Test]
public void Frame_writes_ushort() public void Frame_writes_ushort()
{ {
_expectedBytes = new byte[] {3, 2, 0, 191, 215}; _expectedBytes = new byte[] {3, 2, 0, 191, 215};
@ -366,10 +373,10 @@ namespace DtronixMessageQueue.Tests.Mq
_actualFrame.Write(0, (ushort) 55231); _actualFrame.Write(0, (ushort) 55231);
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_writes_ushort_position() public void Frame_writes_ushort_position()
{ {
_expectedBytes = new byte[] {3, 3, 0, 0, 191, 215}; _expectedBytes = new byte[] {3, 3, 0, 0, 191, 215};
@ -377,31 +384,31 @@ namespace DtronixMessageQueue.Tests.Mq
_actualFrame.Write(1, (ushort) 55231); _actualFrame.Write(1, (ushort) 55231);
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_reads_ushort() public void Frame_reads_ushort()
{ {
var value = (ushort) 55231; var value = (ushort) 55231;
_actualFrame = new MqFrame(new byte[2], MqFrameType.Last, _config); _actualFrame = new MqFrame(new byte[2], MqFrameType.Last, _config);
_actualFrame.Write(0, value); _actualFrame.Write(0, value);
Assert.Equal(value, _actualFrame.ReadUInt16(0)); Assert.AreEqual(value, _actualFrame.ReadUInt16(0));
} }
[Fact] [Test]
public void Frame_reads_ushort_position() public void Frame_reads_ushort_position()
{ {
var value = (ushort) 55231; var value = (ushort) 55231;
_actualFrame = new MqFrame(new byte[3], MqFrameType.Last, _config); _actualFrame = new MqFrame(new byte[3], MqFrameType.Last, _config);
_actualFrame.Write(1, value); _actualFrame.Write(1, value);
Assert.Equal(value, _actualFrame.ReadUInt16(1)); Assert.AreEqual(value, _actualFrame.ReadUInt16(1));
} }
[Fact] [Test]
public void Frame_writes_int_positive() public void Frame_writes_int_positive()
{ {
_expectedBytes = new byte[] {3, 4, 0, 210, 2, 150, 73}; _expectedBytes = new byte[] {3, 4, 0, 210, 2, 150, 73};
@ -409,10 +416,10 @@ namespace DtronixMessageQueue.Tests.Mq
_actualFrame.Write(0, (int) 1234567890); _actualFrame.Write(0, (int) 1234567890);
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_writes_int_negative() public void Frame_writes_int_negative()
{ {
_expectedBytes = new byte[] {3, 4, 0, 46, 253, 105, 182}; _expectedBytes = new byte[] {3, 4, 0, 46, 253, 105, 182};
@ -420,10 +427,10 @@ namespace DtronixMessageQueue.Tests.Mq
_actualFrame.Write(0, (int) -1234567890); _actualFrame.Write(0, (int) -1234567890);
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_writes_int_position() public void Frame_writes_int_position()
{ {
_expectedBytes = new byte[] {3, 5, 0, 0, 210, 2, 150, 73}; _expectedBytes = new byte[] {3, 5, 0, 0, 210, 2, 150, 73};
@ -431,30 +438,30 @@ namespace DtronixMessageQueue.Tests.Mq
_actualFrame.Write(1, (int) 1234567890); _actualFrame.Write(1, (int) 1234567890);
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_reads_int() public void Frame_reads_int()
{ {
var value = (int) 1234567890; var value = (int) 1234567890;
_actualFrame = new MqFrame(new byte[4], MqFrameType.Last, _config); _actualFrame = new MqFrame(new byte[4], MqFrameType.Last, _config);
_actualFrame.Write(0, value); _actualFrame.Write(0, value);
Assert.Equal(value, _actualFrame.ReadInt32(0)); Assert.AreEqual(value, _actualFrame.ReadInt32(0));
} }
[Fact] [Test]
public void Frame_reads_int_position() public void Frame_reads_int_position()
{ {
var value = (int) 1234567890; var value = (int) 1234567890;
_actualFrame = new MqFrame(new byte[5], MqFrameType.Last, _config); _actualFrame = new MqFrame(new byte[5], MqFrameType.Last, _config);
_actualFrame.Write(1, value); _actualFrame.Write(1, value);
Assert.Equal(value, _actualFrame.ReadInt32(1)); Assert.AreEqual(value, _actualFrame.ReadInt32(1));
} }
[Fact] [Test]
public void Frame_writes_uint() public void Frame_writes_uint()
{ {
_expectedBytes = new byte[] {3, 4, 0, 167, 251, 4, 253}; _expectedBytes = new byte[] {3, 4, 0, 167, 251, 4, 253};
@ -462,11 +469,11 @@ namespace DtronixMessageQueue.Tests.Mq
_actualFrame.Write(0, (uint) 4244962215); _actualFrame.Write(0, (uint) 4244962215);
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_writes_uint_position() public void Frame_writes_uint_position()
{ {
_expectedBytes = new byte[] {3, 4, 0, 167, 251, 4, 253}; _expectedBytes = new byte[] {3, 4, 0, 167, 251, 4, 253};
@ -474,31 +481,31 @@ namespace DtronixMessageQueue.Tests.Mq
_actualFrame.Write(0, (uint) 4244962215); _actualFrame.Write(0, (uint) 4244962215);
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_reads_uint() public void Frame_reads_uint()
{ {
var value = (uint) 4244962215; var value = (uint) 4244962215;
_actualFrame = new MqFrame(new byte[4], MqFrameType.Last, _config); _actualFrame = new MqFrame(new byte[4], MqFrameType.Last, _config);
_actualFrame.Write(0, value); _actualFrame.Write(0, value);
Assert.Equal(value, _actualFrame.ReadUInt32(0)); Assert.AreEqual(value, _actualFrame.ReadUInt32(0));
} }
[Fact] [Test]
public void Frame_reads_uint_position() public void Frame_reads_uint_position()
{ {
var value = (uint) 4244962215; var value = (uint) 4244962215;
_actualFrame = new MqFrame(new byte[5], MqFrameType.Last, _config); _actualFrame = new MqFrame(new byte[5], MqFrameType.Last, _config);
_actualFrame.Write(1, value); _actualFrame.Write(1, value);
Assert.Equal(value, _actualFrame.ReadUInt32(1)); Assert.AreEqual(value, _actualFrame.ReadUInt32(1));
} }
[Fact] [Test]
public void Frame_writes_long_positive() public void Frame_writes_long_positive()
{ {
_expectedBytes = new byte[] {3, 8, 0, 178, 125, 244, 181, 59, 233, 33, 17}; _expectedBytes = new byte[] {3, 8, 0, 178, 125, 244, 181, 59, 233, 33, 17};
@ -506,10 +513,10 @@ namespace DtronixMessageQueue.Tests.Mq
_actualFrame.Write(0, (long) 1234524215541267890); _actualFrame.Write(0, (long) 1234524215541267890);
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_writes_long_negative() public void Frame_writes_long_negative()
{ {
_expectedBytes = new byte[] {3, 8, 0, 78, 130, 11, 74, 196, 22, 222, 238}; _expectedBytes = new byte[] {3, 8, 0, 78, 130, 11, 74, 196, 22, 222, 238};
@ -517,10 +524,10 @@ namespace DtronixMessageQueue.Tests.Mq
_actualFrame.Write(0, (long) -1234524215541267890); _actualFrame.Write(0, (long) -1234524215541267890);
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_writes_long_position() public void Frame_writes_long_position()
{ {
_expectedBytes = new byte[] {3, 9, 0, 0, 178, 125, 244, 181, 59, 233, 33, 17}; _expectedBytes = new byte[] {3, 9, 0, 0, 178, 125, 244, 181, 59, 233, 33, 17};
@ -528,30 +535,30 @@ namespace DtronixMessageQueue.Tests.Mq
_actualFrame.Write(1, (long) 1234524215541267890); _actualFrame.Write(1, (long) 1234524215541267890);
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_reads_long() public void Frame_reads_long()
{ {
var value = (long) 4244962215; var value = (long) 4244962215;
_actualFrame = new MqFrame(new byte[8], MqFrameType.Last, _config); _actualFrame = new MqFrame(new byte[8], MqFrameType.Last, _config);
_actualFrame.Write(0, value); _actualFrame.Write(0, value);
Assert.Equal(value, _actualFrame.ReadInt64(0)); Assert.AreEqual(value, _actualFrame.ReadInt64(0));
} }
[Fact] [Test]
public void Frame_reads_long_position() public void Frame_reads_long_position()
{ {
var value = (long) 4244962215; var value = (long) 4244962215;
_actualFrame = new MqFrame(new byte[9], MqFrameType.Last, _config); _actualFrame = new MqFrame(new byte[9], MqFrameType.Last, _config);
_actualFrame.Write(1, value); _actualFrame.Write(1, value);
Assert.Equal(value, _actualFrame.ReadInt64(1)); Assert.AreEqual(value, _actualFrame.ReadInt64(1));
} }
[Fact] [Test]
public void Frame_writes_ulong() public void Frame_writes_ulong()
{ {
_expectedBytes = new byte[] {3, 8, 0, 63, 244, 163, 154, 134, 47, 214, 251}; _expectedBytes = new byte[] {3, 8, 0, 63, 244, 163, 154, 134, 47, 214, 251};
@ -560,10 +567,10 @@ namespace DtronixMessageQueue.Tests.Mq
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_writes_ulong_position() public void Frame_writes_ulong_position()
{ {
_expectedBytes = new byte[] {3, 9, 0, 0, 63, 244, 163, 154, 134, 47, 214, 251}; _expectedBytes = new byte[] {3, 9, 0, 0, 63, 244, 163, 154, 134, 47, 214, 251};
@ -572,31 +579,31 @@ namespace DtronixMessageQueue.Tests.Mq
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_reads_ulong() public void Frame_reads_ulong()
{ {
var value = (ulong) 18146744003702551615; var value = (ulong) 18146744003702551615;
_actualFrame = new MqFrame(new byte[8], MqFrameType.Last, _config); _actualFrame = new MqFrame(new byte[8], MqFrameType.Last, _config);
_actualFrame.Write(0, value); _actualFrame.Write(0, value);
Assert.Equal(value, _actualFrame.ReadUInt64(0)); Assert.AreEqual(value, _actualFrame.ReadUInt64(0));
} }
[Fact] [Test]
public void Frame_reads_ulong_position() public void Frame_reads_ulong_position()
{ {
var value = (ulong) 18146744003702551615; var value = (ulong) 18146744003702551615;
_actualFrame = new MqFrame(new byte[9], MqFrameType.Last, _config); _actualFrame = new MqFrame(new byte[9], MqFrameType.Last, _config);
_actualFrame.Write(1, value); _actualFrame.Write(1, value);
Assert.Equal(value, _actualFrame.ReadUInt64(1)); Assert.AreEqual(value, _actualFrame.ReadUInt64(1));
} }
[Fact] [Test]
public void Frame_writes_float() public void Frame_writes_float()
{ {
_expectedBytes = new byte[] {3, 4, 0, 121, 233, 246, 66}; _expectedBytes = new byte[] {3, 4, 0, 121, 233, 246, 66};
@ -605,10 +612,10 @@ namespace DtronixMessageQueue.Tests.Mq
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_writes_float_position() public void Frame_writes_float_position()
{ {
_expectedBytes = new byte[] {3, 5, 0, 0, 121, 233, 246, 66}; _expectedBytes = new byte[] {3, 5, 0, 0, 121, 233, 246, 66};
@ -617,30 +624,30 @@ namespace DtronixMessageQueue.Tests.Mq
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_reads_float() public void Frame_reads_float()
{ {
var value = (float) 123.456; var value = (float) 123.456;
_actualFrame = new MqFrame(new byte[4], MqFrameType.Last, _config); _actualFrame = new MqFrame(new byte[4], MqFrameType.Last, _config);
_actualFrame.Write(0, value); _actualFrame.Write(0, value);
Assert.Equal(value, _actualFrame.ReadSingle(0)); Assert.AreEqual(value, _actualFrame.ReadSingle(0));
} }
[Fact] [Test]
public void Frame_reads_float_position() public void Frame_reads_float_position()
{ {
var value = (float) 123.456; var value = (float) 123.456;
_actualFrame = new MqFrame(new byte[5], MqFrameType.Last, _config); _actualFrame = new MqFrame(new byte[5], MqFrameType.Last, _config);
_actualFrame.Write(1, value); _actualFrame.Write(1, value);
Assert.Equal(value, _actualFrame.ReadSingle(1)); Assert.AreEqual(value, _actualFrame.ReadSingle(1));
} }
[Fact] [Test]
public void Frame_writes_double() public void Frame_writes_double()
{ {
_expectedBytes = new byte[] {3, 8, 0, 119, 219, 133, 230, 214, 28, 200, 64}; _expectedBytes = new byte[] {3, 8, 0, 119, 219, 133, 230, 214, 28, 200, 64};
@ -649,10 +656,10 @@ namespace DtronixMessageQueue.Tests.Mq
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_writes_double_position() public void Frame_writes_double_position()
{ {
_expectedBytes = new byte[] {3, 9, 0, 0, 119, 219, 133, 230, 214, 28, 200, 64}; _expectedBytes = new byte[] {3, 9, 0, 0, 119, 219, 133, 230, 214, 28, 200, 64};
@ -661,31 +668,31 @@ namespace DtronixMessageQueue.Tests.Mq
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_reads_double() public void Frame_reads_double()
{ {
var value = (double) 12345.67891; var value = (double) 12345.67891;
_actualFrame = new MqFrame(new byte[8], MqFrameType.Last, _config); _actualFrame = new MqFrame(new byte[8], MqFrameType.Last, _config);
_actualFrame.Write(0, value); _actualFrame.Write(0, value);
Assert.Equal(value, _actualFrame.ReadDouble(0)); Assert.AreEqual(value, _actualFrame.ReadDouble(0));
} }
[Fact] [Test]
public void Frame_reads_double_position() public void Frame_reads_double_position()
{ {
var value = (double) 12345.67891; var value = (double) 12345.67891;
_actualFrame = new MqFrame(new byte[9], MqFrameType.Last, _config); _actualFrame = new MqFrame(new byte[9], MqFrameType.Last, _config);
_actualFrame.Write(1, value); _actualFrame.Write(1, value);
Assert.Equal(value, _actualFrame.ReadDouble(1)); Assert.AreEqual(value, _actualFrame.ReadDouble(1));
} }
[Fact] [Test]
public void Frame_writes_decimal() public void Frame_writes_decimal()
{ {
_expectedBytes = new byte[] {3, 16, 0, 160, 107, 84, 143, 156, 7, 157, 126, 0, 0, 0, 0, 0, 0, 0, 0}; _expectedBytes = new byte[] {3, 16, 0, 160, 107, 84, 143, 156, 7, 157, 126, 0, 0, 0, 0, 0, 0, 0, 0};
@ -694,10 +701,10 @@ namespace DtronixMessageQueue.Tests.Mq
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_writes_decimal_position() public void Frame_writes_decimal_position()
{ {
_expectedBytes = new byte[] {3, 17, 0, 0, 160, 107, 84, 143, 156, 7, 157, 126, 0, 0, 0, 0, 0, 0, 0, 0}; _expectedBytes = new byte[] {3, 17, 0, 0, 160, 107, 84, 143, 156, 7, 157, 126, 0, 0, 0, 0, 0, 0, 0, 0};
@ -706,30 +713,30 @@ namespace DtronixMessageQueue.Tests.Mq
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_reads_decimal() public void Frame_reads_decimal()
{ {
var value = (decimal) 9123456789123456789.9123456789123456789; var value = (decimal) 9123456789123456789.9123456789123456789;
_actualFrame = new MqFrame(new byte[16], MqFrameType.Last, _config); _actualFrame = new MqFrame(new byte[16], MqFrameType.Last, _config);
_actualFrame.Write(0, value); _actualFrame.Write(0, value);
Assert.Equal(value, _actualFrame.ReadDecimal(0)); Assert.AreEqual(value, _actualFrame.ReadDecimal(0));
} }
[Fact] [Test]
public void Frame_reads_decimal_position() public void Frame_reads_decimal_position()
{ {
var value = (decimal) 9123456789123456789.9123456789123456789; var value = (decimal) 9123456789123456789.9123456789123456789;
_actualFrame = new MqFrame(new byte[17], MqFrameType.Last, _config); _actualFrame = new MqFrame(new byte[17], MqFrameType.Last, _config);
_actualFrame.Write(1, value); _actualFrame.Write(1, value);
Assert.Equal(value, _actualFrame.ReadDecimal(1)); Assert.AreEqual(value, _actualFrame.ReadDecimal(1));
} }
[Fact] [Test]
public void Frame_writes_sbyte_positive() public void Frame_writes_sbyte_positive()
{ {
_expectedBytes = new byte[] {3, 1, 0, 101}; _expectedBytes = new byte[] {3, 1, 0, 101};
@ -738,10 +745,10 @@ namespace DtronixMessageQueue.Tests.Mq
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_writes_ascii_text_prepended_with_size() public void Frame_writes_ascii_text_prepended_with_size()
{ {
_expectedBytes = new byte[] _expectedBytes = new byte[]
@ -756,10 +763,10 @@ namespace DtronixMessageQueue.Tests.Mq
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_writes_ascii_text_prepended_with_size_position() public void Frame_writes_ascii_text_prepended_with_size_position()
{ {
_expectedBytes = new byte[] _expectedBytes = new byte[]
@ -775,10 +782,10 @@ namespace DtronixMessageQueue.Tests.Mq
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_writes_ascii_text_not_prepended_with_size() public void Frame_writes_ascii_text_not_prepended_with_size()
{ {
_expectedBytes = new byte[] _expectedBytes = new byte[]
@ -792,10 +799,10 @@ namespace DtronixMessageQueue.Tests.Mq
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_writes_ascii_text_not_prepended_with_size_position() public void Frame_writes_ascii_text_not_prepended_with_size_position()
{ {
_expectedBytes = new byte[] _expectedBytes = new byte[]
@ -810,31 +817,31 @@ namespace DtronixMessageQueue.Tests.Mq
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_reads_ascii_text_prepended_with_size() public void Frame_reads_ascii_text_prepended_with_size()
{ {
var value = "abcdefghijklmnopqrstuvwxyz"; var value = "abcdefghijklmnopqrstuvwxyz";
_actualFrame = new MqFrame(new byte[28], MqFrameType.Last, _config); _actualFrame = new MqFrame(new byte[28], MqFrameType.Last, _config);
_actualFrame.WriteAscii(0, value, true); _actualFrame.WriteAscii(0, value, true);
Assert.Equal(value, _actualFrame.ReadAscii(0)); Assert.AreEqual(value, _actualFrame.ReadAscii(0));
} }
[Fact] [Test]
public void Frame_reads_ascii_text_not_prepended_with_size() public void Frame_reads_ascii_text_not_prepended_with_size()
{ {
var value = "abcdefghijklmnopqrstuvwxyz"; var value = "abcdefghijklmnopqrstuvwxyz";
_actualFrame = new MqFrame(new byte[26], MqFrameType.Last, _config); _actualFrame = new MqFrame(new byte[26], MqFrameType.Last, _config);
_actualFrame.WriteAscii(0, value, false); _actualFrame.WriteAscii(0, value, false);
Assert.Equal(value, _actualFrame.ReadAscii(0, _actualFrame.DataLength)); Assert.AreEqual(value, _actualFrame.ReadAscii(0, _actualFrame.DataLength));
} }
[Fact] [Test]
public void Frame_throws_on_ascii_text_write_when_larger_than_frame() public void Frame_throws_on_ascii_text_write_when_larger_than_frame()
{ {
var value = "abcdefghijklmnopqrstuvwxyz"; var value = "abcdefghijklmnopqrstuvwxyz";
@ -848,7 +855,7 @@ namespace DtronixMessageQueue.Tests.Mq
Assert.Throws<InvalidOperationException>(() => _actualFrame.WriteAscii(0, value, false)); Assert.Throws<InvalidOperationException>(() => _actualFrame.WriteAscii(0, value, false));
} }
[Fact] [Test]
public void Frame_writes_guid() public void Frame_writes_guid()
{ {
var value = Guid.NewGuid(); var value = Guid.NewGuid();
@ -862,10 +869,10 @@ namespace DtronixMessageQueue.Tests.Mq
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_writes_guid_position() public void Frame_writes_guid_position()
{ {
var value = Guid.NewGuid(); var value = Guid.NewGuid();
@ -879,27 +886,27 @@ namespace DtronixMessageQueue.Tests.Mq
_actualBytes = _actualFrame.RawFrame(); _actualBytes = _actualFrame.RawFrame();
Assert.Equal(_expectedBytes, _actualBytes); Assert.AreEqual(_expectedBytes, _actualBytes);
} }
[Fact] [Test]
public void Frame_reads_guid() public void Frame_reads_guid()
{ {
var value = Guid.NewGuid(); var value = Guid.NewGuid();
_actualFrame = new MqFrame(new byte[16], MqFrameType.Last, _config); _actualFrame = new MqFrame(new byte[16], MqFrameType.Last, _config);
_actualFrame.Write(0, value); _actualFrame.Write(0, value);
Assert.Equal(value, _actualFrame.ReadGuid(0)); Assert.AreEqual(value, _actualFrame.ReadGuid(0));
} }
[Fact] [Test]
public void Frame_reads_guid_position() public void Frame_reads_guid_position()
{ {
var value = Guid.NewGuid(); var value = Guid.NewGuid();
_actualFrame = new MqFrame(new byte[17], MqFrameType.Last, _config); _actualFrame = new MqFrame(new byte[17], MqFrameType.Last, _config);
_actualFrame.Write(1, value); _actualFrame.Write(1, value);
Assert.Equal(value, _actualFrame.ReadGuid(1)); Assert.AreEqual(value, _actualFrame.ReadGuid(1));
} }
} }
} }

Просмотреть файл

@ -1,14 +1,13 @@
using System; using System;
using System.Text; using System.Text;
using Xunit; using NUnit.Framework;
using Xunit.Abstractions;
using Assert = Xunit.Assert;
namespace DtronixMessageQueue.Tests.Mq namespace DtronixMessageQueue.Tests.Mq
{ {
[TestFixture]
public class MqMessageWriterReaderTests public class MqMessageWriterReaderTests
{ {
public ITestOutputHelper Output;
private MqMessageWriter _messageBuilder; private MqMessageWriter _messageBuilder;
private MqMessageReader _messageReader; private MqMessageReader _messageReader;
private MqConfig _config = new MqConfig(); private MqConfig _config = new MqConfig();
@ -16,14 +15,18 @@ namespace DtronixMessageQueue.Tests.Mq
private const string FillerText = private const string FillerText =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."; "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
public MqMessageWriterReaderTests(ITestOutputHelper output) public MqMessageWriterReaderTests()
{
}
[SetUp]
public void Init()
{ {
Output = output;
_messageBuilder = new MqMessageWriter(_config); _messageBuilder = new MqMessageWriter(_config);
_messageReader = new MqMessageReader(); _messageReader = new MqMessageReader();
} }
[Fact] [Test]
public void MessageWriter_writes_bool_true() public void MessageWriter_writes_bool_true()
{ {
var expectedValue = (bool) true; var expectedValue = (bool) true;
@ -31,11 +34,11 @@ namespace DtronixMessageQueue.Tests.Mq
var message = _messageBuilder.ToMessage(); var message = _messageBuilder.ToMessage();
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(expectedValue, _messageReader.ReadBoolean()); Assert.AreEqual(expectedValue, _messageReader.ReadBoolean());
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageWriter_writes_bool_false() public void MessageWriter_writes_bool_false()
{ {
var expectedValue = (bool) false; var expectedValue = (bool) false;
@ -43,11 +46,11 @@ namespace DtronixMessageQueue.Tests.Mq
var message = _messageBuilder.ToMessage(); var message = _messageBuilder.ToMessage();
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(expectedValue, _messageReader.ReadBoolean()); Assert.AreEqual(expectedValue, _messageReader.ReadBoolean());
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageWriter_writes_byte() public void MessageWriter_writes_byte()
{ {
var expectedValue = (byte) 221; var expectedValue = (byte) 221;
@ -55,11 +58,11 @@ namespace DtronixMessageQueue.Tests.Mq
var message = _messageBuilder.ToMessage(); var message = _messageBuilder.ToMessage();
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(expectedValue, _messageReader.ReadByte()); Assert.AreEqual(expectedValue, _messageReader.ReadByte());
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageWriter_writes_sbyte_positive() public void MessageWriter_writes_sbyte_positive()
{ {
var expectedValue = (sbyte) 101; var expectedValue = (sbyte) 101;
@ -67,11 +70,11 @@ namespace DtronixMessageQueue.Tests.Mq
var message = _messageBuilder.ToMessage(); var message = _messageBuilder.ToMessage();
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(expectedValue, _messageReader.ReadSByte()); Assert.AreEqual(expectedValue, _messageReader.ReadSByte());
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageWriter_writes_sbyte_negative() public void MessageWriter_writes_sbyte_negative()
{ {
var expectedValue = (sbyte) -101; var expectedValue = (sbyte) -101;
@ -79,11 +82,11 @@ namespace DtronixMessageQueue.Tests.Mq
var message = _messageBuilder.ToMessage(); var message = _messageBuilder.ToMessage();
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(expectedValue, _messageReader.ReadSByte()); Assert.AreEqual(expectedValue, _messageReader.ReadSByte());
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageWriter_writes_short_positive() public void MessageWriter_writes_short_positive()
{ {
var expectedValue = (short) 21457; var expectedValue = (short) 21457;
@ -91,11 +94,11 @@ namespace DtronixMessageQueue.Tests.Mq
var message = _messageBuilder.ToMessage(); var message = _messageBuilder.ToMessage();
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(expectedValue, _messageReader.ReadInt16()); Assert.AreEqual(expectedValue, _messageReader.ReadInt16());
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageWriter_writes_short_negative() public void MessageWriter_writes_short_negative()
{ {
var expectedValue = (short) -21457; var expectedValue = (short) -21457;
@ -103,11 +106,11 @@ namespace DtronixMessageQueue.Tests.Mq
var message = _messageBuilder.ToMessage(); var message = _messageBuilder.ToMessage();
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(expectedValue, _messageReader.ReadInt16()); Assert.AreEqual(expectedValue, _messageReader.ReadInt16());
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageWriter_writes_ushort() public void MessageWriter_writes_ushort()
{ {
var expectedValue = (ushort) 51574; var expectedValue = (ushort) 51574;
@ -115,11 +118,11 @@ namespace DtronixMessageQueue.Tests.Mq
var message = _messageBuilder.ToMessage(); var message = _messageBuilder.ToMessage();
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(expectedValue, _messageReader.ReadUInt16()); Assert.AreEqual(expectedValue, _messageReader.ReadUInt16());
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageWriter_writes_int_positive() public void MessageWriter_writes_int_positive()
{ {
var expectedValue = (int) 515725234; var expectedValue = (int) 515725234;
@ -127,11 +130,11 @@ namespace DtronixMessageQueue.Tests.Mq
var message = _messageBuilder.ToMessage(); var message = _messageBuilder.ToMessage();
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(expectedValue, _messageReader.ReadInt32()); Assert.AreEqual(expectedValue, _messageReader.ReadInt32());
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageWriter_writes_int_negative() public void MessageWriter_writes_int_negative()
{ {
var expectedValue = (int) -515725234; var expectedValue = (int) -515725234;
@ -139,11 +142,11 @@ namespace DtronixMessageQueue.Tests.Mq
var message = _messageBuilder.ToMessage(); var message = _messageBuilder.ToMessage();
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(expectedValue, _messageReader.ReadInt32()); Assert.AreEqual(expectedValue, _messageReader.ReadInt32());
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageWriter_writes_uint() public void MessageWriter_writes_uint()
{ {
var expectedValue = (uint) 1215725234; var expectedValue = (uint) 1215725234;
@ -151,11 +154,11 @@ namespace DtronixMessageQueue.Tests.Mq
var message = _messageBuilder.ToMessage(); var message = _messageBuilder.ToMessage();
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(expectedValue, _messageReader.ReadUInt32()); Assert.AreEqual(expectedValue, _messageReader.ReadUInt32());
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageWriter_writes_long_positive() public void MessageWriter_writes_long_positive()
{ {
var expectedValue = (long) 515352135236725234; var expectedValue = (long) 515352135236725234;
@ -163,11 +166,11 @@ namespace DtronixMessageQueue.Tests.Mq
var message = _messageBuilder.ToMessage(); var message = _messageBuilder.ToMessage();
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(expectedValue, _messageReader.ReadInt64()); Assert.AreEqual(expectedValue, _messageReader.ReadInt64());
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageWriter_writes_long_negative() public void MessageWriter_writes_long_negative()
{ {
var expectedValue = (long) -515352135236725234; var expectedValue = (long) -515352135236725234;
@ -175,11 +178,11 @@ namespace DtronixMessageQueue.Tests.Mq
var message = _messageBuilder.ToMessage(); var message = _messageBuilder.ToMessage();
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(expectedValue, _messageReader.ReadInt64()); Assert.AreEqual(expectedValue, _messageReader.ReadInt64());
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageWriter_writes_ulong() public void MessageWriter_writes_ulong()
{ {
var expectedValue = (ulong) 12231512365365725234; var expectedValue = (ulong) 12231512365365725234;
@ -187,11 +190,11 @@ namespace DtronixMessageQueue.Tests.Mq
var message = _messageBuilder.ToMessage(); var message = _messageBuilder.ToMessage();
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(expectedValue, _messageReader.ReadUInt64()); Assert.AreEqual(expectedValue, _messageReader.ReadUInt64());
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageWriter_writes_float() public void MessageWriter_writes_float()
{ {
var expectedValue = (float) 123.456; var expectedValue = (float) 123.456;
@ -199,11 +202,11 @@ namespace DtronixMessageQueue.Tests.Mq
var message = _messageBuilder.ToMessage(); var message = _messageBuilder.ToMessage();
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(expectedValue, _messageReader.ReadSingle()); Assert.AreEqual(expectedValue, _messageReader.ReadSingle());
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageWriter_writes_double() public void MessageWriter_writes_double()
{ {
var expectedValue = (double) 12345.67891; var expectedValue = (double) 12345.67891;
@ -211,11 +214,11 @@ namespace DtronixMessageQueue.Tests.Mq
var message = _messageBuilder.ToMessage(); var message = _messageBuilder.ToMessage();
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(expectedValue, _messageReader.ReadDouble()); Assert.AreEqual(expectedValue, _messageReader.ReadDouble());
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageWriter_writes_decimal() public void MessageWriter_writes_decimal()
{ {
var expectedValue = (decimal) 9123456789123456789.9123456789123456789; var expectedValue = (decimal) 9123456789123456789.9123456789123456789;
@ -223,11 +226,11 @@ namespace DtronixMessageQueue.Tests.Mq
var message = _messageBuilder.ToMessage(); var message = _messageBuilder.ToMessage();
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(expectedValue, _messageReader.ReadDecimal()); Assert.AreEqual(expectedValue, _messageReader.ReadDecimal());
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageWriter_writes_multi_frame_byte_array() public void MessageWriter_writes_multi_frame_byte_array()
{ {
var expectedValue = new byte[1024 * 32]; var expectedValue = new byte[1024 * 32];
@ -255,7 +258,7 @@ namespace DtronixMessageQueue.Tests.Mq
byteArraySize += frame.DataLength; byteArraySize += frame.DataLength;
} }
Assert.Equal(expectedValue.Length, byteArraySize); Assert.AreEqual(expectedValue.Length, byteArraySize);
var resultByteArray = new byte[byteArraySize]; var resultByteArray = new byte[byteArraySize];
var position = 0; var position = 0;
@ -265,10 +268,10 @@ namespace DtronixMessageQueue.Tests.Mq
position += frame.DataLength; position += frame.DataLength;
} }
Assert.Equal(expectedValue, resultByteArray); Assert.AreEqual(expectedValue, resultByteArray);
} }
[Fact] [Test]
public void MessageWriter_writes_multi_frame_string_bytes() public void MessageWriter_writes_multi_frame_string_bytes()
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
@ -293,7 +296,7 @@ namespace DtronixMessageQueue.Tests.Mq
VerifyMessageBytes(expectedBytes, message); VerifyMessageBytes(expectedBytes, message);
} }
[Fact] [Test]
public void MessageReader_reads_multi_frame_byte_array() public void MessageReader_reads_multi_frame_byte_array()
{ {
var expectedValue = new byte[1024 * 32]; var expectedValue = new byte[1024 * 32];
@ -314,13 +317,13 @@ namespace DtronixMessageQueue.Tests.Mq
var read = _messageReader.Read(actualValue, 0, actualValue.Length); var read = _messageReader.Read(actualValue, 0, actualValue.Length);
Assert.Equal(expectedValue.Length, read); Assert.AreEqual(expectedValue.Length, read);
Assert.Equal(expectedValue, actualValue); Assert.AreEqual(expectedValue, actualValue);
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageWriter_writes_string() public void MessageWriter_writes_string()
{ {
var expectedValue = FillerText; var expectedValue = FillerText;
@ -328,12 +331,12 @@ namespace DtronixMessageQueue.Tests.Mq
var message = _messageBuilder.ToMessage(); var message = _messageBuilder.ToMessage();
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(expectedValue, _messageReader.ReadString()); Assert.AreEqual(expectedValue, _messageReader.ReadString());
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageReader_reads_multi_frame_string() public void MessageReader_reads_multi_frame_string()
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
@ -348,12 +351,12 @@ namespace DtronixMessageQueue.Tests.Mq
var message = _messageBuilder.ToMessage(); var message = _messageBuilder.ToMessage();
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(expectedValue, _messageReader.ReadString()); Assert.AreEqual(expectedValue, _messageReader.ReadString());
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageWriter_multiple_reads_writes() public void MessageWriter_multiple_reads_writes()
{ {
@ -395,46 +398,46 @@ namespace DtronixMessageQueue.Tests.Mq
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(true, _messageReader.ReadBoolean()); Assert.AreEqual(true, _messageReader.ReadBoolean());
Assert.Equal(false, _messageReader.ReadBoolean()); Assert.AreEqual(false, _messageReader.ReadBoolean());
Assert.Equal('D', _messageReader.ReadChar()); Assert.AreEqual('D', _messageReader.ReadChar());
Assert.Equal(new char[] {'A', 'Y', 'X', '0', '9', '8'}, _messageReader.ReadChars(6)); Assert.AreEqual(new char[] {'A', 'Y', 'X', '0', '9', '8'}, _messageReader.ReadChars(6));
Assert.Equal((byte) 214, _messageReader.ReadByte()); Assert.AreEqual((byte) 214, _messageReader.ReadByte());
Assert.Equal((sbyte) 125, _messageReader.ReadSByte()); Assert.AreEqual((sbyte) 125, _messageReader.ReadSByte());
Assert.Equal((sbyte) -125, _messageReader.ReadSByte()); Assert.AreEqual((sbyte) -125, _messageReader.ReadSByte());
Assert.Equal((short) 4513, _messageReader.ReadInt16()); Assert.AreEqual((short) 4513, _messageReader.ReadInt16());
Assert.Equal((short) -4513, _messageReader.ReadInt16()); Assert.AreEqual((short) -4513, _messageReader.ReadInt16());
Assert.Equal((ushort) 43513, _messageReader.ReadUInt16()); Assert.AreEqual((ushort) 43513, _messageReader.ReadUInt16());
Assert.Equal((int) 236236231, _messageReader.ReadInt32()); Assert.AreEqual((int) 236236231, _messageReader.ReadInt32());
Assert.Equal((int) -236236231, _messageReader.ReadInt32()); Assert.AreEqual((int) -236236231, _messageReader.ReadInt32());
Assert.Equal((uint) 2362326231, _messageReader.ReadUInt32()); Assert.AreEqual((uint) 2362326231, _messageReader.ReadUInt32());
Assert.Equal((long) 2362362312561531, _messageReader.ReadInt64()); Assert.AreEqual((long) 2362362312561531, _messageReader.ReadInt64());
Assert.Equal((long) -2362362312561531, _messageReader.ReadInt64()); Assert.AreEqual((long) -2362362312561531, _messageReader.ReadInt64());
Assert.Equal((ulong) 2362362312561531125, _messageReader.ReadUInt64()); Assert.AreEqual((ulong) 2362362312561531125, _messageReader.ReadUInt64());
Assert.Equal((float) 1234.56789, _messageReader.ReadSingle()); Assert.AreEqual((float) 1234.56789, _messageReader.ReadSingle());
Assert.Equal((double) 123467.5678912, _messageReader.ReadDouble()); Assert.AreEqual((double) 123467.5678912, _messageReader.ReadDouble());
Assert.Equal((decimal) 123456789123456789.123456789123456789, _messageReader.ReadDecimal()); Assert.AreEqual((decimal) 123456789123456789.123456789123456789, _messageReader.ReadDecimal());
var readByteArray = new byte[50]; var readByteArray = new byte[50];
_messageReader.Read(readByteArray, 0, readByteArray.Length); _messageReader.Read(readByteArray, 0, readByteArray.Length);
Assert.Equal(expectedByteArray, readByteArray); Assert.AreEqual(expectedByteArray, readByteArray);
Assert.Equal(FillerText, _messageReader.ReadString()); Assert.AreEqual(FillerText, _messageReader.ReadString());
Assert.Equal(expectedGuid, _messageReader.ReadGuid()); Assert.AreEqual(expectedGuid, _messageReader.ReadGuid());
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageWriter_writes_char() public void MessageWriter_writes_char()
{ {
var expectedValue = (char) 'D'; var expectedValue = (char) 'D';
@ -442,11 +445,11 @@ namespace DtronixMessageQueue.Tests.Mq
var message = _messageBuilder.ToMessage(); var message = _messageBuilder.ToMessage();
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(expectedValue, _messageReader.ReadChar()); Assert.AreEqual(expectedValue, _messageReader.ReadChar());
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageWriter_writes_char_array() public void MessageWriter_writes_char_array()
{ {
var expectedValue = new char[] {'A', 'B', 'C', '1', '2', '3'}; var expectedValue = new char[] {'A', 'B', 'C', '1', '2', '3'};
@ -454,11 +457,11 @@ namespace DtronixMessageQueue.Tests.Mq
var message = _messageBuilder.ToMessage(); var message = _messageBuilder.ToMessage();
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(expectedValue, _messageReader.ReadChars(expectedValue.Length)); Assert.AreEqual(expectedValue, _messageReader.ReadChars(expectedValue.Length));
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageWriter_writes_char_array_slice() public void MessageWriter_writes_char_array_slice()
{ {
var inputValue = new char[] {'A', 'B', 'C', '1', '2', '3'}; var inputValue = new char[] {'A', 'B', 'C', '1', '2', '3'};
@ -467,11 +470,11 @@ namespace DtronixMessageQueue.Tests.Mq
var message = _messageBuilder.ToMessage(); var message = _messageBuilder.ToMessage();
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(expectedValue, _messageReader.ReadChars(expectedValue.Length)); Assert.AreEqual(expectedValue, _messageReader.ReadChars(expectedValue.Length));
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageReader_peeks_char() public void MessageReader_peeks_char()
{ {
var expectedValue = new char[] {'D', 'Z'}; var expectedValue = new char[] {'D', 'Z'};
@ -479,12 +482,12 @@ namespace DtronixMessageQueue.Tests.Mq
var message = _messageBuilder.ToMessage(); var message = _messageBuilder.ToMessage();
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(expectedValue[0], _messageReader.PeekChar()); Assert.AreEqual(expectedValue[0], _messageReader.PeekChar());
Assert.Equal(expectedValue, _messageReader.ReadChars(expectedValue.Length)); Assert.AreEqual(expectedValue, _messageReader.ReadChars(expectedValue.Length));
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageReader_reads_to_end() public void MessageReader_reads_to_end()
{ {
var expectedValue = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; var expectedValue = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
@ -492,11 +495,11 @@ namespace DtronixMessageQueue.Tests.Mq
var message = _messageBuilder.ToMessage(); var message = _messageBuilder.ToMessage();
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(expectedValue, _messageReader.ReadToEnd()); Assert.AreEqual(expectedValue, _messageReader.ReadToEnd());
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageReader_reads_to_end_multi_frame() public void MessageReader_reads_to_end_multi_frame()
{ {
var expectedValue = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}; var expectedValue = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
@ -508,11 +511,11 @@ namespace DtronixMessageQueue.Tests.Mq
var message = _messageBuilder.ToMessage(); var message = _messageBuilder.ToMessage();
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(expectedValue, _messageReader.ReadToEnd()); Assert.AreEqual(expectedValue, _messageReader.ReadToEnd());
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageReader_reads_to_end_multi_frame_skipping_empty_frame() public void MessageReader_reads_to_end_multi_frame_skipping_empty_frame()
{ {
var expectedValue = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}; var expectedValue = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
@ -525,12 +528,12 @@ namespace DtronixMessageQueue.Tests.Mq
var message = _messageBuilder.ToMessage(); var message = _messageBuilder.ToMessage();
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(expectedValue, _messageReader.ReadToEnd()); Assert.AreEqual(expectedValue, _messageReader.ReadToEnd());
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageReader_reads_to_end_partial() public void MessageReader_reads_to_end_partial()
{ {
var expectedValue = new byte[] {4, 5, 6, 7, 8, 9, 10}; var expectedValue = new byte[] {4, 5, 6, 7, 8, 9, 10};
@ -539,12 +542,12 @@ namespace DtronixMessageQueue.Tests.Mq
_messageReader.Message = message; _messageReader.Message = message;
_messageReader.ReadBytes(3); _messageReader.ReadBytes(3);
Assert.Equal(expectedValue, _messageReader.ReadToEnd()); Assert.AreEqual(expectedValue, _messageReader.ReadToEnd());
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageReader_maintains_position() public void MessageReader_maintains_position()
{ {
var expectedValue = 5; var expectedValue = 5;
@ -553,11 +556,11 @@ namespace DtronixMessageQueue.Tests.Mq
_messageReader.Message = message; _messageReader.Message = message;
_messageReader.ReadBytes(5); _messageReader.ReadBytes(5);
Assert.Equal(expectedValue, _messageReader.Position); Assert.AreEqual(expectedValue, _messageReader.Position);
Assert.False(_messageReader.IsAtEnd); Assert.False(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageReader_maintains_position_across_frames() public void MessageReader_maintains_position_across_frames()
{ {
var expectedValue = 7; var expectedValue = 7;
@ -569,12 +572,12 @@ namespace DtronixMessageQueue.Tests.Mq
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(new byte[] {1, 2, 3, 4, 5, 6, 7}, _messageReader.ReadBytes(7)); Assert.AreEqual(new byte[] {1, 2, 3, 4, 5, 6, 7}, _messageReader.ReadBytes(7));
Assert.Equal(expectedValue, _messageReader.Position); Assert.AreEqual(expectedValue, _messageReader.Position);
Assert.False(_messageReader.IsAtEnd); Assert.False(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageReader_throws_when_reading_simple_type_across_frames() public void MessageReader_throws_when_reading_simple_type_across_frames()
{ {
_messageBuilder.Write(new byte[] {1, 2}); _messageBuilder.Write(new byte[] {1, 2});
@ -587,7 +590,7 @@ namespace DtronixMessageQueue.Tests.Mq
Assert.Throws<InvalidOperationException>(() => _messageReader.ReadInt32()); Assert.Throws<InvalidOperationException>(() => _messageReader.ReadInt32());
} }
[Fact] [Test]
public void MessageReader_skips_bytes() public void MessageReader_skips_bytes()
{ {
_messageBuilder.Write(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}); _messageBuilder.Write(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
@ -596,11 +599,11 @@ namespace DtronixMessageQueue.Tests.Mq
_messageReader.Skip(4); _messageReader.Skip(4);
Assert.Equal(4, _messageReader.Position); Assert.AreEqual(4, _messageReader.Position);
Assert.False(_messageReader.IsAtEnd); Assert.False(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageReader_skips_empty_frames() public void MessageReader_skips_empty_frames()
{ {
_messageBuilder.Write(new byte[] {1, 2}); _messageBuilder.Write(new byte[] {1, 2});
@ -614,12 +617,12 @@ namespace DtronixMessageQueue.Tests.Mq
_messageReader.Skip(3); _messageReader.Skip(3);
Assert.Equal(3, _messageReader.Position); Assert.AreEqual(3, _messageReader.Position);
Assert.Equal(4, _messageReader.ReadByte()); Assert.AreEqual(4, _messageReader.ReadByte());
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageReader_sets_position() public void MessageReader_sets_position()
{ {
_messageBuilder.Write(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9}); _messageBuilder.Write(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9});
@ -627,16 +630,16 @@ namespace DtronixMessageQueue.Tests.Mq
_messageReader.Message = message; _messageReader.Message = message;
_messageReader.Position = 2; _messageReader.Position = 2;
Assert.Equal(2, _messageReader.Position); Assert.AreEqual(2, _messageReader.Position);
_messageReader.Position = 1; _messageReader.Position = 1;
Assert.Equal(1, _messageReader.Position); Assert.AreEqual(1, _messageReader.Position);
_messageReader.Position = 3; _messageReader.Position = 3;
Assert.Equal(3, _messageReader.Position); Assert.AreEqual(3, _messageReader.Position);
} }
[Fact] [Test]
public void MessageReader_sets_position_and_reads() public void MessageReader_sets_position_and_reads()
{ {
_messageBuilder.Write(new byte[] {1, 2, 3, 4, 5}); _messageBuilder.Write(new byte[] {1, 2, 3, 4, 5});
@ -644,19 +647,19 @@ namespace DtronixMessageQueue.Tests.Mq
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(new byte[] {1, 2, 3, 4, 5}, _messageReader.ReadBytes(5)); Assert.AreEqual(new byte[] {1, 2, 3, 4, 5}, _messageReader.ReadBytes(5));
Assert.Equal(5, _messageReader.Position); Assert.AreEqual(5, _messageReader.Position);
_messageReader.Position = 2; _messageReader.Position = 2;
Assert.Equal(2, _messageReader.Position); Assert.AreEqual(2, _messageReader.Position);
Assert.Equal(new byte[] {3, 4, 5}, _messageReader.ReadBytes(3)); Assert.AreEqual(new byte[] {3, 4, 5}, _messageReader.ReadBytes(3));
Assert.Equal(5, _messageReader.Position); Assert.AreEqual(5, _messageReader.Position);
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageReader_sets_position_and_updates_isatend() public void MessageReader_sets_position_and_updates_isatend()
{ {
_messageBuilder.Write(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9}); _messageBuilder.Write(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9});
@ -672,7 +675,7 @@ namespace DtronixMessageQueue.Tests.Mq
Assert.False(_messageReader.IsAtEnd); Assert.False(_messageReader.IsAtEnd);
} }
[Fact] [Test]
public void MessageReader_writes_guid() public void MessageReader_writes_guid()
{ {
var expectedValue = (Guid)Guid.NewGuid(); var expectedValue = (Guid)Guid.NewGuid();
@ -680,7 +683,7 @@ namespace DtronixMessageQueue.Tests.Mq
var message = _messageBuilder.ToMessage(); var message = _messageBuilder.ToMessage();
_messageReader.Message = message; _messageReader.Message = message;
Assert.Equal(expectedValue, _messageReader.ReadGuid()); Assert.AreEqual(expectedValue, _messageReader.ReadGuid());
Assert.True(_messageReader.IsAtEnd); Assert.True(_messageReader.IsAtEnd);
} }
} }

Просмотреть файл

@ -1,23 +1,17 @@
using System; using System;
using System.Threading; using System.Threading;
using DtronixMessageQueue.Socket; using DtronixMessageQueue.TcpSocket;
using Xunit; using NUnit.Framework;
using Xunit.Abstractions;
namespace DtronixMessageQueue.Tests.Mq namespace DtronixMessageQueue.Tests.Mq
{ {
public class MqServerTests : MqTestsBase public class MqServerTests : MqTestsBase
{ {
public MqServerTests(ITestOutputHelper output) : base(output)
{
}
[TestCase(1, false)]
[Theory] [TestCase(1, true)]
[InlineData(1, false)] [TestCase(100, true)]
[InlineData(1, true)] [TestCase(1000, true)]
[InlineData(100, true)]
[InlineData(1000, true)]
public void Server_should_send_data_to_client(int number, bool validate) public void Server_should_send_data_to_client(int number, bool validate)
{ {
var messageSource = GenerateRandomMessage(4, 50); var messageSource = GenerateRandomMessage(4, 50);
@ -49,100 +43,84 @@ namespace DtronixMessageQueue.Tests.Mq
if (clientMessageCount == number) if (clientMessageCount == number)
{ {
TestStatus.Set(); TestComplete.Set();
} }
}; };
StartAndWait(); StartAndWait();
} }
[Fact] [Test]
public void Server_accepts_new_connection() public void Server_accepts_new_connection()
{ {
Server.Connected += (sender, session) => { TestStatus.Set(); }; Server.Connected += (sender, session) => { TestComplete.Set(); };
StartAndWait(); StartAndWait();
} }
[Fact] [Test]
public void Server_detects_client_disconnect() public void Server_detects_client_disconnect()
{ {
Client.Connected += (sender, args) => { Client.Close(); }; Client.Connected += (sender, args) => { Client.Close(); };
Server.Closed += (session, value) => { TestStatus.Set(); }; Server.Closed += (session, value) => { TestComplete.Set(); };
StartAndWait(); StartAndWait();
} }
[Fact] [Test]
public void Server_stops() public void Server_stops()
{ {
Server.Start(); Server.Start();
Assert.Equal(true, Server.IsRunning); Assert.AreEqual(true, Server.IsRunning);
Server.Stop(); Server.Stop();
Assert.Equal(false, Server.IsRunning); Assert.AreEqual(false, Server.IsRunning);
} }
[Fact] [Test]
public void Server_accepts_new_connection_after_max() public void Server_accepts_new_connection_after_max()
{ {
Server.Config.MaxConnections = 1; Server.Config.MaxConnections = 1;
var client = CreateClient(Config); var client = CreateClient(ClientConfig);
var client2 = CreateClient(Config); var client2 = CreateClient(ClientConfig);
Server.Start(); Server.Start();
client.Connected += (sender, args) => client.Close(); client.Connected += (sender, args) => client.Close();
client.Closed += (sender, args) => client2.Connect(); client.Closed += (sender, args) => client2.Connect();
client2.Connected += (sender, args) => TestStatus.Set(); client2.Connected += (sender, args) => TestComplete.Set();
client.Connect(); client.Connect();
TestStatus.Wait(new TimeSpan(0, 0, 0, 0, 1000)); TestComplete.Wait(new TimeSpan(0, 0, 0, 0, 1000));
if (TestStatus.IsSet == false) if (TestComplete.IsSet == false)
{ {
throw new TimeoutException("Test timed out."); throw new TimeoutException("Test timed out.");
} }
} }
[Fact] [Test]
public void Server_refuses_new_connection_after_max() public void Server_refuses_new_connection_after_max()
{ {
Server.Config.MaxConnections = 1; Server.Config.MaxConnections = 1;
Exception invalidClosException = null; var client2 = CreateClient(ClientConfig);
var client = CreateClient(Config);
var client2 = CreateClient(Config);
Server.Start(); Client.Connected += (sender, args) => client2.Connect();
client.Connected += (sender, args) => client2.Connect();
client2.Closed += (sender, args) => client2.Closed += (sender, args) =>
{ {
if (args.CloseReason != SocketCloseReason.ConnectionRefused) if (args.CloseReason != CloseReason.ConnectionRefused)
{ {
invalidClosException = new Exception("Client socket did not close for the correct reason."); LastException = new Exception("Client socket did not close for the correct reason.");
} }
TestStatus.Set(); TestComplete.Set();
}; };
client.Connect();
StartAndWait();
TestStatus.Wait(new TimeSpan(0, 0, 0, 0, 1000));
if (TestStatus.IsSet == false)
{
throw new TimeoutException("Test timed out.");
} }
if (invalidClosException != null) [Test]
{
throw invalidClosException;
}
}
[Fact]
public void Server_restarts_after_stop() public void Server_restarts_after_stop()
{ {
int connected_times = 0; int connected_times = 0;
@ -154,7 +132,7 @@ namespace DtronixMessageQueue.Tests.Mq
Client.Close(); Client.Close();
if (++connected_times == 2) if (++connected_times == 2)
{ {
TestStatus.Set(); TestComplete.Set();
} }
else else
{ {
@ -175,42 +153,42 @@ namespace DtronixMessageQueue.Tests.Mq
TestStatus.Wait(new TimeSpan(0, 0, 0, 0, 2000)); TestComplete.Wait(new TimeSpan(0, 0, 0, 0, 2000));
if (TestStatus.IsSet == false) if (TestComplete.IsSet == false)
{ {
throw new TimeoutException("Test timed out."); throw new TimeoutException("Test timed out.");
} }
} }
[Fact] [Test]
public void Server_invokes_stopped_event() public void Server_invokes_stopped_event()
{ {
Server.Started += (sender, args) => Server.Stop(); Server.Started += (sender, args) => Server.Stop();
Server.Started += (sender, args) => TestStatus.Set(); Server.Started += (sender, args) => TestComplete.Set();
Server.Start(); Server.Start();
TestStatus.Wait(new TimeSpan(0, 0, 0, 0, 2000)); TestComplete.Wait(new TimeSpan(0, 0, 0, 0, 2000));
if (TestStatus.IsSet == false) if (TestComplete.IsSet == false)
{ {
throw new TimeoutException("Test timed out."); throw new TimeoutException("Test timed out.");
} }
} }
[Fact] [Test]
public void Server_invokes_started_event() public void Server_invokes_started_event()
{ {
Server.Started += (sender, args) => TestStatus.Set(); Server.Started += (sender, args) => TestComplete.Set();
Server.Start(); Server.Start();
TestStatus.Wait(new TimeSpan(0, 0, 0, 0, 2000)); TestComplete.Wait(new TimeSpan(0, 0, 0, 0, 2000));
if (TestStatus.IsSet == false) if (TestComplete.IsSet == false)
{ {
throw new TimeoutException("Test timed out."); throw new TimeoutException("Test timed out.");
} }

Просмотреть файл

@ -2,86 +2,64 @@
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Threading; using System.Threading;
using Xunit; using NUnit.Framework;
using Xunit.Abstractions;
namespace DtronixMessageQueue.Tests.Mq namespace DtronixMessageQueue.Tests.Mq
{ {
public class MqTestsBase : IDisposable public class MqTestsBase : TestBase
{ {
private Random _random = new Random();
public ITestOutputHelper Output;
public MqServer<SimpleMqSession, MqConfig> Server { get; protected set; } public MqServer<SimpleMqSession, MqConfig> Server { get; protected set; }
public MqClient<SimpleMqSession, MqConfig> Client { get; protected set; } public MqClient<SimpleMqSession, MqConfig> Client { get; protected set; }
public int Port { get; }
protected MqConfig Config; protected MqConfig ClientConfig;
protected MqConfig ServerConfig;
public Exception LastException { get; set; } public override void Init()
public TimeSpan TestTimeout { get; set; } = new TimeSpan(0, 0, 0, 0, 2000);
public ManualResetEventSlim TestStatus { get; set; } = new ManualResetEventSlim(false);
public MqTestsBase(ITestOutputHelper output)
{ {
Output = output; base.Init();
Port = FreeTcpPort();
Config = new MqConfig ClientConfig = new MqConfig
{ {
Ip = "127.0.0.1", Address = $"127.0.0.1:{Port}",
Port = Port
}; };
Server = new MqServer<SimpleMqSession, MqConfig>(Config); ServerConfig = new MqConfig
Client = CreateClient(Config);
}
public MqClient<SimpleMqSession, MqConfig> CreateClient(MqConfig config)
{ {
return new MqClient<SimpleMqSession, MqConfig>(config); Address = $"127.0.0.1:{Port}"
};
Server = new MqServer<SimpleMqSession, MqConfig>(ServerConfig);
Client = CreateClient(ClientConfig);
} }
public static int FreeTcpPort()
{
TcpListener l = new TcpListener(IPAddress.Loopback, 0);
l.Start();
int port = ((IPEndPoint) l.LocalEndpoint).Port;
l.Stop();
return port;
}
public void StartAndWait(bool timeoutError = true, int timeoutLength = -1, bool startServer = true, bool startClient = true) public void StartAndWait(bool timeoutError = true, int timeoutLength = -1, bool startServer = true, bool startClient = true)
{ {
if (startServer && Server.IsRunning == false)
{ if (startServer)
Server.Start(); Server.Start();
}
if (startClient && Client.IsRunning == false) if (startClient)
{
Client.Connect(); Client.Connect();
base.StartAndWait(timeoutError, timeoutLength);
} }
timeoutLength = timeoutLength != -1 ? timeoutLength : (int) TestTimeout.TotalMilliseconds; protected override void StopClientServer()
TestStatus.Wait(new TimeSpan(0, 0, 0, 0, timeoutLength));
if (timeoutError && TestStatus.IsSet == false)
{ {
throw new TimeoutException("Test timed out.");
}
if (LastException != null)
{
throw LastException;
}
try try
{ {
Server.Stop(); Server.Stop();
}
catch
{
// ignored
}
try
{
Client.Close(); Client.Close();
} }
catch catch
@ -90,30 +68,15 @@ namespace DtronixMessageQueue.Tests.Mq
} }
} }
public void CompareMessages(MqMessage expected, MqMessage actual)
{
try
{
// Total frame count comparison.
Assert.Equal(expected.Count, actual.Count);
for (int i = 0; i < expected.Count; i++) public MqClient<SimpleMqSession, MqConfig> CreateClient(MqConfig config)
{ {
// Frame length comparison. return new MqClient<SimpleMqSession, MqConfig>(config);
Assert.Equal(expected[i].DataLength, actual[i].DataLength);
Assert.Equal(expected[i].Buffer, actual[i].Buffer);
}
}
catch (Exception e)
{
LastException = e;
}
} }
public MqMessage GenerateRandomMessage(int frames = -1, int frameLength = -1) public MqMessage GenerateRandomMessage(int frames = -1, int frameLength = -1)
{ {
var frameCount = frames == -1 ? _random.Next(8, 16) : frames; var frameCount = frames == -1 ? Random.Next(8, 16) : frames;
var message = new MqMessage(); var message = new MqMessage();
for (int i = 0; i < frameCount; i++) for (int i = 0; i < frameCount; i++)
{ {
@ -121,13 +84,13 @@ namespace DtronixMessageQueue.Tests.Mq
if (frameLength == -1) if (frameLength == -1)
{ {
frame = new MqFrame(Utilities.SequentialBytes(_random.Next(50, 1024 * 16 - 3)), frame = new MqFrame(Utilities.SequentialBytes(Random.Next(50, 1024 * 16 - 3)),
(i + 1 < frameCount) ? MqFrameType.More : MqFrameType.Last, Config); (i + 1 < frameCount) ? MqFrameType.More : MqFrameType.Last, ClientConfig);
} }
else else
{ {
frame = new MqFrame(Utilities.SequentialBytes(frameLength), frame = new MqFrame(Utilities.SequentialBytes(frameLength),
(i + 1 < frameCount) ? MqFrameType.More : MqFrameType.Last, Config); (i + 1 < frameCount) ? MqFrameType.More : MqFrameType.Last, ClientConfig);
} }
message.Add(frame); message.Add(frame);
} }
@ -135,23 +98,5 @@ namespace DtronixMessageQueue.Tests.Mq
return message; return message;
} }
public void Dispose()
{
try
{
Server.Stop();
}
catch
{
}
try
{
Client.Close();
}
catch
{
}
}
} }
} }

Просмотреть файл

@ -1,14 +0,0 @@
using Xunit.Abstractions;
namespace DtronixMessageQueue.Tests
{
public class PerformanceTests
{
private ITestOutputHelper _output;
public PerformanceTests(ITestOutputHelper output)
{
_output = output;
}
}
}

Просмотреть файл

@ -1,28 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Xunit.Sdk;
namespace DtronixMessageQueue.Tests
{
public class RepeatAttribute : DataAttribute
{
private readonly int _count;
public RepeatAttribute(int count)
{
if (count < 1)
{
throw new ArgumentOutOfRangeException(nameof(count),
"Repeat count must be greater than 0.");
}
_count = count;
}
public override IEnumerable<object[]> GetData(MethodInfo testMethod)
{
return Enumerable.Repeat(new object[0], _count);
}
}
}

Просмотреть файл

@ -1,18 +1,14 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Threading; using System.Threading;
using DtronixMessageQueue.Socket; using DtronixMessageQueue.TcpSocket;
using DtronixMessageQueue.Tests.Rpc.Services.Server; using DtronixMessageQueue.Tests.Rpc.Services.Server;
using Xunit; using NUnit.Framework;
using Xunit.Abstractions;
namespace DtronixMessageQueue.Tests.Rpc namespace DtronixMessageQueue.Tests.Rpc
{ {
public class RpcClientTests : RpcTestsBase public class RpcClientTests : RpcTestsBase
{ {
public RpcClientTests(ITestOutputHelper output) : base(output)
{
}
public class Test public class Test
{ {
@ -20,7 +16,7 @@ namespace DtronixMessageQueue.Tests.Rpc
public int Length { get; set; } public int Length { get; set; }
} }
[Fact] [Test]
public void Client_calls_proxy_method() public void Client_calls_proxy_method()
{ {
Server.SessionSetup += (sender, args) => { args.Session.AddService(new CalculatorService()); }; Server.SessionSetup += (sender, args) => { args.Session.AddService(new CalculatorService()); };
@ -41,13 +37,13 @@ namespace DtronixMessageQueue.Tests.Rpc
LastException = new Exception("Service returned wrong result."); LastException = new Exception("Service returned wrong result.");
} }
TestStatus.Set(); TestComplete.Set();
}; };
StartAndWait(); StartAndWait();
} }
[Fact] [Test]
public void Client_calls_proxy_method_sequential() public void Client_calls_proxy_method_sequential()
{ {
Server.SessionSetup += (sender, args) => { args.Session.AddService(new CalculatorService()); }; Server.SessionSetup += (sender, args) => { args.Session.AddService(new CalculatorService()); };
@ -60,19 +56,30 @@ namespace DtronixMessageQueue.Tests.Rpc
Stopwatch stopwatch = Stopwatch.StartNew(); Stopwatch stopwatch = Stopwatch.StartNew();
int addedInt = 0; int addedInt = 0;
for (int i = 0; i < 10; i++) int totalAdds = 50;
for (int i = 0; i < totalAdds; i++)
{ {
addedInt = service.Add(addedInt, 1); addedInt = service.Add(addedInt, 1);
} }
Output.WriteLine($"{stopwatch.ElapsedMilliseconds}");
TestStatus.Set(); try
{
Assert.AreEqual(totalAdds, addedInt);
TestComplete.Set();
}
catch (Exception e)
{
LastException = e;
}
}; };
StartAndWait(); StartAndWait();
} }
[Fact] [Test]
public void Client_calls_proxy_method_and_canceles() public void Client_calls_proxy_method_and_canceles()
{ {
Server.SessionSetup += (sender, args) => Server.SessionSetup += (sender, args) =>
@ -80,7 +87,7 @@ namespace DtronixMessageQueue.Tests.Rpc
var service = new CalculatorService(); var service = new CalculatorService();
args.Session.AddService<ICalculatorService>(service); args.Session.AddService<ICalculatorService>(service);
service.LongRunningTaskCanceled += (o, eventArgs) => { TestStatus.Set(); }; service.LongRunningTaskCanceled += (o, eventArgs) => { TestComplete.Set(); };
}; };
@ -111,19 +118,19 @@ namespace DtronixMessageQueue.Tests.Rpc
StartAndWait(); StartAndWait();
} }
[Fact] [Test]
public void Server_requests_authentication() public void Server_requests_authentication()
{ {
Server.Config.RequireAuthentication = true; Server.Config.RequireAuthentication = true;
Client.Authenticate += (sender, e) => { TestStatus.Set(); }; Client.Authenticate += (sender, e) => { TestComplete.Set(); };
StartAndWait(); StartAndWait();
} }
[Fact] [Test]
public void Server_does_not_request_authentication() public void Server_does_not_request_authentication()
{ {
Server.Config.RequireAuthentication = false; Server.Config.RequireAuthentication = false;
@ -145,7 +152,7 @@ namespace DtronixMessageQueue.Tests.Rpc
{ {
LastException = new Exception("Client authenticated."); LastException = new Exception("Client authenticated.");
} }
TestStatus.Set(); TestComplete.Set();
}; };
@ -153,7 +160,7 @@ namespace DtronixMessageQueue.Tests.Rpc
} }
[Fact] [Test]
public void Server_verifies_authentication() public void Server_verifies_authentication()
{ {
var authData = new byte[] {1, 2, 3, 4, 5}; var authData = new byte[] {1, 2, 3, 4, 5};
@ -167,7 +174,7 @@ namespace DtronixMessageQueue.Tests.Rpc
{ {
try try
{ {
Assert.Equal(authData, e.AuthData); Assert.AreEqual(authData, e.AuthData);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -175,7 +182,7 @@ namespace DtronixMessageQueue.Tests.Rpc
} }
finally finally
{ {
TestStatus.Set(); TestComplete.Set();
} }
}; };
@ -185,7 +192,7 @@ namespace DtronixMessageQueue.Tests.Rpc
StartAndWait(); StartAndWait();
} }
[Fact] [Test]
public void Server_disconnectes_from_failed_authentication() public void Server_disconnectes_from_failed_authentication()
{ {
Server.Config.RequireAuthentication = true; Server.Config.RequireAuthentication = true;
@ -197,11 +204,11 @@ namespace DtronixMessageQueue.Tests.Rpc
Server.Closed += (sender, e) => Server.Closed += (sender, e) =>
{ {
if (e.CloseReason != SocketCloseReason.AuthenticationFailure) if (e.CloseReason != CloseReason.AuthenticationFailure)
{ {
LastException = new Exception("Server closed session for invalid reason"); LastException = new Exception("Server closed session for invalid reason");
} }
TestStatus.Set(); TestComplete.Set();
}; };
Client.Authenticate += (sender, e) => { e.AuthData = new byte[] {5, 4, 3, 2, 1}; }; Client.Authenticate += (sender, e) => { e.AuthData = new byte[] {5, 4, 3, 2, 1}; };
@ -209,7 +216,7 @@ namespace DtronixMessageQueue.Tests.Rpc
StartAndWait(); StartAndWait();
} }
[Fact] [Test]
public void Client_disconnectes_from_failed_authentication() public void Client_disconnectes_from_failed_authentication()
{ {
Server.Config.RequireAuthentication = true; Server.Config.RequireAuthentication = true;
@ -221,11 +228,11 @@ namespace DtronixMessageQueue.Tests.Rpc
Client.Closed += (sender, e) => Client.Closed += (sender, e) =>
{ {
if (e.CloseReason != SocketCloseReason.AuthenticationFailure) if (e.CloseReason != CloseReason.AuthenticationFailure)
{ {
LastException = new Exception("Server closed session for invalid reason"); LastException = new Exception("Server closed session for invalid reason");
} }
TestStatus.Set(); TestComplete.Set();
}; };
Client.Authenticate += (sender, e) => { e.AuthData = new byte[] {5, 4, 3, 2, 1}; }; Client.Authenticate += (sender, e) => { e.AuthData = new byte[] {5, 4, 3, 2, 1}; };
@ -234,10 +241,10 @@ namespace DtronixMessageQueue.Tests.Rpc
} }
[Fact] [Test]
public void Client_notified_of_authentication_success() public void Client_notified_of_authentication_success()
{ {
Server.Config.RequireAuthentication = true; ServerConfig.RequireAuthentication = true;
Server.SessionSetup += Server.SessionSetup +=
(sender, args) => { args.Session.AddService<ICalculatorService>(new CalculatorService()); }; (sender, args) => { args.Session.AddService<ICalculatorService>(new CalculatorService()); };
@ -250,7 +257,7 @@ namespace DtronixMessageQueue.Tests.Rpc
{ {
LastException = new Exception("Client notified of authentication wrongly."); LastException = new Exception("Client notified of authentication wrongly.");
} }
TestStatus.Set(); TestComplete.Set();
}; };
Client.Authenticate += (sender, e) => { e.AuthData = new byte[] {5, 4, 3, 2, 1}; }; Client.Authenticate += (sender, e) => { e.AuthData = new byte[] {5, 4, 3, 2, 1}; };
@ -258,7 +265,7 @@ namespace DtronixMessageQueue.Tests.Rpc
StartAndWait(); StartAndWait();
} }
[Fact] [Test]
public void Client_times_out_on_long_auth() public void Client_times_out_on_long_auth()
{ {
Server.Config.RequireAuthentication = true; Server.Config.RequireAuthentication = true;
@ -266,44 +273,20 @@ namespace DtronixMessageQueue.Tests.Rpc
Client.Closed += (sender, e) => Client.Closed += (sender, e) =>
{ {
if (e.CloseReason != SocketCloseReason.TimeOut) if (e.CloseReason != CloseReason.TimeOut)
{ {
LastException = new Exception("Client was not notified that the authentication failed."); LastException = new Exception("Client was not notified that the authentication failed.");
} }
TestStatus.Set(); TestComplete.Set();
}; };
Server.Authenticate += (sender, e) => { Thread.Sleep(500); }; Server.Authenticate += (sender, e) => { Thread.Sleep(500); };
StartAndWait(true, 5000, true); StartAndWait(true, 5000);
} }
[Fact]
public void Client_does_not_ready_before_server_authenticates()
{
Server.Config.RequireAuthentication = true;
Server.Authenticate += (sender, args) => [Test]
{
args.Authenticated = true;
Thread.Sleep(200);
};
Client.Ready += (sender, args) =>
{
if (!args.Session.Authenticated)
{
LastException = new Exception("Client ready event called while authentication failed.");
}
TestStatus.Set();
};
Client.Authenticate += (sender, e) => { e.AuthData = new byte[] {5, 4, 3, 2, 1}; };
StartAndWait();
}
[Fact]
public void Client_connects_disconnects_and_reconnects() public void Client_connects_disconnects_and_reconnects()
{ {
Server.Config.RequireAuthentication = false; Server.Config.RequireAuthentication = false;
@ -314,7 +297,7 @@ namespace DtronixMessageQueue.Tests.Rpc
{ {
if (++connectedTimes == 5) if (++connectedTimes == 5)
{ {
TestStatus.Set(); TestComplete.Set();
} }
else else
{ {
@ -324,7 +307,7 @@ namespace DtronixMessageQueue.Tests.Rpc
Client.Closed += (sender, args) => Client.Closed += (sender, args) =>
{ {
if (!TestStatus.IsSet) if (!TestComplete.IsSet)
{ {
Client.Connect(); Client.Connect();
} }

Просмотреть файл

@ -3,113 +3,75 @@ using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Threading; using System.Threading;
using DtronixMessageQueue.Rpc; using DtronixMessageQueue.Rpc;
using Xunit; using NUnit.Framework;
using Xunit.Abstractions;
namespace DtronixMessageQueue.Tests.Rpc namespace DtronixMessageQueue.Tests.Rpc
{ {
public class RpcTestsBase : IDisposable public class RpcTestsBase : TestBase
{ {
private Random _random = new Random();
public ITestOutputHelper Output;
public RpcServer<SimpleRpcSession, RpcConfig> Server { get; protected set; } public RpcServer<SimpleRpcSession, RpcConfig> Server { get; protected set; }
public RpcClient<SimpleRpcSession, RpcConfig> Client { get; protected set; } public RpcClient<SimpleRpcSession, RpcConfig> Client { get; protected set; }
public int Port { get; }
protected RpcConfig Config; protected RpcConfig ClientConfig;
protected RpcConfig ServerConfig;
public Exception LastException { get; set; }
public TimeSpan TestTimeout { get; set; } = new TimeSpan(0, 0, 0, 0, 5000); public override void Init()
public ManualResetEventSlim TestStatus { get; set; } = new ManualResetEventSlim(false);
public RpcTestsBase(ITestOutputHelper output)
{ {
Output = output; base.Init();
Port = FreeTcpPort();
Config = new RpcConfig ClientConfig = new RpcConfig
{ {
Ip = "127.0.0.1", Address = $"127.0.0.1:{Port}",
Port = Port
}; };
Server = new RpcServer<SimpleRpcSession, RpcConfig>(Config, null); ServerConfig = new RpcConfig
Client = new RpcClient<SimpleRpcSession, RpcConfig>(Config); {
Address = $"127.0.0.1:{Port}",
};
Server = new RpcServer<SimpleRpcSession, RpcConfig>(ServerConfig);
Client = new RpcClient<SimpleRpcSession, RpcConfig>(ClientConfig);
} }
public static int FreeTcpPort()
{
TcpListener l = new TcpListener(IPAddress.Loopback, 0);
l.Start();
int port = ((IPEndPoint) l.LocalEndpoint).Port;
l.Stop();
return port;
}
public void StartAndWait(bool timeoutError = true, int timeoutLength = -1, bool startServer = true)
{
if (Server.IsRunning == false && startServer)
{
Server.Start();
}
if (Client.IsRunning == false)
{
Client.Connect();
}
timeoutLength = timeoutLength != -1 ? timeoutLength : (int) TestTimeout.TotalMilliseconds; protected override void StopClientServer()
TestStatus.Wait(new TimeSpan(0, 0, 0, 0, timeoutLength));
if (timeoutError && TestStatus.IsSet == false)
{ {
throw new TimeoutException("Test timed out.");
}
if (LastException != null)
{
throw LastException;
}
try try
{ {
Server.Stop(); Server.Stop();
}
catch
{
}
try
{
Client.Close(); Client.Close();
} }
catch catch
{ {
// ignored
} }
} }
public void CompareMessages(MqMessage expected, MqMessage actual)
{
try
{
// Total frame count comparison.
Assert.Equal(expected.Count, actual.Count);
for (int i = 0; i < expected.Count; i++) public void StartAndWait(bool timeoutError = true, int timeoutLength = -1, bool startServer = true, bool startClient = true)
{ {
// Frame length comparison.
Assert.Equal(expected[i].DataLength, actual[i].DataLength);
Assert.Equal(expected[i].Buffer, actual[i].Buffer); if (startServer)
} Server.Start();
}
catch (Exception e) if (startClient)
{ Client.Connect();
LastException = e;
} base.StartAndWait(timeoutError, timeoutLength);
} }
public MqMessage GenerateRandomMessage(int frames = -1, int frameLength = -1) public MqMessage GenerateRandomMessage(int frames = -1, int frameLength = -1)
{ {
var frameCount = frames == -1 ? _random.Next(8, 16) : frames; var frameCount = frames == -1 ? Random.Next(8, 16) : frames;
var message = new MqMessage(); var message = new MqMessage();
for (int i = 0; i < frameCount; i++) for (int i = 0; i < frameCount; i++)
{ {
@ -117,37 +79,18 @@ namespace DtronixMessageQueue.Tests.Rpc
if (frameLength == -1) if (frameLength == -1)
{ {
frame = new MqFrame(Utilities.SequentialBytes(_random.Next(50, 1024 * 16 - 3)), frame = new MqFrame(Utilities.SequentialBytes(Random.Next(50, 1024 * 16 - 3)),
(i + 1 < frameCount) ? MqFrameType.More : MqFrameType.Last, Config); (i + 1 < frameCount) ? MqFrameType.More : MqFrameType.Last, ClientConfig);
} }
else else
{ {
frame = new MqFrame(Utilities.SequentialBytes(frameLength), frame = new MqFrame(Utilities.SequentialBytes(frameLength),
(i + 1 < frameCount) ? MqFrameType.More : MqFrameType.Last, Config); (i + 1 < frameCount) ? MqFrameType.More : MqFrameType.Last, ClientConfig);
} }
message.Add(frame); message.Add(frame);
} }
return message; return message;
} }
public void Dispose()
{
try
{
Server.Stop();
}
catch
{
}
try
{
Client.Close();
}
catch
{
}
}
} }
} }

Просмотреть файл

@ -0,0 +1,112 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework;
namespace DtronixMessageQueue.Tests
{
public abstract class TestBase : IDisposable
{
protected Random Random = new Random();
private Exception _lastException;
public static int Port { get; private set; }
public static bool IsMono => Type.GetType("Mono.Runtime") != null;
public Exception LastException
{
get => _lastException;
set
{
_lastException = value;
TestComplete.Set();
}
}
public TimeSpan TestTimeout { get; } = new TimeSpan(0, 0, 0, 0, 2000);
public ManualResetEventSlim TestComplete { get; private set; }
static TestBase()
{
}
[SetUp]
public virtual void Init()
{
TestComplete = new ManualResetEventSlim(false);
_lastException = null;
Port = FreeTcpPort();
}
public static int FreeTcpPort()
{
TcpListener l = new TcpListener(IPAddress.Loopback, 0);
l.Start();
int port = ((IPEndPoint)l.LocalEndpoint).Port;
l.Stop();
return port;
}
protected abstract void StopClientServer();
protected void StartAndWait(bool timeoutError = true, int timeoutLength = -1)
{
timeoutLength = timeoutLength != -1 ? timeoutLength : (int)TestTimeout.TotalMilliseconds;
#if false
timeoutLength = 100000;
#endif
TestComplete.Wait(TimeSpan.FromMilliseconds(timeoutLength));
if (timeoutError && TestComplete.IsSet == false)
{
throw new TimeoutException("Test timed out.");
}
if (LastException != null)
{
throw LastException;
}
StopClientServer();
}
public void CompareMessages(MqMessage expected, MqMessage actual)
{
try
{
// Total frame count comparison.
Assert.AreEqual(expected.Count, actual.Count);
for (int i = 0; i < expected.Count; i++)
{
// Frame length comparison.
Assert.AreEqual(expected[i].DataLength, actual[i].DataLength);
Assert.AreEqual(expected[i].Buffer, actual[i].Buffer);
}
}
catch (Exception e)
{
LastException = e;
}
}
[TearDown]
public void Dispose()
{
TestComplete?.Dispose();
StopClientServer();
}
}
}

Просмотреть файл

@ -1,5 +1,5 @@
using System; using System;
using Xunit; using NUnit.Framework;
namespace DtronixMessageQueue.Tests namespace DtronixMessageQueue.Tests
{ {
@ -10,8 +10,8 @@ namespace DtronixMessageQueue.Tests
if (expected == null) throw new ArgumentNullException(nameof(expected)); if (expected == null) throw new ArgumentNullException(nameof(expected));
if (actual == null) throw new ArgumentNullException(nameof(actual)); if (actual == null) throw new ArgumentNullException(nameof(actual));
Assert.Equal(expected.FrameType, actual.FrameType); Assert.AreEqual(expected.FrameType, actual.FrameType);
Assert.Equal(expected.Buffer, actual.Buffer); Assert.AreEqual(expected.Buffer, actual.Buffer);
} }
public static byte[] SequentialBytes(int len) public static byte[] SequentialBytes(int len)

Просмотреть файл

@ -1,12 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="NuGet.CommandLine" version="4.1.0" targetFramework="net45" developmentDependency="true" /> <package id="NuGet.CommandLine" version="4.3.0" targetFramework="net45" developmentDependency="true" />
<package id="xunit" version="2.2.0-beta2-build3300" targetFramework="net45" /> <package id="NUnit" version="3.8.1" targetFramework="net45" />
<package id="xunit.abstractions" version="2.0.1" targetFramework="net45" /> <package id="NUnit.ConsoleRunner" version="3.7.0" targetFramework="net45" />
<package id="xunit.assert" version="2.2.0-beta2-build3300" targetFramework="net45" /> <package id="NUnit3TestAdapter" version="3.8.0" targetFramework="net45" />
<package id="xunit.core" version="2.2.0-beta2-build3300" targetFramework="net45" />
<package id="xunit.extensibility.core" version="2.2.0-beta2-build3300" targetFramework="net45" />
<package id="xunit.extensibility.execution" version="2.2.0-beta2-build3300" targetFramework="net45" />
<package id="xunit.runner.console" version="2.1.0" targetFramework="net45" />
<package id="xunit.runner.visualstudio" version="2.2.0-beta2-build1149" targetFramework="net45" developmentDependency="true" />
</packages> </packages>

Просмотреть файл

@ -1,9 +1,9 @@
namespace DtronixMessageQueue.Socket namespace DtronixMessageQueue
{ {
/// <summary> /// <summary>
/// CloseReason enum /// CloseReason enum
/// </summary> /// </summary>
public enum SocketCloseReason : byte public enum CloseReason : byte
{ {
/// <summary> /// <summary>
/// The socket is closed for unknown reason /// The socket is closed for unknown reason
@ -18,12 +18,7 @@
/// <summary> /// <summary>
/// The client close the socket /// The client close the socket
/// </summary> /// </summary>
ClientClosing = 2, Closing = 2,
/// <summary>
/// The server side close the socket
/// </summary>
ServerClosing = 3,
/// <summary> /// <summary>
/// Application error /// Application error

Просмотреть файл

@ -32,8 +32,8 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="protobuf-net, Version=2.3.0.0, Culture=neutral, PublicKeyToken=257b51d87d2e4d67, processorArchitecture=MSIL"> <Reference Include="protobuf-net, Version=2.3.2.0, Culture=neutral, PublicKeyToken=257b51d87d2e4d67, processorArchitecture=MSIL">
<HintPath>..\packages\protobuf-net.2.3.0\lib\net40\protobuf-net.dll</HintPath> <HintPath>..\packages\protobuf-net.2.3.2\lib\net40\protobuf-net.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Configuration" /> <Reference Include="System.Configuration" />
@ -46,6 +46,7 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="MemoryQueueBufferStream.cs" />
<Compile Include="MqCommandType.cs" /> <Compile Include="MqCommandType.cs" />
<Compile Include="MqMessageReader.cs" /> <Compile Include="MqMessageReader.cs" />
<Compile Include="MqMessageWriter.cs" /> <Compile Include="MqMessageWriter.cs" />
@ -69,19 +70,19 @@
<Compile Include="Rpc\RpcServer.cs" /> <Compile Include="Rpc\RpcServer.cs" />
<Compile Include="Rpc\RpcSession.cs" /> <Compile Include="Rpc\RpcSession.cs" />
<Compile Include="Rpc\SerializationCache.cs" /> <Compile Include="Rpc\SerializationCache.cs" />
<Compile Include="ServiceMethodCache.cs" /> <Compile Include="Rpc\ServiceMethodCache.cs" />
<Compile Include="Socket\BufferManager.cs" /> <Compile Include="TcpSocket\BufferManager.cs" />
<Compile Include="Socket\ISetupSocketSession.cs" /> <Compile Include="TcpSocket\ISetupSocketSession.cs" />
<Compile Include="Socket\SessionEventArgs.cs" /> <Compile Include="SessionEventArgs.cs" />
<Compile Include="Socket\SessionClosedEventArgs.cs" /> <Compile Include="SessionClosedEventArgs.cs" />
<Compile Include="Socket\SocketAsyncEventArgsManager.cs" /> <Compile Include="TcpSocket\SocketAsyncEventArgsManager.cs" />
<Compile Include="Socket\SessionHandler.cs" /> <Compile Include="TcpSocket\TcpSocketHandler.cs" />
<Compile Include="Socket\SocketClient.cs" /> <Compile Include="TcpSocket\TcpSocketClient.cs" />
<Compile Include="Socket\SocketCloseReason.cs" /> <Compile Include="CloseReason.cs" />
<Compile Include="Socket\SocketConfig.cs" /> <Compile Include="TcpSocket\TcpSocketConfig.cs" />
<Compile Include="Socket\SocketMode.cs" /> <Compile Include="TcpSocket\TcpSocketMode.cs" />
<Compile Include="Socket\SocketServer.cs" /> <Compile Include="TcpSocket\TcpSocketServer.cs" />
<Compile Include="Socket\SocketSession.cs" /> <Compile Include="TcpSocket\TcpSocketSession.cs" />
<Compile Include="Utilities.cs" /> <Compile Include="Utilities.cs" />
<Content Include="DtronixMessageQueue.nuspec"> <Content Include="DtronixMessageQueue.nuspec">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>

Просмотреть файл

@ -0,0 +1,169 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DtronixMessageQueue
{
/// <summary>
/// This stream maintains data only until the data is read, then it is purged from the stream.
/// </summary>
public class MemoryQueueBufferStream : Stream
{
public override bool CanSeek => false;
/// <summary>
/// Always returns 0
/// </summary>
public override long Position {
get => 0;
set => throw new NotSupportedException(GetType().Name + " is not seekable");
}
public override bool CanWrite => true;
public override bool CanRead => true;
public override long Length {
get {
if (_buffer == null)
{
return 0;
}
if (_buffer.Count == 0)
{
return 0;
}
return _buffer.Sum(b => b.Data.Length - b.ChunkReadStartIndex);
}
}
/// <summary>
/// Represents a single write into the MemoryQueueBufferStream. Each write is a separate chunk
/// </summary>
private class Chunk
{
/// <summary>
/// As we read through the chunk, the start index will increment. When we get to the end of the chunk,
/// we will remove the chunk
/// </summary>
public int ChunkReadStartIndex { get; set; }
/// <summary>
/// Actual Data
/// </summary>
public byte[] Data { get; set; }
}
//Maintains the streams data. The Queue object provides an easy and efficient way to add and remove data
//Each item in the queue represents each write to the stream. Every call to write translates to an item in the queue
private readonly Queue<Chunk> _buffer;
public MemoryQueueBufferStream()
{
_buffer = new Queue<Chunk>();
}
/// <summary>
/// Reads up to count bytes from the stream, and removes the read data from the stream.
/// </summary>
/// <param name="buffer"></param>
/// <param name="offset"></param>
/// <param name="count"></param>
/// <returns></returns>
public override int Read(byte[] buffer, int offset, int count)
{
var remainingBytesToRead = count;
var totalBytesRead = 0;
//Read until we hit the requested count, or until we hav nothing left to read
while (totalBytesRead <= count && _buffer.Count > 0)
{
//Get first chunk from the queue
var chunk = _buffer.Peek();
//Determine how much of the chunk there is left to read
var unreadChunkLength = chunk.Data.Length - chunk.ChunkReadStartIndex;
//Determine how much of the unread part of the chunk we can actually read
var bytesToRead = Math.Min(unreadChunkLength, remainingBytesToRead);
if (bytesToRead > 0)
{
//Read from the chunk into the buffer
Buffer.BlockCopy(chunk.Data, chunk.ChunkReadStartIndex, buffer, offset + totalBytesRead, bytesToRead);
totalBytesRead += bytesToRead;
remainingBytesToRead -= bytesToRead;
//If the entire chunk has been read, remove it
if (chunk.ChunkReadStartIndex + bytesToRead >= chunk.Data.Length)
{
_buffer.Dequeue();
}
else
{
//Otherwise just update the chunk read start index, so we know where to start reading on the next call
chunk.ChunkReadStartIndex = chunk.ChunkReadStartIndex + bytesToRead;
}
}
else
{
break;
}
}
return totalBytesRead;
}
/// <summary>
/// Writes data to the stream
/// </summary>
/// <param name="buffer">Data to copy into the stream</param>
/// <param name="offset"></param>
/// <param name="count"></param>
public override void Write(byte[] buffer, int offset, int count)
{
//We don't want to use the buffer passed in, as it could be altered by the caller
var bufSave = new byte[count];
Buffer.BlockCopy(buffer, offset, bufSave, 0, count);
//Add the data to the queue
_buffer.Enqueue(new Chunk { ChunkReadStartIndex = 0, Data = bufSave });
}
/// <summary>
/// Adds the passed buffer to the steam.
/// </summary>
/// <param name="buffer">Data to add to the stream</param>
public void Write(byte[] buffer)
{
//Add the data to the queue
_buffer.Enqueue(new Chunk { ChunkReadStartIndex = 0, Data = buffer });
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException(GetType().Name + " is not seekable");
}
public override void SetLength(long value)
{
throw new NotSupportedException(GetType().Name + " length can not be changed");
}
public override void Flush()
{
}
}
}

Просмотреть файл

@ -1,6 +1,6 @@
using System; using System;
using System.Threading; using System.Threading;
using DtronixMessageQueue.Socket; using DtronixMessageQueue.TcpSocket;
namespace DtronixMessageQueue namespace DtronixMessageQueue
@ -10,7 +10,7 @@ namespace DtronixMessageQueue
/// </summary> /// </summary>
/// <typeparam name="TSession">Session type for this connection.</typeparam> /// <typeparam name="TSession">Session type for this connection.</typeparam>
/// <typeparam name="TConfig">Configuration for this connection.</typeparam> /// <typeparam name="TConfig">Configuration for this connection.</typeparam>
public class MqClient<TSession, TConfig> : SocketClient<TSession, TConfig> public class MqClient<TSession, TConfig> : TcpSocketClient<TSession, TConfig>
where TSession : MqSession<TSession, TConfig>, new() where TSession : MqSession<TSession, TConfig>, new()
where TConfig : MqConfig where TConfig : MqConfig
{ {
@ -54,7 +54,7 @@ namespace DtronixMessageQueue
base.OnConnect(session); base.OnConnect(session);
} }
protected override void OnClose(TSession session, SocketCloseReason reason) protected override void OnClose(TSession session, CloseReason reason)
{ {
// Stop the timeout timer. // Stop the timeout timer.
_pingTimer.Change(Timeout.Infinite, Timeout.Infinite); _pingTimer.Change(Timeout.Infinite, Timeout.Infinite);
@ -117,7 +117,7 @@ namespace DtronixMessageQueue
return; return;
} }
Session.IncomingMessage -= OnIncomingMessage; Session.IncomingMessage -= OnIncomingMessage;
Session.Close(SocketCloseReason.ClientClosing); Session.Close(CloseReason.Closing);
Session.Dispose(); Session.Dispose();
} }

Просмотреть файл

@ -1,8 +1,8 @@
using DtronixMessageQueue.Socket; using DtronixMessageQueue.TcpSocket;
namespace DtronixMessageQueue namespace DtronixMessageQueue
{ {
public class MqConfig : SocketConfig public class MqConfig : TcpSocketConfig
{ {
/// <summary> /// <summary>
/// Max size of the frame. Needs to be equal or smaller than SendAndReceiveBufferSize. /// Max size of the frame. Needs to be equal or smaller than SendAndReceiveBufferSize.

Просмотреть файл

@ -10,11 +10,6 @@ namespace DtronixMessageQueue
/// </summary> /// </summary>
public class MqFrameBuilder : IDisposable public class MqFrameBuilder : IDisposable
{ {
/// <summary>
/// Byte buffer used to maintain and parse the passed buffers.
/// </summary>
private readonly byte[] _internalBuffer;
/// <summary> /// <summary>
/// Data for this frame /// Data for this frame
/// </summary> /// </summary>
@ -25,25 +20,10 @@ namespace DtronixMessageQueue
/// </summary> /// </summary>
private MqFrameType _currentFrameType; private MqFrameType _currentFrameType;
/// <summary>
/// Reading position in the internal buffer. Set by the internal reader.
/// </summary>
private int _readPosition;
/// <summary>
/// Writing position in the internal buffer. Set by the internal writer.
/// </summary>
private int _writePosition;
/// <summary>
/// Total length of the internal buffer's data. Set by the reader and writer.
/// </summary>
private int _streamLength;
/// <summary> /// <summary>
/// Memory stream used to read and write to the internal buffer. /// Memory stream used to read and write to the internal buffer.
/// </summary> /// </summary>
private readonly MemoryStream _bufferStream; private readonly MemoryQueueBufferStream _bufferStream;
/// <summary> /// <summary>
/// Used to cache the maximum size of the MqFrameType. /// Used to cache the maximum size of the MqFrameType.
@ -55,16 +35,14 @@ namespace DtronixMessageQueue
/// </summary> /// </summary>
private readonly MqConfig _config; private readonly MqConfig _config;
public Queue<MqFrame> Frames { get; }
/// <summary> /// <summary>
/// Size in bytes of the header of a frame. /// Size in bytes of the header of a frame.
/// MqFrameType:byte[1], Length:UInt16[2] /// MqFrameType:byte[1], Length:UInt16[2]
/// </summary> /// </summary>
public const int HeaderLength = 3; public const int HeaderLength = 3;
/// <summary>
/// Parsed frames from the incoming stream.
/// </summary>
public Queue<MqFrame> Frames { get; } = new Queue<MqFrame>();
/// <summary> /// <summary>
/// Creates a new instance of the frame builder to handle parsing of incoming byte stream. /// Creates a new instance of the frame builder to handle parsing of incoming byte stream.
@ -73,116 +51,23 @@ namespace DtronixMessageQueue
public MqFrameBuilder(MqConfig config) public MqFrameBuilder(MqConfig config)
{ {
_config = config; _config = config;
_internalBuffer = new byte[(config.FrameBufferSize + MqFrame.HeaderLength) * 2 ]; Frames = new Queue<MqFrame>();
_bufferStream = new MemoryQueueBufferStream();
// Determine what our max enum value is for the FrameType // Determine what our max enum value is for the FrameType
if (_maxTypeEnum == -1) if (_maxTypeEnum == -1)
{ {
_maxTypeEnum = Enum.GetValues(typeof(MqFrameType)).Cast<byte>().Max(); _maxTypeEnum = Enum.GetValues(typeof(MqFrameType)).Cast<byte>().Max();
} }
_bufferStream = new MemoryStream(_internalBuffer, 0, _internalBuffer.Length, true, true);
} }
/// <summary> /// <summary>
/// Reads from the internal stream. /// Writes the specified bytes to the FrameBuilder and parses them as they are read.
/// </summary>
/// <param name="buffer">Byte buffer to read into.</param>
/// <param name="offset">Offset position in the buffer to copy from.</param>
/// <param name="count">Number of bytes to attempt to read.</param>
/// <returns>Total bytes that were read.</returns>
private int ReadInternal(byte[] buffer, int offset, int count)
{
_bufferStream.Position = _readPosition;
var length = _bufferStream.Read(buffer, offset, count);
_readPosition += length;
// Update the stream length
_streamLength = _writePosition - _readPosition;
return length;
}
/// <summary>
/// Writes to the internal stream from the specified buffer.
/// </summary>
/// <param name="buffer">Buffer to write from.</param>
/// <param name="offset">Offset position in the buffer copy from.</param>
/// <param name="count">Number of bytes to copy from the write_buffer.</param>
private void WriteInternal(byte[] buffer, int offset, int count)
{
_bufferStream.Position = _writePosition;
try
{
_bufferStream.Write(buffer, offset, count);
}
catch (Exception e)
{
throw new InvalidDataException("FrameBuilder was sent a frame larger than the session allows.", e);
}
_writePosition += count;
// Update the stream length
_streamLength = _writePosition - _readPosition;
}
/// <summary>
/// Moves the internal buffer stream from the read position to the end, to the beginning.
/// Frees up space to write in the buffer.
/// </summary>
private void MoveStreamBytesToBeginning()
{
var i = 0;
for (; i < _writePosition - _readPosition; i++)
{
_internalBuffer[i] = _internalBuffer[i + _readPosition];
}
// Update the length for the new size.
_bufferStream.SetLength(i);
//buffer_stream.Position -= write_position;
// Reset the internal writer and reader positions.
_streamLength = _writePosition = i;
_readPosition = 0;
}
/// <summary>
/// Writes the specified bytes to the FrameBuilder and parses them as they are copied.
/// </summary> /// </summary>
/// <param name="buffer">Byte buffer to write and parse.</param> /// <param name="buffer">Byte buffer to write and parse.</param>
/// <param name="offset">Offset in the byte buffer to copy from.</param> public void Write(byte[] buffer)
/// <param name="count">Number of bytes to write into the builder.</param>
public void Write(byte[] buffer, int offset, int count)
{ {
while (count > 0) _bufferStream.Write(buffer);
{
int maxWrite = count;
// If we are over the byte limitation, then move the buffer back to the beginning of the stream and reset the stream.
if (count + _writePosition > _internalBuffer.Length)
{
MoveStreamBytesToBeginning();
maxWrite = Math.Min(Math.Abs(count - _writePosition), count);
}
WriteInternalPart(buffer, offset, maxWrite);
offset += maxWrite;
count -= maxWrite;
//count
}
}
/// <summary>
/// Writes the specified partial bytes to the FrameBuilder and parses them as they are copied.
/// </summary>
/// <param name="buffer">Byte buffer to write and parse.</param>
/// <param name="offset">Offset in the byte buffer to copy from.</param>
/// <param name="count">Number of bytes to write into the builder.</param>
private void WriteInternalPart(byte[] buffer, int offset, int count)
{
// Write the incoming bytes to the stream.
WriteInternal(buffer, offset, count);
// Loop until we require more data // Loop until we require more data
while (true) while (true)
@ -192,7 +77,7 @@ namespace DtronixMessageQueue
var frameTypeBytes = new byte[1]; var frameTypeBytes = new byte[1];
// This will always return one byte. // This will always return one byte.
ReadInternal(frameTypeBytes, 0, 1); _bufferStream.Read(frameTypeBytes, 0, 1);
if (frameTypeBytes[0] > _maxTypeEnum) if (frameTypeBytes[0] > _maxTypeEnum)
{ {
@ -208,15 +93,15 @@ namespace DtronixMessageQueue
_currentFrameType == MqFrameType.Ping) _currentFrameType == MqFrameType.Ping)
{ {
EnqueueAndReset(); EnqueueAndReset();
break; continue;
} }
// Read the length from the stream if there are enough buffer. // Read the length from the stream if there are enough buffer.
if (_currentFrameData == null && _streamLength >= 2) if (_currentFrameData == null && _bufferStream.Length >= 2)
{ {
var frameLen = new byte[2]; var frameLen = new byte[2];
ReadInternal(frameLen, 0, frameLen.Length); _bufferStream.Read(frameLen, 0, frameLen.Length);
var currentFrameLength = BitConverter.ToUInt16(frameLen, 0); var currentFrameLength = BitConverter.ToUInt16(frameLen, 0);
if (currentFrameLength < 1) if (currentFrameLength < 1)
@ -225,7 +110,7 @@ namespace DtronixMessageQueue
$"FrameBuilder was sent a frame with an invalid size of {currentFrameLength}"); $"FrameBuilder was sent a frame with an invalid size of {currentFrameLength}");
} }
if (currentFrameLength > _internalBuffer.Length) if (currentFrameLength > _config.FrameBufferSize)
{ {
throw new InvalidDataException( throw new InvalidDataException(
$"Frame size is {currentFrameLength} while the maximum size for frames is 16KB."); $"Frame size is {currentFrameLength} while the maximum size for frames is 16KB.");
@ -237,15 +122,15 @@ namespace DtronixMessageQueue
} }
// Read the data into the frame holder. // Read the data into the frame holder.
if (_currentFrameData != null && _streamLength >= _currentFrameData.Length) if (_currentFrameData != null && _bufferStream.Length >= _currentFrameData.Length)
{ {
ReadInternal(_currentFrameData, 0, _currentFrameData.Length); _bufferStream.Read(_currentFrameData, 0, _currentFrameData.Length);
// Create the frame and enqueue it. // Create the frame and enqueue it.
EnqueueAndReset(); EnqueueAndReset();
// If we are at the end of the data, complete this loop and wait for more data. // If we are at the end of the data, complete this loop and wait for more data.
if (_writePosition == _readPosition) if (_bufferStream.Length == 0)
{ {
break; break;
} }

Просмотреть файл

@ -1,5 +1,5 @@
using System; using System;
using DtronixMessageQueue.Socket; using DtronixMessageQueue.TcpSocket;
namespace DtronixMessageQueue namespace DtronixMessageQueue
{ {
@ -8,7 +8,7 @@ namespace DtronixMessageQueue
/// </summary> /// </summary>
/// <typeparam name="TSession">Session type for this connection.</typeparam> /// <typeparam name="TSession">Session type for this connection.</typeparam>
/// <typeparam name="TConfig">Configuration for this connection.</typeparam> /// <typeparam name="TConfig">Configuration for this connection.</typeparam>
public class MqServer<TSession, TConfig> : SocketServer<TSession, TConfig> public class MqServer<TSession, TConfig> : TcpSocketServer<TSession, TConfig>
where TSession : MqSession<TSession, TConfig>, new() where TSession : MqSession<TSession, TConfig>, new()
where TConfig : MqConfig where TConfig : MqConfig
{ {
@ -52,7 +52,7 @@ namespace DtronixMessageQueue
/// </summary> /// </summary>
/// <param name="session">Session which closed.</param> /// <param name="session">Session which closed.</param>
/// <param name="reason">Reason the session closed.</param> /// <param name="reason">Reason the session closed.</param>
protected override void OnClose(TSession session, SocketCloseReason reason) protected override void OnClose(TSession session, CloseReason reason)
{ {
session.IncomingMessage -= OnIncomingMessage; session.IncomingMessage -= OnIncomingMessage;
session.Dispose(); session.Dispose();

Просмотреть файл

@ -3,7 +3,7 @@ using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Threading; using System.Threading;
using DtronixMessageQueue.Socket; using DtronixMessageQueue.TcpSocket;
namespace DtronixMessageQueue namespace DtronixMessageQueue
{ {
@ -12,7 +12,7 @@ namespace DtronixMessageQueue
/// </summary> /// </summary>
/// <typeparam name="TSession">Session type for this connection.</typeparam> /// <typeparam name="TSession">Session type for this connection.</typeparam>
/// <typeparam name="TConfig">Configuration for this connection.</typeparam> /// <typeparam name="TConfig">Configuration for this connection.</typeparam>
public abstract class MqSession<TSession, TConfig> : SocketSession<TSession, TConfig> public abstract class MqSession<TSession, TConfig> : TcpSocketSession<TSession, TConfig>
where TSession : MqSession<TSession, TConfig>, new() where TSession : MqSession<TSession, TConfig>, new()
where TConfig : MqConfig where TConfig : MqConfig
{ {
@ -111,7 +111,7 @@ namespace DtronixMessageQueue
while (_outbox.TryDequeue(out message)) while (_outbox.TryDequeue(out message))
{ {
if(CurrentState != State.Closing) if(CurrentState != State.Closed)
_sendingSemaphore.Release(); _sendingSemaphore.Release();
message.PrepareSend(); message.PrepareSend();
@ -162,15 +162,18 @@ namespace DtronixMessageQueue
if (CurrentState == State.Connected) if (CurrentState == State.Connected)
_receivingSemaphore.Release(); _receivingSemaphore.Release();
if (buffer == null)
Close(CloseReason.Closing);
try try
{ {
_frameBuilder.Write(buffer, 0, buffer.Length); _frameBuilder.Write(buffer);
} }
catch (InvalidDataException) catch (InvalidDataException)
{ {
//logger.Error(ex, "Connector {0}: Client send invalid data.", Connection.Id); //logger.Error(ex, "Connector {0}: Client send invalid data.", Connection.Id);
Close(SocketCloseReason.ProtocolError); Close(CloseReason.ProtocolError);
break; break;
} }
@ -184,7 +187,7 @@ namespace DtronixMessageQueue
// Do nothing if this is a ping frame. // Do nothing if this is a ping frame.
if (frame.FrameType == MqFrameType.Ping) if (frame.FrameType == MqFrameType.Ping)
{ {
if (BaseSocket.Mode == SocketMode.Server) if (SocketHandler.Mode == TcpSocketMode.Server)
{ {
// Re-send ping frame back to the client to refresh client connection timeout timer. // Re-send ping frame back to the client to refresh client connection timeout timer.
Send(CreateFrame(null, MqFrameType.Ping)); Send(CreateFrame(null, MqFrameType.Ping));
@ -242,18 +245,14 @@ namespace DtronixMessageQueue
/// Notifies the recipient connection the reason for the session's closure. /// Notifies the recipient connection the reason for the session's closure.
/// </summary> /// </summary>
/// <param name="reason">Reason for closing this session.</param> /// <param name="reason">Reason for closing this session.</param>
public override void Close(SocketCloseReason reason) public override void Close(CloseReason reason)
{
if (CurrentState == State.Closed)
{ {
if (CurrentState == State.Closed && reason != CloseReason.ConnectionRefused)
return; return;
}
MqFrame closeFrame = null; MqFrame closeFrame = null;
if (CurrentState == State.Connected || CurrentState == State.Connecting) if (CurrentState == State.Connected || reason == CloseReason.ConnectionRefused)
{ {
CurrentState = State.Closing;
closeFrame = CreateFrame(new byte[2], MqFrameType.Command); closeFrame = CreateFrame(new byte[2], MqFrameType.Command);
closeFrame.Write(0, (byte)0); closeFrame.Write(0, (byte)0);
@ -278,6 +277,9 @@ namespace DtronixMessageQueue
msg = new MqMessage(closeFrame); msg = new MqMessage(closeFrame);
_outbox.Enqueue(msg); _outbox.Enqueue(msg);
// Take one wait to send the close packet.
_sendingSemaphore.Wait();
// QueueOnce the last bit of data. // QueueOnce the last bit of data.
ProcessOutbox(); ProcessOutbox();
} }
@ -352,12 +354,11 @@ namespace DtronixMessageQueue
switch (commandType) switch (commandType)
{ {
case MqCommandType.Disconnect: case MqCommandType.Disconnect:
CurrentState = State.Closing; Close((CloseReason)frame.ReadByte(1));
Close((SocketCloseReason)frame.ReadByte(1));
break; break;
default: default:
Close(SocketCloseReason.ProtocolError); Close(CloseReason.ProtocolError);
break; break;
} }
} }
@ -368,7 +369,7 @@ namespace DtronixMessageQueue
/// <returns>String representation.</returns> /// <returns>String representation.</returns>
public override string ToString() public override string ToString()
{ {
return $"MqSession; Reading {_inboxBytes.Count} byte packets; Sending {_outbox.Count} messages."; return $"{SocketHandler.Mode} RcpSocketSession; Reading {_inboxBytes.Count} byte packets; Sending {_outbox.Count} messages.";
} }

Просмотреть файл

@ -1,5 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using DtronixMessageQueue.Socket; using DtronixMessageQueue.TcpSocket;
namespace DtronixMessageQueue.Rpc namespace DtronixMessageQueue.Rpc
{ {
@ -49,7 +49,7 @@ namespace DtronixMessageQueue.Rpc
{ {
if (message[0][0] != Id) if (message[0][0] != Id)
{ {
Session.Close(SocketCloseReason.ProtocolError); Session.Close(CloseReason.ProtocolError);
} }
// Read the type of message. // Read the type of message.
@ -63,7 +63,7 @@ namespace DtronixMessageQueue.Rpc
} }
// Unknown message type passed. Disconnect the connection. // Unknown message type passed. Disconnect the connection.
Session.Close(SocketCloseReason.ProtocolError); Session.Close(CloseReason.ProtocolError);
return false; return false;
} }

Просмотреть файл

@ -1,6 +1,6 @@
using System; using System;
using DtronixMessageQueue.Rpc.DataContract; using DtronixMessageQueue.Rpc.DataContract;
using DtronixMessageQueue.Socket; using DtronixMessageQueue.TcpSocket;
namespace DtronixMessageQueue.Rpc namespace DtronixMessageQueue.Rpc
{ {

Просмотреть файл

@ -19,6 +19,6 @@
/// <summary> /// <summary>
/// Server is sending the result of the authentication request. /// Server is sending the result of the authentication request.
/// </summary> /// </summary>
AuthenticationResult = 2, AuthenticationSuccess = 2,
} }
} }

Просмотреть файл

@ -1,6 +1,6 @@
using System; using System;
using DtronixMessageQueue.Rpc.DataContract; using DtronixMessageQueue.Rpc.DataContract;
using DtronixMessageQueue.Socket; using DtronixMessageQueue.TcpSocket;
namespace DtronixMessageQueue.Rpc namespace DtronixMessageQueue.Rpc
{ {
@ -78,12 +78,12 @@ namespace DtronixMessageQueue.Rpc
if (session.LastReceived < timeoutTime) if (session.LastReceived < timeoutTime)
{ {
// Check for session timeout // Check for session timeout
session.Close(SocketCloseReason.TimeOut); session.Close(CloseReason.TimeOut);
} }
else if (session.Authenticated == false && session.ConnectedTime < timeoutTime) else if (session.Authenticated == false && session.ConnectedTime < timeoutTime)
{ {
// Ensure that failed authentications are removed. // Ensure that failed authentications are removed.
session.Close(SocketCloseReason.AuthenticationFailure); session.Close(CloseReason.AuthenticationFailure);
} }
} }
} }

Просмотреть файл

@ -4,7 +4,7 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using DtronixMessageQueue.Rpc.DataContract; using DtronixMessageQueue.Rpc.DataContract;
using DtronixMessageQueue.Rpc.MessageHandlers; using DtronixMessageQueue.Rpc.MessageHandlers;
using DtronixMessageQueue.Socket; using DtronixMessageQueue.TcpSocket;
namespace DtronixMessageQueue.Rpc namespace DtronixMessageQueue.Rpc
{ {
@ -75,10 +75,10 @@ namespace DtronixMessageQueue.Rpc
base.OnSetup(); base.OnSetup();
// Determine if this session is running on the server or client to retrieve the worker thread pool. // Determine if this session is running on the server or client to retrieve the worker thread pool.
if (BaseSocket.Mode == SocketMode.Server) if (SocketHandler.Mode == TcpSocketMode.Server)
Server = (RpcServer<TSession, TConfig>) BaseSocket; Server = (RpcServer<TSession, TConfig>) SocketHandler;
else else
Client = (RpcClient<TSession, TConfig>) BaseSocket; Client = (RpcClient<TSession, TConfig>) SocketHandler;
SerializationCache = new SerializationCache(Config); SerializationCache = new SerializationCache(Config);
@ -112,9 +112,9 @@ namespace DtronixMessageQueue.Rpc
// RpcCommand:byte; RpcCommandType:byte; RpcServerInfoDataContract:byte[]; // RpcCommand:byte; RpcCommandType:byte; RpcServerInfoDataContract:byte[];
// Ensure that this command is running on the client. // Ensure that this command is running on the client.
if (BaseSocket.Mode != SocketMode.Client) if (SocketHandler.Mode != TcpSocketMode.Client)
{ {
Close(SocketCloseReason.ProtocolError); Close(CloseReason.ProtocolError);
return; return;
} }
@ -131,7 +131,7 @@ namespace DtronixMessageQueue.Rpc
if (Client.ServerInfo == null) if (Client.ServerInfo == null)
{ {
Close(SocketCloseReason.ProtocolError); Close(CloseReason.ProtocolError);
return; return;
} }
@ -169,7 +169,7 @@ namespace DtronixMessageQueue.Rpc
} }
if (!_authTimeoutCancel.IsCancellationRequested) if (!_authTimeoutCancel.IsCancellationRequested)
Close(SocketCloseReason.TimeOut); Close(CloseReason.TimeOut);
}); });
// RpcCommand:byte; RpcCommandType:byte; AuthData:byte[]; // RpcCommand:byte; RpcCommandType:byte; AuthData:byte[];
@ -194,16 +194,16 @@ namespace DtronixMessageQueue.Rpc
// RpcCommand:byte; RpcCommandType:byte; AuthData:byte[]; // RpcCommand:byte; RpcCommandType:byte; AuthData:byte[];
// If this is not run on the server, quit. // If this is not run on the server, quit.
if (BaseSocket.Mode != SocketMode.Server) if (SocketHandler.Mode != TcpSocketMode.Server)
{ {
Close(SocketCloseReason.ProtocolError); Close(CloseReason.ProtocolError);
return; return;
} }
// Ensure that the server requires authentication. // Ensure that the server requires authentication.
if (Server.Config.RequireAuthentication == false) if (Server.Config.RequireAuthentication == false)
{ {
Close(SocketCloseReason.ProtocolError); Close(CloseReason.ProtocolError);
return; return;
} }
@ -222,18 +222,15 @@ namespace DtronixMessageQueue.Rpc
if (Authenticated == false) if (Authenticated == false)
{ {
Close(SocketCloseReason.AuthenticationFailure); Close(CloseReason.AuthenticationFailure);
} }
else else
{ {
var authFrame = CreateFrame(new byte[authArgs.AuthData.Length + 2], MqFrameType.Command); var authFrame = CreateFrame(new byte[authArgs.AuthData.Length + 2], MqFrameType.Command);
authFrame.Write(0, (byte) MqCommandType.RpcCommand); authFrame.Write(0, (byte) MqCommandType.RpcCommand);
authFrame.Write(1, (byte) RpcCommandType.AuthenticationResult); authFrame.Write(1, (byte) RpcCommandType.AuthenticationSuccess);
// State of the authentication // RpcCommand:byte; RpcCommandType:byte;
authFrame.Write(2, Authenticated);
// RpcCommand:byte; RpcCommandType:byte; AuthResult:bool;
Send(authFrame); Send(authFrame);
// Alert the server that this session is ready for usage. // Alert the server that this session is ready for usage.
@ -241,32 +238,29 @@ namespace DtronixMessageQueue.Rpc
() => { Ready?.Invoke(this, new SessionEventArgs<TSession, TConfig>((TSession) this)); }); () => { Ready?.Invoke(this, new SessionEventArgs<TSession, TConfig>((TSession) this)); });
} }
} }
else if (rpcCommandType == RpcCommandType.AuthenticationResult) else if (rpcCommandType == RpcCommandType.AuthenticationSuccess)
{ {
// RpcCommand:byte; RpcCommandType:byte; AuthResult:bool; // RpcCommand:byte; RpcCommandType:byte;
// Cancel the timeout request. // Cancel the timeout request.
_authTimeoutCancel.Cancel(); _authTimeoutCancel.Cancel();
// Ensure that this command is running on the client. // Ensure that this command is running on the client.
if (BaseSocket.Mode != SocketMode.Client) if (SocketHandler.Mode != TcpSocketMode.Client)
{ {
Close(SocketCloseReason.ProtocolError); Close(CloseReason.ProtocolError);
return; return;
} }
if (Client.Config.RequireAuthentication == false) if (Client.ServerInfo.RequireAuthentication == false)
{ {
Close(SocketCloseReason.ProtocolError); Close(CloseReason.ProtocolError);
return; return;
} }
Authenticated = true; Authenticated = true;
var authArgs = new RpcAuthenticateEventArgs<TSession, TConfig>((TSession) this) var authArgs = new RpcAuthenticateEventArgs<TSession, TConfig>((TSession) this);
{
Authenticated = frame.ReadBoolean(2)
};
// Alert the client that the sesion has been authenticated. // Alert the client that the sesion has been authenticated.
AuthenticationSuccess?.Invoke(this, authArgs); AuthenticationSuccess?.Invoke(this, authArgs);
@ -276,12 +270,12 @@ namespace DtronixMessageQueue.Rpc
} }
else else
{ {
Close(SocketCloseReason.ProtocolError); Close(CloseReason.ProtocolError);
} }
} }
catch (Exception) catch (Exception)
{ {
Close(SocketCloseReason.ProtocolError); Close(CloseReason.ProtocolError);
} }
} }
@ -291,7 +285,7 @@ namespace DtronixMessageQueue.Rpc
protected override void OnConnected() protected override void OnConnected()
{ {
// If this is a new session on the server, send the welcome message. // If this is a new session on the server, send the welcome message.
if (BaseSocket.Mode == SocketMode.Server) if (SocketHandler.Mode == TcpSocketMode.Server)
{ {
Server.ServerInfo.RequireAuthentication = Config.RequireAuthentication; Server.ServerInfo.RequireAuthentication = Config.RequireAuthentication;
@ -312,7 +306,7 @@ namespace DtronixMessageQueue.Rpc
base.OnConnected(); base.OnConnected();
// If the server does not require authentication, alert the server session that it is ready. // If the server does not require authentication, alert the server session that it is ready.
if (BaseSocket.Mode == SocketMode.Server && Config.RequireAuthentication == false) if (SocketHandler.Mode == TcpSocketMode.Server && Config.RequireAuthentication == false)
{ {
Authenticated = true; Authenticated = true;
Ready?.Invoke(this, new SessionEventArgs<TSession, TConfig>((TSession) this)); Ready?.Invoke(this, new SessionEventArgs<TSession, TConfig>((TSession) this));
@ -348,7 +342,7 @@ namespace DtronixMessageQueue.Rpc
} }
catch catch
{ {
Close(SocketCloseReason.ApplicationError); Close(CloseReason.ApplicationError);
return; return;
} }
@ -357,7 +351,7 @@ namespace DtronixMessageQueue.Rpc
// If the we can not handle this message, disconnect the session. // If the we can not handle this message, disconnect the session.
if (handledMessage == false) if (handledMessage == false)
{ {
Close(SocketCloseReason.ProtocolError); Close(CloseReason.ProtocolError);
return; return;
} }
} }

Просмотреть файл

@ -5,7 +5,7 @@ using System.Reflection;
using System.Reflection.Emit; using System.Reflection.Emit;
using System.Threading; using System.Threading;
namespace DtronixMessageQueue namespace DtronixMessageQueue.Rpc
{ {
public class ServiceMethodCache public class ServiceMethodCache
{ {

Просмотреть файл

@ -1,6 +1,7 @@
using System; using System;
using DtronixMessageQueue.TcpSocket;
namespace DtronixMessageQueue.Socket namespace DtronixMessageQueue
{ {
/// <summary> /// <summary>
/// Event args used when a session is closed. /// Event args used when a session is closed.
@ -8,8 +9,8 @@ namespace DtronixMessageQueue.Socket
/// <typeparam name="TSession">Session type for this connection.</typeparam> /// <typeparam name="TSession">Session type for this connection.</typeparam>
/// <typeparam name="TConfig">Configuration for this connection.</typeparam> /// <typeparam name="TConfig">Configuration for this connection.</typeparam>
public class SessionClosedEventArgs<TSession, TConfig> : EventArgs public class SessionClosedEventArgs<TSession, TConfig> : EventArgs
where TSession : SocketSession<TSession, TConfig>, new() where TSession : TcpSocketSession<TSession, TConfig>, new()
where TConfig : SocketConfig where TConfig : TcpSocketConfig
{ {
/// <summary> /// <summary>
/// Closed session. /// Closed session.
@ -19,14 +20,14 @@ namespace DtronixMessageQueue.Socket
/// <summary> /// <summary>
/// Reason the session was closed. /// Reason the session was closed.
/// </summary> /// </summary>
public SocketCloseReason CloseReason { get; } public CloseReason CloseReason { get; }
/// <summary> /// <summary>
/// Creates a new instance of the session closed event args. /// Creates a new instance of the session closed event args.
/// </summary> /// </summary>
/// <param name="session">Closed session.</param> /// <param name="session">Closed session.</param>
/// <param name="closeReason">Reason the session was closed.</param> /// <param name="closeReason">Reason the session was closed.</param>
public SessionClosedEventArgs(TSession session, SocketCloseReason closeReason) public SessionClosedEventArgs(TSession session, CloseReason closeReason)
{ {
Session = session; Session = session;
CloseReason = closeReason; CloseReason = closeReason;

Просмотреть файл

@ -1,6 +1,7 @@
using System; using System;
using DtronixMessageQueue.TcpSocket;
namespace DtronixMessageQueue.Socket namespace DtronixMessageQueue
{ {
/// <summary> /// <summary>
/// Event args used when the session has connected to a remote endpoint. /// Event args used when the session has connected to a remote endpoint.
@ -8,8 +9,8 @@ namespace DtronixMessageQueue.Socket
/// <typeparam name="TSession">Session type for this connection.</typeparam> /// <typeparam name="TSession">Session type for this connection.</typeparam>
/// <typeparam name="TConfig">Configuration for this connection.</typeparam> /// <typeparam name="TConfig">Configuration for this connection.</typeparam>
public class SessionEventArgs<TSession, TConfig> : EventArgs public class SessionEventArgs<TSession, TConfig> : EventArgs
where TSession : SocketSession<TSession, TConfig>, new() where TSession : TcpSocketSession<TSession, TConfig>, new()
where TConfig : SocketConfig where TConfig : TcpSocketConfig
{ {
/// <summary> /// <summary>
/// Connected session. /// Connected session.

Просмотреть файл

@ -1,7 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Net.Sockets; using System.Net.Sockets;
namespace DtronixMessageQueue.Socket namespace DtronixMessageQueue.TcpSocket
{ {
/// <summary> /// <summary>
/// Large memory buffer manager /// Large memory buffer manager

Просмотреть файл

@ -1,4 +1,4 @@
namespace DtronixMessageQueue.Socket namespace DtronixMessageQueue.TcpSocket
{ {
/// <summary> /// <summary>
/// Class to implement on classes which have setup events. /// Class to implement on classes which have setup events.

Просмотреть файл

@ -1,9 +1,7 @@
using System; using System.Net.Sockets;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Threading; using System.Threading;
namespace DtronixMessageQueue.Socket namespace DtronixMessageQueue.TcpSocket
{ {
/// <summary> /// <summary>
/// Represents a collection of reusable SocketAsyncEventArgs objects. /// Represents a collection of reusable SocketAsyncEventArgs objects.

Просмотреть файл

@ -4,16 +4,16 @@ using System.Net.Sockets;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace DtronixMessageQueue.Socket namespace DtronixMessageQueue.TcpSocket
{ {
/// <summary> /// <summary>
/// Base functionality for all client connections to a remote server. /// Base functionality for all client connections to a remote server.
/// </summary> /// </summary>
/// <typeparam name="TSession">Session type for this connection.</typeparam> /// <typeparam name="TSession">Session type for this connection.</typeparam>
/// <typeparam name="TConfig">Configuration for this connection.</typeparam> /// <typeparam name="TConfig">Configuration for this connection.</typeparam>
public class SocketClient<TSession, TConfig> : SessionHandler<TSession, TConfig> public class TcpSocketClient<TSession, TConfig> : TcpSocketHandler<TSession, TConfig>
where TSession : SocketSession<TSession, TConfig>, new() where TSession : TcpSocketSession<TSession, TConfig>, new()
where TConfig : SocketConfig where TConfig : TcpSocketConfig
{ {
/// <summary> /// <summary>
/// True if the client is connected to a server. /// True if the client is connected to a server.
@ -26,11 +26,16 @@ namespace DtronixMessageQueue.Socket
/// </summary> /// </summary>
public TSession Session { get; private set; } public TSession Session { get; private set; }
/// <summary>
/// Cancellation token to cancel the timeout event for connections.
/// </summary>
private CancellationTokenSource _connectionTimeoutCancellation;
/// <summary> /// <summary>
/// Creates a socket client with the specified configurations. /// Creates a socket client with the specified configurations.
/// </summary> /// </summary>
/// <param name="config">Configurations to use.</param> /// <param name="config">Configurations to use.</param>
public SocketClient(TConfig config) : base(config, SocketMode.Client) public TcpSocketClient(TConfig config) : base(config, TcpSocketMode.Client)
{ {
// Override the number of processors to one for each sending queue and receiving queue. // Override the number of processors to one for each sending queue and receiving queue.
config.ProcessorThreads = 1; config.ProcessorThreads = 1;
@ -41,13 +46,9 @@ namespace DtronixMessageQueue.Socket
/// </summary> /// </summary>
public void Connect() public void Connect()
{ {
Connect(new IPEndPoint(IPAddress.Parse(Config.Ip), Config.Port)); Connect(Utilities.CreateIPEndPoint(Config.Address));
} }
/// <summary>
/// Cancellation token to cancel the timeout event for connections.
/// </summary>
private CancellationTokenSource _connectionTimeoutCancellation;
/// <summary> /// <summary>
/// Connects to the specified endpoint. /// Connects to the specified endpoint.
@ -55,7 +56,7 @@ namespace DtronixMessageQueue.Socket
/// <param name="endPoint">Endpoint to connect to.</param> /// <param name="endPoint">Endpoint to connect to.</param>
public void Connect(IPEndPoint endPoint) public void Connect(IPEndPoint endPoint)
{ {
if (MainSocket != null && Session?.CurrentState != SocketSession<TSession, TConfig>.State.Closed) if (MainSocket != null && Session?.CurrentState != TcpSocketSession<TSession, TConfig>.State.Closed)
{ {
throw new InvalidOperationException("Client is in the process of connecting."); throw new InvalidOperationException("Client is in the process of connecting.");
} }
@ -114,12 +115,12 @@ namespace DtronixMessageQueue.Socket
} }
timedOut = true; timedOut = true;
OnClose(null, SocketCloseReason.TimeOut); OnClose(null, CloseReason.TimeOut);
MainSocket.Close(); MainSocket.Close();
}, _connectionTimeoutCancellation.Token); }, _connectionTimeoutCancellation.Token);
} }
protected override void OnClose(TSession session, SocketCloseReason reason) protected override void OnClose(TSession session, CloseReason reason)
{ {
MainSocket.Close(); MainSocket.Close();

Просмотреть файл

@ -1,9 +1,9 @@
namespace DtronixMessageQueue.Socket namespace DtronixMessageQueue.TcpSocket
{ {
/// <summary> /// <summary>
/// Configurations for the server/client. /// Configurations for the server/client.
/// </summary> /// </summary>
public class SocketConfig public class TcpSocketConfig
{ {
/// <summary> /// <summary>
/// Maximum number of connections allowed. Only used by the server. /// Maximum number of connections allowed. Only used by the server.
@ -34,12 +34,7 @@
/// <summary> /// <summary>
/// IP address to bind or connect to. /// IP address to bind or connect to.
/// </summary> /// </summary>
public string Ip { get; set; } public string Address { get; set; }
/// <summary>
/// Port to bind or connect to.
/// </summary>
public int Port { get; set; }
/// <summary> /// <summary>
/// (Server) /// (Server)

Просмотреть файл

@ -2,22 +2,23 @@
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading; using System.Threading;
using DtronixMessageQueue.Rpc;
namespace DtronixMessageQueue.Socket namespace DtronixMessageQueue.TcpSocket
{ {
/// <summary> /// <summary>
/// Base socket for all server and client sockets. /// Base socket for all server and client sockets.
/// </summary> /// </summary>
/// <typeparam name="TSession">Session type for this connection.</typeparam> /// <typeparam name="TSession">Session type for this connection.</typeparam>
/// <typeparam name="TConfig">Configuration for this connection.</typeparam> /// <typeparam name="TConfig">Configuration for this connection.</typeparam>
public abstract class SessionHandler<TSession, TConfig> public abstract class TcpSocketHandler<TSession, TConfig>
where TSession : SocketSession<TSession, TConfig>, new() where TSession : TcpSocketSession<TSession, TConfig>, new()
where TConfig : SocketConfig where TConfig : TcpSocketConfig
{ {
/// <summary> /// <summary>
/// Mode that this socket is running as. /// Mode that this socket is running as.
/// </summary> /// </summary>
public SocketMode Mode { get; } public TcpSocketMode Mode { get; }
/// <summary> /// <summary>
/// True if the socket is connected/listening. /// True if the socket is connected/listening.
@ -90,7 +91,7 @@ namespace DtronixMessageQueue.Socket
/// </summary> /// </summary>
/// <param name="config">Configurations for this socket.</param> /// <param name="config">Configurations for this socket.</param>
/// <param name="mode">Mode of that this socket is running in.</param> /// <param name="mode">Mode of that this socket is running in.</param>
protected SessionHandler(TConfig config, SocketMode mode) protected TcpSocketHandler(TConfig config, TcpSocketMode mode)
{ {
TimeoutTimer = new Timer(TimeoutCallback); TimeoutTimer = new Timer(TimeoutCallback);
ServiceMethodCache = new ServiceMethodCache(); ServiceMethodCache = new ServiceMethodCache();
@ -98,7 +99,7 @@ namespace DtronixMessageQueue.Socket
Config = config; Config = config;
var modeLower = mode.ToString().ToLower(); var modeLower = mode.ToString().ToLower();
if (mode == SocketMode.Client) if (mode == TcpSocketMode.Client)
{ {
OutboxProcessor = new ActionProcessor<Guid>(new ActionProcessor<Guid>.Config OutboxProcessor = new ActionProcessor<Guid>(new ActionProcessor<Guid>.Config
{ {
@ -149,7 +150,7 @@ namespace DtronixMessageQueue.Socket
{ {
if (session.LastReceived < timeoutTime) if (session.LastReceived < timeoutTime)
{ {
session.Close(SocketCloseReason.TimeOut); session.Close(CloseReason.TimeOut);
} }
} }
} }
@ -177,7 +178,7 @@ namespace DtronixMessageQueue.Socket
/// </summary> /// </summary>
/// <param name="session">Session that closed.</param> /// <param name="session">Session that closed.</param>
/// <param name="reason">Reason for the closing of the session.</param> /// <param name="reason">Reason for the closing of the session.</param>
protected virtual void OnClose(TSession session, SocketCloseReason reason) protected virtual void OnClose(TSession session, CloseReason reason)
{ {
// If there are no clients connected, stop the timer. // If there are no clients connected, stop the timer.
if (ConnectedSessions.IsEmpty) if (ConnectedSessions.IsEmpty)
@ -209,7 +210,7 @@ namespace DtronixMessageQueue.Socket
/// <returns>New session instance.</returns> /// <returns>New session instance.</returns>
protected virtual TSession CreateSession(System.Net.Sockets.Socket socket) protected virtual TSession CreateSession(System.Net.Sockets.Socket socket)
{ {
var session = SocketSession<TSession, TConfig>.Create(socket, var session = TcpSocketSession<TSession, TConfig>.Create(socket,
AsyncManager, AsyncManager,
Config, Config,
this, this,

Просмотреть файл

@ -1,9 +1,9 @@
namespace DtronixMessageQueue.Socket namespace DtronixMessageQueue.TcpSocket
{ {
/// <summary> /// <summary>
/// Mode that the current Socket base is in. /// Mode that the current Socket base is in.
/// </summary> /// </summary>
public enum SocketMode public enum TcpSocketMode
{ {
/// <summary> /// <summary>
/// Socket base is running in server mode. /// Socket base is running in server mode.

Просмотреть файл

@ -2,16 +2,16 @@
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
namespace DtronixMessageQueue.Socket namespace DtronixMessageQueue.TcpSocket
{ {
/// <summary> /// <summary>
/// Base functionality for handling connection requests. /// Base functionality for handling connection requests.
/// </summary> /// </summary>
/// <typeparam name="TSession">Session type for this connection.</typeparam> /// <typeparam name="TSession">Session type for this connection.</typeparam>
/// <typeparam name="TConfig">Configuration for this connection.</typeparam> /// <typeparam name="TConfig">Configuration for this connection.</typeparam>
public class SocketServer<TSession, TConfig> : SessionHandler<TSession, TConfig> public class TcpSocketServer<TSession, TConfig> : TcpSocketHandler<TSession, TConfig>
where TSession : SocketSession<TSession, TConfig>, new() where TSession : TcpSocketSession<TSession, TConfig>, new()
where TConfig : SocketConfig where TConfig : TcpSocketConfig
{ {
/// <summary> /// <summary>
/// Set to the max number of connections allowed for the server. /// Set to the max number of connections allowed for the server.
@ -48,7 +48,7 @@ namespace DtronixMessageQueue.Socket
/// Creates a socket server with the specified configurations. /// Creates a socket server with the specified configurations.
/// </summary> /// </summary>
/// <param name="config">Configurations for this socket.</param> /// <param name="config">Configurations for this socket.</param>
public SocketServer(TConfig config) : base(config, SocketMode.Server) public TcpSocketServer(TConfig config) : base(config, TcpSocketMode.Server)
{ {
} }
@ -61,8 +61,7 @@ namespace DtronixMessageQueue.Socket
// Reset the remaining connections. // Reset the remaining connections.
_remainingConnections = Config.MaxConnections; _remainingConnections = Config.MaxConnections;
var ip = IPAddress.Parse(Config.Ip); var localEndPoint = Utilities.CreateIPEndPoint(Config.Address);
var localEndPoint = new IPEndPoint(ip, Config.Port);
if (_isStopped == false) if (_isStopped == false)
{ {
throw new InvalidOperationException("Server is already running."); throw new InvalidOperationException("Server is already running.");
@ -151,7 +150,7 @@ namespace DtronixMessageQueue.Socket
// If we are at max sessions, close the new connection with a connection refused reason. // If we are at max sessions, close the new connection with a connection refused reason.
if (maxSessions) if (maxSessions)
{ {
session.Close(SocketCloseReason.ConnectionRefused); session.Close(CloseReason.ConnectionRefused);
} }
else else
{ {
@ -208,7 +207,7 @@ namespace DtronixMessageQueue.Socket
foreach (var session in sessions) foreach (var session in sessions)
{ {
session.Close(SocketCloseReason.ServerClosing); session.Close(CloseReason.Closing);
} }
try try

Просмотреть файл

@ -1,17 +1,18 @@
using System; using System;
using System.Net.Sockets; using System.Net.Sockets;
using System.Threading; using System.Threading;
using DtronixMessageQueue.Rpc;
namespace DtronixMessageQueue.Socket namespace DtronixMessageQueue.TcpSocket
{ {
/// <summary> /// <summary>
/// Base socket session to be sub-classes by the implementer. /// Base socket session to be sub-classes by the implementer.
/// </summary> /// </summary>
/// <typeparam name="TConfig">Configuration for this connection.</typeparam> /// <typeparam name="TConfig">Configuration for this connection.</typeparam>
/// <typeparam name="TSession">Session for this connection.</typeparam> /// <typeparam name="TSession">Session for this connection.</typeparam>
public abstract class SocketSession<TSession, TConfig> : IDisposable, ISetupSocketSession public abstract class TcpSocketSession<TSession, TConfig> : IDisposable, ISetupSocketSession
where TSession : SocketSession<TSession, TConfig>, new() where TSession : TcpSocketSession<TSession, TConfig>, new()
where TConfig : SocketConfig where TConfig : TcpSocketConfig
{ {
/// <summary> /// <summary>
/// Current state of the socket. /// Current state of the socket.
@ -23,21 +24,11 @@ namespace DtronixMessageQueue.Socket
/// </summary> /// </summary>
Unknown, Unknown,
/// <summary>
/// Session is attempting to connect to remote connection.
/// </summary>
Connecting,
/// <summary> /// <summary>
/// Session has connected to remote session. /// Session has connected to remote session.
/// </summary> /// </summary>
Connected, Connected,
/// <summary>
/// Session is in the process of closing its connection.
/// </summary>
Closing,
/// <summary> /// <summary>
/// Session has been closed and no longer can be used. /// Session has been closed and no longer can be used.
/// </summary> /// </summary>
@ -84,7 +75,7 @@ namespace DtronixMessageQueue.Socket
/// <summary> /// <summary>
/// Base socket for this session. /// Base socket for this session.
/// </summary> /// </summary>
public SessionHandler<TSession, TConfig> BaseSocket { get; private set; } public TcpSocketHandler<TSession, TConfig> SocketHandler { get; private set; }
/// <summary> /// <summary>
/// Processor to handle all inbound messages. /// Processor to handle all inbound messages.
@ -143,10 +134,10 @@ namespace DtronixMessageQueue.Socket
/// <summary> /// <summary>
/// Creates a new socket session with a new Id. /// Creates a new socket session with a new Id.
/// </summary> /// </summary>
protected SocketSession() protected TcpSocketSession()
{ {
Id = Guid.NewGuid(); Id = Guid.NewGuid();
CurrentState = State.Connecting; CurrentState = State.Closed;
} }
/// <summary> /// <summary>
@ -155,14 +146,14 @@ namespace DtronixMessageQueue.Socket
/// <param name="sessionSocket">Socket this session is to use.</param> /// <param name="sessionSocket">Socket this session is to use.</param>
/// <param name="socketArgsManager">Argument pool for this session to use. Pulls two asyncevents for reading and writing and returns them at the end of this socket's life.</param> /// <param name="socketArgsManager">Argument pool for this session to use. Pulls two asyncevents for reading and writing and returns them at the end of this socket's life.</param>
/// <param name="sessionConfig">Socket configurations this session is to use.</param> /// <param name="sessionConfig">Socket configurations this session is to use.</param>
/// <param name="sessionHandler">Handler base which is handling this session.</param> /// <param name="tcpSocketHandler">Handler base which is handling this session.</param>
/// <param name="inboxProcessor">Processor which handles all inbox data.</param> /// <param name="inboxProcessor">Processor which handles all inbox data.</param>
/// /// <param name="outboxProcessor">Processor which handles all outbox data.</param> /// /// <param name="outboxProcessor">Processor which handles all outbox data.</param>
/// <param name="serviceMethodCache">Cache for commonly called methods used throughout the session.</param> /// <param name="serviceMethodCache">Cache for commonly called methods used throughout the session.</param>
public static TSession Create(System.Net.Sockets.Socket sessionSocket, public static TSession Create(System.Net.Sockets.Socket sessionSocket,
SocketAsyncEventArgsManager socketArgsManager, SocketAsyncEventArgsManager socketArgsManager,
TConfig sessionConfig, TConfig sessionConfig,
SessionHandler<TSession, TConfig> sessionHandler, TcpSocketHandler<TSession, TConfig> tcpSocketHandler,
ActionProcessor<Guid> inboxProcessor, ActionProcessor<Guid> inboxProcessor,
ActionProcessor<Guid> outboxProcessor, ActionProcessor<Guid> outboxProcessor,
ServiceMethodCache serviceMethodCache) ServiceMethodCache serviceMethodCache)
@ -173,7 +164,7 @@ namespace DtronixMessageQueue.Socket
_argsPool = socketArgsManager, _argsPool = socketArgsManager,
_socket = sessionSocket, _socket = sessionSocket,
_writeSemaphore = new SemaphoreSlim(1, 1), _writeSemaphore = new SemaphoreSlim(1, 1),
BaseSocket = sessionHandler, SocketHandler = tcpSocketHandler,
_sendArgs = socketArgsManager.Create(), _sendArgs = socketArgsManager.Create(),
_receiveArgs = socketArgsManager.Create(), _receiveArgs = socketArgsManager.Create(),
InboxProcessor = inboxProcessor, InboxProcessor = inboxProcessor,
@ -206,7 +197,7 @@ namespace DtronixMessageQueue.Socket
/// </summary> /// </summary>
void ISetupSocketSession.Start() void ISetupSocketSession.Start()
{ {
if (CurrentState != State.Connecting) if (CurrentState != State.Closed)
return; return;
CurrentState = State.Connected; CurrentState = State.Connected;
@ -235,7 +226,7 @@ namespace DtronixMessageQueue.Socket
/// Called when this session is disconnected from the socket. /// Called when this session is disconnected from the socket.
/// </summary> /// </summary>
/// <param name="reason">Reason this socket is disconnecting</param> /// <param name="reason">Reason this socket is disconnecting</param>
protected virtual void OnDisconnected(SocketCloseReason reason) protected virtual void OnDisconnected(CloseReason reason)
{ {
Closed?.Invoke(this, new SessionClosedEventArgs<TSession, TConfig>((TSession)this, reason)); Closed?.Invoke(this, new SessionClosedEventArgs<TSession, TConfig>((TSession)this, reason));
} }
@ -257,7 +248,7 @@ namespace DtronixMessageQueue.Socket
switch (e.LastOperation) switch (e.LastOperation)
{ {
case SocketAsyncOperation.Disconnect: case SocketAsyncOperation.Disconnect:
Close(SocketCloseReason.ClientClosing); Close(CloseReason.Closing);
break; break;
case SocketAsyncOperation.Receive: case SocketAsyncOperation.Receive:
@ -303,7 +294,7 @@ namespace DtronixMessageQueue.Socket
} }
catch (ObjectDisposedException) catch (ObjectDisposedException)
{ {
Close(SocketCloseReason.SocketError); Close(CloseReason.SocketError);
} }
} }
@ -317,7 +308,7 @@ namespace DtronixMessageQueue.Socket
{ {
if (e.SocketError != SocketError.Success) if (e.SocketError != SocketError.Success)
{ {
Close(SocketCloseReason.SocketError); Close(CloseReason.SocketError);
} }
_writeSemaphore.Release(1); _writeSemaphore.Release(1);
} }
@ -329,12 +320,12 @@ namespace DtronixMessageQueue.Socket
/// <param name="e">Event args of this action.</param> /// <param name="e">Event args of this action.</param>
protected void RecieveComplete(SocketAsyncEventArgs e) protected void RecieveComplete(SocketAsyncEventArgs e)
{ {
if (CurrentState == State.Closing) if (CurrentState == State.Closed)
return; return;
if (e.BytesTransferred == 0 && CurrentState == State.Connected) if (e.BytesTransferred == 0)
{ {
CurrentState = State.Closing; HandleIncomingBytes(null);
return; return;
} }
if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success) if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
@ -359,12 +350,12 @@ namespace DtronixMessageQueue.Socket
} }
catch (ObjectDisposedException) catch (ObjectDisposedException)
{ {
Close(SocketCloseReason.SocketError); Close(CloseReason.SocketError);
} }
} }
else else
{ {
Close(SocketCloseReason.SocketError); Close(CloseReason.SocketError);
} }
} }
@ -372,18 +363,23 @@ namespace DtronixMessageQueue.Socket
/// Called when this session is desired or requested to be closed. /// Called when this session is desired or requested to be closed.
/// </summary> /// </summary>
/// <param name="reason">Reason this socket is closing.</param> /// <param name="reason">Reason this socket is closing.</param>
public virtual void Close(SocketCloseReason reason) public virtual void Close(CloseReason reason)
{ {
// If this session has already been closed, nothing more to do. // If this session has already been closed, nothing more to do.
if (CurrentState == State.Closed) if (CurrentState == State.Closed && reason != CloseReason.ConnectionRefused)
return; return;
CurrentState = State.Closed;
// close the socket associated with the client // close the socket associated with the client
try try
{
if (Socket.Connected)
{ {
Socket.Shutdown(SocketShutdown.Receive); Socket.Shutdown(SocketShutdown.Receive);
Socket.Disconnect(false); Socket.Disconnect(false);
} }
}
catch (Exception) catch (Exception)
{ {
// ignored // ignored
@ -409,14 +405,25 @@ namespace DtronixMessageQueue.Socket
OnDisconnected(reason); OnDisconnected(reason);
} }
/// <summary>
/// String representation of the active session.
/// </summary>
/// <returns>String representation.</returns>
public override string ToString()
{
return $"{SocketHandler.Mode} RcpSocketSession;";
}
/// <summary> /// <summary>
/// Disconnects client and releases resources. /// Disconnects client and releases resources.
/// </summary> /// </summary>
public void Dispose() public void Dispose()
{ {
if (CurrentState == State.Connected) if (CurrentState == State.Connected)
Close(SocketCloseReason.ClientClosing); Close(CloseReason.Closing);
} }
} }
} }

Просмотреть файл

@ -1,9 +1,17 @@
namespace DtronixMessageQueue using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Net;
using System.Runtime.CompilerServices;
using System.Threading;
namespace DtronixMessageQueue
{ {
/// <summary> /// <summary>
/// Static helper utility class. /// Static helper utility class.
/// </summary> /// </summary>
public static class Utilities internal static class Utilities
{ {
/// <summary> /// <summary>
/// Creates a frame with the specified parameters. /// Creates a frame with the specified parameters.
@ -21,5 +29,58 @@
} }
return new MqFrame(bytes, type, config); return new MqFrame(bytes, type, config);
} }
/// <summary>
/// Parses an IPv4 and IPv6 strings with port into an IpEndpoint.
/// </summary>
/// <param name="endPoint">Endpoint string to parse.</param>
/// <returns>Configured IPEndPoint from the input string.</returns>
/// <remarks>
/// Created by Jens Granlund
/// https://stackoverflow.com/a/2727880
/// </remarks>
// ReSharper disable once InconsistentNaming
public static IPEndPoint CreateIPEndPoint(string endPoint)
{
string[] ep = endPoint.Split(':');
if (ep.Length < 2)
throw new FormatException("Invalid endpoint format");
IPAddress ip;
if (ep.Length > 2)
{
if (!IPAddress.TryParse(string.Join(":", ep, 0, ep.Length - 1), out ip))
{
throw new FormatException("Invalid ip-adress");
}
}
else
{
if (!IPAddress.TryParse(ep[0], out ip))
{
throw new FormatException("Invalid ip-adress");
}
}
int port;
if (!int.TryParse(ep[ep.Length - 1], NumberStyles.None, NumberFormatInfo.CurrentInfo, out port))
{
throw new FormatException("Invalid port");
}
return new IPEndPoint(ip, port);
}
private static Stopwatch sw = new Stopwatch();
internal static void TraceHelper(string text = "", [CallerMemberName] string callerName = "",
[CallerFilePath] string file = "", [CallerLineNumber] int lineNumber = 0)
{
#if false
if (!sw.IsRunning)
sw.Start();
Console.WriteLine($"{sw.Elapsed}{Thread.CurrentThread.Name,-20}{Path.GetFileNameWithoutExtension(file),-30}:{lineNumber:0000} {callerName,-15:5}: {text}");
#endif
}
} }
} }

Просмотреть файл

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="protobuf-net" version="2.3.0" targetFramework="net45" /> <package id="protobuf-net" version="2.3.2" targetFramework="net45" />
</packages> </packages>

Просмотреть файл

@ -1 +1 @@
git log v1.0..HEAD --pretty="%%H - %%s" --no-merges >output.txt git log v0.5..HEAD --pretty="%%H - %%s" --no-merges >output.txt

1
tools/MonoTests.bat Normal file
Просмотреть файл

@ -0,0 +1 @@
"C:\Program Files\Mono\bin\mono.exe" .././src/packages/NUnit.ConsoleRunner.3.7.0/tools/nunit3-console.exe .././src/DtronixMessageQueue.Tests/bin/Release/DtronixMessageQueue.Tests.dll

Просмотреть файл

@ -1,2 +1,2 @@
..\..\..\packages\NuGet.CommandLine.4.1.0\tools\nuget.exe push *0.nupkg -Source https://www.nuget.org/api/v2/package ..\..\..\packages\NuGet.CommandLine.3.4.3\tools\nuget.exe push *0.nupkg -Source https://www.nuget.org/api/v2/package
..\..\..\packages\NuGet.CommandLine.4.1.0\tools\nuget.exe push *.symbols.nupkg -Source https://nuget.smbsrc.net/ ..\..\..\packages\NuGet.CommandLine.3.4.3\tools\nuget.exe push *.symbols.nupkg -Source https://www.nuget.org/api/v2/package