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