#1 - Implement Autobahn test client & server.

This commit is contained in:
Chris Ross 2014-10-22 10:39:28 -07:00
parent 86822d541c
commit ade78b1aba
9 changed files with 284 additions and 1 deletions

View File

@ -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
@ -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
@ -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
@ -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

View File

@ -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>

View File

@ -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);
}
}
}

View File

@ -0,0 +1,11 @@
{
"dependencies": {
"Microsoft.AspNet.WebSockets.Client": "1.0.0-*"
},
"commands": {
"run" : "run"
},
"frameworks" : {
"aspnet50" : { }
}
}

View File

@ -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.

View File

@ -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>

View File

@ -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" : { }
}
}

View File

@ -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": {}
}

View File

@ -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);
}
}
}