Path: blob/master/test/jdk/java/nio/channels/SocketChannel/ShortWrite.java
41154 views
/*1* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/* @test24* @bug 7176630 707443625* @summary Check for short writes on SocketChannels configured in blocking mode26* @key randomness27*/2829import java.net.*;30import java.nio.ByteBuffer;31import java.nio.channels.*;32import java.util.concurrent.*;33import java.util.Random;34import java.util.zip.CRC32;3536public class ShortWrite {3738static final Random rand = new Random();3940/**41* Returns a checksum on the remaining bytes in the given buffers.42*/43static long computeChecksum(ByteBuffer... bufs) {44CRC32 crc32 = new CRC32();45for (int i=0; i<bufs.length; i++)46crc32.update(bufs[i]);47return crc32.getValue();48}4950/**51* A task that reads the expected number of bytes and returns the CRC3252* of those bytes.53*/54static class Reader implements Callable<Long> {55final SocketChannel sc;56final ByteBuffer buf;5758Reader(SocketChannel sc, int expectedSize) {59this.sc = sc;60this.buf = ByteBuffer.allocate(expectedSize);61}6263public Long call() throws Exception {64while (buf.hasRemaining()) {65int n = sc.read(buf);66if (n == -1)67throw new RuntimeException("Premature EOF encountered");68}69buf.flip();70return computeChecksum(buf);71}72}7374/**75* Exercise write(ByteBuffer) with given number of bytes.76*/77static void test1(ExecutorService pool,78SocketChannel source,79SocketChannel sink,80int size)81throws Exception82{83System.out.println("write(ByteBuffer), size=" + size);8485// random bytes in the buffer86ByteBuffer buf = ByteBuffer.allocate(size);87rand.nextBytes(buf.array());8889// submit task to read the bytes90Future<Long> result = pool.submit(new Reader(sink, size));9192// write the bytes93int n = source.write(buf);94if (n != size)95throw new RuntimeException("Short write detected");9697// check the bytes that were received match98buf.rewind();99long expected = computeChecksum(buf);100long actual = result.get();101if (actual != expected)102throw new RuntimeException("Checksum did not match");103}104105/**106* Exercise write(ByteBuffer[]) with buffers of the given sizes.107*/108static void testN(ExecutorService pool,109SocketChannel source,110SocketChannel sink,111int... sizes)112throws Exception113{114System.out.print("write(ByteBuffer[]), sizes=");115for (int size: sizes)116System.out.print(size + " ");117System.out.println();118119int total = 0;120int len = sizes.length;121ByteBuffer[] bufs = new ByteBuffer[len];122for (int i=0; i<len; i++) {123int size = sizes[i];124ByteBuffer buf = ByteBuffer.allocate(size);125rand.nextBytes(buf.array());126bufs[i] = buf;127total += size;128}129130// submit task to read the bytes131Future<Long> result = pool.submit(new Reader(sink, total));132133// write the bytes134long n = source.write(bufs);135if (n != total)136throw new RuntimeException("Short write detected");137138// check the bytes that were received match139for (int i=0; i<len; i++)140bufs[i].rewind();141long expected = computeChecksum(bufs);142long actual = result.get();143if (actual != expected)144throw new RuntimeException("Checksum did not match");145}146147public static void main(String[] args) throws Exception {148ExecutorService pool = Executors.newSingleThreadExecutor();149try {150try (ServerSocketChannel ssc = ServerSocketChannel.open()) {151ssc.bind(new InetSocketAddress(0));152InetAddress lh = InetAddress.getLocalHost();153int port = ssc.socket().getLocalPort();154SocketAddress sa = new InetSocketAddress(lh, port);155156try (SocketChannel source = SocketChannel.open(sa);157SocketChannel sink = ssc.accept())158{159// Exercise write(BufferBuffer) on sizes around 128k160int BOUNDARY = 128 * 1024;161for (int size=(BOUNDARY-2); size<=(BOUNDARY+2); size++) {162test1(pool, source, sink, size);163}164165// Exercise write(BufferBuffer) on random sizes166for (int i=0; i<20; i++) {167int size = rand.nextInt(1024*1024);168test1(pool, source, sink, size);169}170171// Exercise write(BufferBuffer[]) on sizes around 128k172for (int i=BOUNDARY-2; i<=BOUNDARY+2; i++) {173testN(pool, source, sink, i);174testN(pool, source, sink, 0, i);175testN(pool, source, sink, i, 0);176for (int j=BOUNDARY-2; j<=BOUNDARY+2; j++) {177testN(pool, source, sink, i, j);178testN(pool, source, sink, 0, i, j);179testN(pool, source, sink, i, 0, j);180testN(pool, source, sink, i, j, 0);181for (int k=BOUNDARY-2; k<=BOUNDARY+2; k++) {182testN(pool, source, sink, i, j, k);183testN(pool, source, sink, 0, i, j, k);184testN(pool, source, sink, i, 0, j, k);185testN(pool, source, sink, i, j, 0, k);186testN(pool, source, sink, i, j, k, 0);187}188}189}190191// Exercise write(BufferBuffer[]) on random sizes192// (assumes IOV_MAX >= 8)193for (int i=0; i<20; i++) {194int n = rand.nextInt(9);195int[] sizes = new int[n];196for (int j=0; j<n; j++) {197sizes[j] = rand.nextInt(1024*1024);198}199testN(pool, source, sink, sizes);200}201}202}203204} finally {205pool.shutdown();206}207}208}209210211