1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.transport;
21
22 import java.io.IOException;
23 import java.net.SocketAddress;
24 import java.util.Collection;
25
26 import junit.framework.TestCase;
27
28 import org.apache.mina.core.buffer.IoBuffer;
29 import org.apache.mina.core.future.ConnectFuture;
30 import org.apache.mina.core.service.IoAcceptor;
31 import org.apache.mina.core.service.IoConnector;
32 import org.apache.mina.core.service.IoHandlerAdapter;
33 import org.apache.mina.core.session.IdleStatus;
34 import org.apache.mina.core.session.IoSession;
35 import org.apache.mina.transport.socket.DatagramAcceptor;
36 import org.apache.mina.transport.socket.DatagramSessionConfig;
37 import org.apache.mina.transport.socket.SocketAcceptor;
38 import org.apache.mina.transport.socket.SocketSessionConfig;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42
43
44
45
46
47 public abstract class AbstractBindTest extends TestCase {
48 protected final IoAcceptor acceptor;
49
50 protected int port;
51
52 public AbstractBindTest(IoAcceptor acceptor) {
53 this.acceptor = acceptor;
54 }
55
56 protected abstract SocketAddress createSocketAddress(int port);
57
58 protected abstract int getPort(SocketAddress address);
59
60 protected abstract IoConnector newConnector();
61
62 protected void bind(boolean reuseAddress) throws IOException {
63 acceptor.setHandler(new EchoProtocolHandler());
64
65 setReuseAddress(reuseAddress);
66
67
68 boolean socketBound = false;
69
70
71
72
73 for (port = 1; port <= 65535; port++) {
74 socketBound = false;
75 try {
76 acceptor.setDefaultLocalAddress(createSocketAddress(port));
77 acceptor.bind();
78 socketBound = true;
79 break;
80 } catch (IOException e) {
81
82 }
83 }
84
85
86 if (!socketBound) {
87 throw new IOException("Cannot bind any test port.");
88 }
89
90
91 }
92
93 private void setReuseAddress(boolean reuseAddress) {
94 if (acceptor instanceof DatagramAcceptor) {
95 ((DatagramSessionConfig) acceptor.getSessionConfig())
96 .setReuseAddress(reuseAddress);
97 } else if (acceptor instanceof SocketAcceptor) {
98 ((SocketAcceptor) acceptor).setReuseAddress(reuseAddress);
99 }
100 }
101
102 @Override
103 public void tearDown() {
104 try {
105 acceptor.dispose();
106 } catch (Exception e) {
107
108 }
109
110 acceptor.setDefaultLocalAddress(null);
111 }
112
113 public void testAnonymousBind() throws Exception {
114 acceptor.setHandler(new IoHandlerAdapter());
115 acceptor.setDefaultLocalAddress(null);
116 acceptor.bind();
117 assertNotNull(acceptor.getLocalAddress());
118 acceptor.unbind(acceptor.getLocalAddress());
119 assertNull(acceptor.getLocalAddress());
120 acceptor.setDefaultLocalAddress(createSocketAddress(0));
121 acceptor.bind();
122 assertNotNull(acceptor.getLocalAddress());
123 assertTrue(getPort(acceptor.getLocalAddress()) != 0);
124 acceptor.unbind(acceptor.getLocalAddress());
125 }
126
127 public void testDuplicateBind() throws IOException {
128 bind(false);
129
130 try {
131 acceptor.bind();
132 fail("Exception is not thrown");
133 } catch (Exception e) {
134
135 assertTrue(true);
136 }
137 }
138
139 public void testDuplicateUnbind() throws IOException {
140 bind(false);
141
142
143 acceptor.unbind();
144
145
146 acceptor.unbind();
147 }
148
149 public void testManyTimes() throws IOException {
150 bind(true);
151
152 for (int i = 0; i < 1024; i++) {
153 acceptor.unbind();
154 acceptor.bind();
155 }
156 }
157
158 public void testUnbindDisconnectsClients() throws Exception {
159 bind(true);
160 IoConnector connector = newConnector();
161 IoSession[] sessions = new IoSession[5];
162 connector.setHandler(new IoHandlerAdapter());
163 for (int i = 0; i < sessions.length; i++) {
164 ConnectFuture future = connector.connect(createSocketAddress(port));
165 future.awaitUninterruptibly();
166 sessions[i] = future.getSession();
167 assertTrue(sessions[i].isConnected());
168 assertTrue(sessions[i].write(IoBuffer.allocate(1)).awaitUninterruptibly().isWritten());
169 }
170
171
172 Thread.sleep(500);
173
174 Collection<IoSession> managedSessions = acceptor.getManagedSessions().values();
175 assertEquals(5, managedSessions.size());
176
177 acceptor.unbind();
178
179
180 Thread.sleep(500);
181
182 assertEquals(0, managedSessions.size());
183 for (IoSession element : managedSessions) {
184 assertFalse(element.isConnected());
185 }
186 }
187
188 public void testUnbindResume() throws Exception {
189 bind(true);
190 IoConnector connector = newConnector();
191 IoSession session = null;
192 connector.setHandler(new IoHandlerAdapter());
193
194 ConnectFuture future = connector.connect(createSocketAddress(port));
195 future.awaitUninterruptibly();
196 session = future.getSession();
197 assertTrue(session.isConnected());
198 assertTrue(session.write(IoBuffer.allocate(1)).awaitUninterruptibly().isWritten());
199
200
201 Thread.sleep(500);
202
203 Collection<IoSession> managedSession = acceptor.getManagedSessions().values();
204 assertEquals(1, managedSession.size());
205
206 acceptor.unbind();
207
208
209 Thread.sleep(500);
210
211 assertEquals(0, managedSession.size());
212 for (IoSession element : managedSession) {
213 assertFalse(element.isConnected());
214 }
215
216
217 bind(true);
218
219
220 future = connector.connect(createSocketAddress(port));
221 future.awaitUninterruptibly();
222 session = future.getSession();
223 assertTrue(session.isConnected());
224 assertTrue(session.write(IoBuffer.allocate(1)).awaitUninterruptibly().isWritten());
225
226
227 Thread.sleep(500);
228
229 managedSession = acceptor.getManagedSessions().values();
230 assertEquals(1, managedSession.size());
231 }
232
233 public void _testRegressively() throws IOException {
234 setReuseAddress(true);
235
236 SocketAddress addr = createSocketAddress(port);
237 EchoProtocolHandler handler = new EchoProtocolHandler();
238 acceptor.setDefaultLocalAddress(addr);
239 acceptor.setHandler(handler);
240 for (int i = 0; i < 1048576; i++) {
241 acceptor.bind();
242 acceptor.unbind();
243
244
245
246 }
247 bind(false);
248 }
249
250 private static class EchoProtocolHandler extends IoHandlerAdapter {
251 private static final Logger LOG = LoggerFactory
252 .getLogger(EchoProtocolHandler.class);
253
254
255
256
257 public EchoProtocolHandler() {
258 super();
259 }
260
261 @Override
262 public void sessionCreated(IoSession session) {
263 if (session.getConfig() instanceof SocketSessionConfig) {
264 ((SocketSessionConfig) session.getConfig())
265 .setReceiveBufferSize(2048);
266 }
267
268 session.getConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
269 }
270
271 @Override
272 public void sessionIdle(IoSession session, IdleStatus status) {
273 LOG.info("*** IDLE #" + session.getIdleCount(IdleStatus.BOTH_IDLE)
274 + " ***");
275 }
276
277 @Override
278 public void exceptionCaught(IoSession session, Throwable cause) {
279
280 session.close(true);
281 }
282
283 @Override
284 public void messageReceived(IoSession session, Object message)
285 throws Exception {
286 if (!(message instanceof IoBuffer)) {
287 return;
288 }
289
290 IoBuffer rb = (IoBuffer) message;
291
292 IoBuffer wb = IoBuffer.allocate(rb.remaining());
293 wb.put(rb);
294 wb.flip();
295 session.write(wb);
296 }
297 }
298 }