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;
21  
22  import static org.junit.Assert.assertEquals;
23  import static org.junit.Assert.assertTrue;
24  
25  import java.io.File;
26  import java.io.FileOutputStream;
27  import java.io.IOException;
28  import java.net.InetSocketAddress;
29  import java.nio.ByteBuffer;
30  import java.nio.channels.FileChannel;
31  import java.util.concurrent.CountDownLatch;
32  
33  import org.apache.mina.core.buffer.IoBuffer;
34  import org.apache.mina.core.future.ConnectFuture;
35  import org.apache.mina.core.service.IoAcceptor;
36  import org.apache.mina.core.service.IoConnector;
37  import org.apache.mina.core.service.IoHandlerAdapter;
38  import org.apache.mina.core.session.IoSession;
39  import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
40  import org.apache.mina.util.AvailablePortFinder;
41  import org.junit.Test;
42  
43  /**
44   * TODO Add documentation
45   * 
46   * @author <a href="http://mina.apache.org">Apache MINA Project</a>
47   */
48  public abstract class AbstractFileRegionTest {
49  
50      private static final int FILE_SIZE = 1 * 1024 * 1024; // 1MB file
51      
52      protected abstract IoAcceptor createAcceptor();
53      protected abstract IoConnector createConnector();
54  
55      @Test
56      public void testSendLargeFile() throws Throwable {
57          File file = createLargeFile();
58          assertEquals("Test file not as big as specified", FILE_SIZE, file.length());
59          
60          final CountDownLatch latch = new CountDownLatch(1);
61          final boolean[] success = {false};
62          final Throwable[] exception = {null};
63          
64          int port = AvailablePortFinder.getNextAvailable(1025);
65          IoAcceptor acceptor = createAcceptor();
66          IoConnector connector = createConnector();
67  
68          try {
69              acceptor.setHandler(new IoHandlerAdapter() {
70                  private int index = 0;
71                  @Override
72                  public void exceptionCaught(IoSession session, Throwable cause)
73                          throws Exception {
74                      exception[0] = cause;
75                      session.close(true);
76                  }
77                  @Override
78                  public void messageReceived(IoSession session, Object message) throws Exception {
79                      IoBuffer buffer = (IoBuffer) message;
80                      while (buffer.hasRemaining()) {
81                          int x = buffer.getInt();
82                          if (x != index) {
83                              throw new Exception(String.format("Integer at %d was %d but should have been %d", index, x, index));
84                          }
85                          index++;
86                      }
87                      if (index > FILE_SIZE / 4) {
88                          throw new Exception("Read too much data");
89                      }
90                      if (index == FILE_SIZE / 4) {
91                          success[0] = true;
92                          session.close(true);
93                      }
94                  }
95              });
96              
97              ((NioSocketAcceptor)acceptor).setReuseAddress(true);
98              
99              acceptor.bind(new InetSocketAddress(port));
100             
101             connector.setHandler(new IoHandlerAdapter() {
102                 @Override
103                 public void exceptionCaught(IoSession session, Throwable cause)
104                         throws Exception {
105                     exception[0] = cause;
106                     session.close(true);
107                 }
108                 @Override
109                 public void sessionClosed(IoSession session) throws Exception {
110                     latch.countDown();
111                 }
112             });
113             
114             ConnectFuture future = connector.connect(new InetSocketAddress("localhost", port));
115             future.awaitUninterruptibly();
116             
117             IoSession session = future.getSession();
118             session.write(file);
119             
120             latch.await();
121             
122             if (exception[0] != null) {
123                 throw exception[0];
124             }
125             assertTrue("Did not complete file transfer successfully", success[0]);
126             
127             assertEquals("Written messages should be 1 (we wrote one file)", 1, session.getWrittenMessages());
128             assertEquals("Written bytes should match file size", FILE_SIZE, session.getWrittenBytes());
129         } finally {
130             try {
131                 connector.dispose();
132             } finally {
133                 acceptor.dispose();
134             }
135         }
136     }
137     
138     private File createLargeFile() throws IOException {
139         File largeFile = File.createTempFile("mina-test", "largefile");
140         largeFile.deleteOnExit();
141         FileChannel channel = new FileOutputStream(largeFile).getChannel();
142         ByteBuffer buffer = createBuffer();
143         channel.write(buffer);
144         channel.close();
145         return largeFile;
146     }
147     
148     private ByteBuffer createBuffer() {
149         ByteBuffer buffer = ByteBuffer.allocate(FILE_SIZE);
150         for (int i = 0; i < FILE_SIZE / 4; i++) {
151             buffer.putInt(i);
152         }
153         buffer.flip();
154         return buffer;
155     }
156 }