1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
45
46
47
48 public abstract class AbstractFileRegionTest {
49
50 private static final int FILE_SIZE = 1 * 1024 * 1024;
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.close(true);
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.close(true);
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.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 = new FileOutputStream(largeFile).getChannel();
145 ByteBuffer buffer = createBuffer();
146 channel.write(buffer);
147 channel.close();
148 return largeFile;
149 }
150
151 private ByteBuffer createBuffer() {
152 ByteBuffer buffer = ByteBuffer.allocate(FILE_SIZE);
153 for (int i = 0; i < FILE_SIZE / 4; i++) {
154 buffer.putInt(i);
155 }
156 buffer.flip();
157 return buffer;
158 }
159 }