package com.github.marschall.memoryfilesystem;
import static com.github.marschall.memoryfilesystem.FileContentsMatcher.hasContents;
import static com.github.marschall.memoryfilesystem.FileExistsMatcher.exists;
import static com.github.marschall.memoryfilesystem.FileUtility.setContents;
import static com.github.marschall.memoryfilesystem.IsSameFileMatcher.isSameFile;
import static java.nio.charset.StandardCharsets.US_ASCII;
import static java.nio.file.StandardOpenOption.APPEND;
import static java.nio.file.StandardOpenOption.DELETE_ON_CLOSE;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import java.nio.file.FileSystem;
import java.nio.file.FileSystemException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.junit.Rule;
import org.junit.Test;
public class MemoryHardLinkTest {
private static final Date A_TIME;
private static final Date C_TIME;
private static final Date M_TIME;
static {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
dateFormat.setLenient(false);
try {
C_TIME = dateFormat.parse("1997-08-04 02:04:00 EST");
M_TIME = dateFormat.parse("2004-07-25 18:18:00 EST");
A_TIME = dateFormat.parse("2001-04-21 12:00:00 EST");
} catch (ParseException e) {
throw new RuntimeException("could not parse date");
}
}
@Rule
public final FileSystemRule rule = new FileSystemRule();
@Test
public void sameConents() throws IOException {
FileSystem fileSystem = this.rule.getFileSystem();
Path target = Files.createFile(fileSystem.getPath("target"));
String initialContents = "initial";
setContents(target, initialContents);
Path link = Files.createLink(fileSystem.getPath("link"), target);
assertThat(target, hasContents(initialContents));
assertThat(link, hasContents(initialContents));
assertThat(target, isSameFile(link));
assertThat(link, isSameFile(target));
try (Writer writer = Files.newBufferedWriter(link, US_ASCII, APPEND)) {
writer.write(" first");
}
try (Writer writer = Files.newBufferedWriter(target, US_ASCII, APPEND)) {
writer.write(" second");
}
String expected = "initial first second";
assertThat(target, hasContents(expected));
assertThat(link, hasContents(expected));
}
@Test
public void explicitDeletePreserves() throws IOException {
FileSystem fileSystem = this.rule.getFileSystem();
Path target = Files.createFile(fileSystem.getPath("target"));
String initialContents = "initial";
setContents(target, initialContents);
Path link = Files.createLink(fileSystem.getPath("link"), target);
Files.delete(target);
assertThat(target, not(exists()));
assertThat(link, exists());
assertThat(link, hasContents(initialContents));
}
@Test
public void implicitDeletePreserves() throws IOException {
FileSystem fileSystem = this.rule.getFileSystem();
Path target = Files.createFile(fileSystem.getPath("target"));
String initialContents = "initial";
setContents(target, initialContents);
Path link = Files.createLink(fileSystem.getPath("link"), target);
try (OutputStream outputStream = Files.newOutputStream(target, DELETE_ON_CLOSE)) {
// nothing
}
assertThat(target, not(exists()));
assertThat(link, exists());
assertThat(link, hasContents(initialContents));
}
@Test
public void noLinksOnDirectories() throws IOException {
FileSystem fileSystem = this.rule.getFileSystem();
Path target = Files.createDirectory(fileSystem.getPath("target"));
Path link = fileSystem.getPath("link");
try {
Files.createLink(link, target);
fail("hard links on directories not supported");
} catch (FileSystemException e) {
assertEquals(link.toString(), e.getFile());
assertEquals(target.toString(), e.getOtherFile());
}
}
@Test
public void sameAttributes() throws IOException {
FileSystem fileSystem = this.rule.getFileSystem();
Path target = Files.createFile(fileSystem.getPath("target"));
Path link = Files.createLink(fileSystem.getPath("link"), target);
BasicFileAttributeView view = Files.getFileAttributeView(target, BasicFileAttributeView.class);
FileTime mTime = FileTime.fromMillis(M_TIME.getTime());
FileTime aTime = FileTime.fromMillis(A_TIME.getTime());
FileTime cTime = FileTime.fromMillis(C_TIME.getTime());
view.setTimes(mTime, aTime, cTime);
BasicFileAttributes attributes = Files.getFileAttributeView(link, BasicFileAttributeView.class).readAttributes();
assertEquals(mTime, attributes.lastModifiedTime());
assertEquals(aTime, attributes.lastAccessTime());
assertEquals(cTime, attributes.creationTime());
}
}