You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by gn...@apache.org on 2015/02/23 16:30:07 UTC

[06/15] mina-sshd git commit: [SSHD-377] Create a nio FileSystem implementation for sftp

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cc4d7877/sshd-core/src/test/java/org/apache/sshd/common/file/util/BasePathTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/file/util/BasePathTest.java b/sshd-core/src/test/java/org/apache/sshd/common/file/util/BasePathTest.java
new file mode 100644
index 0000000..55c6b74
--- /dev/null
+++ b/sshd-core/src/test/java/org/apache/sshd/common/file/util/BasePathTest.java
@@ -0,0 +1,560 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sshd.common.file.util;
+
+import java.io.IOException;
+import java.net.URI;
+import java.nio.file.FileSystem;
+import java.nio.file.LinkOption;
+import java.nio.file.Path;
+import java.nio.file.attribute.UserPrincipalLookupService;
+import java.nio.file.spi.FileSystemProvider;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public class BasePathTest {
+
+    private TestFileSystem fileSystem;
+
+    @Before
+    public void setUp() {
+        fileSystem = new TestFileSystem(null);
+    }
+
+    @Test
+    public void testPathParsing() {
+        assertPathEquals("/", "/");
+        assertPathEquals("/foo", "/foo");
+        assertPathEquals("/foo", "/", "foo");
+        assertPathEquals("/foo/bar", "/foo/bar");
+        assertPathEquals("/foo/bar", "/", "foo", "bar");
+        assertPathEquals("/foo/bar", "/foo", "bar");
+        assertPathEquals("/foo/bar", "/", "foo/bar");
+        assertPathEquals("foo/bar/baz", "foo/bar/baz");
+        assertPathEquals("foo/bar/baz", "foo", "bar", "baz");
+        assertPathEquals("foo/bar/baz", "foo/bar", "baz");
+        assertPathEquals("foo/bar/baz", "foo", "bar/baz");
+    }
+
+    @Test
+    public void testPathParsing_withExtraSeparators() {
+        assertPathEquals("/foo/bar", "///foo/bar");
+        assertPathEquals("/foo/bar", "/foo///bar//");
+        assertPathEquals("/foo/bar/baz", "/foo", "/bar", "baz/");
+        //assertPathEquals("/foo/bar/baz", "/foo\\/bar//\\\\/baz\\/");
+    }
+
+    @Test
+    public void testRootPath() {
+        new PathTester(fileSystem, "/")
+                .root("/")
+                .test("/");
+    }
+
+    @Test
+    public void testRelativePath_singleName() {
+        new PathTester(fileSystem, "test")
+                .names("test")
+                .test("test");
+
+        Path path = parsePath("test");
+        assertEquals(path, path.getFileName());
+    }
+
+    @Test
+    public void testRelativePath_twoNames() {
+        PathTester tester = new PathTester(fileSystem, "foo/bar")
+                .names("foo", "bar");
+
+        tester.test("foo/bar");
+    }
+
+    @Test
+    public void testRelativePath_fourNames() {
+        new PathTester(fileSystem, "foo/bar/baz/test")
+                .names("foo", "bar", "baz", "test")
+                .test("foo/bar/baz/test");
+    }
+
+    @Test
+    public void testAbsolutePath_singleName() {
+        new PathTester(fileSystem, "/foo")
+                .root("/")
+                .names("foo")
+                .test("/foo");
+    }
+
+    @Test
+    public void testAbsolutePath_twoNames() {
+        new PathTester(fileSystem, "/foo/bar")
+                .root("/")
+                .names("foo", "bar")
+                .test("/foo/bar");
+    }
+
+    @Test
+    public void testAbsoluteMultiNamePath_fourNames() {
+        new PathTester(fileSystem, "/foo/bar/baz/test")
+                .root("/")
+                .names("foo", "bar", "baz", "test")
+                .test("/foo/bar/baz/test");
+    }
+
+    @Test
+    public void testResolve_fromRoot() {
+        Path root = parsePath("/");
+
+        assertResolvedPathEquals("/foo", root, "foo");
+        assertResolvedPathEquals("/foo/bar", root, "foo/bar");
+        assertResolvedPathEquals("/foo/bar", root, "foo", "bar");
+        assertResolvedPathEquals("/foo/bar/baz/test", root, "foo/bar/baz/test");
+        assertResolvedPathEquals("/foo/bar/baz/test", root, "foo", "bar/baz", "test");
+    }
+
+    @Test
+    public void testResolve_fromAbsolute() {
+        Path path = parsePath("/foo");
+
+        assertResolvedPathEquals("/foo/bar", path, "bar");
+        assertResolvedPathEquals("/foo/bar/baz/test", path, "bar/baz/test");
+        assertResolvedPathEquals("/foo/bar/baz/test", path, "bar/baz", "test");
+        assertResolvedPathEquals("/foo/bar/baz/test", path, "bar", "baz", "test");
+    }
+
+    @Test
+    public void testResolve_fromRelative() {
+        Path path = parsePath("foo");
+
+        assertResolvedPathEquals("foo/bar", path, "bar");
+        assertResolvedPathEquals("foo/bar/baz/test", path, "bar/baz/test");
+        assertResolvedPathEquals("foo/bar/baz/test", path, "bar", "baz", "test");
+        assertResolvedPathEquals("foo/bar/baz/test", path, "bar/baz", "test");
+    }
+
+    @Test
+    public void testResolve_withThisAndParentDirNames() {
+        Path path = parsePath("/foo");
+
+        assertResolvedPathEquals("/foo/bar/../baz", path, "bar/../baz");
+        assertResolvedPathEquals("/foo/bar/../baz", path, "bar", "..", "baz");
+        assertResolvedPathEquals("/foo/./bar/baz", path, "./bar/baz");
+        assertResolvedPathEquals("/foo/./bar/baz", path, ".", "bar/baz");
+    }
+
+    @Test
+    public void testResolve_givenAbsolutePath() {
+        assertResolvedPathEquals("/test", parsePath("/foo"), "/test");
+        assertResolvedPathEquals("/test", parsePath("foo"), "/test");
+    }
+
+    @Test
+    public void testResolve_givenEmptyPath() {
+        assertResolvedPathEquals("/foo", parsePath("/foo"), "");
+        assertResolvedPathEquals("foo", parsePath("foo"), "");
+    }
+
+    @Test
+    public void testResolve_againstEmptyPath() {
+        assertResolvedPathEquals("foo/bar", parsePath(""), "foo/bar");
+    }
+
+    @Test
+    public void testResolveSibling_givenEmptyPath() {
+        Path path = parsePath("foo/bar");
+        Path resolved = path.resolveSibling("");
+        assertPathEquals("foo", resolved);
+
+        path = parsePath("foo");
+        resolved = path.resolveSibling("");
+        assertPathEquals("", resolved);
+    }
+
+    @Test
+    public void testResolveSibling_againstEmptyPath() {
+        Path path = parsePath("");
+        Path resolved = path.resolveSibling("foo");
+        assertPathEquals("foo", resolved);
+
+        path = parsePath("");
+        resolved = path.resolveSibling("");
+        assertPathEquals("", resolved);
+    }
+
+    @Test
+    public void testRelativize_bothAbsolute() {
+        assertRelativizedPathEquals("b/c", parsePath("/a"), "/a/b/c");
+        assertRelativizedPathEquals("c/d", parsePath("/a/b"), "/a/b/c/d");
+    }
+
+    @Test
+    public void testRelativize_bothRelative() {
+        assertRelativizedPathEquals("b/c", parsePath("a"), "a/b/c");
+        assertRelativizedPathEquals("d", parsePath("a/b/c"), "a/b/c/d");
+    }
+
+    @Test
+    public void testRelativize_againstEmptyPath() {
+        assertRelativizedPathEquals("foo/bar", parsePath(""), "foo/bar");
+    }
+
+    @Test
+    public void testRelativize_oneAbsoluteOneRelative() {
+        try {
+            parsePath("/foo/bar").relativize(parsePath("foo"));
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            parsePath("foo").relativize(parsePath("/foo/bar"));
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    @Test
+    public void testNormalize_withParentDirName() {
+        assertNormalizedPathEquals("/foo/baz", "/foo/bar/../baz");
+        assertNormalizedPathEquals("/foo/baz", "/foo", "bar", "..", "baz");
+    }
+
+    @Test
+    public void testNormalize_withThisDirName() {
+        assertNormalizedPathEquals("/foo/bar/baz", "/foo/bar/./baz");
+        assertNormalizedPathEquals("/foo/bar/baz", "/foo", "bar", ".", "baz");
+    }
+
+    @Test
+    public void testNormalize_withThisAndParentDirNames() {
+        assertNormalizedPathEquals("foo/test", "foo/./bar/../././baz/../test");
+    }
+
+    @Test
+    public void testNormalize_withLeadingParentDirNames() {
+        assertNormalizedPathEquals("../../foo/baz", "../../foo/bar/../baz");
+    }
+
+    @Test
+    public void testNormalize_withLeadingThisAndParentDirNames() {
+        assertNormalizedPathEquals("../../foo/baz", "./.././.././foo/bar/../baz");
+    }
+
+    @Test
+    public void testNormalize_withExtraParentDirNamesAtRoot() {
+        assertNormalizedPathEquals("/", "/..");
+        assertNormalizedPathEquals("/", "/../../..");
+        assertNormalizedPathEquals("/", "/foo/../../..");
+        assertNormalizedPathEquals("/", "/../foo/../../bar/baz/../../../..");
+    }
+
+    @Test
+    public void testPathWithExtraSlashes() {
+        assertPathEquals("/foo/bar/baz", parsePath("/foo/bar/baz/"));
+        assertPathEquals("/foo/bar/baz", parsePath("/foo//bar///baz"));
+        assertPathEquals("/foo/bar/baz", parsePath("///foo/bar/baz"));
+    }
+
+    private void assertResolvedPathEquals(String expected, Path path, String firstResolvePath,
+                                          String... moreResolvePaths) {
+        Path resolved = path.resolve(firstResolvePath);
+        for (String additionalPath : moreResolvePaths) {
+            resolved = resolved.resolve(additionalPath);
+        }
+        assertPathEquals(expected, resolved);
+
+        Path relative = parsePath(firstResolvePath, moreResolvePaths);
+        resolved = path.resolve(relative);
+        assertPathEquals(expected, resolved);
+
+        // assert the invariant that p.relativize(p.resolve(q)).equals(q) when q does not have a root
+        // p = path, q = relative, p.resolve(q) = resolved
+        if (relative.getRoot() == null) {
+            assertEquals(relative, path.relativize(resolved));
+        }
+    }
+
+    private void assertRelativizedPathEquals(String expected, Path path, String relativizePath) {
+        Path relativized = path.relativize(parsePath(relativizePath));
+        assertPathEquals(expected, relativized);
+    }
+
+    private void assertNormalizedPathEquals(String expected, String first, String... more) {
+        assertPathEquals(expected, parsePath(first, more).normalize());
+    }
+
+    private void assertPathEquals(String expected, String first, String... more) {
+        assertPathEquals(expected, parsePath(first, more));
+    }
+
+    private void assertPathEquals(String expected, Path path) {
+        assertEquals(parsePath(expected), path);
+    }
+
+    private Path parsePath(String first, String... more) {
+        return fileSystem.getPath(first, more);
+    }
+
+    private static class TestFileSystem extends BaseFileSystem<TestPath> {
+
+        public TestFileSystem(FileSystemProvider fileSystemProvider) {
+            super(fileSystemProvider);
+        }
+
+        @Override
+        protected TestPath create(String root, ImmutableList<String> names) {
+            return new TestPath(this, root, names);
+        }
+
+        @Override
+        public void close() throws IOException {
+
+        }
+
+        @Override
+        public boolean isOpen() {
+            return false;
+        }
+
+        @Override
+        public Set<String> supportedFileAttributeViews() {
+            return null;
+        }
+
+        @Override
+        public UserPrincipalLookupService getUserPrincipalLookupService() {
+            return null;
+        }
+    }
+
+    private static class TestPath extends BasePath<TestPath, TestFileSystem> {
+
+        public TestPath(TestFileSystem fileSystem, String root, ImmutableList<String> names) {
+            super(fileSystem, root, names);
+        }
+
+        @Override
+        protected TestPath create(String root, ImmutableList<String> names) {
+            return new TestPath(fileSystem, root, names);
+        }
+
+        @Override
+        public URI toUri() {
+            return null;
+        }
+
+        @Override
+        public Path toRealPath(LinkOption... options) throws IOException {
+            return null;
+        }
+    }
+
+    public static class PathTester {
+
+        private final FileSystem fileSystem;
+        private final String string;
+        private String root;
+        private ImmutableList<String> names = new ImmutableList<>(new String[0]);
+
+        public PathTester(FileSystem fileSystem, String string) {
+            this.fileSystem = fileSystem;
+            this.string = string;
+        }
+
+        public PathTester root(String root) {
+            this.root = root;
+            return this;
+        }
+
+        public PathTester names(Collection<String> names) {
+            this.names = new ImmutableList<>(names.toArray(new String[names.size()]));
+            return this;
+        }
+
+        public PathTester names(String... names) {
+            return names(Arrays.asList(names));
+        }
+
+        public void test(String first, String... more) {
+            Path path = fileSystem.getPath(first, more);
+            test(path);
+        }
+
+        public void test(Path path) {
+            assertEquals(string, path.toString());
+
+            testRoot(path);
+            testNames(path);
+            testParents(path);
+            testStartsWith(path);
+            testEndsWith(path);
+            testSubpaths(path);
+        }
+
+        private void testRoot(Path path) {
+            if (root != null) {
+                assertTrue(path + ".isAbsolute() should be true", path.isAbsolute());
+                assertNotNull(path + ".getRoot() should not be null", path.getRoot());
+                assertEquals(root, path.getRoot().toString());
+            } else {
+                assertFalse(path + ".isAbsolute() should be false", path.isAbsolute());
+                assertNull(path + ".getRoot() should be null", path.getRoot());
+            }
+        }
+
+        private void testNames(Path path) {
+            assertEquals(names.size(), path.getNameCount());
+            assertEquals(names, names(path));
+            for (int i = 0; i < names.size(); i++) {
+                assertEquals(names.get(i), path.getName(i).toString());
+                // don't test individual names if this is an individual name
+                if (names.size() > 1) {
+                    new PathTester(fileSystem, names.get(i))
+                            .names(names.get(i))
+                            .test(path.getName(i));
+                }
+            }
+            if (names.size() > 0) {
+                String fileName = names.get(names.size() - 1);
+                assertEquals(fileName, path.getFileName().toString());
+                // don't test individual names if this is an individual name
+                if (names.size() > 1) {
+                    new PathTester(fileSystem, fileName)
+                            .names(fileName)
+                            .test(path.getFileName());
+                }
+            }
+        }
+
+        private void testParents(Path path) {
+            Path parent = path.getParent();
+
+            if (root != null && names.size() >= 1 || names.size() > 1) {
+                assertNotNull(parent);
+            }
+
+            if (parent != null) {
+                String parentName = names.size() == 1 ? root :
+                        string.substring(0, string.lastIndexOf('/'));
+                new PathTester(fileSystem, parentName)
+                        .root(root)
+                        .names(names.subList(0, names.size() - 1))
+                        .test(parent);
+            }
+        }
+
+        private void testSubpaths(Path path) {
+            if (path.getRoot() == null) {
+                assertEquals(path, path.subpath(0, path.getNameCount()));
+            }
+
+            if (path.getNameCount() > 1) {
+                String stringWithoutRoot = root == null ? string : string.substring(root.length());
+
+                // test start + 1 to end and start to end - 1 subpaths... this recursively tests all subpaths
+                // actually tests most possible subpaths multiple times but... eh
+                Path startSubpath = path.subpath(1, path.getNameCount());
+                List<String> startNames = split(stringWithoutRoot, "/")
+                        .subList(1, path.getNameCount());
+
+                new PathTester(fileSystem, join(startNames, "/"))
+                        .names(startNames)
+                        .test(startSubpath);
+
+                Path endSubpath = path.subpath(0, path.getNameCount() - 1);
+                List<String> endNames = split(stringWithoutRoot, "/")
+                        .subList(0, path.getNameCount() - 1);
+
+                new PathTester(fileSystem, join(endNames, "/"))
+                        .names(endNames)
+                        .test(endSubpath);
+            }
+        }
+
+        private void testStartsWith(Path path) {
+            // empty path doesn't start with any path
+            if (root != null || !names.isEmpty()) {
+                Path other = path;
+                while (other != null) {
+                    assertTrue(path + ".startsWith(" + other + ") should be true",
+                            path.startsWith(other));
+                    assertTrue(path + ".startsWith(" + other + ") should be true",
+                            path.startsWith(other.toString()));
+                    other = other.getParent();
+                }
+            }
+        }
+
+        private void testEndsWith(Path path) {
+            // empty path doesn't start with any path
+            if (root != null || !names.isEmpty()) {
+                Path other = path;
+                while (other != null) {
+                    assertTrue(path + ".endsWith(" + other + ") should be true",
+                            path.endsWith(other));
+                    assertTrue(path + ".endsWith(" + other + ") should be true",
+                            path.endsWith(other.toString()));
+                    if (other.getRoot() != null && other.getNameCount() > 0) {
+                        other = other.subpath(0, other.getNameCount());
+                    } else if (other.getNameCount() > 1) {
+                        other = other.subpath(1, other.getNameCount());
+                    } else {
+                        other = null;
+                    }
+                }
+            }
+        }
+
+        private static List<String> names(Path path) {
+            List<String> list = new ArrayList<>();
+            for (Path p : path) {
+                list.add(p.toString());
+            }
+            return list;
+        }
+
+        private List<String> split(String string, String sep) {
+            return Arrays.asList(string.split(sep));
+        }
+
+        private static String join(Iterable<String> strings, String sep) {
+            StringBuilder sb = new StringBuilder();
+            for (String s : strings) {
+                if (sb.length() > 0) {
+                    sb.append(sep);
+                }
+                sb.append(s);
+            }
+            return sb.toString();
+        }
+    }
+
+}