View Javadoc
1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
4    *
5    * This program and the accompanying materials are dual-licensed under
6    * either the terms of the Eclipse Public License v1.0 as published by
7    * the Eclipse Foundation
8    *
9    *   or (per the licensee's choosing)
10   *
11   * under the terms of the GNU Lesser General Public License version 2.1
12   * as published by the Free Software Foundation.
13   */
14  package ch.qos.logback.core.net.server;
15  
16  import java.io.IOException;
17  import java.net.InetAddress;
18  import java.net.ServerSocket;
19  import java.net.Socket;
20  
21  import org.junit.jupiter.api.Assertions;
22  import org.junit.jupiter.api.BeforeEach;
23  import org.junit.jupiter.api.Test;
24  
25  import ch.qos.logback.core.net.server.test.ServerSocketUtil;
26  
27  /**
28   * Unit tests for {@link ServerSocketListener}.
29   *
30   * @author Carl Harris
31   */
32  public class ServerSocketListenerTest {
33  
34      private ServerSocket serverSocket;
35      @SuppressWarnings("rawtypes")
36      private ServerSocketListener listener;
37  
38      @BeforeEach
39      public void setUp() throws Exception {
40          serverSocket = ServerSocketUtil.createServerSocket();
41          Assertions.assertNotNull(serverSocket);
42          listener = new InstrumentedServerSocketListener(serverSocket);
43      }
44  
45      @Test
46      public void testAcceptClient() throws Exception {
47          RunnableClient localClient = new RunnableClient(InetAddress.getLocalHost(), serverSocket.getLocalPort());
48          Thread thread = new Thread(localClient);
49          thread.start();
50          synchronized (localClient) {
51              int retries = 200;
52              while (retries-- > 0 && !localClient.isConnected()) {
53                  localClient.wait(10);
54              }
55          }
56          Assertions.assertTrue(localClient.isConnected());
57          localClient.close();
58  
59          serverSocket.setSoTimeout(5000);
60          Client client = listener.acceptClient();
61          Assertions.assertNotNull(client);
62          client.close();
63      }
64  
65      private static class InstrumentedServerSocketListener extends ServerSocketListener<RemoteClient> {
66  
67          public InstrumentedServerSocketListener(ServerSocket serverSocket) {
68              super(serverSocket);
69          }
70  
71          @Override
72          protected RemoteClient createClient(String id, Socket socket) throws IOException {
73              return new RemoteClient(socket);
74          }
75  
76      }
77  
78      private static class RemoteClient implements Client {
79  
80          private final Socket socket;
81  
82          public RemoteClient(Socket socket) {
83              this.socket = socket;
84          }
85  
86          public void run() {
87          }
88  
89          public void close() {
90              try {
91                  socket.close();
92              } catch (IOException ex) {
93                  ex.printStackTrace(System.err);
94              }
95          }
96  
97      }
98  
99      private static class RunnableClient implements Client {
100 
101         private final InetAddress inetAddress;
102         private final int port;
103         private boolean connected;
104         private boolean closed;
105 
106         public RunnableClient(InetAddress inetAddress, int port) {
107             super();
108             this.inetAddress = inetAddress;
109             this.port = port;
110         }
111 
112         public synchronized boolean isConnected() {
113             return connected;
114         }
115 
116         public synchronized void setConnected(boolean connected) {
117             this.connected = connected;
118         }
119 
120         public void run() {
121             try {
122                 Socket socket = new Socket(inetAddress, port);
123                 synchronized (this) {
124                     setConnected(true);
125                     notifyAll();
126                     while (!closed && !Thread.currentThread().isInterrupted()) {
127                         try {
128                             wait();
129                         } catch (InterruptedException ex) {
130                             Thread.currentThread().interrupt();
131                         }
132                     }
133                     socket.close();
134                 }
135             } catch (IOException ex) {
136                 ex.printStackTrace(System.err);
137             }
138         }
139 
140         public synchronized void close() {
141             closed = true;
142             notifyAll();
143         }
144 
145     }
146 }