http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/ae8d1c99/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpTest.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpTest.java b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpTest.java index 3ddfe18..983addf 100644 --- a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpTest.java +++ b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpTest.java @@ -34,10 +34,10 @@ import java.nio.file.Files; import java.nio.file.LinkOption; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.EnumSet; -import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -89,15 +89,14 @@ import org.apache.sshd.server.subsystem.sftp.AbstractSftpEventListenerAdapter; import org.apache.sshd.server.subsystem.sftp.DirectoryHandle; import org.apache.sshd.server.subsystem.sftp.FileHandle; import org.apache.sshd.server.subsystem.sftp.Handle; +import org.apache.sshd.server.subsystem.sftp.SftpEventListener; import org.apache.sshd.server.subsystem.sftp.SftpSubsystem; import org.apache.sshd.server.subsystem.sftp.SftpSubsystemFactory; -import org.apache.sshd.util.test.JSchLogger; import org.apache.sshd.util.test.SimpleUserInfo; import org.apache.sshd.util.test.Utils; import org.junit.After; import org.junit.Assume; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runners.MethodSorters; @@ -115,11 +114,6 @@ public class SftpTest extends AbstractSftpClientTestSupport { super(); } - @BeforeClass - public static void jschInit() { - JSchLogger.init(); - } - @Before public void setUp() throws Exception { setupServer(); @@ -134,8 +128,6 @@ public class SftpTest extends AbstractSftpClientTestSupport { if (session != null) { session.disconnect(); } - - tearDownServer(); } @Test // see SSHD-547 @@ -152,32 +144,26 @@ public class SftpTest extends AbstractSftpClientTestSupport { rnd.fill(expectedRandom); byte[] expectedText = (getClass().getName() + "#" + getCurrentTestName()).getBytes(StandardCharsets.UTF_8); - try (SshClient client = setupTestClient()) { - client.start(); - - try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { - session.addPasswordIdentity(getCurrentTestName()); - session.auth().verify(5L, TimeUnit.SECONDS); - - try (SftpClient sftp = session.createSftpClient()) { - String file = Utils.resolveRelativeRemotePath(parentPath, testFile); - - try (CloseableHandle handle = sftp.open(file, OpenMode.Create, OpenMode.Write, OpenMode.Read, OpenMode.Append)) { - sftp.write(handle, 7365L, expectedRandom); - byte[] actualRandom = new byte[expectedRandom.length]; - int readLen = sftp.read(handle, 0L, actualRandom); - assertEquals("Incomplete random data read", expectedRandom.length, readLen); - assertArrayEquals("Mismatched read random data", expectedRandom, actualRandom); - - sftp.write(handle, 3777347L, expectedText); - byte[] actualText = new byte[expectedText.length]; - readLen = sftp.read(handle, actualRandom.length, actualText); - assertEquals("Incomplete text data read", actualText.length, readLen); - assertArrayEquals("Mismatched read text data", expectedText, actualText); - } + try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { + session.addPasswordIdentity(getCurrentTestName()); + session.auth().verify(5L, TimeUnit.SECONDS); + + try (SftpClient sftp = session.createSftpClient()) { + String file = Utils.resolveRelativeRemotePath(parentPath, testFile); + + try (CloseableHandle handle = sftp.open(file, OpenMode.Create, OpenMode.Write, OpenMode.Read, OpenMode.Append)) { + sftp.write(handle, 7365L, expectedRandom); + byte[] actualRandom = new byte[expectedRandom.length]; + int readLen = sftp.read(handle, 0L, actualRandom); + assertEquals("Incomplete random data read", expectedRandom.length, readLen); + assertArrayEquals("Mismatched read random data", expectedRandom, actualRandom); + + sftp.write(handle, 3777347L, expectedText); + byte[] actualText = new byte[expectedText.length]; + readLen = sftp.read(handle, actualRandom.length, actualText); + assertEquals("Incomplete text data read", actualText.length, readLen); + assertArrayEquals("Mismatched read text data", expectedText, actualText); } - } finally { - client.stop(); } } @@ -204,36 +190,32 @@ public class SftpTest extends AbstractSftpClientTestSupport { rnd.fill(expected); Files.write(testFile, expected); - try (SshClient client = setupTestClient()) { - client.start(); - - try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { - session.addPasswordIdentity(getCurrentTestName()); - session.auth().verify(5L, TimeUnit.SECONDS); - - try (SftpClient sftp = session.createSftpClient()) { - String file = Utils.resolveRelativeRemotePath(parentPath, testFile); - byte[] actual = new byte[expected.length]; - int maxAllowed = actual.length / 4; - // allow less than actual - PropertyResolverUtils.updateProperty(sshd, SftpSubsystem.MAX_PACKET_LENGTH_PROP, maxAllowed); - try (CloseableHandle handle = sftp.open(file, OpenMode.Read)) { - int readLen = sftp.read(handle, 0L, actual); - assertEquals("Mismatched read len", maxAllowed, readLen); - - for (int index = 0; index < readLen; index++) { - byte expByte = expected[index]; - byte actByte = actual[index]; - if (expByte != actByte) { - fail("Mismatched values at index=" + index - + ": expected=0x" + Integer.toHexString(expByte & 0xFF) - + ", actual=0x" + Integer.toHexString(actByte & 0xFF)); - } + try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { + session.addPasswordIdentity(getCurrentTestName()); + session.auth().verify(5L, TimeUnit.SECONDS); + + try (SftpClient sftp = session.createSftpClient()) { + String file = Utils.resolveRelativeRemotePath(parentPath, testFile); + byte[] actual = new byte[expected.length]; + int maxAllowed = actual.length / 4; + // allow less than actual + PropertyResolverUtils.updateProperty(sshd, SftpSubsystem.MAX_PACKET_LENGTH_PROP, maxAllowed); + try (CloseableHandle handle = sftp.open(file, OpenMode.Read)) { + int readLen = sftp.read(handle, 0L, actual); + assertEquals("Mismatched read len", maxAllowed, readLen); + + for (int index = 0; index < readLen; index++) { + byte expByte = expected[index]; + byte actByte = actual[index]; + if (expByte != actByte) { + fail("Mismatched values at index=" + index + + ": expected=0x" + Integer.toHexString(expByte & 0xFF) + + ", actual=0x" + Integer.toHexString(actByte & 0xFF)); } } + } finally { + PropertyResolverUtils.updateProperty(sshd, SftpSubsystem.MAX_PACKET_LENGTH_PROP, SftpSubsystem.DEFAULT_MAX_PACKET_LENGTH); } - } finally { - client.stop(); } } } @@ -249,20 +231,14 @@ public class SftpTest extends AbstractSftpClientTestSupport { } }); - try (SshClient client = setupTestClient()) { - client.start(); + try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { + session.addPasswordIdentity(getCurrentTestName()); + session.auth().verify(5L, TimeUnit.SECONDS); - try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { - session.addPasswordIdentity(getCurrentTestName()); - session.auth().verify(5L, TimeUnit.SECONDS); - - try (SftpClient sftp = session.createSftpClient()) { - String rootDir = sftp.canonicalPath("/"); - String upDir = sftp.canonicalPath(rootDir + "/.."); - assertEquals("Mismatched root dir parent", rootDir, upDir); - } - } finally { - client.stop(); + try (SftpClient sftp = session.createSftpClient()) { + String rootDir = sftp.canonicalPath("/"); + String upDir = sftp.canonicalPath(rootDir + "/.."); + assertEquals("Mismatched root dir parent", rootDir, upDir); } } } @@ -283,70 +259,58 @@ public class SftpTest extends AbstractSftpClientTestSupport { assertHierarchyTargetFolderExists(lclSftp); sshd.setFileSystemFactory(new VirtualFileSystemFactory(lclSftp)); - try (SshClient client = setupTestClient()) { - client.start(); - - try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { - session.addPasswordIdentity(getCurrentTestName()); - session.auth().verify(5L, TimeUnit.SECONDS); + try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { + session.addPasswordIdentity(getCurrentTestName()); + session.auth().verify(5L, TimeUnit.SECONDS); - String escapePath; - if (useAbsolutePath) { - escapePath = targetPath.toString(); - if (OsUtils.isWin32()) { - escapePath = "/" + escapePath.replace(File.separatorChar, '/'); - } - } else { - Path parent = lclSftp.getParent(); - Path forbidden = Files.createDirectories(parent.resolve("forbidden")); - escapePath = "../" + forbidden.getFileName(); + String escapePath; + if (useAbsolutePath) { + escapePath = targetPath.toString(); + if (OsUtils.isWin32()) { + escapePath = "/" + escapePath.replace(File.separatorChar, '/'); } + } else { + Path parent = lclSftp.getParent(); + Path forbidden = Files.createDirectories(parent.resolve("forbidden")); + escapePath = "../" + forbidden.getFileName(); + } - try (SftpClient sftp = session.createSftpClient()) { - SftpClient.Attributes attrs = sftp.stat(escapePath); - fail("Unexpected escape success for path=" + escapePath + ": " + attrs); - } catch (SftpException e) { - int expected = OsUtils.isWin32() || (!useAbsolutePath) - ? SftpConstants.SSH_FX_INVALID_FILENAME - : SftpConstants.SSH_FX_NO_SUCH_FILE; - assertEquals("Mismatched status for " + escapePath, - SftpConstants.getStatusName(expected), - SftpConstants.getStatusName(e.getStatus())); - } - } finally { - client.stop(); + try (SftpClient sftp = session.createSftpClient()) { + SftpClient.Attributes attrs = sftp.stat(escapePath); + fail("Unexpected escape success for path=" + escapePath + ": " + attrs); + } catch (SftpException e) { + int expected = OsUtils.isWin32() || (!useAbsolutePath) + ? SftpConstants.SSH_FX_INVALID_FILENAME + : SftpConstants.SSH_FX_NO_SUCH_FILE; + assertEquals("Mismatched status for " + escapePath, + SftpConstants.getStatusName(expected), + SftpConstants.getStatusName(e.getStatus())); } } } @Test public void testNormalizeRemoteRootValues() throws Exception { - try (SshClient client = setupTestClient()) { - client.start(); - - try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { - session.addPasswordIdentity(getCurrentTestName()); - session.auth().verify(5L, TimeUnit.SECONDS); - - try (SftpClient sftp = session.createSftpClient()) { - StringBuilder sb = new StringBuilder(Long.SIZE + 1); - String expected = sftp.canonicalPath("/"); - for (int i = 0; i < Long.SIZE; i++) { - if (sb.length() > 0) { - sb.setLength(0); - } - - for (int j = 1; j <= i; j++) { - sb.append('/'); - } + try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { + session.addPasswordIdentity(getCurrentTestName()); + session.auth().verify(5L, TimeUnit.SECONDS); + + try (SftpClient sftp = session.createSftpClient()) { + StringBuilder sb = new StringBuilder(Long.SIZE + 1); + String expected = sftp.canonicalPath("/"); + for (int i = 0; i < Long.SIZE; i++) { + if (sb.length() > 0) { + sb.setLength(0); + } - String remotePath = sb.toString(); - String actual = sftp.canonicalPath(remotePath); - assertEquals("Mismatched roots for " + remotePath.length() + " slashes", expected, actual); + for (int j = 1; j <= i; j++) { + sb.append('/'); } + + String remotePath = sb.toString(); + String actual = sftp.canonicalPath(remotePath); + assertEquals("Mismatched roots for " + remotePath.length() + " slashes", expected, actual); } - } finally { - client.stop(); } } } @@ -360,42 +324,36 @@ public class SftpTest extends AbstractSftpClientTestSupport { String file = Utils.resolveRelativeRemotePath(parentPath, testFile); String[] comps = GenericUtils.split(file, '/'); - try (SshClient client = setupTestClient()) { - client.start(); - - Factory<? extends Random> factory = client.getRandomFactory(); - Random rnd = factory.create(); - try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { - session.addPasswordIdentity(getCurrentTestName()); - session.auth().verify(5L, TimeUnit.SECONDS); - - try (SftpClient sftp = session.createSftpClient()) { - StringBuilder sb = new StringBuilder(file.length() + comps.length); - String expected = sftp.canonicalPath(file); - for (int i = 0; i < file.length(); i++) { - if (sb.length() > 0) { - sb.setLength(0); - } + Factory<? extends Random> factory = client.getRandomFactory(); + Random rnd = factory.create(); + try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { + session.addPasswordIdentity(getCurrentTestName()); + session.auth().verify(5L, TimeUnit.SECONDS); + + try (SftpClient sftp = session.createSftpClient()) { + StringBuilder sb = new StringBuilder(file.length() + comps.length); + String expected = sftp.canonicalPath(file); + for (int i = 0; i < file.length(); i++) { + if (sb.length() > 0) { + sb.setLength(0); + } - sb.append(comps[0]); - for (int j = 1; j < comps.length; j++) { - String name = comps[j]; - slashify(sb, rnd); - sb.append(name); - } + sb.append(comps[0]); + for (int j = 1; j < comps.length; j++) { + String name = comps[j]; slashify(sb, rnd); + sb.append(name); + } + slashify(sb, rnd); - if (rnd.random(Byte.SIZE) < (Byte.SIZE / 2)) { - sb.append('.'); - } - - String remotePath = sb.toString(); - String actual = sftp.canonicalPath(remotePath); - assertEquals("Mismatched canonical value for " + remotePath, expected, actual); + if (rnd.random(Byte.SIZE) < (Byte.SIZE / 2)) { + sb.append('.'); } + + String remotePath = sb.toString(); + String actual = sftp.canonicalPath(remotePath); + assertEquals("Mismatched canonical value for " + remotePath, expected, actual); } - } finally { - client.stop(); } } } @@ -421,94 +379,88 @@ public class SftpTest extends AbstractSftpClientTestSupport { File javaFile = testFile.toFile(); assertHierarchyTargetFolderExists(javaFile.getParentFile()); - try (SshClient client = setupTestClient()) { - client.start(); - - try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { - session.addPasswordIdentity(getCurrentTestName()); - session.auth().verify(5L, TimeUnit.SECONDS); + try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { + session.addPasswordIdentity(getCurrentTestName()); + session.auth().verify(5L, TimeUnit.SECONDS); - javaFile.createNewFile(); - javaFile.setWritable(false, false); - javaFile.setReadable(false, false); + javaFile.createNewFile(); + javaFile.setWritable(false, false); + javaFile.setReadable(false, false); - try (SftpClient sftp = session.createSftpClient()) { - boolean isWindows = OsUtils.isWin32(); - - try (SftpClient.CloseableHandle h = sftp.open(file /* no mode == read */)) { - // NOTE: on Windows files are always readable - // see https://svn.apache.org/repos/asf/harmony/enhanced/java/branches/java6/classlib/modules/ - // luni/src/test/api/windows/org/apache/harmony/luni/tests/java/io/WinFileTest.java - assertTrue("Empty read should have failed on " + file, isWindows); - } catch (IOException e) { - if (isWindows) { - throw e; - } - } + try (SftpClient sftp = session.createSftpClient()) { + boolean isWindows = OsUtils.isWin32(); - try (SftpClient.CloseableHandle h = sftp.open(file, EnumSet.of(SftpClient.OpenMode.Write))) { - fail("Empty write should have failed on " + file); - } catch (IOException e) { - // ok + try (SftpClient.CloseableHandle h = sftp.open(file /* no mode == read */)) { + // NOTE: on Windows files are always readable + // see https://svn.apache.org/repos/asf/harmony/enhanced/java/branches/java6/classlib/modules/ + // luni/src/test/api/windows/org/apache/harmony/luni/tests/java/io/WinFileTest.java + assertTrue("Empty read should have failed on " + file, isWindows); + } catch (IOException e) { + if (isWindows) { + throw e; } + } - try (SftpClient.CloseableHandle h = sftp.open(file, EnumSet.of(SftpClient.OpenMode.Truncate))) { - // NOTE: on Windows files are always readable - assertTrue("Empty truncate should have failed on " + file, isWindows); - } catch (IOException e) { - // ok - } + try (SftpClient.CloseableHandle h = sftp.open(file, EnumSet.of(SftpClient.OpenMode.Write))) { + fail("Empty write should have failed on " + file); + } catch (IOException e) { + // ok + } + try (SftpClient.CloseableHandle h = sftp.open(file, EnumSet.of(SftpClient.OpenMode.Truncate))) { // NOTE: on Windows files are always readable - int perms = sftp.stat(file).getPermissions(); - int readMask = isWindows ? 0 : SftpConstants.S_IRUSR; - int permsMask = SftpConstants.S_IWUSR | readMask; - assertEquals("Mismatched permissions for " + file + ": 0x" + Integer.toHexString(perms), 0, perms & permsMask); + assertTrue("Empty truncate should have failed on " + file, isWindows); + } catch (IOException e) { + // ok + } - javaFile.setWritable(true, false); + // NOTE: on Windows files are always readable + int perms = sftp.stat(file).getPermissions(); + int readMask = isWindows ? 0 : SftpConstants.S_IRUSR; + int permsMask = SftpConstants.S_IWUSR | readMask; + assertEquals("Mismatched permissions for " + file + ": 0x" + Integer.toHexString(perms), 0, perms & permsMask); - try (SftpClient.CloseableHandle h = sftp.open(file, EnumSet.of(SftpClient.OpenMode.Truncate, SftpClient.OpenMode.Write))) { - // OK should succeed - assertTrue("Handle not marked as open for file=" + file, h.isOpen()); - } + javaFile.setWritable(true, false); - byte[] d = "0123456789\n".getBytes(StandardCharsets.UTF_8); - try (SftpClient.CloseableHandle h = sftp.open(file, EnumSet.of(SftpClient.OpenMode.Write))) { - sftp.write(h, 0, d, 0, d.length); - sftp.write(h, d.length, d, 0, d.length); - } + try (SftpClient.CloseableHandle h = sftp.open(file, EnumSet.of(SftpClient.OpenMode.Truncate, SftpClient.OpenMode.Write))) { + // OK should succeed + assertTrue("Handle not marked as open for file=" + file, h.isOpen()); + } - try (SftpClient.CloseableHandle h = sftp.open(file, EnumSet.of(SftpClient.OpenMode.Write))) { - sftp.write(h, d.length * 2, d, 0, d.length); - } + byte[] d = "0123456789\n".getBytes(StandardCharsets.UTF_8); + try (SftpClient.CloseableHandle h = sftp.open(file, EnumSet.of(SftpClient.OpenMode.Write))) { + sftp.write(h, 0, d, 0, d.length); + sftp.write(h, d.length, d, 0, d.length); + } - try (SftpClient.CloseableHandle h = sftp.open(file, EnumSet.of(SftpClient.OpenMode.Write))) { - byte[] overwrite = "-".getBytes(StandardCharsets.UTF_8); - sftp.write(h, 3L, overwrite, 0, 1); - d[3] = overwrite[0]; - } + try (SftpClient.CloseableHandle h = sftp.open(file, EnumSet.of(SftpClient.OpenMode.Write))) { + sftp.write(h, d.length * 2, d, 0, d.length); + } - try (SftpClient.CloseableHandle h = sftp.open(file /* no mode == read */)) { - // NOTE: on Windows files are always readable - assertTrue("Data read should have failed on " + file, isWindows); - } catch (IOException e) { - if (isWindows) { - throw e; - } + try (SftpClient.CloseableHandle h = sftp.open(file, EnumSet.of(SftpClient.OpenMode.Write))) { + byte[] overwrite = "-".getBytes(StandardCharsets.UTF_8); + sftp.write(h, 3L, overwrite, 0, 1); + d[3] = overwrite[0]; + } + + try (SftpClient.CloseableHandle h = sftp.open(file /* no mode == read */)) { + // NOTE: on Windows files are always readable + assertTrue("Data read should have failed on " + file, isWindows); + } catch (IOException e) { + if (isWindows) { + throw e; } + } - javaFile.setReadable(true, false); + javaFile.setReadable(true, false); - byte[] buf = new byte[3]; - try (SftpClient.CloseableHandle h = sftp.open(file /* no mode == read */)) { - int l = sftp.read(h, 2L, buf, 0, buf.length); - String expected = new String(d, 2, l, StandardCharsets.UTF_8); - String actual = new String(buf, 0, l, StandardCharsets.UTF_8); - assertEquals("Mismatched read data", expected, actual); - } + byte[] buf = new byte[3]; + try (SftpClient.CloseableHandle h = sftp.open(file /* no mode == read */)) { + int l = sftp.read(h, 2L, buf, 0, buf.length); + String expected = new String(d, 2, l, StandardCharsets.UTF_8); + String actual = new String(buf, 0, l, StandardCharsets.UTF_8); + assertEquals("Mismatched read data", expected, actual); } - } finally { - client.stop(); } } } @@ -535,8 +487,7 @@ public class SftpTest extends AbstractSftpClientTestSupport { final AtomicInteger removedCount = new AtomicInteger(0); final AtomicInteger modifyingCount = new AtomicInteger(0); final AtomicInteger modifiedCount = new AtomicInteger(0); - - factory.addSftpEventListener(new AbstractSftpEventListenerAdapter() { + SftpEventListener listener = new AbstractSftpEventListenerAdapter() { @Override public void initialized(ServerSession session, int version) { log.info("initialized(" + session + ") version: " + version); @@ -686,33 +637,30 @@ public class SftpTest extends AbstractSftpClientTestSupport { log.info("close(" + session + ")[" + remoteHandle + "] " + (Files.isDirectory(path) ? "directory" : "file") + " " + path); closeCount.incrementAndGet(); } - }); - - try (SshClient client = setupTestClient()) { - client.start(); - - try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { - session.addPasswordIdentity(getCurrentTestName()); - session.auth().verify(5L, TimeUnit.SECONDS); + }; + factory.addSftpEventListener(listener); - try (SftpClient sftp = session.createSftpClient()) { - assertEquals("Mismatched negotiated version", sftp.getVersion(), versionHolder.get()); - testClient(client, sftp); - } + try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { + session.addPasswordIdentity(getCurrentTestName()); + session.auth().verify(5L, TimeUnit.SECONDS); - assertEquals("Mismatched open/close count", openCount.get(), closeCount.get()); - assertTrue("No entries read", entriesCount.get() > 0); - assertTrue("No data read", readSize.get() > 0L); - assertTrue("No data written", writeSize.get() > 0L); - assertEquals("Mismatched removal counts", removingCount.get(), removedCount.get()); - assertTrue("No removals signalled", removedCount.get() > 0); - assertEquals("Mismatched creation counts", creatingCount.get(), createdCount.get()); - assertTrue("No creations signalled", creatingCount.get() > 0); - assertEquals("Mismatched modification counts", modifyingCount.get(), modifiedCount.get()); - assertTrue("No modifications signalled", modifiedCount.get() > 0); - } finally { - client.stop(); + try (SftpClient sftp = session.createSftpClient()) { + assertEquals("Mismatched negotiated version", sftp.getVersion(), versionHolder.get()); + testClient(client, sftp); } + + assertEquals("Mismatched open/close count", openCount.get(), closeCount.get()); + assertTrue("No entries read", entriesCount.get() > 0); + assertTrue("No data read", readSize.get() > 0L); + assertTrue("No data written", writeSize.get() > 0L); + assertEquals("Mismatched removal counts", removingCount.get(), removedCount.get()); + assertTrue("No removals signalled", removedCount.get() > 0); + assertEquals("Mismatched creation counts", creatingCount.get(), createdCount.get()); + assertTrue("No creations signalled", creatingCount.get() > 0); + assertEquals("Mismatched modification counts", modifyingCount.get(), modifiedCount.get()); + assertTrue("No modifications signalled", modifiedCount.get() > 0); + } finally { + factory.removeSftpEventListener(listener); } } @@ -725,45 +673,39 @@ public class SftpTest extends AbstractSftpClientTestSupport { */ @Test public void testWriteChunking() throws Exception { - try (SshClient client = setupTestClient()) { - client.start(); - - try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { - session.addPasswordIdentity(getCurrentTestName()); - session.auth().verify(5L, TimeUnit.SECONDS); - - Path targetPath = detectTargetFolder(); - Path lclSftp = Utils.resolve(targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(), getCurrentTestName()); - Utils.deleteRecursive(lclSftp); - - Path parentPath = targetPath.getParent(); - Path clientFolder = assertHierarchyTargetFolderExists(lclSftp).resolve("client"); - String dir = Utils.resolveRelativeRemotePath(parentPath, clientFolder); - - try (SftpClient sftp = session.createSftpClient()) { - sftp.mkdir(dir); - - uploadAndVerifyFile(sftp, clientFolder, dir, 0, "emptyFile.txt"); - uploadAndVerifyFile(sftp, clientFolder, dir, 1000, "smallFile.txt"); - uploadAndVerifyFile(sftp, clientFolder, dir, ByteArrayBuffer.MAX_LEN - 1, "bufferMaxLenMinusOneFile.txt"); - uploadAndVerifyFile(sftp, clientFolder, dir, ByteArrayBuffer.MAX_LEN, "bufferMaxLenFile.txt"); - // were chunking not implemented, these would fail. these sizes should invoke our internal chunking mechanism - uploadAndVerifyFile(sftp, clientFolder, dir, ByteArrayBuffer.MAX_LEN + 1, "bufferMaxLenPlusOneFile.txt"); - uploadAndVerifyFile(sftp, clientFolder, dir, (int) (1.5 * ByteArrayBuffer.MAX_LEN), "1point5BufferMaxLenFile.txt"); - uploadAndVerifyFile(sftp, clientFolder, dir, (2 * ByteArrayBuffer.MAX_LEN) - 1, "2TimesBufferMaxLenMinusOneFile.txt"); - uploadAndVerifyFile(sftp, clientFolder, dir, 2 * ByteArrayBuffer.MAX_LEN, "2TimesBufferMaxLenFile.txt"); - uploadAndVerifyFile(sftp, clientFolder, dir, (2 * ByteArrayBuffer.MAX_LEN) + 1, "2TimesBufferMaxLenPlusOneFile.txt"); - uploadAndVerifyFile(sftp, clientFolder, dir, 200000, "largerFile.txt"); - - // test erroneous calls that check for negative values - Path invalidPath = clientFolder.resolve(getCurrentTestName() + "-invalid"); - testInvalidParams(sftp, invalidPath, Utils.resolveRelativeRemotePath(parentPath, invalidPath)); - - // cleanup - sftp.rmdir(dir); - } - } finally { - client.stop(); + try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { + session.addPasswordIdentity(getCurrentTestName()); + session.auth().verify(5L, TimeUnit.SECONDS); + + Path targetPath = detectTargetFolder(); + Path lclSftp = Utils.resolve(targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(), getCurrentTestName()); + Utils.deleteRecursive(lclSftp); + + Path parentPath = targetPath.getParent(); + Path clientFolder = assertHierarchyTargetFolderExists(lclSftp).resolve("client"); + String dir = Utils.resolveRelativeRemotePath(parentPath, clientFolder); + + try (SftpClient sftp = session.createSftpClient()) { + sftp.mkdir(dir); + + uploadAndVerifyFile(sftp, clientFolder, dir, 0, "emptyFile.txt"); + uploadAndVerifyFile(sftp, clientFolder, dir, 1000, "smallFile.txt"); + uploadAndVerifyFile(sftp, clientFolder, dir, ByteArrayBuffer.MAX_LEN - 1, "bufferMaxLenMinusOneFile.txt"); + uploadAndVerifyFile(sftp, clientFolder, dir, ByteArrayBuffer.MAX_LEN, "bufferMaxLenFile.txt"); + // were chunking not implemented, these would fail. these sizes should invoke our internal chunking mechanism + uploadAndVerifyFile(sftp, clientFolder, dir, ByteArrayBuffer.MAX_LEN + 1, "bufferMaxLenPlusOneFile.txt"); + uploadAndVerifyFile(sftp, clientFolder, dir, (int) (1.5 * ByteArrayBuffer.MAX_LEN), "1point5BufferMaxLenFile.txt"); + uploadAndVerifyFile(sftp, clientFolder, dir, (2 * ByteArrayBuffer.MAX_LEN) - 1, "2TimesBufferMaxLenMinusOneFile.txt"); + uploadAndVerifyFile(sftp, clientFolder, dir, 2 * ByteArrayBuffer.MAX_LEN, "2TimesBufferMaxLenFile.txt"); + uploadAndVerifyFile(sftp, clientFolder, dir, (2 * ByteArrayBuffer.MAX_LEN) + 1, "2TimesBufferMaxLenPlusOneFile.txt"); + uploadAndVerifyFile(sftp, clientFolder, dir, 200000, "largerFile.txt"); + + // test erroneous calls that check for negative values + Path invalidPath = clientFolder.resolve(getCurrentTestName() + "-invalid"); + testInvalidParams(sftp, invalidPath, Utils.resolveRelativeRemotePath(parentPath, invalidPath)); + + // cleanup + sftp.rmdir(dir); } } } @@ -903,8 +845,8 @@ public class SftpTest extends AbstractSftpClientTestSupport { Vector<?> res = c.ls(path); File dir = baseDir.getParentFile(); Collection<String> expNames = OsUtils.isUNIX() - ? new LinkedList<String>() - : new TreeSet<String>(String.CASE_INSENSITIVE_ORDER); + ? new LinkedList<>() + : new TreeSet<>(String.CASE_INSENSITIVE_ORDER); String[] names = dir.list(); if (GenericUtils.length(names) > 0) { for (String n : names) { @@ -942,123 +884,110 @@ public class SftpTest extends AbstractSftpClientTestSupport { Path parentPath = targetPath.getParent(); Path clientFolder = assertHierarchyTargetFolderExists(lclSftp.resolve("client")); + try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { + session.addPasswordIdentity(getCurrentTestName()); + session.auth().verify(5L, TimeUnit.SECONDS); + + try (SftpClient sftp = session.createSftpClient()) { + Path file1 = clientFolder.resolve("file-1.txt"); + String file1Path = Utils.resolveRelativeRemotePath(parentPath, file1); + try (OutputStream os = sftp.write(file1Path, SftpClient.MIN_WRITE_BUFFER_SIZE)) { + os.write((getCurrentTestName() + "\n").getBytes(StandardCharsets.UTF_8)); + } - try (SshClient client = setupTestClient()) { - client.start(); - - try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { - session.addPasswordIdentity(getCurrentTestName()); - session.auth().verify(5L, TimeUnit.SECONDS); - - try (SftpClient sftp = session.createSftpClient()) { - Path file1 = clientFolder.resolve("file-1.txt"); - String file1Path = Utils.resolveRelativeRemotePath(parentPath, file1); - try (OutputStream os = sftp.write(file1Path, SftpClient.MIN_WRITE_BUFFER_SIZE)) { - os.write((getCurrentTestName() + "\n").getBytes(StandardCharsets.UTF_8)); - } - - Path file2 = clientFolder.resolve("file-2.txt"); - String file2Path = Utils.resolveRelativeRemotePath(parentPath, file2); - Path file3 = clientFolder.resolve("file-3.txt"); - String file3Path = Utils.resolveRelativeRemotePath(parentPath, file3); - try { - sftp.rename(file2Path, file3Path); - fail("Unxpected rename success of " + file2Path + " => " + file3Path); - } catch (org.apache.sshd.common.subsystem.sftp.SftpException e) { - assertEquals("Mismatched status for failed rename of " + file2Path + " => " + file3Path, SftpConstants.SSH_FX_NO_SUCH_FILE, e.getStatus()); - } - - try (OutputStream os = sftp.write(file2Path, SftpClient.MIN_WRITE_BUFFER_SIZE)) { - os.write("h".getBytes(StandardCharsets.UTF_8)); - } + Path file2 = clientFolder.resolve("file-2.txt"); + String file2Path = Utils.resolveRelativeRemotePath(parentPath, file2); + Path file3 = clientFolder.resolve("file-3.txt"); + String file3Path = Utils.resolveRelativeRemotePath(parentPath, file3); + try { + sftp.rename(file2Path, file3Path); + fail("Unxpected rename success of " + file2Path + " => " + file3Path); + } catch (org.apache.sshd.common.subsystem.sftp.SftpException e) { + assertEquals("Mismatched status for failed rename of " + file2Path + " => " + file3Path, SftpConstants.SSH_FX_NO_SUCH_FILE, e.getStatus()); + } - try { - sftp.rename(file1Path, file2Path); - fail("Unxpected rename success of " + file1Path + " => " + file2Path); - } catch (org.apache.sshd.common.subsystem.sftp.SftpException e) { - assertEquals("Mismatched status for failed rename of " + file1Path + " => " + file2Path, SftpConstants.SSH_FX_FILE_ALREADY_EXISTS, e.getStatus()); - } + try (OutputStream os = sftp.write(file2Path, SftpClient.MIN_WRITE_BUFFER_SIZE)) { + os.write("h".getBytes(StandardCharsets.UTF_8)); + } - sftp.rename(file1Path, file2Path, SftpClient.CopyMode.Overwrite); + try { + sftp.rename(file1Path, file2Path); + fail("Unxpected rename success of " + file1Path + " => " + file2Path); + } catch (org.apache.sshd.common.subsystem.sftp.SftpException e) { + assertEquals("Mismatched status for failed rename of " + file1Path + " => " + file2Path, SftpConstants.SSH_FX_FILE_ALREADY_EXISTS, e.getStatus()); } - } finally { - client.stop(); + + sftp.rename(file1Path, file2Path, SftpClient.CopyMode.Overwrite); } } } @Test public void testServerExtensionsDeclarations() throws Exception { - try (SshClient client = setupTestClient()) { - client.start(); - - try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { - session.addPasswordIdentity(getCurrentTestName()); - session.auth().verify(5L, TimeUnit.SECONDS); - - try (SftpClient sftp = session.createSftpClient()) { - Map<String, byte[]> extensions = sftp.getServerExtensions(); - for (String name : new String[]{ - SftpConstants.EXT_NEWLINE, SftpConstants.EXT_VERSIONS, - SftpConstants.EXT_VENDOR_ID, SftpConstants.EXT_ACL_SUPPORTED, - SftpConstants.EXT_SUPPORTED, SftpConstants.EXT_SUPPORTED2 - }) { - assertTrue("Missing extension=" + name, extensions.containsKey(name)); - } + try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { + session.addPasswordIdentity(getCurrentTestName()); + session.auth().verify(5L, TimeUnit.SECONDS); + + try (SftpClient sftp = session.createSftpClient()) { + Map<String, byte[]> extensions = sftp.getServerExtensions(); + for (String name : new String[]{ + SftpConstants.EXT_NEWLINE, SftpConstants.EXT_VERSIONS, + SftpConstants.EXT_VENDOR_ID, SftpConstants.EXT_ACL_SUPPORTED, + SftpConstants.EXT_SUPPORTED, SftpConstants.EXT_SUPPORTED2 + }) { + assertTrue("Missing extension=" + name, extensions.containsKey(name)); + } - Map<String, ?> data = ParserUtils.parse(extensions); - for (Map.Entry<String, ?> de : data.entrySet()) { - String extName = de.getKey(); - Object extValue = de.getValue(); - outputDebugMessage("%s: %s", extName, extValue); - if (SftpConstants.EXT_SUPPORTED.equalsIgnoreCase(extName)) { - assertSupportedExtensions(extName, ((Supported) extValue).extensionNames); - } else if (SftpConstants.EXT_SUPPORTED2.equalsIgnoreCase(extName)) { - assertSupportedExtensions(extName, ((Supported2) extValue).extensionNames); - } else if (SftpConstants.EXT_ACL_SUPPORTED.equalsIgnoreCase(extName)) { - assertSupportedAclCapabilities((AclCapabilities) extValue); - } else if (SftpConstants.EXT_VERSIONS.equalsIgnoreCase(extName)) { - assertSupportedVersions((Versions) extValue); - } else if (SftpConstants.EXT_NEWLINE.equalsIgnoreCase(extName)) { - assertNewlineValue((Newline) extValue); - } + Map<String, ?> data = ParserUtils.parse(extensions); + for (Map.Entry<String, ?> de : data.entrySet()) { + String extName = de.getKey(); + Object extValue = de.getValue(); + outputDebugMessage("%s: %s", extName, extValue); + if (SftpConstants.EXT_SUPPORTED.equalsIgnoreCase(extName)) { + assertSupportedExtensions(extName, ((Supported) extValue).extensionNames); + } else if (SftpConstants.EXT_SUPPORTED2.equalsIgnoreCase(extName)) { + assertSupportedExtensions(extName, ((Supported2) extValue).extensionNames); + } else if (SftpConstants.EXT_ACL_SUPPORTED.equalsIgnoreCase(extName)) { + assertSupportedAclCapabilities((AclCapabilities) extValue); + } else if (SftpConstants.EXT_VERSIONS.equalsIgnoreCase(extName)) { + assertSupportedVersions((Versions) extValue); + } else if (SftpConstants.EXT_NEWLINE.equalsIgnoreCase(extName)) { + assertNewlineValue((Newline) extValue); } + } - for (String extName : extensions.keySet()) { - if (!data.containsKey(extName)) { - outputDebugMessage("No parser for extension=%s", extName); - } + for (String extName : extensions.keySet()) { + if (!data.containsKey(extName)) { + outputDebugMessage("No parser for extension=%s", extName); } + } - for (OpenSSHExtension expected : SftpSubsystem.DEFAULT_OPEN_SSH_EXTENSIONS) { - String name = expected.getName(); - Object value = data.get(name); - assertNotNull("OpenSSH extension not declared: " + name, value); + for (OpenSSHExtension expected : SftpSubsystem.DEFAULT_OPEN_SSH_EXTENSIONS) { + String name = expected.getName(); + Object value = data.get(name); + assertNotNull("OpenSSH extension not declared: " + name, value); - OpenSSHExtension actual = (OpenSSHExtension) value; - assertEquals("Mismatched version for OpenSSH extension=" + name, expected.getVersion(), actual.getVersion()); - } + OpenSSHExtension actual = (OpenSSHExtension) value; + assertEquals("Mismatched version for OpenSSH extension=" + name, expected.getVersion(), actual.getVersion()); + } + + for (BuiltinSftpClientExtensions type : BuiltinSftpClientExtensions.VALUES) { + String extensionName = type.getName(); + boolean isOpenSSHExtension = extensionName.endsWith("@openssh.com"); + SftpClientExtension instance = sftp.getExtension(extensionName); - for (BuiltinSftpClientExtensions type : BuiltinSftpClientExtensions.VALUES) { - String extensionName = type.getName(); - boolean isOpenSSHExtension = extensionName.endsWith("@openssh.com"); - SftpClientExtension instance = sftp.getExtension(extensionName); - - assertNotNull("Extension not implemented:" + extensionName, instance); - assertEquals("Mismatched instance name", extensionName, instance.getName()); - - if (instance.isSupported()) { - if (isOpenSSHExtension) { - assertTrue("Unlisted default OpenSSH extension: " + extensionName, SftpSubsystem.DEFAULT_OPEN_SSH_EXTENSIONS_NAMES.contains(extensionName)); - } - } else { - assertTrue("Unsupported non-OpenSSH extension: " + extensionName, isOpenSSHExtension); - assertFalse("Unsupported default OpenSSH extension: " + extensionName, SftpSubsystem.DEFAULT_OPEN_SSH_EXTENSIONS_NAMES.contains(extensionName)); + assertNotNull("Extension not implemented:" + extensionName, instance); + assertEquals("Mismatched instance name", extensionName, instance.getName()); + + if (instance.isSupported()) { + if (isOpenSSHExtension) { + assertTrue("Unlisted default OpenSSH extension: " + extensionName, SftpSubsystem.DEFAULT_OPEN_SSH_EXTENSIONS_NAMES.contains(extensionName)); } + } else { + assertTrue("Unsupported non-OpenSSH extension: " + extensionName, isOpenSSHExtension); + assertFalse("Unsupported default OpenSSH extension: " + extensionName, SftpSubsystem.DEFAULT_OPEN_SSH_EXTENSIONS_NAMES.contains(extensionName)); } } - } finally { - client.stop(); } } } @@ -1129,43 +1058,37 @@ public class SftpTest extends AbstractSftpClientTestSupport { } }; - try (SshClient client = setupTestClient()) { - client.start(); - - try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { - session.addPasswordIdentity(getCurrentTestName()); - session.auth().verify(5L, TimeUnit.SECONDS); + try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { + session.addPasswordIdentity(getCurrentTestName()); + session.auth().verify(5L, TimeUnit.SECONDS); - try (SftpClient sftp = session.createSftpClient(selector)) { - assertEquals("Mismatched negotiated version", selected.get(), sftp.getVersion()); - testClient(client, sftp); - } - } finally { - client.stop(); + try (SftpClient sftp = session.createSftpClient(selector)) { + assertEquals("Mismatched negotiated version", selected.get(), sftp.getVersion()); + testClient(client, sftp); } } } @Test // see SSHD-621 public void testServerDoesNotSupportSftp() throws Exception { - sshd.setSubsystemFactories(null); - - try (SshClient client = setupTestClient()) { - client.start(); - - try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { - session.addPasswordIdentity(getCurrentTestName()); - session.auth().verify(5L, TimeUnit.SECONDS); + List<NamedFactory<Command>> factories = sshd.getSubsystemFactories(); + assertEquals("Mismatched subsystem factories count", 1, GenericUtils.size(factories)); - PropertyResolverUtils.updateProperty(session, SftpClient.SFTP_CHANNEL_OPEN_TIMEOUT, TimeUnit.SECONDS.toMillis(4L)); - try (SftpClient sftp = session.createSftpClient()) { - fail("Unexpected SFTP client creation success"); - } catch (SocketTimeoutException | EOFException | WindowClosedException e) { - // expected - ignored - } + sshd.setSubsystemFactories(null); + try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { + session.addPasswordIdentity(getCurrentTestName()); + session.auth().verify(5L, TimeUnit.SECONDS); + + PropertyResolverUtils.updateProperty(session, SftpClient.SFTP_CHANNEL_OPEN_TIMEOUT, TimeUnit.SECONDS.toMillis(4L)); + try (SftpClient sftp = session.createSftpClient()) { + fail("Unexpected SFTP client creation success"); + } catch (SocketTimeoutException | EOFException | WindowClosedException e) { + // expected - ignored } finally { - client.stop(); + PropertyResolverUtils.updateProperty(session, SftpClient.SFTP_CHANNEL_OPEN_TIMEOUT, SftpClient.DEFAULT_CHANNEL_OPEN_TIMEOUT); } + } finally { + sshd.setSubsystemFactories(factories); } } @@ -1177,10 +1100,9 @@ public class SftpTest extends AbstractSftpClientTestSupport { Path parentPath = targetPath.getParent(); Path clientFolder = assertHierarchyTargetFolderExists(lclSftp).resolve("client"); String dir = Utils.resolveRelativeRemotePath(parentPath, clientFolder); - String file = dir + "/" + "file.txt"; - sftp.mkdir(dir); + String file = dir + "/" + getCurrentTestName() + "-file.txt"; try (SftpClient.CloseableHandle h = sftp.open(file, EnumSet.of(SftpClient.OpenMode.Write, SftpClient.OpenMode.Create))) { byte[] d = "0123456789\n".getBytes(StandardCharsets.UTF_8); sftp.write(h, 0, d, 0, d.length); @@ -1191,20 +1113,18 @@ public class SftpTest extends AbstractSftpClientTestSupport { } try (SftpClient.CloseableHandle h = sftp.openDir(dir)) { - List<SftpClient.DirEntry> dirEntries = sftp.readDir(h); - assertNotNull("No dir entries", dirEntries); - + List<SftpClient.DirEntry> dirEntries = new ArrayList<>(); boolean dotFiltered = false; boolean dotdotFiltered = false; - for (Iterator<SftpClient.DirEntry> it = dirEntries.iterator(); it.hasNext();) { - SftpClient.DirEntry entry = it.next(); + for (SftpClient.DirEntry entry : sftp.listDir(h)) { String name = entry.getFilename(); + outputDebugMessage("readDir(%s) initial file: %s", dir, name); if (".".equals(name) && (!dotFiltered)) { - it.remove(); dotFiltered = true; } else if ("..".equals(name) && (!dotdotFiltered)) { - it.remove(); dotdotFiltered = true; + } else { + dirEntries.add(entry); } } @@ -1247,6 +1167,8 @@ public class SftpTest extends AbstractSftpClientTestSupport { for (SftpClient.DirEntry entry : sftp.readDir(dir)) { assertNotNull("Unexpected null entry", entry); String name = entry.getFilename(); + outputDebugMessage("readDir(%s) overwritten file: %s", dir, name); + if (".".equals(name) && (!dotFiltered)) { dotFiltered = true; } else if ("..".equals(name) && (!dotdotFiltered)) { @@ -1258,9 +1180,7 @@ public class SftpTest extends AbstractSftpClientTestSupport { assertTrue("Dot entry not read", dotFiltered); assertTrue("Dot-dot entry not read", dotdotFiltered); assertEquals("Mismatched read dir entries", 1, nb); - sftp.remove(file); - sftp.rmdir(dir); } @@ -1276,7 +1196,7 @@ public class SftpTest extends AbstractSftpClientTestSupport { SftpSubsystemFactory factory = (SftpSubsystemFactory) f; final AtomicReference<LinkData> linkDataHolder = new AtomicReference<>(); - factory.addSftpEventListener(new AbstractSftpEventListenerAdapter() { + SftpEventListener listener = new AbstractSftpEventListenerAdapter() { @Override public void linking(ServerSession session, Path src, Path target, boolean symLink) { assertNull("Multiple linking calls", linkDataHolder.getAndSet(new LinkData(src, target, symLink))); @@ -1291,7 +1211,7 @@ public class SftpTest extends AbstractSftpClientTestSupport { assertEquals("Mismatched link type", data.isSymLink(), symLink); assertNull("Unexpected failure", thrown); } - }); + }; Path targetPath = detectTargetFolder(); Path lclSftp = Utils.resolve(targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(), getCurrentTestName()); @@ -1313,35 +1233,41 @@ public class SftpTest extends AbstractSftpClientTestSupport { Path sourcePath = assertHierarchyTargetFolderExists(lclSftp).resolve("src.txt"); String remSrcPath = "/" + Utils.resolveRelativeRemotePath(parentPath, sourcePath); - String data = getCurrentTestName(); - ChannelSftp c = (ChannelSftp) session.openChannel(SftpConstants.SFTP_SUBSYSTEM_NAME); - c.connect(); + factory.addSftpEventListener(listener); try { - try (InputStream dataStream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8))) { - c.put(dataStream, remSrcPath); - } - assertTrue("Source file not created: " + sourcePath, Files.exists(sourcePath)); - assertEquals("Mismatched stored data in " + remSrcPath, data, readFile(remSrcPath)); - - Path linkPath = lclSftp.resolve("link-" + sourcePath.getFileName()); - String remLinkPath = "/" + Utils.resolveRelativeRemotePath(parentPath, linkPath); - LinkOption[] options = IoUtils.getLinkOptions(false); - if (Files.exists(linkPath, options)) { - Files.delete(linkPath); - } - assertFalse("Target link exists before linking: " + linkPath, Files.exists(linkPath, options)); + String data = getCurrentTestName(); + ChannelSftp c = (ChannelSftp) session.openChannel(SftpConstants.SFTP_SUBSYSTEM_NAME); + c.connect(); - outputDebugMessage("Symlink %s => %s", remLinkPath, remSrcPath); - c.symlink(remSrcPath, remLinkPath); + try { + try (InputStream dataStream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8))) { + c.put(dataStream, remSrcPath); + } + assertTrue("Source file not created: " + sourcePath, Files.exists(sourcePath)); + assertEquals("Mismatched stored data in " + remSrcPath, data, readFile(remSrcPath)); + + Path linkPath = lclSftp.resolve("link-" + sourcePath.getFileName()); + String remLinkPath = "/" + Utils.resolveRelativeRemotePath(parentPath, linkPath); + LinkOption[] options = IoUtils.getLinkOptions(false); + if (Files.exists(linkPath, options)) { + Files.delete(linkPath); + } + assertFalse("Target link exists before linking: " + linkPath, Files.exists(linkPath, options)); + + outputDebugMessage("Symlink %s => %s", remLinkPath, remSrcPath); + c.symlink(remSrcPath, remLinkPath); - assertTrue("Symlink not created: " + linkPath, Files.exists(linkPath, options)); - assertEquals("Mismatched link data in " + remLinkPath, data, readFile(remLinkPath)); + assertTrue("Symlink not created: " + linkPath, Files.exists(linkPath, options)); + assertEquals("Mismatched link data in " + remLinkPath, data, readFile(remLinkPath)); - String str1 = c.readlink(remLinkPath); - String str2 = c.realpath(remSrcPath); - assertEquals("Mismatched link vs. real path", str1, str2); + String str1 = c.readlink(remLinkPath); + String str2 = c.realpath(remSrcPath); + assertEquals("Mismatched link vs. real path", str1, str2); + } finally { + c.disconnect(); + } } finally { - c.disconnect(); + factory.removeSftpEventListener(listener); } assertNotNull("No symlink signalled", linkDataHolder.getAndSet(null));
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/ae8d1c99/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpVersionsTest.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpVersionsTest.java b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpVersionsTest.java index ab9d74c..0da39a9 100644 --- a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpVersionsTest.java +++ b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpVersionsTest.java @@ -40,7 +40,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; -import org.apache.sshd.client.SshClient; import org.apache.sshd.client.session.ClientSession; import org.apache.sshd.client.subsystem.sftp.SftpClient.Attributes; import org.apache.sshd.client.subsystem.sftp.SftpClient.CloseableHandle; @@ -57,7 +56,6 @@ import org.apache.sshd.server.subsystem.sftp.SftpEventListener; import org.apache.sshd.server.subsystem.sftp.SftpSubsystem; import org.apache.sshd.server.subsystem.sftp.SftpSubsystemFactory; import org.apache.sshd.util.test.Utils; -import org.junit.After; import org.junit.Before; import org.junit.FixMethodOrder; import org.junit.Test; @@ -99,29 +97,18 @@ public class SftpVersionsTest extends AbstractSftpClientTestSupport { setupServer(); } - @After - public void tearDown() throws Exception { - tearDownServer(); - } - public final int getTestedVersion() { return testVersion; } @Test public void testSftpVersionSelector() throws Exception { - try (SshClient client = setupTestClient()) { - client.start(); - - try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { - session.addPasswordIdentity(getCurrentTestName()); - session.auth().verify(5L, TimeUnit.SECONDS); + try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { + session.addPasswordIdentity(getCurrentTestName()); + session.auth().verify(5L, TimeUnit.SECONDS); - try (SftpClient sftp = session.createSftpClient(getTestedVersion())) { - assertEquals("Mismatched negotiated version", getTestedVersion(), sftp.getVersion()); - } - } finally { - client.stop(); + try (SftpClient sftp = session.createSftpClient(getTestedVersion())) { + assertEquals("Mismatched negotiated version", getTestedVersion(), sftp.getVersion()); } } } @@ -134,35 +121,28 @@ public class SftpVersionsTest extends AbstractSftpClientTestSupport { Files.write(lclFile, getClass().getName().getBytes(StandardCharsets.UTF_8)); Path parentPath = targetPath.getParent(); String remotePath = Utils.resolveRelativeRemotePath(parentPath, lclFile); - - try (SshClient client = setupTestClient()) { - client.start(); - - try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { - session.addPasswordIdentity(getCurrentTestName()); - session.auth().verify(5L, TimeUnit.SECONDS); - - try (SftpClient sftp = session.createSftpClient(getTestedVersion())) { - Attributes attrs = sftp.lstat(remotePath); - long expectedSeconds = TimeUnit.SECONDS.convert(System.currentTimeMillis() - TimeUnit.HOURS.toMillis(1L), TimeUnit.MILLISECONDS); - attrs.getFlags().clear(); - attrs.modifyTime(expectedSeconds); - sftp.setStat(remotePath, attrs); - - attrs = sftp.lstat(remotePath); - long actualSeconds = attrs.getModifyTime().to(TimeUnit.SECONDS); - // The NTFS file system delays updates to the last access time for a file by up to 1 hour after the last access - if (expectedSeconds != actualSeconds) { - System.err.append("Mismatched last modified time for ").append(lclFile.toString()) - .append(" - expected=").append(String.valueOf(expectedSeconds)) - .append('[').append(new Date(TimeUnit.SECONDS.toMillis(expectedSeconds)).toString()).append(']') - .append(", actual=").append(String.valueOf(actualSeconds)) - .append('[').append(new Date(TimeUnit.SECONDS.toMillis(actualSeconds)).toString()).append(']') - .println(); - } + try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { + session.addPasswordIdentity(getCurrentTestName()); + session.auth().verify(5L, TimeUnit.SECONDS); + + try (SftpClient sftp = session.createSftpClient(getTestedVersion())) { + Attributes attrs = sftp.lstat(remotePath); + long expectedSeconds = TimeUnit.SECONDS.convert(System.currentTimeMillis() - TimeUnit.HOURS.toMillis(1L), TimeUnit.MILLISECONDS); + attrs.getFlags().clear(); + attrs.modifyTime(expectedSeconds); + sftp.setStat(remotePath, attrs); + + attrs = sftp.lstat(remotePath); + long actualSeconds = attrs.getModifyTime().to(TimeUnit.SECONDS); + // The NTFS file system delays updates to the last access time for a file by up to 1 hour after the last access + if (expectedSeconds != actualSeconds) { + System.err.append("Mismatched last modified time for ").append(lclFile.toString()) + .append(" - expected=").append(String.valueOf(expectedSeconds)) + .append('[').append(new Date(TimeUnit.SECONDS.toMillis(expectedSeconds)).toString()).append(']') + .append(", actual=").append(String.valueOf(actualSeconds)) + .append('[').append(new Date(TimeUnit.SECONDS.toMillis(actualSeconds)).toString()).append(']') + .println(); } - } finally { - client.stop(); } } } @@ -179,32 +159,26 @@ public class SftpVersionsTest extends AbstractSftpClientTestSupport { Path parentPath = targetPath.getParent(); String remotePath = Utils.resolveRelativeRemotePath(parentPath, lclSftp); - try (SshClient client = setupTestClient()) { - client.start(); - - try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { - session.addPasswordIdentity(getCurrentTestName()); - session.auth().verify(5L, TimeUnit.SECONDS); - - try (SftpClient sftp = session.createSftpClient(getTestedVersion())) { - for (DirEntry entry : sftp.readDir(remotePath)) { - String fileName = entry.getFilename(); - if (".".equals(fileName) || "..".equals(fileName)) { - continue; - } + try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { + session.addPasswordIdentity(getCurrentTestName()); + session.auth().verify(5L, TimeUnit.SECONDS); + + try (SftpClient sftp = session.createSftpClient(getTestedVersion())) { + for (DirEntry entry : sftp.readDir(remotePath)) { + String fileName = entry.getFilename(); + if (".".equals(fileName) || "..".equals(fileName)) { + continue; + } - Attributes attrs = validateSftpFileTypeAndPermissions(fileName, getTestedVersion(), entry.getAttributes()); - if (subFolderName.equals(fileName)) { - assertEquals("Mismatched sub-folder type", SftpConstants.SSH_FILEXFER_TYPE_DIRECTORY, attrs.getType()); - assertTrue("Sub-folder not marked as directory", attrs.isDirectory()); - } else if (lclFileName.equals(fileName)) { - assertEquals("Mismatched sub-file type", SftpConstants.SSH_FILEXFER_TYPE_REGULAR, attrs.getType()); - assertTrue("Sub-folder not marked as directory", attrs.isRegularFile()); - } + Attributes attrs = validateSftpFileTypeAndPermissions(fileName, getTestedVersion(), entry.getAttributes()); + if (subFolderName.equals(fileName)) { + assertEquals("Mismatched sub-folder type", SftpConstants.SSH_FILEXFER_TYPE_DIRECTORY, attrs.getType()); + assertTrue("Sub-folder not marked as directory", attrs.isDirectory()); + } else if (lclFileName.equals(fileName)) { + assertEquals("Mismatched sub-file type", SftpConstants.SSH_FILEXFER_TYPE_REGULAR, attrs.getType()); + assertTrue("Sub-folder not marked as directory", attrs.isRegularFile()); } } - } finally { - client.stop(); } } } @@ -231,7 +205,7 @@ public class SftpVersionsTest extends AbstractSftpClientTestSupport { protected Map<String, Object> resolveFileAttributes(Path file, int flags, LinkOption... options) throws IOException { Map<String, Object> attrs = super.resolveFileAttributes(file, flags, options); if (GenericUtils.isEmpty(attrs)) { - attrs = new TreeMap<String, Object>(String.CASE_INSENSITIVE_ORDER); + attrs = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); } @SuppressWarnings("unchecked") @@ -285,8 +259,6 @@ public class SftpVersionsTest extends AbstractSftpClientTestSupport { } }); - sshd.setSubsystemFactories(Collections.<NamedFactory<Command>>singletonList(factory)); - Path targetPath = detectTargetFolder(); Path lclSftp = Utils.resolve(targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName()); Files.createDirectories(lclSftp.resolve("sub-folder")); @@ -296,39 +268,38 @@ public class SftpVersionsTest extends AbstractSftpClientTestSupport { Path parentPath = targetPath.getParent(); String remotePath = Utils.resolveRelativeRemotePath(parentPath, lclSftp); int numInvoked = 0; - try (SshClient client = setupTestClient()) { - client.start(); - - try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { - session.addPasswordIdentity(getCurrentTestName()); - session.auth().verify(5L, TimeUnit.SECONDS); - - try (SftpClient sftp = session.createSftpClient(getTestedVersion())) { - for (DirEntry entry : sftp.readDir(remotePath)) { - String fileName = entry.getFilename(); - if (".".equals(fileName) || "..".equals(fileName)) { - continue; - } - Attributes attrs = validateSftpFileTypeAndPermissions(fileName, getTestedVersion(), entry.getAttributes()); - List<AclEntry> aclActual = attrs.getAcl(); - if (getTestedVersion() == SftpConstants.SFTP_V3) { - assertNull("Unexpected ACL for entry=" + fileName, aclActual); - } else { - assertListEquals("Mismatched ACL for entry=" + fileName, aclExpected, aclActual); - } + List<NamedFactory<Command>> factories = sshd.getSubsystemFactories(); + sshd.setSubsystemFactories(Collections.<NamedFactory<Command>>singletonList(factory)); + try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { + session.addPasswordIdentity(getCurrentTestName()); + session.auth().verify(5L, TimeUnit.SECONDS); + + try (SftpClient sftp = session.createSftpClient(getTestedVersion())) { + for (DirEntry entry : sftp.readDir(remotePath)) { + String fileName = entry.getFilename(); + if (".".equals(fileName) || "..".equals(fileName)) { + continue; + } - attrs.getFlags().clear(); - attrs.setAcl(aclExpected); - sftp.setStat(remotePath + "/" + fileName, attrs); - if (getTestedVersion() > SftpConstants.SFTP_V3) { - numInvoked++; - } + Attributes attrs = validateSftpFileTypeAndPermissions(fileName, getTestedVersion(), entry.getAttributes()); + List<AclEntry> aclActual = attrs.getAcl(); + if (getTestedVersion() == SftpConstants.SFTP_V3) { + assertNull("Unexpected ACL for entry=" + fileName, aclActual); + } else { + assertListEquals("Mismatched ACL for entry=" + fileName, aclExpected, aclActual); + } + + attrs.getFlags().clear(); + attrs.setAcl(aclExpected); + sftp.setStat(remotePath + "/" + fileName, attrs); + if (getTestedVersion() > SftpConstants.SFTP_V3) { + numInvoked++; } } - } finally { - client.stop(); } + } finally { + sshd.setSubsystemFactories(factories); } assertEquals("Mismatched invocations count", numInvoked, numInvocations.get()); @@ -356,7 +327,7 @@ public class SftpVersionsTest extends AbstractSftpClientTestSupport { protected Map<String, Object> resolveFileAttributes(Path file, int flags, LinkOption... options) throws IOException { Map<String, Object> attrs = super.resolveFileAttributes(file, flags, options); if (GenericUtils.isEmpty(attrs)) { - attrs = new TreeMap<String, Object>(String.CASE_INSENSITIVE_ORDER); + attrs = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); } @SuppressWarnings("unchecked") @@ -408,7 +379,6 @@ public class SftpVersionsTest extends AbstractSftpClientTestSupport { } }); - sshd.setSubsystemFactories(Collections.<NamedFactory<Command>>singletonList(factory)); Path targetPath = detectTargetFolder(); Path lclSftp = Utils.resolve(targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName()); Files.createDirectories(lclSftp.resolve("sub-folder")); @@ -418,32 +388,31 @@ public class SftpVersionsTest extends AbstractSftpClientTestSupport { Path parentPath = targetPath.getParent(); String remotePath = Utils.resolveRelativeRemotePath(parentPath, lclSftp); int numInvoked = 0; - try (SshClient client = setupTestClient()) { - client.start(); - - try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { - session.addPasswordIdentity(getCurrentTestName()); - session.auth().verify(5L, TimeUnit.SECONDS); - - try (SftpClient sftp = session.createSftpClient(getTestedVersion())) { - for (DirEntry entry : sftp.readDir(remotePath)) { - String fileName = entry.getFilename(); - if (".".equals(fileName) || "..".equals(fileName)) { - continue; - } - Attributes attrs = validateSftpFileTypeAndPermissions(fileName, getTestedVersion(), entry.getAttributes()); - Map<String, byte[]> actExtensions = attrs.getExtensions(); - assertExtensionsMapEquals("dirEntry=" + fileName, expExtensions, actExtensions); - attrs.getFlags().clear(); - attrs.setStringExtensions(expExtensions); - sftp.setStat(remotePath + "/" + fileName, attrs); - numInvoked++; + List<NamedFactory<Command>> factories = sshd.getSubsystemFactories(); + sshd.setSubsystemFactories(Collections.<NamedFactory<Command>>singletonList(factory)); + try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { + session.addPasswordIdentity(getCurrentTestName()); + session.auth().verify(5L, TimeUnit.SECONDS); + + try (SftpClient sftp = session.createSftpClient(getTestedVersion())) { + for (DirEntry entry : sftp.readDir(remotePath)) { + String fileName = entry.getFilename(); + if (".".equals(fileName) || "..".equals(fileName)) { + continue; } + + Attributes attrs = validateSftpFileTypeAndPermissions(fileName, getTestedVersion(), entry.getAttributes()); + Map<String, byte[]> actExtensions = attrs.getExtensions(); + assertExtensionsMapEquals("dirEntry=" + fileName, expExtensions, actExtensions); + attrs.getFlags().clear(); + attrs.setStringExtensions(expExtensions); + sftp.setStat(remotePath + "/" + fileName, attrs); + numInvoked++; } - } finally { - client.stop(); } + } finally { + sshd.setSubsystemFactories(factories); } assertEquals("Mismatched invocations count", numInvoked, numInvocations.get()); @@ -451,48 +420,42 @@ public class SftpVersionsTest extends AbstractSftpClientTestSupport { @Test // see SSHD-623 public void testEndOfListIndicator() throws Exception { - try (SshClient client = setupTestClient()) { - client.start(); - - try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { - session.addPasswordIdentity(getCurrentTestName()); - session.auth().verify(5L, TimeUnit.SECONDS); - - try (SftpClient sftp = session.createSftpClient(getTestedVersion())) { - AtomicReference<Boolean> eolIndicator = new AtomicReference<>(); - int version = sftp.getVersion(); - Path targetPath = detectTargetFolder(); - Path parentPath = targetPath.getParent(); - String remotePath = Utils.resolveRelativeRemotePath(parentPath, targetPath); - - try (CloseableHandle handle = sftp.openDir(remotePath)) { - List<DirEntry> entries = sftp.readDir(handle, eolIndicator); - for (int index = 1; entries != null; entries = sftp.readDir(handle, eolIndicator), index++) { - Boolean value = eolIndicator.get(); - if (version < SftpConstants.SFTP_V6) { - assertNull("Unexpected indicator value at iteration #" + index, value); - } else { - assertNotNull("No indicator returned at iteration #" + index, value); - if (value.booleanValue()) { - break; - } - } - eolIndicator.set(null); // make sure starting fresh - } - + try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) { + session.addPasswordIdentity(getCurrentTestName()); + session.auth().verify(5L, TimeUnit.SECONDS); + + try (SftpClient sftp = session.createSftpClient(getTestedVersion())) { + AtomicReference<Boolean> eolIndicator = new AtomicReference<>(); + int version = sftp.getVersion(); + Path targetPath = detectTargetFolder(); + Path parentPath = targetPath.getParent(); + String remotePath = Utils.resolveRelativeRemotePath(parentPath, targetPath); + + try (CloseableHandle handle = sftp.openDir(remotePath)) { + List<DirEntry> entries = sftp.readDir(handle, eolIndicator); + for (int index = 1; entries != null; entries = sftp.readDir(handle, eolIndicator), index++) { Boolean value = eolIndicator.get(); if (version < SftpConstants.SFTP_V6) { - assertNull("Unexpected end-of-list indication received at end of entries", value); - assertNull("Unexpected no last entries indication", entries); + assertNull("Unexpected indicator value at iteration #" + index, value); } else { - assertNotNull("No end-of-list indication received at end of entries", value); - assertNotNull("No last received entries", entries); - assertTrue("Bad end-of-list value", value.booleanValue()); + assertNotNull("No indicator returned at iteration #" + index, value); + if (value.booleanValue()) { + break; + } } + eolIndicator.set(null); // make sure starting fresh + } + + Boolean value = eolIndicator.get(); + if (version < SftpConstants.SFTP_V6) { + assertNull("Unexpected end-of-list indication received at end of entries", value); + assertNull("Unexpected no last entries indication", entries); + } else { + assertNotNull("No end-of-list indication received at end of entries", value); + assertNotNull("No last received entries", entries); + assertTrue("Bad end-of-list value", value.booleanValue()); } } - } finally { - client.stop(); } } }
