OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/bind.h" | 5 #include "base/bind.h" |
6 #include "base/command_line.h" | 6 #include "base/command_line.h" |
7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
8 #include "base/files/file_enumerator.h" | |
9 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
10 #include "base/memory/ref_counted.h" | 9 #include "base/memory/ref_counted.h" |
11 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
12 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
13 #include "base/test/thread_test_helper.h" | 12 #include "base/test/thread_test_helper.h" |
14 #include "content/browser/browser_main_loop.h" | 13 #include "content/browser/browser_main_loop.h" |
15 #include "content/browser/indexed_db/indexed_db_context_impl.h" | 14 #include "content/browser/indexed_db/indexed_db_context_impl.h" |
16 #include "content/browser/web_contents/web_contents_impl.h" | 15 #include "content/browser/web_contents/web_contents_impl.h" |
17 #include "content/public/browser/browser_context.h" | 16 #include "content/public/browser/browser_context.h" |
18 #include "content/public/browser/browser_thread.h" | 17 #include "content/public/browser/browser_thread.h" |
19 #include "content/public/browser/render_process_host.h" | 18 #include "content/public/browser/render_process_host.h" |
20 #include "content/public/browser/storage_partition.h" | 19 #include "content/public/browser/storage_partition.h" |
21 #include "content/public/browser/web_contents.h" | 20 #include "content/public/browser/web_contents.h" |
22 #include "content/public/common/content_switches.h" | 21 #include "content/public/common/content_switches.h" |
23 #include "content/public/common/url_constants.h" | 22 #include "content/public/common/url_constants.h" |
24 #include "content/public/test/browser_test_utils.h" | 23 #include "content/public/test/browser_test_utils.h" |
25 #include "content/public/test/content_browser_test.h" | 24 #include "content/public/test/content_browser_test.h" |
26 #include "content/public/test/content_browser_test_utils.h" | 25 #include "content/public/test/content_browser_test_utils.h" |
27 #include "content/shell/browser/shell.h" | 26 #include "content/shell/browser/shell.h" |
28 #include "net/base/net_errors.h" | |
29 #include "net/test/embedded_test_server/embedded_test_server.h" | |
30 #include "net/test/embedded_test_server/http_request.h" | |
31 #include "net/test/embedded_test_server/http_response.h" | |
32 #include "webkit/browser/database/database_util.h" | 27 #include "webkit/browser/database/database_util.h" |
33 #include "webkit/browser/quota/quota_manager.h" | 28 #include "webkit/browser/quota/quota_manager.h" |
34 | 29 |
35 using base::ASCIIToUTF16; | 30 using base::ASCIIToUTF16; |
36 using quota::QuotaManager; | 31 using quota::QuotaManager; |
37 using webkit_database::DatabaseUtil; | 32 using webkit_database::DatabaseUtil; |
38 | 33 |
39 namespace content { | 34 namespace content { |
40 | 35 |
41 // This browser test is aimed towards exercising the IndexedDB bindings and | 36 // This browser test is aimed towards exercising the IndexedDB bindings and |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 | 349 |
355 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CanDeleteWhenOverQuotaTest) { | 350 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CanDeleteWhenOverQuotaTest) { |
356 SimpleTest(GetTestUrl("indexeddb", "fill_up_5k.html")); | 351 SimpleTest(GetTestUrl("indexeddb", "fill_up_5k.html")); |
357 int64 size = RequestDiskUsage(); | 352 int64 size = RequestDiskUsage(); |
358 const int kQuotaKilobytes = 2; | 353 const int kQuotaKilobytes = 2; |
359 EXPECT_GT(size, kQuotaKilobytes * 1024); | 354 EXPECT_GT(size, kQuotaKilobytes * 1024); |
360 SetQuota(kQuotaKilobytes); | 355 SetQuota(kQuotaKilobytes); |
361 SimpleTest(GetTestUrl("indexeddb", "delete_over_quota.html")); | 356 SimpleTest(GetTestUrl("indexeddb", "delete_over_quota.html")); |
362 } | 357 } |
363 | 358 |
364 namespace { | |
365 | |
366 static void CompactIndexedDBBackingStore( | |
367 scoped_refptr<IndexedDBContextImpl> context, | |
368 const GURL& origin_url) { | |
369 IndexedDBFactory* factory = context->GetIDBFactory(); | |
370 | |
371 std::pair<IndexedDBFactory::OriginDBMapIterator, | |
372 IndexedDBFactory::OriginDBMapIterator> range = | |
373 factory->GetOpenDatabasesForOrigin(origin_url); | |
374 | |
375 if (range.first == range.second) // If no open db's for this origin | |
376 return; | |
377 | |
378 // Compact the first db's backing store since all the db's are in the same | |
379 // backing store. | |
380 IndexedDBDatabase* db = range.first->second; | |
381 IndexedDBBackingStore* backing_store = db->backing_store(); | |
382 backing_store->Compact(); | |
383 } | |
384 | |
385 static void CorruptIndexedDBDatabase( | |
386 IndexedDBContextImpl* context, | |
387 const GURL& origin_url, | |
388 base::WaitableEvent* signal_when_finished) { | |
389 | |
390 CompactIndexedDBBackingStore(context, origin_url); | |
391 | |
392 int numFiles = 0; | |
393 int numErrors = 0; | |
394 base::FilePath idb_data_path = context->GetFilePath(origin_url); | |
395 const bool recursive = false; | |
396 base::FileEnumerator enumerator( | |
397 idb_data_path, recursive, base::FileEnumerator::FILES); | |
398 for (base::FilePath idb_file = enumerator.Next(); !idb_file.empty(); | |
399 idb_file = enumerator.Next()) { | |
400 int64 size(0); | |
401 GetFileSize(idb_file, &size); | |
402 | |
403 if (idb_file.Extension() == FILE_PATH_LITERAL(".ldb")) { | |
404 numFiles++; | |
405 base::ScopedFILE f(base::OpenFile(idb_file, "w")); | |
406 if (f) { | |
407 char zero(0); | |
408 if (size != (int64)fwrite(&zero, sizeof(zero), size, f.get())) | |
409 numErrors++; | |
410 } else { | |
411 numErrors++; | |
412 } | |
413 } | |
414 } | |
415 | |
416 VLOG(0) << "There were " << numFiles << " in " << idb_data_path.value() | |
417 << " with " << numErrors << " errors"; | |
418 signal_when_finished->Signal(); | |
419 } | |
420 | |
421 const std::string s_corrupt_db_test_prefix = "/corrupt/test/"; | |
422 | |
423 static scoped_ptr<net::test_server::HttpResponse> CorruptDBRequestHandler( | |
424 IndexedDBContextImpl* context, | |
425 const GURL& origin_url, | |
426 const std::string& path, | |
427 const net::test_server::HttpRequest& request) { | |
428 | |
429 std::string request_path; | |
430 if (path.find(s_corrupt_db_test_prefix) != std::string::npos) | |
431 request_path = request.relative_url.substr(s_corrupt_db_test_prefix.size()); | |
432 else | |
433 return scoped_ptr<net::test_server::HttpResponse>(); | |
434 | |
435 // Remove the query string if present. | |
436 std::string request_query; | |
437 size_t query_pos = request_path.find('?'); | |
438 if (query_pos != std::string::npos) { | |
439 request_query = request_path.substr(query_pos + 1); | |
440 request_path = request_path.substr(0, query_pos); | |
441 } | |
442 | |
443 if (request_path == "corruptdb" && !request_query.empty()) { | |
444 VLOG(0) << "Requested to corrupt IndexedDB: " << request_query; | |
445 base::WaitableEvent signal_when_finished(false, false); | |
446 context->TaskRunner()->PostTask(FROM_HERE, | |
447 base::Bind(&CorruptIndexedDBDatabase, | |
448 base::ConstRef(context), | |
449 origin_url, | |
450 &signal_when_finished)); | |
451 signal_when_finished.Wait(); | |
452 | |
453 scoped_ptr<net::test_server::BasicHttpResponse> http_response( | |
454 new net::test_server::BasicHttpResponse); | |
455 http_response->set_code(net::HTTP_OK); | |
456 return http_response.PassAs<net::test_server::HttpResponse>(); | |
457 } | |
458 | |
459 // A request for a test resource | |
460 base::FilePath resourcePath = | |
461 content::GetTestFilePath("indexeddb", request_path.c_str()); | |
462 scoped_ptr<net::test_server::BasicHttpResponse> http_response( | |
463 new net::test_server::BasicHttpResponse); | |
464 http_response->set_code(net::HTTP_OK); | |
465 std::string file_contents; | |
466 if (!base::ReadFileToString(resourcePath, &file_contents)) | |
467 return scoped_ptr<net::test_server::HttpResponse>(); | |
468 http_response->set_content(file_contents); | |
469 return http_response.PassAs<net::test_server::HttpResponse>(); | |
470 } | |
471 | |
472 } // namespace | |
473 | |
474 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CorruptedOpenDatabase) { | |
475 ASSERT_TRUE(embedded_test_server()->Started() || | |
476 embedded_test_server()->InitializeAndWaitUntilReady()); | |
477 const GURL& origin_url = embedded_test_server()->base_url(); | |
478 embedded_test_server()->RegisterRequestHandler( | |
479 base::Bind(&CorruptDBRequestHandler, | |
480 base::ConstRef(GetContext()), | |
481 origin_url, | |
482 s_corrupt_db_test_prefix)); | |
483 | |
484 std::string test_file = | |
485 s_corrupt_db_test_prefix + "corrupted_open_db_detection.html"; | |
486 SimpleTest(embedded_test_server()->GetURL(test_file)); | |
487 | |
488 test_file = s_corrupt_db_test_prefix + "corrupted_open_db_recovery.html"; | |
489 SimpleTest(embedded_test_server()->GetURL(test_file)); | |
490 } | |
491 | |
492 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DeleteCompactsBackingStore) { | 359 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DeleteCompactsBackingStore) { |
493 const GURL test_url = GetTestUrl("indexeddb", "delete_compact.html"); | 360 const GURL test_url = GetTestUrl("indexeddb", "delete_compact.html"); |
494 SimpleTest(GURL(test_url.spec() + "#fill")); | 361 SimpleTest(GURL(test_url.spec() + "#fill")); |
495 int64 after_filling = RequestDiskUsage(); | 362 int64 after_filling = RequestDiskUsage(); |
496 EXPECT_GT(after_filling, 0); | 363 EXPECT_GT(after_filling, 0); |
497 | 364 |
498 SimpleTest(GURL(test_url.spec() + "#purge")); | 365 SimpleTest(GURL(test_url.spec() + "#purge")); |
499 int64 after_deleting = RequestDiskUsage(); | 366 int64 after_deleting = RequestDiskUsage(); |
500 EXPECT_LT(after_deleting, after_filling); | 367 EXPECT_LT(after_deleting, after_filling); |
501 | 368 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
575 "connection ready"); | 442 "connection ready"); |
576 | 443 |
577 GetContext()->TaskRunner()->PostTask( | 444 GetContext()->TaskRunner()->PostTask( |
578 FROM_HERE, | 445 FROM_HERE, |
579 base::Bind(&IndexedDBContextImpl::DeleteForOrigin, | 446 base::Bind(&IndexedDBContextImpl::DeleteForOrigin, |
580 GetContext(), | 447 GetContext(), |
581 GURL("file:///"))); | 448 GURL("file:///"))); |
582 | 449 |
583 base::string16 expected_title16(ASCIIToUTF16("connection closed")); | 450 base::string16 expected_title16(ASCIIToUTF16("connection closed")); |
584 TitleWatcher title_watcher(shell()->web_contents(), expected_title16); | 451 TitleWatcher title_watcher(shell()->web_contents(), expected_title16); |
585 title_watcher.AlsoWaitForTitle(ASCIIToUTF16("connection closed with error")); | |
586 EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle()); | 452 EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle()); |
587 } | 453 } |
588 | 454 |
589 class IndexedDBBrowserTestSingleProcess : public IndexedDBBrowserTest { | 455 class IndexedDBBrowserTestSingleProcess : public IndexedDBBrowserTest { |
590 public: | 456 public: |
591 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { | 457 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { |
592 command_line->AppendSwitch(switches::kSingleProcess); | 458 command_line->AppendSwitch(switches::kSingleProcess); |
593 } | 459 } |
594 }; | 460 }; |
595 | 461 |
596 // Crashing on Android due to kSingleProcess flag: http://crbug.com/342525 | 462 // Crashing on Android due to kSingleProcess flag: http://crbug.com/342525 |
597 #if defined(OS_ANDROID) | 463 #if defined(OS_ANDROID) |
598 #define MAYBE_RenderThreadShutdownTest DISABLED_RenderThreadShutdownTest | 464 #define MAYBE_RenderThreadShutdownTest DISABLED_RenderThreadShutdownTest |
599 #else | 465 #else |
600 #define MAYBE_RenderThreadShutdownTest RenderThreadShutdownTest | 466 #define MAYBE_RenderThreadShutdownTest RenderThreadShutdownTest |
601 #endif | 467 #endif |
602 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestSingleProcess, | 468 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestSingleProcess, |
603 MAYBE_RenderThreadShutdownTest) { | 469 MAYBE_RenderThreadShutdownTest) { |
604 SimpleTest(GetTestUrl("indexeddb", "shutdown_with_requests.html")); | 470 SimpleTest(GetTestUrl("indexeddb", "shutdown_with_requests.html")); |
605 } | 471 } |
606 | 472 |
607 } // namespace content | 473 } // namespace content |
OLD | NEW |