1 /*
   2  * Copyright (c) 2011, 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 /* @test
  25  * @bug 7006126 8020669
  26  * @summary Unit test for methods for Files readAllBytes, readAllLines and
  27  *     and write methods.
  28  */
  29 
  30 import java.nio.file.*;
  31 import static java.nio.file.Files.*;
  32 import java.io.*;
  33 import java.util.*;
  34 import java.nio.charset.*;
  35 
  36 public class BytesAndLines {
  37     static final Random rand = new Random();
  38 
  39     static final Charset US_ASCII = Charset.forName("US-ASCII");
  40 
  41     public static void main(String[] args) throws IOException {
  42         testReadAndWriteBytes();
  43         testReadLines();
  44         testWriteLines();
  45     }
  46 
  47     /**
  48      * Test readAllBytes(Path) and write(Path, byte[], OpenOption...)
  49      */
  50     static void testReadAndWriteBytes() throws IOException {
  51         // exercise methods with various sizes
  52         testReadAndWriteBytes(0);
  53         for (int i=0; i<100; i++) {
  54             testReadAndWriteBytes(rand.nextInt(32000));
  55         }
  56 
  57         // NullPointerException
  58         Path file = Paths.get("foo");
  59         List<String> lines = Collections.emptyList();
  60         try {
  61             readAllBytes(null);
  62             throw new RuntimeException("NullPointerException expected");
  63         } catch (NullPointerException ignore) { }
  64         try {
  65             write(null, lines, Charset.defaultCharset());
  66             throw new RuntimeException("NullPointerException expected");
  67         } catch (NullPointerException ignore) { }
  68         try {
  69             write(file, null, Charset.defaultCharset());
  70             throw new RuntimeException("NullPointerException expected");
  71         } catch (NullPointerException ignore) { }
  72         try {
  73             write(file, lines, null);
  74             throw new RuntimeException("NullPointerException expected");
  75         } catch (NullPointerException ignore) { }
  76         try {
  77             write(file, lines, Charset.defaultCharset(), (OpenOption[])null);
  78             throw new RuntimeException("NullPointerException expected");
  79         } catch (NullPointerException ignore) { }
  80         try {
  81             OpenOption[] opts = { null };
  82             write(file, lines, Charset.defaultCharset(), opts);
  83             throw new RuntimeException("NullPointerException expected");
  84         } catch (NullPointerException ignore) { }
  85 
  86         // read from procfs
  87         if (System.getProperty("os.name").equals("Linux")) {
  88             // Refer to the Linux proc(5) man page for details about /proc/self/stat file
  89             // procfs reports it to be zero sized, even though data can be read from it
  90             String statFile = "/proc/self/stat";
  91             Path pathStat = Paths.get(statFile);
  92             byte[] data = Files.readAllBytes(pathStat);
  93             assertTrue(data.length > 0, "Files.readAllBytes('" + statFile + "') failed to read");
  94         }
  95     }
  96 
  97 
  98     static void testReadAndWriteBytes(int size) throws IOException {
  99         Path path = createTempFile("blah", null);
 100         try {
 101             boolean append = rand.nextBoolean();
 102 
 103             byte[] b1 = new byte[size];
 104             rand.nextBytes(b1);
 105 
 106             byte[] b2 = (append) ? new byte[size] : new byte[0];
 107             rand.nextBytes(b2);
 108 
 109             // write method should create file if it doesn't exist
 110             if (rand.nextBoolean())
 111                 delete(path);
 112 
 113             // write bytes to file
 114             Path target = write(path, b1);
 115             assertTrue(target==path, "Unexpected path");
 116             assertTrue(size(path) == b1.length, "Unexpected file size");
 117 
 118             // append bytes to file (might be 0 bytes)
 119             write(path, b2, StandardOpenOption.APPEND);
 120             assertTrue(size(path) == b1.length + b2.length, "Unexpected file size");
 121 
 122             // read entire file
 123             byte[] read = readAllBytes(path);
 124 
 125             // check bytes are correct
 126             byte[] expected;
 127             if (append) {
 128                 expected = new byte[b1.length + b2.length];
 129                 System.arraycopy(b1, 0, expected, 0, b1.length);
 130                 System.arraycopy(b2, 0, expected, b1.length, b2.length);
 131             } else {
 132                 expected = b1;
 133             }
 134             assertTrue(Arrays.equals(read, expected),
 135                        "Bytes read not the same as bytes written");
 136         } finally {
 137             deleteIfExists(path);
 138         }
 139     }
 140 
 141     /**
 142      * Test readAllLines(Path,Charset)
 143      */
 144     static void testReadLines() throws IOException {
 145         Path tmpfile = createTempFile("blah", "txt");
 146         try {
 147             List<String> lines;
 148 
 149             // zero lines
 150             assertTrue(size(tmpfile) == 0, "File should be empty");
 151             lines = readAllLines(tmpfile, US_ASCII);
 152             assertTrue(lines.isEmpty(), "No line expected");
 153 
 154             // one line
 155             byte[] hi = { (byte)'h', (byte)'i' };
 156             write(tmpfile, hi);
 157             lines = readAllLines(tmpfile, US_ASCII);
 158             assertTrue(lines.size() == 1, "One line expected");
 159             assertTrue(lines.get(0).equals("hi"), "'Hi' expected");
 160 
 161             // two lines using platform's line separator
 162             List<String> expected = Arrays.asList("hi", "there");
 163             write(tmpfile, expected, US_ASCII);
 164             assertTrue(size(tmpfile) > 0, "File is empty");
 165             lines = readAllLines(tmpfile, US_ASCII);
 166             assertTrue(lines.equals(expected), "Unexpected lines");
 167 
 168             // MalformedInputException
 169             byte[] bad = { (byte)0xff, (byte)0xff };
 170             write(tmpfile, bad);
 171             try {
 172                 readAllLines(tmpfile, US_ASCII);
 173                 throw new RuntimeException("MalformedInputException expected");
 174             } catch (MalformedInputException ignore) { }
 175 
 176 
 177             // NullPointerException
 178             try {
 179                 readAllLines(null, US_ASCII);
 180                 throw new RuntimeException("NullPointerException expected");
 181             } catch (NullPointerException ignore) { }
 182             try {
 183                 readAllLines(tmpfile, null);
 184                 throw new RuntimeException("NullPointerException expected");
 185             } catch (NullPointerException ignore) { }
 186 
 187             // read from procfs
 188             if (System.getProperty("os.name").equals("Linux")) {
 189                 // Refer to the Linux proc(5) man page for details about /proc/self/status file
 190                 // procfs reports this file to be zero sized, even though data can be read from it
 191                 String statusFile = "/proc/self/status";
 192                 Path pathStatus = Paths.get(statusFile);
 193                 lines = Files.readAllLines(pathStatus, US_ASCII);
 194                 assertTrue(lines.size() > 0, "Files.readAllLines('" + pathStatus + "') failed to read");
 195             }
 196 
 197         } finally {
 198             delete(tmpfile);
 199         }
 200     }
 201 
 202     /**
 203      * Test write(Path,Iterable<? extends CharSequence>,Charset,OpenOption...)
 204      */
 205     static void testWriteLines() throws IOException {
 206         Path tmpfile = createTempFile("blah", "txt");
 207         try {
 208             // write method should create file if it doesn't exist
 209             if (rand.nextBoolean())
 210                 delete(tmpfile);
 211 
 212             // zero lines
 213             Path result = write(tmpfile, Collections.<String>emptyList(), US_ASCII);
 214             assert(size(tmpfile) == 0);
 215             assert(result == tmpfile);
 216 
 217             // two lines
 218             List<String> lines = Arrays.asList("hi", "there");
 219             write(tmpfile, lines, US_ASCII);
 220             List<String> actual = readAllLines(tmpfile, US_ASCII);
 221             assertTrue(actual.equals(lines), "Unexpected lines");
 222 
 223             // append two lines
 224             write(tmpfile, lines, US_ASCII, StandardOpenOption.APPEND);
 225             List<String> expected = new ArrayList<String>();
 226             expected.addAll(lines);
 227             expected.addAll(lines);
 228             assertTrue(expected.size() == 4, "List should have 4 elements");
 229             actual = readAllLines(tmpfile, US_ASCII);
 230             assertTrue(actual.equals(expected), "Unexpected lines");
 231 
 232             // UnmappableCharacterException
 233             try {
 234                 String s = "\u00A0\u00A1";
 235                 write(tmpfile, Arrays.asList(s), US_ASCII);
 236                 throw new RuntimeException("UnmappableCharacterException expected");
 237             } catch (UnmappableCharacterException ignore) { }
 238 
 239             // NullPointerException
 240             try {
 241                 write(null, lines, US_ASCII);
 242                 throw new RuntimeException("NullPointerException expected");
 243             } catch (NullPointerException ignore) { }
 244             try {
 245                 write(tmpfile, null, US_ASCII);
 246                 throw new RuntimeException("NullPointerException expected");
 247             } catch (NullPointerException ignore) { }
 248             try {
 249                 write(tmpfile, lines, null);
 250                 throw new RuntimeException("NullPointerException expected");
 251             } catch (NullPointerException ignore) { }
 252             try {
 253                 write(tmpfile, lines, US_ASCII, (OpenOption[])null);
 254                 throw new RuntimeException("NullPointerException expected");
 255             } catch (NullPointerException ignore) { }
 256             try {
 257                 OpenOption[] opts = { (OpenOption)null };
 258                 write(tmpfile, lines, US_ASCII, opts);
 259                 throw new RuntimeException("NullPointerException expected");
 260             } catch (NullPointerException ignore) { }
 261 
 262         } finally {
 263             delete(tmpfile);
 264         }
 265     }
 266 
 267     static void assertTrue(boolean expr, String errmsg) {
 268         if (!expr)
 269             throw new RuntimeException(errmsg);
 270     }
 271 }