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