diff options
| author | Joel Klinghed <the_jk@spawned.biz> | 2024-09-25 21:12:24 +0200 |
|---|---|---|
| committer | Joel Klinghed <the_jk@spawned.biz> | 2024-09-25 21:12:24 +0200 |
| commit | 28a55fdc69e31490a4086ecae8cc687f40ba0b94 (patch) | |
| tree | 9bde6e49eb091f912e8a9f8b2853d87f6a932d27 /libs/sftp/src/test/java | |
| parent | 07d35782b377a8b98cf8dbbb5734d3f2514bccd5 (diff) | |
Add libs:sftp
sftp implementation using libssh2 and openssl
Diffstat (limited to 'libs/sftp/src/test/java')
| -rw-r--r-- | libs/sftp/src/test/java/org/the_jk/cleversync/sftp/SftpTreeTest.kt | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/libs/sftp/src/test/java/org/the_jk/cleversync/sftp/SftpTreeTest.kt b/libs/sftp/src/test/java/org/the_jk/cleversync/sftp/SftpTreeTest.kt new file mode 100644 index 0000000..60b25f2 --- /dev/null +++ b/libs/sftp/src/test/java/org/the_jk/cleversync/sftp/SftpTreeTest.kt @@ -0,0 +1,168 @@ +package org.the_jk.cleversync.sftp + +import android.content.Context +import androidx.test.core.app.ApplicationProvider +import com.google.common.truth.Truth.assertThat +import org.junit.After +import org.junit.AfterClass +import org.junit.Before +import org.junit.BeforeClass +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config +import org.robolectric.shadows.ShadowLooper +import org.the_jk.cleversync.TreeAbstractTest +import org.the_jk.cleversync.io.Link +import org.the_jk.cleversync.io.sftp.SftpCredentials +import java.io.File +import java.nio.charset.StandardCharsets +import java.nio.file.Files +import java.util.concurrent.TimeUnit + +@Config(manifest=Config.NONE) +@RunWith(RobolectricTestRunner::class) +class SftpTreeTest : TreeAbstractTest() { + @Before + fun setUpTest() { + assertThat(shareDir.listFiles()).isEmpty() + + val credentials = SftpCredentials.SftpPasswordCredentials("user", "notverysecret") + + tree = SftpTreeFactory.modifiableTree(uri, credentials).getOrThrow() + } + + @After + fun tearDownTest() { + tree.close() + + for (file in shareDir.listFiles()!!) { + if (file.isDirectory) { + file.deleteRecursively() + } else { + file.delete() + } + } + } + + @Test + fun description() { + val resources = ApplicationProvider.getApplicationContext<Context>().resources + assertThat(tree.description(resources).toString()).contains(uri) + } + + @Test + fun listRootWithSymlink() { + File(shareDir, "dir").mkdir() + File(shareDir, "file").writeText("foo") + Files.createSymbolicLink(File(shareDir, "link").toPath(), File("file").toPath()) + + val content = tree.list() + + assertThat(content.directories).hasSize(1) + assertThat(content.directories[0].name).isEqualTo("dir") + assertThat(content.files).hasSize(1) + assertThat(content.files[0].name).isEqualTo("file") + assertThat(content.files[0].size).isEqualTo(3UL) + assertThat(content.links).hasSize(1) + assertThat(content.links[0].name).isEqualTo("link") + val target = content.links[0].resolve() + assertThat( + when (target) { + is Link.DirectoryTarget -> null + Link.NoTarget -> null + is Link.FileTarget -> target.file + }, + ).isEqualTo(content.files[0]) + } + + @Test + fun readExistingFile() { + File(shareDir, "file").writeText("hello world") + + val file = tree.openFile("file") + assertThat(file?.name).isEqualTo("file") + assertThat(file?.size).isEqualTo(11UL) + + file?.read().use { input -> + assertThat(input?.readAllBytes()?.toString(StandardCharsets.UTF_8)).isEqualTo("hello world") + } + + file?.read().use { input -> + val buffer = ByteArray(10) + assertThat(input?.read(buffer, 5, 5)).isEqualTo(5) + assertThat(buffer.sliceArray(5..<10).toString(StandardCharsets.UTF_8)).isEqualTo("hello") + assertThat(input?.read(buffer)).isEqualTo(6) + assertThat(buffer.sliceArray(0..<6).toString(StandardCharsets.UTF_8)).isEqualTo(" world") + } + } + + @Test + override fun createFile() { + super.createFile() + + assertThat(File(shareDir, "foo").readBytes()).isEqualTo(byteArrayOf(1, 2, 3, 4)) + } + + @Test + override fun overwriteFile() { + super.overwriteFile() + + assertThat(File(shareDir, "foo").readBytes()).isEqualTo(byteArrayOf(127, 1)) + } + + @Test + override fun createDirectory() { + super.createDirectory() + + assertThat(File(shareDir, "foo").isDirectory).isTrue() + } + + @Test(timeout = 10000) + override fun observeCreateDirectory() { + super.observeCreateDirectory() + + assertThat(File(shareDir, "foo").isDirectory).isTrue() + } + + override fun supportSymlinks() = true + + override fun idle() { + ShadowLooper.idleMainLooper(10, TimeUnit.SECONDS) + } + + companion object { + private lateinit var uri: String + private lateinit var dockerDir: File + private lateinit var shareDir: File + private var dockerRunning = false + + @BeforeClass + @JvmStatic + fun setUpClass() { + uri = "ssh://127.0.0.1:10022/share" + dockerDir = File(System.getProperty("dockerDir")!!) + shareDir = File(System.getProperty("shareDir")!!) + shareDir.deleteRecursively() + shareDir.mkdirs() + + val pb = ProcessBuilder("docker", "compose", "up", "--wait", "--wait-timeout", "60") + pb.directory(dockerDir) + val exitCode = pb.start().waitFor() + assertThat(exitCode).isEqualTo(0) + dockerRunning = true + } + + @AfterClass + @JvmStatic + fun tearDownClass() { + if (dockerRunning) { + val pb = ProcessBuilder("docker", "compose", "down") + pb.directory(dockerDir) + pb.start().waitFor() + dockerRunning = false + } + shareDir.deleteRecursively() + } + } +} |
