usernamesAndPasswords = new HashMap<>();
181 | private int port = 0;
182 |
183 | private FileSystem fileSystem;
184 | private SshServer server;
185 |
186 | /**
187 | * Returns the port of the SFTP server. If the SFTP server listens on an
188 | * auto-allocated port (that means you didn't call {@link #setPort(int)})
189 | * then you can only call this method during the test.
190 | *
191 | * @return the port of the SFTP server.
192 | * @throws IllegalStateException if you call the method outside of a test
193 | * but haven't called {@link #setPort(int)}) before.
194 | */
195 | public int getPort() {
196 | if (port == 0)
197 | return getPortFromServer();
198 | else
199 | return port;
200 | }
201 |
202 | private int getPortFromServer() {
203 | verifyThatTestIsRunning("call getPort()");
204 | return server.getPort();
205 | }
206 |
207 | /**
208 | * Set the port of the SFTP server. The SFTP server gets restarted if you
209 | * call {@code setPort} from within a test. The time-consuming restart can
210 | * be avoided by setting the port immediately after creating the rule.
211 | * @param port the port. Must be between 1 and 65535.
212 | * @return the rule itself.
213 | * @throws IllegalArgumentException if the port is not between 1 and 65535.
214 | * @throws IllegalStateException if the server cannot be restarted.
215 | */
216 | public FakeSftpServerRule setPort(
217 | int port
218 | ) {
219 | if (port < 1 || port > 65535)
220 | throw new IllegalArgumentException(
221 | "Port cannot be set to " + port
222 | + " because only ports between 1 and 65535 are valid."
223 | );
224 | this.port = port;
225 | if (server != null)
226 | restartServer();
227 | return this;
228 | }
229 |
230 | /**
231 | * Register a username with its password. After registering a username
232 | * it is only possible to connect to the server with one of the registered
233 | * username/password pairs.
234 | * If {@code addUser} is called multiple times with the same username but
235 | * different passwords then the last password is effective.
236 | * @param username the username.
237 | * @param password the password for the specified username.
238 | * @return the rule itself.
239 | */
240 | public FakeSftpServerRule addUser(
241 | String username,
242 | String password
243 | ) {
244 | usernamesAndPasswords.put(username, password);
245 | return this;
246 | }
247 |
248 | private void restartServer() {
249 | try {
250 | server.stop();
251 | startServer(fileSystem);
252 | } catch (IOException e) {
253 | throw new IllegalStateException(
254 | "The SFTP server cannot be restarted.",
255 | e
256 | );
257 | }
258 | }
259 |
260 | /**
261 | * Put a text file on the SFTP folder. The file is available by the
262 | * specified path.
263 | * @param path the path to the file.
264 | * @param content the files content.
265 | * @param encoding the encoding of the file.
266 | * @throws IOException if the file cannot be written.
267 | */
268 | public void putFile(
269 | String path,
270 | String content,
271 | Charset encoding
272 | ) throws IOException {
273 | byte[] contentAsBytes = content.getBytes(encoding);
274 | putFile(path, contentAsBytes);
275 | }
276 |
277 | /**
278 | * Put a file on the SFTP folder. The file is available by the specified
279 | * path.
280 | * @param path the path to the file.
281 | * @param content the files content.
282 | * @throws IOException if the file cannot be written.
283 | */
284 | public void putFile(
285 | String path,
286 | byte[] content
287 | ) throws IOException {
288 | verifyThatTestIsRunning("upload file");
289 | Path pathAsObject = fileSystem.getPath(path);
290 | ensureDirectoryOfPathExists(pathAsObject);
291 | write(pathAsObject, content);
292 | }
293 |
294 | /**
295 | * Put a file on the SFTP folder. The file is available by the specified
296 | * path. The file content is read from an {@code InputStream}.
297 | * @param path the path to the file.
298 | * @param is an {@code InputStream} that provides the file's content.
299 | * @throws IOException if the file cannot be written or the input stream
300 | * cannot be read.
301 | */
302 | public void putFile(
303 | String path,
304 | InputStream is
305 | ) throws IOException {
306 | verifyThatTestIsRunning("upload file");
307 | Path pathAsObject = fileSystem.getPath(path);
308 | ensureDirectoryOfPathExists(pathAsObject);
309 | copy(is, pathAsObject);
310 | }
311 |
312 | /**
313 | * Create a directory on the SFTP server.
314 | * @param path the directory's path.
315 | * @throws IOException if the directory cannot be created.
316 | */
317 | public void createDirectory(
318 | String path
319 | ) throws IOException {
320 | verifyThatTestIsRunning("create directory");
321 | Path pathAsObject = fileSystem.getPath(path);
322 | Files.createDirectories(pathAsObject);
323 | }
324 |
325 | /**
326 | * Create multiple directories on the SFTP server.
327 | * @param paths the directories' paths.
328 | * @throws IOException if at least one directory cannot be created.
329 | */
330 | public void createDirectories(
331 | String... paths
332 | ) throws IOException {
333 | for (String path: paths)
334 | createDirectory(path);
335 | }
336 |
337 | /**
338 | * Get a text file from the SFTP server. The file is decoded using the
339 | * specified encoding.
340 | * @param path the path to the file.
341 | * @param encoding the file's encoding.
342 | * @return the content of the text file.
343 | * @throws IOException if the file cannot be read.
344 | * @throws IllegalStateException if not called from within a test.
345 | */
346 | public String getFileContent(
347 | String path,
348 | Charset encoding
349 | ) throws IOException {
350 | byte[] content = getFileContent(path);
351 | return new String(content, encoding);
352 | }
353 |
354 | /**
355 | * Get a file from the SFTP server.
356 | * @param path the path to the file.
357 | * @return the content of the file.
358 | * @throws IOException if the file cannot be read.
359 | * @throws IllegalStateException if not called from within a test.
360 | */
361 | public byte[] getFileContent(
362 | String path
363 | ) throws IOException {
364 | verifyThatTestIsRunning("download file");
365 | Path pathAsObject = fileSystem.getPath(path);
366 | return readAllBytes(pathAsObject);
367 | }
368 |
369 | /**
370 | * Checks the existence of a file. returns {@code true} iff the file exists
371 | * and it is not a directory.
372 | * @param path the path to the file.
373 | * @return {@code true} iff the file exists and it is not a directory.
374 | * @throws IllegalStateException if not called from within a test.
375 | */
376 | public boolean existsFile(
377 | String path
378 | ) {
379 | verifyThatTestIsRunning("check existence of file");
380 | Path pathAsObject = fileSystem.getPath(path);
381 | return exists(pathAsObject) && !isDirectory(pathAsObject);
382 | }
383 |
384 | /**
385 | * Deletes all files and directories.
386 | * @throws IOException if an I/O error is thrown while deleting the files
387 | * and directories
388 | */
389 | public void deleteAllFilesAndDirectories() throws IOException {
390 | for (Path directory: fileSystem.getRootDirectories())
391 | walkFileTree(directory, DELETE_FILES_AND_DIRECTORIES);
392 | }
393 |
394 | @Override
395 | public Statement apply(
396 | Statement base,
397 | Description description
398 | ) {
399 | return new Statement() {
400 | @Override
401 | public void evaluate() throws Throwable {
402 | try (
403 | FileSystem fileSystem = createFileSystem()
404 | ) {
405 | startServer(fileSystem);
406 | try {
407 | base.evaluate();
408 | } finally {
409 | server.stop();
410 | server = null;
411 | }
412 | } finally {
413 | fileSystem = null;
414 | }
415 | }
416 | };
417 | }
418 |
419 | private FileSystem createFileSystem(
420 | ) throws IOException {
421 | fileSystem = newLinux().build("FakeSftpServerRule@" + hashCode());
422 | return fileSystem;
423 | }
424 |
425 | private SshServer startServer(
426 | FileSystem fileSystem
427 | ) throws IOException {
428 | SshServer server = SshServer.setUpDefaultServer();
429 | server.setPort(port);
430 | server.setKeyPairProvider(new SimpleGeneratorHostKeyProvider());
431 | server.setPasswordAuthenticator(this::authenticate);
432 | server.setSubsystemFactories(singletonList(new SftpSubsystemFactory()));
433 | /* When a channel is closed SshServer calls close() on the file system.
434 | * In order to use the file system for multiple channels/sessions we
435 | * have to use a file system wrapper whose close() does nothing.
436 | */
437 | server.setFileSystemFactory(session -> new DoNotClose(fileSystem));
438 | server.start();
439 | this.server = server;
440 | return server;
441 | }
442 |
443 | private boolean authenticate(
444 | String username,
445 | String password,
446 | ServerSession session
447 | ) {
448 | return usernamesAndPasswords.isEmpty()
449 | || Objects.equals(
450 | usernamesAndPasswords.get(username),
451 | password
452 | );
453 | }
454 |
455 | private void ensureDirectoryOfPathExists(
456 | Path path
457 | ) throws IOException {
458 | Path directory = path.getParent();
459 | if (directory != null && !directory.equals(path.getRoot()))
460 | Files.createDirectories(directory);
461 | }
462 |
463 | private void verifyThatTestIsRunning(
464 | String mode
465 | ) {
466 | if (fileSystem == null)
467 | throw new IllegalStateException(
468 | "Failed to " + mode + " because test has not been started or"
469 | + " is already finished."
470 | );
471 | }
472 |
473 | private static class DoNotClose extends FileSystem {
474 | final FileSystem fileSystem;
475 |
476 | DoNotClose(
477 | FileSystem fileSystem
478 | ) {
479 | this.fileSystem = fileSystem;
480 | }
481 |
482 | @Override
483 | public FileSystemProvider provider() {
484 | return fileSystem.provider();
485 | }
486 |
487 | @Override
488 | public void close(
489 | ) throws IOException {
490 | //will not be closed
491 | }
492 |
493 | @Override
494 | public boolean isOpen() {
495 | return fileSystem.isOpen();
496 | }
497 |
498 | @Override
499 | public boolean isReadOnly() {
500 | return fileSystem.isReadOnly();
501 | }
502 |
503 | @Override
504 | public String getSeparator() {
505 | return fileSystem.getSeparator();
506 | }
507 |
508 | @Override
509 | public Iterable getRootDirectories() {
510 | return fileSystem.getRootDirectories();
511 | }
512 |
513 | @Override
514 | public Iterable getFileStores() {
515 | return fileSystem.getFileStores();
516 | }
517 |
518 | @Override
519 | public Set supportedFileAttributeViews() {
520 | return fileSystem.supportedFileAttributeViews();
521 | }
522 |
523 | @Override
524 | public Path getPath(
525 | String first,
526 | String... more
527 | ) {
528 | return fileSystem.getPath(first, more);
529 | }
530 |
531 | @Override
532 | public PathMatcher getPathMatcher(
533 | String syntaxAndPattern
534 | ) {
535 | return fileSystem.getPathMatcher(syntaxAndPattern);
536 | }
537 |
538 | @Override
539 | public UserPrincipalLookupService getUserPrincipalLookupService() {
540 | return fileSystem.getUserPrincipalLookupService();
541 | }
542 |
543 | @Override
544 | public WatchService newWatchService() throws IOException {
545 | return fileSystem.newWatchService();
546 | }
547 | }
548 | }
549 |
--------------------------------------------------------------------------------
/src/test/java/com/github/stefanbirkner/fakesftpserver/rule/FakeSftpServerRuleTest.java:
--------------------------------------------------------------------------------
1 | package com.github.stefanbirkner.fakesftpserver.rule;
2 |
3 |
4 | import com.jcraft.jsch.*;
5 | import org.apache.commons.io.IOUtils;
6 | import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
7 | import org.junit.Test;
8 | import org.junit.experimental.runners.Enclosed;
9 | import org.junit.runner.RunWith;
10 |
11 | import java.io.ByteArrayInputStream;
12 | import java.io.IOException;
13 | import java.io.InputStream;
14 | import java.net.ConnectException;
15 | import java.nio.file.Path;
16 | import java.nio.file.Paths;
17 | import java.util.Vector;
18 | import java.util.concurrent.atomic.AtomicInteger;
19 |
20 | import static com.github.stefanbirkner.fakesftpserver.rule.Executor.executeTestThatThrowsExceptionWithRule;
21 | import static com.github.stefanbirkner.fakesftpserver.rule.Executor.executeTestWithRule;
22 | import static com.github.stefanbirkner.fishbowl.Fishbowl.exceptionThrownBy;
23 | import static java.nio.charset.StandardCharsets.UTF_8;
24 | import static org.apache.commons.io.IOUtils.toByteArray;
25 | import static org.assertj.core.api.Assertions.assertThat;
26 | import static org.assertj.core.api.Assertions.assertThatThrownBy;
27 | import static org.assertj.core.api.Assertions.catchThrowable;
28 |
29 | /* Wording according to the draft:
30 | * http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13
31 | */
32 | @RunWith(Enclosed.class)
33 | public class FakeSftpServerRuleTest {
34 | private static final byte[] DUMMY_CONTENT = new byte[]{1, 4, 2, 4, 2, 4};
35 | private static final int DUMMY_PORT = 46354;
36 | private static final InputStream DUMMY_STREAM = new ByteArrayInputStream(DUMMY_CONTENT);
37 | private static final JSch JSCH = new JSch();
38 | private static final int TIMEOUT = 500;
39 |
40 | public static class round_trip {
41 | @Test
42 | public void a_file_that_is_written_to_the_SFTP_server_can_be_read() {
43 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
44 | executeTestWithRule(
45 | () -> {
46 | Session session = connectToServer(sftpServer);
47 | ChannelSftp channel = connectSftpChannel(session);
48 | channel.put(
49 | new ByteArrayInputStream(
50 | "dummy content".getBytes(UTF_8)
51 | ),
52 | "dummy_file.txt"
53 | );
54 | InputStream file = channel.get("dummy_file.txt");
55 | assertThat(IOUtils.toString(file, UTF_8))
56 | .isEqualTo("dummy content");
57 | channel.disconnect();
58 | session.disconnect();
59 | },
60 | sftpServer
61 | );
62 | }
63 | }
64 |
65 | public static class connection {
66 |
67 | @Test
68 | public void multiple_connections_to_the_server_are_possible() {
69 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
70 | executeTestWithRule(
71 | () -> {
72 | connectAndDisconnect(sftpServer);
73 | connectAndDisconnect(sftpServer);
74 | },
75 | sftpServer
76 | );
77 | }
78 |
79 | @Test
80 | public void a_client_can_connect_to_the_server_at_a_user_specified_port() {
81 | FakeSftpServerRule sftpServer = new FakeSftpServerRule()
82 | .setPort(8394);
83 | executeTestWithRule(
84 | () -> connectToServerAtPort(8394),
85 | sftpServer
86 | );
87 | }
88 | }
89 |
90 | @RunWith(Enclosed.class)
91 | public static class authentication {
92 | public static class server_without_credentials {
93 | @Test
94 | public void the_server_accepts_connections_with_password() {
95 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
96 | executeTestWithRule(
97 | () -> {
98 | Session session = createSessionWithCredentials(
99 | sftpServer,
100 | "dummy user",
101 | "dummy password"
102 | );
103 | session.connect(TIMEOUT);
104 | },
105 | sftpServer
106 | );
107 | }
108 | }
109 |
110 | public static class server_with_credentials_immediately_set {
111 | @Test
112 | public void the_server_accepts_connections_with_correct_password() {
113 | FakeSftpServerRule sftpServer = new FakeSftpServerRule()
114 | .addUser("dummy user", "dummy password");
115 | executeTestWithRule(
116 | () -> {
117 | Session session = createSessionWithCredentials(
118 | sftpServer,
119 | "dummy user",
120 | "dummy password"
121 | );
122 | session.connect(TIMEOUT);
123 | },
124 | sftpServer
125 | );
126 | }
127 |
128 |
129 | @Test
130 | public void the_server_rejects_connections_with_wrong_password() {
131 | FakeSftpServerRule sftpServer = new FakeSftpServerRule()
132 | .addUser("dummy user", "correct password");
133 | executeTestWithRule(
134 | () -> {
135 | Session session = createSessionWithCredentials(
136 | sftpServer,
137 | "dummy user",
138 | "wrong password"
139 | );
140 | assertAuthenticationFails(
141 | () -> session.connect(TIMEOUT)
142 | );
143 | },
144 | sftpServer
145 | );
146 | }
147 |
148 | @Test
149 | public void the_last_password_is_effective_if_addUser_is_called_multiple_times() {
150 | FakeSftpServerRule sftpServer = new FakeSftpServerRule()
151 | .addUser("dummy user", "first password")
152 | .addUser("dummy user", "second password");
153 | executeTestWithRule(
154 | () -> {
155 | Session session = createSessionWithCredentials(
156 | sftpServer,
157 | "dummy user",
158 | "second password"
159 | );
160 | session.connect(TIMEOUT);
161 | },
162 | sftpServer
163 | );
164 | }
165 | }
166 |
167 | public static class server_with_credentials_set_during_test {
168 | @Test
169 | public void the_server_accepts_connections_with_correct_password() {
170 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
171 | executeTestWithRule(
172 | () -> {
173 | sftpServer.addUser("dummy user", "dummy password");
174 | Session session = createSessionWithCredentials(
175 | sftpServer,
176 | "dummy user",
177 | "dummy password"
178 | );
179 | session.connect(TIMEOUT);
180 | },
181 | sftpServer
182 | );
183 | }
184 |
185 | @Test
186 | public void the_server_rejects_connections_with_wrong_password() {
187 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
188 | executeTestWithRule(
189 | () -> {
190 | sftpServer.addUser("dummy user", "correct password");
191 | Session session = createSessionWithCredentials(
192 | sftpServer,
193 | "dummy user",
194 | "wrong password"
195 | );
196 | assertAuthenticationFails(
197 | () -> session.connect(TIMEOUT)
198 | );
199 | },
200 | sftpServer
201 | );
202 | }
203 |
204 | @Test
205 | public void the_last_password_is_effective_if_addUser_is_called_multiple_times() {
206 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
207 | executeTestWithRule(
208 | () -> {
209 | sftpServer
210 | .addUser("dummy user", "first password")
211 | .addUser("dummy user", "second password");
212 | Session session = createSessionWithCredentials(
213 | sftpServer,
214 | "dummy user",
215 | "second password"
216 | );
217 | session.connect(TIMEOUT);
218 | },
219 | sftpServer
220 | );
221 | }
222 | }
223 |
224 | private static Session createSessionWithCredentials(
225 | FakeSftpServerRule sftpServer,
226 | String username,
227 | String password
228 | ) throws JSchException {
229 | return FakeSftpServerRuleTest.createSessionWithCredentials(
230 | username, password, sftpServer.getPort()
231 | );
232 | }
233 |
234 | private static void assertAuthenticationFails(
235 | ThrowingCallable connectToServer
236 | ) {
237 | assertThatThrownBy(connectToServer)
238 | .isInstanceOf(JSchException.class)
239 | .hasMessage("Auth fail");
240 | }
241 | }
242 |
243 | @RunWith(Enclosed.class)
244 | public static class file_upload {
245 | public static class a_text_file {
246 | @Test
247 | public void that_is_put_to_root_directory_via_the_rule_can_be_read_from_server() {
248 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
249 | executeTestWithRule(
250 | () -> {
251 | sftpServer.putFile(
252 | "/dummy_file.txt",
253 | "dummy content with umlaut ü",
254 | UTF_8
255 | );
256 | byte[] file = downloadFile(sftpServer, "/dummy_file.txt");
257 | assertThat(new String(file, UTF_8))
258 | .isEqualTo("dummy content with umlaut ü");
259 | },
260 | sftpServer
261 | );
262 | }
263 |
264 | @Test
265 | public void that_is_put_to_directory_via_the_rule_can_be_read_from_server() {
266 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
267 | executeTestWithRule(
268 | () -> {
269 | sftpServer.putFile(
270 | "/dummy_directory/dummy_file.txt",
271 | "dummy content with umlaut ü",
272 | UTF_8
273 | );
274 | byte[] file = downloadFile(
275 | sftpServer,
276 | "/dummy_directory/dummy_file.txt"
277 | );
278 | assertThat(new String(file, UTF_8))
279 | .isEqualTo("dummy content with umlaut ü");
280 | },
281 | sftpServer
282 | );
283 | }
284 |
285 | @Test
286 | public void cannot_be_put_before_the_test_is_started() {
287 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
288 | Throwable exception = exceptionThrownBy(
289 | () -> sftpServer.putFile(
290 | "/dummy_file.txt", "dummy content", UTF_8
291 | )
292 | );
293 | assertThat(exception)
294 | .isInstanceOf(IllegalStateException.class)
295 | .hasMessage(
296 | "Failed to upload file because test has not been started"
297 | + " or is already finished."
298 | );
299 | }
300 |
301 | @Test
302 | public void cannot_be_put_after_the_test_is_finished() {
303 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
304 | executeTestWithRule(
305 | () -> {},
306 | sftpServer
307 | );
308 | Throwable exception = exceptionThrownBy(
309 | () -> sftpServer.putFile(
310 | "/dummy_file.txt", "dummy content", UTF_8
311 | )
312 | );
313 | assertThat(exception)
314 | .isInstanceOf(IllegalStateException.class)
315 | .hasMessage(
316 | "Failed to upload file because test has not been started"
317 | + " or is already finished."
318 | );
319 | }
320 | }
321 |
322 | public static class a_binary_file {
323 | @Test
324 | public void that_is_put_to_root_directory_via_the_rule_can_be_read_from_server() {
325 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
326 | executeTestWithRule(
327 | () -> {
328 | sftpServer.putFile("/dummy_file.bin", DUMMY_CONTENT);
329 | byte[] file = downloadFile(sftpServer, "/dummy_file.bin");
330 | assertThat(file).isEqualTo(DUMMY_CONTENT);
331 | },
332 | sftpServer
333 | );
334 | }
335 |
336 | @Test
337 | public void that_is_put_to_directory_via_the_rule_can_be_read_from_server() {
338 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
339 | executeTestWithRule(
340 | () -> {
341 | sftpServer.putFile(
342 | "/dummy_directory/dummy_file.bin",
343 | DUMMY_CONTENT
344 | );
345 | byte[] file = downloadFile(
346 | sftpServer,
347 | "/dummy_directory/dummy_file.bin"
348 | );
349 | assertThat(file).isEqualTo(DUMMY_CONTENT);
350 | },
351 | sftpServer
352 | );
353 | }
354 |
355 | @Test
356 | public void cannot_be_put_before_the_test_is_started() {
357 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
358 | Throwable exception = exceptionThrownBy(
359 | () -> sftpServer.putFile("/dummy_file.bin", DUMMY_CONTENT)
360 | );
361 | assertThat(exception)
362 | .isInstanceOf(IllegalStateException.class)
363 | .hasMessage(
364 | "Failed to upload file because test has not been started"
365 | + " or is already finished."
366 | );
367 | }
368 |
369 | @Test
370 | public void cannot_be_put_after_the_test_is_finished() {
371 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
372 | executeTestWithRule(
373 | () -> {},
374 | sftpServer
375 | );
376 | Throwable exception = exceptionThrownBy(
377 | () -> sftpServer.putFile("/dummy_file.bin", DUMMY_CONTENT)
378 | );
379 | assertThat(exception)
380 | .isInstanceOf(IllegalStateException.class)
381 | .hasMessage(
382 | "Failed to upload file because test has not been started"
383 | + " or is already finished."
384 | );
385 | }
386 | }
387 |
388 | public static class a_file_from_a_stream {
389 | @Test
390 | public void that_is_put_to_root_directory_via_the_rule_can_be_read_from_server() {
391 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
392 | executeTestWithRule(
393 | () -> {
394 | InputStream is = new ByteArrayInputStream(DUMMY_CONTENT);
395 | sftpServer.putFile("/dummy_file.bin", is);
396 | byte[] file = downloadFile(sftpServer, "/dummy_file.bin");
397 | assertThat(file).isEqualTo(DUMMY_CONTENT);
398 | },
399 | sftpServer
400 | );
401 | }
402 |
403 | @Test
404 | public void that_is_put_to_directory_via_the_rule_can_be_read_from_server() {
405 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
406 | executeTestWithRule(
407 | () -> {
408 | InputStream is = new ByteArrayInputStream(DUMMY_CONTENT);
409 | sftpServer.putFile("/dummy_directory/dummy_file.bin", is);
410 | byte[] file = downloadFile(
411 | sftpServer,
412 | "/dummy_directory/dummy_file.bin"
413 | );
414 | assertThat(file).isEqualTo(DUMMY_CONTENT);
415 | },
416 | sftpServer
417 | );
418 | }
419 |
420 | @Test
421 | public void cannot_be_put_before_the_test_is_started() {
422 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
423 | Throwable exception = exceptionThrownBy(
424 | () -> sftpServer.putFile("/dummy_file.bin", DUMMY_STREAM)
425 | );
426 | assertThat(exception)
427 | .isInstanceOf(IllegalStateException.class)
428 | .hasMessage(
429 | "Failed to upload file because test has not been started"
430 | + " or is already finished."
431 | );
432 | }
433 |
434 | @Test
435 | public void cannot_be_put_after_the_test_is_finished() {
436 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
437 | executeTestWithRule(
438 | () -> {},
439 | sftpServer
440 | );
441 | Throwable exception = exceptionThrownBy(
442 | () -> sftpServer.putFile("/dummy_file.bin", DUMMY_STREAM)
443 | );
444 | assertThat(exception)
445 | .isInstanceOf(IllegalStateException.class)
446 | .hasMessage(
447 | "Failed to upload file because test has not been started"
448 | + " or is already finished."
449 | );
450 | }
451 | }
452 | }
453 |
454 | @RunWith(Enclosed.class)
455 | public static class directory_creation {
456 |
457 | public static class a_single_directory {
458 | @Test
459 | public void that_is_created_with_the_rule_can_be_read_by_a_client() {
460 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
461 | executeTestWithRule(
462 | () -> {
463 | sftpServer.createDirectory("/a/directory");
464 | assertEmptyDirectory(sftpServer, "/a/directory");
465 | },
466 | sftpServer
467 | );
468 | }
469 |
470 | @Test
471 | public void cannot_be_created_before_the_test_is_started() {
472 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
473 | Throwable exception = exceptionThrownBy(
474 | () -> sftpServer.createDirectory("/a/directory")
475 | );
476 | assertThat(exception)
477 | .isInstanceOf(IllegalStateException.class)
478 | .hasMessage(
479 | "Failed to create directory because test has not been"
480 | + " started or is already finished."
481 | );
482 | }
483 |
484 | @Test
485 | public void cannot_be_created_after_the_test_is_finished() {
486 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
487 | executeTestWithRule(
488 | () -> {},
489 | sftpServer
490 | );
491 | Throwable exception = exceptionThrownBy(
492 | () -> sftpServer.createDirectory("/a/directory")
493 | );
494 | assertThat(exception)
495 | .isInstanceOf(IllegalStateException.class)
496 | .hasMessage(
497 | "Failed to create directory because test has not been"
498 | + " started or is already finished."
499 | );
500 | }
501 | }
502 |
503 | public static class multiple_directories {
504 | @Test
505 | public void that_are_created_with_the_rule_can_be_read_by_a_client() {
506 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
507 | executeTestWithRule(
508 | () -> {
509 | sftpServer.createDirectories(
510 | "/a/directory",
511 | "/another/directory"
512 | );
513 | assertEmptyDirectory(sftpServer, "/a/directory");
514 | assertEmptyDirectory(sftpServer, "/another/directory");
515 | },
516 | sftpServer
517 | );
518 | }
519 |
520 | @Test
521 | public void cannot_be_created_before_the_test_is_started() {
522 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
523 | Throwable exception = exceptionThrownBy(
524 | () -> sftpServer.createDirectories(
525 | "/a/directory",
526 | "/another/directory"
527 | )
528 | );
529 | assertThat(exception)
530 | .isInstanceOf(IllegalStateException.class)
531 | .hasMessage(
532 | "Failed to create directory because test has not been"
533 | + " started or is already finished."
534 | );
535 | }
536 |
537 | @Test
538 | public void cannot_be_created_after_the_test_is_finished() {
539 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
540 | executeTestWithRule(
541 | () -> {},
542 | sftpServer
543 | );
544 | Throwable exception = exceptionThrownBy(
545 | () -> sftpServer.createDirectories(
546 | "/a/directory",
547 | "/another/directory"
548 | )
549 | );
550 | assertThat(exception)
551 | .isInstanceOf(IllegalStateException.class)
552 | .hasMessage(
553 | "Failed to create directory because test has not been"
554 | + " started or is already finished."
555 | );
556 | }
557 | }
558 |
559 | private static void assertEmptyDirectory(
560 | FakeSftpServerRule sftpServer,
561 | String directory
562 | ) throws JSchException, SftpException {
563 | Session session = connectToServer(sftpServer);
564 | ChannelSftp channel = connectSftpChannel(session);
565 | Vector entries = channel.ls(directory);
566 | assertThat(entries).hasSize(2); //these are the entries . and ..
567 | channel.disconnect();
568 | session.disconnect();
569 | }
570 | }
571 |
572 | @RunWith(Enclosed.class)
573 | public static class file_download {
574 | public static class a_text_file {
575 | @Test
576 | public void that_is_written_to_the_server_can_be_retrieved_with_the_rule() {
577 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
578 | executeTestWithRule(
579 | () -> {
580 | uploadFile(
581 | sftpServer,
582 | "/dummy_directory/dummy_file.txt",
583 | "dummy content with umlaut ü".getBytes(UTF_8)
584 | );
585 | String fileContent = sftpServer.getFileContent(
586 | "/dummy_directory/dummy_file.txt",
587 | UTF_8
588 | );
589 | assertThat(fileContent)
590 | .isEqualTo("dummy content with umlaut ü");
591 | },
592 | sftpServer
593 | );
594 | }
595 |
596 | @Test
597 | public void cannot_be_retrieved_before_the_test_is_started() {
598 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
599 | Throwable exception = exceptionThrownBy(
600 | () -> sftpServer.getFileContent(
601 | "/dummy_directory/dummy_file.txt"
602 | )
603 | );
604 | assertThat(exception)
605 | .isInstanceOf(IllegalStateException.class)
606 | .hasMessage(
607 | "Failed to download file because test has not been started"
608 | + " or is already finished."
609 | );
610 | }
611 |
612 | @Test
613 | public void cannot_be_retrieved_after_the_test_is_finished() {
614 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
615 | executeTestWithRule(
616 | () -> uploadFile(
617 | sftpServer,
618 | "/dummy_directory/dummy_file.txt",
619 | "dummy content".getBytes(UTF_8)
620 | ),
621 | sftpServer
622 | );
623 | Throwable exception = exceptionThrownBy(
624 | () -> sftpServer.getFileContent(
625 | "/dummy_directory/dummy_file.txt"
626 | )
627 | );
628 | assertThat(exception)
629 | .isInstanceOf(IllegalStateException.class)
630 | .hasMessage(
631 | "Failed to download file because test has not been started"
632 | + " or is already finished."
633 | );
634 | }
635 | }
636 |
637 | public static class a_binary_file {
638 | @Test
639 | public void that_is_written_to_the_server_can_be_retrieved_with_the_rule() {
640 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
641 | executeTestWithRule(
642 | () -> {
643 | uploadFile(
644 | sftpServer,
645 | "/dummy_directory/dummy_file.bin",
646 | DUMMY_CONTENT
647 | );
648 | byte[] fileContent = sftpServer.getFileContent(
649 | "/dummy_directory/dummy_file.bin"
650 | );
651 | assertThat(fileContent).isEqualTo(DUMMY_CONTENT);
652 | },
653 | sftpServer
654 | );
655 | }
656 |
657 | @Test
658 | public void cannot_be_retrieved_before_the_test_is_started() {
659 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
660 | Throwable exception = exceptionThrownBy(
661 | () -> sftpServer.getFileContent(
662 | "/dummy_directory/dummy_file.bin"
663 | )
664 | );
665 | assertThat(exception)
666 | .isInstanceOf(IllegalStateException.class)
667 | .hasMessage(
668 | "Failed to download file because test has not been started"
669 | + " or is already finished."
670 | );
671 | }
672 |
673 | @Test
674 | public void cannot_be_retrieved_after_the_test_is_finished() {
675 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
676 | executeTestWithRule(
677 | () -> uploadFile(
678 | sftpServer,
679 | "/dummy_directory/dummy_file.bin",
680 | DUMMY_CONTENT
681 | ),
682 | sftpServer
683 | );
684 | Throwable exception = exceptionThrownBy(
685 | () -> sftpServer.getFileContent("/dummy_file.bin")
686 | );
687 | assertThat(exception)
688 | .isInstanceOf(IllegalStateException.class)
689 | .hasMessage(
690 | "Failed to download file because test has not been started"
691 | + " or is already finished."
692 | );
693 | }
694 | }
695 | }
696 |
697 | public static class file_existence_check {
698 |
699 | @Test
700 | public void exists_returns_true_for_a_file_that_exists_on_the_server() {
701 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
702 | executeTestWithRule(
703 | () -> {
704 | uploadFile(
705 | sftpServer,
706 | "/dummy_directory/dummy_file.bin",
707 | DUMMY_CONTENT
708 | );
709 | boolean exists = sftpServer.existsFile(
710 | "/dummy_directory/dummy_file.bin"
711 | );
712 | assertThat(exists).isTrue();
713 | },
714 | sftpServer
715 | );
716 | }
717 |
718 | @Test
719 | public void exists_returns_false_for_a_file_that_does_not_exists_on_the_server() {
720 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
721 | executeTestWithRule(
722 | () -> {
723 | boolean exists = sftpServer.existsFile(
724 | "/dummy_directory/dummy_file.bin"
725 | );
726 | assertThat(exists).isFalse();
727 | },
728 | sftpServer
729 | );
730 | }
731 |
732 | @Test
733 | public void exists_returns_false_for_a_directory_that_exists_on_the_server() {
734 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
735 | executeTestWithRule(
736 | () -> {
737 | uploadFile(
738 | sftpServer,
739 | "/dummy_directory/dummy_file.bin",
740 | DUMMY_CONTENT
741 | );
742 | boolean exists = sftpServer.existsFile("/dummy_directory");
743 | assertThat(exists).isFalse();
744 | },
745 | sftpServer
746 | );
747 | }
748 |
749 | @Test
750 | public void existence_of_a_file_cannot_be_checked_before_the_test_is_started() {
751 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
752 | Throwable exception = exceptionThrownBy(
753 | () -> sftpServer.existsFile("/dummy_file.bin")
754 | );
755 | assertThat(exception)
756 | .isInstanceOf(IllegalStateException.class)
757 | .hasMessage(
758 | "Failed to check existence of file because test has not"
759 | + " been started or is already finished."
760 | );
761 | }
762 |
763 | @Test
764 | public void existence_of_a_file_cannot_be_checked_after_the_test_is_finished() {
765 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
766 | executeTestWithRule(
767 | () -> {},
768 | sftpServer
769 | );
770 | Throwable exception = exceptionThrownBy(
771 | () -> sftpServer.existsFile("/dummy_file.bin")
772 | );
773 | assertThat(exception)
774 | .isInstanceOf(IllegalStateException.class)
775 | .hasMessage(
776 | "Failed to check existence of file because test has not"
777 | + " been started or is already finished."
778 | );
779 | }
780 | }
781 |
782 | public static class server_shutdown {
783 | @Test
784 | public void after_a_successful_test_SFTP_server_is_shutdown() {
785 | FakeSftpServerRule sftpServer = new FakeSftpServerRule()
786 | .setPort(DUMMY_PORT);
787 | executeTestWithRule(
788 | () -> {},
789 | sftpServer
790 | );
791 | assertConnectionToSftpServerNotPossible(DUMMY_PORT);
792 | }
793 |
794 | @Test
795 | public void after_an_erroneous_test_SFTP_server_is_shutdown() {
796 | FakeSftpServerRule sftpServer = new FakeSftpServerRule()
797 | .setPort(DUMMY_PORT);
798 | executeTestThatThrowsExceptionWithRule(
799 | () -> {
800 | throw new RuntimeException();
801 | },
802 | sftpServer
803 | );
804 | assertConnectionToSftpServerNotPossible(DUMMY_PORT);
805 | }
806 |
807 | @Test
808 | public void after_a_test_first_SFTP_server_is_shutdown_when_port_was_changed_during_test() {
809 | FakeSftpServerRule sftpServer = new FakeSftpServerRule()
810 | .setPort(DUMMY_PORT - 1);
811 | executeTestWithRule(
812 | () -> sftpServer.setPort(DUMMY_PORT),
813 | sftpServer
814 | );
815 | assertConnectionToSftpServerNotPossible(DUMMY_PORT - 1);
816 | }
817 |
818 | @Test
819 | public void after_a_test_second_SFTP_server_is_shutdown_when_port_was_changed_during_test() {
820 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
821 | executeTestWithRule(
822 | () -> sftpServer.setPort(DUMMY_PORT),
823 | sftpServer
824 | );
825 | assertConnectionToSftpServerNotPossible(DUMMY_PORT);
826 | }
827 |
828 | private void assertConnectionToSftpServerNotPossible(
829 | int port
830 | ) {
831 | Throwable throwable = catchThrowable(
832 | () -> connectToServerAtPort(port)
833 | );
834 | assertThat(throwable)
835 | .withFailMessage(
836 | "SFTP server is still running on port %d.",
837 | port
838 | )
839 | .hasCauseInstanceOf(ConnectException.class);
840 | }
841 | }
842 |
843 | public static class port_selection {
844 | @Test
845 | public void by_default_two_rules_run_servers_at_different_ports() {
846 | FakeSftpServerRule firstSftpServer = new FakeSftpServerRule();
847 | AtomicInteger portCaptureForFirstServer = new AtomicInteger();
848 | FakeSftpServerRule secondSftpServer = new FakeSftpServerRule();
849 | AtomicInteger portCaptureForSecondServer = new AtomicInteger();
850 |
851 | executeTestWithRule(
852 | () -> portCaptureForFirstServer.set(firstSftpServer.getPort()),
853 | firstSftpServer
854 | );
855 | executeTestWithRule(
856 | () -> portCaptureForSecondServer.set(secondSftpServer.getPort()),
857 | secondSftpServer
858 | );
859 |
860 | assertThat(portCaptureForFirstServer)
861 | .doesNotHaveValue(portCaptureForSecondServer.get());
862 | }
863 |
864 | @Test
865 | public void the_port_can_be_changed_during_the_test() {
866 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
867 | executeTestWithRule(
868 | () -> {
869 | sftpServer.setPort(DUMMY_PORT);
870 | connectToServerAtPort(DUMMY_PORT);
871 | },
872 | sftpServer
873 | );
874 | }
875 |
876 | @Test
877 | public void it_is_not_possible_to_set_a_negative_port() {
878 | assertThatThrownBy(() -> new FakeSftpServerRule().setPort(-1))
879 | .isInstanceOf(IllegalArgumentException.class)
880 | .hasMessage(
881 | "Port cannot be set to -1 because only ports between 1 and"
882 | + " 65535 are valid."
883 | );
884 | }
885 |
886 | @Test
887 | public void it_is_not_possible_to_set_port_zero() {
888 | assertThatThrownBy(() -> new FakeSftpServerRule().setPort(0))
889 | .isInstanceOf(IllegalArgumentException.class)
890 | .hasMessage(
891 | "Port cannot be set to 0 because only ports between 1 and"
892 | + " 65535 are valid."
893 | );
894 | }
895 |
896 | @Test
897 | public void the_port_can_be_set_to_1() {
898 | //I don't test the connection, because port 1 can not be used by a
899 | //standard user.
900 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
901 | sftpServer.setPort(1);
902 | }
903 |
904 | @Test
905 | public void the_server_can_be_run_at_port_65535() {
906 | FakeSftpServerRule sftpServer = new FakeSftpServerRule()
907 | .setPort(65535);
908 | executeTestWithRule(
909 | () -> connectToServerAtPort(65535),
910 | sftpServer
911 | );
912 | }
913 |
914 | @Test
915 | public void it_is_not_possible_to_set_a_port_greater_than_65535() {
916 | assertThatThrownBy(() -> new FakeSftpServerRule().setPort(65536))
917 | .isInstanceOf(IllegalArgumentException.class)
918 | .hasMessage(
919 | "Port cannot be set to 65536 because only ports between 1"
920 | + " and 65535 are valid."
921 | );
922 | }
923 | }
924 |
925 | @RunWith(Enclosed.class)
926 | public static class port_query {
927 |
928 | public static class random_port {
929 | @Test
930 | public void cannot_be_read_before_the_test() {
931 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
932 | assertPortCannotBeRead(sftpServer);
933 | }
934 |
935 | @Test
936 | public void can_be_read_during_the_test() {
937 | AtomicInteger portCapture = new AtomicInteger();
938 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
939 | executeTestWithRule(
940 | () -> portCapture.set(sftpServer.getPort()),
941 | sftpServer
942 | );
943 | assertThat(portCapture).doesNotHaveValue(0);
944 | }
945 |
946 | @Test
947 | public void cannot_be_read_after_the_test() {
948 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
949 | executeTestWithRule(
950 | () -> {},
951 | sftpServer
952 | );
953 | assertPortCannotBeRead(sftpServer);
954 | }
955 |
956 | private void assertPortCannotBeRead(FakeSftpServerRule sftpServer) {
957 | assertThatThrownBy(sftpServer::getPort)
958 | .isInstanceOf(IllegalStateException.class)
959 | .hasMessage(
960 | "Failed to call getPort() because test has not been"
961 | + " started or is already finished."
962 | );
963 | }
964 | }
965 |
966 | public static class specified_port {
967 | @Test
968 | public void can_be_read_before_the_test() {
969 | FakeSftpServerRule sftpServer = new FakeSftpServerRule()
970 | .setPort(DUMMY_PORT);
971 | int port = sftpServer.getPort();
972 | assertThat(port).isEqualTo(DUMMY_PORT);
973 | }
974 |
975 | @Test
976 | public void can_be_read_during_the_test() {
977 | AtomicInteger portCapture = new AtomicInteger();
978 | FakeSftpServerRule sftpServer = new FakeSftpServerRule()
979 | .setPort(DUMMY_PORT);
980 | executeTestWithRule(
981 | () -> portCapture.set(sftpServer.getPort()),
982 | sftpServer
983 | );
984 | assertThat(portCapture).hasValue(DUMMY_PORT);
985 | }
986 |
987 | @Test
988 | public void can_be_read_after_the_test() {
989 | FakeSftpServerRule sftpServer = new FakeSftpServerRule()
990 | .setPort(DUMMY_PORT);
991 | executeTestWithRule(
992 | () -> {},
993 | sftpServer
994 | );
995 | int port = sftpServer.getPort();
996 | assertThat(port).isEqualTo(DUMMY_PORT);
997 | }
998 | }
999 | }
1000 |
1001 | public static class cleanup {
1002 |
1003 | @Test
1004 | public void deletes_file_in_root_directory() {
1005 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
1006 | executeTestWithRule(
1007 | () -> {
1008 | uploadFile(
1009 | sftpServer,
1010 | "/dummy_file.bin",
1011 | DUMMY_CONTENT
1012 | );
1013 | sftpServer.deleteAllFilesAndDirectories();
1014 | assertFileDoesNotExist(
1015 | sftpServer,
1016 | "/dummy_file.bin"
1017 | );
1018 | },
1019 | sftpServer
1020 | );
1021 | }
1022 |
1023 | @Test
1024 | public void deletes_file_in_directory() {
1025 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
1026 | executeTestWithRule(
1027 | () -> {
1028 | uploadFile(
1029 | sftpServer,
1030 | "/dummy_directory/dummy_file.bin",
1031 | DUMMY_CONTENT
1032 | );
1033 | sftpServer.deleteAllFilesAndDirectories();
1034 | assertFileDoesNotExist(
1035 | sftpServer,
1036 | "/dummy_directory/dummy_file.bin"
1037 | );
1038 | },
1039 | sftpServer
1040 | );
1041 | }
1042 |
1043 | @Test
1044 | public void deletes_directory() {
1045 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
1046 | executeTestWithRule(
1047 | () -> {
1048 | sftpServer.createDirectory("/dummy_directory");
1049 | sftpServer.deleteAllFilesAndDirectories();
1050 | assertDirectoryDoesNotExist(
1051 | sftpServer,
1052 | "/dummy_directory"
1053 | );
1054 | },
1055 | sftpServer
1056 | );
1057 | }
1058 |
1059 | @Test
1060 | public void works_on_an_empty_filesystem() {
1061 | FakeSftpServerRule sftpServer = new FakeSftpServerRule();
1062 | executeTestWithRule(
1063 | sftpServer::deleteAllFilesAndDirectories,
1064 | sftpServer
1065 | );
1066 | }
1067 |
1068 | private static void assertFileDoesNotExist(
1069 | FakeSftpServerRule sftpServer,
1070 | String path
1071 | ) {
1072 | boolean exists = sftpServer.existsFile(path);
1073 | assertThat(exists).isFalse();
1074 | }
1075 |
1076 | private static void assertDirectoryDoesNotExist(
1077 | FakeSftpServerRule sftpServer,
1078 | String directory
1079 | ) throws JSchException {
1080 | Session session = connectToServer(sftpServer);
1081 | ChannelSftp channel = connectSftpChannel(session);
1082 | try {
1083 | assertThatThrownBy(() -> channel.ls(directory))
1084 | .isInstanceOf(SftpException.class)
1085 | .hasMessage("No such file or directory");
1086 | } finally {
1087 | channel.disconnect();
1088 | session.disconnect();
1089 | }
1090 | }
1091 | }
1092 |
1093 | private static Session connectToServer(
1094 | FakeSftpServerRule sftpServer
1095 | ) throws JSchException {
1096 | return connectToServerAtPort(sftpServer.getPort());
1097 | }
1098 |
1099 | private static Session connectToServerAtPort(
1100 | int port
1101 | ) throws JSchException {
1102 | Session session = createSessionWithCredentials(
1103 | "dummy user", "dummy password", port
1104 | );
1105 | session.connect(TIMEOUT);
1106 | return session;
1107 | }
1108 |
1109 | private static ChannelSftp connectSftpChannel(
1110 | Session session
1111 | ) throws JSchException {
1112 | ChannelSftp channel = (ChannelSftp) session.openChannel("sftp");
1113 | channel.connect();
1114 | return channel;
1115 | }
1116 |
1117 | private static void connectAndDisconnect(
1118 | FakeSftpServerRule sftpServer
1119 | ) throws JSchException {
1120 | Session session = connectToServer(sftpServer);
1121 | ChannelSftp channel = connectSftpChannel(session);
1122 | channel.disconnect();
1123 | session.disconnect();
1124 | }
1125 |
1126 | private static Session createSessionWithCredentials(
1127 | String username,
1128 | String password,
1129 | int port
1130 | ) throws JSchException {
1131 | Session session = JSCH.getSession(username, "127.0.0.1", port);
1132 | session.setConfig("StrictHostKeyChecking", "no");
1133 | session.setPassword(password);
1134 | return session;
1135 | }
1136 |
1137 | private static byte[] downloadFile(
1138 | FakeSftpServerRule server,
1139 | String path
1140 | ) throws JSchException, SftpException, IOException {
1141 | Session session = connectToServer(server);
1142 | ChannelSftp channel = connectSftpChannel(session);
1143 | try {
1144 | InputStream is = channel.get(path);
1145 | return toByteArray(is);
1146 | } finally {
1147 | channel.disconnect();
1148 | session.disconnect();
1149 | }
1150 | }
1151 |
1152 | private static void uploadFile(
1153 | FakeSftpServerRule server,
1154 | String pathAsString,
1155 | byte[] content
1156 | ) throws JSchException, SftpException {
1157 | Session session = connectToServer(server);
1158 | ChannelSftp channel = connectSftpChannel(session);
1159 | try {
1160 | Path path = Paths.get(pathAsString);
1161 | if (!path.getParent().equals(path.getRoot()))
1162 | channel.mkdir(path.getParent().toString());
1163 | channel.put(new ByteArrayInputStream(content), pathAsString);
1164 | } finally {
1165 | channel.disconnect();
1166 | session.disconnect();
1167 | }
1168 | }
1169 | }
1170 |
--------------------------------------------------------------------------------