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

Unified Diff: content/browser/indexed_db/indexed_db_browsertest.cc

Issue 197333009: Handling LevelDB errors encountered after open. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Commented that DestroyBackingStore leaves non LevelDB files alone Created 6 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/indexed_db/indexed_db_browsertest.cc
diff --git a/content/browser/indexed_db/indexed_db_browsertest.cc b/content/browser/indexed_db/indexed_db_browsertest.cc
index 5a2389333516c899ec373d118fcb7d21d26a0aa6..414f26600a75c85fced586d07665c83a97c2d4a7 100644
--- a/content/browser/indexed_db/indexed_db_browsertest.cc
+++ b/content/browser/indexed_db/indexed_db_browsertest.cc
@@ -5,6 +5,7 @@
#include "base/bind.h"
#include "base/command_line.h"
#include "base/file_util.h"
+#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
@@ -24,6 +25,10 @@
#include "content/shell/browser/shell.h"
#include "content/test/content_browser_test.h"
#include "content/test/content_browser_test_utils.h"
+#include "net/base/net_errors.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/test/embedded_test_server/http_request.h"
+#include "net/test/embedded_test_server/http_response.h"
#include "webkit/browser/database/database_util.h"
#include "webkit/browser/quota/quota_manager.h"
@@ -356,6 +361,134 @@ IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CanDeleteWhenOverQuotaTest) {
SimpleTest(GetTestUrl("indexeddb", "delete_over_quota.html"));
}
+namespace {
+
+static void CompactIndexedDBBackingStore(
+ scoped_refptr<IndexedDBContextImpl> context,
+ const GURL& origin_url) {
+ IndexedDBFactory* factory = context->GetIDBFactory();
+
+ std::pair<IndexedDBFactory::OriginDBMapIterator,
+ IndexedDBFactory::OriginDBMapIterator> range =
+ factory->GetOpenDatabasesForOrigin(origin_url);
+
+ if (range.first == range.second) // If no open db's for this origin
+ return;
+
+ // Compact the first db's backing store since all the db's are in the same
+ // backing store.
+ IndexedDBDatabase* db = range.first->second;
+ IndexedDBBackingStore* backing_store = db->backing_store();
+ backing_store->Compact();
+}
+
+static void CorruptIndexedDBDatabase(
+ IndexedDBContextImpl* context,
+ const GURL& origin_url,
+ base::WaitableEvent* signal_when_finished) {
+
+ CompactIndexedDBBackingStore(context, origin_url);
+
+ int numFiles = 0;
+ int numErrors = 0;
+ base::FilePath idb_data_path = context->GetFilePath(origin_url);
+ const bool recursive = false;
+ base::FileEnumerator enumerator(
+ idb_data_path, recursive, base::FileEnumerator::FILES);
+ for (base::FilePath idb_file = enumerator.Next(); !idb_file.empty();
+ idb_file = enumerator.Next()) {
+ int64 size(0);
+ GetFileSize(idb_file, &size);
+
+ if (idb_file.Extension() == ".ldb") {
+ numFiles++;
+ base::ScopedFILE f(base::OpenFile(idb_file, "w"));
+ if (f) {
+ char zero(0);
+ if (size != (int64)fwrite(&zero, sizeof(zero), size, f.get()))
+ numErrors++;
+ } else {
+ numErrors++;
+ }
+ }
+ }
+
+ VLOG(0) << "There were " << numFiles << " in " << idb_data_path.value()
+ << " with " << numErrors << " errors";
+ signal_when_finished->Signal();
+}
+
+const std::string s_corrupt_db_test_prefix = "/corrupt/test/";
+
+static scoped_ptr<net::test_server::HttpResponse> CorruptDBRequestHandler(
+ IndexedDBContextImpl* context,
+ const GURL& origin_url,
+ const std::string& path,
+ const net::test_server::HttpRequest& request) {
+
+ std::string request_path;
+ if (path.find(s_corrupt_db_test_prefix) != std::string::npos)
+ request_path = request.relative_url.substr(s_corrupt_db_test_prefix.size());
+ else
+ return scoped_ptr<net::test_server::HttpResponse>();
+
+ // Remove the query string if present.
+ std::string request_query;
+ size_t query_pos = request_path.find('?');
+ if (query_pos != std::string::npos) {
+ request_query = request_path.substr(query_pos + 1);
+ request_path = request_path.substr(0, query_pos);
+ }
+
+ if (request_path == "corruptdb" && !request_query.empty()) {
+ VLOG(0) << "Requested to corrupt IndexedDB: " << request_query;
+ base::WaitableEvent signal_when_finished(false, false);
+ context->TaskRunner()->PostTask(FROM_HERE,
+ base::Bind(&CorruptIndexedDBDatabase,
+ base::ConstRef(context),
+ origin_url,
+ &signal_when_finished));
+ signal_when_finished.Wait();
+
+ scoped_ptr<net::test_server::BasicHttpResponse> http_response(
+ new net::test_server::BasicHttpResponse);
+ http_response->set_code(net::HTTP_OK);
+ return http_response.PassAs<net::test_server::HttpResponse>();
+ }
+
+ // A request for a test resource
+ base::FilePath resourcePath =
+ content::GetTestFilePath("indexeddb", request_path.c_str());
+ scoped_ptr<net::test_server::BasicHttpResponse> http_response(
+ new net::test_server::BasicHttpResponse);
+ http_response->set_code(net::HTTP_OK);
+ std::string file_contents;
+ if (!base::ReadFileToString(resourcePath, &file_contents))
+ return scoped_ptr<net::test_server::HttpResponse>();
+ http_response->set_content(file_contents);
+ return http_response.PassAs<net::test_server::HttpResponse>();
+}
+
+} // namespace
+
+IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CorruptedOpenDatabase) {
+ ASSERT_TRUE(embedded_test_server()->Started() ||
+ embedded_test_server()->InitializeAndWaitUntilReady());
+ const GURL& origin_url = embedded_test_server()->base_url();
+ embedded_test_server()->RegisterRequestHandler(
+ base::Bind(&CorruptDBRequestHandler,
+ base::ConstRef(GetContext()),
+ origin_url,
+ s_corrupt_db_test_prefix));
+
+ std::string test_file =
+ s_corrupt_db_test_prefix + "corrupted_open_db_detection.html";
+ SimpleTest(embedded_test_server()->GetURL(test_file));
+
+ test_file = s_corrupt_db_test_prefix + "corrupted_open_db_recovery.html";
+ SimpleTest(embedded_test_server()->GetURL(test_file));
+}
+
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DeleteCompactsBackingStore) {
const GURL test_url = GetTestUrl("indexeddb", "delete_compact.html");
SimpleTest(GURL(test_url.spec() + "#fill"));
@@ -449,6 +582,7 @@ IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, ForceCloseEventTest) {
base::string16 expected_title16(ASCIIToUTF16("connection closed"));
TitleWatcher title_watcher(shell()->web_contents(), expected_title16);
+ title_watcher.AlsoWaitForTitle(ASCIIToUTF16("connection closed with error"));
EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle());
}

Powered by Google App Engine
This is Rietveld 408576698