public async Task SendMoreThanStreamLimitRequests_Succeeds(int streamLimit)
        {
            using Http3LoopbackServer server = CreateHttp3LoopbackServer(new Http3Options()
            {
                MaxBidirectionalStreams = streamLimit
            });

            Task serverTask = Task.Run(async() =>
            {
                using Http3LoopbackConnection connection = (Http3LoopbackConnection) await server.EstablishGenericConnectionAsync();
                for (int i = 0; i < streamLimit + 1; ++i)
                {
                    using Http3LoopbackStream stream = await connection.AcceptRequestStreamAsync();
                    await stream.HandleRequestAsync();
                }
            });

            Task clientTask = Task.Run(async() =>
            {
                using HttpClient client = CreateHttpClient();

                for (int i = 0; i < streamLimit + 1; ++i)
                {
                    HttpRequestMessage request = new()
                    {
                        Method        = HttpMethod.Get,
                        RequestUri    = server.Address,
                        Version       = HttpVersion30,
                        VersionPolicy = HttpVersionPolicy.RequestVersionExact
                    };
                    using var response = await client.SendAsync(request).WaitAsync(TimeSpan.FromSeconds(10));
                }
            });

            await new[] { clientTask, serverTask }.WhenAllOrAnyFailed(20_000);
        }
        public async Task SendStreamLimitRequestsConcurrently_Succeeds(int streamLimit)
        {
            using Http3LoopbackServer server = CreateHttp3LoopbackServer(new Http3Options()
            {
                MaxBidirectionalStreams = streamLimit
            });

            Task serverTask = Task.Run(async() =>
            {
                using Http3LoopbackConnection connection = (Http3LoopbackConnection) await server.EstablishGenericConnectionAsync();
                for (int i = 0; i < streamLimit; ++i)
                {
                    using Http3LoopbackStream stream = await connection.AcceptRequestStreamAsync();
                    await stream.HandleRequestAsync();
                }
            });

            Task clientTask = Task.Run(async() =>
            {
                using HttpClient client = CreateHttpClient();

                var tasks = new Task <HttpResponseMessage> [streamLimit];
                Parallel.For(0, streamLimit, i =>
                {
                    HttpRequestMessage request = new()
                    {
                        Method        = HttpMethod.Get,
                        RequestUri    = server.Address,
                        Version       = HttpVersion30,
                        VersionPolicy = HttpVersionPolicy.RequestVersionExact
                    };

                    tasks[i] = client.SendAsync(request);
                });

                var responses = await Task.WhenAll(tasks);
                foreach (var response in responses)
                {
                    response.Dispose();
                }
            });
        [InlineData(10_000_000)] // 8 bytes settings value.
        public async Task ClientSettingsReceived_Success(int headerSizeLimit)
        {
            using Http3LoopbackServer server = CreateHttp3LoopbackServer();

            Task serverTask = Task.Run(async() =>
            {
                using Http3LoopbackConnection connection = (Http3LoopbackConnection) await server.EstablishGenericConnectionAsync();

                (Http3LoopbackStream settingsStream, Http3LoopbackStream requestStream) = await connection.AcceptControlAndRequestStreamAsync();

                using (settingsStream)
                    using (requestStream)
                    {
                        Assert.False(settingsStream.CanWrite, "Expected unidirectional control stream.");

                        long?streamType = await settingsStream.ReadIntegerAsync();
                        Assert.Equal(Http3LoopbackStream.ControlStream, streamType);

                        List <(long settingId, long settingValue)> settings = await settingsStream.ReadSettingsAsync();
                        (long settingId, long settingValue) = Assert.Single(settings);

                        Assert.Equal(Http3LoopbackStream.MaxHeaderListSize, settingId);
                        Assert.Equal(headerSizeLimit * 1024L, settingValue);

                        await requestStream.ReadRequestDataAsync();
                        await requestStream.SendResponseAsync();
                    }
            });

            Task clientTask = Task.Run(async() =>
            {
                using HttpClientHandler handler  = CreateHttpClientHandler();
                handler.MaxResponseHeadersLength = headerSizeLimit;

                using HttpClient client          = CreateHttpClient(handler);
                using HttpRequestMessage request = new()
                      {
                          Method        = HttpMethod.Get,
                          RequestUri    = server.Address,
                          Version       = HttpVersion30,
                          VersionPolicy = HttpVersionPolicy.RequestVersionExact
                      };
                using HttpResponseMessage response = await client.SendAsync(request);
            });

            await new[] { clientTask, serverTask }.WhenAllOrAnyFailed(20_000);
        }
        public async Task ReservedFrameType_Throws()
        {
            const int  ReservedHttp2PriorityFrameId = 0x2;
            const long UnexpectedFrameErrorCode     = 0x105;

            using Http3LoopbackServer server = CreateHttp3LoopbackServer();

            Task serverTask = Task.Run(async() =>
            {
                using Http3LoopbackConnection connection = (Http3LoopbackConnection) await server.EstablishGenericConnectionAsync();
                using Http3LoopbackStream stream         = await connection.AcceptRequestStreamAsync();

                await stream.SendFrameAsync(ReservedHttp2PriorityFrameId, new byte[8]);

                QuicConnectionAbortedException ex = await Assert.ThrowsAsync <QuicConnectionAbortedException>(async() =>
                {
                    await stream.HandleRequestAsync();
                    using Http3LoopbackStream stream2 = await connection.AcceptRequestStreamAsync();
                });

                Assert.Equal(UnexpectedFrameErrorCode, ex.ErrorCode);
            });

            Task clientTask = Task.Run(async() =>
            {
                using HttpClient client          = CreateHttpClient();
                using HttpRequestMessage request = new()
                      {
                          Method        = HttpMethod.Get,
                          RequestUri    = server.Address,
                          Version       = HttpVersion30,
                          VersionPolicy = HttpVersionPolicy.RequestVersionExact
                      };

                await Assert.ThrowsAsync <HttpRequestException>(async() => await client.SendAsync(request));
            });

            await new[] { clientTask, serverTask }.WhenAllOrAnyFailed(20_000);
        }