001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.mina.transport; 021 022import static org.junit.Assert.assertEquals; 023import static org.junit.Assert.assertTrue; 024 025import java.io.File; 026import java.io.FileOutputStream; 027import java.io.IOException; 028import java.net.InetSocketAddress; 029import java.nio.ByteBuffer; 030import java.nio.channels.FileChannel; 031import java.util.concurrent.CountDownLatch; 032 033import org.apache.mina.core.buffer.IoBuffer; 034import org.apache.mina.core.future.ConnectFuture; 035import org.apache.mina.core.service.IoAcceptor; 036import org.apache.mina.core.service.IoConnector; 037import org.apache.mina.core.service.IoHandlerAdapter; 038import org.apache.mina.core.session.IoSession; 039import org.apache.mina.transport.socket.nio.NioSocketAcceptor; 040import org.apache.mina.util.AvailablePortFinder; 041import org.junit.Test; 042 043/** 044 * TODO Add documentation 045 * 046 * @author <a href="http://mina.apache.org">Apache MINA Project</a> 047 */ 048public abstract class AbstractFileRegionTest { 049 050 private static final int FILE_SIZE = 1 * 1024 * 1024; // 1MB file 051 052 protected abstract IoAcceptor createAcceptor(); 053 054 protected abstract IoConnector createConnector(); 055 056 @Test 057 public void testSendLargeFile() throws Throwable { 058 File file = createLargeFile(); 059 assertEquals("Test file not as big as specified", FILE_SIZE, file.length()); 060 061 final CountDownLatch latch = new CountDownLatch(1); 062 final boolean[] success = { false }; 063 final Throwable[] exception = { null }; 064 065 int port = AvailablePortFinder.getNextAvailable(1025); 066 IoAcceptor acceptor = createAcceptor(); 067 IoConnector connector = createConnector(); 068 069 try { 070 acceptor.setHandler(new IoHandlerAdapter() { 071 private int index = 0; 072 073 @Override 074 public void exceptionCaught(IoSession session, Throwable cause) throws Exception { 075 exception[0] = cause; 076 session.close(true); 077 } 078 079 @Override 080 public void messageReceived(IoSession session, Object message) throws Exception { 081 IoBuffer buffer = (IoBuffer) message; 082 while (buffer.hasRemaining()) { 083 int x = buffer.getInt(); 084 if (x != index) { 085 throw new Exception(String.format("Integer at %d was %d but should have been %d", index, x, 086 index)); 087 } 088 index++; 089 } 090 if (index > FILE_SIZE / 4) { 091 throw new Exception("Read too much data"); 092 } 093 if (index == FILE_SIZE / 4) { 094 success[0] = true; 095 session.close(true); 096 } 097 } 098 }); 099 100 ((NioSocketAcceptor) acceptor).setReuseAddress(true); 101 102 acceptor.bind(new InetSocketAddress(port)); 103 104 connector.setHandler(new IoHandlerAdapter() { 105 @Override 106 public void exceptionCaught(IoSession session, Throwable cause) throws Exception { 107 exception[0] = cause; 108 session.close(true); 109 } 110 111 @Override 112 public void sessionClosed(IoSession session) throws Exception { 113 latch.countDown(); 114 } 115 }); 116 117 ConnectFuture future = connector.connect(new InetSocketAddress("localhost", port)); 118 future.awaitUninterruptibly(); 119 120 IoSession session = future.getSession(); 121 session.write(file); 122 123 latch.await(); 124 125 if (exception[0] != null) { 126 throw exception[0]; 127 } 128 assertTrue("Did not complete file transfer successfully", success[0]); 129 130 assertEquals("Written messages should be 1 (we wrote one file)", 1, session.getWrittenMessages()); 131 assertEquals("Written bytes should match file size", FILE_SIZE, session.getWrittenBytes()); 132 } finally { 133 try { 134 connector.dispose(); 135 } finally { 136 acceptor.dispose(); 137 } 138 } 139 } 140 141 private File createLargeFile() throws IOException { 142 File largeFile = File.createTempFile("mina-test", "largefile"); 143 largeFile.deleteOnExit(); 144 FileChannel channel = null; 145 FileOutputStream out = null; 146 147 try { 148 out = new FileOutputStream(largeFile); 149 channel = out.getChannel(); 150 ByteBuffer buffer = createBuffer(); 151 channel.write(buffer); 152 channel.close(); 153 out.close(); 154 } finally { 155 if (channel != null) { 156 channel.close(); 157 } 158 159 if (out != null) { 160 out.close(); 161 } 162 } 163 164 return largeFile; 165 } 166 167 private ByteBuffer createBuffer() { 168 ByteBuffer buffer = ByteBuffer.allocate(FILE_SIZE); 169 for (int i = 0; i < FILE_SIZE / 4; i++) { 170 buffer.putInt(i); 171 } 172 buffer.flip(); 173 return buffer; 174 } 175}