Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Unified Diff: webkit/chromeos/fileapi/cros_mount_point_provider_unittest.cc

Issue 11648027: Extract external file systems handling from isolated context. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webkit/chromeos/fileapi/cros_mount_point_provider_unittest.cc
diff --git a/webkit/chromeos/fileapi/cros_mount_point_provider_unittest.cc b/webkit/chromeos/fileapi/cros_mount_point_provider_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b0a1a959810e89ed41a127cca68f1238988b58d9
--- /dev/null
+++ b/webkit/chromeos/fileapi/cros_mount_point_provider_unittest.cc
@@ -0,0 +1,498 @@
+
kinuko 2013/01/08 12:22:43 License comment? It's great to have this test fil
tbarzic 2013/01/09 01:26:34 yeah, test files are always good, I even caught a
+#include "base/file_path.h"
+#include "googleurl/src/url_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webkit/chromeos/fileapi/cros_mount_point_provider.h"
+#include "webkit/fileapi/external_mount_points.h"
+#include "webkit/fileapi/file_system_url.h"
+#include "webkit/fileapi/isolated_context.h"
+#include "webkit/quota/mock_special_storage_policy.h"
+
+#define FPL(x) FILE_PATH_LITERAL(x)
+
+#if defined(FILE_PATH_USES_DRIVE_LETTERS)
+#define DRIVE FPL("C:")
+#else
+#define DRIVE
+#endif
+
+namespace {
+
+FilePath GetFilePath(const std::string& path_str) {
+ return FilePath(DRIVE FPL(path_str));
+}
+
+fileapi::FileSystemURL CreateFileSystemURL(const std::string& extension,
+ const std::string& path) {
+ return fileapi::FileSystemURL(GURL("chrome-extension://" + extension + "/"),
+ fileapi::kFileSystemTypeNativeLocal,
+ GetFilePath(path));
+}
+
+bool VectorHasPath(const std::vector<FilePath>& path_vector,
+ const FilePath& path) {
+ for (size_t i = 0; i < path_vector.size(); ++i) {
+ if (path_vector[i] == path) {
+ return true;
+ }
+ }
+ return false;
+}
+
+TEST(CrosMountPointProviderTest, DefaultMountPoints) {
+ scoped_refptr<quota::SpecialStoragePolicy> storage_policy =
+ new quota::MockSpecialStoragePolicy();
+ scoped_refptr<fileapi::ExternalMountPoints> mount_points(
+ fileapi::ExternalMountPoints::CreateRefCounted());
+ chromeos::CrosMountPointProvider provider(
+ storage_policy,
+ mount_points.get(),
+ fileapi::ExternalMountPoints::GetSystemInstance());
+ // By default there should be 4 mount points.
+ std::vector<FilePath> root_dirs = provider.GetRootDirectories(true);
+ EXPECT_EQ(4u, root_dirs.size());
+ EXPECT_TRUE(VectorHasPath(root_dirs, GetFilePath("/media/removable")));
+ EXPECT_TRUE(VectorHasPath(root_dirs, GetFilePath("/media/archive")));
+ EXPECT_TRUE(VectorHasPath(root_dirs, GetFilePath("/usr/share/oem")));
+ // Fourth mount point is Downloads, but it's local path is device specific.
+}
+
+TEST(CrosMountPointProviderTest, GetRootDirectories) {
+ scoped_refptr<quota::SpecialStoragePolicy> storage_policy =
+ new quota::MockSpecialStoragePolicy();
+ scoped_refptr<fileapi::ExternalMountPoints> mount_points(
+ fileapi::ExternalMountPoints::CreateRefCounted());
+
+ scoped_refptr<fileapi::ExternalMountPoints> system_mount_points(
+ fileapi::ExternalMountPoints::CreateRefCounted());
+
+ chromeos::CrosMountPointProvider provider(
+ storage_policy,
+ mount_points.get(),
+ system_mount_points.get());
+
+ // Register 'local' test mount points.
+ mount_points->RegisterFileSystem("c",
+ fileapi::kFileSystemTypeNativeLocal,
+ GetFilePath("/a/b/c"));
+ mount_points->RegisterFileSystem("d",
+ fileapi::kFileSystemTypeNativeLocal,
+ GetFilePath("/b/c/d"));
+
+ // Register system test mount points.
+ system_mount_points->RegisterFileSystem("d",
+ fileapi::kFileSystemTypeNativeLocal,
+ GetFilePath("/g/c/d"));
+ system_mount_points->RegisterFileSystem("e",
+ fileapi::kFileSystemTypeNativeLocal,
+ GetFilePath("/g/d/e"));
+
+ std::vector<FilePath> root_dirs =
+ provider.GetRootDirectories(true /* include system points */);
+ EXPECT_EQ(4u, root_dirs.size());
+ EXPECT_TRUE(VectorHasPath(root_dirs, GetFilePath("/a/b/c")));
+ EXPECT_TRUE(VectorHasPath(root_dirs, GetFilePath("/b/c/d")));
+ EXPECT_TRUE(VectorHasPath(root_dirs, GetFilePath("/g/c/d")));
+ EXPECT_TRUE(VectorHasPath(root_dirs, GetFilePath("/g/d/e")));
+
+ root_dirs = provider.GetRootDirectories(false /* include system points */);
+ EXPECT_EQ(2u, root_dirs.size());
+ EXPECT_TRUE(VectorHasPath(root_dirs, GetFilePath("/a/b/c")));
+ EXPECT_TRUE(VectorHasPath(root_dirs, GetFilePath("/b/c/d")));
+}
+
+TEST(CrosMountPointProviderTest, MountPointsVisibility) {
+ scoped_refptr<quota::SpecialStoragePolicy> storage_policy =
+ new quota::MockSpecialStoragePolicy();
+ scoped_refptr<fileapi::ExternalMountPoints> mount_points(
+ fileapi::ExternalMountPoints::CreateRefCounted());
+ scoped_refptr<fileapi::ExternalMountPoints> sibling_mount_points(
+ fileapi::ExternalMountPoints::CreateRefCounted());
+
+ scoped_refptr<fileapi::ExternalMountPoints> system_mount_points(
+ fileapi::ExternalMountPoints::CreateRefCounted());
+
+ chromeos::CrosMountPointProvider provider(
+ storage_policy,
+ mount_points.get(),
+ system_mount_points.get());
+
+ // A provider that shares system_mount_points with |provider|.
+ chromeos::CrosMountPointProvider sibling_provider(
+ storage_policy,
+ sibling_mount_points.get(),
+ system_mount_points.get());
+
+ FilePath ignored;
+
+ // Add mount point to the provider.
+ EXPECT_TRUE(provider.AddLocalMountPoint(GetFilePath("/a/b/c")));
+
+ EXPECT_TRUE(provider.HasMountPoint(GetFilePath("/a/b/c")));
+ EXPECT_FALSE(sibling_provider.HasMountPoint(GetFilePath("/a/b/c")));
+ EXPECT_TRUE(mount_points->GetRegisteredPath("c", &ignored));
+ EXPECT_FALSE(system_mount_points->GetRegisteredPath("c", &ignored));
+
+ // Add mount point directly to |mount_points|. It should be seen by
+ // |provider|.
+ EXPECT_TRUE(mount_points->RegisterFileSystem(
+ "d", fileapi::kFileSystemTypeNativeLocal, GetFilePath("/b/c/d")));
+
+ EXPECT_TRUE(provider.HasMountPoint(GetFilePath("/b/c/d")));
+ EXPECT_FALSE(sibling_provider.HasMountPoint(GetFilePath("/b/c/d")));
+
+ // Add mount point to system mount points.
+ EXPECT_TRUE(system_mount_points->RegisterFileSystem(
+ "e", fileapi::kFileSystemTypeNativeLocal, GetFilePath("/g/c/d/e")));
+
+ EXPECT_FALSE(provider.HasMountPoint(GetFilePath("/g/c/d/e")));
+ EXPECT_FALSE(sibling_provider.HasMountPoint(GetFilePath("/g/c/d/e")));
+
+ // Can't remove system nount point.
+ provider.RemoveMountPoint(GetFilePath("/g/c/d/e"));
+ EXPECT_TRUE(system_mount_points->GetRegisteredPath("e", &ignored));
+
+ // Add a mount points whose paths overlap with the system one's.
+ // The same path
+ EXPECT_TRUE(provider.AddLocalMountPoint(GetFilePath("/g/c/d/e")));
+ EXPECT_TRUE(provider.HasMountPoint(GetFilePath("/g/c/d/e")));
+ provider.RemoveMountPoint(GetFilePath("/g/c/d/e"));
+ // Parent path.
+ EXPECT_TRUE(provider.AddLocalMountPoint(GetFilePath("/g")));
+ EXPECT_TRUE(provider.HasMountPoint(GetFilePath("/g")));
+ provider.RemoveMountPoint(GetFilePath("/g"));
+ // Child path.
+ EXPECT_TRUE(provider.AddLocalMountPoint(GetFilePath("/g/c/d/e/f/g")));
+ EXPECT_TRUE(provider.HasMountPoint(GetFilePath("/g/c/d/e/f/g")));
+ provider.RemoveMountPoint(GetFilePath("/g/c/d/e/f/g"));
+
+ // Add mount point with the same name as a global one. Should succeed.
+ EXPECT_TRUE(provider.AddLocalMountPoint(GetFilePath("/d/e")));
+
+ EXPECT_TRUE(provider.HasMountPoint(GetFilePath("/d/e")));
+
+ // Remove system mount point with the same name as the added one.
+ // Should fail.
+ provider.RemoveMountPoint(GetFilePath("/g/c/d/e"));
+
+ EXPECT_TRUE(provider.HasMountPoint(GetFilePath("/d/e")));
+ EXPECT_TRUE(system_mount_points->GetRegisteredPath("e", &ignored));
+
+ // Remove mount point.
+ provider.RemoveMountPoint(GetFilePath("/d/e"));
+
+ EXPECT_FALSE(provider.HasMountPoint(GetFilePath("/d/e")));
+}
+
+TEST(CrosMountPointProviderTest, AddMountPoint) {
+ scoped_refptr<quota::SpecialStoragePolicy> storage_policy =
+ new quota::MockSpecialStoragePolicy();
+ scoped_refptr<fileapi::ExternalMountPoints> mount_points(
+ fileapi::ExternalMountPoints::CreateRefCounted());
+ scoped_refptr<fileapi::ExternalMountPoints> ignored_mount_points(
+ fileapi::ExternalMountPoints::CreateRefCounted());
+ chromeos::CrosMountPointProvider provider(storage_policy,
+ mount_points.get(),
+ ignored_mount_points);
+
+ struct TestCase {
+ const char* const mount_point;
+ bool success;
+ bool should_exist_after_adding;
+ };
+
+ const TestCase kTestCases[] = {
+ // Valid mount point.
+ { "/foo/test", true, true },
+ // Valid mount point with only one path component.
+ { "/bbb/", true, true },
+ // Existing mount point path is substring of the mount points path.
+ { "/foo/test11", true, true },
+ // Path substring of an existing path.
+ { "/foo/test1", true, true },
+ // Empty mount point path.
+ { "", false, false },
+ // Empty mount point name.
+ { "/", false, false },
+ // References parent.
+ { "../foo/invalid", false, false },
+ // Relative path.
+ { "foo/relative", false, false },
+ // Existing mount point.
+ { "/foo/test", false, true },
+ // Existing mount point with trailing /.
+ { "/foo/test/", false, false },
+ // Mount point with the same name exists.
+ { "/foo/a/test", false, false },
+ // Child of an existing mount point.
+ { "/foo/test/a", false, false },
+ // Parent of an existing mount point.
+ { "/foo", false, false },
+ // Bit bigger depth.
+ { "/foo/a/b/c/d/e/f/g", true, true },
+ // Sibling mount point (with similar name) exists.
+ { "/foo/a/b/c/d/e/ff", true, true },
+ // Lexicographically last among existing mount points.
+ { "/zzz/yyy", true, true },
+ // Parent of the lexicographically last mount point.
+ { "/zzz/", false, false },
+ // Child of the lexicographically last mount point.
+ { "/zzz/yyy/xxx", false, false },
+ // Lexicographically first among existing mount points.
+ { "/a/b", true, true },
+ // Parent of lexicographically first mount point.
+ { "/a", false, false },
+ // Child of lexicographically last mount point.
+ { "/a/b/c", false, false },
+ };
+
+ // Test adding mount points.
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
+ FilePath mount_point = GetFilePath(kTestCases[i].mount_point);
+ EXPECT_EQ(kTestCases[i].success,
+ provider.AddLocalMountPoint(mount_point))
+ << "Adding mount point: " << kTestCases[i].mount_point;
+ }
+
+ // Test that final mount point presence state is as expected.
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
+ FilePath mount_point = GetFilePath(kTestCases[i].mount_point);
+ EXPECT_EQ(kTestCases[i].should_exist_after_adding,
+ provider.HasMountPoint(mount_point))
+ << "Has mount point: " << kTestCases[i].mount_point;
+ }
+}
+
+TEST(CrosMountPointProviderTest, AccessPermissions) {
+ url_util::AddStandardScheme("chrome-extension");
+
+ scoped_refptr<quota::MockSpecialStoragePolicy> storage_policy =
+ new quota::MockSpecialStoragePolicy();
+ scoped_refptr<fileapi::ExternalMountPoints> mount_points(
+ fileapi::ExternalMountPoints::CreateRefCounted());
+ scoped_refptr<fileapi::ExternalMountPoints> system_mount_points(
+ fileapi::ExternalMountPoints::CreateRefCounted());
+ chromeos::CrosMountPointProvider provider(
+ storage_policy,
+ mount_points.get(),
+ system_mount_points.get());
+
+ std::string extension("ddammdhioacbehjngdmkjcjbnfginlla");
+
+ storage_policy->AddFileHandler(extension);
+
+ // Initialize mount points.
+ system_mount_points->RegisterFileSystem("system",
+ fileapi::kFileSystemTypeNativeLocal,
+ GetFilePath("/g/system"));
+ ASSERT_TRUE(provider.AddLocalMountPoint(GetFilePath("/media/removable")));
+ ASSERT_TRUE(provider.AddRestrictedLocalMountPoint(
+ GetFilePath("/usr/share/oem")));
+
+ // Provider specific mount point access.
+ EXPECT_FALSE(provider.IsAccessAllowed(CreateFileSystemURL(extension,
+ "removable/foo")));
+
+ provider.GrantFileAccessToExtension(extension, GetFilePath("removable/foo"));
+ EXPECT_TRUE(provider.IsAccessAllowed(CreateFileSystemURL(extension,
+ "removable/foo")));
+ EXPECT_FALSE(provider.IsAccessAllowed(CreateFileSystemURL(extension,
+ "removable/foo1")));
+
+ // System mount point access.
+ EXPECT_FALSE(
+ provider.IsAccessAllowed(CreateFileSystemURL(extension, "system/foo")));
+
+ provider.GrantFileAccessToExtension(extension, GetFilePath("system/foo"));
+ EXPECT_TRUE(
+ provider.IsAccessAllowed(CreateFileSystemURL(extension, "system/foo")));
+ EXPECT_FALSE(
+ provider.IsAccessAllowed(CreateFileSystemURL(extension, "system/foo1")));
+
+ // oem is restricted file system.
+ provider.GrantFileAccessToExtension(extension, GetFilePath("oem/foo"));
+ // The extension should not be able to access the file even if
+ // GrantFileAccessToExtension was called.
+ EXPECT_FALSE(
+ provider.IsAccessAllowed(CreateFileSystemURL(extension, "oem/foo")));
+
+ provider.GrantFullAccessToExtension(extension);
+ // The extension should be able to access restricted file system after it was
+ // granted full access.
+ EXPECT_TRUE(
+ provider.IsAccessAllowed(CreateFileSystemURL(extension, "oem/foo")));
+ // The extension which was granted fulle access should be able to access any
+ // path on curent file systems.
+ EXPECT_TRUE(provider.IsAccessAllowed(
+ CreateFileSystemURL(extension, "removable/foo1")));
+ EXPECT_TRUE(provider.IsAccessAllowed(
+ CreateFileSystemURL(extension, "system/foo1")));
+
+ // The extension still cannot access new mount points.
+ ASSERT_TRUE(provider.AddLocalMountPoint(GetFilePath("/foo/test")));
+ EXPECT_FALSE(
+ provider.IsAccessAllowed(CreateFileSystemURL(extension, "test_/foo")));
+
+ provider.RevokeAccessForExtension(extension);
+ EXPECT_FALSE(provider.IsAccessAllowed(
+ CreateFileSystemURL(extension,"removable/foo")));
+
+ fileapi::FileSystemURL internal_url(GURL("chrome://foo"),
+ fileapi::kFileSystemTypeExternal,
+ GetFilePath("removable/"));
+ // Internal WebUI should have full access.
+ EXPECT_TRUE(provider.IsAccessAllowed(internal_url));
+}
+
+// TODO(tbarzic): This could be moved to external_mount_points tests.
+TEST(CrosMountPointProvider, GetVirtualPath) {
+ scoped_refptr<quota::MockSpecialStoragePolicy> storage_policy =
+ new quota::MockSpecialStoragePolicy();
+ scoped_refptr<fileapi::ExternalMountPoints> mount_points(
+ fileapi::ExternalMountPoints::CreateRefCounted());
+ scoped_refptr<fileapi::ExternalMountPoints> system_mount_points(
+ fileapi::ExternalMountPoints::CreateRefCounted());
+ chromeos::CrosMountPointProvider provider(storage_policy,
+ system_mount_points.get(),
+ mount_points.get());
+
+ ASSERT_TRUE(provider.AddLocalMountPoint(GetFilePath("/a/b/c")));
+ ASSERT_TRUE(provider.AddLocalMountPoint(GetFilePath("/z/y/x")));
+ ASSERT_TRUE(provider.AddLocalMountPoint(GetFilePath("/m/n/o")));
+
+ // Register mount point whose name does not match its path base name.
+ ASSERT_TRUE(
+ mount_points->RegisterFileSystem("mount",
+ fileapi::kFileSystemTypeNativeLocal,
+ FilePath(DRIVE FPL("/root/foo"))));
+
+ struct TestCase {
+ const char* const local_path;
+ bool success;
+ const char* const virtual_path;
+ };
+
+ const TestCase kTestCases[] = {
+ // Empty path.
+ { "", false, "" },
+ // No registered mount point (but is parent to a mount point).
+ { "/a/b", false, ""},
+ // No registered mount point (but is parent to a mount point).
+ { "/z/y", false, ""},
+ // No registered mount point (but is parent to a mount point).
+ { "/m/n", false, ""},
+ // No registered mount point.
+ { "/foo/mount", false, ""},
+ // An existing mount point path is substring.
+ { "/a/b/c1", false, "" },
+ // No leading /.
+ { "a/b/c", false, "" },
+ // Sibling to a root path.
+ { "/a/b/d/e", false, ""},
+ // Sibling to a root path.
+ { "/z/y/v/u", false, ""},
+ // Sibling to a root path.
+ { "/m/n/p/q", false, ""},
+ // Mount point root path.
+ { "/a/b/c", true, "c"},
+ // Mount point root path.
+ { "/z/y/x", true, "x"},
+ // Mount point root path.
+ { "/m/n/o", true, "o"},
+ // Mount point child path.
+ { "/a/b/c/d/e", true, "c/d/e"},
+ // Mount point child path.
+ { "/z/y/x/v/u", true, "x/v/u"},
+ // Mount point child path.
+ { "/m/n/o/p/q", true, "o/p/q"},
+ // Name doesn't match mount point path base name.
+ { "/root/foo/a/b/c", true, "mount/a/b/c" },
+ { "/root/foo", true, "mount" },
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
+ // Init virtual path with a value.
+ FilePath virtual_path(DRIVE FPL("/mount"));
+ FilePath local_path(DRIVE FPL(kTestCases[i].local_path));
+ EXPECT_EQ(kTestCases[i].success,
+ provider.GetVirtualPath(local_path, &virtual_path))
+ << "Resolving " << kTestCases[i].local_path;
+
+ // There are no guaranties for |virtual_path| value if |GetVirtualPath|
+ // fails.
+ if (!kTestCases[i].success)
+ continue;
+
+ FilePath expected_virtual_path(DRIVE FPL(kTestCases[i].virtual_path));
+ EXPECT_EQ(expected_virtual_path, virtual_path)
+ << "Resolving " << kTestCases[i].local_path;
+ }
+}
+
+TEST(CrosMountPointProvider, GetVirtualPathConflictWithSystemPoints) {
+ scoped_refptr<quota::MockSpecialStoragePolicy> storage_policy =
+ new quota::MockSpecialStoragePolicy();
+ scoped_refptr<fileapi::ExternalMountPoints> mount_points(
+ fileapi::ExternalMountPoints::CreateRefCounted());
+ scoped_refptr<fileapi::ExternalMountPoints> system_mount_points(
+ fileapi::ExternalMountPoints::CreateRefCounted());
+ chromeos::CrosMountPointProvider provider(storage_policy,
+ mount_points.get(),
+ system_mount_points.get());
+
+ const fileapi::FileSystemType type = fileapi::kFileSystemTypeNativeLocal;
+
+ // Provider specific mount points.
+ ASSERT_TRUE(
+ mount_points->RegisterFileSystem("b", type, GetFilePath("/a/b")));
+ ASSERT_TRUE(
+ mount_points->RegisterFileSystem("y", type, GetFilePath("/z/y")));
+ ASSERT_TRUE(
+ mount_points->RegisterFileSystem("n", type, GetFilePath("/m/n")));
+
+ // System mount points
+ ASSERT_TRUE(
+ system_mount_points->RegisterFileSystem("gb", type, GetFilePath("/a/b")));
+ ASSERT_TRUE(
+ system_mount_points->RegisterFileSystem("gz", type, GetFilePath("/z")));
+ ASSERT_TRUE(system_mount_points->RegisterFileSystem("gp", type,
+ GetFilePath("/m/n/o/p")));
+ struct TestCase {
+ const char* const local_path;
+ bool success;
+ const char* const virtual_path;
+ };
+
+ const TestCase kTestCases[] = {
+ // Same paths in both mount points.
+ { "/a/b/c/d", true, "b/c/d" },
+ // System mount points path more specific.
+ { "/m/n/o/p/r/s", true, "n/o/p/r/s" },
+ // System mount points path less specific.
+ { "/z/y/x", true, "y/x"},
+ // Only system mount points path matches.
+ { "/z/q/r/s", true, "gz/q/r/s"},
+ // No match.
+ { "/foo/xxx", false, "" },
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
+ // Init virtual path with a value.
+ FilePath virtual_path(DRIVE FPL("/mount"));
+ FilePath local_path(DRIVE FPL(kTestCases[i].local_path));
+ EXPECT_EQ(kTestCases[i].success,
+ provider.GetVirtualPath(local_path, &virtual_path))
+ << "Resolving " << kTestCases[i].local_path;
+
+ // There are no guaranties for |virtual_path| value if |GetVirtualPath|
+ // fails.
+ if (!kTestCases[i].success)
+ continue;
+
+ FilePath expected_virtual_path(DRIVE FPL(kTestCases[i].virtual_path));
+ EXPECT_EQ(expected_virtual_path, virtual_path)
+ << "Resolving " << kTestCases[i].local_path;
+ }
+}
+
+} // namespace

Powered by Google App Engine
This is Rietveld 408576698