View Javadoc

1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License.
18   *
19   */
20  package org.apache.mina.transport.nio;
21  
22  import static org.junit.Assert.assertEquals;
23  import static org.junit.Assert.assertTrue;
24  import static org.junit.Assert.fail;
25  
26  import java.io.IOException;
27  import java.net.Socket;
28  import java.nio.ByteBuffer;
29  import java.util.concurrent.CountDownLatch;
30  import java.util.concurrent.TimeUnit;
31  
32  import org.apache.mina.api.AbstractIoHandler;
33  import org.apache.mina.api.IdleStatus;
34  import org.apache.mina.api.IoHandler;
35  import org.apache.mina.api.IoSession;
36  import org.apache.mina.transport.nio.FixedSelectorLoopPool;
37  import org.apache.mina.transport.nio.NioTcpServer;
38  import org.apache.mina.transport.nio.SelectorLoopPool;
39  import org.junit.Test;
40  import org.slf4j.Logger;
41  import org.slf4j.LoggerFactory;
42  
43  /**
44   * This class test the event dispatching of {@link NioTcpServer}. It tests if alls the {@link IoHandler} events are
45   * correctly generated.
46   * 
47   * @author <a href="http://mina.apache.org">Apache MINA Project</a>
48   */
49  public class NioTcpServerHandlerTest {
50  
51      private static final Logger LOG = LoggerFactory.getLogger(NioTcpServerHandlerTest.class);
52  
53      private static final int CLIENT_COUNT = 100;
54  
55      private static final int WAIT_TIME = 5000;
56  
57      private final CountDownLatch msgSentLatch = new CountDownLatch(CLIENT_COUNT);
58  
59      private final CountDownLatch msgReadLatch = new CountDownLatch(CLIENT_COUNT);
60  
61      private final CountDownLatch openLatch = new CountDownLatch(CLIENT_COUNT);
62  
63      private final CountDownLatch closedLatch = new CountDownLatch(CLIENT_COUNT);
64  
65      private final CountDownLatch idleLatch = new CountDownLatch(CLIENT_COUNT);
66  
67      @Test
68      public void generate_all_kind_of_server_event() throws IOException, InterruptedException {
69          final NioTcpServer server = new NioTcpServer();
70          server.setFilters();
71          server.getSessionConfig().setIdleTimeInMillis(IdleStatus.READ_IDLE, 1000);
72          server.setIoHandler(new Handler());
73          server.bind(0);
74  
75          // warm up
76          Thread.sleep(100);
77  
78          final int port = server.getServerSocketChannel().socket().getLocalPort();
79  
80          final Socket[] clients = new Socket[CLIENT_COUNT];
81  
82          // connect some clients
83          for (int i = 0; i < CLIENT_COUNT; i++) {
84              clients[i] = new Socket("127.0.0.1", port);
85          }
86  
87          // does the session open message was fired ?
88          assertTrue(openLatch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
89  
90          // write some messages
91          for (int i = 0; i < CLIENT_COUNT; i++) {
92              clients[i].getOutputStream().write(("test:" + i).getBytes());
93              clients[i].getOutputStream().flush();
94          }
95  
96          // test is message was received by the server
97          assertTrue(msgReadLatch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
98  
99          // does response was wrote and sent ?
100         assertTrue(msgSentLatch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
101 
102         // read the echos
103         final byte[] buffer = new byte[1024];
104 
105         for (int i = 0; i < CLIENT_COUNT; i++) {
106             final int bytes = clients[i].getInputStream().read(buffer);
107             final String text = new String(buffer, 0, bytes);
108             assertEquals("test:" + i, text);
109         }
110 
111         // does the session idle event was fired ?
112         assertTrue(idleLatch.await(5 * WAIT_TIME, TimeUnit.MILLISECONDS));
113 
114         // close the session
115         assertEquals(CLIENT_COUNT, closedLatch.getCount());
116         for (int i = 0; i < CLIENT_COUNT; i++) {
117             clients[i].close();
118         }
119 
120         // does the session close event was fired ?
121         assertTrue(closedLatch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
122 
123         server.unbind();
124     }
125 
126     @Test
127     public void generateAllKindOfServerEventOneSelector() throws IOException, InterruptedException {
128         SelectorLoopPool selectorLoopPool = new FixedSelectorLoopPool("Server", 1);
129         final NioTcpServer server = new NioTcpServer(selectorLoopPool.getSelectorLoop(), selectorLoopPool, null);
130         server.setFilters();
131         server.setIoHandler(new Handler());
132         server.bind(0);
133 
134         // warm up
135         Thread.sleep(100);
136 
137         final int port = server.getServerSocketChannel().socket().getLocalPort();
138 
139         final Socket[] clients = new Socket[CLIENT_COUNT];
140 
141         // connect some clients
142         for (int i = 0; i < CLIENT_COUNT; i++) {
143             clients[i] = new Socket("127.0.0.1", port);
144         }
145 
146         // does the session open message was fired ?
147         assertTrue(openLatch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
148 
149         // write some messages
150         for (int i = 0; i < CLIENT_COUNT; i++) {
151             clients[i].getOutputStream().write(("test:" + i).getBytes());
152             clients[i].getOutputStream().flush();
153         }
154 
155         // test is message was received by the server
156         assertTrue(msgReadLatch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
157 
158         // does response was wrote and sent ?
159         assertTrue(msgSentLatch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
160 
161         // read the echos
162         final byte[] buffer = new byte[1024];
163 
164         for (int i = 0; i < CLIENT_COUNT; i++) {
165             final int bytes = clients[i].getInputStream().read(buffer);
166             final String text = new String(buffer, 0, bytes);
167             assertEquals("test:" + i, text);
168         }
169 
170         // close the session
171         assertEquals(CLIENT_COUNT, closedLatch.getCount());
172         for (int i = 0; i < CLIENT_COUNT; i++) {
173             clients[i].close();
174         }
175 
176         // does the session close event was fired ?
177         assertTrue(closedLatch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
178 
179         server.unbind();
180     }
181 
182     private class Handler extends AbstractIoHandler {
183 
184         @Override
185         public void sessionOpened(final IoSession session) {
186             LOG.debug("** session open");
187             openLatch.countDown();
188         }
189 
190         @Override
191         public void sessionClosed(final IoSession session) {
192             LOG.debug("** session closed");
193             closedLatch.countDown();
194         }
195 
196         @Override
197         public void messageReceived(final IoSession session, final Object message) {
198             LOG.debug("** message received {}", message);
199             msgReadLatch.countDown();
200             if (message instanceof ByteBuffer) {
201                 ByteBuffer msg = (ByteBuffer) message;
202                 session.write(ByteBuffer.allocate(msg.remaining()).put(msg).flip());
203             } else {
204                 fail("non bytebuffer received??");
205             }
206         }
207 
208         @Override
209         public void messageSent(final IoSession session, final Object message) {
210             LOG.debug("** message sent {}", message);
211             msgSentLatch.countDown();
212         }
213 
214         @Override
215         public void sessionIdle(IoSession session, IdleStatus status) {
216             if (status == IdleStatus.READ_IDLE) {
217                 idleLatch.countDown();
218             }
219         }
220     }
221 
222 }