Path: blob/master/test/jdk/java/io/InputStream/TransferTo.java
41149 views
/*1* Copyright (c) 2014, 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*/2223import java.io.ByteArrayOutputStream;24import java.io.FilterInputStream;25import java.io.FilterOutputStream;26import java.io.IOException;27import java.io.InputStream;28import java.io.OutputStream;29import java.util.Arrays;30import java.util.Random;3132import static java.lang.String.format;3334/*35* @test36* @bug 806686737* @summary tests whether java.io.InputStream.transferTo conforms to its38* contract defined in the javadoc39* @key randomness40*/41public class TransferTo {4243public static void main(String[] args) throws IOException {44ifOutIsNullThenNpeIsThrown();45ifExceptionInInputNeitherStreamIsClosed();46ifExceptionInOutputNeitherStreamIsClosed();47onReturnNeitherStreamIsClosed();48onReturnInputIsAtEnd();49contents();50}5152private static void ifOutIsNullThenNpeIsThrown() throws IOException {53try (InputStream in = input()) {54assertThrowsNPE(() -> in.transferTo(null), "out");55}5657try (InputStream in = input((byte) 1)) {58assertThrowsNPE(() -> in.transferTo(null), "out");59}6061try (InputStream in = input((byte) 1, (byte) 2)) {62assertThrowsNPE(() -> in.transferTo(null), "out");63}6465InputStream in = null;66try {67InputStream fin = in = new ThrowingInputStream();68// null check should precede everything else:69// InputStream shouldn't be touched if OutputStream is null70assertThrowsNPE(() -> fin.transferTo(null), "out");71} finally {72if (in != null)73try {74in.close();75} catch (IOException ignored) { }76}77}7879private static void ifExceptionInInputNeitherStreamIsClosed()80throws IOException {81transferToThenCheckIfAnyClosed(input(0, new byte[]{1, 2, 3}), output());82transferToThenCheckIfAnyClosed(input(1, new byte[]{1, 2, 3}), output());83transferToThenCheckIfAnyClosed(input(2, new byte[]{1, 2, 3}), output());84}8586private static void ifExceptionInOutputNeitherStreamIsClosed()87throws IOException {88transferToThenCheckIfAnyClosed(input(new byte[]{1, 2, 3}), output(0));89transferToThenCheckIfAnyClosed(input(new byte[]{1, 2, 3}), output(1));90transferToThenCheckIfAnyClosed(input(new byte[]{1, 2, 3}), output(2));91}9293private static void transferToThenCheckIfAnyClosed(InputStream input,94OutputStream output)95throws IOException {96try (CloseLoggingInputStream in = new CloseLoggingInputStream(input);97CloseLoggingOutputStream out =98new CloseLoggingOutputStream(output)) {99boolean thrown = false;100try {101in.transferTo(out);102} catch (IOException ignored) {103thrown = true;104}105if (!thrown)106throw new AssertionError();107108if (in.wasClosed() || out.wasClosed()) {109throw new AssertionError();110}111}112}113114private static void onReturnNeitherStreamIsClosed()115throws IOException {116try (CloseLoggingInputStream in =117new CloseLoggingInputStream(input(new byte[]{1, 2, 3}));118CloseLoggingOutputStream out =119new CloseLoggingOutputStream(output())) {120121in.transferTo(out);122123if (in.wasClosed() || out.wasClosed()) {124throw new AssertionError();125}126}127}128129private static void onReturnInputIsAtEnd() throws IOException {130try (InputStream in = input(new byte[]{1, 2, 3});131OutputStream out = output()) {132133in.transferTo(out);134135if (in.read() != -1) {136throw new AssertionError();137}138}139}140141private static void contents() throws IOException {142checkTransferredContents(new byte[0]);143checkTransferredContents(createRandomBytes(1024, 4096));144// to span through several batches145checkTransferredContents(createRandomBytes(16384, 16384));146}147148private static void checkTransferredContents(byte[] bytes)149throws IOException {150try (InputStream in = input(bytes);151ByteArrayOutputStream out = new ByteArrayOutputStream()) {152in.transferTo(out);153154byte[] outBytes = out.toByteArray();155if (!Arrays.equals(bytes, outBytes)) {156throw new AssertionError(157format("bytes.length=%s, outBytes.length=%s",158bytes.length, outBytes.length));159}160}161}162163private static byte[] createRandomBytes(int min, int maxRandomAdditive) {164Random rnd = new Random();165byte[] bytes = new byte[min + rnd.nextInt(maxRandomAdditive)];166rnd.nextBytes(bytes);167return bytes;168}169170private static OutputStream output() {171return output(-1);172}173174private static OutputStream output(int exceptionPosition) {175return new OutputStream() {176177int pos;178179@Override180public void write(int b) throws IOException {181if (pos++ == exceptionPosition)182throw new IOException();183}184};185}186187private static InputStream input(byte... bytes) {188return input(-1, bytes);189}190191private static InputStream input(int exceptionPosition, byte... bytes) {192return new InputStream() {193194int pos;195196@Override197public int read() throws IOException {198if (pos == exceptionPosition) {199// because of the pesky IOException swallowing in200// java.io.InputStream.read(byte[], int, int)201// pos++;202throw new IOException();203}204205if (pos >= bytes.length)206return -1;207return bytes[pos++] & 0xff;208}209};210}211212private static class ThrowingInputStream extends InputStream {213214boolean closed;215216@Override217public int read(byte[] b) throws IOException {218throw new IOException();219}220221@Override222public int read(byte[] b, int off, int len) throws IOException {223throw new IOException();224}225226@Override227public long skip(long n) throws IOException {228throw new IOException();229}230231@Override232public int available() throws IOException {233throw new IOException();234}235236@Override237public void close() throws IOException {238if (!closed) {239closed = true;240throw new IOException();241}242}243244@Override245public void reset() throws IOException {246throw new IOException();247}248249@Override250public int read() throws IOException {251throw new IOException();252}253}254255private static class CloseLoggingInputStream extends FilterInputStream {256257boolean closed;258259CloseLoggingInputStream(InputStream in) {260super(in);261}262263@Override264public void close() throws IOException {265closed = true;266super.close();267}268269boolean wasClosed() {270return closed;271}272}273274private static class CloseLoggingOutputStream extends FilterOutputStream {275276boolean closed;277278CloseLoggingOutputStream(OutputStream out) {279super(out);280}281282@Override283public void close() throws IOException {284closed = true;285super.close();286}287288boolean wasClosed() {289return closed;290}291}292293public interface Thrower {294public void run() throws Throwable;295}296297public static void assertThrowsNPE(Thrower thrower, String message) {298assertThrows(thrower, NullPointerException.class, message);299}300301public static <T extends Throwable> void assertThrows(Thrower thrower,302Class<T> throwable,303String message) {304Throwable thrown;305try {306thrower.run();307thrown = null;308} catch (Throwable caught) {309thrown = caught;310}311312if (!throwable.isInstance(thrown)) {313String caught = thrown == null ?314"nothing" : thrown.getClass().getCanonicalName();315throw new AssertionError(316format("Expected to catch %s, but caught %s",317throwable, caught), thrown);318}319320if (thrown != null && !message.equals(thrown.getMessage())) {321throw new AssertionError(322format("Expected exception message to be '%s', but it's '%s'",323message, thrown.getMessage()));324}325}326}327328329