001: /*
002: * Copyright (c) xsocket.org, 2006-2008. All rights reserved.
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: * Please refer to the LGPL license at: http://www.gnu.org/copyleft/lesser.txt
019: * The latest copy of this software may be found on http://www.xsocket.org/
020: */
021: package org.xsocket.connection;
022:
023: import java.io.IOException;
024: import java.net.SocketTimeoutException;
025: import java.nio.BufferUnderflowException;
026: import java.nio.ByteBuffer;
027: import java.nio.channels.ClosedChannelException;
028: import java.util.logging.Logger;
029:
030: import org.junit.Assert;
031: import org.junit.Test;
032:
033: import org.xsocket.QAUtil;
034: import org.xsocket.connection.BlockingConnection;
035: import org.xsocket.connection.IBlockingConnection;
036: import org.xsocket.connection.IConnectHandler;
037: import org.xsocket.connection.IDataHandler;
038: import org.xsocket.connection.INonBlockingConnection;
039: import org.xsocket.connection.IServer;
040: import org.xsocket.connection.Server;
041: import org.xsocket.connection.ConnectionUtils;
042: import org.xsocket.connection.IConnection.FlushMode;
043:
044: /**
045: *
046: * @author grro@xsocket.org
047: */
048: public final class BlockingConnectionTest {
049:
050: private static final Logger LOG = Logger
051: .getLogger(BlockingConnectionTest.class.getName());
052:
053: private static final String DELIMITER = "x";
054:
055: private static byte[] byteArray = new byte[] { 1, 2, 3, 4, 5 };
056:
057: private int running = 0;
058:
059: public static void main(String[] args) throws Exception {
060: IServer responsingServer = new Server(new ResponsingHandler());
061: responsingServer.setFlushMode(FlushMode.ASYNC);
062: ConnectionUtils.start(responsingServer);
063:
064: for (int i = 0; i < 1000000; i++) {
065: IBlockingConnection connection = new BlockingConnection(
066: "localhost", responsingServer.getLocalPort());
067: connection.setFlushmode(FlushMode.ASYNC);
068:
069: connection.write(byteArray);
070: connection.write(DELIMITER);
071: connection.flush();
072:
073: byte[] response = connection.readBytesByDelimiter(
074: DELIMITER, Integer.MAX_VALUE);
075:
076: connection.close();
077: }
078:
079: responsingServer.close();
080: }
081:
082: @Test
083: public void testLiveHttp() throws Exception {
084: IBlockingConnection connection = new BlockingConnection(
085: "www.web.de", 80);
086: connection.setAutoflush(true);
087:
088: connection.write("GET /\r\n");
089: String response = connection.readStringByDelimiter("\r\n\r\n");
090: Assert.assertTrue(response.indexOf("WEB.DE") != -1);
091:
092: connection.close();
093: }
094:
095: @Test
096: public void testLiveSmtp() throws Exception {
097: IBlockingConnection connection = new BlockingConnection(
098: "smtp.web.de", 25);
099: connection.setAutoflush(true);
100:
101: String greeting = connection.readStringByDelimiter("\r\n");
102: Assert.assertTrue(greeting.indexOf("220") != -1);
103:
104: connection.close();
105: }
106:
107: @Test
108: public void testAsyncServerSide() throws Exception {
109: perform(new Server(new AsyncHandler()));
110: }
111:
112: @Test
113: public void testSyncServerSide() throws Exception {
114: perform(new Server(new SyncHandler()));
115: }
116:
117: private void perform(final IServer server) throws Exception {
118: ConnectionUtils.start(server);
119:
120: for (int i = 0; i < 50; i++) {
121:
122: final int num = i;
123: Thread t = new Thread() {
124: @Override
125: public void run() {
126: running++;
127:
128: try {
129: IBlockingConnection connection = new BlockingConnection(
130: "localhost", server.getLocalPort());
131: connection.setAutoflush(true);
132:
133: String request = "helo" + num;
134: connection.write(request);
135: connection.write(DELIMITER);
136: String response = connection
137: .readStringByDelimiter(DELIMITER);
138: Assert.assertEquals(request, response);
139:
140: LOG
141: .fine("server returned helo. send next request");
142:
143: byte[] requestArray = QAUtil
144: .generateByteArray(10 + num);
145: connection.write(requestArray);
146: connection.write(DELIMITER);
147:
148: LOG.fine("waiting for response..");
149: byte[] responseArray = connection
150: .readBytesByDelimiter(DELIMITER,
151: Integer.MAX_VALUE);
152: Assert.assertTrue(QAUtil.isEquals(requestArray,
153: responseArray));
154: LOG.fine("server returned second request");
155:
156: connection.close();
157:
158: } catch (Exception e) {
159: e.printStackTrace();
160: }
161:
162: running--;
163: }
164: };
165:
166: t.start();
167: }
168:
169: do {
170: QAUtil.sleep(100);
171: } while (running > 0);
172:
173: server.close();
174: }
175:
176: @Test
177: public void testNonAutoflush() throws Exception {
178: IServer responsingServer = new Server(new ResponsingHandler());
179: ConnectionUtils.start(responsingServer);
180:
181: IBlockingConnection connection = new BlockingConnection(
182: "localhost", responsingServer.getLocalPort());
183: connection.setAutoflush(false);
184:
185: connection.write(byteArray);
186: connection.write(DELIMITER);
187: connection.flush();
188: byte[] response = connection.readBytesByDelimiter(DELIMITER,
189: Integer.MAX_VALUE);
190: Assert.assertTrue(QAUtil.isEquals(byteArray, response));
191:
192: connection.write(byteArray);
193: connection.write(DELIMITER);
194: connection.flush();
195: byte[] response2 = connection.readBytesByDelimiter(DELIMITER,
196: Integer.MAX_VALUE);
197: Assert.assertTrue(QAUtil.isEquals(byteArray, response2));
198:
199: connection.close();
200:
201: responsingServer.close();
202: }
203:
204: @Test
205: public void testIdleTimeout() throws Exception {
206: IServer responsingServer = new Server(new ResponsingHandler());
207: ConnectionUtils.start(responsingServer);
208:
209: IBlockingConnection connection = new BlockingConnection(
210: "localhost", responsingServer.getLocalPort());
211: connection.setAutoflush(false);
212: connection.setIdleTimeoutMillis(1 * 1000);
213:
214: try {
215: connection.readByte();
216: } catch (ClosedChannelException e) {
217: // should occur
218: }
219:
220: connection.close();
221:
222: responsingServer.close();
223: }
224:
225: @Test
226: public void testConnectionTimeout() throws Exception {
227: IServer responsingServer = new Server(new ResponsingHandler());
228: ConnectionUtils.start(responsingServer);
229:
230: IBlockingConnection connection = new BlockingConnection(
231: "localhost", responsingServer.getLocalPort());
232: connection.setAutoflush(false);
233: connection.setConnectionTimeoutMillis(1 * 1000);
234:
235: try {
236: connection.readByte();
237: } catch (ClosedChannelException e) {
238: // should occur
239: }
240:
241: connection.close();
242:
243: responsingServer.close();
244: }
245:
246: @Test
247: public void testBulk() throws Exception {
248: IServer server = new Server(new EchoHandler());
249: ConnectionUtils.start(server);
250:
251: for (int i = 0; i < 300; i++) {
252: IBlockingConnection connection = new BlockingConnection(
253: "localhost", server.getLocalPort());
254:
255: connection.write("test" + EchoHandler.DELIMITER);
256: Assert.assertEquals("test", connection
257: .readStringByDelimiter(EchoHandler.DELIMITER));
258: connection.close();
259: }
260:
261: server.close();
262: }
263:
264: @Test
265: public void testReceiveTimeoutVeryHigh() throws Exception {
266: IServer responsingServer = new Server(new ResponsingHandler());
267: ConnectionUtils.start(responsingServer);
268:
269: IBlockingConnection connection = new BlockingConnection(
270: "localhost", responsingServer.getLocalPort());
271: connection.setAutoflush(false);
272: connection.setReceiveTimeoutMillis(1000000);
273:
274: connection.write(byteArray);
275: connection.write(DELIMITER);
276: connection.flush();
277: byte[] response = connection.readBytesByDelimiter(DELIMITER);
278: Assert.assertTrue(QAUtil.isEquals(byteArray, response));
279:
280: connection.close();
281: responsingServer.close();
282: }
283:
284: @Test
285: public void testReceiveNormal() throws Exception {
286: IServer responsingServer = new Server(new ResponsingHandler());
287: ConnectionUtils.start(responsingServer);
288:
289: IBlockingConnection connection = new BlockingConnection(
290: "localhost", responsingServer.getLocalPort());
291: connection.setAutoflush(false);
292: connection.setReceiveTimeoutMillis(1000);
293:
294: connection.write(byteArray);
295: connection.write(DELIMITER);
296: connection.flush();
297: byte[] response = connection.readBytesByDelimiter(DELIMITER,
298: Integer.MAX_VALUE);
299: Assert.assertTrue(QAUtil.isEquals(byteArray, response));
300: connection.close();
301: responsingServer.close();
302: }
303:
304: @Test
305: public void testNonresponsive() throws Exception {
306: IServer nonResponsingServer = new Server(
307: new NonResponsingHandler());
308: ConnectionUtils.start(nonResponsingServer);
309:
310: IBlockingConnection connection = new BlockingConnection(
311: "localhost", nonResponsingServer.getLocalPort());
312: connection.setReceiveTimeoutMillis(1000);
313: connection.setAutoflush(true);
314:
315: long start = System.currentTimeMillis();
316: try {
317: connection.readInt();
318: Assert.fail("Timeout Exception should have been occured");
319: } catch (SocketTimeoutException te) {
320: QAUtil.assertTimeout(System.currentTimeMillis() - start,
321: 1000, 1000, 2000);
322: }
323:
324: connection.setReceiveTimeoutMillis(3000);
325:
326: start = System.currentTimeMillis();
327: try {
328: connection.readInt();
329: Assert.fail("Timeout Exception should have been occured");
330: } catch (SocketTimeoutException te) {
331: QAUtil.assertTimeout(System.currentTimeMillis() - start,
332: 3000, 3000, 3500);
333: }
334:
335: connection.close();
336:
337: nonResponsingServer.close();
338: }
339:
340: private static final class NonResponsingHandler implements
341: IDataHandler {
342:
343: public boolean onData(INonBlockingConnection connection)
344: throws IOException, BufferUnderflowException {
345: // do nothing
346: return true;
347: }
348: }
349:
350: private static final class ResponsingHandler implements
351: IDataHandler {
352:
353: public boolean onData(INonBlockingConnection connection)
354: throws IOException, BufferUnderflowException {
355: connection.setAutoflush(false);
356:
357: ByteBuffer[] buffers = connection
358: .readByteBufferByDelimiter(DELIMITER);
359: connection.write(buffers);
360: connection.write(DELIMITER);
361: LOG.fine("return data");
362:
363: connection.flush();
364: return true;
365: }
366: }
367:
368: private static final class AsyncHandler implements IConnectHandler,
369: IDataHandler {
370:
371: public boolean onConnect(INonBlockingConnection connection)
372: throws IOException {
373: connection.setAutoflush(false);
374: connection.setFlushmode(FlushMode.ASYNC);
375:
376: return true;
377: }
378:
379: public boolean onData(INonBlockingConnection connection)
380: throws IOException, BufferUnderflowException {
381: ByteBuffer[] buffers = connection
382: .readByteBufferByDelimiter(DELIMITER);
383: connection.write(buffers);
384: connection.write(DELIMITER);
385: LOG.fine("return data");
386:
387: connection.flush();
388: return true;
389: }
390: }
391:
392: private static final class SyncHandler implements IConnectHandler,
393: IDataHandler {
394:
395: public boolean onConnect(INonBlockingConnection connection)
396: throws IOException {
397: connection.setAutoflush(false);
398: connection.setFlushmode(FlushMode.SYNC);
399:
400: return true;
401: }
402:
403: public boolean onData(INonBlockingConnection connection)
404: throws IOException, BufferUnderflowException {
405: ByteBuffer[] buffers = connection
406: .readByteBufferByDelimiter(DELIMITER);
407: connection.write(buffers);
408: connection.write(DELIMITER);
409: LOG.fine("return data");
410:
411: connection.flush();
412: return true;
413: }
414: }
415:
416: }
|