Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,5 @@ UpgradeLog.htm
*.svclog
mono_crash.*.json
mono_crash.*.blob

autobahn/reports/*
7 changes: 3 additions & 4 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<!--
<!--
This section covers packages that are **not** directly referenced by the NuGet packages published from this repository.
For example, these packages are used in the tests, examples or referenced as "PrivateAssets", but not in the NuGet packages themselves.
-->
Expand All @@ -13,9 +13,8 @@
<PackageVersion Include="xunit.runner.visualstudio" Version="[2.5.4,3.0)" />
<PackageVersion Include="coverlet.collector" Version="[6.0.0,)" />
<PackageVersion Include="FluentAssertions" Version="[6.12.0,)" />
<PackageVersion Include="Nuke.Common" Version="8.0.0" />
<PackageVersion Include="Nuke.Common" Version="8.0.0" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
<PackageVersion Include="Microsoft.AspNetCore.TestHost" Version="6.0.21" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.21" />
Expand All @@ -28,4 +27,4 @@
<PackageVersion Include="Microsoft.AspNetCore.TestHost" Version="8.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.0" />
</ItemGroup>
</Project>
</Project>
11 changes: 11 additions & 0 deletions SimpleR.sln
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ext", "ext", "{813A63E0-FB3
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleR.Ocpp", "ext\SimpleR.Ocpp\SimpleR.Ocpp.csproj", "{531643BE-44A4-404B-A3BB-6C44BC7C49D9}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "autobahn", "autobahn", "{D4D520AA-4FE3-4F44-857B-B4AC0AF37E5A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleR.Authobahn.Server", "autobahn\server\SimpleR.Authobahn.Server.csproj", "{2D7F07BA-59E0-4B6D-8AB2-5AF9962AAD13}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -144,6 +148,12 @@ Global
{531643BE-44A4-404B-A3BB-6C44BC7C49D9}.Release|Any CPU.Build.0 = Release|Any CPU
{531643BE-44A4-404B-A3BB-6C44BC7C49D9}.Publish|Any CPU.ActiveCfg = Debug|Any CPU
{531643BE-44A4-404B-A3BB-6C44BC7C49D9}.Publish|Any CPU.Build.0 = Debug|Any CPU
{2D7F07BA-59E0-4B6D-8AB2-5AF9962AAD13}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2D7F07BA-59E0-4B6D-8AB2-5AF9962AAD13}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2D7F07BA-59E0-4B6D-8AB2-5AF9962AAD13}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2D7F07BA-59E0-4B6D-8AB2-5AF9962AAD13}.Release|Any CPU.Build.0 = Release|Any CPU
{2D7F07BA-59E0-4B6D-8AB2-5AF9962AAD13}.Publish|Any CPU.ActiveCfg = Debug|Any CPU
{2D7F07BA-59E0-4B6D-8AB2-5AF9962AAD13}.Publish|Any CPU.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -164,5 +174,6 @@ Global
{8CA715D9-6491-42C2-878D-6FBDA9D9B87C} = {D1E4601A-E2A0-43AC-8D33-B05D0001C88F}
{1EFE8056-F4BD-4ED0-B7AB-5B61BFE35C29} = {4BEDDC2A-CC7B-4650-BC97-AF81DE36D351}
{531643BE-44A4-404B-A3BB-6C44BC7C49D9} = {813A63E0-FB31-48A3-AC0D-D4F3C469706A}
{2D7F07BA-59E0-4B6D-8AB2-5AF9962AAD13} = {D4D520AA-4FE3-4F44-857B-B4AC0AF37E5A}
EndGlobalSection
EndGlobal
13 changes: 13 additions & 0 deletions autobahn/config/fuzzingclient.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"options": {"failByDrop": false},
"outdir": "./reports/servers",

"servers": [{"agent": "SimpleR", "url": "ws://host.docker.internal:9002"}],
"cases": ["*"],
"exclude-cases": [
"9.*",
"12.*",
"13.*"
],
"exclude-agent-cases": {}
}
3 changes: 3 additions & 0 deletions autobahn/fuzzingclient.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#! /bin/sh

docker run -it --rm -v "${PWD}/config:/config" -v "${PWD}/reports:/reports" -p 9002:9002 --name fuzzingclient crossbario/autobahn-testsuite wstest -m fuzzingclient -s /config/fuzzingclient.json
19 changes: 19 additions & 0 deletions autobahn/server/EchoDispatcher.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace SimpleR.Authobahn.Server;

public class EchoDispatcher : IWebSocketMessageDispatcher<byte[]>
{
public Task OnConnectedAsync(IWebsocketConnectionContext<byte[]> connection)
{
return Task.CompletedTask;
}

public Task OnDisconnectedAsync(IWebsocketConnectionContext<byte[]> connection, Exception? exception)
{
return Task.CompletedTask;
}

public async Task DispatchMessageAsync(IWebsocketConnectionContext<byte[]> connection, byte[] message)
{
await connection.WriteAsync(message);
}
}
17 changes: 17 additions & 0 deletions autobahn/server/EchoProtocol.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Buffers;
using SimpleR.Protocol;

namespace SimpleR.Authobahn.Server;

public class EchoProtocol : IDelimitedMessageProtocol<byte[]>
{
public void WriteMessage(byte[] message, IBufferWriter<byte> output)
{
output.Write(message);
}

public byte[] ParseMessage(ref ReadOnlySequence<byte> input)
{
return input.ToArray();
}
}
20 changes: 20 additions & 0 deletions autobahn/server/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using SimpleR.Authobahn.Server;
using SimpleR.Protocol;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddSimpleR();

var app = builder.Build();

app.UseRouting();

app.UseAuthorization();

app.MapSimpleR<byte[]>("/", b =>
{
b.UseEndOfMessageDelimitedProtocol(new EchoProtocol()).UseDispatcher<EchoDispatcher>();
});

app.Run();
38 changes: 38 additions & 0 deletions autobahn/server/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:62410",
"sslPort": 44332
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:9002",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:9003;http://localhost:9002",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
13 changes: 13 additions & 0 deletions autobahn/server/SimpleR.Authobahn.Server.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\SimpleR\SimpleR.csproj" />
</ItemGroup>

</Project>
8 changes: 8 additions & 0 deletions autobahn/server/appsettings.Development.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Trace",
"Microsoft.AspNetCore": "Trace"
}
}
}
9 changes: 9 additions & 0 deletions autobahn/server/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,27 +45,4 @@ await socket.SendAsync(new ArraySegment<byte>(new byte[] { 5, 0 }), WebSocketMes
client.Dispose();
}
}

[Fact]
public async Task SendSinglePartMessage_GetReversed()
{
// Arrange
var receivedQueue = new List<byte[]?>();
var (client, socket) = await _factory.Server.ConnectWebsocketAsync(_route);
try
{
using var sub = client.MessageReceived.Subscribe(message => { receivedQueue.Add(message.Binary); });

await socket.SendAsync(new ArraySegment<byte>(new byte[] { 1, 2, 3, 4, 5, 0 }), WebSocketMessageType.Binary,
false, CancellationToken.None);
await WaitHelpers.WaitFor(() => receivedQueue.Any());

receivedQueue.Should().HaveCount(1);
receivedQueue[0].Should().Equal(5, 4, 3, 2, 1);
}
finally
{
client.Dispose();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,30 @@ await socket.SendAsync(new ArraySegment<byte>(new byte[] { 1, 2, 3, 4, 5 }), Web
client.Dispose();
}
}

[Fact]
public async Task SendEmptyMessage_GetReversed()
{
// Arrange
var receivedQueue = new List<byte[]?>();
var (client, socket) = await _factory.Server.ConnectWebsocketAsync(_route);
try
{
using var sub = client.MessageReceived.Subscribe((message) => { receivedQueue.Add(message.Binary); });

await socket.SendAsync(new ArraySegment<byte>([], 0, 0), WebSocketMessageType.Binary,
true, CancellationToken.None);
await socket.SendAsync(new ArraySegment<byte>([], 0, 0), WebSocketMessageType.Binary,
true, CancellationToken.None);
await WaitHelpers.WaitFor(() => receivedQueue.Count == 2);

receivedQueue.Should().HaveCount(2);
receivedQueue[0].Should().Equal([]);
receivedQueue[1].Should().Equal([]);
}
finally
{
client.Dispose();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,4 @@ await socket.SendAsync(new ArraySegment<byte>(bytes), WebSocketMessageType.Text,
client.Dispose();
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,30 @@ await socket.SendAsync(new ArraySegment<byte>(bytes), WebSocketMessageType.Text,
client.Dispose();
}
}

[Fact]
public async Task SendEmptyMessage_GetBack()
{
// Arrange
var receivedQueue = new List<string?>();
var (client, socket) = await _factory.Server.ConnectWebsocketAsync(_route);
try
{
using var sub = client.MessageReceived.Subscribe((message) => { receivedQueue.Add(message.Text); });
await socket.SendAsync(new ArraySegment<byte>([], 0, 0), WebSocketMessageType.Text, true,
CancellationToken.None);
await socket.SendAsync(new ArraySegment<byte>([], 0, 0), WebSocketMessageType.Text, true,
CancellationToken.None);

await WaitHelpers.WaitFor(() => receivedQueue.Count == 2);

receivedQueue.Should().HaveCount(2);
receivedQueue[0].Should().Be("");
receivedQueue[1].Should().Be("");
}
finally
{
client.Dispose();
}
}
}
17 changes: 17 additions & 0 deletions test/SimpleR.Protocol.Tests/FrameBufferWriterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,23 @@ public FrameBufferWriterTests()
_frameWriter = new FrameBufferWriter(_bufferWriter);
}

[Fact]
public void EmptyAdvance_ShouldBeCorrect()
{
// Advance the writer by the number of bytes written
_frameWriter.Advance(0);

// Finish writing the last frame
_frameWriter.FinishLastFrame(true);

// Get the written bytes as an array
var result = _bufferWriter.WrittenMemory.ToArray();

// Assert that the result is as expected
result.Should()
.BeEquivalentTo(new byte[] { 0, 0, 0, 0, 1 });
}

[Fact]
public void WriteTwoFrames_UsingMemory_ShouldBeCorrect()
{
Expand Down