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