Index: content/browser/indexed_db/indexed_db_browsertest_mock_factory.cc |
diff --git a/content/browser/indexed_db/indexed_db_browsertest_mock_factory.cc b/content/browser/indexed_db/indexed_db_browsertest_mock_factory.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..deda506145b697a54114d5e2da84823c4bca7aab |
--- /dev/null |
+++ b/content/browser/indexed_db/indexed_db_browsertest_mock_factory.cc |
@@ -0,0 +1,163 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include <string> |
+ |
+#include "base/logging.h" |
+#include "content/browser/indexed_db/indexed_db_browsertest_mock_factory.h" |
+#include "content/browser/indexed_db/leveldb/leveldb_transaction.h" |
+#include "third_party/leveldatabase/src/include/leveldb/status.h" |
+ |
+namespace { |
+ |
+class FunctionTracer { |
+ public: |
+ FunctionTracer(const std::string& class_name, |
+ const std::string& method_name, |
+ int instance_num) |
+ : class_name_(class_name), |
+ method_name_(method_name), |
+ instance_count_(instance_num), |
+ current_call_num_(0) {} |
+ |
+ void log_call() { |
+ current_call_num_++; |
+ VLOG(0) << class_name_ << '[' << instance_count_ << "]::" << method_name_ |
+ << "()[" << current_call_num_ << ']'; |
+ } |
+ |
+ private: |
+ std::string class_name_; |
+ std::string method_name_; |
+ int instance_count_; |
+ int current_call_num_; |
+}; |
+ |
+} // anonymous namespace |
jsbell
2014/06/18 17:03:08
nit: Just `// namespace`
cmumford
2014/06/18 18:06:44
Done.
|
+ |
+namespace content { |
+ |
+class LevelDBTestTansaction : public LevelDBTransaction { |
+ public: |
+ LevelDBTestTansaction(LevelDBDatabase* db, |
+ FailMethod fail_method, |
+ int fail_on_call_num) |
+ : LevelDBTransaction(db), |
+ fail_method_(fail_method), |
+ fail_on_call_num_(fail_on_call_num), |
+ current_call_num_(0) { |
+ DCHECK(fail_method != FAIL_METHOD_NOTHING); |
+ DCHECK_GT(fail_on_call_num, 0); |
+ } |
+ |
+ virtual leveldb::Status Get(const base::StringPiece& key, |
+ std::string* value, |
+ bool* found) OVERRIDE { |
+ if (fail_method_ != FAIL_METHOD_GET || |
+ ++current_call_num_ != fail_on_call_num_) |
+ return LevelDBTransaction::Get(key, value, found); |
+ |
+ *found = false; |
+ return leveldb::Status::Corruption("Corrupted for the test"); |
+ } |
+ |
+ virtual leveldb::Status Commit() OVERRIDE { |
+ if (fail_method_ != FAIL_METHOD_COMMIT || |
+ ++current_call_num_ != fail_on_call_num_) |
+ return LevelDBTransaction::Commit(); |
+ |
+ return leveldb::Status::Corruption("Corrupted for the test"); |
+ } |
+ |
+ private: |
+ virtual ~LevelDBTestTansaction() {} |
+ |
+ FailMethod fail_method_; |
+ int fail_on_call_num_; |
+ int current_call_num_; |
+}; |
+ |
+class LevelDBTraceTansaction : public LevelDBTransaction { |
+ public: |
+ LevelDBTraceTansaction(LevelDBDatabase* db, int tx_num) |
+ : LevelDBTransaction(db), |
+ commit_tracer_(s_class_name, "Commit", tx_num), |
+ get_tracer_(s_class_name, "Get", tx_num) {} |
+ |
+ virtual leveldb::Status Get(const base::StringPiece& key, |
+ std::string* value, |
+ bool* found) OVERRIDE { |
+ get_tracer_.log_call(); |
+ return LevelDBTransaction::Get(key, value, found); |
+ } |
+ |
+ virtual leveldb::Status Commit() OVERRIDE { |
+ commit_tracer_.log_call(); |
+ return LevelDBTransaction::Commit(); |
+ } |
+ |
+ private: |
+ virtual ~LevelDBTraceTansaction() {} |
+ |
+ const std::string s_class_name = "LevelDBTransaction"; |
+ |
+ FunctionTracer commit_tracer_; |
+ FunctionTracer get_tracer_; |
+}; |
+ |
+IndexedDBBrowserTestClassFactory::IndexedDBBrowserTestClassFactory() |
+ : failure_class_(FAIL_CLASS_NOTHING), |
+ failure_method_(FAIL_METHOD_NOTHING), |
+ only_trace_calls_(false) { |
+} |
+ |
+IndexedDBBrowserTestClassFactory::~IndexedDBBrowserTestClassFactory() { |
+} |
+ |
+LevelDBTransaction* IndexedDBBrowserTestClassFactory::CreateLevelDBTransaction( |
+ LevelDBDatabase* db) { |
+ instance_count_[FAIL_CLASS_LEVELDB_TRANSACTION] = |
+ instance_count_[FAIL_CLASS_LEVELDB_TRANSACTION] + 1; |
+ if (only_trace_calls_) { |
+ return new LevelDBTraceTansaction( |
+ db, instance_count_[FAIL_CLASS_LEVELDB_TRANSACTION]); |
+ } else { |
+ if (failure_class_ == FAIL_CLASS_LEVELDB_TRANSACTION && |
+ instance_count_[FAIL_CLASS_LEVELDB_TRANSACTION] == |
+ fail_on_instance_num_[FAIL_CLASS_LEVELDB_TRANSACTION]) |
+ return new LevelDBTestTansaction( |
+ db, |
+ failure_method_, |
+ fail_on_call_num_[FAIL_CLASS_LEVELDB_TRANSACTION]); |
+ else |
+ return IndexedDBClassFactory::CreateLevelDBTransaction(db); |
+ } |
+} |
+ |
+void IndexedDBBrowserTestClassFactory::FailOperation(FailClass failure_class, |
+ FailMethod failure_method, |
+ int fail_on_instance_num, |
+ int fail_on_call_num) { |
+ VLOG(0) << "FailOperation: class=" << failure_class |
+ << ", method=" << failure_method |
+ << ", instanceNum=" << fail_on_instance_num |
+ << ", callNum=" << fail_on_call_num; |
+ DCHECK(failure_class != FAIL_CLASS_NOTHING); |
+ DCHECK(failure_method != FAIL_METHOD_NOTHING); |
+ failure_class_ = failure_class; |
+ failure_method_ = failure_method; |
+ fail_on_instance_num_[failure_class_] = fail_on_instance_num; |
+ fail_on_call_num_[failure_class_] = fail_on_call_num; |
+ instance_count_.clear(); |
+} |
+ |
+void IndexedDBBrowserTestClassFactory::Reset() { |
+ failure_class_ = FAIL_CLASS_NOTHING; |
+ failure_method_ = FAIL_METHOD_NOTHING; |
+ instance_count_.clear(); |
+ fail_on_instance_num_.clear(); |
+ fail_on_call_num_.clear(); |
+} |
+ |
+} // namespace content |