1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.core.net;
15
16 import java.net.ConnectException;
17 import java.net.ServerSocket;
18 import java.net.Socket;
19 import java.net.SocketAddress;
20 import java.util.concurrent.BrokenBarrierException;
21 import java.util.concurrent.CyclicBarrier;
22 import java.util.concurrent.ExecutorService;
23 import java.util.concurrent.Executors;
24 import java.util.concurrent.Future;
25 import java.util.concurrent.TimeUnit;
26 import java.util.concurrent.TimeoutException;
27
28 import org.junit.jupiter.api.AfterEach;
29 import org.junit.jupiter.api.Assertions;
30 import org.junit.jupiter.api.BeforeEach;
31 import org.junit.jupiter.api.Disabled;
32
33 import ch.qos.logback.core.net.SocketConnector.ExceptionHandler;
34 import ch.qos.logback.core.net.server.test.ServerSocketUtil;
35 import ch.qos.logback.core.testUtil.EnvUtilForTests;
36 import org.junit.jupiter.api.Test;
37 import org.junit.jupiter.api.Timeout;
38
39
40
41
42
43
44 public class DefaultSocketConnectorTest {
45
46 private static final int DELAY = 2000;
47 private static final int SHORT_DELAY = 10;
48 private static final int RETRY_DELAY = 10;
49
50 private MockExceptionHandler exceptionHandler = new MockExceptionHandler();
51
52 private ServerSocket serverSocket;
53 private DefaultSocketConnector connector;
54
55 ExecutorService executor = Executors.newSingleThreadExecutor();
56
57 @BeforeEach
58 public void setUp() throws Exception {
59 if(EnvUtilForTests.isGithubAction())
60 return;
61
62 serverSocket = ServerSocketUtil.createServerSocket();
63 connector = new DefaultSocketConnector(serverSocket.getInetAddress(), serverSocket.getLocalPort(), 0,
64 RETRY_DELAY);
65 connector.setExceptionHandler(exceptionHandler);
66 }
67
68 @AfterEach
69 public void tearDown() throws Exception {
70 if(EnvUtilForTests.isGithubAction())
71 return;
72
73 if (serverSocket != null) {
74 serverSocket.close();
75 }
76 }
77
78 @Test
79 public void testConnect() throws Exception {
80 if(EnvUtilForTests.isGithubAction())
81 return;
82
83 Future<Socket> connectorTask = executor.submit(connector);
84
85 Socket socket = connectorTask.get(DELAY, TimeUnit.MILLISECONDS);
86 Assertions.assertNotNull(socket);
87 connectorTask.cancel(true);
88
89 Assertions.assertTrue(connectorTask.isDone());
90 socket.close();
91 }
92
93 @Test
94 public void testConnectionFails() throws Exception {
95 if(EnvUtilForTests.isGithubAction())
96 return;
97
98 serverSocket.close();
99 Future<Socket> connectorTask = executor.submit(connector);
100
101
102 try {
103 connectorTask.get(SHORT_DELAY, TimeUnit.MILLISECONDS);
104 Assertions.fail();
105 } catch (TimeoutException e) {
106 }
107 Exception lastException = exceptionHandler.awaitConnectionFailed();
108 Assertions.assertTrue(lastException instanceof ConnectException);
109 Assertions.assertFalse(connectorTask.isDone());
110 connectorTask.cancel(true);
111
112
113 Assertions.assertTrue(connectorTask.isCancelled());
114 }
115
116 @Disabled
117 @Test
118 @Timeout(value=5, unit = TimeUnit.SECONDS)
119 public void testConnectEventually() throws Exception {
120 if(EnvUtilForTests.isGithubAction())
121 return;
122
123 serverSocket.close();
124
125 Future<Socket> connectorTask = executor.submit(connector);
126
127 try {
128 connectorTask.get(SHORT_DELAY, TimeUnit.MILLISECONDS);
129 Assertions.fail();
130 } catch (TimeoutException e) {
131 }
132
133
134 Exception lastException = exceptionHandler.awaitConnectionFailed();
135 Assertions.assertNotNull(lastException);
136 Assertions.assertTrue(lastException instanceof ConnectException);
137
138
139 SocketAddress address = serverSocket.getLocalSocketAddress();
140 serverSocket = new ServerSocket();
141 serverSocket.setReuseAddress(true);
142 serverSocket.bind(address);
143
144
145 Socket socket = connectorTask.get(2 * DELAY, TimeUnit.MILLISECONDS);
146
147 Assertions.assertNotNull(socket);
148
149 Assertions.assertFalse(connectorTask.isCancelled());
150 socket.close();
151 }
152
153 private static class MockExceptionHandler implements ExceptionHandler {
154
155 private final CyclicBarrier failureBarrier = new CyclicBarrier(2);
156
157 private Exception lastException;
158
159 public void connectionFailed(SocketConnector connector, Exception ex) {
160 lastException = ex;
161 try {
162 failureBarrier.await();
163 } catch (InterruptedException | BrokenBarrierException e) {
164 e.printStackTrace();
165 }
166 }
167
168 public Exception awaitConnectionFailed() throws InterruptedException {
169 if (lastException != null) {
170 return lastException;
171 }
172
173 try {
174 failureBarrier.await();
175 } catch (InterruptedException | BrokenBarrierException e) {
176 e.printStackTrace();
177 }
178 return lastException;
179 }
180
181 }
182
183 }