Path: blob/master/test/jdk/java/io/Reader/TransferTo.java
41149 views
/*1* Copyright (c) 2017, 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.*;24import java.util.Arrays;25import java.util.Random;2627import jdk.test.lib.RandomFactory;2829import static java.lang.String.format;3031/*32* @test33* @bug 819170634* @summary tests whether java.io.Reader.transferTo conforms to its35* contract defined source the javadoc36* @library /test/lib37* @build jdk.test.lib.RandomFactory38* @run main TransferTo39* @key randomness40* @author Patrick Reinhart41*/42public class TransferTo {4344private static Random generator = RandomFactory.getRandom();4546public static void main(String[] args) throws IOException {47ifOutIsNullThenNpeIsThrown();48ifExceptionInInputNeitherStreamIsClosed();49ifExceptionInOutputNeitherStreamIsClosed();50onReturnNeitherStreamIsClosed();51onReturnInputIsAtEnd();52contents();53}5455private static void ifOutIsNullThenNpeIsThrown() throws IOException {56try (Reader in = input()) {57assertThrowsNPE(() -> in.transferTo(null), "out");58}5960try (Reader in = input((char) 1)) {61assertThrowsNPE(() -> in.transferTo(null), "out");62}6364try (Reader in = input((char) 1, (char) 2)) {65assertThrowsNPE(() -> in.transferTo(null), "out");66}6768Reader in = null;69try {70Reader fin = in = new ThrowingReader();71// null check should precede everything else:72// Reader shouldn't be touched if Writer is null73assertThrowsNPE(() -> fin.transferTo(null), "out");74} finally {75if (in != null)76try {77in.close();78} catch (IOException ignored) { }79}80}8182private static void ifExceptionInInputNeitherStreamIsClosed()83throws IOException {84transferToThenCheckIfAnyClosed(input(0, new char[]{1, 2, 3}), output());85transferToThenCheckIfAnyClosed(input(1, new char[]{1, 2, 3}), output());86transferToThenCheckIfAnyClosed(input(2, new char[]{1, 2, 3}), output());87}8889private static void ifExceptionInOutputNeitherStreamIsClosed()90throws IOException {91transferToThenCheckIfAnyClosed(input(new char[]{1, 2, 3}), output(0));92transferToThenCheckIfAnyClosed(input(new char[]{1, 2, 3}), output(1));93transferToThenCheckIfAnyClosed(input(new char[]{1, 2, 3}), output(2));94}9596private static void transferToThenCheckIfAnyClosed(Reader input,97Writer output)98throws IOException {99try (CloseLoggingReader in = new CloseLoggingReader(input);100CloseLoggingWriter out =101new CloseLoggingWriter(output)) {102boolean thrown = false;103try {104in.transferTo(out);105} catch (IOException ignored) {106thrown = true;107}108if (!thrown)109throw new AssertionError();110111if (in.wasClosed() || out.wasClosed()) {112throw new AssertionError();113}114}115}116117private static void onReturnNeitherStreamIsClosed()118throws IOException {119try (CloseLoggingReader in =120new CloseLoggingReader(input(new char[]{1, 2, 3}));121CloseLoggingWriter out =122new CloseLoggingWriter(output())) {123124in.transferTo(out);125126if (in.wasClosed() || out.wasClosed()) {127throw new AssertionError();128}129}130}131132private static void onReturnInputIsAtEnd() throws IOException {133try (Reader in = input(new char[]{1, 2, 3});134Writer out = output()) {135136in.transferTo(out);137138if (in.read() != -1) {139throw new AssertionError();140}141}142}143144private static void contents() throws IOException {145checkTransferredContents(new char[0]);146checkTransferredContents(createRandomChars(1024, 4096));147// to span through several batches148checkTransferredContents(createRandomChars(16384, 16384));149}150151private static void checkTransferredContents(char[] chars)152throws IOException {153try (Reader in = input(chars);154StringWriter out = new StringWriter()) {155in.transferTo(out);156157char[] outChars = out.toString().toCharArray();158if (!Arrays.equals(chars, outChars)) {159throw new AssertionError(160format("chars.length=%s, outChars.length=%s",161chars.length, outChars.length));162}163}164}165166private static char[] createRandomChars(int min, int maxRandomAdditive) {167char[] chars = new char[min + generator.nextInt(maxRandomAdditive)];168for (int index=0; index<chars.length; index++) {169chars[index] = (char)generator.nextInt();170}171return chars;172}173174private static Writer output() {175return output(-1);176}177178private static Writer output(int exceptionPosition) {179return new Writer() {180181int pos;182183@Override184public void write(int b) throws IOException {185if (pos++ == exceptionPosition)186throw new IOException();187}188189@Override190public void write(char[] chars, int off, int len) throws IOException {191for (int i=0; i<len; i++) {192write(chars[off + i]);193}194}195196@Override197public Writer append(CharSequence csq, int start, int end) throws IOException {198for (int i = start; i < end; i++) {199write(csq.charAt(i));200}201return this;202}203204@Override205public void flush() throws IOException {206}207208@Override209public void close() throws IOException {210}211};212}213214private static Reader input(char... chars) {215return input(-1, chars);216}217218private static Reader input(int exceptionPosition, char... chars) {219return new Reader() {220221int pos;222223@Override224public int read() throws IOException {225if (pos == exceptionPosition) {226throw new IOException();227}228229if (pos >= chars.length)230return -1;231return chars[pos++];232}233234@Override235public int read(char[] cbuf, int off, int len) throws IOException {236int c = read();237if (c == -1) {238return -1;239}240cbuf[off] = (char)c;241242int i = 1;243for (; i < len ; i++) {244c = read();245if (c == -1) {246break;247}248cbuf[off + i] = (char)c;249}250return i;251}252253@Override254public void close() throws IOException {255}256};257}258259private static class ThrowingReader extends Reader {260261boolean closed;262263@Override264public int read(char[] b, int off, int len) throws IOException {265throw new IOException();266}267268@Override269public void close() throws IOException {270if (!closed) {271closed = true;272throw new IOException();273}274}275@Override276public int read() throws IOException {277throw new IOException();278}279}280281private static class CloseLoggingReader extends FilterReader {282283boolean closed;284285CloseLoggingReader(Reader in) {286super(in);287}288289@Override290public void close() throws IOException {291closed = true;292super.close();293}294295boolean wasClosed() {296return closed;297}298}299300private static class CloseLoggingWriter extends FilterWriter {301302boolean closed;303304CloseLoggingWriter(Writer out) {305super(out);306}307308@Override309public void close() throws IOException {310closed = true;311super.close();312}313314boolean wasClosed() {315return closed;316}317}318319public interface Thrower {320public void run() throws Throwable;321}322323public static void assertThrowsNPE(Thrower thrower, String message) {324assertThrows(thrower, NullPointerException.class, message);325}326327public static <T extends Throwable> void assertThrows(Thrower thrower,328Class<T> throwable,329String message) {330Throwable thrown;331try {332thrower.run();333thrown = null;334} catch (Throwable caught) {335thrown = caught;336}337338if (!throwable.isInstance(thrown)) {339String caught = thrown == null ?340"nothing" : thrown.getClass().getCanonicalName();341throw new AssertionError(342format("Expected to catch %s, but caught %s",343throwable, caught), thrown);344}345346if (thrown != null && !message.equals(thrown.getMessage())) {347throw new AssertionError(348format("Expected exception message to be '%s', but it's '%s'",349message, thrown.getMessage()));350}351}352}353354355