public async Task ConnectionShouldCloseAndSignalDoneInCaseOfAProtocolError(bool isServer)
        {
            var inPipe   = new BufferedPipe(1024);
            var outPipe  = new BufferedPipe(1024);
            var http2Con = await ConnectionUtils.BuildEstablishedConnection(
                isServer, inPipe, outPipe, loggerProvider);

            // Cause a protocol error
            var fh = new FrameHeader
            {
                Type     = FrameType.Data,
                StreamId = 0u,
                Flags    = 0,
                Length   = 0,
            };
            await inPipe.WriteFrameHeader(fh);

            await outPipe.AssertGoAwayReception(ErrorCode.ProtocolError, 0u);

            await outPipe.AssertStreamEnd();

            await inPipe.CloseAsync();

            // Expect the connection to close within timeout
            var closed = http2Con.Done;

            Assert.True(
                closed == await Task.WhenAny(closed, Task.Delay(1000)),
                "Expected connection to close");
        }
        public async Task ConnectionShouldCloseAndSignalDoneWhenReadingFromInputFails(bool isServer)
        {
            var inPipe         = new BufferedPipe(1024);
            var outPipe        = new BufferedPipe(1024);
            var failableInPipe = new FailingPipe(inPipe);
            var http2Con       = await ConnectionUtils.BuildEstablishedConnection(
                isServer, failableInPipe, outPipe, loggerProvider);

            // Make the next write attempt fail
            failableInPipe.FailNextRead = true;
            // Send something which triggers no response but will start a new read call
            await inPipe.WriteWindowUpdate(0, 128);

            // Wait for the connection to close the outgoing part
            await outPipe.AssertStreamEnd();

            // If the connection was successfully closed close the incoming data
            // stream, since this is expected from a bidirectional stream implementation
            await inPipe.CloseAsync();

            // Expect the connection to close within timeout
            var closed = http2Con.Done;

            Assert.True(
                closed == await Task.WhenAny(closed, Task.Delay(1000)),
                "Expected connection to close");
        }
        public async Task ConnectionShouldCloseAndStreamsShouldGetResetWhenExternalCloseIsRequested()
        {
            // TODO: Add a variant of this test for clients as soon as they are supported
            var inPipe  = new BufferedPipe(1024);
            var outPipe = new BufferedPipe(1024);

            var res = await ServerStreamTests.StreamCreator.CreateConnectionAndStream(
                StreamState.Open, loggerProvider, inPipe, outPipe);

            // Close the connection
            var closeTask = res.conn.CloseNow();
            // Expect end of stream
            await outPipe.AssertStreamEnd();

            // If the connection was successfully closed close the incoming data
            // stream, since this is expected from a bidirectional stream implementation
            await inPipe.CloseAsync();

            // Close should now be completed
            await closeTask;

            // The stream should be reset
            Assert.Equal(StreamState.Reset, res.stream.State);
            // Which also means that further writes/reads should fail
            await Assert.ThrowsAsync <StreamResetException>(async() =>
            {
                await res.stream.WriteHeadersAsync(
                    TestHeaders.DefaultStatusHeaders, true);
            });

            await Assert.ThrowsAsync <StreamResetException>(async() =>
            {
                await res.stream.ReadAllToArray();
            });
        }
Exemplo n.º 4
0
        public async Task PingShouldFailWhenConnectionIsClosedAfterPingStart()
        {
            var inPipe   = new BufferedPipe(1024);
            var outPipe  = new BufferedPipe(1024);
            var http2Con = await ConnectionUtils.BuildEstablishedConnection(
                true, inPipe, outPipe, loggerProvider);

            // Request ping
            var pingTask = http2Con.PingAsync();
            // Expect ping emission
            var fh = await outPipe.ReadFrameHeaderWithTimeout();

            Assert.Equal(FrameType.Ping, fh.Type);
            Assert.Equal(8, fh.Length);
            Assert.Equal(0, fh.Flags);
            Assert.Equal(0u, fh.StreamId);
            var pingData = new ArraySegment <byte>(new byte[8]);
            await outPipe.ReadAllWithTimeout(pingData);

            // Close the connection
            await inPipe.CloseAsync();

            await outPipe.AssertStreamEnd();

            // Await ping to finish with exception
            var timeoutTask = Task.Delay(200);

            Assert.True(
                pingTask == await Task.WhenAny(pingTask, timeoutTask),
                "Expected pingTask to finish");
            await Assert.ThrowsAsync <ConnectionClosedException>(
                async() => await pingTask);
        }
        public async Task ConnectionShouldCloseAndSignalDoneWhenWritingToOutputFails(bool isServer)
        {
            var inPipe          = new BufferedPipe(1024);
            var outPipe         = new BufferedPipe(1024);
            var failableOutPipe = new FailingPipe(outPipe);
            var http2Con        = await ConnectionUtils.BuildEstablishedConnection(
                isServer, inPipe, failableOutPipe, loggerProvider);

            // Make the next write attempt fail
            failableOutPipe.FailNextWrite = true;
            // Send something which triggers a response
            await inPipe.WritePing(new byte[8], false);

            // Wait for the connection to close the outgoing part
            await outPipe.AssertStreamEnd();

            Assert.True(failableOutPipe.CloseCalled);
            // If the connection was successfully closed close the incoming data
            // stream, since this is expected from a bidirectional stream implementation
            await inPipe.CloseAsync();

            // Expect the connection to close within timeout
            var closed = http2Con.Done;

            Assert.True(
                closed == await Task.WhenAny(closed, Task.Delay(1000)),
                "Expected connection to close");
        }
Exemplo n.º 6
0
        public async Task CloseShouldUnblockReads()
        {
            var p      = new BufferedPipe(128);
            var input  = new byte[70];
            var output = new byte[50];

            for (var i = 0; i < 70; i++)
            {
                input[i] = (byte)i;
            }
            // Start read first
            var task = p.ReadAsync(new ArraySegment <byte>(output)).AsTask();
            // Schedule close
            var writeTask = Task.Run(async() =>
            {
                await Task.Delay(10);
                await p.CloseAsync();
            });
            // And wait for read to unblock
            var res = await task;

            Assert.Equal(true, res.EndOfStream);
            Assert.Equal(0, res.BytesRead);
            // The writeTask should also finish
            await writeTask;
        }
Exemplo n.º 7
0
        public async Task WritingOnOneEndShallYieldInDataOnTheOtherEnd()
        {
            var p      = new BufferedPipe(128);
            var input  = new byte[70];
            var output = new byte[50];

            for (var i = 0; i < 70; i++)
            {
                input[i] = (byte)i;
            }

            await p.WriteAsync(new ArraySegment <byte>(input));

            var res = await p.ReadAsync(new ArraySegment <byte>(output));

            Assert.Equal(false, res.EndOfStream);
            Assert.Equal(50, res.BytesRead);
            for (var i = 0; i < 50; i++)
            {
                Assert.Equal(i, output[i]);
            }

            await p.CloseAsync();

            res = await p.ReadAsync(new ArraySegment <byte>(output));

            Assert.Equal(false, res.EndOfStream);
            Assert.Equal(20, res.BytesRead);
            for (var i = 0; i < 20; i++)
            {
                Assert.Equal(50 + i, output[i]);
            }

            await p.CloseAsync();

            res = await p.ReadAsync(new ArraySegment <byte>(output));

            Assert.Equal(true, res.EndOfStream);
            Assert.Equal(0, res.BytesRead);
        }
Exemplo n.º 8
0
        public async Task ShouldErrorIfStreamWasClosedWithinTimeout()
        {
            var timeout = 200;
            var pipe    = new BufferedPipe(50);
            var _       = Task.Run(async() =>
            {
                await Task.Delay(10);
                await pipe.CloseAsync();
            });
            var ex = await Assert.ThrowsAsync <AggregateException>(
                () => ClientPreface.ReadAsync(pipe, timeout).AsTask());

            Assert.IsType <EndOfStreamException>(ex.InnerException);
        }
        public async Task ConnectionShouldSignalDoneWhenInputIsClosed(bool isServer)
        {
            var inPipe   = new BufferedPipe(1024);
            var outPipe  = new BufferedPipe(1024);
            var http2Con = await ConnectionUtils.BuildEstablishedConnection(
                isServer, inPipe, outPipe, loggerProvider);

            await inPipe.CloseAsync();

            // Expect the connection to close within timeout
            var closed = http2Con.Done;

            Assert.True(
                closed == await Task.WhenAny(closed, Task.Delay(1000)),
                "Expected connection to close");
        }
Exemplo n.º 10
0
        public async Task RemoteGoAwayReasonTaskShouldYieldExceptionIfNoGoAwayIsSent()
        {
            var inPipe  = new BufferedPipe(1024);
            var outPipe = new BufferedPipe(1024);

            var res = await ServerStreamTests.StreamCreator.CreateConnectionAndStream(
                StreamState.Open, loggerProvider, inPipe, outPipe);

            var readGoAwayTask = res.conn.RemoteGoAwayReason;
            await inPipe.CloseAsync();

            Assert.True(
                readGoAwayTask == await Task.WhenAny(readGoAwayTask, Task.Delay(200)),
                "Expected readGoAwayTask to finish");
            await Assert.ThrowsAsync <EndOfStreamException>(
                async() => await readGoAwayTask);
        }
Exemplo n.º 11
0
        public async Task PingShouldFailWhenConnectionIsClosedBeforePingStart()
        {
            var inPipe   = new BufferedPipe(1024);
            var outPipe  = new BufferedPipe(1024);
            var http2Con = await ConnectionUtils.BuildEstablishedConnection(
                true, inPipe, outPipe, loggerProvider);

            // Close the connection
            await inPipe.CloseAsync();

            await outPipe.AssertStreamEnd();

            // Request ping
            var pingTask = http2Con.PingAsync();
            // Await ping to finish with exception
            var timeoutTask = Task.Delay(200);

            Assert.True(
                pingTask == await Task.WhenAny(pingTask, timeoutTask),
                "Expected pingTask to finish");
            await Assert.ThrowsAsync <ConnectionClosedException>(
                async() => await pingTask);
        }
Exemplo n.º 12
0
        public async Task CloseShouldAllowRemainingDataToBeReadBeforeSignalClose()
        {
            var p      = new BufferedPipe(128);
            var input  = new byte[20];
            var output = new byte[10];

            for (var i = 0; i < 20; i++)
            {
                input[i] = (byte)i;
            }
            await p.WriteAsync(new ArraySegment <byte>(input));

            await p.CloseAsync();

            var res = await p.ReadAsync(new ArraySegment <byte>(output));

            Assert.Equal(false, res.EndOfStream);
            Assert.Equal(10, res.BytesRead);
            for (var i = 0; i < 10; i++)
            {
                Assert.Equal(i, output[i]);
            }

            res = await p.ReadAsync(new ArraySegment <byte>(output));

            Assert.Equal(false, res.EndOfStream);
            Assert.Equal(10, res.BytesRead);
            for (var i = 0; i < 10; i++)
            {
                Assert.Equal(i + 10, output[i]);
            }

            res = await p.ReadAsync(new ArraySegment <byte>(output));

            Assert.Equal(true, res.EndOfStream);
            Assert.Equal(0, res.BytesRead);
        }
Exemplo n.º 13
0
        public async Task GoAwayShouldBeSendable(bool withConnectionClose)
        {
            var inPipe  = new BufferedPipe(1024);
            var outPipe = new BufferedPipe(1024);

            var res = await ServerStreamTests.StreamCreator.CreateConnectionAndStream(
                StreamState.Open, loggerProvider, inPipe, outPipe);

            // Start the GoAway process in a background task.
            // As waiting for this will block the current task in case
            // of connection close
            var closeTask = Task.Run(() =>
                                     res.conn.GoAwayAsync(ErrorCode.InternalError, withConnectionClose));
            // Expect the GoAway message
            await outPipe.AssertGoAwayReception(ErrorCode.InternalError, 1u);

            if (withConnectionClose)
            {
                await outPipe.AssertStreamEnd();

                await inPipe.CloseAsync();
            }
            await closeTask;
        }