| /* |
| * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| /* @test |
| * @bug 7006126 8020669 8024788 8019526 |
| * @build BytesAndLines PassThroughFileSystem |
| * @run testng BytesAndLines |
| * @summary Unit test for methods for Files readAllBytes, readAllLines and |
| * and write methods. |
| * @key randomness |
| */ |
| |
| import java.nio.ByteBuffer; |
| import java.nio.CharBuffer; |
| import java.nio.file.Files; |
| import java.nio.file.Path; |
| import java.nio.file.Paths; |
| import java.nio.file.OpenOption; |
| import static java.nio.file.StandardOpenOption.*; |
| import java.nio.charset.Charset; |
| import java.nio.charset.CharacterCodingException; |
| import java.nio.charset.MalformedInputException; |
| import java.nio.charset.UnmappableCharacterException; |
| import static java.nio.charset.StandardCharsets.*; |
| import java.util.Arrays; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.List; |
| import java.util.Random; |
| import java.util.concurrent.Callable; |
| import java.io.IOException; |
| |
| import org.testng.annotations.AfterClass; |
| import org.testng.annotations.BeforeClass; |
| import org.testng.annotations.Test; |
| import static org.testng.Assert.*; |
| |
| @Test(groups = "unit") |
| public class BytesAndLines { |
| |
| // data for text files |
| private static final String EN_STRING = "The quick brown fox jumps over the lazy dog"; |
| private static final String JA_STRING = "\u65e5\u672c\u8a9e\u6587\u5b57\u5217"; |
| |
| // used for random byte content |
| private static Random RAND = new Random(); |
| |
| // file used by most tests |
| private Path tmpfile; |
| |
| @BeforeClass |
| void setup() throws IOException { |
| tmpfile = Files.createTempFile("blah", null); |
| } |
| |
| @AfterClass |
| void cleanup() throws IOException { |
| Files.deleteIfExists(tmpfile); |
| } |
| |
| /** |
| * Returns a byte[] of the given size with random content |
| */ |
| private byte[] genBytes(int size) { |
| byte[] arr = new byte[size]; |
| RAND.nextBytes(arr); |
| return arr; |
| } |
| |
| /** |
| * Exercise NullPointerException |
| */ |
| public void testNulls() { |
| Path file = Paths.get("foo"); |
| byte[] bytes = new byte[100]; |
| List<String> lines = Collections.emptyList(); |
| |
| checkNullPointerException(() -> Files.readAllBytes(null)); |
| |
| checkNullPointerException(() -> Files.write(null, bytes)); |
| checkNullPointerException(() -> Files.write(file, (byte[])null)); |
| checkNullPointerException(() -> Files.write(file, bytes, (OpenOption[])null)); |
| checkNullPointerException(() -> Files.write(file, bytes, new OpenOption[] { null } )); |
| |
| checkNullPointerException(() -> Files.readAllLines(null)); |
| checkNullPointerException(() -> Files.readAllLines(file, (Charset)null)); |
| checkNullPointerException(() -> Files.readAllLines(null, Charset.defaultCharset())); |
| |
| checkNullPointerException(() -> Files.write(null, lines)); |
| checkNullPointerException(() -> Files.write(file, (List<String>)null)); |
| checkNullPointerException(() -> Files.write(file, lines, (OpenOption[])null)); |
| checkNullPointerException(() -> Files.write(file, lines, new OpenOption[] { null } )); |
| checkNullPointerException(() -> Files.write(null, lines, Charset.defaultCharset())); |
| checkNullPointerException(() -> Files.write(file, null, Charset.defaultCharset())); |
| checkNullPointerException(() -> Files.write(file, lines, (Charset)null)); |
| checkNullPointerException(() -> Files.write(file, lines, Charset.defaultCharset(), (OpenOption[])null)); |
| checkNullPointerException(() -> Files.write(file, lines, Charset.defaultCharset(), new OpenOption[] { null } )); |
| } |
| |
| private void checkNullPointerException(Callable<?> c) { |
| try { |
| c.call(); |
| fail("NullPointerException expected"); |
| } catch (NullPointerException ignore) { |
| } catch (Exception e) { |
| fail(e + " not expected"); |
| } |
| } |
| |
| /** |
| * Exercise Files.readAllBytes(Path) on varied file sizes |
| */ |
| public void testReadAllBytes() throws IOException { |
| int size = 0; |
| while (size <= 16*1024) { |
| testReadAllBytes(size); |
| size += 512; |
| } |
| } |
| |
| private void testReadAllBytes(int size) throws IOException { |
| // write bytes to file (random content) |
| byte[] expected = genBytes(size); |
| Files.write(tmpfile, expected); |
| |
| // check expected bytes are read |
| byte[] read = Files.readAllBytes(tmpfile); |
| assertTrue(Arrays.equals(read, expected), "Bytes read not the same as written"); |
| } |
| |
| /** |
| * Linux specific test to exercise Files.readAllBytes on /proc. This is |
| * special because file sizes are reported as 0 even though the file |
| * has content. |
| */ |
| public void testReadAllBytesOnProcFS() throws IOException { |
| // read from procfs |
| if (System.getProperty("os.name").equals("Linux")) { |
| Path statFile = Paths.get("/proc/self/stat"); |
| byte[] data = Files.readAllBytes(statFile); |
| assertTrue(data.length > 0, "Files.readAllBytes('" + statFile + "') failed to read"); |
| } |
| } |
| |
| /** |
| * Exercise Files.readAllBytes(Path) on custom file system. This is special |
| * because readAllBytes was originally implemented to use FileChannel |
| * and so may not be supported by custom file system providers. |
| */ |
| public void testReadAllBytesOnCustomFS() throws IOException { |
| Path myfile = PassThroughFileSystem.create().getPath("myfile"); |
| try { |
| int size = 0; |
| while (size <= 1024) { |
| byte[] b1 = genBytes(size); |
| Files.write(myfile, b1); |
| byte[] b2 = Files.readAllBytes(myfile); |
| assertTrue(Arrays.equals(b1, b2), "bytes not equal"); |
| size += 512; |
| } |
| } finally { |
| Files.deleteIfExists(myfile); |
| } |
| } |
| |
| /** |
| * Exercise Files.write(Path, byte[], OpenOption...) on various sizes |
| */ |
| public void testWriteBytes() throws IOException { |
| int size = 0; |
| while (size < 16*1024) { |
| testWriteBytes(size, false); |
| testWriteBytes(size, true); |
| size += 512; |
| } |
| } |
| |
| private void testWriteBytes(int size, boolean append) throws IOException { |
| byte[] bytes = genBytes(size); |
| Path result = Files.write(tmpfile, bytes); |
| assertTrue(result == tmpfile); |
| if (append) { |
| Files.write(tmpfile, bytes, APPEND); |
| assertTrue(Files.size(tmpfile) == size*2); |
| } |
| |
| byte[] expected; |
| if (append) { |
| expected = new byte[size << 1]; |
| System.arraycopy(bytes, 0, expected, 0, bytes.length); |
| System.arraycopy(bytes, 0, expected, bytes.length, bytes.length); |
| } else { |
| expected = bytes; |
| } |
| |
| byte[] read = Files.readAllBytes(tmpfile); |
| assertTrue(Arrays.equals(read, expected), "Bytes read not the same as written"); |
| } |
| |
| /** |
| * Exercise Files.readAllLines(Path, Charset) |
| */ |
| public void testReadAllLines() throws IOException { |
| // zero lines |
| Files.write(tmpfile, new byte[0]); |
| List<String> lines = Files.readAllLines(tmpfile, US_ASCII); |
| assertTrue(lines.isEmpty(), "No line expected"); |
| |
| // one line |
| byte[] hi = { (byte)'h', (byte)'i' }; |
| Files.write(tmpfile, hi); |
| lines = Files.readAllLines(tmpfile, US_ASCII); |
| assertTrue(lines.size() == 1, "One line expected"); |
| assertTrue(lines.get(0).equals("hi"), "'Hi' expected"); |
| |
| // two lines using platform's line separator |
| List<String> expected = Arrays.asList("hi", "there"); |
| Files.write(tmpfile, expected, US_ASCII); |
| assertTrue(Files.size(tmpfile) > 0, "File is empty"); |
| lines = Files.readAllLines(tmpfile, US_ASCII); |
| assertTrue(lines.equals(expected), "Unexpected lines"); |
| |
| // MalformedInputException |
| byte[] bad = { (byte)0xff, (byte)0xff }; |
| Files.write(tmpfile, bad); |
| try { |
| Files.readAllLines(tmpfile, US_ASCII); |
| fail("MalformedInputException expected"); |
| } catch (MalformedInputException ignore) { } |
| } |
| |
| /** |
| * Linux specific test to exercise Files.readAllLines(Path) on /proc. This |
| * is special because file sizes are reported as 0 even though the file |
| * has content. |
| */ |
| public void testReadAllLinesOnProcFS() throws IOException { |
| if (System.getProperty("os.name").equals("Linux")) { |
| Path statFile = Paths.get("/proc/self/stat"); |
| List<String> lines = Files.readAllLines(statFile); |
| assertTrue(lines.size() > 0, "Files.readAllLines('" + statFile + "') failed to read"); |
| } |
| } |
| |
| /** |
| * Exercise Files.readAllLines(Path) |
| */ |
| public void testReadAllLinesUTF8() throws IOException { |
| Files.write(tmpfile, encodeAsUTF8(EN_STRING + "\n" + JA_STRING)); |
| |
| List<String> lines = Files.readAllLines(tmpfile); |
| assertTrue(lines.size() == 2, "Read " + lines.size() + " lines instead of 2"); |
| assertTrue(lines.get(0).equals(EN_STRING)); |
| assertTrue(lines.get(1).equals(JA_STRING)); |
| |
| // a sample of malformed sequences |
| testReadAllLinesMalformedUTF8((byte)0xFF); // one-byte sequence |
| testReadAllLinesMalformedUTF8((byte)0xC0, (byte)0x80); // invalid first byte |
| testReadAllLinesMalformedUTF8((byte)0xC2, (byte)0x00); // invalid second byte |
| } |
| |
| private byte[] encodeAsUTF8(String s) throws CharacterCodingException { |
| // not using s.getBytes here so as to catch unmappable characters |
| ByteBuffer bb = UTF_8.newEncoder().encode(CharBuffer.wrap(s)); |
| byte[] result = new byte[bb.limit()]; |
| bb.get(result); |
| assertTrue(bb.remaining() == 0); |
| return result; |
| } |
| |
| private void testReadAllLinesMalformedUTF8(byte... bytes) throws IOException { |
| Files.write(tmpfile, bytes); |
| try { |
| Files.readAllLines(tmpfile); |
| fail("MalformedInputException expected"); |
| } catch (MalformedInputException ignore) { } |
| } |
| |
| /** |
| * Exercise Files.write(Path, Iterable<? extends CharSequence>, Charset, OpenOption...) |
| */ |
| public void testWriteLines() throws IOException { |
| // zero lines |
| Path result = Files.write(tmpfile, Collections.<String>emptyList(), US_ASCII); |
| assert(Files.size(tmpfile) == 0); |
| assert(result == tmpfile); |
| |
| // two lines |
| List<String> lines = Arrays.asList("hi", "there"); |
| Files.write(tmpfile, lines, US_ASCII); |
| List<String> actual = Files.readAllLines(tmpfile, US_ASCII); |
| assertTrue(actual.equals(lines), "Unexpected lines"); |
| |
| // append two lines |
| Files.write(tmpfile, lines, US_ASCII, APPEND); |
| List<String> expected = new ArrayList<>(); |
| expected.addAll(lines); |
| expected.addAll(lines); |
| assertTrue(expected.size() == 4, "List should have 4 elements"); |
| actual = Files.readAllLines(tmpfile, US_ASCII); |
| assertTrue(actual.equals(expected), "Unexpected lines"); |
| |
| // UnmappableCharacterException |
| try { |
| String s = "\u00A0\u00A1"; |
| Files.write(tmpfile, Arrays.asList(s), US_ASCII); |
| fail("UnmappableCharacterException expected"); |
| } catch (UnmappableCharacterException ignore) { } |
| } |
| |
| /** |
| * Exercise Files.write(Path, Iterable<? extends CharSequence>, OpenOption...) |
| */ |
| public void testWriteLinesUTF8() throws IOException { |
| List<String> lines = Arrays.asList(EN_STRING, JA_STRING); |
| Files.write(tmpfile, lines); |
| List<String> actual = Files.readAllLines(tmpfile, UTF_8); |
| assertTrue(actual.equals(lines), "Unexpected lines"); |
| } |
| } |