[runtime] Fix test_op_il_seq_point in amd64.
[mono.git] / mcs / class / System / Test / System.Net.WebSockets / ClientWebSocketTest.cs
index e193a5f53072d43025d0810d6e144911c15b4773..7422a1f2695dc2e345220d5736974c5223a40a4e 100644 (file)
@@ -10,6 +10,7 @@ using System.Text;
 
 using NUnit.Framework;
 
+using MonoTests.Helpers;
 
 namespace MonoTests.System.Net.WebSockets
 {
@@ -17,7 +18,7 @@ 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;
@@ -47,9 +48,13 @@ namespace MonoTests.System.Net.WebSockets
                }
 
                [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) {
@@ -60,12 +65,15 @@ namespace MonoTests.System.Net.WebSockets
                }
 
                [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) {
@@ -76,14 +84,17 @@ namespace MonoTests.System.Net.WebSockets
                }
 
                [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) {
@@ -94,6 +105,7 @@ namespace MonoTests.System.Net.WebSockets
                }
 
                [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";
@@ -118,6 +130,7 @@ namespace MonoTests.System.Net.WebSockets
                }
 
                [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));
@@ -134,6 +147,7 @@ namespace MonoTests.System.Net.WebSockets
                }
 
                [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));
@@ -150,6 +164,7 @@ namespace MonoTests.System.Net.WebSockets
                }
 
                [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));
@@ -163,6 +178,7 @@ namespace MonoTests.System.Net.WebSockets
                }
 
                [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));
@@ -170,6 +186,7 @@ namespace MonoTests.System.Net.WebSockets
                }
 
                [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 {
@@ -184,6 +201,7 @@ namespace MonoTests.System.Net.WebSockets
                }
 
                [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 {
@@ -198,6 +216,7 @@ namespace MonoTests.System.Net.WebSockets
                }
 
                [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 {
@@ -211,6 +230,45 @@ namespace MonoTests.System.Net.WebSockets
                        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 ();