From a15cfde0fcbdb29dafdb9ebe39fe53c8da4073be Mon Sep 17 00:00:00 2001 From: Joel Klinghed Date: Sun, 25 Aug 2024 02:30:36 +0200 Subject: Combine tests from both local and samba Most the tests test the Tree implementation and thus should work on all such implementations. Current exception is symlinks which Samba backend doesn't (currently?) support. Improve the Samba remove methods to better match the expected behavior. --- .../java/org/the_jk/cleversync/TreeAbstractTest.kt | 342 +++++++++++++++++++++ 1 file changed, 342 insertions(+) create mode 100644 libs/test-utils/src/main/java/org/the_jk/cleversync/TreeAbstractTest.kt (limited to 'libs/test-utils/src/main/java/org/the_jk') diff --git a/libs/test-utils/src/main/java/org/the_jk/cleversync/TreeAbstractTest.kt b/libs/test-utils/src/main/java/org/the_jk/cleversync/TreeAbstractTest.kt new file mode 100644 index 0000000..b513503 --- /dev/null +++ b/libs/test-utils/src/main/java/org/the_jk/cleversync/TreeAbstractTest.kt @@ -0,0 +1,342 @@ +package org.the_jk.cleversync + +import com.google.common.truth.Truth.assertThat +import org.junit.Assert +import org.junit.Assume +import org.junit.Test +import org.robolectric.shadows.ShadowLooper +import org.the_jk.cleversync.io.Directory +import org.the_jk.cleversync.io.Link +import org.the_jk.cleversync.io.ModifiableLink +import org.the_jk.cleversync.io.ModifiableTree + +abstract class TreeAbstractTest { + protected lateinit var tree: ModifiableTree + + @Test + open fun empty() { + val content = tree.list() + assertThat(content.directories).isEmpty() + assertThat(content.files).isEmpty() + assertThat(content.links).isEmpty() + } + + @Test + open fun emptyLive() { + val content = tree.liveList().safeValue() + assertThat(content?.directories).isEmpty() + assertThat(content?.files).isEmpty() + assertThat(content?.links).isEmpty() + } + + @Test + open fun createDirectory() { + val foo = tree.createDirectory("foo") + assertThat(foo.name).isEqualTo("foo") + val fooContent = foo.list() + assertThat(fooContent.directories).isEmpty() + assertThat(fooContent.files).isEmpty() + assertThat(fooContent.links).isEmpty() + val content = tree.list() + assertThat(content.directories).contains(foo) + assertThat(content.files).isEmpty() + assertThat(content.links).isEmpty() + } + + @Test(timeout = 10000) + open fun observeCreateDirectory() { + val content = tree.liveList() + var dir: Directory? = null + content.observeForever { + if (it.directories.size == 1) dir = it.directories[0] + } + tree.createDirectory("foo") + while (dir == null) { + idle() + } + assertThat(dir?.name).isEqualTo("foo") + } + + @Test + open fun createFile() { + val foo = tree.createFile("foo") + // Files are not created until you write to them. + assertThat(tree.list().files).isEmpty() + foo.write().use { os -> + os.write(byteArrayOf(1, 2, 3, 4)) + } + assertThat(tree.list().files).contains(foo) + assertThat(foo.size).isEqualTo(4.toULong()) + foo.read().use { + assertThat(it.readBytes()).isEqualTo(byteArrayOf(1, 2, 3, 4)) + } + } + + @Test + open fun overwriteFile() { + val foo = tree.createFile("foo") + foo.write().use { os -> + os.write(byteArrayOf(1, 2, 3, 4)) + } + foo.write().use { os -> + os.write(127) + os.write(byteArrayOf(1)) + os.write(byteArrayOf(2), 0, 0) + } + assertThat(foo.size).isEqualTo(2.toULong()) + assertThat(tree.list().files).hasSize(1) + foo.read().use { + assertThat(it.readBytes()).isEqualTo(byteArrayOf(127, 1)) + } + } + + @Test + open fun removeDir() { + tree.createDirectory("foo") + tree.removeDirectory("foo") + assertThat(tree.list().directories).isEmpty() + } + + @Test(timeout = 10000) + open fun removeDirLive() { + tree.createDirectory("foo") + val content = tree.liveList() + var done = false + content.observeForever { + if (it.directories.isEmpty()) done = true + } + tree.removeDirectory("foo") + while (!done) { + idle() + } + } + + @Test + open fun createLink() { + Assume.assumeTrue(supportSymlinks()) + + val dir = tree.createDirectory("dir") + val file = tree.createFile("file") + val link = tree.createLink("link", dir.name) + var target = link.resolve() + when (target) { + is Link.DirectoryTarget -> assertThat(target.directory).isEqualTo( + dir + ) + is Link.FileTarget -> Assert.fail() + is Link.NoTarget -> Assert.fail() + } + assertThat(tree.openDir("link")).isEqualTo(dir) + + link.target(file) + target = link.resolve() + when (target) { + is Link.DirectoryTarget -> Assert.fail() + is Link.FileTarget -> Assert.fail() + is Link.NoTarget -> Unit + } + file.write().use { it.write(1) } + target = link.resolve() + when (target) { + is Link.DirectoryTarget -> Assert.fail() + is Link.FileTarget -> assertThat(target.file).isEqualTo(file) + is Link.NoTarget -> Assert.fail() + } + + assertThat(tree.openFile("link")).isEqualTo(file) + } + + @Test + open fun createLinkSubdir() { + Assume.assumeTrue(supportSymlinks()) + + val foo = tree.createDirectory("foo") + val bar = foo.createDirectory("bar") + val link1 = tree.createLink("link1", "foo/bar") + val link2 = tree.createLink("link2", bar) + assertThat(link1.resolve()).isEqualTo(link2.resolve()) + assertThat((link1.resolve() as Link.DirectoryTarget).directory) + .isEqualTo(bar) + val link3 = foo.createLink("link3", "../link1") + assertThat((link3.resolve() as Link.DirectoryTarget).directory) + .isEqualTo(bar) + } + + @Test(timeout = 10000) + open fun createLiveLink() { + Assume.assumeTrue(supportSymlinks()) + + val content = tree.liveList() + var link: Link? = null + content.observeForever { + if (it.links.size == 1) link = it.links[0] + } + val dir = tree.createDirectory("dir") + tree.createLink("link", "dir") + while (link == null) { + idle() + } + assertThat((link?.resolve() as Link.DirectoryTarget).directory).isEqualTo(dir) + } + + @Test + open fun sameDir() { + val dir1 = tree.createDirectory("dir") + val dir2 = tree.openDir("dir") + assertThat(dir1).isEqualTo(dir2) + assertThat(dir1.hashCode()).isEqualTo(dir2.hashCode()) + assertThat(dir1.toString()).isEqualTo(dir2.toString()) + } + + @Test + open fun sameFile() { + val file1 = tree.createFile("file") + file1.write().use { it.write(127) } + val file2 = tree.openFile("file") + assertThat(file1).isEqualTo(file2) + assertThat(file1.hashCode()).isEqualTo(file2.hashCode()) + assertThat(file1.toString()).isEqualTo(file2.toString()) + } + + @Test + open fun sameLink() { + Assume.assumeTrue(supportSymlinks()) + + val link1 = tree.createLink("link", "foo") + val link2 = tree.openLink("link") + assertThat(link1).isEqualTo(link2) + assertThat(link1.hashCode()).isEqualTo(link2.hashCode()) + assertThat(link1.toString()).isEqualTo(link2.toString()) + } + + @Test + open fun removeDirWithContent() { + val foo = tree.createDirectory("foo") + foo.createDirectory("dir") + foo.createFile("file").write().use { it.write(byteArrayOf(1, 2, 3, 4)) } + if (supportSymlinks()) { + foo.createLink("link", "file") + } + assertThat(tree.list().directories).hasSize(1) + assertThat(tree.removeDirectory("foo")).isTrue() + assertThat(tree.list().directories).isEmpty() + } + + @Test + open fun removeWrongType() { + tree.createDirectory("dir") + assertThat(tree.removeFile("dir")).isFalse() + assertThat(tree.removeLink("dir")).isFalse() + tree.createFile("file").write().use { it.write(byteArrayOf(1, 2, 3, 4)) } + assertThat(tree.removeDirectory("file")).isFalse() + assertThat(tree.removeLink("file")).isFalse() + if (supportSymlinks()) { + tree.createLink("link", "doesn't exist") + assertThat(tree.removeDirectory("link")).isFalse() + assertThat(tree.removeFile("link")).isFalse() + } + val content = tree.list() + assertThat(content.directories).hasSize(1) + assertThat(content.files).hasSize(1) + if (supportSymlinks()) { + assertThat(content.links).hasSize(1) + } + } + + @Test + open fun removeFile() { + tree.createFile("file").write().use { it.write(byteArrayOf(1, 2, 3, 4)) } + assertThat(tree.list().files).hasSize(1) + tree.removeFile("file") + assertThat(tree.list().files).isEmpty() + } + + @Test + open fun removeLink() { + Assume.assumeTrue(supportSymlinks()) + + val dir = tree.createDirectory("dir") + val file = tree.createFile("file") + file.write().use { it.write(127) } + tree.createLink("link1", dir) + tree.createLink("link2", file) + assertThat(tree.list().links).hasSize(2) + tree.removeLink("link1") + tree.removeLink("link2") + assertThat(tree.list().links).isEmpty() + } + + @Test + open fun changeLink() { + Assume.assumeTrue(supportSymlinks()) + + val dir = tree.createDirectory("dir") + val file = tree.createFile("file") + file.write().use { it.write(127) } + val link = tree.createLink("link", "doesn't exist") + assertThat(link.resolve() is Link.NoTarget).isTrue() + link.target(file) + assertThat((link.resolve() as Link.FileTarget).file).isEqualTo(file) + link.target(dir) + assertThat((link.resolve() as Link.DirectoryTarget).directory).isEqualTo(dir) + link.target("bad") + assertThat(link.resolve() is Link.NoTarget).isTrue() + } + + @Test + open fun changeModifiableLink() { + Assume.assumeTrue(supportSymlinks()) + + val dir = tree.createDirectory("dir") + val file = tree.createFile("file") + file.write().use { it.write(127) } + val link = tree.createLink("link", "doesn't exist") + assertThat(link.modifiableResolve() is ModifiableLink.NoTarget).isTrue() + link.target(file) + assertThat((link.modifiableResolve() as ModifiableLink.ModifiableFileTarget).file).isEqualTo(file) + link.target(dir) + assertThat((link.modifiableResolve() as ModifiableLink.ModifiableDirectoryTarget).directory).isEqualTo(dir) + link.target("bad") + assertThat(link.modifiableResolve() is ModifiableLink.NoTarget).isTrue() + } + + @Test + open fun recursiveLink() { + Assume.assumeTrue(supportSymlinks()) + + val link = tree.createLink("link", "link") + assertThat(link.resolve() is Link.NoTarget).isTrue() + } + + @Test + open fun names() { + assertThat(tree.createDirectory("dir").name).isEqualTo("dir") + assertThat(tree.createFile("file").name).isEqualTo("file") + if (supportSymlinks()) { + assertThat(tree.createLink("link", "file").name).isEqualTo("link") + } + } + + @Test + open fun openNonExistent() { + assertThat(tree.openDir("dir")).isNull() + assertThat(tree.openFile("file")).isNull() + assertThat(tree.openLink("link")).isNull() + } + + @Test + open fun lastModified() { + val file = tree.createFile("foo") + file.write().use { it.write(1) } + val old = file.lastModified + file.write().use { it.write(2); it.flush() } + val new = file.lastModified + assertThat(old.isBefore(new) || old == new).isTrue() + } + + protected abstract fun supportSymlinks(): Boolean + + protected open fun idle() { + ShadowLooper.idleMainLooper() + } +} -- cgit v1.2.3-70-g09d2