feat: vfs2

This commit is contained in:
hstyi
2025-04-03 00:42:51 +08:00
committed by hstyi
parent f9aaf7143f
commit 01aac98437
24 changed files with 988 additions and 457 deletions

View File

@@ -11,11 +11,9 @@ class SFTPTest : SSHDTest() {
@Test
fun test() {
val client = SshClients.openClient(host)
val session = SshClients.openSession(host, client)
val session = newClientSession()
assertTrue(session.isOpen)
val fileSystem = DefaultSftpClientFactory.INSTANCE.createSftpFileSystem(session)
for (path in Files.list(fileSystem.rootDirectories.first())) {
println(path)

View File

@@ -1,8 +1,10 @@
package app.termora
import org.apache.sshd.client.session.ClientSession
import org.testcontainers.containers.GenericContainer
import kotlin.test.AfterTest
import kotlin.test.BeforeTest
import kotlin.test.assertTrue
abstract class SSHDTest {
@@ -17,8 +19,8 @@ abstract class SSHDTest {
.withEnv("SUDO_ACCESS", "true")
.withExposedPorts(2222)
protected val host by lazy {
Host(
protected val host
get() = Host(
name = sshd.containerName,
protocol = Protocol.SSH,
host = "127.0.0.1",
@@ -26,7 +28,6 @@ abstract class SSHDTest {
username = "foo",
authentication = Authentication.No.copy(type = AuthenticationType.Password, password = "pass"),
)
}
@BeforeTest
@@ -38,4 +39,11 @@ abstract class SSHDTest {
fun teardown() {
sshd.stop()
}
fun newClientSession(): ClientSession {
val client = SshClients.openClient(host)
val session = SshClients.openSession(host, client)
assertTrue(session.isOpen)
return session
}
}

View File

@@ -0,0 +1,114 @@
package app.termora.vfs2.sftp
import app.termora.SSHDTest
import app.termora.toSimpleString
import org.apache.commons.vfs2.*
import org.apache.commons.vfs2.impl.DefaultFileSystemManager
import org.apache.commons.vfs2.provider.local.DefaultLocalFileProvider
import org.apache.sshd.sftp.client.SftpClientFactory
import java.io.File
import java.util.*
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue
class MySftpFileProviderTest : SSHDTest() {
companion object {
init {
val fileSystemManager = DefaultFileSystemManager()
fileSystemManager.addProvider("sftp", MySftpFileProvider())
fileSystemManager.addProvider("file", DefaultLocalFileProvider())
fileSystemManager.init()
VFS.setManager(fileSystemManager)
}
}
@Test
fun testSetExecutable() {
val file = newFileObject("/config/test.txt")
file.createFile()
file.refresh()
assertFalse(file.isExecutable)
file.setExecutable(true, false)
file.refresh()
assertTrue(file.isExecutable)
}
@Test
fun testCreateFile() {
val file = newFileObject("/config/test.txt")
assertFalse(file.exists())
file.createFile()
assertTrue(file.exists())
}
@Test
fun testWriteAndReadFile() {
val file = newFileObject("/config/test.txt")
file.createFile()
assertFalse(file.content.isOpen)
val os = file.content.outputStream
os.write("test".toByteArray())
os.flush()
assertTrue(file.content.isOpen)
os.close()
assertFalse(file.content.isOpen)
val input = file.content.inputStream
assertEquals("test", String(input.readAllBytes()))
assertTrue(file.content.isOpen)
input.close()
assertFalse(file.content.isOpen)
}
@Test
fun testCreateFolder() {
val file = newFileObject("/config/test")
assertFalse(file.exists())
file.createFolder()
assertTrue(file.exists())
}
@Test
fun testSftpClient() {
val session = newClientSession()
val client = SftpClientFactory.instance().createSftpClient(session)
assertTrue(client.isOpen)
session.close()
assertFalse(client.isOpen)
}
@Test
fun testCopy() {
val file = newFileObject("/config/sshd.pid")
val filepath = File("build", UUID.randomUUID().toSimpleString())
val localFile = getVFS().resolveFile("file://${filepath.absolutePath}")
localFile.copyFrom(file, Selectors.SELECT_ALL)
assertEquals(
file.content.getString(Charsets.UTF_8),
localFile.content.getString(Charsets.UTF_8)
)
localFile.delete()
}
private fun getVFS(): FileSystemManager {
return VFS.getManager()
}
private fun newFileObject(path: String): FileObject {
val vfs = getVFS()
val fileSystemOptions = FileSystemOptions()
MySftpFileSystemConfigBuilder.getInstance().setClientSession(fileSystemOptions, newClientSession())
return vfs.resolveFile("sftp://${path}", fileSystemOptions)
}
}