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 import java.util.Date;
26
27 import junit.framework.Assert;
28 import junit.framework.TestCase;
29
30 import org.apache.mina.core.buffer.IoBuffer;
31 import org.apache.mina.core.future.ConnectFuture;
32 import org.apache.mina.core.service.IoAcceptor;
33 import org.apache.mina.core.service.IoConnector;
34 import org.apache.mina.core.service.IoHandlerAdapter;
35 import org.apache.mina.core.session.IdleStatus;
36 import org.apache.mina.core.session.IoSession;
37 import org.apache.mina.transport.socket.DatagramAcceptor;
38 import org.apache.mina.transport.socket.DatagramSessionConfig;
39 import org.apache.mina.transport.socket.SocketAcceptor;
40 import org.apache.mina.transport.socket.SocketSessionConfig;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44
45
46
47
48
49
50 public abstract class AbstractBindTest extends TestCase {
51 protected final IoAcceptor acceptor;
52
53 protected int port;
54
55 public AbstractBindTest(IoAcceptor acceptor) {
56 this.acceptor = acceptor;
57 }
58
59 protected abstract SocketAddress createSocketAddress(int port);
60
61 protected abstract int getPort(SocketAddress address);
62
63 protected abstract IoConnector newConnector();
64
65 protected void bind(boolean reuseAddress) throws IOException {
66 acceptor.setHandler(new EchoProtocolHandler());
67
68 setReuseAddress(reuseAddress);
69
70
71 boolean socketBound = false;
72
73
74
75
76 for (port = 1; port <= 65535; port++) {
77 socketBound = false;
78 try {
79 acceptor.setDefaultLocalAddress(createSocketAddress(port));
80 acceptor.bind();
81 socketBound = true;
82 break;
83 } catch (IOException e) {
84
85 }
86 }
87
88
89 if (!socketBound) {
90 throw new IOException("Cannot bind any test port.");
91 }
92
93
94 }
95
96 private void setReuseAddress(boolean reuseAddress) {
97 if (acceptor instanceof DatagramAcceptor) {
98 ((DatagramSessionConfig) acceptor.getSessionConfig())
99 .setReuseAddress(reuseAddress);
100 } else if (acceptor instanceof SocketAcceptor) {
101 ((SocketAcceptor) acceptor).setReuseAddress(reuseAddress);
102 }
103 }
104
105 @Override
106 public void tearDown() {
107 try {
108 acceptor.dispose();
109 } catch (Exception e) {
110
111 }
112
113 acceptor.setDefaultLocalAddress(null);
114 }
115
116 public void testAnonymousBind() throws Exception {
117 acceptor.setHandler(new IoHandlerAdapter());
118 acceptor.setDefaultLocalAddress(null);
119 acceptor.bind();
120 Assert.assertNotNull(acceptor.getLocalAddress());
121 acceptor.unbind(acceptor.getLocalAddress());
122 Assert.assertNull(acceptor.getLocalAddress());
123 acceptor.setDefaultLocalAddress(createSocketAddress(0));
124 acceptor.bind();
125 Assert.assertNotNull(acceptor.getLocalAddress());
126 Assert.assertTrue(getPort(acceptor.getLocalAddress()) != 0);
127 acceptor.unbind(acceptor.getLocalAddress());
128 }
129
130 public void testDuplicateBind() throws IOException {
131 bind(false);
132
133 try {
134 acceptor.bind();
135 Assert.fail("Exception is not thrown");
136 } catch (Exception e) {
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 Assert.assertTrue(sessions[i].isConnected());
169 Assert.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 Assert.assertEquals(5, managedSessions.size());
177
178 acceptor.unbind();
179
180
181 Thread.sleep(500);
182
183 Assert.assertEquals(0, managedSessions.size());
184 for (IoSession element : managedSessions) {
185 Assert.assertFalse(element.isConnected());
186 }
187 }
188
189 public void _testRegressively() throws IOException {
190 setReuseAddress(true);
191
192 SocketAddress addr = createSocketAddress(port);
193 EchoProtocolHandler handler = new EchoProtocolHandler();
194 acceptor.setDefaultLocalAddress(addr);
195 acceptor.setHandler(handler);
196 for (int i = 0; i < 1048576; i++) {
197 acceptor.bind();
198 acceptor.unbind();
199 if (i % 100 == 0) {
200 System.out.println(i + " (" + new Date() + ")");
201 }
202 }
203 bind(false);
204 }
205
206 private static class EchoProtocolHandler extends IoHandlerAdapter {
207 private static final Logger log = LoggerFactory
208 .getLogger(EchoProtocolHandler.class);
209
210 @Override
211 public void sessionCreated(IoSession session) {
212 if (session.getConfig() instanceof SocketSessionConfig) {
213 ((SocketSessionConfig) session.getConfig())
214 .setReceiveBufferSize(2048);
215 }
216
217 session.getConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
218 }
219
220 @Override
221 public void sessionIdle(IoSession session, IdleStatus status) {
222 log.info("*** IDLE #" + session.getIdleCount(IdleStatus.BOTH_IDLE)
223 + " ***");
224 }
225
226 @Override
227 public void exceptionCaught(IoSession session, Throwable cause) {
228 cause.printStackTrace();
229 session.close();
230 }
231
232 @Override
233 public void messageReceived(IoSession session, Object message)
234 throws Exception {
235 if (!(message instanceof IoBuffer)) {
236 return;
237 }
238
239 IoBuffer rb = (IoBuffer) message;
240
241 IoBuffer wb = IoBuffer.allocate(rb.remaining());
242 wb.put(rb);
243 wb.flip();
244 session.write(wb);
245 }
246 }
247 }