This is an automated email from the ASF dual-hosted git repository.

garydgregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-vfs.git


The following commit(s) were added to refs/heads/master by this push:
     new b1e2aaef0 Port SFTP tests from  Apache SSHd 0.8.0 to 3.0.0-M2 #754
b1e2aaef0 is described below

commit b1e2aaef0c54213c362207f7532ffd3014a98fe8
Author: Gary Gregory <[email protected]>
AuthorDate: Tue Apr 28 14:54:22 2026 -0400

    Port SFTP tests from  Apache SSHd 0.8.0 to 3.0.0-M2 #754
    
    - Reuse IOUtils.closeQuietly()
    - Sort members
    - Use longer lines
    - Reduce nesting
---
 .../vfs2/provider/sftp/SftpPasswordAuthTest.java   |  74 +++---
 .../vfs2/provider/sftp/SftpTestServerHelper.java   | 294 ++++++++++-----------
 src/changes/changes.xml                            |   2 +
 3 files changed, 167 insertions(+), 203 deletions(-)

diff --git 
a/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/sftp/SftpPasswordAuthTest.java
 
b/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/sftp/SftpPasswordAuthTest.java
index 0408630cb..347cd4b50 100644
--- 
a/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/sftp/SftpPasswordAuthTest.java
+++ 
b/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/sftp/SftpPasswordAuthTest.java
@@ -29,6 +29,7 @@ import java.nio.file.Path;
 import java.time.Duration;
 import java.util.Collections;
 
+import org.apache.commons.io.IOUtils;
 import org.apache.commons.vfs2.FileObject;
 import org.apache.commons.vfs2.FileSystemException;
 import org.apache.commons.vfs2.FileSystemOptions;
@@ -50,48 +51,66 @@ import com.jcraft.jsch.TestIdentityRepositoryFactory;
 /**
  * Tests SFTP password authentication using {@link StaticUserAuthenticator}.
  * <p>
- * Verifies that credentials supplied via {@link 
DefaultFileSystemConfigBuilder#setUserAuthenticator}
- * are correctly propagated to the SFTP server.
+ * Verifies that credentials supplied via {@link 
DefaultFileSystemConfigBuilder#setUserAuthenticator} are correctly propagated 
to the SFTP server.
  * </p>
  */
 public class SftpPasswordAuthTest {
 
     private static final String TEST_USERNAME = "testuser";
+
     private static final String TEST_PASSWORD = "testpass";
 
     private static SshServer sshServer;
+
     private static int serverPort;
+
     private static DefaultFileSystemManager manager;
 
+    private static String baseUri() {
+        return String.format("sftp://%s@localhost:%d";, TEST_USERNAME, 
serverPort);
+    }
+
+    private static void configureSftpOptions(final FileSystemOptions opts) 
throws FileSystemException {
+        final SftpFileSystemConfigBuilder builder = 
SftpFileSystemConfigBuilder.getInstance();
+        builder.setStrictHostKeyChecking(opts, "no");
+        builder.setUserInfo(opts, new TrustEveryoneUserInfo());
+        builder.setIdentityRepositoryFactory(opts, new 
TestIdentityRepositoryFactory());
+        builder.setConnectTimeout(opts, Duration.ofSeconds(60));
+        builder.setSessionTimeout(opts, Duration.ofSeconds(60));
+    }
+
     @BeforeAll
     static void setUp() throws Exception {
         sshServer = SshServer.setUpDefaultServer();
         sshServer.setPort(0);
-
         final Path tmpKeyFile = Files.createTempFile("sshd-test-key", ".ser");
         tmpKeyFile.toFile().deleteOnExit();
         final SimpleGeneratorHostKeyProvider keyProvider = new 
SimpleGeneratorHostKeyProvider(tmpKeyFile);
         keyProvider.setAlgorithm("RSA");
         sshServer.setKeyPairProvider(keyProvider);
-
-        sshServer.setPasswordAuthenticator(
-                (user, pass, session) -> TEST_USERNAME.equals(user) && 
TEST_PASSWORD.equals(pass));
-
+        sshServer.setPasswordAuthenticator((user, pass, session) -> 
TEST_USERNAME.equals(user) && TEST_PASSWORD.equals(pass));
         sshServer.setSubsystemFactories(Collections.singletonList(new 
SftpSubsystemFactory()));
-
         final File homeDir = getTestDirectoryFile();
-        sshServer.setFileSystemFactory(
-                new 
VirtualFileSystemFactory(homeDir.toPath().toAbsolutePath()));
-
+        sshServer.setFileSystemFactory(new 
VirtualFileSystemFactory(homeDir.toPath().toAbsolutePath()));
         sshServer.start();
         serverPort = sshServer.getPort();
-
         manager = new DefaultFileSystemManager();
         manager.addProvider("sftp", new SftpFileProvider());
         manager.addProvider("file", new DefaultLocalFileProvider());
         manager.init();
     }
 
+    private static void stopServerWithTimeout(final long timeoutMs) {
+        final Thread stopThread = new Thread(() -> 
IOUtils.closeQuietly(sshServer), "sshd-stop");
+        stopThread.setDaemon(true);
+        stopThread.start();
+        try {
+            stopThread.join(timeoutMs);
+        } catch (final InterruptedException e) {
+            Thread.currentThread().interrupt();
+        }
+    }
+
     @AfterAll
     static void tearDown() throws Exception {
         if (manager != null) {
@@ -106,27 +125,6 @@ public class SftpPasswordAuthTest {
         }
     }
 
-    private static void stopServerWithTimeout(final long timeoutMs) {
-        final Thread stopThread = new Thread(() -> {
-            try {
-                sshServer.close();
-            } catch (final Exception e) {
-                // ignore
-            }
-        }, "sshd-stop");
-        stopThread.setDaemon(true);
-        stopThread.start();
-        try {
-            stopThread.join(timeoutMs);
-        } catch (final InterruptedException e) {
-            Thread.currentThread().interrupt();
-        }
-    }
-
-    private static String baseUri() {
-        return String.format("sftp://%s@localhost:%d";, TEST_USERNAME, 
serverPort);
-    }
-
     private FileSystemOptions authOptions() throws FileSystemException {
         final FileSystemOptions opts = new FileSystemOptions();
         final StaticUserAuthenticator auth = new StaticUserAuthenticator(null, 
TEST_USERNAME, TEST_PASSWORD);
@@ -135,15 +133,6 @@ public class SftpPasswordAuthTest {
         return opts;
     }
 
-    private static void configureSftpOptions(final FileSystemOptions opts) 
throws FileSystemException {
-        final SftpFileSystemConfigBuilder builder = 
SftpFileSystemConfigBuilder.getInstance();
-        builder.setStrictHostKeyChecking(opts, "no");
-        builder.setUserInfo(opts, new TrustEveryoneUserInfo());
-        builder.setIdentityRepositoryFactory(opts, new 
TestIdentityRepositoryFactory());
-        builder.setConnectTimeout(opts, Duration.ofSeconds(60));
-        builder.setSessionTimeout(opts, Duration.ofSeconds(60));
-    }
-
     @Test
     void testResolveFile() throws FileSystemException {
         final FileSystemOptions opts = authOptions();
@@ -179,7 +168,6 @@ public class SftpPasswordAuthTest {
         final StaticUserAuthenticator auth = new StaticUserAuthenticator(null, 
"wronguser", "wrongpassword");
         
DefaultFileSystemConfigBuilder.getInstance().setUserAuthenticator(opts, auth);
         configureSftpOptions(opts);
-
         final String wrongUserUri = 
String.format("sftp://wronguser@localhost:%d/read-tests/file1.txt";, serverPort);
         assertThrows(FileSystemException.class, () -> {
             try (FileObject file = manager.resolveFile(wrongUserUri, opts)) {
diff --git 
a/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/sftp/SftpTestServerHelper.java
 
b/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/sftp/SftpTestServerHelper.java
index aa02f87a0..0937d3110 100644
--- 
a/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/sftp/SftpTestServerHelper.java
+++ 
b/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/sftp/SftpTestServerHelper.java
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.vfs2.provider.sftp;
 
 import static org.apache.commons.vfs2.VfsTestUtils.getTestDirectoryFile;
@@ -38,6 +39,7 @@ import java.util.NavigableMap;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
+import org.apache.commons.io.IOUtils;
 import org.apache.commons.io.file.PathUtils;
 import org.apache.commons.lang3.Strings;
 import org.apache.sshd.common.file.virtualfs.VirtualFileSystemFactory;
@@ -60,89 +62,105 @@ import org.apache.sshd.sftp.server.SftpSubsystemProxy;
  */
 public final class SftpTestServerHelper {
 
-    private static final String DEFAULT_USER = "testuser";
-    private static final int TEST_UID = 1000;
-    private static final int TEST_GID = 1000;
-    private static SshServer server;
-    private static String connectionUri;
-
-    private SftpTestServerHelper() {
-    }
-
     /**
-     * Custom {@link SftpFileSystemAccessor} that tracks POSIX permissions in 
memory so that
-     * {@code setExecutable}/{@code setReadable}/{@code setWritable} 
round-trip correctly on
-     * platforms without native POSIX support (e.g.&nbsp;Windows).
+     * Command factory for handling special commands needed by VFS tests.
      */
-    private static class TestSftpFileSystemAccessor implements 
SftpFileSystemAccessor {
-        private static final ConcurrentHashMap<String, 
Set<PosixFilePermission>> permissionsCache =
-                new ConcurrentHashMap<>();
+    private static class TestCommandFactory implements CommandFactory {
 
         @Override
-        public void setFilePermissions(
-                final SftpSubsystemProxy subsystem, final Path file,
-                final Set<PosixFilePermission> perms, final LinkOption... 
options) throws IOException {
-            permissionsCache.put(file.toAbsolutePath().toString(), new 
HashSet<>(perms));
+        public Command createCommand(final ChannelSession channel, final 
String command) throws IOException {
+            if (command.startsWith("id -u")) {
+                return createIdCommand("1000");
+            }
+            if (command.startsWith("id -G")) {
+                return createIdCommand("1000 1001 1002");
+            }
+            throw new IOException("Unknown command: " + command);
         }
 
-        @Override
-        public void setFileOwner(
-                final SftpSubsystemProxy subsystem, final Path file,
-                final Principal owner, final LinkOption... options) throws 
IOException {
+        private Command createIdCommand(final String output) {
+            return new Command() {
+
+                private ExitCallback callback;
+
+                private OutputStream out;
+
+                @Override
+                public void destroy(final ChannelSession channel) throws 
Exception {
+                }
+
+                @Override
+                public void setErrorStream(final OutputStream err) {
+                }
+
+                @Override
+                public void setExitCallback(final ExitCallback callback) {
+                    this.callback = callback;
+                }
+
+                @Override
+                public void setInputStream(final InputStream in) {
+                }
+
+                @Override
+                public void setOutputStream(final OutputStream out) {
+                    this.out = out;
+                }
+
+                @Override
+                public void start(final ChannelSession channel, final 
Environment env) throws IOException {
+                    out.write((output + "\n").getBytes());
+                    out.flush();
+                    callback.onExit(0);
+                }
+            };
         }
+    }
 
-        @Override
-        public void setGroupOwner(
-                final SftpSubsystemProxy subsystem, final Path file,
-                final Principal group, final LinkOption... options) throws 
IOException {
-            // No-op: same rationale as setFileOwner.
+    /**
+     * Custom {@link SftpFileSystemAccessor} that tracks POSIX permissions in 
memory so that {@code setExecutable}/{@code setReadable}/{@code setWritable}
+     * round-trip correctly on platforms without native POSIX support 
(e.g.&nbsp;Windows).
+     */
+    private static class TestSftpFileSystemAccessor implements 
SftpFileSystemAccessor {
+
+        private static final ConcurrentHashMap<String, 
Set<PosixFilePermission>> permissionsCache = new ConcurrentHashMap<>();
+
+        static void clearCache() {
+            permissionsCache.clear();
         }
 
-        @Override
-        public void setFileAttribute(
-                final SftpSubsystemProxy subsystem, final Path file,
-                final String view, final String attribute, final Object value,
-                final LinkOption... options) throws IOException {
-            if ("uid".equals(attribute) || "gid".equals(attribute)) {
-                // No-op: SSHD routes integer uid/gid through setFileAttribute
-                // (not setFileOwner/setGroupOwner). The default calls
-                // Files.setAttribute(file, "unix:uid", ...) which throws
-                // IOException on non-root Unix when the uid doesn't match.
-                return;
-            }
+        private static Set<PosixFilePermission> defaultPermissions(final Path 
file, final LinkOption... options) {
+            final Set<PosixFilePermission> perms = 
EnumSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE);
             try {
-                SftpFileSystemAccessor.super.setFileAttribute(subsystem, file, 
view, attribute, value, options);
-            } catch (final IOException | RuntimeException ignored) {
-                // Silently swallow; covers platforms without native POSIX
-                // support and edge-cases where the rooted file system
-                // rejects certain attribute writes.
+                if (Files.isDirectory(file, options)) {
+                    perms.add(PosixFilePermission.OWNER_EXECUTE);
+                }
+            } catch (final Exception ignored) {
+                // ignore
             }
+            return perms;
         }
 
         @Override
-        public Map<String, ?> readFileAttributes(
-                final SftpSubsystemProxy subsystem, final Path file,
-                final String view, final LinkOption... options) throws 
IOException {
+        public Map<String, ?> readFileAttributes(final SftpSubsystemProxy 
subsystem, final Path file, final String view, final LinkOption... options)
+                throws IOException {
             Map<String, ?> result;
             boolean synthetic = false;
             try {
                 result = 
SftpFileSystemAccessor.super.readFileAttributes(subsystem, file, view, options);
             } catch (final UnsupportedOperationException | 
IllegalArgumentException e) {
-                if (view.startsWith("unix:") || view.startsWith("posix:")) {
-                    final Map<String, Object> attrs = new HashMap<>(
-                            Files.readAttributes(file, "basic:*", options));
-                    attrs.put("uid", TEST_UID);
-                    attrs.put("gid", TEST_GID);
-                    result = attrs;
-                    synthetic = true;
-                } else {
+                if (!view.startsWith("unix:") && !view.startsWith("posix:")) {
                     throw e;
                 }
+                final Map<String, Object> attrs = new 
HashMap<>(Files.readAttributes(file, "basic:*", options));
+                attrs.put("uid", TEST_UID);
+                attrs.put("gid", TEST_GID);
+                result = attrs;
+                synthetic = true;
             }
             if (view.startsWith("unix:") || view.startsWith("posix:") || 
synthetic) {
                 final Map<String, Object> attrs = new HashMap<>(result);
-                final Set<PosixFilePermission> cached =
-                        permissionsCache.get(file.toAbsolutePath().toString());
+                final Set<PosixFilePermission> cached = 
permissionsCache.get(file.toAbsolutePath().toString());
                 attrs.put("permissions", cached != null ? cached : 
defaultPermissions(file, options));
                 attrs.put("uid", TEST_UID);
                 attrs.put("gid", TEST_GID);
@@ -152,15 +170,19 @@ public final class SftpTestServerHelper {
         }
 
         @Override
-        public NavigableMap<String, Object> resolveReportedFileAttributes(
-                final SftpSubsystemProxy subsystem, final Path file, final int 
flags,
+        public void removeFile(final SftpSubsystemProxy subsystem, final Path 
path, final boolean isDirectory) throws IOException {
+            permissionsCache.remove(path.toAbsolutePath().toString());
+            SftpFileSystemAccessor.super.removeFile(subsystem, path, 
isDirectory);
+        }
+
+        @Override
+        public NavigableMap<String, Object> 
resolveReportedFileAttributes(final SftpSubsystemProxy subsystem, final Path 
file, final int flags,
                 final NavigableMap<String, Object> attrs, final LinkOption... 
options) throws IOException {
             // Always override uid/gid to match TestCommandFactory's "id 
-u"/"id -G" responses,
             // so that PosixPermissions owner checks are consistent across all 
platforms.
             attrs.put("uid", TEST_UID);
             attrs.put("gid", TEST_GID);
-            final Set<PosixFilePermission> cached =
-                    permissionsCache.get(file.toAbsolutePath().toString());
+            final Set<PosixFilePermission> cached = 
permissionsCache.get(file.toAbsolutePath().toString());
             if (cached != null) {
                 attrs.put("permissions", cached);
             } else if (!attrs.containsKey("permissions")) {
@@ -170,83 +192,66 @@ public final class SftpTestServerHelper {
         }
 
         @Override
-        public void removeFile(
-                final SftpSubsystemProxy subsystem, final Path path,
-                final boolean isDirectory) throws IOException {
-            permissionsCache.remove(path.toAbsolutePath().toString());
-            SftpFileSystemAccessor.super.removeFile(subsystem, path, 
isDirectory);
-        }
-
-        private static Set<PosixFilePermission> defaultPermissions(
-                final Path file, final LinkOption... options) {
-            final Set<PosixFilePermission> perms = EnumSet.of(
-                    PosixFilePermission.OWNER_READ,
-                    PosixFilePermission.OWNER_WRITE);
+        public void setFileAttribute(final SftpSubsystemProxy subsystem, final 
Path file, final String view, final String attribute, final Object value,
+                final LinkOption... options) throws IOException {
+            if ("uid".equals(attribute) || "gid".equals(attribute)) {
+                // No-op: SSHD routes integer uid/gid through setFileAttribute
+                // (not setFileOwner/setGroupOwner). The default calls
+                // Files.setAttribute(file, "unix:uid", ...) which throws
+                // IOException on non-root Unix when the uid doesn't match.
+                return;
+            }
             try {
-                if (Files.isDirectory(file, options)) {
-                    perms.add(PosixFilePermission.OWNER_EXECUTE);
-                }
-            } catch (final Exception ignored) {
-                // ignore
+                SftpFileSystemAccessor.super.setFileAttribute(subsystem, file, 
view, attribute, value, options);
+            } catch (final IOException | RuntimeException ignored) {
+                // Silently swallow; covers platforms without native POSIX
+                // support and edge-cases where the rooted file system
+                // rejects certain attribute writes.
             }
-            return perms;
         }
 
-        static void clearCache() {
-            permissionsCache.clear();
+        @Override
+        public void setFileOwner(final SftpSubsystemProxy subsystem, final 
Path file, final Principal owner, final LinkOption... options) throws 
IOException {
         }
-    }
 
-    /**
-     * Command factory for handling special commands needed by VFS tests.
-     */
-    private static class TestCommandFactory implements CommandFactory {
         @Override
-        public Command createCommand(final ChannelSession channel, final 
String command) throws IOException {
-            if (command.startsWith("id -u")) {
-                return createIdCommand("1000");
-            }
-            if (command.startsWith("id -G")) {
-                return createIdCommand("1000 1001 1002");
-            }
-            throw new IOException("Unknown command: " + command);
+        public void setFilePermissions(final SftpSubsystemProxy subsystem, 
final Path file, final Set<PosixFilePermission> perms, final LinkOption... 
options)
+                throws IOException {
+            permissionsCache.put(file.toAbsolutePath().toString(), new 
HashSet<>(perms));
         }
 
-        private Command createIdCommand(final String output) {
-            return new Command() {
-                private ExitCallback callback;
-                private OutputStream out;
+        @Override
+        public void setGroupOwner(final SftpSubsystemProxy subsystem, final 
Path file, final Principal group, final LinkOption... options) throws 
IOException {
+            // No-op: same rationale as setFileOwner.
+        }
+    }
 
-                @Override
-                public void destroy(final ChannelSession channel) throws 
Exception {
-                }
+    private static final String DEFAULT_USER = "testuser";
 
-                @Override
-                public void setErrorStream(final OutputStream err) {
-                }
+    private static final int TEST_UID = 1000;
 
-                @Override
-                public void setExitCallback(final ExitCallback callback) {
-                    this.callback = callback;
-                }
+    private static final int TEST_GID = 1000;
 
-                @Override
-                public void setInputStream(final InputStream in) {
-                }
+    private static SshServer server;
 
-                @Override
-                public void setOutputStream(final OutputStream out) {
-                    this.out = out;
-                }
+    private static String connectionUri;
 
-                @Override
-                public void start(final ChannelSession channel, final 
Environment env) throws IOException {
-                    out.write((output + "\n").getBytes());
-                    out.flush();
-                    callback.onExit(0);
-                }
-            };
-        }
+    /**
+     * Gets the connection URI for the embedded server.
+     *
+     * @return the connection URI, or null if server is not started
+     */
+    public static String getConnectionUri() {
+        return connectionUri;
+    }
+
+    /**
+     * Checks if the server is running.
+     *
+     * @return true if server is running
+     */
+    public static boolean isServerRunning() {
+        return server != null;
     }
 
     /**
@@ -258,36 +263,24 @@ public final class SftpTestServerHelper {
         if (server != null) {
             return;
         }
-
         final Path tmpDir = PathUtils.getTempDirectory();
         server = SshServer.setUpDefaultServer();
         server.setPort(0);
-
-        final SimpleGeneratorHostKeyProvider keyProvider =
-                new 
SimpleGeneratorHostKeyProvider(tmpDir.resolve("hostkey.ser"));
+        final SimpleGeneratorHostKeyProvider keyProvider = new 
SimpleGeneratorHostKeyProvider(tmpDir.resolve("hostkey.ser"));
         keyProvider.setAlgorithm("RSA");
         server.setKeyPairProvider(keyProvider);
-
         final SftpSubsystemFactory sftpFactory = new SftpSubsystemFactory();
         sftpFactory.setFileSystemAccessor(new TestSftpFileSystemAccessor());
         server.setSubsystemFactories(Collections.singletonList(sftpFactory));
-
-        server.setPasswordAuthenticator(
-                (username, password, session) -> Strings.CS.equals(username, 
password));
+        server.setPasswordAuthenticator((username, password, session) -> 
Strings.CS.equals(username, password));
         
server.setPublickeyAuthenticator(AcceptAllPublickeyAuthenticator.INSTANCE);
-
         server.setCommandFactory(new TestCommandFactory());
-
         final File homeDir = getTestDirectoryFile();
-        server.setFileSystemFactory(
-                new 
VirtualFileSystemFactory(homeDir.toPath().toAbsolutePath()));
-
+        server.setFileSystemFactory(new 
VirtualFileSystemFactory(homeDir.toPath().toAbsolutePath()));
         server.start();
-
         final List<UserAuthFactory> authFactories = new 
ArrayList<>(server.getUserAuthFactories());
         authFactories.add(UserAuthNoneFactory.INSTANCE);
         server.setUserAuthFactories(authFactories);
-
         final int socketPort = server.getPort();
         connectionUri = String.format("sftp://%s@localhost:%d";, DEFAULT_USER, 
socketPort);
     }
@@ -299,32 +292,13 @@ public final class SftpTestServerHelper {
      */
     public static synchronized void stopServer() throws InterruptedException {
         if (server != null) {
-            try {
-                server.close();
-            } catch (final IOException e) {
-                // ignore
-            }
+            IOUtils.closeQuietly(server);
             server = null;
             connectionUri = null;
             TestSftpFileSystemAccessor.clearCache();
         }
     }
 
-    /**
-     * Gets the connection URI for the embedded server.
-     *
-     * @return the connection URI, or null if server is not started
-     */
-    public static String getConnectionUri() {
-        return connectionUri;
-    }
-
-    /**
-     * Checks if the server is running.
-     *
-     * @return true if server is running
-     */
-    public static boolean isServerRunning() {
-        return server != null;
+    private SftpTestServerHelper() {
     }
 }
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 4a4b4cee7..b152a0bf4 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -65,6 +65,8 @@ The <action> type attribute can be add,update,fix,remove.
       <action type="fix" dev="ggregory" due-to="Gary Gregory, Ilan 
Goldfeld">Fix FtpFileObject.exists() returning true for root-level folders 
after connection drop #757.</action>
       <action type="fix" dev="ggregory" due-to="Gary Gregory, Ilan 
Goldfeld">Fix refresh() not clearing cached state when file was never attached 
#758.</action>
       <action type="fix" dev="ggregory" due-to="Ilan Goldfeld, Gary Gregory" 
issue="VFS-862">Fix ON_RESOLVE triggering refresh on internal navigation 
#761.</action>
+      <action type="fix" dev="ggregory" due-to="VaishKumbhar, Gary 
Gregory">Add SFTP password authentication tests for Commons VFS2 #754.</action>
+      <action type="fix" dev="ggregory" due-to="VaishKumbhar, Gary 
Gregory">Port SFTP tests from  Apache SSHd 0.8.0 to 3.0.0-M2 #754.</action>
       <!-- ADD -->
       <action type="add" dev="ggregory" due-to="Gary Gregory">Add 
org.apache.commons.vfs2.provider.ftp.FTPClientWrapper.sendOptions(String, 
String).</action>
       <action type="add" dev="ggregory" due-to="Gary Gregory">Add 
FtpFileSystemConfigBuilder.getControlEncodingCharset(FileSystemOptions) and 
deprecate getControlEncoding(FileSystemOptions).</action>

Reply via email to