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