| 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.h" | 8 #include "base/files/file.h" |
| 9 #include "base/files/file_enumerator.h" | 9 #include "base/files/file_enumerator.h" |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| 11 #include "base/lazy_instance.h" |
| 11 #include "base/memory/ref_counted.h" | 12 #include "base/memory/ref_counted.h" |
| 12 #include "base/message_loop/message_loop.h" | 13 #include "base/message_loop/message_loop.h" |
| 13 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
| 14 #include "base/test/thread_test_helper.h" | 15 #include "base/test/thread_test_helper.h" |
| 15 #include "content/browser/browser_main_loop.h" | 16 #include "content/browser/browser_main_loop.h" |
| 17 #include "content/browser/indexed_db/indexed_db_class_factory.h" |
| 16 #include "content/browser/indexed_db/indexed_db_context_impl.h" | 18 #include "content/browser/indexed_db/indexed_db_context_impl.h" |
| 19 #include "content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.h
" |
| 17 #include "content/browser/web_contents/web_contents_impl.h" | 20 #include "content/browser/web_contents/web_contents_impl.h" |
| 18 #include "content/public/browser/browser_context.h" | 21 #include "content/public/browser/browser_context.h" |
| 19 #include "content/public/browser/browser_thread.h" | 22 #include "content/public/browser/browser_thread.h" |
| 20 #include "content/public/browser/render_process_host.h" | 23 #include "content/public/browser/render_process_host.h" |
| 21 #include "content/public/browser/storage_partition.h" | 24 #include "content/public/browser/storage_partition.h" |
| 22 #include "content/public/browser/web_contents.h" | 25 #include "content/public/browser/web_contents.h" |
| 23 #include "content/public/common/content_switches.h" | 26 #include "content/public/common/content_switches.h" |
| 24 #include "content/public/common/url_constants.h" | 27 #include "content/public/common/url_constants.h" |
| 25 #include "content/public/test/browser_test_utils.h" | 28 #include "content/public/test/browser_test_utils.h" |
| 26 #include "content/public/test/content_browser_test.h" | 29 #include "content/public/test/content_browser_test.h" |
| 27 #include "content/public/test/content_browser_test_utils.h" | 30 #include "content/public/test/content_browser_test_utils.h" |
| 28 #include "content/shell/browser/shell.h" | 31 #include "content/shell/browser/shell.h" |
| 32 #include "net/base/escape.h" |
| 29 #include "net/base/net_errors.h" | 33 #include "net/base/net_errors.h" |
| 30 #include "net/test/embedded_test_server/embedded_test_server.h" | 34 #include "net/test/embedded_test_server/embedded_test_server.h" |
| 31 #include "net/test/embedded_test_server/http_request.h" | 35 #include "net/test/embedded_test_server/http_request.h" |
| 32 #include "net/test/embedded_test_server/http_response.h" | 36 #include "net/test/embedded_test_server/http_response.h" |
| 33 #include "webkit/browser/database/database_util.h" | 37 #include "webkit/browser/database/database_util.h" |
| 34 #include "webkit/browser/quota/quota_manager.h" | 38 #include "webkit/browser/quota/quota_manager.h" |
| 35 | 39 |
| 36 using base::ASCIIToUTF16; | 40 using base::ASCIIToUTF16; |
| 37 using quota::QuotaManager; | 41 using quota::QuotaManager; |
| 38 using webkit_database::DatabaseUtil; | 42 using webkit_database::DatabaseUtil; |
| 39 | 43 |
| 40 namespace content { | 44 namespace content { |
| 41 | 45 |
| 42 // This browser test is aimed towards exercising the IndexedDB bindings and | 46 // This browser test is aimed towards exercising the IndexedDB bindings and |
| 43 // the actual implementation that lives in the browser side. | 47 // the actual implementation that lives in the browser side. |
| 44 class IndexedDBBrowserTest : public ContentBrowserTest { | 48 class IndexedDBBrowserTest : public ContentBrowserTest { |
| 45 public: | 49 public: |
| 46 IndexedDBBrowserTest() : disk_usage_(-1) {} | 50 IndexedDBBrowserTest() : disk_usage_(-1) {} |
| 47 | 51 |
| 52 virtual void SetUp() OVERRIDE { |
| 53 GetTestClassFactory()->Reset(); |
| 54 IndexedDBClassFactory::SetIndexedDBClassFactoryGetter(GetIDBClassFactory); |
| 55 ContentBrowserTest::SetUp(); |
| 56 } |
| 57 |
| 58 virtual void TearDown() OVERRIDE { |
| 59 IndexedDBClassFactory::SetIndexedDBClassFactoryGetter(NULL); |
| 60 ContentBrowserTest::TearDown(); |
| 61 } |
| 62 |
| 63 void FailOperation(FailClass failure_class, |
| 64 FailMethod failure_method, |
| 65 int fail_on_instance_num, |
| 66 int fail_on_call_num) { |
| 67 GetTestClassFactory()->FailOperation( |
| 68 failure_class, failure_method, fail_on_instance_num, fail_on_call_num); |
| 69 } |
| 70 |
| 48 void SimpleTest(const GURL& test_url, bool incognito = false) { | 71 void SimpleTest(const GURL& test_url, bool incognito = false) { |
| 49 // The test page will perform tests on IndexedDB, then navigate to either | 72 // The test page will perform tests on IndexedDB, then navigate to either |
| 50 // a #pass or #fail ref. | 73 // a #pass or #fail ref. |
| 51 Shell* the_browser = incognito ? CreateOffTheRecordBrowser() : shell(); | 74 Shell* the_browser = incognito ? CreateOffTheRecordBrowser() : shell(); |
| 52 | 75 |
| 53 VLOG(0) << "Navigating to URL and blocking."; | 76 VLOG(0) << "Navigating to URL and blocking."; |
| 54 NavigateToURLBlockUntilNavigationsComplete(the_browser, test_url, 2); | 77 NavigateToURLBlockUntilNavigationsComplete(the_browser, test_url, 2); |
| 55 VLOG(0) << "Navigation done."; | 78 VLOG(0) << "Navigation done."; |
| 56 std::string result = | 79 std::string result = |
| 57 the_browser->web_contents()->GetLastCommittedURL().ref(); | 80 the_browser->web_contents()->GetLastCommittedURL().ref(); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 scoped_refptr<base::ThreadTestHelper> helper(new base::ThreadTestHelper( | 143 scoped_refptr<base::ThreadTestHelper> helper(new base::ThreadTestHelper( |
| 121 BrowserMainLoop::GetInstance()->indexed_db_thread()-> | 144 BrowserMainLoop::GetInstance()->indexed_db_thread()-> |
| 122 message_loop_proxy())); | 145 message_loop_proxy())); |
| 123 EXPECT_TRUE(helper->Run()); | 146 EXPECT_TRUE(helper->Run()); |
| 124 // Wait for DidGetDiskUsage to be called. | 147 // Wait for DidGetDiskUsage to be called. |
| 125 base::MessageLoop::current()->RunUntilIdle(); | 148 base::MessageLoop::current()->RunUntilIdle(); |
| 126 return disk_usage_; | 149 return disk_usage_; |
| 127 } | 150 } |
| 128 | 151 |
| 129 private: | 152 private: |
| 153 static MockBrowserTestIndexedDBClassFactory* GetTestClassFactory() { |
| 154 static ::base::LazyInstance<MockBrowserTestIndexedDBClassFactory>::Leaky |
| 155 s_factory = LAZY_INSTANCE_INITIALIZER; |
| 156 return s_factory.Pointer(); |
| 157 } |
| 158 |
| 159 static IndexedDBClassFactory* GetIDBClassFactory() { |
| 160 return GetTestClassFactory(); |
| 161 } |
| 162 |
| 130 virtual void DidGetDiskUsage(int64 bytes) { | 163 virtual void DidGetDiskUsage(int64 bytes) { |
| 131 EXPECT_GT(bytes, 0); | 164 EXPECT_GT(bytes, 0); |
| 132 disk_usage_ = bytes; | 165 disk_usage_ = bytes; |
| 133 } | 166 } |
| 134 | 167 |
| 135 int64 disk_usage_; | 168 int64 disk_usage_; |
| 136 | 169 |
| 137 DISALLOW_COPY_AND_ASSIGN(IndexedDBBrowserTest); | 170 DISALLOW_COPY_AND_ASSIGN(IndexedDBBrowserTest); |
| 138 }; | 171 }; |
| 139 | 172 |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 << " with " << numErrors << " errors"; | 468 << " with " << numErrors << " errors"; |
| 436 signal_when_finished->Signal(); | 469 signal_when_finished->Signal(); |
| 437 } | 470 } |
| 438 | 471 |
| 439 const std::string s_corrupt_db_test_prefix = "/corrupt/test/"; | 472 const std::string s_corrupt_db_test_prefix = "/corrupt/test/"; |
| 440 | 473 |
| 441 static scoped_ptr<net::test_server::HttpResponse> CorruptDBRequestHandler( | 474 static scoped_ptr<net::test_server::HttpResponse> CorruptDBRequestHandler( |
| 442 IndexedDBContextImpl* context, | 475 IndexedDBContextImpl* context, |
| 443 const GURL& origin_url, | 476 const GURL& origin_url, |
| 444 const std::string& path, | 477 const std::string& path, |
| 478 IndexedDBBrowserTest* test, |
| 445 const net::test_server::HttpRequest& request) { | 479 const net::test_server::HttpRequest& request) { |
| 446 | |
| 447 std::string request_path; | 480 std::string request_path; |
| 448 if (path.find(s_corrupt_db_test_prefix) != std::string::npos) | 481 if (path.find(s_corrupt_db_test_prefix) != std::string::npos) |
| 449 request_path = request.relative_url.substr(s_corrupt_db_test_prefix.size()); | 482 request_path = request.relative_url.substr(s_corrupt_db_test_prefix.size()); |
| 450 else | 483 else |
| 451 return scoped_ptr<net::test_server::HttpResponse>(); | 484 return scoped_ptr<net::test_server::HttpResponse>(); |
| 452 | 485 |
| 453 // Remove the query string if present. | 486 // Remove the query string if present. |
| 454 std::string request_query; | 487 std::string request_query; |
| 455 size_t query_pos = request_path.find('?'); | 488 size_t query_pos = request_path.find('?'); |
| 456 if (query_pos != std::string::npos) { | 489 if (query_pos != std::string::npos) { |
| 457 request_query = request_path.substr(query_pos + 1); | 490 request_query = request_path.substr(query_pos + 1); |
| 458 request_path = request_path.substr(0, query_pos); | 491 request_path = request_path.substr(0, query_pos); |
| 459 } | 492 } |
| 460 | 493 |
| 461 if (request_path == "corruptdb" && !request_query.empty()) { | 494 if (request_path == "corruptdb" && !request_query.empty()) { |
| 462 VLOG(0) << "Requested to corrupt IndexedDB: " << request_query; | 495 VLOG(0) << "Requested to corrupt IndexedDB: " << request_query; |
| 463 base::WaitableEvent signal_when_finished(false, false); | 496 base::WaitableEvent signal_when_finished(false, false); |
| 464 context->TaskRunner()->PostTask(FROM_HERE, | 497 context->TaskRunner()->PostTask(FROM_HERE, |
| 465 base::Bind(&CorruptIndexedDBDatabase, | 498 base::Bind(&CorruptIndexedDBDatabase, |
| 466 base::ConstRef(context), | 499 base::ConstRef(context), |
| 467 origin_url, | 500 origin_url, |
| 468 &signal_when_finished)); | 501 &signal_when_finished)); |
| 469 signal_when_finished.Wait(); | 502 signal_when_finished.Wait(); |
| 470 | 503 |
| 471 scoped_ptr<net::test_server::BasicHttpResponse> http_response( | 504 scoped_ptr<net::test_server::BasicHttpResponse> http_response( |
| 472 new net::test_server::BasicHttpResponse); | 505 new net::test_server::BasicHttpResponse); |
| 473 http_response->set_code(net::HTTP_OK); | 506 http_response->set_code(net::HTTP_OK); |
| 474 return http_response.PassAs<net::test_server::HttpResponse>(); | 507 return http_response.PassAs<net::test_server::HttpResponse>(); |
| 508 } else if (request_path == "fail" && !request_query.empty()) { |
| 509 FailClass failure_class = FAIL_CLASS_NOTHING; |
| 510 FailMethod failure_method = FAIL_METHOD_NOTHING; |
| 511 int instance_num = 1; |
| 512 int call_num = 1; |
| 513 std::string fail_class; |
| 514 std::string fail_method; |
| 515 |
| 516 url::Component query(0, request_query.length()), key_pos, value_pos; |
| 517 while (url::ExtractQueryKeyValue( |
| 518 request_query.c_str(), &query, &key_pos, &value_pos)) { |
| 519 std::string escaped_key(request_query.substr(key_pos.begin, key_pos.len)); |
| 520 std::string escaped_value( |
| 521 request_query.substr(value_pos.begin, value_pos.len)); |
| 522 |
| 523 std::string key = net::UnescapeURLComponent( |
| 524 escaped_key, |
| 525 net::UnescapeRule::NORMAL | net::UnescapeRule::SPACES | |
| 526 net::UnescapeRule::URL_SPECIAL_CHARS); |
| 527 |
| 528 std::string value = net::UnescapeURLComponent( |
| 529 escaped_value, |
| 530 net::UnescapeRule::NORMAL | net::UnescapeRule::SPACES | |
| 531 net::UnescapeRule::URL_SPECIAL_CHARS); |
| 532 |
| 533 if (key == "method") |
| 534 fail_method = value; |
| 535 else if (key == "class") |
| 536 fail_class = value; |
| 537 else if (key == "instNum") |
| 538 instance_num = atoi(value.c_str()); |
| 539 else if (key == "callNum") |
| 540 call_num = atoi(value.c_str()); |
| 541 else |
| 542 NOTREACHED() << "Unknown param: \"" << key << "\""; |
| 543 } |
| 544 |
| 545 if (fail_class == "LevelDBTransaction") { |
| 546 failure_class = FAIL_CLASS_LEVELDB_TRANSACTION; |
| 547 if (fail_method == "Get") |
| 548 failure_method = FAIL_METHOD_GET; |
| 549 else if (fail_method == "Commit") |
| 550 failure_method = FAIL_METHOD_COMMIT; |
| 551 else { |
| 552 NOTREACHED() << "Unknown method: \"" << fail_method << "\""; |
| 553 } |
| 554 } |
| 555 |
| 556 DCHECK_GE(instance_num, 1); |
| 557 DCHECK_GE(call_num, 1); |
| 558 |
| 559 test->FailOperation(failure_class, failure_method, instance_num, call_num); |
| 560 |
| 561 scoped_ptr<net::test_server::BasicHttpResponse> http_response( |
| 562 new net::test_server::BasicHttpResponse); |
| 563 http_response->set_code(net::HTTP_OK); |
| 564 return http_response.PassAs<net::test_server::HttpResponse>(); |
| 475 } | 565 } |
| 476 | 566 |
| 477 // A request for a test resource | 567 // A request for a test resource |
| 478 base::FilePath resourcePath = | 568 base::FilePath resourcePath = |
| 479 content::GetTestFilePath("indexeddb", request_path.c_str()); | 569 content::GetTestFilePath("indexeddb", request_path.c_str()); |
| 480 scoped_ptr<net::test_server::BasicHttpResponse> http_response( | 570 scoped_ptr<net::test_server::BasicHttpResponse> http_response( |
| 481 new net::test_server::BasicHttpResponse); | 571 new net::test_server::BasicHttpResponse); |
| 482 http_response->set_code(net::HTTP_OK); | 572 http_response->set_code(net::HTTP_OK); |
| 483 std::string file_contents; | 573 std::string file_contents; |
| 484 if (!base::ReadFileToString(resourcePath, &file_contents)) | 574 if (!base::ReadFileToString(resourcePath, &file_contents)) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 495 | 585 |
| 496 IN_PROC_BROWSER_TEST_P(IndexedDBBrowserCorruptionTest, | 586 IN_PROC_BROWSER_TEST_P(IndexedDBBrowserCorruptionTest, |
| 497 OperationOnCorruptedOpenDatabase) { | 587 OperationOnCorruptedOpenDatabase) { |
| 498 ASSERT_TRUE(embedded_test_server()->Started() || | 588 ASSERT_TRUE(embedded_test_server()->Started() || |
| 499 embedded_test_server()->InitializeAndWaitUntilReady()); | 589 embedded_test_server()->InitializeAndWaitUntilReady()); |
| 500 const GURL& origin_url = embedded_test_server()->base_url(); | 590 const GURL& origin_url = embedded_test_server()->base_url(); |
| 501 embedded_test_server()->RegisterRequestHandler( | 591 embedded_test_server()->RegisterRequestHandler( |
| 502 base::Bind(&CorruptDBRequestHandler, | 592 base::Bind(&CorruptDBRequestHandler, |
| 503 base::ConstRef(GetContext()), | 593 base::ConstRef(GetContext()), |
| 504 origin_url, | 594 origin_url, |
| 505 s_corrupt_db_test_prefix)); | 595 s_corrupt_db_test_prefix, |
| 596 this)); |
| 506 | 597 |
| 507 std::string test_file = s_corrupt_db_test_prefix + | 598 std::string test_file = s_corrupt_db_test_prefix + |
| 508 "corrupted_open_db_detection.html#" + GetParam(); | 599 "corrupted_open_db_detection.html#" + GetParam(); |
| 509 SimpleTest(embedded_test_server()->GetURL(test_file)); | 600 SimpleTest(embedded_test_server()->GetURL(test_file)); |
| 510 | 601 |
| 511 test_file = s_corrupt_db_test_prefix + "corrupted_open_db_recovery.html"; | 602 test_file = s_corrupt_db_test_prefix + "corrupted_open_db_recovery.html"; |
| 512 SimpleTest(embedded_test_server()->GetURL(test_file)); | 603 SimpleTest(embedded_test_server()->GetURL(test_file)); |
| 513 } | 604 } |
| 514 | 605 |
| 515 INSTANTIATE_TEST_CASE_P(IndexedDBBrowserCorruptionTestInstantiation, | 606 INSTANTIATE_TEST_CASE_P(IndexedDBBrowserCorruptionTestInstantiation, |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 629 #define MAYBE_RenderThreadShutdownTest DISABLED_RenderThreadShutdownTest | 720 #define MAYBE_RenderThreadShutdownTest DISABLED_RenderThreadShutdownTest |
| 630 #else | 721 #else |
| 631 #define MAYBE_RenderThreadShutdownTest RenderThreadShutdownTest | 722 #define MAYBE_RenderThreadShutdownTest RenderThreadShutdownTest |
| 632 #endif | 723 #endif |
| 633 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestSingleProcess, | 724 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestSingleProcess, |
| 634 MAYBE_RenderThreadShutdownTest) { | 725 MAYBE_RenderThreadShutdownTest) { |
| 635 SimpleTest(GetTestUrl("indexeddb", "shutdown_with_requests.html")); | 726 SimpleTest(GetTestUrl("indexeddb", "shutdown_with_requests.html")); |
| 636 } | 727 } |
| 637 | 728 |
| 638 } // namespace content | 729 } // namespace content |
| OLD | NEW |