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  
54      protected abstract IoConnector createConnector();
55  
56      @Test
57      public void testSendLargeFile() throws Throwable {
58          File file = createLargeFile();
59          assertEquals("Test file not as big as specified", FILE_SIZE, file.length());
60  
61          final CountDownLatch latch = new CountDownLatch(1);
62          final boolean[] success = { false };
63          final Throwable[] exception = { null };
64  
65          int port = AvailablePortFinder.getNextAvailable(1025);
66          IoAcceptor acceptor = createAcceptor();
67          IoConnector connector = createConnector();
68  
69          try {
70              acceptor.setHandler(new IoHandlerAdapter() {
71                  private int index = 0;
72  
73                  @Override
74                  public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
75                      exception[0] = cause;
76                      session.closeNow();
77                  }
78  
79                  @Override
80                  public void messageReceived(IoSession session, Object message) throws Exception {
81                      IoBuffer buffer = (IoBuffer) message;
82                      while (buffer.hasRemaining()) {
83                          int x = buffer.getInt();
84                          if (x != index) {
85                              throw new Exception(String.format("Integer at %d was %d but should have been %d", index, x,
86                                      index));
87                          }
88                          index++;
89                      }
90                      if (index > FILE_SIZE / 4) {
91                          throw new Exception("Read too much data");
92                      }
93                      if (index == FILE_SIZE / 4) {
94                          success[0] = true;
95                          session.closeNow();
96                      }
97                  }
98              });
99  
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.closeNow();
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 }