Respond with QuotaExceededError when IndexedDB has no disk space on open.
[chromium-blink-merge.git] / content / browser / indexed_db / indexed_db_unittest.cc
blobc9aec2915f215dbbdf7f69a75e69230065e5e52e
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/file_util.h"
6 #include "base/files/scoped_temp_dir.h"
7 #include "base/test/test_simple_task_runner.h"
8 #include "base/threading/thread.h"
9 #include "content/browser/browser_thread_impl.h"
10 #include "content/browser/indexed_db/indexed_db_connection.h"
11 #include "content/browser/indexed_db/indexed_db_context_impl.h"
12 #include "content/public/browser/storage_partition.h"
13 #include "content/public/common/url_constants.h"
14 #include "content/public/test/test_browser_context.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "webkit/browser/quota/mock_special_storage_policy.h"
17 #include "webkit/browser/quota/quota_manager.h"
18 #include "webkit/browser/quota/special_storage_policy.h"
19 #include "webkit/common/database/database_identifier.h"
21 namespace content {
23 class IndexedDBTest : public testing::Test {
24 public:
25 const GURL kNormalOrigin;
26 const GURL kSessionOnlyOrigin;
28 IndexedDBTest()
29 : kNormalOrigin("http://normal/"),
30 kSessionOnlyOrigin("http://session-only/"),
31 message_loop_(base::MessageLoop::TYPE_IO),
32 task_runner_(new base::TestSimpleTaskRunner),
33 special_storage_policy_(new quota::MockSpecialStoragePolicy),
34 file_thread_(BrowserThread::FILE_USER_BLOCKING, &message_loop_),
35 io_thread_(BrowserThread::IO, &message_loop_) {
36 special_storage_policy_->AddSessionOnly(kSessionOnlyOrigin);
39 protected:
40 void FlushIndexedDBTaskRunner() { task_runner_->RunUntilIdle(); }
42 base::MessageLoop message_loop_;
43 scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
44 scoped_refptr<quota::MockSpecialStoragePolicy> special_storage_policy_;
46 private:
47 BrowserThreadImpl file_thread_;
48 BrowserThreadImpl io_thread_;
51 TEST_F(IndexedDBTest, ClearSessionOnlyDatabases) {
52 base::ScopedTempDir temp_dir;
53 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
55 base::FilePath normal_path;
56 base::FilePath session_only_path;
58 // Create the scope which will ensure we run the destructor of the context
59 // which should trigger the clean up.
61 scoped_refptr<IndexedDBContextImpl> idb_context = new IndexedDBContextImpl(
62 temp_dir.path(), special_storage_policy_, NULL, task_runner_);
64 normal_path = idb_context->GetFilePathForTesting(
65 webkit_database::GetIdentifierFromOrigin(kNormalOrigin));
66 session_only_path = idb_context->GetFilePathForTesting(
67 webkit_database::GetIdentifierFromOrigin(kSessionOnlyOrigin));
68 ASSERT_TRUE(file_util::CreateDirectory(normal_path));
69 ASSERT_TRUE(file_util::CreateDirectory(session_only_path));
70 FlushIndexedDBTaskRunner();
71 message_loop_.RunUntilIdle();
74 FlushIndexedDBTaskRunner();
75 message_loop_.RunUntilIdle();
77 EXPECT_TRUE(base::DirectoryExists(normal_path));
78 EXPECT_FALSE(base::DirectoryExists(session_only_path));
81 TEST_F(IndexedDBTest, SetForceKeepSessionState) {
82 base::ScopedTempDir temp_dir;
83 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
85 base::FilePath normal_path;
86 base::FilePath session_only_path;
88 // Create the scope which will ensure we run the destructor of the context.
90 // Create some indexedDB paths.
91 // With the levelDB backend, these are directories.
92 scoped_refptr<IndexedDBContextImpl> idb_context = new IndexedDBContextImpl(
93 temp_dir.path(), special_storage_policy_, NULL, task_runner_);
95 // Save session state. This should bypass the destruction-time deletion.
96 idb_context->SetForceKeepSessionState();
98 normal_path = idb_context->GetFilePathForTesting(
99 webkit_database::GetIdentifierFromOrigin(kNormalOrigin));
100 session_only_path = idb_context->GetFilePathForTesting(
101 webkit_database::GetIdentifierFromOrigin(kSessionOnlyOrigin));
102 ASSERT_TRUE(file_util::CreateDirectory(normal_path));
103 ASSERT_TRUE(file_util::CreateDirectory(session_only_path));
104 message_loop_.RunUntilIdle();
107 // Make sure we wait until the destructor has run.
108 message_loop_.RunUntilIdle();
110 // No data was cleared because of SetForceKeepSessionState.
111 EXPECT_TRUE(base::DirectoryExists(normal_path));
112 EXPECT_TRUE(base::DirectoryExists(session_only_path));
115 class MockConnection : public IndexedDBConnection {
116 public:
117 explicit MockConnection(bool expect_force_close)
118 : IndexedDBConnection(NULL, NULL),
119 expect_force_close_(expect_force_close),
120 force_close_called_(false) {}
122 virtual ~MockConnection() {
123 EXPECT_TRUE(force_close_called_ == expect_force_close_);
126 virtual void ForceClose() OVERRIDE {
127 ASSERT_TRUE(expect_force_close_);
128 force_close_called_ = true;
131 private:
132 bool expect_force_close_;
133 bool force_close_called_;
136 TEST_F(IndexedDBTest, ForceCloseOpenDatabasesOnDelete) {
137 base::ScopedTempDir temp_dir;
138 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
140 base::FilePath test_path;
142 // Create the scope which will ensure we run the destructor of the context.
144 TestBrowserContext browser_context;
146 const GURL kTestOrigin("http://test/");
148 scoped_refptr<IndexedDBContextImpl> idb_context = new IndexedDBContextImpl(
149 temp_dir.path(), special_storage_policy_, NULL, task_runner_);
151 test_path = idb_context->GetFilePathForTesting(
152 webkit_database::GetIdentifierFromOrigin(kTestOrigin));
153 ASSERT_TRUE(file_util::CreateDirectory(test_path));
155 const bool kExpectForceClose = true;
157 MockConnection connection1(kExpectForceClose);
158 idb_context->TaskRunner()->PostTask(
159 FROM_HERE,
160 base::Bind(&IndexedDBContextImpl::ConnectionOpened,
161 idb_context,
162 kTestOrigin,
163 &connection1));
165 MockConnection connection2(!kExpectForceClose);
166 idb_context->TaskRunner()->PostTask(
167 FROM_HERE,
168 base::Bind(&IndexedDBContextImpl::ConnectionOpened,
169 idb_context,
170 kTestOrigin,
171 &connection2));
172 idb_context->TaskRunner()->PostTask(
173 FROM_HERE,
174 base::Bind(&IndexedDBContextImpl::ConnectionClosed,
175 idb_context,
176 kTestOrigin,
177 &connection2));
179 idb_context->TaskRunner()->PostTask(
180 FROM_HERE,
181 base::Bind(
182 &IndexedDBContextImpl::DeleteForOrigin, idb_context, kTestOrigin));
183 FlushIndexedDBTaskRunner();
184 message_loop_.RunUntilIdle();
187 // Make sure we wait until the destructor has run.
188 message_loop_.RunUntilIdle();
190 EXPECT_FALSE(base::DirectoryExists(test_path));
193 } // namespace content