1   package org.apache.mina.transport;
2   
3   import java.io.File;
4   import java.io.FileOutputStream;
5   import java.io.IOException;
6   import java.net.InetSocketAddress;
7   import java.nio.ByteBuffer;
8   import java.nio.channels.FileChannel;
9   import java.util.concurrent.CountDownLatch;
10  
11  import junit.framework.TestCase;
12  
13  import org.apache.mina.common.ConnectFuture;
14  import org.apache.mina.common.IoAcceptor;
15  import org.apache.mina.common.IoBuffer;
16  import org.apache.mina.common.IoConnector;
17  import org.apache.mina.common.IoHandlerAdapter;
18  import org.apache.mina.common.IoSession;
19  import org.apache.mina.util.AvailablePortFinder;
20  
21  public abstract class AbstractFileRegionTest extends TestCase {
22  
23      private static final int FILE_SIZE = 1 * 1024 * 1024; // 1MB file
24      
25      protected abstract IoAcceptor createAcceptor();
26      protected abstract IoConnector createConnector();
27  
28      public void testSendLargeFile() throws Throwable {
29          File file = createLargeFile();
30          assertEquals("Test file not as big as specified", FILE_SIZE, file.length());
31          
32          final CountDownLatch latch = new CountDownLatch(1);
33          final boolean[] success = {false};
34          final Throwable[] exception = {null};
35          
36          int port = AvailablePortFinder.getNextAvailable(1025);
37          IoAcceptor acceptor = createAcceptor();
38          acceptor.setHandler(new IoHandlerAdapter() {
39              private int index = 0;
40              @Override
41              public void exceptionCaught(IoSession session, Throwable cause)
42                      throws Exception {
43                  exception[0] = cause;
44                  session.close();
45              }
46              @Override
47              public void sessionClosed(IoSession session) throws Exception {
48                  latch.countDown();
49              }
50              @Override
51              public void messageReceived(IoSession session, Object message) throws Exception {
52                  IoBuffer buffer = (IoBuffer) message;
53                  while (buffer.hasRemaining()) {
54                      int x = buffer.getInt();
55                      if (x != index) {
56                          throw new Exception(String.format("Integer at %d was %d but should have been %d", index, x, index));
57                      }
58                      index++;
59                  }
60                  if (index > FILE_SIZE / 4) {
61                      throw new Exception("Read too much data");
62                  }
63                  if (index == FILE_SIZE / 4) {
64                      success[0] = true;
65                      session.close();
66                  }
67              }
68          });
69          acceptor.bind(new InetSocketAddress(port));
70          
71          IoConnector connector = createConnector();
72          connector.setHandler(new IoHandlerAdapter() {
73              @Override
74              public void exceptionCaught(IoSession session, Throwable cause)
75                      throws Exception {
76                  exception[0] = cause;
77                  latch.countDown();
78              }
79          });
80          ConnectFuture future = connector.connect(new InetSocketAddress("localhost", port));
81          future.awaitUninterruptibly();
82          
83          IoSession session = future.getSession();
84          session.write(file);
85          
86          latch.await();
87          
88          if (exception[0] != null) {
89              throw exception[0];
90          }
91          assertTrue("Did not complete file transfer successfully", success[0]);
92          
93          assertEquals("Written messages should be 1 (we wrote one file)", 1, session.getWrittenMessages());
94          assertEquals("Written bytes should match file size", FILE_SIZE, session.getWrittenBytes());
95          
96          connector.dispose();
97          acceptor.dispose();
98      }
99      
100     private File createLargeFile() throws IOException {
101         File largeFile = File.createTempFile("mina-test", "largefile");
102         FileChannel channel = new FileOutputStream(largeFile).getChannel();
103         ByteBuffer buffer = createBuffer();
104         channel.write(buffer);
105         channel.close();
106         return largeFile;
107     }
108     private ByteBuffer createBuffer() {
109         ByteBuffer buffer = ByteBuffer.allocate(FILE_SIZE);
110         for (int i = 0; i < FILE_SIZE / 4; i++) {
111             buffer.putInt(i);
112         }
113         buffer.flip();
114         return buffer;
115     }
116     
117 }