#1 - Implement Autobahn test client & server.
This commit is contained in:
parent
86822d541c
commit
ade78b1aba
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 14
|
# Visual Studio 14
|
||||||
VisualStudioVersion = 14.0.22013.1
|
VisualStudioVersion = 14.0.22216.0
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestServer", "test\TestServer\TestServer.csproj", "{4E5F5FCC-172C-44D9-BEA0-39098A79CD0B}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestServer", "test\TestServer\TestServer.csproj", "{4E5F5FCC-172C-44D9-BEA0-39098A79CD0B}"
|
||||||
EndProject
|
EndProject
|
||||||
|
|
@ -28,6 +28,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
||||||
global.json = global.json
|
global.json = global.json
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
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
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
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}.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.ActiveCfg = Release|Any CPU
|
||||||
{78A097D0-C0A4-4AED-93E2-84A65392FB52}.Release|Any CPU.Build.0 = 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
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
@ -74,5 +86,7 @@ Global
|
||||||
{4A1C4875-AE21-4A78-979A-F0E4DF5EB518} = {2C7947A5-9FBD-4267-97C1-2D726D7B3BAF}
|
{4A1C4875-AE21-4A78-979A-F0E4DF5EB518} = {2C7947A5-9FBD-4267-97C1-2D726D7B3BAF}
|
||||||
{6604D154-817F-4BC5-BE95-FF7E851179D9} = {C45106D0-76C8-4776-A140-F7DD83CA2958}
|
{6604D154-817F-4BC5-BE95-FF7E851179D9} = {C45106D0-76C8-4776-A140-F7DD83CA2958}
|
||||||
{78A097D0-C0A4-4AED-93E2-84A65392FB52} = {2C7947A5-9FBD-4267-97C1-2D726D7B3BAF}
|
{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
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.AspNet.WebSockets.Client": "1.0.0-*"
|
||||||
|
},
|
||||||
|
"commands": {
|
||||||
|
"run" : "run"
|
||||||
|
},
|
||||||
|
"frameworks" : {
|
||||||
|
"aspnet50" : { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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.
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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" : { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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": {}
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue