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