1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.testsuite.transport;
17
18 import io.netty.channel.Channel;
19 import io.netty.channel.DefaultEventLoopGroup;
20 import io.netty.channel.EventLoop;
21 import io.netty.channel.EventLoopGroup;
22 import io.netty.channel.MultithreadEventLoopGroup;
23 import io.netty.channel.ServerChannel;
24 import io.netty.channel.SingleThreadEventLoop;
25 import io.netty.channel.local.LocalChannel;
26 import io.netty.channel.local.LocalServerChannel;
27 import io.netty.util.concurrent.EventExecutorChooserFactory;
28 import io.netty.util.concurrent.RejectedExecutionHandlers;
29 import org.junit.jupiter.api.Test;
30 import org.junit.jupiter.api.Timeout;
31 import org.junit.jupiter.api.function.Executable;
32
33 import java.util.concurrent.Executor;
34 import java.util.concurrent.TimeUnit;
35
36 import static org.junit.jupiter.api.Assertions.assertThrows;
37
38 public class DefaultEventLoopTest extends AbstractSingleThreadEventLoopTest {
39
40 @Test
41 @Timeout(value = 3000, unit = TimeUnit.MILLISECONDS)
42 public void testChannelsIteratorNotSupported() throws Exception {
43 EventLoopGroup group = newEventLoopGroup();
44 final SingleThreadEventLoop loop = (SingleThreadEventLoop) group.next();
45 try {
46 final Channel ch = newChannel();
47 loop.register(ch).syncUninterruptibly();
48
49 assertThrows(UnsupportedOperationException.class, new Executable() {
50 @Override
51 public void execute() throws Throwable {
52 loop.registeredChannelsIterator();
53 }
54 });
55 } finally {
56 group.shutdownGracefully();
57 }
58 }
59
60 @Override
61 protected EventLoopGroup newEventLoopGroup() {
62 return new DefaultEventLoopGroup();
63 }
64
65 @Override
66 protected EventLoopGroup newAutoScalingEventLoopGroup() {
67 return new AutoScalingDefaultEventLoopGroup(SCALING_MAX_THREADS, AUTO_SCALING_CHOOSER_FACTORY);
68 }
69
70 @Override
71 protected Channel newChannel() {
72 return new LocalChannel();
73 }
74
75 @Override
76 protected Class<? extends ServerChannel> serverChannelClass() {
77 return LocalServerChannel.class;
78 }
79
80 private static final class SuspendableDefaultEventLoop extends SingleThreadEventLoop {
81 SuspendableDefaultEventLoop(EventLoopGroup parent, Executor executor) {
82 super(parent, executor, true, true, DEFAULT_MAX_PENDING_TASKS,
83 RejectedExecutionHandlers.reject());
84 }
85
86 @Override
87 protected void run() {
88 for (;;) {
89 Runnable task = takeTask();
90 if (task != null) {
91 runTask(task);
92 updateLastExecutionTime();
93 }
94
95
96
97 if (canSuspend()) {
98 break;
99 }
100
101 if (confirmShutdown()) {
102 break;
103 }
104 }
105 }
106 }
107
108 private static final class AutoScalingDefaultEventLoopGroup extends MultithreadEventLoopGroup {
109 AutoScalingDefaultEventLoopGroup(int nThreads, EventExecutorChooserFactory chooserFactory) {
110 super(nThreads, (Executor) null, chooserFactory);
111 }
112
113 @Override
114 protected EventLoop newChild(Executor executor, Object... args) throws Exception {
115 return new SuspendableDefaultEventLoop(this, executor);
116 }
117 }
118 }