summaryrefslogtreecommitdiffstats
path: root/chromium/content/browser/fileapi/sandbox_origin_database_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/browser/fileapi/sandbox_origin_database_unittest.cc')
-rw-r--r--chromium/content/browser/fileapi/sandbox_origin_database_unittest.cc305
1 files changed, 305 insertions, 0 deletions
diff --git a/chromium/content/browser/fileapi/sandbox_origin_database_unittest.cc b/chromium/content/browser/fileapi/sandbox_origin_database_unittest.cc
new file mode 100644
index 00000000000..cda5b77d9a8
--- /dev/null
+++ b/chromium/content/browser/fileapi/sandbox_origin_database_unittest.cc
@@ -0,0 +1,305 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <algorithm>
+#include <functional>
+#include <limits>
+#include <string>
+#include <vector>
+
+#include "base/file_util.h"
+#include "base/files/file.h"
+#include "base/files/file_path.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/stl_util.h"
+#include "content/browser/fileapi/sandbox_database_test_helper.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/leveldatabase/src/db/filename.h"
+#include "third_party/leveldatabase/src/include/leveldb/db.h"
+#include "webkit/browser/fileapi/sandbox_origin_database.h"
+#include "webkit/common/fileapi/file_system_util.h"
+
+using fileapi::SandboxOriginDatabase;
+
+namespace content {
+
+namespace {
+const base::FilePath::CharType kFileSystemDirName[] =
+ FILE_PATH_LITERAL("File System");
+const base::FilePath::CharType kOriginDatabaseName[] =
+ FILE_PATH_LITERAL("Origins");
+} // namespace
+
+TEST(SandboxOriginDatabaseTest, BasicTest) {
+ base::ScopedTempDir dir;
+ ASSERT_TRUE(dir.CreateUniqueTempDir());
+ const base::FilePath kFSDir = dir.path().Append(kFileSystemDirName);
+ EXPECT_FALSE(base::PathExists(kFSDir));
+ EXPECT_TRUE(base::CreateDirectory(kFSDir));
+
+ SandboxOriginDatabase database(kFSDir, NULL);
+ std::string origin("origin");
+
+ EXPECT_FALSE(database.HasOriginPath(origin));
+ // Double-check to make sure that had no side effects.
+ EXPECT_FALSE(database.HasOriginPath(origin));
+
+ base::FilePath path0;
+ base::FilePath path1;
+
+ // Empty strings aren't valid origins.
+ EXPECT_FALSE(database.GetPathForOrigin(std::string(), &path0));
+
+ EXPECT_TRUE(database.GetPathForOrigin(origin, &path0));
+ EXPECT_TRUE(database.HasOriginPath(origin));
+ EXPECT_TRUE(database.GetPathForOrigin(origin, &path1));
+ EXPECT_FALSE(path0.empty());
+ EXPECT_FALSE(path1.empty());
+ EXPECT_EQ(path0, path1);
+
+ EXPECT_TRUE(base::PathExists(kFSDir.Append(kOriginDatabaseName)));
+}
+
+TEST(SandboxOriginDatabaseTest, TwoPathTest) {
+ base::ScopedTempDir dir;
+ ASSERT_TRUE(dir.CreateUniqueTempDir());
+ const base::FilePath kFSDir = dir.path().Append(kFileSystemDirName);
+ EXPECT_FALSE(base::PathExists(kFSDir));
+ EXPECT_TRUE(base::CreateDirectory(kFSDir));
+
+ SandboxOriginDatabase database(kFSDir, NULL);
+ std::string origin0("origin0");
+ std::string origin1("origin1");
+
+ EXPECT_FALSE(database.HasOriginPath(origin0));
+ EXPECT_FALSE(database.HasOriginPath(origin1));
+
+ base::FilePath path0;
+ base::FilePath path1;
+ EXPECT_TRUE(database.GetPathForOrigin(origin0, &path0));
+ EXPECT_TRUE(database.HasOriginPath(origin0));
+ EXPECT_FALSE(database.HasOriginPath(origin1));
+ EXPECT_TRUE(database.GetPathForOrigin(origin1, &path1));
+ EXPECT_TRUE(database.HasOriginPath(origin1));
+ EXPECT_FALSE(path0.empty());
+ EXPECT_FALSE(path1.empty());
+ EXPECT_NE(path0, path1);
+
+ EXPECT_TRUE(base::PathExists(kFSDir.Append(kOriginDatabaseName)));
+}
+
+TEST(SandboxOriginDatabaseTest, DropDatabaseTest) {
+ base::ScopedTempDir dir;
+ ASSERT_TRUE(dir.CreateUniqueTempDir());
+ const base::FilePath kFSDir = dir.path().Append(kFileSystemDirName);
+ EXPECT_FALSE(base::PathExists(kFSDir));
+ EXPECT_TRUE(base::CreateDirectory(kFSDir));
+
+ SandboxOriginDatabase database(kFSDir, NULL);
+ std::string origin("origin");
+
+ EXPECT_FALSE(database.HasOriginPath(origin));
+
+ base::FilePath path0;
+ EXPECT_TRUE(database.GetPathForOrigin(origin, &path0));
+ EXPECT_TRUE(database.HasOriginPath(origin));
+ EXPECT_FALSE(path0.empty());
+
+ EXPECT_TRUE(base::PathExists(kFSDir.Append(kOriginDatabaseName)));
+
+ database.DropDatabase();
+
+ base::FilePath path1;
+ EXPECT_TRUE(database.HasOriginPath(origin));
+ EXPECT_TRUE(database.GetPathForOrigin(origin, &path1));
+ EXPECT_FALSE(path1.empty());
+ EXPECT_EQ(path0, path1);
+}
+
+TEST(SandboxOriginDatabaseTest, DeleteOriginTest) {
+ base::ScopedTempDir dir;
+ ASSERT_TRUE(dir.CreateUniqueTempDir());
+ const base::FilePath kFSDir = dir.path().Append(kFileSystemDirName);
+ EXPECT_FALSE(base::PathExists(kFSDir));
+ EXPECT_TRUE(base::CreateDirectory(kFSDir));
+
+ SandboxOriginDatabase database(kFSDir, NULL);
+ std::string origin("origin");
+
+ EXPECT_FALSE(database.HasOriginPath(origin));
+ EXPECT_TRUE(database.RemovePathForOrigin(origin));
+
+ base::FilePath path0;
+ EXPECT_TRUE(database.GetPathForOrigin(origin, &path0));
+ EXPECT_TRUE(database.HasOriginPath(origin));
+ EXPECT_FALSE(path0.empty());
+
+ EXPECT_TRUE(database.RemovePathForOrigin(origin));
+ EXPECT_FALSE(database.HasOriginPath(origin));
+
+ base::FilePath path1;
+ EXPECT_TRUE(database.GetPathForOrigin(origin, &path1));
+ EXPECT_FALSE(path1.empty());
+ EXPECT_NE(path0, path1);
+}
+
+TEST(SandboxOriginDatabaseTest, ListOriginsTest) {
+ base::ScopedTempDir dir;
+ ASSERT_TRUE(dir.CreateUniqueTempDir());
+ const base::FilePath kFSDir = dir.path().Append(kFileSystemDirName);
+ EXPECT_FALSE(base::PathExists(kFSDir));
+ EXPECT_TRUE(base::CreateDirectory(kFSDir));
+
+ std::vector<SandboxOriginDatabase::OriginRecord> origins;
+
+ SandboxOriginDatabase database(kFSDir, NULL);
+ EXPECT_TRUE(database.ListAllOrigins(&origins));
+ EXPECT_TRUE(origins.empty());
+ origins.clear();
+
+ std::string origin0("origin0");
+ std::string origin1("origin1");
+
+ EXPECT_FALSE(database.HasOriginPath(origin0));
+ EXPECT_FALSE(database.HasOriginPath(origin1));
+
+ base::FilePath path0;
+ base::FilePath path1;
+ EXPECT_TRUE(database.GetPathForOrigin(origin0, &path0));
+ EXPECT_TRUE(database.ListAllOrigins(&origins));
+ EXPECT_EQ(origins.size(), 1UL);
+ EXPECT_EQ(origins[0].origin, origin0);
+ EXPECT_EQ(origins[0].path, path0);
+ origins.clear();
+ EXPECT_TRUE(database.GetPathForOrigin(origin1, &path1));
+ EXPECT_TRUE(database.ListAllOrigins(&origins));
+ EXPECT_EQ(origins.size(), 2UL);
+ if (origins[0].origin == origin0) {
+ EXPECT_EQ(origins[0].path, path0);
+ EXPECT_EQ(origins[1].origin, origin1);
+ EXPECT_EQ(origins[1].path, path1);
+ } else {
+ EXPECT_EQ(origins[0].origin, origin1);
+ EXPECT_EQ(origins[0].path, path1);
+ EXPECT_EQ(origins[1].origin, origin0);
+ EXPECT_EQ(origins[1].path, path0);
+ }
+}
+
+TEST(SandboxOriginDatabaseTest, DatabaseRecoveryTest) {
+ // Checks if SandboxOriginDatabase properly handles database corruption.
+ // In this test, we'll register some origins to the origin database, then
+ // corrupt database and its log file.
+ // After repairing, the origin database should be consistent even when some
+ // entries lost.
+
+ base::ScopedTempDir dir;
+ ASSERT_TRUE(dir.CreateUniqueTempDir());
+ const base::FilePath kFSDir = dir.path().Append(kFileSystemDirName);
+ const base::FilePath kDBDir = kFSDir.Append(kOriginDatabaseName);
+ EXPECT_FALSE(base::PathExists(kFSDir));
+ EXPECT_TRUE(base::CreateDirectory(kFSDir));
+
+ const std::string kOrigins[] = {
+ "foo.example.com",
+ "bar.example.com",
+ "baz.example.com",
+ "hoge.example.com",
+ "fuga.example.com",
+ };
+
+ scoped_ptr<SandboxOriginDatabase> database(
+ new SandboxOriginDatabase(kFSDir, NULL));
+ for (size_t i = 0; i < arraysize(kOrigins); ++i) {
+ base::FilePath path;
+ EXPECT_FALSE(database->HasOriginPath(kOrigins[i]));
+ EXPECT_TRUE(database->GetPathForOrigin(kOrigins[i], &path));
+ EXPECT_FALSE(path.empty());
+ EXPECT_TRUE(database->GetPathForOrigin(kOrigins[i], &path));
+
+ if (i != 1)
+ EXPECT_TRUE(base::CreateDirectory(kFSDir.Append(path)));
+ }
+ database.reset();
+
+ const base::FilePath kGarbageDir = kFSDir.AppendASCII("foo");
+ const base::FilePath kGarbageFile = kGarbageDir.AppendASCII("bar");
+ EXPECT_TRUE(base::CreateDirectory(kGarbageDir));
+ base::File file(kGarbageFile,
+ base::File::FLAG_CREATE | base::File::FLAG_WRITE);
+ EXPECT_TRUE(file.IsValid());
+ file.Close();
+
+ // Corrupt database itself and last log entry to drop last 1 database
+ // operation. The database should detect the corruption and should recover
+ // its consistency after recovery.
+ CorruptDatabase(kDBDir, leveldb::kDescriptorFile,
+ 0, std::numeric_limits<size_t>::max());
+ CorruptDatabase(kDBDir, leveldb::kLogFile, -1, 1);
+
+ base::FilePath path;
+ database.reset(new SandboxOriginDatabase(kFSDir, NULL));
+ std::vector<SandboxOriginDatabase::OriginRecord> origins_in_db;
+ EXPECT_TRUE(database->ListAllOrigins(&origins_in_db));
+
+ // Expect all but last added origin will be repaired back, and kOrigins[1]
+ // should be dropped due to absence of backing directory.
+ EXPECT_EQ(arraysize(kOrigins) - 2, origins_in_db.size());
+
+ const std::string kOrigin("piyo.example.org");
+ EXPECT_FALSE(database->HasOriginPath(kOrigin));
+ EXPECT_TRUE(database->GetPathForOrigin(kOrigin, &path));
+ EXPECT_FALSE(path.empty());
+ EXPECT_TRUE(database->HasOriginPath(kOrigin));
+
+ EXPECT_FALSE(base::PathExists(kGarbageFile));
+ EXPECT_FALSE(base::PathExists(kGarbageDir));
+}
+
+TEST(SandboxOriginDatabaseTest, DatabaseRecoveryForMissingDBFileTest) {
+ const leveldb::FileType kLevelDBFileTypes[] = {
+ leveldb::kLogFile,
+ leveldb::kDBLockFile,
+ leveldb::kTableFile,
+ leveldb::kDescriptorFile,
+ leveldb::kCurrentFile,
+ leveldb::kTempFile,
+ leveldb::kInfoLogFile,
+ };
+
+ for (size_t i = 0; i < arraysize(kLevelDBFileTypes); ++i) {
+ base::ScopedTempDir dir;
+ ASSERT_TRUE(dir.CreateUniqueTempDir());
+ const base::FilePath kFSDir = dir.path().Append(kFileSystemDirName);
+ const base::FilePath kDBDir = kFSDir.Append(kOriginDatabaseName);
+ EXPECT_FALSE(base::PathExists(kFSDir));
+ EXPECT_TRUE(base::CreateDirectory(kFSDir));
+
+ const std::string kOrigin = "foo.example.com";
+ base::FilePath path;
+
+ scoped_ptr<SandboxOriginDatabase> database(
+ new SandboxOriginDatabase(kFSDir, NULL));
+ EXPECT_FALSE(database->HasOriginPath(kOrigin));
+ EXPECT_TRUE(database->GetPathForOrigin(kOrigin, &path));
+ EXPECT_FALSE(path.empty());
+ EXPECT_TRUE(database->GetPathForOrigin(kOrigin, &path));
+ EXPECT_TRUE(base::CreateDirectory(kFSDir.Append(path)));
+ database.reset();
+
+ DeleteDatabaseFile(kDBDir, kLevelDBFileTypes[i]);
+
+ database.reset(new SandboxOriginDatabase(kFSDir, NULL));
+ std::vector<SandboxOriginDatabase::OriginRecord> origins_in_db;
+ EXPECT_TRUE(database->ListAllOrigins(&origins_in_db));
+
+ const std::string kOrigin2("piyo.example.org");
+ EXPECT_FALSE(database->HasOriginPath(kOrigin2));
+ EXPECT_TRUE(database->GetPathForOrigin(kOrigin2, &path));
+ EXPECT_FALSE(path.empty());
+ EXPECT_TRUE(database->HasOriginPath(kOrigin2));
+ }
+}
+
+} // namespace content