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