public EchoHandler(bool autoRead, byte[] expected, ITestOutputHelper output) { this.autoRead = autoRead; this.expected = expected; this.output = output; this.completion = new DefaultPromise(); }
public void TaskSchedulerIsPreserved() { var executor = new DefaultEventExecutor(); // SingleThreadEventExecutor("test", TimeSpan.FromSeconds(5)); IEnumerable <Task <int> > tasks = Enumerable.Range(1, 1).Select(async i => { //Clear SynchronizationContext set by xunit SynchronizationContext.SetSynchronizationContext(null); var completion = new DefaultPromise(); executor.Execute(async() => { try { Assert.True(executor.InEventLoop); await Task.Delay(1); Assert.True(executor.InEventLoop); completion.TryComplete(); // all is well } catch (Exception ex) { completion.TrySetException(ex); } }); await completion.Task; Assert.False(executor.InEventLoop); return(i); }); Task.WhenAll(tasks).Wait(TimeSpan.FromSeconds(500)); executor.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5)).GetAwaiter().GetResult(); }
public IPromise Unvoid() { var promise = new DefaultPromise(); if (_fireException) { _ = promise.Task.ContinueWith(FireExceptionOnFailureAction, _channel, TaskContinuationOptions.ExecuteSynchronously); } return(promise); }
public void TestReuseFd(ServerBootstrap sb, Bootstrap cb) { sb.ChildOption(ChannelOption.AutoRead, true); cb.Option(ChannelOption.AutoRead, true); // Use a number which will typically not exceed /proc/sys/net/core/somaxconn (which is 128 on linux by default // often). int numChannels = 100; AtomicReference <Exception> globalException = new AtomicReference <Exception>(); AtomicInteger serverRemaining = new AtomicInteger(numChannels); AtomicInteger clientRemaining = new AtomicInteger(numChannels); IPromise serverDonePromise = new DefaultPromise(); IPromise clientDonePromise = new DefaultPromise(); sb.ChildHandler(new ActionChannelInitializer <IChannel>(sch => { ReuseFdHandler sh = new ReuseFdHandler( false, globalException, serverRemaining, serverDonePromise); sch.Pipeline.AddLast("handler", sh); })); cb.Handler(new ActionChannelInitializer <IChannel>(sch => { ReuseFdHandler ch = new ReuseFdHandler( true, globalException, clientRemaining, clientDonePromise); sch.Pipeline.AddLast("handler", ch); })); IChannel sc = sb.BindAsync().GetAwaiter().GetResult(); for (int i = 0; i < numChannels; i++) { cb.ConnectAsync(sc.LocalAddress).ContinueWith(t => { if (!t.IsSuccess()) { clientDonePromise.TrySetException(t.Exception); } }); } clientDonePromise.Task.GetAwaiter().GetResult(); serverDonePromise.Task.GetAwaiter().GetResult(); sc.CloseAsync().GetAwaiter().GetResult(); if (globalException.Value is object) { throw globalException.Value; } }
public override Task ConnectAsync(EndPoint remoteAddress, EndPoint localAddress) { var promise = new DefaultPromise(); if (Volatile.Read(ref _channel.v_state) == State.Connected) { var cause = new AlreadyConnectedException(); Util.SafeSetFailure(promise, cause, Logger); _ = _channel.Pipeline.FireExceptionCaught(cause); return(promise.Task); } if (Volatile.Read(ref _channel.v_connectPromise) is object) { return(ThrowHelper.FromConnectionPendingException()); } _ = Interlocked.Exchange(ref _channel.v_connectPromise, promise); if (Volatile.Read(ref _channel.v_state) != State.Bound) { // Not bound yet and no localAddress specified - get one. if (localAddress is null) { localAddress = new LocalAddress(_channel); } } if (localAddress is object) { try { _channel.DoBind(localAddress); } catch (Exception ex) { Util.SafeSetFailure(promise, ex, Logger); _ = _channel.CloseAsync(); return(promise.Task); } } IChannel boundChannel = LocalChannelRegistry.Get(remoteAddress); if (!(boundChannel is LocalServerChannel serverChannel)) { Exception cause = new ConnectException($"connection refused: {remoteAddress}", null); Util.SafeSetFailure(promise, cause, Logger); _ = _channel.CloseAsync(); return(promise.Task); } _ = Interlocked.Exchange(ref _channel.v_peer, serverChannel.Serve(_channel)); return(promise.Task); }
public async Task ScheduledTaskFiresOnTime(bool scheduleFromExecutor) { var scheduler = new DefaultEventExecutor(); // SingleThreadEventExecutor(null, TimeSpan.FromMinutes(1)) var promise = new DefaultPromise(); Func <Task> scheduleFunc = () => scheduler.ScheduleAsync(() => promise.Complete(), TimeSpan.FromMilliseconds(100)); Task task = scheduleFromExecutor ? await scheduler.SubmitAsync(scheduleFunc) : scheduleFunc(); await Task.WhenAny(task, Task.Delay(TimeSpan.FromMilliseconds(300))); Assert.True(task.IsCompleted); }
[Fact]//(timeout = 5000) public async Task NewOutboundStream() { IHttp2FrameStream stream = _frameCodec.NewStream(); Assert.NotNull(stream); Assert.False(Http2CodecUtil.IsStreamIdValid(stream.Id)); var listenerExecuted = new DefaultPromise(); await _channel.WriteAndFlushAsync(new DefaultHttp2HeadersFrame(new DefaultHttp2Headers(), false) { Stream = stream }); Assert.True(Http2CodecUtil.IsStreamIdValid(stream.Id)); var data = Unpooled.Buffer().WriteZero(100); await _channel.WriteAndFlushAsync(new DefaultHttp2DataFrame(data) { Stream = stream }); }
public void WriteMultipleRstFramesForSameStream() { _handler = NewHandler(); _stream.SetupGet(x => x.Id).Returns(STREAM_ID); AtomicBoolean resetSent = new AtomicBoolean(); _stream.Setup(x => x.ResetSent()).Returns(() => { resetSent.Value = true; return(_stream.Object); }); _stream.SetupGet(x => x.IsResetSent).Returns(() => resetSent.Value); _frameWriter .Setup(x => x.WriteRstStreamAsync( It.Is <IChannelHandlerContext>(v => v == _ctx.Object), It.Is <int>(v => v == STREAM_ID), It.IsAny <Http2Error>(), It.IsAny <IPromise>())) .Returns <IChannelHandlerContext, int, Http2Error, IPromise>((ctx, id, err, p) => { p.TryComplete(); return(p.Task); }); var promise = new DefaultPromise(); var promise2 = new DefaultPromise(); promise.Task.ContinueWith(t => { _handler.ResetStreamAsync(_ctx.Object, STREAM_ID, Http2Error.StreamClosed, promise2); }, TaskContinuationOptions.ExecuteSynchronously); _handler.ResetStreamAsync(_ctx.Object, STREAM_ID, Http2Error.Cancel, promise); _frameWriter.Verify( x => x.WriteRstStreamAsync( It.Is <IChannelHandlerContext>(v => v == _ctx.Object), It.Is <int>(v => v == STREAM_ID), It.IsAny <Http2Error>(), It.IsAny <IPromise>())); Assert.True(promise.IsSuccess); Assert.True(promise2.IsSuccess); }
public async Task ScheduledTaskFiresOnTimeWhileBusy() { var scheduler = new DefaultEventExecutor(); var promise = new DefaultPromise(); Action selfQueueAction = null; selfQueueAction = () => { if (!promise.Task.IsCompleted) { scheduler.Execute(selfQueueAction); } }; scheduler.Execute(selfQueueAction); Task task = scheduler.ScheduleAsync(() => promise.Complete(), TimeSpan.FromMilliseconds(100)); await Task.WhenAny(task, Task.Delay(TimeSpan.FromSeconds(1))); Assert.True(task.IsCompleted); }
private static void TestDecrementAll(bool write) { EmbeddedChannel channel = new EmbeddedChannel(new ChannelOutboundHandlerAdapter0(), new ChannelHandlerAdapter()); AbstractCoalescingBufferQueue queue = new TestCoalescingBufferQueue(channel, 128); byte[] bytes = new byte[128]; var promise = new DefaultPromise(); promise.Task.ContinueWith(t => { queue.Add(Unpooled.WrappedBuffer(bytes)); Assert.Equal(bytes.Length, queue.ReadableBytes()); }, TaskContinuationOptions.ExecuteSynchronously); queue.Add(Unpooled.WrappedBuffer(bytes), promise); Assert.Equal(bytes.Length, queue.ReadableBytes()); IChannelHandlerContext ctx = channel.Pipeline.LastContext(); if (write) { queue.WriteAndRemoveAll(ctx); } else { queue.ReleaseAndFailAll(/*ctx, */ new ClosedChannelException()); } IByteBuffer buffer = queue.Remove(channel.Allocator, 128, channel.NewPromise()); Assert.False(buffer.IsReadable()); buffer.Release(); Assert.True(queue.IsEmpty()); Assert.Equal(0, queue.ReadableBytes()); Assert.False(channel.Finish()); }
private async Task TestGatheringWrite0( ServerBootstrap sb, Bootstrap cb, byte[] data, bool composite, bool autoRead) { sb.ChildOption(ChannelOption.AutoRead, autoRead); cb.Option(ChannelOption.AutoRead, autoRead); IPromise serverDonePromise = new DefaultPromise(); TestServerHandler sh = new TestServerHandler(autoRead, serverDonePromise, data.Length); TestHandler ch = new TestHandler(autoRead); cb.Handler(ch); sb.ChildHandler(sh); IChannel sc = await sb.BindAsync(); IChannel cc = await cb.ConnectAsync(sc.LocalAddress); for (int i = 0; i < data.Length;) { int length = Math.Min(s_random.Next(1024 * 8), data.Length - i); if (composite && i % 2 == 0) { int firstBufLength = length / 2; CompositeByteBuffer comp = Unpooled.CompositeBuffer(); comp.AddComponent(true, Unpooled.WrappedBuffer(data, i, firstBufLength)) .AddComponent(true, Unpooled.WrappedBuffer(data, i + firstBufLength, length - firstBufLength)); cc.WriteAsync(comp).Ignore(); } else { cc.WriteAsync(Unpooled.WrappedBuffer(data, i, length)).Ignore(); } i += length; } var cf = cc.WriteAndFlushAsync(Unpooled.Empty); Assert.NotEqual(cc.VoidPromise().Task, cf); try { Assert.True(cf.Wait(60000)); await cf; } catch (Exception) { throw; } await serverDonePromise.Task; await sh._channel.CloseAsync(); await ch._channel.CloseAsync(); await sc.CloseAsync(); if (sh._exception.Value != null && !(sh._exception.Value is SocketException || (sh._exception.Value is ChannelException chexc && chexc.InnerException is OperationException) || sh._exception.Value is OperationException)) { throw sh._exception.Value; } if (sh._exception.Value != null) { throw sh._exception.Value; } if (ch._exception.Value != null && !(ch._exception.Value is SocketException || (sh._exception.Value is ChannelException chexc1 && chexc1.InnerException is OperationException) || sh._exception.Value is OperationException)) { throw ch._exception.Value; } if (ch._exception.Value != null) { throw ch._exception.Value; } IByteBuffer expected = Unpooled.WrappedBuffer(data); Assert.Equal(expected, sh._received); expected.Release(); sh._received.Release(); }
public ClientHandler() { this.completion = new DefaultPromise(); }
public WriteHandler(int expectedBytesRead) { this.expectedBytesRead = expectedBytesRead; this.completion = new DefaultPromise(); }
public RunCounter(int expected) { this.expected = expected; this.completionSource = new DefaultPromise(); }
public void ServerCloseSocketInputProvidesData() { #if NETCOREAPP2_1 var runInAzureDevOps = false; // 本地测试 #else var runInAzureDevOps = true; #endif if (runInAzureDevOps) { // TODO Azure DevOps 有时测试无法通过 return; } var clientGroup = new MultithreadEventLoopGroup(1); var serverGroup = new MultithreadEventLoopGroup(1); try { var serverCompletion = new DefaultPromise(); var serverHandler = new ServerHandler(); ServerBootstrap sb = new ServerBootstrap() .Group(serverGroup) .Channel <TcpServerSocketChannel>() .ChildHandler( new ActionChannelInitializer <ISocketChannel>( ch => { // Don't use the HttpServerCodec, because we don't want to have content-length or anything added. ch.Pipeline.AddLast(new HttpRequestDecoder(4096, 8192, 8192, true)); ch.Pipeline.AddLast(new HttpObjectAggregator(4096)); ch.Pipeline.AddLast(serverHandler); serverCompletion.TryComplete(); })); var clientHandler = new ClientHandler(); Bootstrap cb = new Bootstrap() .Group(clientGroup) .Channel <TcpSocketChannel>() .Handler( new ActionChannelInitializer <ISocketChannel>( ch => { ch.Pipeline.AddLast(new HttpClientCodec(4096, 8192, 8192, true)); ch.Pipeline.AddLast(new HttpObjectAggregator(4096)); ch.Pipeline.AddLast(clientHandler); })); Task <IChannel> task = sb.BindAsync(IPAddress.Loopback, IPEndPoint.MinPort); task.Wait(TimeSpan.FromSeconds(5)); Assert.True(task.Status == TaskStatus.RanToCompletion); IChannel serverChannel = task.Result; int port = ((IPEndPoint)serverChannel.LocalAddress).Port; task = cb.ConnectAsync(IPAddress.Loopback, port); task.Wait(TimeSpan.FromSeconds(5)); Assert.True(task.Status == TaskStatus.RanToCompletion); IChannel clientChannel = task.Result; serverCompletion.Task.Wait(TimeSpan.FromSeconds(5)); clientChannel.WriteAndFlushAsync(new DefaultHttpRequest(HttpVersion.Http11, HttpMethod.Get, "/")).Wait(TimeSpan.FromSeconds(1)); Assert.True(serverHandler.WaitForCompletion()); Assert.True(clientHandler.WaitForCompletion()); } finally { try { Task.WaitAll( clientGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5)), serverGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5))); } catch { // Ignore RejectedExecutionException(on Azure DevOps) } } }
public async Task EchoServerAndClient() { var testPromise = new DefaultPromise(); var tlsCertificate = TestResourceHelper.GetTestCertificate(); Func <Task> closeServerFunc = await this.StartServerAsync(true, ch => { ch.Pipeline.AddLast("server logger", new LoggingHandler("SERVER")); ch.Pipeline.AddLast("server tls", TlsHandler.Server(tlsCertificate)); ch.Pipeline.AddLast("server logger2", new LoggingHandler("SER***")); ch.Pipeline.AddLast("server prepender", new LengthFieldPrepender2(2)); ch.Pipeline.AddLast("server decoder", new LengthFieldBasedFrameDecoder2(ushort.MaxValue, 0, 2, 0, 2)); ch.Pipeline.AddLast(new EchoChannelHandler()); }, testPromise); var group = new MultithreadEventLoopGroup(); var readListener = new ReadListeningHandler(DefaultTimeout); Bootstrap b = new Bootstrap() .Group(group) .Channel <TcpSocketChannel>() .Option(ChannelOption.TcpNodelay, true) .Handler(new ActionChannelInitializer <ISocketChannel>(ch => { string targetHost = tlsCertificate.GetNameInfo(X509NameType.DnsName, false); var clientTlsSettings = new ClientTlsSettings(targetHost); ch.Pipeline.AddLast("client logger", new LoggingHandler("CLIENT")); ch.Pipeline.AddLast("client tls", new TlsHandler(stream => new SslStream(stream, true, (sender, certificate, chain, errors) => true), clientTlsSettings)); ch.Pipeline.AddLast("client logger2", new LoggingHandler("CLI***")); ch.Pipeline.AddLast("client prepender", new LengthFieldPrepender2(2)); ch.Pipeline.AddLast("client decoder", new LengthFieldBasedFrameDecoder2(ushort.MaxValue, 0, 2, 0, 2)); ch.Pipeline.AddLast(readListener); })); this.Output.WriteLine("Configured Bootstrap: {0}", b); IChannel clientChannel = null; try { clientChannel = await b.ConnectAsync(IPAddress.Loopback, Port); this.Output.WriteLine("Connected channel: {0}", clientChannel); string[] messages = { "message 1", string.Join(",", Enumerable.Range(1, 300)) }; foreach (string message in messages) { await clientChannel.WriteAndFlushAsync(Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes(message))).WithTimeout(DefaultTimeout); var responseMessage = Assert.IsAssignableFrom <IByteBuffer>(await readListener.ReceiveAsync()); Assert.Equal(message, responseMessage.ToString(Encoding.UTF8)); } testPromise.TryComplete(); await testPromise.Task.WithTimeout(TimeSpan.FromMinutes(5)); } finally { Task serverCloseTask = closeServerFunc(); clientChannel?.CloseAsync().Wait(TimeSpan.FromSeconds(5)); group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5)).Wait(TimeSpan.FromSeconds(10)); if (!serverCloseTask.Wait(ShutdownTimeout)) { this.Output.WriteLine("Didn't stop in time."); } } }
public async Task MqttServerAndClient() { var testPromise = new DefaultPromise(); var tlsCertificate = TestResourceHelper.GetTestCertificate(); var serverReadListener = new ReadListeningHandler(); IChannel serverChannel = null; Func <Task> closeServerFunc = await this.StartServerAsync(true, ch => { serverChannel = ch; ch.Pipeline.AddLast("server logger", new LoggingHandler("SERVER")); ch.Pipeline.AddLast("server tls", TlsHandler.Server(tlsCertificate)); ch.Pipeline.AddLast("server logger2", new LoggingHandler("SER***")); ch.Pipeline.AddLast( MqttEncoder.Instance, new MqttDecoder(true, 256 * 1024), serverReadListener); }, testPromise); var group = new MultithreadEventLoopGroup(); var clientReadListener = new ReadListeningHandler(); Bootstrap b = new Bootstrap() .Group(group) .Channel <TcpSocketChannel>() .Option(ChannelOption.TcpNodelay, true) .Handler(new ActionChannelInitializer <ISocketChannel>(ch => { string targetHost = tlsCertificate.GetNameInfo(X509NameType.DnsName, false); var clientTlsSettings = new ClientTlsSettings(targetHost); ch.Pipeline.AddLast("client logger", new LoggingHandler("CLIENT")); ch.Pipeline.AddLast("client tls", new TlsHandler(stream => new SslStream(stream, true, (sender, certificate, chain, errors) => true), clientTlsSettings)); ch.Pipeline.AddLast("client logger2", new LoggingHandler("CLI***")); ch.Pipeline.AddLast( MqttEncoder.Instance, new MqttDecoder(false, 256 * 1024), clientReadListener); })); this.Output.WriteLine("Configured Bootstrap: {0}", b); IChannel clientChannel = null; try { clientChannel = await b.ConnectAsync(IPAddress.Loopback, Port); this.Output.WriteLine("Connected channel: {0}", clientChannel); await Task.WhenAll(this.RunMqttClientScenarioAsync(clientChannel, clientReadListener), this.RunMqttServerScenarioAsync(serverChannel, serverReadListener)) .WithTimeout(TimeSpan.FromMinutes(5)); testPromise.TryComplete(); await testPromise.Task; } finally { Task serverCloseTask = closeServerFunc(); clientChannel?.CloseAsync().Wait(TimeSpan.FromSeconds(5)); group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5)).Wait(TimeSpan.FromSeconds(10)); if (!serverCloseTask.Wait(ShutdownTimeout)) { this.Output.WriteLine("Didn't stop in time."); } } }
public ExceptionHandler() { this.completionSource = new DefaultPromise(); }
public ServerInitializer() { this.completion = new DefaultPromise(); }
/// <summary> /// Starts Echo server. /// </summary> /// <returns>function to trigger closure of the server.</returns> async Task <Func <Task> > StartServerAsync(bool tcpNoDelay, Action <IChannel> childHandlerSetupAction, DefaultPromise testPromise) { var bossGroup = new MultithreadEventLoopGroup(1); var workerGroup = new MultithreadEventLoopGroup(); bool started = false; try { ServerBootstrap b = new ServerBootstrap() .Group(bossGroup, workerGroup) .Channel <TcpServerSocketChannel>() .Handler(new ExceptionCatchHandler(ex => testPromise.TrySetException(ex))) .ChildHandler(new ActionChannelInitializer <ISocketChannel>(childHandlerSetupAction)) .ChildOption(ChannelOption.TcpNodelay, tcpNoDelay); this.Output.WriteLine("Configured ServerBootstrap: {0}", b); IChannel serverChannel = await b.BindAsync(Port); this.Output.WriteLine("Bound server channel: {0}", serverChannel); started = true; return(async() => { try { await serverChannel.CloseAsync(); } finally { bossGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5)).Ignore(); workerGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5)).Ignore(); } }); } finally { if (!started) { bossGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5)).Ignore(); workerGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5)).Ignore(); } } }
public BufWriterHandler() { this.random = new Random(); this.completion = new DefaultPromise(); }
private static async Task TestStringEcho0(ServerBootstrap sb, Bootstrap cb, bool autoRead, ITestOutputHelper output) { sb.ChildOption(ChannelOption.AutoRead, autoRead); cb.Option(ChannelOption.AutoRead, autoRead); IPromise serverDonePromise = new DefaultPromise(); IPromise clientDonePromise = new DefaultPromise(); StringEchoHandler sh = new StringEchoHandler(autoRead, serverDonePromise, output); StringEchoHandler ch = new StringEchoHandler(autoRead, clientDonePromise, output); sb.ChildHandler(new ActionChannelInitializer <IChannel>(sch => { sch.Pipeline.AddLast("framer", new DelimiterBasedFrameDecoder(512, Delimiters.LineDelimiter())); sch.Pipeline.AddLast("decoder", new StringDecoder(Encoding.ASCII)); sch.Pipeline.AddBefore("decoder", "encoder", new StringEncoder(Encoding.ASCII)); sch.Pipeline.AddAfter("decoder", "handler", sh); })); cb.Handler(new ActionChannelInitializer <IChannel>(sch => { sch.Pipeline.AddLast("framer", new DelimiterBasedFrameDecoder(512, Delimiters.LineDelimiter())); sch.Pipeline.AddLast("decoder", new StringDecoder(Encoding.ASCII)); sch.Pipeline.AddBefore("decoder", "encoder", new StringEncoder(Encoding.ASCII)); sch.Pipeline.AddAfter("decoder", "handler", ch); })); IChannel sc = await sb.BindAsync(); IChannel cc = await cb.ConnectAsync(sc.LocalAddress); for (int i = 0; i < s_data.Length; i++) { string element = s_data[i]; string delimiter = s_random.Next(0, 1) == 1 ? "\r\n" : "\n"; await cc.WriteAndFlushAsync(element + delimiter); } await ch._donePromise.Task; await sh._donePromise.Task; await sh._channel.CloseAsync(); await ch._channel.CloseAsync(); await sc.CloseAsync(); if (sh._exception.Value != null && !(sh._exception.Value is SocketException || (sh._exception.Value is ChannelException chexc && chexc.InnerException is OperationException) || sh._exception.Value is OperationException)) { throw sh._exception.Value; } if (ch._exception.Value != null && !(ch._exception.Value is SocketException || (sh._exception.Value is ChannelException chexc1 && chexc1.InnerException is OperationException) || sh._exception.Value is OperationException)) { throw ch._exception.Value; } if (sh._exception.Value != null) { throw sh._exception.Value; } if (ch._exception.Value != null) { throw ch._exception.Value; } }
private async Task TestCancelWrite0(ServerBootstrap sb, Bootstrap cb) { TestHandler sh = new TestHandler(); TestHandler ch = new TestHandler(); IByteBuffer a = Unpooled.Buffer().WriteByte('a'); IByteBuffer b = Unpooled.Buffer().WriteByte('b'); IByteBuffer c = Unpooled.Buffer().WriteByte('c'); IByteBuffer d = Unpooled.Buffer().WriteByte('d'); IByteBuffer e = Unpooled.Buffer().WriteByte('e'); cb.Handler(ch); sb.ChildHandler(sh); IChannel sc = await sb.BindAsync(); IChannel cc = await cb.ConnectAsync(sc.LocalAddress); var promise = new DefaultPromise(); Assert.True(promise.TrySetCanceled()); var f = cc.WriteAsync(a, promise); await cc.WriteAndFlushAsync(b); cc.WriteAsync(c).Ignore(); promise = new DefaultPromise(); Assert.True(promise.TrySetCanceled()); var f2 = cc.WriteAsync(d, promise); await cc.WriteAndFlushAsync(e); while (sh._counter < 3) { if (sh._exception.Value != null) { break; } if (ch._exception.Value != null) { break; } Thread.Sleep(50); } await sh._channel.CloseAsync(); await ch._channel.CloseAsync(); await sc.CloseAsync(); Task.WaitAll( sb.Group().ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5)), sb.ChildGroup().ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5)), cb.Group().ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5))); if (sh._exception.Value != null && !(sh._exception.Value is SocketException || (sh._exception.Value is ChannelException chexc && chexc.InnerException is OperationException) || sh._exception.Value is OperationException)) { throw sh._exception.Value; } if (sh._exception.Value != null) { throw sh._exception.Value; } if (ch._exception.Value != null && !(ch._exception.Value is SocketException || (sh._exception.Value is ChannelException chexc1 && chexc1.InnerException is OperationException) || sh._exception.Value is OperationException)) { throw ch._exception.Value; } if (ch._exception.Value != null) { throw ch._exception.Value; } Assert.Equal(0, ch._counter); Assert.True(Unpooled.WrappedBuffer(new byte[] { (byte)'b', (byte)'c', (byte)'e' }).Equals(sh._received)); }