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;
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 }