1
2
3
4
5
6
7
8
9
10
11 package org.mule.providers.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 if (pause > 0)
124 {
125 Thread.sleep(pause);
126 }
127 }
128 catch (InterruptedException e)
129 {
130
131 }
132 }
133 openCloseClientServer(numberOfConnections, port, clientLinger, serverLinger);
134 }
135 }
136
137 protected void openCloseClientServer(int numberOfConnections, int port, int clientLinger, int serverLinger)
138 throws IOException
139 {
140 Server server = new Server(port, serverLinger);
141 try
142 {
143 new Thread(server).start();
144 for (int i = 0; i < numberOfConnections; i++)
145 {
146 logger.debug("opening socket " + i);
147 Socket client = new Socket("localhost", port);
148 if (NO_LINGER != clientLinger)
149 {
150 client.setSoLinger(true, clientLinger);
151 }
152 client.close();
153 }
154 }
155 finally
156 {
157 server.close();
158 }
159 }
160
161 protected static class Server implements Runnable
162 {
163
164 private Log logger = LogFactory.getLog(getClass());
165 private ServerSocket server;
166 private int linger;
167
168 public Server(int port, int linger) throws IOException
169 {
170 this.linger = linger;
171 server = new ServerSocket();
172 server.bind(new InetSocketAddress("localhost", port));
173 }
174
175 public void run()
176 {
177 try
178 {
179 while (true)
180 {
181 Socket socket = server.accept();
182 if (NO_LINGER != linger)
183 {
184 socket.setSoLinger(true, linger);
185 }
186 socket.close();
187 }
188 }
189 catch (Exception e)
190 {
191 logger.debug("Expected - dirty closedown: " + e);
192 }
193 }
194
195 public void close() throws IOException
196 {
197 server.close();
198 server = null;
199 }
200 }
201
202 }