test/jdk/java/nio/channels/Channels/EncodingTest.java
changeset 48252 77b88d8f8380
equal deleted inserted replaced
48251:57148c79bd75 48252:77b88d8f8380
       
     1 /*
       
     2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 import java.io.ByteArrayOutputStream;
       
    25 import java.io.FileInputStream;
       
    26 import java.io.FileOutputStream;
       
    27 import java.io.IOException;
       
    28 import java.io.Reader;
       
    29 import java.io.Writer;
       
    30 import java.nio.channels.Channels;
       
    31 import java.nio.channels.ReadableByteChannel;
       
    32 import java.nio.channels.WritableByteChannel;
       
    33 import java.nio.charset.Charset;
       
    34 import java.nio.charset.MalformedInputException;
       
    35 import java.nio.charset.StandardCharsets;
       
    36 import java.nio.file.Paths;
       
    37 import org.testng.Assert;
       
    38 import org.testng.annotations.DataProvider;
       
    39 import org.testng.annotations.Test;
       
    40 
       
    41 /**
       
    42  * @test
       
    43  * @bug 8183743
       
    44  * @summary Test to verify the new overload method with Charset functions the same
       
    45  * as the existing method that takes a charset name.
       
    46  * @run testng EncodingTest
       
    47  */
       
    48 public class EncodingTest {
       
    49     static final int ITERATIONS = 2;
       
    50     public static final String CS_UTF8 = StandardCharsets.UTF_8.name();
       
    51     public static final String CS_ISO8859 = StandardCharsets.ISO_8859_1.name();
       
    52     static String USER_DIR = System.getProperty("user.dir", ".");
       
    53 
       
    54     // malformed input: a high surrogate without the low surrogate
       
    55     static char[] illChars = {
       
    56         '\u00fa', '\ud800'
       
    57     };
       
    58 
       
    59     static byte[] data = getData();
       
    60 
       
    61     static byte[] getData() {
       
    62         try {
       
    63             String str1 = "A string that contains ";
       
    64             String str2 = " , an invalid character for UTF-8.";
       
    65 
       
    66             ByteArrayOutputStream baos = new ByteArrayOutputStream();
       
    67             baos.write(str1.getBytes());
       
    68             baos.write(0xFA);
       
    69             baos.write(str2.getBytes());
       
    70             return baos.toByteArray();
       
    71         } catch (IOException ex) {
       
    72             return null; //shouldn't happen
       
    73         }
       
    74     }
       
    75 
       
    76     String testFile = Paths.get(USER_DIR, "channelsEncodingTest.txt").toString();
       
    77     String testIllegalInput = Paths.get(USER_DIR, "channelsIllegalInputTest.txt").toString();
       
    78     String testIllegalOutput = Paths.get(USER_DIR, "channelsIllegalOutputTest.txt").toString();
       
    79 
       
    80 
       
    81     /*
       
    82      * DataProvider for read and write test.
       
    83      * Writes and reads with the same encoding
       
    84      */
       
    85     @DataProvider(name = "writeAndRead")
       
    86     public Object[][] getWRParameters() {
       
    87         return new Object[][]{
       
    88             {testFile, StandardCharsets.ISO_8859_1.name(), null,
       
    89                 StandardCharsets.ISO_8859_1.name(), StandardCharsets.ISO_8859_1},
       
    90             {testFile, null, StandardCharsets.ISO_8859_1,
       
    91                 StandardCharsets.ISO_8859_1.name(), StandardCharsets.ISO_8859_1},
       
    92             {testFile, StandardCharsets.UTF_8.name(), null,
       
    93                 StandardCharsets.UTF_8.name(), StandardCharsets.UTF_8},
       
    94             {testFile, null, StandardCharsets.UTF_8,
       
    95                 StandardCharsets.UTF_8.name(), StandardCharsets.UTF_8}
       
    96         };
       
    97     }
       
    98 
       
    99     /*
       
   100      * DataProvider for illegal input test
       
   101      * Writes the data in ISO8859 and reads with UTF8, expects MalformedInputException
       
   102      */
       
   103     @DataProvider(name = "illegalInput")
       
   104     public Object[][] getParameters() {
       
   105         return new Object[][]{
       
   106             {testIllegalInput, StandardCharsets.ISO_8859_1.name(), null, StandardCharsets.UTF_8.name(), null},
       
   107             {testIllegalInput, StandardCharsets.ISO_8859_1.name(), null, null, StandardCharsets.UTF_8},
       
   108             {testIllegalInput, null, StandardCharsets.ISO_8859_1, StandardCharsets.UTF_8.name(), null},
       
   109             {testIllegalInput, null, StandardCharsets.ISO_8859_1, null, StandardCharsets.UTF_8},
       
   110         };
       
   111     }
       
   112 
       
   113     /*
       
   114      * DataProvider for illegal output test
       
   115      * Attemps to write some malformed chars, expects MalformedInputException
       
   116      */
       
   117     @DataProvider(name = "illegalOutput")
       
   118     public Object[][] getWriteParameters() {
       
   119         return new Object[][]{
       
   120             {testIllegalOutput, StandardCharsets.UTF_8.name(), null},
       
   121             {testIllegalOutput, null, StandardCharsets.UTF_8}
       
   122         };
       
   123     }
       
   124 
       
   125     /**
       
   126      * Verifies that the Readers created with the following methods are
       
   127      * equivalent:
       
   128      * newReader(ReadableByteChannel ch, String csName)
       
   129      * newReader(ReadableByteChannel ch, Charset charset)
       
   130      *
       
   131      * The verification follows the following steps:
       
   132      * Writes a file with a writer created with the specified charset
       
   133      * Reads it with a reader created with newReader using the same charset;
       
   134      * Compares that the results are the same.
       
   135      *
       
   136      * @param file the file name
       
   137      * @param csnWriter the charset name for creating the writer
       
   138      * @param charsetWriter the charset for creating the writer
       
   139      * @param csnReader the charset name for creating the reader
       
   140      * @param charsetReader the charset for creating the reader
       
   141      * @throws Exception
       
   142      */
       
   143     @Test(dataProvider = "writeAndRead")
       
   144     public void testWriteAndRead(String file, String csnWriter, Charset charsetWriter,
       
   145             String csnReader, Charset charsetReader) throws Exception {
       
   146         writeToFile(data, file, csnWriter, charsetWriter);
       
   147         // read using charset name
       
   148         String result1 = readFileToString(file, csnReader, null);
       
   149         String result2 = readFileToString(file, null, charsetReader);
       
   150 
       
   151         Assert.assertEquals(result1, result2);
       
   152     }
       
   153 
       
   154     /**
       
   155      * Verifies that MalformedInputException is thrown when an input byte sequence
       
   156      * is illegal for given charset that is configured for the reader.
       
   157      *
       
   158      * @param file the file to be read
       
   159      * @param csnWriter the charset name for creating the writer
       
   160      * @param charsetWriter the charset for creating the writer
       
   161      * @param csnReader the charset name for creating the reader
       
   162      * @param charsetReader the charset for creating the reader
       
   163      * @throws Exception
       
   164      */
       
   165     @Test(dataProvider = "illegalInput", expectedExceptions = MalformedInputException.class)
       
   166     void testMalformedInput(String file, String csnWriter, Charset charsetWriter,
       
   167             String csnReader, Charset charsetReader) throws Exception {
       
   168         writeToFile(data, file, csnWriter, charsetWriter);
       
   169         readFileToString(file, csnReader, charsetReader);
       
   170     }
       
   171 
       
   172     /**
       
   173      * Attempts to write illegal characters using a writer created by calling
       
   174      * the newWriter method and expects a MalformedInputException.
       
   175      *
       
   176      * @param fileName the file name
       
   177      * @param csn the charset name
       
   178      * @param charset the charset
       
   179      * @throws Exception
       
   180      */
       
   181     @Test(dataProvider = "illegalOutput", expectedExceptions = MalformedInputException.class)
       
   182     public void testMalformedOutput(String fileName, String csn, Charset charset)
       
   183             throws Exception {
       
   184         try (FileOutputStream fos = new FileOutputStream(fileName);
       
   185                 WritableByteChannel wbc = (WritableByteChannel) fos.getChannel();) {
       
   186             Writer writer;
       
   187             if (csn != null) {
       
   188                 writer = Channels.newWriter(wbc, csn);
       
   189             } else {
       
   190                 writer = Channels.newWriter(wbc, charset);
       
   191             }
       
   192 
       
   193             for (int i = 0; i < ITERATIONS; i++) {
       
   194                 writer.write(illChars);
       
   195             }
       
   196             writer.flush();
       
   197             writer.close();
       
   198         }
       
   199     }
       
   200 
       
   201     /**
       
   202      * Writes the data to a file using a writer created by calling the newWriter
       
   203      * method.
       
   204      *
       
   205      * @param data the data to be written
       
   206      * @param fileName the file name
       
   207      * @param csn the charset name
       
   208      * @param charset the charset
       
   209      * @throws Exception
       
   210      */
       
   211     private void writeToFile(byte[] data, String fileName, String csn, Charset charset) throws Exception {
       
   212         try (FileOutputStream fos = new FileOutputStream(fileName);
       
   213                 WritableByteChannel wbc = (WritableByteChannel) fos.getChannel()) {
       
   214             Writer writer;
       
   215             String temp;
       
   216             if (csn != null) {
       
   217                 writer = Channels.newWriter(wbc, csn);
       
   218                 temp = new String(data, csn);
       
   219             } else {
       
   220                 writer = Channels.newWriter(wbc, charset);
       
   221                 temp = new String(data, charset);
       
   222             }
       
   223 
       
   224             for (int i = 0; i < ITERATIONS; i++) {
       
   225                 writer.write(temp);
       
   226             }
       
   227             writer.flush();
       
   228             writer.close();
       
   229         }
       
   230     }
       
   231 
       
   232     /**
       
   233      * Reads a file into a String.
       
   234      *
       
   235      * @param file the file to be read
       
   236      * @param csn the charset name
       
   237      * @param charset the charset
       
   238      * @throws Exception
       
   239      */
       
   240     String readFileToString(String file, String csn, Charset charset) throws Exception {
       
   241         String result;
       
   242         try (FileInputStream fis = new FileInputStream(file);
       
   243                 ReadableByteChannel rbc = (ReadableByteChannel) fis.getChannel()) {
       
   244             Reader reader;
       
   245             if (csn != null) {
       
   246                 reader = Channels.newReader(rbc, csn);
       
   247             } else {
       
   248                 reader = Channels.newReader(rbc, charset);
       
   249             }
       
   250 
       
   251             int messageSize = data.length * ITERATIONS;
       
   252             char data1[] = new char[messageSize];
       
   253             int totalRead = 0;
       
   254             int charsRead = 0;
       
   255             while (totalRead < messageSize) {
       
   256                 totalRead += charsRead;
       
   257                 charsRead = reader.read(data1, totalRead, messageSize - totalRead);
       
   258             }
       
   259 
       
   260             result = new String(data1, 0, totalRead);
       
   261             reader.close();
       
   262         }
       
   263 
       
   264         return result;
       
   265     }
       
   266 }