using NUnit.Framework;
+using MonoTests.Helpers;
namespace MonoTests.System.Net.WebSockets
{
public class ClientWebSocketTest
{
const string EchoServerUrl = "ws://echo.websocket.org";
- const int Port = 42123;
+ int Port = NetworkHelpers.FindFreePort ();
HttpListener listener;
ClientWebSocket socket;
MethodInfo headerSetMethod;
}
[Test]
+ [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
public void ServerHandshakeReturnCrapStatusCodeTest ()
{
+ // On purpose,
+ #pragma warning disable 4014
HandleHttpRequestAsync ((req, resp) => resp.StatusCode = 418);
+ #pragma warning restore 4014
try {
Assert.IsTrue (socket.ConnectAsync (new Uri ("ws://localhost:" + Port), CancellationToken.None).Wait (5000));
} catch (AggregateException e) {
}
[Test]
+ [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
public void ServerHandshakeReturnWrongUpgradeHeader ()
{
+ #pragma warning disable 4014
HandleHttpRequestAsync ((req, resp) => {
resp.StatusCode = 101;
resp.Headers["Upgrade"] = "gtfo";
});
+ #pragma warning restore 4014
try {
Assert.IsTrue (socket.ConnectAsync (new Uri ("ws://localhost:" + Port), CancellationToken.None).Wait (5000));
} catch (AggregateException e) {
}
[Test]
+ [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
public void ServerHandshakeReturnWrongConnectionHeader ()
{
+ #pragma warning disable 4014
HandleHttpRequestAsync ((req, resp) => {
resp.StatusCode = 101;
resp.Headers["Upgrade"] = "websocket";
// Mono http request doesn't like the forcing, test still valid since the default connection header value is empty
//ForceSetHeader (resp.Headers, "Connection", "Foo");
});
+ #pragma warning restore 4014
try {
Assert.IsTrue (socket.ConnectAsync (new Uri ("ws://localhost:" + Port), CancellationToken.None).Wait (5000));
} catch (AggregateException e) {
}
[Test]
+ [Category ("AndroidNotWorking")] // The test hangs when ran as part of the entire BCL test suite. Works when only this fixture is ran
public void EchoTest ()
{
const string Payload = "This is a websocket test";
}
[Test]
+ [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
public void CloseOutputAsyncTest ()
{
Assert.IsTrue (socket.ConnectAsync (new Uri (EchoServerUrl), CancellationToken.None).Wait (5000));
}
[Test]
+ [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
public void CloseAsyncTest ()
{
Assert.IsTrue (socket.ConnectAsync (new Uri (EchoServerUrl), CancellationToken.None).Wait (5000));
}
[Test, ExpectedException (typeof (ArgumentNullException))]
+ [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
public void SendAsyncArgTest_NoArray ()
{
Assert.IsTrue (socket.ConnectAsync (new Uri (EchoServerUrl), CancellationToken.None).Wait (5000));
}
[Test, ExpectedException (typeof (ArgumentNullException))]
+ [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
public void ReceiveAsyncArgTest_NoArray ()
{
Assert.IsTrue (socket.ConnectAsync (new Uri (EchoServerUrl), CancellationToken.None).Wait (5000));
}
[Test]
+ [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
public void ReceiveAsyncWrongState_Closed ()
{
try {
}
[Test]
+ [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
public void SendAsyncWrongState_Closed ()
{
try {
}
[Test]
+ [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
public void SendAsyncWrongState_CloseSent ()
{
try {
Assert.Fail ("Should have thrown");
}
+ [Test]
+ [Category ("NotWorking")] // FIXME: test relies on unimplemented HttpListenerContext.AcceptWebSocketAsync (), reenable it when the method is implemented
+ public void SendAsyncEndOfMessageTest ()
+ {
+ var cancellationToken = new CancellationTokenSource (TimeSpan.FromSeconds (30)).Token;
+ SendAsyncEndOfMessageTest (false, WebSocketMessageType.Text, cancellationToken).Wait (5000);
+ SendAsyncEndOfMessageTest (true, WebSocketMessageType.Text, cancellationToken).Wait (5000);
+ SendAsyncEndOfMessageTest (false, WebSocketMessageType.Binary, cancellationToken).Wait (5000);
+ SendAsyncEndOfMessageTest (true, WebSocketMessageType.Binary, cancellationToken).Wait (5000);
+ }
+
+ public async Task SendAsyncEndOfMessageTest (bool expectedEndOfMessage, WebSocketMessageType webSocketMessageType, CancellationToken cancellationToken)
+ {
+ using (var client = new ClientWebSocket ()) {
+ // Configure the listener.
+ var serverReceive = HandleHttpWebSocketRequestAsync<WebSocketReceiveResult> (async socket => await socket.ReceiveAsync (new ArraySegment<byte> (new byte[32]), cancellationToken), cancellationToken);
+
+ // Connect to the listener and make the request.
+ await client.ConnectAsync (new Uri ("ws://localhost:" + Port + "/"), cancellationToken);
+ await client.SendAsync (new ArraySegment<byte> (Encoding.UTF8.GetBytes ("test")), webSocketMessageType, expectedEndOfMessage, cancellationToken);
+
+ // Wait for the listener to handle the request and return its result.
+ var result = await serverReceive;
+
+ // Cleanup and check results.
+ await client.CloseAsync (WebSocketCloseStatus.NormalClosure, "Finished", cancellationToken);
+ Assert.AreEqual (expectedEndOfMessage, result.EndOfMessage, "EndOfMessage should be " + expectedEndOfMessage);
+ }
+ }
+
+ async Task<T> HandleHttpWebSocketRequestAsync<T> (Func<WebSocket, Task<T>> action, CancellationToken cancellationToken)
+ {
+ var ctx = await this.listener.GetContextAsync ();
+ var wsContext = await ctx.AcceptWebSocketAsync (null);
+ var result = await action (wsContext.WebSocket);
+ await wsContext.WebSocket.CloseOutputAsync (WebSocketCloseStatus.NormalClosure, "Finished", cancellationToken);
+ return result;
+ }
+
async Task HandleHttpRequestAsync (Action<HttpListenerRequest, HttpListenerResponse> handler)
{
var ctx = await listener.GetContextAsync ();