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"
23 class IndexedDBTest
: public testing::Test
{
25 const GURL kNormalOrigin
;
26 const GURL kSessionOnlyOrigin
;
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
);
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_
;
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
{
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;
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(
160 base::Bind(&IndexedDBContextImpl::ConnectionOpened
,
165 MockConnection
connection2(!kExpectForceClose
);
166 idb_context
->TaskRunner()->PostTask(
168 base::Bind(&IndexedDBContextImpl::ConnectionOpened
,
172 idb_context
->TaskRunner()->PostTask(
174 base::Bind(&IndexedDBContextImpl::ConnectionClosed
,
179 idb_context
->TaskRunner()->PostTask(
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