Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,12 @@
# Eclipse
.settings/
.classpath
.project

# IntelliJ IDEA
.idea/
*.iml

# Maven
target/
.flattened-pom.xml
target
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
</parent>

<artifactId>fake-sftp-server-lambda</artifactId>
<version>2.0.0</version>
<version>2.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>Fake SFTP Server Lambda</name>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.github.stefanbirkner.fakesftpserver.lambda;

import java.io.Closeable;
import java.io.IOException;
import java.nio.file.FileSystem;

/**
* This extension of {@link FakeSftpServer} can be instantiated, configured and closed manually,
* if doing everything within a single lambda expression is undesirable for your use case.
* <p>For example, in BDD (behaviour-driven development) you want to test in a <i>given-when-then</i>
* fashion, i.e. separate the stimulus to the system under test (when) from verifying results later
* (then). Some test frameworks like Spock even require separate blocks, making the use of a single
* lambda feel somewhat unnatural and clunky there.
* <p>Because this class implements {@link AutoCloseable}, if you like you can instantiate it in a
* <i>try with resources</i> structure.
* <p>A parametrised Spock (Groovy) example test looks like this:
* <pre>
* class MySFTPServerTest extends Specification {
* &#064;AutoCleanup
* def server = new CloseableFakeSftpServer()
*
* &#064;Unroll("user #user downloads file #file")
* def "users can download text files"() {
* given: "a preconfigured fake SFTP server"
* server.addUser(user, password)
* server.putFile(file, content, UTF_8)
*
* and: "an SFTP client under test"
* def client = new SFTPFileDownloader("localhost", server.port, user, password)
*
* expect:
* client.getFileContent(file) == content
*
* where:
* user | password | file | content
* "me" | "xoxox" | "/a/b/c/one.txt" | "First line\nSecondLine\n"
* "you" | "mypass" | "/etc/two.xml" | "<root><foo>abc</foo></root>"
* "admin" | "secret" | "/home/admin/three.sh" | "#!/usr/bin/bash\n\nls -al\n"
* }
* }
* </pre>
*/
public class CloseableFakeSftpServer extends FakeSftpServer implements AutoCloseable {
protected final Closeable closeServer;

public CloseableFakeSftpServer() throws IOException {
super(FakeSftpServer.createFileSystem());
closeServer = start(0);
}

@Override
public void close() throws Exception {
fileSystem.close();
closeServer.close();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -214,18 +214,19 @@ public FileVisitResult postVisitDirectory(
}
};
private static final Random RANDOM = new Random();
private final FileSystem fileSystem;
protected final FileSystem fileSystem;
private SshServer server;
private boolean withSftpServerFinished = false;
private final Map<String, String> usernamesAndPasswords = new HashMap<>();

/**
* {@code FakeSftpServer} cannot be created manually. It is always provided
* {@code FakeSftpServer} should not be created manually (unless by
* subclasses which know what they are doing). It is always provided
* to an {@link ExceptionThrowingConsumer}
* by {@link #withSftpServer(ExceptionThrowingConsumer)}.
* @param fileSystem the file system that is used for storing the files
*/
private FakeSftpServer(
protected FakeSftpServer(
FileSystem fileSystem
) {
this.fileSystem = fileSystem;
Expand Down Expand Up @@ -423,12 +424,12 @@ public void deleteAllFilesAndDirectories() throws IOException {
walkFileTree(directory, DELETE_FILES_AND_DIRECTORIES);
}

private static FileSystem createFileSystem(
protected static FileSystem createFileSystem(
) throws IOException {
return newLinux().build("FakeSftpServer-" + RANDOM.nextInt());
}

private Closeable start(
protected Closeable start(
int port
) throws IOException {
SshServer server = SshServer.setUpDefaultServer();
Expand Down