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

Side by Side Diff: content/browser/in_process_webkit/indexed_db_browsertest.cc

Issue 17840006: Move IndexedDB files out of in_process_webkit (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 5 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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.
4
5 #include "base/bind.h"
6 #include "base/command_line.h"
7 #include "base/file_util.h"
8 #include "base/files/file_path.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/message_loop.h"
11 #include "base/process_util.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/test/thread_test_helper.h"
14 #include "content/browser/browser_main_loop.h"
15 #include "content/browser/indexed_db/indexed_db_context_impl.h"
16 #include "content/browser/web_contents/web_contents_impl.h"
17 #include "content/public/browser/browser_context.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "content/public/browser/render_process_host.h"
20 #include "content/public/browser/storage_partition.h"
21 #include "content/public/browser/web_contents.h"
22 #include "content/public/common/content_switches.h"
23 #include "content/public/common/url_constants.h"
24 #include "content/public/test/browser_test_utils.h"
25 #include "content/shell/shell.h"
26 #include "content/test/content_browser_test.h"
27 #include "content/test/content_browser_test_utils.h"
28 #include "webkit/browser/database/database_util.h"
29 #include "webkit/browser/quota/quota_manager.h"
30
31 using quota::QuotaManager;
32 using webkit_database::DatabaseUtil;
33
34 namespace content {
35
36 // This browser test is aimed towards exercising the IndexedDB bindings and
37 // the actual implementation that lives in the browser side (in_process_webkit).
38 class IndexedDBBrowserTest : public ContentBrowserTest {
39 public:
40 IndexedDBBrowserTest() : disk_usage_(-1) {}
41
42 void SimpleTest(const GURL& test_url, bool incognito = false) {
43 // The test page will perform tests on IndexedDB, then navigate to either
44 // a #pass or #fail ref.
45 Shell* the_browser = incognito ? CreateOffTheRecordBrowser() : shell();
46
47 LOG(INFO) << "Navigating to URL and blocking.";
48 NavigateToURLBlockUntilNavigationsComplete(the_browser, test_url, 2);
49 LOG(INFO) << "Navigation done.";
50 std::string result = the_browser->web_contents()->GetURL().ref();
51 if (result != "pass") {
52 std::string js_result;
53 ASSERT_TRUE(ExecuteScriptAndExtractString(
54 the_browser->web_contents(),
55 "window.domAutomationController.send(getLog())",
56 &js_result));
57 FAIL() << "Failed: " << js_result;
58 }
59 }
60
61 void NavigateAndWaitForTitle(Shell* shell,
62 const char* filename,
63 const char* hash,
64 const char* expected_string) {
65 GURL url = GetTestUrl("indexeddb", filename);
66 if (hash)
67 url = GURL(url.spec() + hash);
68
69 string16 expected_title16(ASCIIToUTF16(expected_string));
70 TitleWatcher title_watcher(shell->web_contents(), expected_title16);
71 NavigateToURL(shell, url);
72 EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle());
73 }
74
75 IndexedDBContextImpl* GetContext() {
76 StoragePartition* partition =
77 BrowserContext::GetDefaultStoragePartition(
78 shell()->web_contents()->GetBrowserContext());
79 return static_cast<IndexedDBContextImpl*>(partition->GetIndexedDBContext());
80 };
81
82 void SetQuota(int quotaKilobytes) {
83 const int kTemporaryStorageQuotaSize = quotaKilobytes
84 * 1024 * QuotaManager::kPerHostTemporaryPortion;
85 SetTempQuota(kTemporaryStorageQuotaSize,
86 BrowserContext::GetDefaultStoragePartition(
87 shell()->web_contents()->GetBrowserContext())->GetQuotaManager());
88 }
89
90 static void SetTempQuota(int64 bytes, scoped_refptr<QuotaManager> qm) {
91 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
92 BrowserThread::PostTask(
93 BrowserThread::IO, FROM_HERE,
94 base::Bind(&IndexedDBBrowserTest::SetTempQuota, bytes, qm));
95 return;
96 }
97 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
98 qm->SetTemporaryGlobalOverrideQuota(bytes, quota::QuotaCallback());
99 // Don't return until the quota has been set.
100 scoped_refptr<base::ThreadTestHelper> helper(new base::ThreadTestHelper(
101 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB).get()));
102 ASSERT_TRUE(helper->Run());
103 }
104
105 virtual int64 RequestDiskUsage() {
106 PostTaskAndReplyWithResult(
107 GetContext()->TaskRunner(),
108 FROM_HERE,
109 base::Bind(&IndexedDBContext::GetOriginDiskUsage,
110 GetContext(),
111 GURL("file:///")),
112 base::Bind(&IndexedDBBrowserTest::DidGetDiskUsage, this));
113 scoped_refptr<base::ThreadTestHelper> helper(new base::ThreadTestHelper(
114 BrowserMainLoop::GetInstance()->indexed_db_thread()
115 ->message_loop_proxy()));
116 EXPECT_TRUE(helper->Run());
117 // Wait for DidGetDiskUsage to be called.
118 base::MessageLoop::current()->RunUntilIdle();
119 return disk_usage_;
120 }
121 private:
122 virtual void DidGetDiskUsage(int64 bytes) {
123 EXPECT_GT(bytes, 0);
124 disk_usage_ = bytes;
125 }
126
127 int64 disk_usage_;
128 };
129
130 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CursorTest) {
131 SimpleTest(GetTestUrl("indexeddb", "cursor_test.html"));
132 }
133
134 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CursorTestIncognito) {
135 SimpleTest(GetTestUrl("indexeddb", "cursor_test.html"),
136 true /* incognito */);
137 }
138
139 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CursorPrefetch) {
140 SimpleTest(GetTestUrl("indexeddb", "cursor_prefetch.html"));
141 }
142
143 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, IndexTest) {
144 SimpleTest(GetTestUrl("indexeddb", "index_test.html"));
145 }
146
147 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, KeyPathTest) {
148 SimpleTest(GetTestUrl("indexeddb", "key_path_test.html"));
149 }
150
151 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, TransactionGetTest) {
152 SimpleTest(GetTestUrl("indexeddb", "transaction_get_test.html"));
153 }
154
155 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, KeyTypesTest) {
156 SimpleTest(GetTestUrl("indexeddb", "key_types_test.html"));
157 }
158
159 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, ObjectStoreTest) {
160 SimpleTest(GetTestUrl("indexeddb", "object_store_test.html"));
161 }
162
163 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DatabaseTest) {
164 SimpleTest(GetTestUrl("indexeddb", "database_test.html"));
165 }
166
167 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, TransactionTest) {
168 SimpleTest(GetTestUrl("indexeddb", "transaction_test.html"));
169 }
170
171 // http://crbug.com/239366
172 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, FLAKY_ValueSizeTest) {
173 SimpleTest(GetTestUrl("indexeddb", "value_size_test.html"));
174 }
175
176 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CallbackAccounting) {
177 SimpleTest(GetTestUrl("indexeddb", "callback_accounting.html"));
178 }
179
180 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DoesntHangTest) {
181 SimpleTest(GetTestUrl("indexeddb", "transaction_run_forever.html"));
182 CrashTab(shell()->web_contents());
183 SimpleTest(GetTestUrl("indexeddb", "transaction_not_blocked.html"));
184 }
185
186 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, Bug84933Test) {
187 const GURL url = GetTestUrl("indexeddb", "bug_84933.html");
188
189 // Just navigate to the URL. Test will crash if it fails.
190 NavigateToURLBlockUntilNavigationsComplete(shell(), url, 1);
191 }
192
193 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, Bug106883Test) {
194 const GURL url = GetTestUrl("indexeddb", "bug_106883.html");
195
196 // Just navigate to the URL. Test will crash if it fails.
197 NavigateToURLBlockUntilNavigationsComplete(shell(), url, 1);
198 }
199
200 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, Bug109187Test) {
201 const GURL url = GetTestUrl("indexeddb", "bug_109187.html");
202
203 // Just navigate to the URL. Test will crash if it fails.
204 NavigateToURLBlockUntilNavigationsComplete(shell(), url, 1);
205 }
206
207 class IndexedDBBrowserTestWithLowQuota : public IndexedDBBrowserTest {
208 public:
209 virtual void SetUpOnMainThread() OVERRIDE {
210 const int kInitialQuotaKilobytes = 5000;
211 SetQuota(kInitialQuotaKilobytes);
212 }
213 };
214
215 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithLowQuota, QuotaTest) {
216 SimpleTest(GetTestUrl("indexeddb", "quota_test.html"));
217 }
218
219 class IndexedDBBrowserTestWithGCExposed : public IndexedDBBrowserTest {
220 public:
221 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
222 command_line->AppendSwitchASCII(switches::kJavaScriptFlags, "--expose-gc");
223 }
224 };
225
226 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithGCExposed,
227 DatabaseCallbacksTest) {
228 SimpleTest(GetTestUrl("indexeddb", "database_callbacks_first.html"));
229 }
230
231 static void CopyLevelDBToProfile(Shell* shell,
232 scoped_refptr<IndexedDBContext> context,
233 const std::string& test_directory) {
234 DCHECK(context->TaskRunner()->RunsTasksOnCurrentThread());
235 base::FilePath leveldb_dir(FILE_PATH_LITERAL("file__0.indexeddb.leveldb"));
236 base::FilePath test_data_dir =
237 GetTestFilePath("indexeddb", test_directory.c_str()).Append(leveldb_dir);
238 IndexedDBContextImpl* context_impl =
239 static_cast<IndexedDBContextImpl*>(context.get());
240 base::FilePath dest = context_impl->data_path().Append(leveldb_dir);
241 // If we don't create the destination directory first, the contents of the
242 // leveldb directory are copied directly into profile/IndexedDB instead of
243 // profile/IndexedDB/file__0.xxx/
244 ASSERT_TRUE(file_util::CreateDirectory(dest));
245 const bool kRecursive = true;
246 ASSERT_TRUE(file_util::CopyDirectory(test_data_dir,
247 context_impl->data_path(),
248 kRecursive));
249 }
250
251 class IndexedDBBrowserTestWithPreexistingLevelDB : public IndexedDBBrowserTest {
252 public:
253 virtual void SetUpOnMainThread() OVERRIDE {
254 scoped_refptr<IndexedDBContextImpl> context = GetContext();
255 context->TaskRunner()->PostTask(
256 FROM_HERE,
257 base::Bind(
258 &CopyLevelDBToProfile, shell(), context, EnclosingLevelDBDir()));
259 scoped_refptr<base::ThreadTestHelper> helper(new base::ThreadTestHelper(
260 BrowserMainLoop::GetInstance()->indexed_db_thread()
261 ->message_loop_proxy()));
262 ASSERT_TRUE(helper->Run());
263 }
264
265 virtual std::string EnclosingLevelDBDir() = 0;
266
267 };
268
269 class IndexedDBBrowserTestWithVersion0Schema : public
270 IndexedDBBrowserTestWithPreexistingLevelDB {
271 virtual std::string EnclosingLevelDBDir() OVERRIDE {
272 return "migration_from_0";
273 }
274 };
275
276 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithVersion0Schema, MigrationTest) {
277 SimpleTest(GetTestUrl("indexeddb", "migration_test.html"));
278 }
279
280 class IndexedDBBrowserTestWithVersion123456Schema : public
281 IndexedDBBrowserTestWithPreexistingLevelDB {
282 virtual std::string EnclosingLevelDBDir() OVERRIDE {
283 return "schema_version_123456";
284 }
285 };
286
287 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithVersion123456Schema,
288 DestroyTest) {
289 int64 original_size = RequestDiskUsage();
290 EXPECT_GT(original_size, 0);
291 SimpleTest(GetTestUrl("indexeddb", "open_bad_db.html"));
292 int64 new_size = RequestDiskUsage();
293 EXPECT_NE(original_size, new_size);
294 }
295
296 class IndexedDBBrowserTestWithVersion987654SSVData : public
297 IndexedDBBrowserTestWithPreexistingLevelDB {
298 virtual std::string EnclosingLevelDBDir() OVERRIDE {
299 return "ssv_version_987654";
300 }
301 };
302
303 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithVersion987654SSVData,
304 DestroyTest) {
305 int64 original_size = RequestDiskUsage();
306 EXPECT_GT(original_size, 0);
307 SimpleTest(GetTestUrl("indexeddb", "open_bad_db.html"));
308 int64 new_size = RequestDiskUsage();
309 EXPECT_NE(original_size, new_size);
310 }
311
312 class IndexedDBBrowserTestWithCorruptLevelDB : public
313 IndexedDBBrowserTestWithPreexistingLevelDB {
314 virtual std::string EnclosingLevelDBDir() OVERRIDE {
315 return "corrupt_leveldb";
316 }
317 };
318
319 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithCorruptLevelDB,
320 DestroyTest) {
321 int64 original_size = RequestDiskUsage();
322 EXPECT_GT(original_size, 0);
323 SimpleTest(GetTestUrl("indexeddb", "open_bad_db.html"));
324 int64 new_size = RequestDiskUsage();
325 EXPECT_NE(original_size, new_size);
326 }
327
328 class IndexedDBBrowserTestWithMissingSSTFile : public
329 IndexedDBBrowserTestWithPreexistingLevelDB {
330 virtual std::string EnclosingLevelDBDir() OVERRIDE {
331 return "missing_sst";
332 }
333 };
334
335 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithMissingSSTFile,
336 DestroyTest) {
337 int64 original_size = RequestDiskUsage();
338 EXPECT_GT(original_size, 0);
339 SimpleTest(GetTestUrl("indexeddb", "open_bad_db.html"));
340 int64 new_size = RequestDiskUsage();
341 EXPECT_NE(original_size, new_size);
342 }
343
344 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, LevelDBLogFileTest) {
345 // Any page that opens an IndexedDB will work here.
346 SimpleTest(GetTestUrl("indexeddb", "database_test.html"));
347 scoped_refptr<IndexedDBContext> context =
348 BrowserContext::GetDefaultStoragePartition(
349 shell()->web_contents()->GetBrowserContext())->
350 GetIndexedDBContext();
351 IndexedDBContextImpl* context_impl =
352 static_cast<IndexedDBContextImpl*>(context.get());
353 base::FilePath leveldb_dir(FILE_PATH_LITERAL("file__0.indexeddb.leveldb"));
354 base::FilePath log_file(FILE_PATH_LITERAL("LOG"));
355 base::FilePath log_file_path =
356 context_impl->data_path().Append(leveldb_dir).Append(log_file);
357 int64 size;
358 EXPECT_TRUE(file_util::GetFileSize(log_file_path, &size));
359 EXPECT_GT(size, 0);
360 }
361
362 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CanDeleteWhenOverQuotaTest) {
363 SimpleTest(GetTestUrl("indexeddb", "fill_up_5k.html"));
364 int64 size = RequestDiskUsage();
365 const int kQuotaKilobytes = 2;
366 EXPECT_GT(size, kQuotaKilobytes * 1024);
367 SetQuota(kQuotaKilobytes);
368 SimpleTest(GetTestUrl("indexeddb", "delete_over_quota.html"));
369 }
370
371 // Complex multi-step (converted from pyauto) tests begin here.
372
373 // Verify null key path persists after restarting browser.
374 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, PRE_NullKeyPathPersistence) {
375 NavigateAndWaitForTitle(shell(), "bug_90635.html", "#part1",
376 "pass - first run");
377 }
378
379 // Verify null key path persists after restarting browser.
380 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, NullKeyPathPersistence) {
381 NavigateAndWaitForTitle(shell(), "bug_90635.html", "#part2",
382 "pass - second run");
383 }
384
385 // Verify that a VERSION_CHANGE transaction is rolled back after a
386 // renderer/browser crash
387 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest,
388 PRE_PRE_VersionChangeCrashResilience) {
389 NavigateAndWaitForTitle(shell(), "version_change_crash.html", "#part1",
390 "pass - part1 - complete");
391 }
392
393 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, PRE_VersionChangeCrashResilience) {
394 NavigateAndWaitForTitle(shell(), "version_change_crash.html", "#part2",
395 "pass - part2 - crash me");
396 NavigateToURL(shell(), GURL(kChromeUIBrowserCrashHost));
397 }
398
399 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, VersionChangeCrashResilience) {
400 NavigateAndWaitForTitle(shell(), "version_change_crash.html", "#part3",
401 "pass - part3 - rolled back");
402 }
403
404 // Verify that open DB connections are closed when a tab is destroyed.
405 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, ConnectionsClosedOnTabClose) {
406 NavigateAndWaitForTitle(shell(), "version_change_blocked.html", "#tab1",
407 "setVersion(2) complete");
408
409 // Start on a different URL to force a new renderer process.
410 Shell* new_shell = CreateBrowser();
411 NavigateToURL(new_shell, GURL(kAboutBlankURL));
412 NavigateAndWaitForTitle(new_shell, "version_change_blocked.html", "#tab2",
413 "setVersion(3) blocked");
414
415 string16 expected_title16(ASCIIToUTF16("setVersion(3) complete"));
416 TitleWatcher title_watcher(new_shell->web_contents(), expected_title16);
417
418 base::KillProcess(
419 shell()->web_contents()->GetRenderProcessHost()->GetHandle(), 0, true);
420 shell()->Close();
421
422 EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle());
423 }
424
425 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698