jdk/test/java/nio/channels/FileChannel/TransferTo6GBFile.java
changeset 44273 a2e3e08c5468
child 44363 bdc8543c97f5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/channels/FileChannel/TransferTo6GBFile.java	Fri Mar 17 08:38:12 2017 -0700
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 6253145
+ * @key intermittent
+ * @summary Test FileChannel.transferTo with file positions up to 8GB
+ * @run testng/timeout=300 TransferTo6GBFile
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.RandomAccessFile;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.util.concurrent.TimeUnit;
+
+import org.testng.annotations.Test;
+
+public class TransferTo6GBFile {
+
+    private static PrintStream err = System.err;
+    private static PrintStream out = System.out;
+
+    // Test transferTo with file positions larger than 2 and 4GB
+    @Test
+    public void xferTest08() throws Exception { // for bug 6253145
+        // Creating a sparse 6GB file on Windows takes too long
+        String osName = System.getProperty("os.name");
+        if (osName.startsWith("Windows"))
+            return;
+
+        final long G = 1024L * 1024L * 1024L;
+
+        // Create 6GB file
+
+        File file = File.createTempFile("source", null);
+        file.deleteOnExit();
+
+        RandomAccessFile raf = new RandomAccessFile(file, "rw");
+        FileChannel fc = raf.getChannel();
+
+        out.println("  Writing large file...");
+        long t0 = System.nanoTime();
+        try {
+            fc.write(ByteBuffer.wrap("0123456789012345".getBytes("UTF-8")), 6*G);
+            long t1 = System.nanoTime();
+            out.printf("  Wrote large file in %d ns (%d ms) %n",
+            t1 - t0, TimeUnit.NANOSECONDS.toMillis(t1 - t0));
+        } catch (IOException x) {
+            err.println("  Unable to create test file:" + x);
+            fc.close();
+            return;
+        }
+
+        // Setup looback connection and echo server
+
+        ServerSocketChannel ssc = ServerSocketChannel.open();
+        ssc.socket().bind(new InetSocketAddress(0));
+
+        InetAddress lh = InetAddress.getLocalHost();
+        InetSocketAddress isa = new InetSocketAddress(lh, ssc.socket().getLocalPort());
+        SocketChannel source = SocketChannel.open(isa);
+        SocketChannel sink = ssc.accept();
+
+        Thread thr = new Thread(new EchoServer(sink));
+        thr.start();
+
+        // Test data is array of positions and counts
+
+        long testdata[][] = {
+            { 2*G-1,    1 },
+            { 2*G-1,    10 },       // across 2GB boundary
+            { 2*G,      1 },
+            { 2*G,      10 },
+            { 2*G+1,    1 },
+            { 4*G-1,    1 },
+            { 4*G-1,    10 },       // across 4GB boundary
+            { 4*G,      1 },
+            { 4*G,      10 },
+            { 4*G+1,    1 },
+            { 5*G-1,    1 },
+            { 5*G-1,    10 },
+            { 5*G,      1 },
+            { 5*G,      10 },
+            { 5*G+1,    1 },
+            { 6*G,      1 },
+        };
+
+        ByteBuffer sendbuf = ByteBuffer.allocateDirect(100);
+        ByteBuffer readbuf = ByteBuffer.allocateDirect(100);
+
+        try {
+            byte value = 0;
+            for (int i=0; i<testdata.length; i++) {
+                long position = testdata[(int)i][0];
+                long count = testdata[(int)i][1];
+
+                // generate bytes
+                for (long j=0; j<count; j++) {
+                    sendbuf.put(++value);
+                }
+                sendbuf.flip();
+
+                // write to file and transfer to echo server
+                fc.write(sendbuf, position);
+                t0 = System.nanoTime();
+                fc.transferTo(position, count, source);
+                out.printf("  transferTo(%d, %2d, source): %d ns%n",
+                    position, count, System.nanoTime() - t0);
+
+                // read from echo server
+                long nread = 0;
+                while (nread < count) {
+                    int n = source.read(readbuf);
+                    if (n < 0)
+                        throw new RuntimeException("Premature EOF!");
+                    nread += n;
+                }
+
+                // check reply from echo server
+                readbuf.flip();
+                sendbuf.flip();
+                if (!readbuf.equals(sendbuf))
+                    throw new RuntimeException("Echoed bytes do not match!");
+                readbuf.clear();
+                sendbuf.clear();
+            }
+        } finally {
+            source.close();
+            ssc.close();
+            fc.close();
+            file.delete();
+        }
+    }
+
+    /**
+     * Simple in-process server to echo bytes read by a given socket channel
+     */
+    static class EchoServer implements Runnable {
+        private SocketChannel sc;
+
+        public EchoServer(SocketChannel sc) {
+            this.sc = sc;
+        }
+
+        public void run() {
+            ByteBuffer bb = ByteBuffer.allocateDirect(1024);
+            try {
+                for (;;) {
+                    int n = sc.read(bb);
+                    if (n < 0)
+                        break;
+
+                    bb.flip();
+                    while (bb.remaining() > 0) {
+                        sc.write(bb);
+                    }
+                    bb.clear();
+                }
+            } catch (IOException x) {
+                x.printStackTrace();
+            } finally {
+                try {
+                    sc.close();
+                } catch (IOException ignore) { }
+            }
+        }
+    }
+}