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