summaryrefslogtreecommitdiff
path: root/libs/sftp/src/test
diff options
context:
space:
mode:
authorJoel Klinghed <the_jk@spawned.biz>2024-09-25 21:12:24 +0200
committerJoel Klinghed <the_jk@spawned.biz>2024-09-25 21:12:24 +0200
commit28a55fdc69e31490a4086ecae8cc687f40ba0b94 (patch)
tree9bde6e49eb091f912e8a9f8b2853d87f6a932d27 /libs/sftp/src/test
parent07d35782b377a8b98cf8dbbb5734d3f2514bccd5 (diff)
Add libs:sftp
sftp implementation using libssh2 and openssl
Diffstat (limited to 'libs/sftp/src/test')
-rw-r--r--libs/sftp/src/test/docker/docker-compose.yml12
-rw-r--r--libs/sftp/src/test/docker/ssh_host_ed25519_key7
-rw-r--r--libs/sftp/src/test/docker/ssh_host_ed25519_key.pub1
-rw-r--r--libs/sftp/src/test/docker/ssh_host_rsa_key49
-rw-r--r--libs/sftp/src/test/docker/ssh_host_rsa_key.pub1
-rw-r--r--libs/sftp/src/test/docker/user_private.pem30
-rw-r--r--libs/sftp/src/test/docker/user_public.pem9
-rw-r--r--libs/sftp/src/test/java/org/the_jk/cleversync/sftp/SftpTreeTest.kt168
8 files changed, 277 insertions, 0 deletions
diff --git a/libs/sftp/src/test/docker/docker-compose.yml b/libs/sftp/src/test/docker/docker-compose.yml
new file mode 100644
index 0000000..973a942
--- /dev/null
+++ b/libs/sftp/src/test/docker/docker-compose.yml
@@ -0,0 +1,12 @@
+services:
+ sftp:
+ image: atmoz/sftp:debian
+ restart: always
+ command: user:notverysecret:1000
+ volumes:
+ - ./ssh_host_ed25519_key:/etc/ssh/ssh_host_ed25519_key
+ - ./ssh_host_rsa_key:/etc/ssh/ssh_host_rsa_key
+ - ./user_public.pub:/home/user/.ssh/keys/id_rsa.pub:ro
+ - ../../../build/test-share:/home/user/share
+ ports:
+ - "127.0.0.1:10022:22"
diff --git a/libs/sftp/src/test/docker/ssh_host_ed25519_key b/libs/sftp/src/test/docker/ssh_host_ed25519_key
new file mode 100644
index 0000000..8cb5247
--- /dev/null
+++ b/libs/sftp/src/test/docker/ssh_host_ed25519_key
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACC6aVbkT4F5PcnnVmCfdhyrrfOA+H6qpfcZRJDdZLqnJQAAAJBQNbBOUDWw
+TgAAAAtzc2gtZWQyNTUxOQAAACC6aVbkT4F5PcnnVmCfdhyrrfOA+H6qpfcZRJDdZLqnJQ
+AAAEDE99B9qMrmtNYkRaAy3nvXE82OG3MqIuElVoeXfLqz2rppVuRPgXk9yedWYJ92HKut
+84D4fqql9xlEkN1kuqclAAAADXRoZV9qa0B3aWxsb3c=
+-----END OPENSSH PRIVATE KEY-----
diff --git a/libs/sftp/src/test/docker/ssh_host_ed25519_key.pub b/libs/sftp/src/test/docker/ssh_host_ed25519_key.pub
new file mode 100644
index 0000000..936d72b
--- /dev/null
+++ b/libs/sftp/src/test/docker/ssh_host_ed25519_key.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILppVuRPgXk9yedWYJ92HKut84D4fqql9xlEkN1kuqcl the_jk@willow
diff --git a/libs/sftp/src/test/docker/ssh_host_rsa_key b/libs/sftp/src/test/docker/ssh_host_rsa_key
new file mode 100644
index 0000000..4055a8a
--- /dev/null
+++ b/libs/sftp/src/test/docker/ssh_host_rsa_key
@@ -0,0 +1,49 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+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
+-----END OPENSSH PRIVATE KEY-----
diff --git a/libs/sftp/src/test/docker/ssh_host_rsa_key.pub b/libs/sftp/src/test/docker/ssh_host_rsa_key.pub
new file mode 100644
index 0000000..d53338e
--- /dev/null
+++ b/libs/sftp/src/test/docker/ssh_host_rsa_key.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDwCDcD18wsPssz1G4ANESktHhsKiwudOWZj7lA8jKNHt5FDQmmpZHVBfkoy2R3i7I8cMzuriDd89ntOTCDlD4D/Ymsl5y4tL5hv+mMQKYHbDWk5/bOEyYybjf/vpFSYm7xzw/RyFvXBIsb+7jBuxbLRfcJmZugX8oEO5y+pYz15rsQ4KHNv//vKFQ6nQi/wocPRVpGsWZ/6Jb/pGlKGxbUp4qTU2c9UvTnrD1UOgEOuLTVuaXvj3ZINlTbLNzc58N6KqfkjjIEtuFx9WJbFiwaEkHLTZvRpTtz8x9cKFQD0KDMwntZUFtleESSmjJaOUZqCZFu51s4UJXdLmLVlOQGweEcd9mPIlueTyUUVAz0aa+P+d2Kz67eVOvChjcD+d/kk//UzhOnwBjfoiAVkJpbrXtRU78iAye6kV+7WZ2jlsSm9kkrqBfi7uYj7yZt40PJ105/eOeQ5HAgYAt+yLHT2q12uEOjjS2wJ3xdlmgfP5Mh0GNM1WP4fPoj8x3zz4WAWlFP0+elSimornEZkqQK+l44Jz6SKZrx7JQ5mSORLIToYUnaQoAJBv6+2xYSkL//IIhuju68G87WdcrDcSeNN5YNcNYN+ba5AIPu/8iZJ0w0nYGx3XnFV8+i+vQux7ArW8jyOUhm46pf3yGuRSQv9WWGnDbHDz3B+2te8CrUQQ== the_jk@willow
diff --git a/libs/sftp/src/test/docker/user_private.pem b/libs/sftp/src/test/docker/user_private.pem
new file mode 100644
index 0000000..327db4b
--- /dev/null
+++ b/libs/sftp/src/test/docker/user_private.pem
@@ -0,0 +1,30 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIFJDBWBgkqhkiG9w0BBQ0wSTAxBgkqhkiG9w0BBQwwJAQQfvtNRgdziQX01T8h
+P1oWXwICCAAwDAYIKoZIhvcNAgkFADAUBggqhkiG9w0DBwQIT9jscTxj/XUEggTI
+Ua25QSpuCoi8SpcoCSEbo8Kcru+Mk7okrR1oEoziwYGSuF9vEgOKK4t2GppWMPv2
+VIx1r3M4Tbsr7MJ1lXi6yJHcKYnUuxmRx8HsSwrWDC4IjHiECF3fzphNirZu6mgH
+yG43Hkyt5mAVvb/sIviKCbmzhQ8h0L3KDNY+EFMbLHt3a1OIl5b8z4g0X6TxJgYC
+y7F65svUhiB/l1hwQl5YHqen/VVsa8ENme95/lNXrPUmddBzRqcOeEQL1zwwZ4Ag
+bx03xrOQObG3sslhbqCvDXd0BFJo9YNpCs/GPeYvUl2KU1PQ2ErmmJCGsyIZ2wYk
+QOLp4Ie6TiX7fApe+nV+Sl6DYa+ww7PHvukC5is9hAUO5WUcsIWpY/myGiVdKuxE
+VEmd6fykXhCZfyIBJrmxn9U/aaYDLO75Xzj6ktWbOSJe/DaDtpEBwjh6t8TewsdC
+mawoa6878oM8sji4Jn9Am4O/i0XHSg7qQ5vHJnoW5WKdl9jlcaOWGrZZEugWtSFn
+2I+DdMM3SWkz20w7+6abelTA8LUY11MEnGrHHFz6HIvVxd1wuqzqRsRgI7OTg7e1
+xgW3kwEwJiKLDfcAm+mq0tvyK0lIHZ7+a8vawso4SZKA0egbtbWrqC4flE8OvCDL
+12YUIpIGEGeyE4EwM57+Ivw/DllOUSE5ZI90HrGVG0KXbPbwRC+9VJddcaF4Mxue
+5GRHbRRp5HSRqgY76Sb0HkwypuJCmk8Yi8vmBqEckCJWIACHaBnrebUjE29IacPH
+etCEeHloucCck1kG0fOcM0e2WIhgjHUqJHNb3r9poy80aMijHFv1AlDlqawo5uFh
+tH19TL1feWokqRM71h+S9Z4oZ97Q8xuuk+MlFyKV2bnZ0JRSXdVfgKdMJWMosE0b
+zDFvngb9SWsUmxx+pJpE5tY/GYSQsT0A2rNVY66IWf39XfzauVHmEypMQ20Cb3Ma
+0JzdYPfeEs+r0Bda85sGDev2WAWTgy56SvdsKDDJyHh93RZ9q7T99Kt4w8VOvWxy
+5MekUTUwRTu89HPUU9OxcTHvyweVL4Rh8Y9cx2VglrdvNPWDX9Z6ydkZoXyHfbL3
+QVwNG2LsjihOkE7Ggg5VFTR4ZDi7QT4qF9PkEXC0wFNuRjL2yLB93rHIztA/QNP6
+0dQmMCFtelsAkG3mtGUDLRqTkQZelQx932hAA72pQCRnza/djXAyz7LINNz6AfLc
+RnqBpTEj6gB1MyJQo4Y/Mq06Wbkm2Zh4qhpqTPbtdxfO6vJlgdoAXj6lvmWeKj7v
+0Wv2qE8I0Ai5o0dHrxLlu5qiBW7E4NOXZAuK4uI285kgDXXJd8qriOM25MX9bYR7
+m5LgUuWjq4IhIdFgjEgCx007ZfnnwTpzWI1bJIPmRyStqGPAimT26uZkbQnoC3Ii
++tsAx58v8m7tcDauOF1Fcl1yzYfQgV1QRPkUX2ymWklmZOAUe9Poo2+takLG/5pY
+d2xRJVJ5165zexKLbxeU5bFcHkGm2KWn0Fj4pdJCodpVSqW4pHluDftElAztrlZk
+57eYRVF/xTS+nxMi+nMluV5qzFx1MIxX2TBRCBxCHuC0IlEqs1n7hqG/NiWr3u/c
+5Z/CIiawNGziWe+pqv2VlHnL2JtP+81o
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/libs/sftp/src/test/docker/user_public.pem b/libs/sftp/src/test/docker/user_public.pem
new file mode 100644
index 0000000..f0812d9
--- /dev/null
+++ b/libs/sftp/src/test/docker/user_public.pem
@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4/t3pxBvR68V27NiEp76
+pKxlQWchdyScphxK0pC6sH9goQNOa8YH9pZjQ4ltrTiG4DkeAPG6THjT9sxq6VM7
+mBZkqfeuOdJk1XCE3i06QeUzT2O7XfMFkPllAedkSDKE+PnuiTZHl8LF7Xhx3gcV
+PgSLDs0oqR2NpOccG1gxIV0xQ49BIO/lyHumNN4xQ1WINheCkOQhdryJdVVjpUvm
+zAJ4BAs1daNAgY2shAFUuta+vO6vRT/viCyVo0YfkeQharCMGylv0H7sHzUb3SlR
+kGDci1l3X85LLbRX0JO4je+5sO7vr4ePRhGVNtGYpTldLBoM+Iu29ejnVzqBFieN
+ewIDAQAB
+-----END PUBLIC KEY-----
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()
+ }
+ }
+}