From 8435c0ce1f052771dbdf59483ea59d2469ecf9b7 Mon Sep 17 00:00:00 2001 From: Josef Grieb Date: Mon, 24 Aug 2020 12:11:35 +0200 Subject: [PATCH] Reproduce error: it hangs itself up in echo test Motiviation: after each pass all channel sockets are closed, after the allocator is changed(4. iteration) the server socket BeginRead wont be called after server socket creation, however, both allocators work in netty example Modification: increased the timeout, other tests were commented out Result: testsuite changes will be undone later --- .../transport/AbstractComboTestsuiteTest.java | 10 +- .../transport/socket/SocketEchoTest.java | 108 ++++++------- .../channel/uring/IOUringSocketEchoTest.java | 31 ++++ .../uring/IOUringSocketTestPermutation.java | 151 ++++++++++++++++++ 4 files changed, 243 insertions(+), 57 deletions(-) create mode 100644 transport-native-io_uring/src/test/java/io/netty/channel/uring/IOUringSocketEchoTest.java create mode 100644 transport-native-io_uring/src/test/java/io/netty/channel/uring/IOUringSocketTestPermutation.java diff --git a/testsuite/src/main/java/io/netty/testsuite/transport/AbstractComboTestsuiteTest.java b/testsuite/src/main/java/io/netty/testsuite/transport/AbstractComboTestsuiteTest.java index 938c6388f7..e342b49b60 100644 --- a/testsuite/src/main/java/io/netty/testsuite/transport/AbstractComboTestsuiteTest.java +++ b/testsuite/src/main/java/io/netty/testsuite/transport/AbstractComboTestsuiteTest.java @@ -52,15 +52,18 @@ public abstract class AbstractComboTestsuiteTest> combos = newFactories(); - for (ByteBufAllocator allocator: newAllocators()) { + int counter = 0; + for (ByteBufAllocator allocator : newAllocators()) { int i = 0; - for (TestsuitePermutation.BootstrapComboFactory e: combos) { + logger.info("Allocator Counter: {}", counter); + for (TestsuitePermutation.BootstrapComboFactory e : combos) { + logger.info("combo counter: {}", i); sb = e.newServerInstance(); cb = e.newClientInstance(); configure(sb, cb, allocator); logger.info(String.format( "Running: %s %d of %d (%s + %s) with %s", - testName.getMethodName(), ++ i, combos.size(), sb, cb, StringUtil.simpleClassName(allocator))); + testName.getMethodName(), ++i, combos.size(), sb, cb, StringUtil.simpleClassName(allocator))); try { Method m = getClass().getMethod( TestUtils.testMethodName(testName), sbClazz, cbClazz); @@ -69,6 +72,7 @@ public abstract class AbstractComboTestsuiteTest> newFactories() { + return IOUringSocketTestPermutation.INSTANCE.socket(); + } +} diff --git a/transport-native-io_uring/src/test/java/io/netty/channel/uring/IOUringSocketTestPermutation.java b/transport-native-io_uring/src/test/java/io/netty/channel/uring/IOUringSocketTestPermutation.java new file mode 100644 index 0000000000..2a7e9a62b8 --- /dev/null +++ b/transport-native-io_uring/src/test/java/io/netty/channel/uring/IOUringSocketTestPermutation.java @@ -0,0 +1,151 @@ +/* + * Copyright 2020 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package io.netty.channel.uring; + +import io.netty.bootstrap.Bootstrap; +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.testsuite.transport.TestsuitePermutation; +import io.netty.testsuite.transport.TestsuitePermutation.BootstrapComboFactory; +import io.netty.testsuite.transport.TestsuitePermutation.BootstrapFactory; +import io.netty.testsuite.transport.socket.SocketTestPermutation; +import io.netty.util.concurrent.DefaultThreadFactory; +import io.netty.util.internal.logging.InternalLogger; +import io.netty.util.internal.logging.InternalLoggerFactory; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class IOUringSocketTestPermutation extends SocketTestPermutation { + + static final IOUringSocketTestPermutation INSTANCE = new IOUringSocketTestPermutation(); + + static final EventLoopGroup IO_URING_BOSS_GROUP = + new IOUringEventLoopGroup(BOSSES, new DefaultThreadFactory("testsuite-io_uring-boss", true)); + static final EventLoopGroup IO_URING_WORKER_GROUP = + new IOUringEventLoopGroup(WORKERS, new DefaultThreadFactory("testsuite-io_uring-worker", true)); + + private static final InternalLogger logger = InternalLoggerFactory.getInstance(IOUringSocketTestPermutation.class); + + @Override + public List> socket() { + + List> list = + combo(serverSocket(), clientSocket()); + + list.remove(list.size() - 1); // Exclude NIO x NIO test + + return list; + } + + @SuppressWarnings("unchecked") + @Override + public List> serverSocket() { + List> toReturn = new ArrayList>(); + toReturn.add(new BootstrapFactory() { + @Override + public ServerBootstrap newInstance() { + return new ServerBootstrap().group(IO_URING_BOSS_GROUP, IO_URING_WORKER_GROUP) + .channel(IOUringServerSocketChannel.class); + } + }); + if (isServerFastOpen()) { + toReturn.add(new BootstrapFactory() { + @Override + public ServerBootstrap newInstance() { + ServerBootstrap serverBootstrap = new ServerBootstrap().group(IO_URING_BOSS_GROUP, + IO_URING_WORKER_GROUP) + .channel(IOUringServerSocketChannel.class); + serverBootstrap.option(IOUringChannelOption.TCP_FASTOPEN, 5); + return serverBootstrap; + } + }); + } + toReturn.add(new BootstrapFactory() { + @Override + public ServerBootstrap newInstance() { + return new ServerBootstrap().group(nioBossGroup, nioWorkerGroup) + .channel(NioServerSocketChannel.class); + } + }); + + return toReturn; + } + + @SuppressWarnings("unchecked") + @Override + public List> clientSocket() { + return Arrays.asList( + new BootstrapFactory() { + @Override + public Bootstrap newInstance() { + return new Bootstrap().group(nioWorkerGroup).channel(NioSocketChannel.class); + //.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 100000); + } + }, + new BootstrapFactory() { + @Override + public Bootstrap newInstance() { + return new Bootstrap().group(nioWorkerGroup).channel(NioSocketChannel.class); + // .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 100000); + } + } + ); + } + + public boolean isServerFastOpen() { + return AccessController.doPrivileged(new PrivilegedAction() { + @Override + public Integer run() { + int fastopen = 0; + File file = new File("/proc/sys/net/ipv4/tcp_fastopen"); + if (file.exists()) { + BufferedReader in = null; + try { + in = new BufferedReader(new FileReader(file)); + fastopen = Integer.parseInt(in.readLine()); + if (logger.isDebugEnabled()) { + logger.debug("{}: {}", file, fastopen); + } + } catch (Exception e) { + logger.debug("Failed to get TCP_FASTOPEN from: {}", file, e); + } finally { + if (in != null) { + try { + in.close(); + } catch (Exception e) { + // Ignored. + } + } + } + } else { + if (logger.isDebugEnabled()) { + logger.debug("{}: {} (non-existent)", file, fastopen); + } + } + return fastopen; + } + }) == 3; + } +}