/**
* Copyright 2015 Palantir Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.palantir.giraffe.file.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.Writer;
import java.nio.ByteBuffer;
import java.nio.channels.SeekableByteChannel;
import java.nio.charset.StandardCharsets;
import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import org.junit.Test;
import com.palantir.giraffe.file.test.creator.CrudTestCreator;
import com.palantir.giraffe.file.test.runner.FileSystemTestRule;
/**
* Tests a file system's implementation of create, read, update, and delete
* operations.
*
* @author jchien
*/
// TODO(bkeyes): should this class use the provider directly?
public final class FileSystemCRUDTest extends FileSystemBaseTest {
public FileSystemCRUDTest(FileSystemTestRule testSystem) {
super(testSystem);
}
@Test
public void createsDirectory() throws IOException {
Path dir = generateUnusedPath(getTestPath("create_directory"));
Files.createDirectory(dir);
assertTrue(msg(dir, "does not exist"), Files.exists(dir));
assertTrue(msg(dir, "is not a directory"), Files.isDirectory(dir));
}
@Test(expected = IOException.class)
public void createNestedDirectoryFails() throws IOException {
Path root = generateUnusedPath(getTestPath("missing_directory"));
Files.createDirectory(root.resolve("child"));
}
@Test
public void createsFile() throws IOException {
Path file = generateUnusedPath(getTestPath("create_file"));
Files.createFile(file);
assertTrue(msg(file, "does not exist"), Files.exists(file));
assertTrue(msg(file, "is not a file"), Files.isRegularFile(file));
}
@Test
public void deletesFile() throws IOException {
Path file = generateUnusedPath(getTestPath("delete_file"));
Files.createFile(file);
assertTrue(msg(file, "does not exist"), Files.exists(file));
Files.delete(file);
assertTrue(msg(file, "exists"), Files.notExists(file));
}
@Test(expected = NoSuchFileException.class)
public void deleteMissingFileFails() throws IOException {
Files.delete(getTestPath("not_exists.txt"));
}
@Test
public void deleteIfExistsMissingFile() throws IOException {
assertFalse("missing file deleted", Files.deleteIfExists(getTestPath("not_exists.txt")));
}
@Test
public void deletesEmptyDirectory() throws IOException {
Path dir = generateUnusedPath(getTestPath("delete_directory"));
Files.createDirectory(dir);
assertTrue(msg(dir, "is not directory"), Files.isDirectory(dir));
Files.delete(dir);
assertTrue(msg(dir, "exists"), Files.notExists(dir));
}
@Test(expected = DirectoryNotEmptyException.class)
public void deleteNonEmptyDirectoryFails() throws IOException {
Path root = generateUnusedPath(getTestPath("non_empty_directory"));
Files.createDirectory(root);
Files.createFile(root.resolve("child.txt"));
Files.delete(root);
}
@Test(expected = DirectoryNotEmptyException.class)
public void deleteIfExistsNonEmptyDirectoryFails() throws IOException {
Path root = generateUnusedPath(getTestPath("non_empty_directory"));
Files.createDirectory(root);
Files.createFile(root.resolve("child.txt"));
Files.deleteIfExists(root);
}
@Test
public void readsFile() throws IOException {
Path file = getTestPath(CrudTestCreator.F_RO_READ);
String actualData = read(file);
assertEquals(msg(file, " has wrong data"), CrudTestCreator.READ_DATA, actualData);
}
@Test(expected = NoSuchFileException.class)
public void readMissingFileFails() throws IOException {
OpenOption[] options = { StandardOpenOption.READ };
Files.newInputStream(generateUnusedPath(getTestPath("not_exists.txt")), options).close();
}
@Test
public void createsAndWritesFile() throws IOException {
Path file = generateUnusedPath(getTestPath("create_and_write.txt"));
String data = "I wrote this data";
write(file, data);
assertTrue(msg(file, "does not exist"), Files.exists(file));
String actualData = read(file);
assertEquals(msg(file, " has wrong data"), data, actualData);
}
@Test
public void createsDeleteOnClose() throws IOException {
OpenOption[] options = {
StandardOpenOption.WRITE,
StandardOpenOption.CREATE,
StandardOpenOption.DELETE_ON_CLOSE
};
Path file = generateUnusedPath(getTestPath("delete_on_close.txt"));
try (SeekableByteChannel ch = Files.newByteChannel(file, options)) {
assertTrue(msg(file, "does not exist"), Files.exists(file));
}
assertTrue(msg(file, "exists"), Files.notExists(file));
}
@Test(expected = FileAlreadyExistsException.class)
public void createNewWithExistingFails() throws IOException {
OpenOption[] options = { StandardOpenOption.WRITE, StandardOpenOption.CREATE_NEW };
Path file = getTestPath(CrudTestCreator.F_RO_READ);
Files.newByteChannel(file, options).close();
}
@Test
public void writeOverwrites() throws IOException {
OpenOption[] options = { StandardOpenOption.WRITE, StandardOpenOption.CREATE };
Path file = generateUnusedPath(getTestPath("overwrite.txt"));
String data = "HelloWorld";
write(file, data);
String moreData = "World";
try (BufferedWriter w = Files.newBufferedWriter(file, StandardCharsets.UTF_8, options)) {
w.write(moreData);
}
String actualData = read(file);
assertEquals(msg(file, " has wrong data"), "WorldWorld", actualData);
}
@Test
public void writeAppends() throws IOException {
OpenOption[] options = {
StandardOpenOption.WRITE,
StandardOpenOption.CREATE,
StandardOpenOption.APPEND
};
Path file = generateUnusedPath(getTestPath("append.txt"));
String data = "Hello";
write(file, data);
String appendData = "World";
try (BufferedWriter w = Files.newBufferedWriter(file, StandardCharsets.UTF_8, options)) {
w.write(appendData);
}
String actualData = read(file);
assertEquals(msg(file, " has wrong data"), data + appendData, actualData);
}
@Test
public void writeAppendsEmptyFile() throws IOException {
OpenOption[] options = {
StandardOpenOption.WRITE,
StandardOpenOption.CREATE,
StandardOpenOption.APPEND
};
String data = "Hello World";
Path file = generateUnusedPath(getTestPath("append_empty.txt"));
try (BufferedWriter w = Files.newBufferedWriter(file, StandardCharsets.UTF_8, options)) {
w.write(data);
}
String actualData = read(file);
assertEquals(msg(file, " has wrong data"), data, actualData);
}
@Test
public void writeTruncates() throws IOException {
OpenOption[] options = {
StandardOpenOption.WRITE,
StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING
};
Path file = generateUnusedPath(getTestPath("truncate.txt"));
String data = "HelloWorld";
write(file, data);
String moreData = "World";
try (BufferedWriter w = Files.newBufferedWriter(file, StandardCharsets.UTF_8, options)) {
w.write(moreData);
}
String actualData = read(file);
assertEquals(msg(file, " has wrong data"), moreData, actualData);
}
private static void write(Path file, String data) throws IOException {
try (Writer w = Files.newBufferedWriter(file, StandardCharsets.UTF_8)) {
w.write(data);
}
}
private static String read(Path file) throws IOException {
ByteBuffer bytes = ByteBuffer.wrap(Files.readAllBytes(file));
return StandardCharsets.UTF_8.decode(bytes).toString();
}
}