blob: 4c2a1e48d3f6c4c32c3cf08756273cbd65cad979 [file] [log] [blame]
/*
* Copyright 2014-present Facebook, 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.facebook.buck.testutil;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import com.facebook.buck.timing.SettableFakeClock;
import com.google.common.base.Charsets;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.io.CharStreams;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.attribute.PosixFilePermissions;
import java.util.List;
public class FakeProjectFilesystemTest {
@Test
public void testFilesystemReturnsAddedContents() throws IOException {
FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
filesystem.writeContentsToPath("Some content", Paths.get("A.txt"));
Optional<String> contents;
contents = filesystem.readFileIfItExists(Paths.get("A.txt"));
assertTrue("Fake file system must return added file contents.", contents.isPresent());
assertEquals("Some content", contents.get());
contents = filesystem.readFileIfItExists(Paths.get("B.txt"));
assertFalse(
"Fake file system must not return non-existing file contents",
contents.isPresent());
}
@Test
public void testReadLines() throws IOException {
FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
filesystem.writeContentsToPath("line one.\nline two.\n", Paths.get("A.txt"));
filesystem.writeLinesToPath(ImmutableList.<String>of(), Paths.get("B.txt"));
filesystem.writeContentsToPath("\n", Paths.get("C.txt"));
MoreAsserts.assertIterablesEquals(
ImmutableList.of("line one.", "line two."),
filesystem.readLines(Paths.get("A.txt")));
MoreAsserts.assertIterablesEquals(
ImmutableList.of(),
filesystem.readLines(Paths.get("B.txt")));
MoreAsserts.assertIterablesEquals(
ImmutableList.of(""),
filesystem.readLines(Paths.get("C.txt")));
MoreAsserts.assertIterablesEquals(
ImmutableList.of(),
filesystem.readLines(Paths.get("D.txt")));
}
@Test
public void testTouch() throws IOException {
FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
filesystem.touch(Paths.get("A.txt"));
filesystem.touch(Paths.get("A/B.txt"));
assertTrue(filesystem.exists(Paths.get("A.txt")));
assertTrue(filesystem.exists(Paths.get("A/B.txt")));
}
@Test
public void testWalkRelativeFileTree() throws IOException {
FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
filesystem.touch(Paths.get("root/A.txt"));
filesystem.touch(Paths.get("root/A/B/C.txt"));
filesystem.touch(Paths.get("root/A/B.txt"));
final List<Path> filesVisited = Lists.newArrayList();
FileVisitor<Path> fileVisitor = new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) {
filesVisited.add(path);
return FileVisitResult.CONTINUE;
}
};
filesystem.walkRelativeFileTree(Paths.get("root"), fileVisitor);
assertThat(filesVisited, containsInAnyOrder(
Paths.get("root/A.txt"),
Paths.get("root/A/B/C.txt"),
Paths.get("root/A/B.txt")));
filesVisited.clear();
filesystem.walkRelativeFileTree(Paths.get("root/A"), fileVisitor);
assertThat(
filesVisited, containsInAnyOrder(
Paths.get("root/A/B/C.txt"),
Paths.get("root/A/B.txt")));
}
@Test
public void testWalkRelativeFileTreeWhenPathIsAFile() throws IOException {
FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
filesystem.touch(Paths.get("A.txt"));
final List<Path> filesVisited = Lists.newArrayList();
FileVisitor<Path> fileVisitor = new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) {
filesVisited.add(path);
return FileVisitResult.CONTINUE;
}
};
filesystem.walkRelativeFileTree(Paths.get("A.txt"), fileVisitor);
// Despite the awkward name, "contains" implies an exact match.
assertThat(filesVisited, contains(Paths.get("A.txt")));
}
@Test
public void testNewFileInputStream() throws IOException {
FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
Path path = Paths.get("hello.txt");
filesystem.writeContentsToPath("hello world", path);
InputStreamReader reader = new InputStreamReader(
filesystem.newFileInputStream(path), Charsets.UTF_8);
String contents = CharStreams.toString(reader);
assertEquals("hello world", contents);
}
@Test
public void testAllExistingFileSystem() throws IOException {
AllExistingProjectFilesystem filesystem = new AllExistingProjectFilesystem();
assertTrue(filesystem.exists(Paths.get("somepath.txt")));
}
@Test
public void testWriteContentsWithDefaultFileAttributes() throws IOException {
FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
Path path = Paths.get("hello.txt");
filesystem.writeContentsToPath("hello world", path);
assertEquals(ImmutableSet.<FileAttribute<?>>of(), filesystem.getFileAttributesAtPath(path));
}
@Test
public void testWriteContentsWithSpecifiedFileAttributes() throws IOException {
FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
ImmutableSet<PosixFilePermission> permissions =
ImmutableSet.of(
PosixFilePermission.OWNER_READ,
PosixFilePermission.GROUP_READ,
PosixFilePermission.OTHERS_READ);
FileAttribute<?> attribute = PosixFilePermissions.asFileAttribute(permissions);
Path path = Paths.get("hello.txt");
filesystem.writeContentsToPath(
"hello world",
Paths.get("hello.txt"),
attribute);
assertEquals(ImmutableSet.of(attribute), filesystem.getFileAttributesAtPath(path));
}
@Test
public void testFileOutputStream() throws IOException {
FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
Path filePath = Paths.get("somefile.txt");
try (OutputStream stream = filesystem.newFileOutputStream(filePath)) {
stream.write("hello world".getBytes());
}
assertEquals("hello world", filesystem.readFileIfItExists(filePath).get());
}
@Test
public void testFlushThenCloseFileOutputStream() throws IOException {
FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
Path filePath = Paths.get("somefile.txt");
OutputStream stream = filesystem.newFileOutputStream(filePath);
stream.write("hello world".getBytes());
stream.flush();
stream.close();
assertEquals("hello world", filesystem.readFileIfItExists(filePath).get());
}
@Test
public void testSingleElementMkdirsExists() throws IOException {
FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
filesystem.mkdirs(Paths.get("foo"));
assertTrue(filesystem.isDirectory(Paths.get("foo")));
assertFalse(filesystem.isDirectory(Paths.get("foo/bar")));
}
@Test
public void testEachElementOfMkdirsExists() throws IOException {
FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
filesystem.mkdirs(Paths.get("foo/bar/baz"));
assertTrue(filesystem.isDirectory(Paths.get("foo")));
assertTrue(filesystem.isDirectory(Paths.get("foo/bar")));
assertTrue(filesystem.isDirectory(Paths.get("foo/bar/baz")));
assertFalse(filesystem.isDirectory(Paths.get("foo/bar/baz/blech")));
}
@Test
public void testDirectoryDoesNotExistAfterRmdir() throws IOException {
FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
filesystem.mkdirs(Paths.get("foo"));
filesystem.rmdir(Paths.get("foo"));
assertFalse(filesystem.isDirectory(Paths.get("foo")));
}
@Test
public void testDirectoryExistsIfIsDirectory() throws IOException {
FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
filesystem.mkdirs(Paths.get("foo"));
assertTrue(filesystem.isDirectory(Paths.get("foo")));
assertTrue(filesystem.exists(Paths.get("foo")));
}
@Test
public void testIsFileAfterTouch() throws IOException {
FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
filesystem.touch(Paths.get("foo"));
assertFalse(filesystem.isDirectory(Paths.get("foo")));
assertTrue(filesystem.isFile(Paths.get("foo")));
assertTrue(filesystem.exists(Paths.get("foo")));
}
@Test(expected = NoSuchFileException.class)
public void fileModifiedTimeThrowsIfDoesNotExist() throws IOException {
FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
filesystem.getLastModifiedTime(Paths.get("foo"));
}
@Test
public void fileModifiedTimeIsSetOnInitialWrite() throws IOException {
SettableFakeClock clock = new SettableFakeClock(49152, 0);
FakeProjectFilesystem filesystem = new FakeProjectFilesystem(clock);
filesystem.touch(Paths.get("foo"));
assertEquals(filesystem.getLastModifiedTime(Paths.get("foo")), 49152);
}
@Test
public void fileModifiedTimeIsUpdatedOnSubsequentWrite() throws IOException {
SettableFakeClock clock = new SettableFakeClock(49152, 0);
FakeProjectFilesystem filesystem = new FakeProjectFilesystem(clock);
filesystem.touch(Paths.get("foo"));
clock.setCurrentTimeMillis(64738);
filesystem.touch(Paths.get("foo"));
assertEquals(filesystem.getLastModifiedTime(Paths.get("foo")), 64738);
}
@Test
public void fileModifiedTimeIsSetOnMkdirs() throws IOException {
SettableFakeClock clock = new SettableFakeClock(49152, 0);
FakeProjectFilesystem filesystem = new FakeProjectFilesystem(clock);
filesystem.mkdirs(Paths.get("foo/bar/baz"));
assertEquals(filesystem.getLastModifiedTime(Paths.get("foo")), 49152);
assertEquals(filesystem.getLastModifiedTime(Paths.get("foo/bar")), 49152);
assertEquals(filesystem.getLastModifiedTime(Paths.get("foo/bar/baz")), 49152);
}
@Test
public void testWritingAFileAddsParentDirectories() throws IOException {
FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
filesystem.writeContentsToPath("hello", Paths.get("test/one/two/three.txt"));
assertTrue(filesystem.exists(Paths.get("test/one/two")));
assertTrue(filesystem.exists(Paths.get("test/one")));
assertTrue(filesystem.exists(Paths.get("test")));
}
@Test
public void testIsSymLinkReturnsTrueForSymLink() throws IOException {
FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
filesystem.createSymLink(Paths.get("foo"), Paths.get("bar"), false);
assertTrue(filesystem.isSymLink(Paths.get("foo")));
}
@Test
public void testIsSymLinkReturnsFalseForFile() throws IOException {
FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
filesystem.touch(Paths.get("foo"));
assertFalse(filesystem.isSymLink(Paths.get("foo")));
}
@Test
public void testIsSymLinkReturnsFalseForNotExistent() throws IOException {
FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
assertFalse(filesystem.isSymLink(Paths.get("foo")));
}
@Test
public void testSortedDirectoryContents() throws IOException {
SettableFakeClock clock = new SettableFakeClock(1000, 0);
FakeProjectFilesystem filesystem = new FakeProjectFilesystem(clock);
filesystem.mkdirs(Paths.get("foo"));
Path a = Paths.get("foo/a.txt");
filesystem.touch(a);
clock.setCurrentTimeMillis(2000);
Path b = Paths.get("foo/b.txt");
filesystem.touch(b);
clock.setCurrentTimeMillis(3000);
Path c = Paths.get("foo/c.txt");
filesystem.touch(c);
filesystem.touch(Paths.get("foo/non-matching"));
assertEquals(
ImmutableSet.of(c, b, a),
filesystem.getSortedMatchingDirectoryContents(
Paths.get("foo"),
"*.txt"));
}
@Test
public void testGetFilesUnderPath() throws IOException {
FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
Path bar = Paths.get("foo/bar.txt");
Path baz = Paths.get("foo/baz/blech.txt");
filesystem.touch(bar);
filesystem.touch(baz);
assertEquals(
ImmutableSet.of(bar, baz),
filesystem.getFilesUnderPath(Paths.get("foo")));
}
}