Skip to content

Commit

Permalink
#1 - Implement Autobahn test client & server.
Browse files Browse the repository at this point in the history
  • Loading branch information
Tratcher committed Oct 22, 2014
1 parent 86822d5 commit ade78b1
Show file tree
Hide file tree
Showing 9 changed files with 284 additions and 1 deletion.
16 changes: 15 additions & 1 deletion WebSockets.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.22013.1
VisualStudioVersion = 14.0.22216.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestServer", "test\TestServer\TestServer.csproj", "{4E5F5FCC-172C-44D9-BEA0-39098A79CD0B}"
EndProject
Expand All @@ -28,6 +28,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
global.json = global.json
EndProjectSection
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "AutobahnTestServer", "test\AutobahnTestServer\AutobahnTestServer.kproj", "{C03C43FE-9201-48A6-B434-AD67EF627D67}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "AutobahnTestClient", "test\AutobahnTestClient\AutobahnTestClient.kproj", "{BC4D2BB1-05A8-4816-8BC1-3A664F09EE32}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -62,6 +66,14 @@ Global
{78A097D0-C0A4-4AED-93E2-84A65392FB52}.Debug|Any CPU.Build.0 = Debug|Any CPU
{78A097D0-C0A4-4AED-93E2-84A65392FB52}.Release|Any CPU.ActiveCfg = Release|Any CPU
{78A097D0-C0A4-4AED-93E2-84A65392FB52}.Release|Any CPU.Build.0 = Release|Any CPU
{C03C43FE-9201-48A6-B434-AD67EF627D67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C03C43FE-9201-48A6-B434-AD67EF627D67}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C03C43FE-9201-48A6-B434-AD67EF627D67}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C03C43FE-9201-48A6-B434-AD67EF627D67}.Release|Any CPU.Build.0 = Release|Any CPU
{BC4D2BB1-05A8-4816-8BC1-3A664F09EE32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BC4D2BB1-05A8-4816-8BC1-3A664F09EE32}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BC4D2BB1-05A8-4816-8BC1-3A664F09EE32}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BC4D2BB1-05A8-4816-8BC1-3A664F09EE32}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -74,5 +86,7 @@ Global
{4A1C4875-AE21-4A78-979A-F0E4DF5EB518} = {2C7947A5-9FBD-4267-97C1-2D726D7B3BAF}
{6604D154-817F-4BC5-BE95-FF7E851179D9} = {C45106D0-76C8-4776-A140-F7DD83CA2958}
{78A097D0-C0A4-4AED-93E2-84A65392FB52} = {2C7947A5-9FBD-4267-97C1-2D726D7B3BAF}
{C03C43FE-9201-48A6-B434-AD67EF627D67} = {C45106D0-76C8-4776-A140-F7DD83CA2958}
{BC4D2BB1-05A8-4816-8BC1-3A664F09EE32} = {C45106D0-76C8-4776-A140-F7DD83CA2958}
EndGlobalSection
EndGlobal
20 changes: 20 additions & 0 deletions test/AutobahnTestClient/AutobahnTestClient.kproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>

<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>bc4d2bb1-05a8-4816-8bc1-3a664f09ee32</ProjectGuid>
<RootNamespace>AutobahnTestClient</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup>

<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>
102 changes: 102 additions & 0 deletions test/AutobahnTestClient/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNet.WebSockets.Client;

namespace AutobahnTestClient
{
public class Program
{
public async Task Main(string[] args)
{
try
{
string serverAddress = "ws://localhost:9001";
string agent =
"ManagedWebSockets";
// "NativeWebSockets";

Console.WriteLine("Getting case count.");
var caseCount = await GetCaseCountAsync(serverAddress, agent);
Console.WriteLine(caseCount + " case(s).");

for (int i = 1; i <= caseCount; i++)
{
await RunCaseAsync(serverAddress, i, agent);
}

await UpdateReportsAsync(serverAddress, agent);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}

Console.WriteLine("Done");
Console.ReadLine();
}

private async Task<WebSocket> ConnectAsync(string address, string agent)
{
if (string.Equals(agent, "NativeWebSockets"))
{
var client = new ClientWebSocket();
await client.ConnectAsync(new Uri(address), CancellationToken.None);
return client;
}
else
{
// TODO: BUG: Require ws or wss schemes
var client = new WebSocketClient();
return await client.ConnectAsync(new Uri(address), CancellationToken.None);
}
}

private async Task<int> GetCaseCountAsync(string serverAddress, string agent)
{
var webSocket = await ConnectAsync(serverAddress + "/getCaseCount", agent);
byte[] buffer = new byte[1024 * 4];
var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
var caseCountText = Encoding.UTF8.GetString(buffer, 0, result.Count);
return int.Parse(caseCountText);
}

private async Task RunCaseAsync(string serverAddress, int caseId, string agent)
{
try
{
Console.WriteLine("Running case " + caseId);
var webSocket = await ConnectAsync(serverAddress + "/runCase?case=" + caseId + "&agent=" + agent, agent);
await Echo(webSocket);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}

private async Task Echo(WebSocket webSocket)
{
byte[] buffer = new byte[1024 * 4];
var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
while (!result.CloseStatus.HasValue)
{
await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, CancellationToken.None);
result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
}
await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
}

private async Task UpdateReportsAsync(string serverAddress, string agent)
{
var webSocket = await ConnectAsync(serverAddress + "/updateReports?agent=" + agent, agent);
await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
}
}
}
11 changes: 11 additions & 0 deletions test/AutobahnTestClient/Project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"dependencies": {
"Microsoft.AspNet.WebSockets.Client": "1.0.0-*"
},
"commands": {
"run" : "run"
},
"frameworks" : {
"aspnet50" : { }
}
}
23 changes: 23 additions & 0 deletions test/AutobahnTestClient/ReadMe.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
This test server is for use in testing client side implementations of the WebSocekt protocol. It is currently implemented to test
Microsoft.AspNet.WebSockets.Client.WebSocketClient and System.Net.WebSockets.ClientWebSocket.

See http://autobahn.ws/ to download and install the test framework.

Usage:
Run the test server:
"C:\Program Files\Python\2.7.6\Scripts\wstest" -d -m fuzzingserver -s fuzzingserver.json
Where fuzzingserver.json contains the following:

{
"url": "ws://127.0.0.1:9001",

"options": {"failByDrop": false},
"outdir": "./reports/clients",
"webport": 8080,

"cases": ["*"],
"exclude-cases": [],
"exclude-agent-cases": {}
}

Then run the client of your choice, taking care to update the serverAddress and agent fields in the client code.
19 changes: 19 additions & 0 deletions test/AutobahnTestServer/AutobahnTestServer.kproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>c03c43fe-9201-48a6-b434-ad67ef627d67</ProjectGuid>
<RootNamespace>AutobahnTestServer</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
<DevelopmentServerPort>60351</DevelopmentServerPort>
</PropertyGroup>
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>
14 changes: 14 additions & 0 deletions test/AutobahnTestServer/Project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"webroot": "wwwroot",
"exclude": "wwwroot/**/*",
"dependencies": {
"Microsoft.AspNet.Server.IIS": "1.0.0-beta1-*",
"Microsoft.AspNet.Server.WebListener": "1.0.0-beta1-*",
"Microsoft.AspNet.WebSockets.Server": "1.0.0-beta1-*"
},
"commands": { "web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:12345" },
"frameworks" : {
"aspnet50" : { },
"aspnetcore50" : { }
}
}
25 changes: 25 additions & 0 deletions test/AutobahnTestServer/ReadMe.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
This test server is for use in testing server side implementations of the WebSocekt protocol. It should work with Helios, WebListener (native),
and the managed implementation of WebSockets in this project (running on WebListener, Kestrel, etc.). The tests only require that the server implement
a basic WebSocket accept and then echo any content received.

See http://autobahn.ws/ to download and install the test framework.

Usage:
Configure and start the server of your choice.
Run the test client:
"C:\Program Files\Python\2.7.6\Scripts\wstest.exe" -d -m fuzzingclient -s fuzzingclient.json
Where fussingclient.json contains:
{
"options": {"failByDrop": false},
"outdir": "./reports/servers",

"servers": [
{"agent": "NameOfImplementationBeingTested",
"url": "ws://localhost:12345",
"options": {"version": 18}}
],

"cases": ["*"],
"exclude-cases": [],
"exclude-agent-cases": {}
}
55 changes: 55 additions & 0 deletions test/AutobahnTestServer/Startup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.WebSockets.Server;

namespace AutobahnTestServer
{
public class Startup
{
public void Configure(IApplicationBuilder app)
{
// Comment this out to test native server implementations
app.UseWebSockets(new WebSocketOptions()
{
ReplaceFeature = true,
});

app.Use(async (context, next) =>
{
if (context.IsWebSocketRequest)
{
Console.WriteLine("Echo: " + context.Request.Path);
var webSocket = await context.AcceptWebSocketAsync();
await Echo(webSocket);
return;
}
await next();
});

app.Run(context =>
{
Console.WriteLine("Hello World");
return context.Response.WriteAsync("Hello World");
});
}

private async Task Echo(WebSocket webSocket)
{
byte[] buffer = new byte[1024 * 4];
var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
while (!result.CloseStatus.HasValue)
{
await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, CancellationToken.None);
result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
}
await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
}
}
}

0 comments on commit ade78b1

Please sign in to comment.