1
2
3
4
5
6
7
8
9
10
11 package org.mule.providers.tcp.issues;
12
13 import java.io.IOException;
14 import java.net.ServerSocket;
15 import java.net.Socket;
16 import java.net.InetSocketAddress;
17
18 import junit.framework.TestCase;
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21
22
23
24
25
26
27
28
29
30 public class LingerExperimentMule2067TestCase extends TestCase
31 {
32
33 private static final int NO_LINGER = -1;
34 private static final int HARD_CLOSE = 0;
35 private static final int NO_WAIT = -1;
36 private static final int PORT = 65432;
37
38 private Log logger = LogFactory.getLog(getClass());
39
40 public void testInoffensive() throws IOException
41 {
42
43 openCloseServer(1000, PORT);
44 openCloseClientServer(1000, PORT, NO_LINGER, NO_LINGER);
45 }
46
47 public void testThisShowsTheProblem() throws IOException
48 {
49
50 repeatOpenCloseClientServer(10, 10, PORT, 1000);
51 repeatOpenCloseClientServer(10, 10, PORT, 100);
52 repeatOpenCloseClientServer(10, 10, PORT, 10);
53 repeatOpenCloseClientServer(10, 10, PORT, 1);
54 repeatOpenCloseClientServer(10, 10, PORT, 0);
55 repeatOpenCloseClientServer(10, 10, PORT, NO_WAIT);
56 }
57
58 public void testWithClientLinger() throws IOException
59 {
60
61 repeatOpenCloseClientServer(10, 10, PORT, NO_WAIT, NO_LINGER);
62 repeatOpenCloseClientServer(10, 10, PORT, 100, 1);
63 repeatOpenCloseClientServer(10, 10, PORT, 10, 1);
64 repeatOpenCloseClientServer(10, 10, PORT, 100, 2);
65 repeatOpenCloseClientServer(10, 10, PORT, 100, 30);
66
67 repeatOpenCloseClientServer(10, 10, PORT, 10, HARD_CLOSE);
68 repeatOpenCloseClientServer(10, 10, PORT, NO_WAIT, HARD_CLOSE);
69 }
70
71 public void testWithServerLinger() throws IOException
72 {
73
74 repeatOpenCloseClientServer(10, 10, PORT, 10, NO_LINGER, 1);
75 repeatOpenCloseClientServer(10, 10, PORT, 10, NO_LINGER, 1);
76 repeatOpenCloseClientServer(10, 10, PORT, 10, NO_LINGER, 2);
77 repeatOpenCloseClientServer(10, 10, PORT, 10, NO_LINGER, 30);
78 repeatOpenCloseClientServer(10, 10, PORT, NO_WAIT, NO_LINGER, 1);
79 }
80
81 public void testHardClose() throws IOException
82 {
83
84
85 repeatOpenCloseClientServer(10, 10, PORT, NO_WAIT, HARD_CLOSE, HARD_CLOSE);
86 }
87
88 protected void openCloseServer(int numberOfSockets, int port) throws IOException
89 {
90 for (int i = 0; i < numberOfSockets; i++)
91 {
92 ServerSocket socket = new ServerSocket(port);
93 socket.close();
94 }
95 }
96
97 protected void repeatOpenCloseClientServer(int numberOfRepeats, int numberOfConnections, int port, long pause)
98 throws IOException
99 {
100 repeatOpenCloseClientServer(numberOfRepeats, numberOfConnections, port, pause, NO_LINGER);
101 }
102
103 protected void repeatOpenCloseClientServer(int numberOfRepeats, int numberOfConnections, int port,
104 long pause, int clientLinger)
105 throws IOException
106 {
107 repeatOpenCloseClientServer(numberOfRepeats, numberOfConnections, port, pause, clientLinger, NO_LINGER);
108 }
109
110 protected void repeatOpenCloseClientServer(int numberOfRepeats, int numberOfConnections, int port,
111 long pause, int clientLinger, int serverLinger)
112 throws IOException
113 {
114 logger.info("Repeating openCloseClientServer with pauses of " + pause + " ms and lingers of "
115 + clientLinger + "/" + serverLinger + " s (client/server)");
116 for (int i = 0; i < numberOfRepeats; i++)
117 {
118 if (0 != i && pause != NO_WAIT)
119 {
120 try
121 {
122 if (pause > 0)
123 {
124 Thread.sleep(pause);
125 }
126 }
127 catch (InterruptedException e)
128 {
129
130 }
131 }
132 openCloseClientServer(numberOfConnections, port, clientLinger, serverLinger);
133 }
134 }
135
136 protected void openCloseClientServer(int numberOfConnections, int port, int clientLinger, int serverLinger)
137 throws IOException
138 {
139 Server server = new Server(port, serverLinger);
140 try
141 {
142 new Thread(server).start();
143 for (int i = 0; i < numberOfConnections; i++)
144 {
145 logger.debug("opening socket " + i);
146 Socket client = new Socket("localhost", port);
147 if (NO_LINGER != clientLinger)
148 {
149 client.setSoLinger(true, clientLinger);
150 }
151 client.close();
152 }
153 }
154 finally
155 {
156 server.close();
157 }
158 }
159
160 protected static class Server implements Runnable
161 {
162
163 private Log logger = LogFactory.getLog(getClass());
164 private ServerSocket server;
165 private int linger;
166
167 public Server(int port, int linger) throws IOException
168 {
169 this.linger = linger;
170 server = new ServerSocket();
171 server.bind(new InetSocketAddress("localhost", port));
172 }
173
174 public void run()
175 {
176 try
177 {
178 while (true)
179 {
180 Socket socket = server.accept();
181 if (NO_LINGER != linger)
182 {
183 socket.setSoLinger(true, linger);
184 }
185 socket.close();
186 }
187 }
188 catch (Exception e)
189 {
190 logger.debug("Expected - dirty closedown: " + e);
191 }
192 }
193
194 public void close() throws IOException
195 {
196 server.close();
197 server = null;
198 }
199 }
200
201 }