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.BindException;
17 import java.net.InetSocketAddress;
18 import java.net.ServerSocket;
19 import java.net.Socket;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 public class ReuseExperimentMule2067TestCase extends AbstractMuleTestCase
52 {
53
54 private static final int NO_WAIT = -1;
55 private static final int PORT = 65432;
56 private static boolean NO_REUSE = false;
57 private static boolean REUSE = true;
58
59 private Log logger = LogFactory.getLog(getClass());
60
61 public void testReuse() throws IOException
62 {
63 repeatOpenCloseClientServer(1000, 10, PORT, 1, REUSE, false);
64 repeatOpenCloseClientServer(100, 10, PORT, 1, NO_REUSE, false);
65 }
66
67 public void testMeasureImprovement() throws IOException
68 {
69 measureMeanRunLength(10, 100, 10, PORT, 100, NO_REUSE);
70 measureMeanRunLength(10, 100, 10, PORT+10, 100, REUSE);
71 measureMeanRunLength(10, 100, 10, PORT+20, 10, NO_REUSE);
72 measureMeanRunLength(10, 100, 10, PORT+30, 10, REUSE);
73 measureMeanRunLength(10, 100, 10, PORT+40, 1, NO_REUSE);
74 measureMeanRunLength(10, 100, 10, PORT+50, 1, REUSE);
75 }
76
77 protected void measureMeanRunLength(int sampleSize, int numberOfRepeats, int numberOfConnections,
78 int port, long pause, boolean reuse)
79 throws IOException
80 {
81 logger.info("Measuring average run length for " + numberOfRepeats + " repeats " +
82 (reuse ? "with" : "without") + " reuse and a pause of " + pause + " ms");
83 int totalLength = 0;
84 long totalLengthSquared = 0;
85 for (int i = 0; i < sampleSize; ++i)
86 {
87 int length = repeatOpenCloseClientServer(numberOfRepeats, numberOfConnections, port+i, pause, reuse, true);
88 totalLength += length;
89 totalLengthSquared += length * length;
90 }
91 double mean = totalLength / (double) sampleSize;
92 double sd = Math.sqrt(totalLengthSquared / (double) sampleSize - mean * mean);
93 logger.info("Average run length: " + mean + " +/- " + sd);
94 }
95
96 protected int repeatOpenCloseClientServer(int numberOfRepeats, int numberOfConnections, int port,
97 long pause, boolean reuse, boolean noFail)
98 throws IOException
99 {
100 String message = "Repeating openCloseClientServer with pauses of " + pause + " ms "
101 + (reuse ? "with" : "without") + " reuse";
102 if (noFail)
103 {
104 logger.debug(message);
105 }
106 else
107 {
108 logger.info(message);
109 }
110 for (int i = 0; i < numberOfRepeats; i++)
111 {
112 if (0 != i)
113 {
114 pause(pause);
115 }
116 try
117 {
118 openCloseClientServer(numberOfConnections, port, reuse);
119 }
120 catch (BindException e)
121 {
122 if (noFail && e.getMessage().indexOf("Address already in use") > -1)
123 {
124 return i;
125 }
126 throw e;
127 }
128 }
129 return numberOfRepeats;
130 }
131
132 protected void openCloseClientServer(int numberOfConnections, int port, boolean reuse)
133 throws IOException
134 {
135 Server server = new Server(port, reuse);
136 try {
137 new Thread(server).start();
138 for (int i = 0; i < numberOfConnections; i++)
139 {
140 logger.debug("opening socket " + i);
141 Socket client = new Socket("localhost", port);
142 client.close();
143 }
144 }
145 finally
146 {
147 server.close();
148 }
149 }
150
151 protected void pause(long pause)
152 {
153 if (pause != NO_WAIT)
154 {
155 try
156 {
157 if (pause > 0)
158 {
159 Thread.sleep(pause);
160 }
161 }
162 catch (InterruptedException e)
163 {
164
165 }
166 }
167 }
168
169 protected static class Server implements Runnable
170 {
171
172 private Log logger = LogFactory.getLog(getClass());
173 private ServerSocket server;
174
175 public Server(int port, boolean reuse) throws IOException
176 {
177 server = new ServerSocket();
178 server.setReuseAddress(reuse);
179 server.bind(new InetSocketAddress("localhost", port));
180 }
181
182 public void run()
183 {
184 try
185 {
186 while (true)
187 {
188 Socket socket = server.accept();
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 }