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