From 3f44d9bb66340b3210ccdbe99b3fdfd1a129806a Mon Sep 17 00:00:00 2001 From: Markus Kreusch Date: Wed, 6 Jan 2016 01:49:15 +0100 Subject: [PATCH] Added project filesystem-invariants-tests * Implemented some tests to be run on multiple implementations to demonstrate how such tests can be implemented * Detected problems with CryptoFileSystem(NioFileSystem) * Made CryptoFileSystem and CryptorImpl public / constructible from other packages --- .../crypto/engine/impl/CryptorImpl.java | 2 +- .../filesystem/crypto/CryptoFileSystem.java | 2 +- main/filesystem-invariants-tests/.gitignore | 1 + main/filesystem-invariants-tests/pom.xml | 53 +++++++++++ .../invariants/FileSystemFactories.java | 78 ++++++++++++++++ .../invariants/FileSystemTests.java | 91 +++++++++++++++++++ main/pom.xml | 1 + 7 files changed, 226 insertions(+), 2 deletions(-) create mode 100644 main/filesystem-invariants-tests/.gitignore create mode 100644 main/filesystem-invariants-tests/pom.xml create mode 100644 main/filesystem-invariants-tests/src/test/java/org/cryptomator/filesystem/invariants/FileSystemFactories.java create mode 100644 main/filesystem-invariants-tests/src/test/java/org/cryptomator/filesystem/invariants/FileSystemTests.java diff --git a/main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/impl/CryptorImpl.java b/main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/impl/CryptorImpl.java index 17b0a721e..64062b8f2 100644 --- a/main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/impl/CryptorImpl.java +++ b/main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/impl/CryptorImpl.java @@ -43,7 +43,7 @@ public class CryptorImpl implements Cryptor { private final AtomicReference fileContentCryptor = new AtomicReference<>(); private final SecureRandom randomSource; - CryptorImpl(SecureRandom randomSource) { + public CryptorImpl(SecureRandom randomSource) { this.randomSource = randomSource; } diff --git a/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/CryptoFileSystem.java b/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/CryptoFileSystem.java index 779d860b2..b19555e20 100644 --- a/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/CryptoFileSystem.java +++ b/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/CryptoFileSystem.java @@ -19,7 +19,7 @@ import org.cryptomator.filesystem.Folder; import org.cryptomator.filesystem.ReadableFile; import org.cryptomator.filesystem.WritableFile; -class CryptoFileSystem extends CryptoFolder implements FileSystem { +public class CryptoFileSystem extends CryptoFolder implements FileSystem { private static final String DATA_ROOT_DIR = "d"; private static final String ROOT_DIR_FILE = "root"; diff --git a/main/filesystem-invariants-tests/.gitignore b/main/filesystem-invariants-tests/.gitignore new file mode 100644 index 000000000..a6f89c2da --- /dev/null +++ b/main/filesystem-invariants-tests/.gitignore @@ -0,0 +1 @@ +/target/ \ No newline at end of file diff --git a/main/filesystem-invariants-tests/pom.xml b/main/filesystem-invariants-tests/pom.xml new file mode 100644 index 000000000..95d6fb829 --- /dev/null +++ b/main/filesystem-invariants-tests/pom.xml @@ -0,0 +1,53 @@ + + + + 4.0.0 + + org.cryptomator + main + 0.11.0-SNAPSHOT + + filesystem-invariants-tests + Cryptomator filesystem invariants tests + Test only project which checks invariants of FileSystem implementations + + + + org.cryptomator + filesystem-api + + + org.cryptomator + filesystem-crypto + + + org.cryptomator + filesystem-inmemory + + + org.cryptomator + filesystem-nameshortening + + + org.cryptomator + filesystem-nio + + + org.cryptomator + commons-test + + + + + + + org.jacoco + jacoco-maven-plugin + + + + \ No newline at end of file diff --git a/main/filesystem-invariants-tests/src/test/java/org/cryptomator/filesystem/invariants/FileSystemFactories.java b/main/filesystem-invariants-tests/src/test/java/org/cryptomator/filesystem/invariants/FileSystemFactories.java new file mode 100644 index 000000000..6963bd784 --- /dev/null +++ b/main/filesystem-invariants-tests/src/test/java/org/cryptomator/filesystem/invariants/FileSystemFactories.java @@ -0,0 +1,78 @@ +package org.cryptomator.filesystem.invariants; + +import static java.nio.file.Files.createTempDirectory; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import org.cryptomator.crypto.engine.impl.CryptorImpl; +import org.cryptomator.filesystem.FileSystem; +import org.cryptomator.filesystem.crypto.CryptoFileSystem; +import org.cryptomator.filesystem.inmem.InMemoryFileSystem; +import org.cryptomator.filesystem.nio.NioFileSystem; + +import com.google.common.base.Supplier; + +class FileSystemFactories implements Iterable> { + + private static final SecureRandom RANDOM_MOCK = new SecureRandom() { + @Override + public void nextBytes(byte[] bytes) { + Arrays.fill(bytes, (byte) 0x00); + } + }; + + private final List> factories = new ArrayList<>(); + + public FileSystemFactories() { + add("NioFileSystem", this::createNioFileSystem); + add("InMemoryFileSystem", this::createInMemoryFileSystem); + add("CryptoFileSystem(InMemoryFileSystem)", this::createCryptoFileSystemInMemory); + // FIXME fails add("CryptoFileSystem(NioFileSystem)", this::createCryptoFileSystemNio); + } + + private FileSystem createNioFileSystem() { + try { + return NioFileSystem.rootedAt(createTempDirectory("fileSystemToTest")); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + private FileSystem createInMemoryFileSystem() { + return new InMemoryFileSystem(); + } + + private FileSystem createCryptoFileSystemInMemory() { + return new CryptoFileSystem(createInMemoryFileSystem(), new CryptorImpl(RANDOM_MOCK), "aPassphrase"); + } + + private FileSystem createCryptoFileSystemNio() { + return new CryptoFileSystem(createNioFileSystem(), new CryptorImpl(RANDOM_MOCK), "aPassphrase"); + } + + private void add(String name, Supplier fileSystemSupplier) { + factories.add(new Supplier() { + @Override + public FileSystem get() { + return fileSystemSupplier.get(); + } + + @Override + public String toString() { + return name; + } + }); + } + + @Override + public Iterator> iterator() { + return factories.iterator(); + } + +} diff --git a/main/filesystem-invariants-tests/src/test/java/org/cryptomator/filesystem/invariants/FileSystemTests.java b/main/filesystem-invariants-tests/src/test/java/org/cryptomator/filesystem/invariants/FileSystemTests.java new file mode 100644 index 000000000..9a39f2ec4 --- /dev/null +++ b/main/filesystem-invariants-tests/src/test/java/org/cryptomator/filesystem/invariants/FileSystemTests.java @@ -0,0 +1,91 @@ +package org.cryptomator.filesystem.invariants; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Optional; + +import org.cryptomator.filesystem.FileSystem; +import org.junit.Rule; +import org.junit.experimental.theories.DataPoints; +import org.junit.experimental.theories.Theories; +import org.junit.experimental.theories.Theory; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; + +import com.google.common.base.Supplier; + +@RunWith(Theories.class) +public class FileSystemTests { + + @DataPoints + public static final Iterable> FILE_SYSTEM_FACTORIES = new FileSystemFactories(); + + @Rule + public final ExpectedException thrown = ExpectedException.none(); + + @Theory + public void testFileSystemHasNoParent(Supplier factory) { + FileSystem inTest = factory.get(); + + assertThat(inTest.parent(), is(Optional.empty())); + } + + @Theory + public void testFileSystemExists(Supplier factory) { + FileSystem inTest = factory.get(); + + assertThat(inTest.exists(), is(true)); + } + + @Theory + public void testFileSystemHasNoChildren(Supplier factory) { + FileSystem inTest = factory.get(); + + assertThat(inTest.children().count(), is(0L)); + } + + @Theory + public void testFileSystemHasNoFiles(Supplier factory) { + FileSystem inTest = factory.get(); + + assertThat(inTest.files().count(), is(0L)); + } + + @Theory + public void testFileSystemHasNoFolders(Supplier factory) { + FileSystem inTest = factory.get(); + + assertThat(inTest.folders().count(), is(0L)); + } + + @Theory + public void testFileSystemsFileSystemIsItself(Supplier factory) { + FileSystem inTest = factory.get(); + + assertThat(inTest.fileSystem(), is(inTest)); + } + + @Theory + public void testFileSystemBelongsToSameFilesystemWhenCheckingItself(Supplier factory) { + FileSystem inTest = factory.get(); + + assertThat(inTest.belongsToSameFilesystem(inTest), is(true)); + } + + @Theory + public void testFileSystemDoesNotBelongToSameFilesystemWhenCheckingOtherInstance(Supplier factory) { + FileSystem inTest = factory.get(); + FileSystem otherInstance = factory.get(); + + assertThat(inTest.belongsToSameFilesystem(otherInstance), is(false)); + } + + @Theory + public void testFileSystemIsNoAncestorOfItself(Supplier factory) { + FileSystem inTest = factory.get(); + + assertThat(inTest.isAncestorOf(inTest), is(false)); + } + +} diff --git a/main/pom.xml b/main/pom.xml index de3e2ddda..de4ddf236 100644 --- a/main/pom.xml +++ b/main/pom.xml @@ -258,6 +258,7 @@ filesystem-nio filesystem-nameshortening filesystem-crypto + filesystem-invariants-tests crypto-api crypto-aes jackrabbit-filesystem-adapter