Merge branch 'develop' into feature/new-hub-keyloading

This commit is contained in:
Sebastian Stenzel
2023-07-28 15:23:00 +02:00
115 changed files with 2206 additions and 310 deletions
@@ -7,6 +7,7 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledIf;
import org.mockito.Mockito;
import java.nio.file.Path;
@@ -24,6 +25,7 @@ public class EnvironmentTest {
public void init() {
env = Mockito.spy(Environment.getInstance());
}
@Test
@DisplayName("cryptomator.logDir=/foo/bar")
public void testAbsoluteLogDir() {
@@ -58,8 +60,9 @@ public class EnvironmentTest {
}
@Test
@EnabledIf("isColonPathSeperator")
@DisplayName("test.path.property=/foo/bar/test:/bar/nez/tost")
public void testTwoPaths() {
public void testTwoPathsColon() {
System.setProperty("test.path.property", "/foo/bar/test:bar/nez/tost");
List<Path> result = env.getPaths("test.path.property").toList();
@@ -67,6 +70,25 @@ public class EnvironmentTest {
MatcherAssert.assertThat(result, Matchers.hasItems(Path.of("/foo/bar/test"), Path.of("bar/nez/tost")));
}
@Test
@EnabledIf("isSemiColonPathSeperator")
@DisplayName("test.path.property=/foo/bar/test;/bar/nez/tost")
public void testTwoPathsSemiColon() {
System.setProperty("test.path.property", "/foo/bar/test;bar/nez/tost");
List<Path> result = env.getPaths("test.path.property").toList();
MatcherAssert.assertThat(result, Matchers.hasSize(2));
MatcherAssert.assertThat(result, Matchers.hasItems(Path.of("/foo/bar/test"), Path.of("bar/nez/tost")));
}
boolean isColonPathSeperator() {
return System.getProperty("path.separator").equals(":");
}
boolean isSemiColonPathSeperator() {
return System.getProperty("path.separator").equals(";");
}
}
@Nested
@@ -78,18 +100,21 @@ public class EnvironmentTest {
env.getSettingsPath();
Mockito.verify(env).getPaths("cryptomator.settingsPath");
}
@Test
public void testP12Path() {
Mockito.doReturn(Stream.of()).when(env).getPaths(Mockito.anyString());
env.getP12Path();
Mockito.verify(env).getPaths("cryptomator.p12Path");
}
@Test
public void testIpcSocketPath() {
Mockito.doReturn(Stream.of()).when(env).getPaths(Mockito.anyString());
env.getIpcSocketPath();
Mockito.verify(env).getPaths("cryptomator.ipcSocketPath");
}
@Test
public void testKeychainPath() {
Mockito.doReturn(Stream.of()).when(env).getPaths(Mockito.anyString());
@@ -0,0 +1,241 @@
package org.cryptomator.common.mount;
import org.apache.commons.lang3.SystemUtils;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.junit.jupiter.api.io.TempDir;
import java.io.File;
import java.io.IOException;
import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Objects;
import static java.nio.file.LinkOption.NOFOLLOW_LINKS;
import static org.cryptomator.common.mount.MountWithinParentUtil.MountPointState.EMPTY_DIR;
import static org.cryptomator.common.mount.MountWithinParentUtil.MountPointState.NOT_EXISTING;
import static org.cryptomator.common.mount.MountWithinParentUtil.cleanup;
import static org.cryptomator.common.mount.MountWithinParentUtil.getHideaway;
import static org.cryptomator.common.mount.MountWithinParentUtil.getMountPointState;
import static org.cryptomator.common.mount.MountWithinParentUtil.prepareParentNoMountPoint;
import static org.cryptomator.common.mount.MountWithinParentUtil.removeResidualHideaway;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
class MountWithinParentUtilTest {
@Test
void testPrepareNeitherExist(@TempDir Path parentDir) {
assertThrows(MountPointNotExistingException.class, () -> {
prepareParentNoMountPoint(parentDir.resolve("mount"));
});
}
@Test
void testPrepareOnlyHideawayFileExists(@TempDir Path parentDir) throws IOException {
var mount = parentDir.resolve("mount");
var hideaway = getHideaway(mount);
Files.createFile(hideaway);
assertThrows(HideawayNotDirectoryException.class, () -> {
prepareParentNoMountPoint(mount);
});
}
@Test
void testPrepareOnlyHideawayDirExists(@TempDir Path parentDir) throws IOException {
var mount = parentDir.resolve("mount");
var hideaway = getHideaway(mount);
Files.createDirectory(hideaway);
assertFalse(isHidden(hideaway));
prepareParentNoMountPoint(mount);
assumeTrue(SystemUtils.IS_OS_WINDOWS);
assertTrue(isHidden(hideaway));
}
@Test
void testPrepareBothExistHideawayFile(@TempDir Path parentDir) throws IOException {
var mount = parentDir.resolve("mount");
var hideaway = getHideaway(mount);
Files.createFile(hideaway);
Files.createDirectory(mount);
assertThrows(HideawayNotDirectoryException.class, () -> {
prepareParentNoMountPoint(mount);
});
}
@Test
void testPrepareBothExistHideawayNotEmpty(@TempDir Path parentDir) throws IOException {
var mount = parentDir.resolve("mount");
var hideaway = getHideaway(mount);
Files.createDirectory(hideaway);
Files.createFile(hideaway.resolve("dummy"));
Files.createDirectory(mount);
assertThrows(DirectoryNotEmptyException.class, () -> {
prepareParentNoMountPoint(mount);
});
}
@Test
void testPrepareBothExistMountNotDir(@TempDir Path parentDir) throws IOException {
var mount = parentDir.resolve("mount");
var hideaway = getHideaway(mount);
Files.createFile(hideaway);
Files.createFile(mount);
assertThrows(MountPointNotEmptyDirectoryException.class, () -> {
prepareParentNoMountPoint(mount); //Must not throw something related to hideaway
});
assertTrue(Files.exists(hideaway, NOFOLLOW_LINKS));
}
@Test
void testPrepareBothExistMountNotEmpty(@TempDir Path parentDir) throws IOException {
var mount = parentDir.resolve("mount");
var hideaway = getHideaway(mount);
Files.createFile(hideaway);
Files.createDirectory(mount);
Files.createFile(mount.resolve("dummy"));
assertThrows(MountPointNotEmptyDirectoryException.class, () -> {
prepareParentNoMountPoint(mount); //Must not throw something related to hideaway
});
assertTrue(Files.exists(hideaway, NOFOLLOW_LINKS));
}
@Test
void testPrepareBothExist(@TempDir Path parentDir) throws IOException {
var mount = parentDir.resolve("mount");
var hideaway = getHideaway(mount);
Files.createDirectory(hideaway);
Files.createDirectory(mount);
prepareParentNoMountPoint(mount);
assertTrue(Files.notExists(mount, NOFOLLOW_LINKS));
assumeTrue(SystemUtils.IS_OS_WINDOWS);
assertTrue(isHidden(hideaway));
}
@Test
void testHandleMountPointFolderDoesNotExist(@TempDir Path parentDir) throws IOException {
assertSame(getMountPointState(parentDir.resolve("notExisting")), NOT_EXISTING);
}
@Test
void testHandleMountPointFolderIsFile(@TempDir Path parentDir) throws IOException {
var regularFile = parentDir.resolve("regularFile");
Files.createFile(regularFile);
assertThrows(MountPointNotEmptyDirectoryException.class, () -> {
getMountPointState(regularFile);
});
}
@Test
void testHandleMountPointFolderIsNotEmpty(@TempDir Path parentDir) throws IOException {
var regularFolder = parentDir.resolve("regularFolder");
var dummyFile = regularFolder.resolve("dummy");
Files.createDirectory(regularFolder);
Files.createFile(dummyFile);
assertThrows(MountPointNotEmptyDirectoryException.class, () -> {
getMountPointState(regularFolder);
});
}
@Test
void testHandleMountPointFolder(@TempDir Path parentDir) throws IOException {
//Sadly can't easily create files with "Other" attribute
var regularFolder = parentDir.resolve("regularFolder");
Files.createDirectory(regularFolder);
assertSame(getMountPointState(regularFolder), EMPTY_DIR);
}
@Test
void testRemoveResidualHideawayFile(@TempDir Path parentDir) throws IOException {
var hideaway = parentDir.resolve("hideaway");
Files.createFile(hideaway);
assertThrows(HideawayNotDirectoryException.class, () -> removeResidualHideaway(parentDir.resolve("mount"), hideaway));
}
@Test
void testRemoveResidualHideawayNotEmpty(@TempDir Path parentDir) throws IOException {
var hideaway = parentDir.resolve("hideaway");
Files.createDirectory(hideaway);
Files.createFile(hideaway.resolve("dummy"));
assertThrows(DirectoryNotEmptyException.class, () -> removeResidualHideaway(parentDir.resolve("mount"), hideaway));
}
@Test
void testCleanupNoHideaway(@TempDir Path parentDir) {
assertDoesNotThrow(() -> cleanup(parentDir.resolve("mount")));
}
@Test
void testCleanup(@TempDir Path parentDir) throws IOException {
var mount = parentDir.resolve("mount");
var hideaway = getHideaway(mount);
Files.createDirectory(hideaway);
cleanup(mount);
assertTrue(Files.exists(mount, NOFOLLOW_LINKS));
assertTrue(Files.notExists(hideaway, NOFOLLOW_LINKS));
assertFalse(isHidden(mount));
}
@Test
@EnabledOnOs(OS.WINDOWS)
void testGetHideawayRootDirWin() {
var mount = Path.of("C:\\mount");
var hideaway = getHideaway(mount);
assertEquals(mount.getParent(), hideaway.getParent());
assertEquals(mount.getParent().resolve(".~$mount.tmp"), hideaway);
assertEquals(mount.getParent().toAbsolutePath() + ".~$mount.tmp", hideaway.toAbsolutePath().toString());
}
@Test
@DisabledOnOs(OS.WINDOWS)
void testGetHideawayRootDirUnix() {
var mount = Path.of("/mount");
var hideaway = getHideaway(mount);
assertEquals(mount.getParent(), hideaway.getParent());
assertEquals(mount.getParent().resolve(".~$mount.tmp"), hideaway);
assertEquals(mount.getParent().toAbsolutePath() + ".~$mount.tmp", hideaway.toAbsolutePath().toString());
}
@Test
void testGetHideaway(@TempDir Path parentDir) {
var mount = parentDir.resolve("mount");
var hideaway = getHideaway(mount);
assertEquals(mount.getParent(), hideaway.getParent());
assertEquals(mount.getParent().resolve(".~$mount.tmp"), hideaway);
assertEquals(mount.getParent().toAbsolutePath() + File.separator + ".~$mount.tmp", hideaway.toAbsolutePath().toString());
}
private static boolean isHidden(Path path) throws IOException {
try {
return (boolean) Objects.requireNonNullElse(Files.getAttribute(path, "dos:hidden", NOFOLLOW_LINKS), false);
} catch (UnsupportedOperationException | IllegalMountPointException e) {
return false;
}
}
}