15c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Copyright 2014 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/external_mount_points.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_url.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define FPL FILE_PATH_LITERAL
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(FILE_PATH_USES_DRIVE_LETTERS)
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define DRIVE FPL("C:")
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define DRIVE
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemURL;
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace content {
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(ExternalMountPointsTest, AddMountPoint) {
2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_refptr<storage::ExternalMountPoints> mount_points(
2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::ExternalMountPoints::CreateRefCounted());
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  struct TestCase {
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The mount point's name.
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const char* const name;
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The mount point's path.
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath::CharType* const path;
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Whether the mount point registration should succeed.
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool success;
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Path returned by GetRegisteredPath. NULL if the method is expected to
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // fail.
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath::CharType* const registered_path;
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const TestCase kTestCases[] = {
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Valid mount point.
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "test", DRIVE FPL("/foo/test"), true, DRIVE FPL("/foo/test") },
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Valid mount point with only one path component.
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "bbb", DRIVE FPL("/bbb"), true, DRIVE FPL("/bbb") },
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Existing mount point path is substring of the mount points path.
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "test11", DRIVE FPL("/foo/test11"), true, DRIVE FPL("/foo/test11") },
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Path substring of an existing path.
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "test1", DRIVE FPL("/foo/test1"), true, DRIVE FPL("/foo/test1") },
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Empty mount point name and path.
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "", DRIVE FPL(""), false, NULL },
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Empty mount point name.
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "", DRIVE FPL("/ddd"), false, NULL },
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Empty mount point path.
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "empty_path", FPL(""), true, FPL("") },
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Name different from path's base name.
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "not_base_name", DRIVE FPL("/x/y/z"), true, DRIVE FPL("/x/y/z") },
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // References parent.
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "invalid", DRIVE FPL("../foo/invalid"), false, NULL },
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Relative path.
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "relative", DRIVE FPL("foo/relative"), false, NULL },
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Existing mount point path.
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "path_exists", DRIVE FPL("/foo/test"), false, NULL },
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Mount point with the same name exists.
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "test", DRIVE FPL("/foo/a/test_name_exists"), false,
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DRIVE FPL("/foo/test") },
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Child of an existing mount point.
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "a1", DRIVE FPL("/foo/test/a"), false, NULL },
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Parent of an existing mount point.
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "foo1", DRIVE FPL("/foo"), false, NULL },
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Bit bigger depth.
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "g", DRIVE FPL("/foo/a/b/c/d/e/f/g"), true,
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DRIVE FPL("/foo/a/b/c/d/e/f/g") },
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Sibling mount point (with similar name) exists.
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "ff", DRIVE FPL("/foo/a/b/c/d/e/ff"), true,
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       DRIVE FPL("/foo/a/b/c/d/e/ff") },
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Lexicographically last among existing mount points.
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "yyy", DRIVE FPL("/zzz/yyy"), true, DRIVE FPL("/zzz/yyy") },
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Parent of the lexicographically last mount point.
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "zzz1", DRIVE FPL("/zzz"), false, NULL },
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Child of the lexicographically last mount point.
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "xxx1", DRIVE FPL("/zzz/yyy/xxx"), false, NULL },
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Lexicographically first among existing mount points.
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "b", DRIVE FPL("/a/b"), true, DRIVE FPL("/a/b") },
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Parent of lexicographically first mount point.
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "a2", DRIVE FPL("/a"), false, NULL },
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Child of lexicographically last mount point.
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "c1", DRIVE FPL("/a/b/c"), false, NULL },
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Parent to all of the mount points.
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "root", DRIVE FPL("/"), false, NULL },
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Path contains .. component.
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "funky", DRIVE FPL("/tt/fun/../funky"), false, NULL },
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Windows separators.
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(FILE_PATH_USES_WIN_SEPARATORS)
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "win", DRIVE FPL("\\try\\separators\\win"), true,
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DRIVE FPL("\\try\\separators\\win") },
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "win1", DRIVE FPL("\\try/separators\\win1"), true,
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DRIVE FPL("\\try/separators\\win1") },
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "win2", DRIVE FPL("\\try/separators\\win"), false, NULL },
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "win", DRIVE FPL("\\separators\\win"), false, NULL },
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "win1", DRIVE FPL("\\try/separators\\win1"), false, NULL },
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Win separators, but relative path.
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { "win2", DRIVE FPL("try\\separators\\win2"), false, NULL },
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Test adding mount points.
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
11003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_EQ(
11103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        kTestCases[i].success,
11203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        mount_points->RegisterFileSystem(kTestCases[i].name,
11303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                         storage::kFileSystemTypeNativeLocal,
11403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                         storage::FileSystemMountOption(),
11503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                         base::FilePath(kTestCases[i].path)))
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << "Adding mount point: " << kTestCases[i].name << " with path "
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << kTestCases[i].path;
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Test that final mount point presence state is as expected.
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath found_path;
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(kTestCases[i].registered_path != NULL,
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              mount_points->GetRegisteredPath(kTestCases[i].name, &found_path))
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << "Test case: " << i;
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (kTestCases[i].registered_path) {
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath expected_path(kTestCases[i].registered_path);
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(expected_path.NormalizePathSeparators(), found_path);
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(ExternalMountPointsTest, GetVirtualPath) {
13503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_refptr<storage::ExternalMountPoints> mount_points(
13603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::ExternalMountPoints::CreateRefCounted());
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mount_points->RegisterFileSystem("c",
13903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   storage::kFileSystemTypeNativeLocal,
14003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   storage::FileSystemMountOption(),
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   base::FilePath(DRIVE FPL("/a/b/c")));
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Note that "/a/b/c" < "/a/b/c(1)" < "/a/b/c/".
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mount_points->RegisterFileSystem("c(1)",
14403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   storage::kFileSystemTypeNativeLocal,
14503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   storage::FileSystemMountOption(),
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   base::FilePath(DRIVE FPL("/a/b/c(1)")));
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mount_points->RegisterFileSystem("x",
14803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   storage::kFileSystemTypeNativeLocal,
14903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   storage::FileSystemMountOption(),
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   base::FilePath(DRIVE FPL("/z/y/x")));
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mount_points->RegisterFileSystem("o",
15203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   storage::kFileSystemTypeNativeLocal,
15303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   storage::FileSystemMountOption(),
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   base::FilePath(DRIVE FPL("/m/n/o")));
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // A mount point whose name does not match its path base name.
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mount_points->RegisterFileSystem("mount",
15703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   storage::kFileSystemTypeNativeLocal,
15803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   storage::FileSystemMountOption(),
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   base::FilePath(DRIVE FPL("/root/foo")));
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // A mount point with an empty path.
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mount_points->RegisterFileSystem("empty_path",
16203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   storage::kFileSystemTypeNativeLocal,
16303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   storage::FileSystemMountOption(),
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                   base::FilePath());
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  struct TestCase {
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath::CharType* const local_path;
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool success;
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath::CharType* const virtual_path;
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const TestCase kTestCases[] = {
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Empty path.
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { FPL(""), false, FPL("") },
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // No registered mount point (but is parent to a mount point).
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { DRIVE FPL("/a/b"), false, FPL("") },
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // No registered mount point (but is parent to a mount point).
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { DRIVE FPL("/z/y"), false, FPL("") },
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // No registered mount point (but is parent to a mount point).
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { DRIVE FPL("/m/n"), false, FPL("") },
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // No registered mount point.
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { DRIVE FPL("/foo/mount"), false, FPL("") },
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // An existing mount point path is substring.
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { DRIVE FPL("/a/b/c1"), false, FPL("") },
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // No leading /.
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { DRIVE FPL("a/b/c"), false, FPL("") },
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Sibling to a root path.
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { DRIVE FPL("/a/b/d/e"), false, FPL("") },
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Sibling to a root path.
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { DRIVE FPL("/z/y/v/u"), false, FPL("") },
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Sibling to a root path.
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { DRIVE FPL("/m/n/p/q"), false, FPL("") },
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Mount point root path.
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { DRIVE FPL("/a/b/c"), true, FPL("c") },
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Mount point root path.
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { DRIVE FPL("/z/y/x"), true, FPL("x") },
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Mount point root path.
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { DRIVE FPL("/m/n/o"), true, FPL("o") },
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Mount point child path.
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { DRIVE FPL("/a/b/c/d/e"), true, FPL("c/d/e") },
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Mount point child path.
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { DRIVE FPL("/z/y/x/v/u"), true, FPL("x/v/u") },
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Mount point child path.
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { DRIVE FPL("/m/n/o/p/q"), true, FPL("o/p/q") },
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Name doesn't match mount point path base name.
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { DRIVE FPL("/root/foo/a/b/c"), true, FPL("mount/a/b/c") },
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { DRIVE FPL("/root/foo"), true, FPL("mount") },
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Mount point contains character whose ASCII code is smaller than file path
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // separator's.
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { DRIVE FPL("/a/b/c(1)/d/e"), true, FPL("c(1)/d/e") },
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(FILE_PATH_USES_WIN_SEPARATORS)
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Path with win separators mixed in.
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { DRIVE FPL("/a\\b\\c/d"), true, FPL("c/d") },
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Initialize virtual path with a value.
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath virtual_path(DRIVE FPL("/mount"));
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath local_path(kTestCases[i].local_path);
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(kTestCases[i].success,
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              mount_points->GetVirtualPath(local_path, &virtual_path))
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << "Resolving " << kTestCases[i].local_path;
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // There are no guarantees for |virtual_path| value if |GetVirtualPath|
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // fails.
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!kTestCases[i].success)
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath expected_virtual_path(kTestCases[i].virtual_path);
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(expected_virtual_path.NormalizePathSeparators(), virtual_path)
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << "Resolving " << kTestCases[i].local_path;
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(ExternalMountPointsTest, HandlesFileSystemMountType) {
23703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_refptr<storage::ExternalMountPoints> mount_points(
23803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::ExternalMountPoints::CreateRefCounted());
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL test_origin("http://chromium.org");
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::FilePath test_path(FPL("/mount"));
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Should handle External File System.
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(mount_points->HandlesFileSystemMountType(
24503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::kFileSystemTypeExternal));
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Shouldn't handle the rest.
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(mount_points->HandlesFileSystemMountType(
24903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::kFileSystemTypeIsolated));
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(mount_points->HandlesFileSystemMountType(
25103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::kFileSystemTypeTemporary));
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(mount_points->HandlesFileSystemMountType(
25303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::kFileSystemTypePersistent));
25403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_FALSE(
25503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      mount_points->HandlesFileSystemMountType(storage::kFileSystemTypeTest));
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Not even if it's external subtype.
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(mount_points->HandlesFileSystemMountType(
25803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::kFileSystemTypeNativeLocal));
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(mount_points->HandlesFileSystemMountType(
26003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::kFileSystemTypeRestrictedNativeLocal));
26103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_FALSE(
26203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      mount_points->HandlesFileSystemMountType(storage::kFileSystemTypeDrive));
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(mount_points->HandlesFileSystemMountType(
26403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::kFileSystemTypeSyncable));
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(ExternalMountPointsTest, CreateCrackedFileSystemURL) {
26803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_refptr<storage::ExternalMountPoints> mount_points(
26903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::ExternalMountPoints::CreateRefCounted());
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL kTestOrigin("http://chromium.org");
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mount_points->RegisterFileSystem("c",
27403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   storage::kFileSystemTypeNativeLocal,
27503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   storage::FileSystemMountOption(),
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   base::FilePath(DRIVE FPL("/a/b/c")));
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mount_points->RegisterFileSystem("c(1)",
27803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   storage::kFileSystemTypeDrive,
27903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   storage::FileSystemMountOption(),
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   base::FilePath(DRIVE FPL("/a/b/c(1)")));
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mount_points->RegisterFileSystem("empty_path",
28203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   storage::kFileSystemTypeSyncable,
28303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   storage::FileSystemMountOption(),
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                   base::FilePath());
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mount_points->RegisterFileSystem("mount",
28603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   storage::kFileSystemTypeDrive,
28703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   storage::FileSystemMountOption(),
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   base::FilePath(DRIVE FPL("/root")));
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Try cracking invalid GURL.
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL invalid = mount_points->CrackURL(GURL("http://chromium.og"));
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(invalid.is_valid());
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Try cracking isolated path.
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL isolated = mount_points->CreateCrackedFileSystemURL(
29603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      kTestOrigin, storage::kFileSystemTypeIsolated, base::FilePath(FPL("c")));
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(isolated.is_valid());
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Try native local which is not cracked.
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL native_local = mount_points->CreateCrackedFileSystemURL(
3014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      kTestOrigin,
30203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::kFileSystemTypeNativeLocal,
3034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::FilePath(FPL("c")));
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(native_local.is_valid());
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  struct TestCase {
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath::CharType* const path;
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool expect_valid;
30903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::FileSystemType expect_type;
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath::CharType* const expect_path;
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const char* const expect_fs_id;
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const TestCase kTestCases[] = {
31503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("c/d/e"), true, storage::kFileSystemTypeNativeLocal,
31603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)     DRIVE FPL("/a/b/c/d/e"), "c"},
31703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("c(1)/d/e"), true, storage::kFileSystemTypeDrive,
31803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)     DRIVE FPL("/a/b/c(1)/d/e"), "c(1)"},
31903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("c(1)"), true, storage::kFileSystemTypeDrive, DRIVE FPL("/a/b/c(1)"),
32003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)     "c(1)"},
32103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("empty_path/a"), true, storage::kFileSystemTypeSyncable, FPL("a"),
32203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)     "empty_path"},
32303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("empty_path"), true, storage::kFileSystemTypeSyncable, FPL(""),
32403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)     "empty_path"},
32503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("mount/a/b"), true, storage::kFileSystemTypeDrive,
32603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)     DRIVE FPL("/root/a/b"), "mount"},
32703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("mount"), true, storage::kFileSystemTypeDrive, DRIVE FPL("/root"),
32803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)     "mount"},
32903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("cc"), false, storage::kFileSystemTypeUnknown, FPL(""), ""},
33003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL(""), false, storage::kFileSystemTypeUnknown, FPL(""), ""},
33103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL(".."), false, storage::kFileSystemTypeUnknown, FPL(""), ""},
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Absolte paths.
33303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("/c/d/e"), false, storage::kFileSystemTypeUnknown, FPL(""), ""},
33403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("/c(1)/d/e"), false, storage::kFileSystemTypeUnknown, FPL(""), ""},
33503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("/empty_path"), false, storage::kFileSystemTypeUnknown, FPL(""), ""},
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // PAth references parent.
33703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("c/d/../e"), false, storage::kFileSystemTypeUnknown, FPL(""), ""},
33803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("/empty_path/a/../b"), false, storage::kFileSystemTypeUnknown, FPL(""),
33903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)     ""},
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(FILE_PATH_USES_WIN_SEPARATORS)
34103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("c/d\\e"), true, storage::kFileSystemTypeNativeLocal,
34203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)     DRIVE FPL("/a/b/c/d/e"), "c"},
34303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("mount\\a\\b"), true, storage::kFileSystemTypeDrive,
34403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)     DRIVE FPL("/root/a/b"), "mount"},
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FileSystemURL cracked = mount_points->CreateCrackedFileSystemURL(
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        kTestOrigin,
35103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        storage::kFileSystemTypeExternal,
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::FilePath(kTestCases[i].path));
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(kTestCases[i].expect_valid, cracked.is_valid())
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << "Test case index: " << i;
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!kTestCases[i].expect_valid)
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(kTestOrigin, cracked.origin())
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << "Test case index: " << i;
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(kTestCases[i].expect_type, cracked.type())
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << "Test case index: " << i;
3644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_EQ(base::FilePath(
3654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        kTestCases[i].expect_path).NormalizePathSeparators(), cracked.path())
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << "Test case index: " << i;
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(base::FilePath(kTestCases[i].path).NormalizePathSeparators(),
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       cracked.virtual_path())
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << "Test case index: " << i;
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(kTestCases[i].expect_fs_id, cracked.filesystem_id())
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << "Test case index: " << i;
37203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_EQ(storage::kFileSystemTypeExternal, cracked.mount_type())
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << "Test case index: " << i;
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(ExternalMountPointsTest, CrackVirtualPath) {
37803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_refptr<storage::ExternalMountPoints> mount_points(
37903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::ExternalMountPoints::CreateRefCounted());
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL kTestOrigin("http://chromium.org");
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mount_points->RegisterFileSystem("c",
38403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   storage::kFileSystemTypeNativeLocal,
38503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   storage::FileSystemMountOption(),
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   base::FilePath(DRIVE FPL("/a/b/c")));
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mount_points->RegisterFileSystem("c(1)",
38803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   storage::kFileSystemTypeDrive,
38903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   storage::FileSystemMountOption(),
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   base::FilePath(DRIVE FPL("/a/b/c(1)")));
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mount_points->RegisterFileSystem("empty_path",
39203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   storage::kFileSystemTypeSyncable,
39303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   storage::FileSystemMountOption(),
394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                   base::FilePath());
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mount_points->RegisterFileSystem("mount",
39603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   storage::kFileSystemTypeDrive,
39703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   storage::FileSystemMountOption(),
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   base::FilePath(DRIVE FPL("/root")));
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  struct TestCase {
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath::CharType* const path;
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool expect_valid;
40303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::FileSystemType expect_type;
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath::CharType* const expect_path;
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const char* const expect_name;
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const TestCase kTestCases[] = {
40903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("c/d/e"), true, storage::kFileSystemTypeNativeLocal,
41003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)     DRIVE FPL("/a/b/c/d/e"), "c"},
41103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("c(1)/d/e"), true, storage::kFileSystemTypeDrive,
41203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)     DRIVE FPL("/a/b/c(1)/d/e"), "c(1)"},
41303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("c(1)"), true, storage::kFileSystemTypeDrive, DRIVE FPL("/a/b/c(1)"),
41403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)     "c(1)"},
41503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("empty_path/a"), true, storage::kFileSystemTypeSyncable, FPL("a"),
41603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)     "empty_path"},
41703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("empty_path"), true, storage::kFileSystemTypeSyncable, FPL(""),
41803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)     "empty_path"},
41903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("mount/a/b"), true, storage::kFileSystemTypeDrive,
42003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)     DRIVE FPL("/root/a/b"), "mount"},
42103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("mount"), true, storage::kFileSystemTypeDrive, DRIVE FPL("/root"),
42203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)     "mount"},
42303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("cc"), false, storage::kFileSystemTypeUnknown, FPL(""), ""},
42403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL(""), false, storage::kFileSystemTypeUnknown, FPL(""), ""},
42503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL(".."), false, storage::kFileSystemTypeUnknown, FPL(""), ""},
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Absolte paths.
42703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("/c/d/e"), false, storage::kFileSystemTypeUnknown, FPL(""), ""},
42803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("/c(1)/d/e"), false, storage::kFileSystemTypeUnknown, FPL(""), ""},
42903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("/empty_path"), false, storage::kFileSystemTypeUnknown, FPL(""), ""},
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // PAth references parent.
43103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("c/d/../e"), false, storage::kFileSystemTypeUnknown, FPL(""), ""},
43203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("/empty_path/a/../b"), false, storage::kFileSystemTypeUnknown, FPL(""),
43303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)     ""},
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(FILE_PATH_USES_WIN_SEPARATORS)
43503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("c/d\\e"), true, storage::kFileSystemTypeNativeLocal,
43603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)     DRIVE FPL("/a/b/c/d/e"), "c"},
43703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    {FPL("mount\\a\\b"), true, storage::kFileSystemTypeDrive,
43803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)     DRIVE FPL("/root/a/b"), "mount"},
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string cracked_name;
44403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::FileSystemType cracked_type;
4456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    std::string cracked_id;
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath cracked_path;
44703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::FileSystemMountOption cracked_option;
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(kTestCases[i].expect_valid,
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              mount_points->CrackVirtualPath(base::FilePath(kTestCases[i].path),
4506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                  &cracked_name, &cracked_type, &cracked_id, &cracked_path,
4516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                  &cracked_option))
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << "Test case index: " << i;
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!kTestCases[i].expect_valid)
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(kTestCases[i].expect_type, cracked_type)
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << "Test case index: " << i;
4594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_EQ(base::FilePath(
4604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        kTestCases[i].expect_path).NormalizePathSeparators(), cracked_path)
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << "Test case index: " << i;
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(kTestCases[i].expect_name, cracked_name)
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << "Test case index: " << i;
4646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // As of now we don't mount other filesystems with non-empty filesystem_id
4656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // onto external mount points.
4666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    EXPECT_TRUE(cracked_id.empty()) << "Test case index: " << i;
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
470a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST(ExternalMountPointsTest, MountOption) {
47103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_refptr<storage::ExternalMountPoints> mount_points(
47203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::ExternalMountPoints::CreateRefCounted());
473a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
474a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  mount_points->RegisterFileSystem(
475a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "nosync",
47603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::kFileSystemTypeNativeLocal,
47703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::FileSystemMountOption(storage::COPY_SYNC_OPTION_NO_SYNC),
478a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::FilePath(DRIVE FPL("/nosync")));
479a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  mount_points->RegisterFileSystem(
480a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "sync",
48103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::kFileSystemTypeNativeLocal,
48203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::FileSystemMountOption(storage::COPY_SYNC_OPTION_SYNC),
483a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::FilePath(DRIVE FPL("/sync")));
484a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
485a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string name;
48603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  storage::FileSystemType type;
4876d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  std::string cracked_id;
48803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  storage::FileSystemMountOption option;
489a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::FilePath path;
490a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(mount_points->CrackVirtualPath(
4916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      base::FilePath(FPL("nosync/file")), &name, &type, &cracked_id, &path,
4926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      &option));
49303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(storage::COPY_SYNC_OPTION_NO_SYNC, option.copy_sync_option());
494a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(mount_points->CrackVirtualPath(
4956d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      base::FilePath(FPL("sync/file")), &name, &type, &cracked_id, &path,
4966d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      &option));
49703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(storage::COPY_SYNC_OPTION_SYNC, option.copy_sync_option());
498a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
499a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
5005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}  // namespace content
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
502