[IndexedDB] Adding traces, perf tests
[chromium-blink-merge.git] / content / browser / indexed_db / mock_browsertest_indexed_db_class_factory.cc
blobdc02ff7331c4748bd2b3998951b89b828dc417f9
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include <string>
7 #include "base/logging.h"
8 #include "content/browser/indexed_db/indexed_db_transaction.h"
9 #include "content/browser/indexed_db/leveldb/leveldb_iterator_impl.h"
10 #include "content/browser/indexed_db/leveldb/leveldb_transaction.h"
11 #include "content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.h"
12 #include "third_party/leveldatabase/env_chromium.h"
13 #include "third_party/leveldatabase/src/include/leveldb/status.h"
15 namespace {
17 class FunctionTracer {
18 public:
19 FunctionTracer(const std::string& class_name,
20 const std::string& method_name,
21 int instance_num)
22 : class_name_(class_name),
23 method_name_(method_name),
24 instance_count_(instance_num),
25 current_call_num_(0) {}
27 void log_call() {
28 current_call_num_++;
29 VLOG(0) << class_name_ << '[' << instance_count_ << "]::" << method_name_
30 << "()[" << current_call_num_ << ']';
33 private:
34 std::string class_name_;
35 std::string method_name_;
36 int instance_count_;
37 int current_call_num_;
40 } // namespace
42 namespace content {
44 class IndexedDBTestDatabase : public IndexedDBDatabase {
45 public:
46 IndexedDBTestDatabase(const base::string16& name,
47 IndexedDBBackingStore* backing_store,
48 IndexedDBFactory* factory,
49 const IndexedDBDatabase::Identifier& unique_identifier)
50 : IndexedDBDatabase(name, backing_store, factory, unique_identifier) {}
52 protected:
53 ~IndexedDBTestDatabase() override {}
55 size_t GetMaxMessageSizeInBytes() const override {
56 return 10 * 1024 * 1024; // 10MB
60 class IndexedDBTestTransaction : public IndexedDBTransaction {
61 public:
62 IndexedDBTestTransaction(
63 int64 id,
64 scoped_refptr<IndexedDBDatabaseCallbacks> callbacks,
65 const std::set<int64>& scope,
66 blink::WebIDBTransactionMode mode,
67 IndexedDBDatabase* db,
68 IndexedDBBackingStore::Transaction* backing_store_transaction)
69 : IndexedDBTransaction(id,
70 callbacks,
71 scope,
72 mode,
73 db,
74 backing_store_transaction) {}
76 protected:
77 ~IndexedDBTestTransaction() override {}
79 // Browser tests run under memory/address sanitizers (etc) may trip the
80 // default 60s timeout, so relax it during tests.
81 base::TimeDelta GetInactivityTimeout() const override {
82 return base::TimeDelta::FromSeconds(60 * 60);
86 class LevelDBTestTransaction : public LevelDBTransaction {
87 public:
88 LevelDBTestTransaction(LevelDBDatabase* db,
89 FailMethod fail_method,
90 int fail_on_call_num)
91 : LevelDBTransaction(db),
92 fail_method_(fail_method),
93 fail_on_call_num_(fail_on_call_num),
94 current_call_num_(0) {
95 DCHECK(fail_method != FAIL_METHOD_NOTHING);
96 DCHECK_GT(fail_on_call_num, 0);
99 leveldb::Status Get(const base::StringPiece& key,
100 std::string* value,
101 bool* found) override {
102 if (fail_method_ != FAIL_METHOD_GET ||
103 ++current_call_num_ != fail_on_call_num_)
104 return LevelDBTransaction::Get(key, value, found);
106 *found = false;
107 return leveldb::Status::Corruption("Corrupted for the test");
110 leveldb::Status Commit() override {
111 if ((fail_method_ != FAIL_METHOD_COMMIT &&
112 fail_method_ != FAIL_METHOD_COMMIT_DISK_FULL) ||
113 ++current_call_num_ != fail_on_call_num_)
114 return LevelDBTransaction::Commit();
116 // TODO(jsbell): Consider parameterizing the failure mode.
117 if (fail_method_ == FAIL_METHOD_COMMIT_DISK_FULL) {
118 return leveldb_env::MakeIOError("dummy filename", "Disk Full",
119 leveldb_env::kWritableFileAppend,
120 base::File::FILE_ERROR_NO_SPACE);
123 return leveldb::Status::Corruption("Corrupted for the test");
126 private:
127 ~LevelDBTestTransaction() override {}
129 FailMethod fail_method_;
130 int fail_on_call_num_;
131 int current_call_num_;
134 class LevelDBTraceTransaction : public LevelDBTransaction {
135 public:
136 LevelDBTraceTransaction(LevelDBDatabase* db, int tx_num)
137 : LevelDBTransaction(db),
138 commit_tracer_(s_class_name, "Commit", tx_num),
139 get_tracer_(s_class_name, "Get", tx_num) {}
141 leveldb::Status Get(const base::StringPiece& key,
142 std::string* value,
143 bool* found) override {
144 get_tracer_.log_call();
145 return LevelDBTransaction::Get(key, value, found);
148 leveldb::Status Commit() override {
149 commit_tracer_.log_call();
150 return LevelDBTransaction::Commit();
153 private:
154 static const std::string s_class_name;
156 ~LevelDBTraceTransaction() override {}
158 FunctionTracer commit_tracer_;
159 FunctionTracer get_tracer_;
162 const std::string LevelDBTraceTransaction::s_class_name = "LevelDBTransaction";
164 class LevelDBTraceIteratorImpl : public LevelDBIteratorImpl {
165 public:
166 LevelDBTraceIteratorImpl(scoped_ptr<leveldb::Iterator> iterator, int inst_num)
167 : LevelDBIteratorImpl(iterator.Pass()),
168 is_valid_tracer_(s_class_name, "IsValid", inst_num),
169 seek_to_last_tracer_(s_class_name, "SeekToLast", inst_num),
170 seek_tracer_(s_class_name, "Seek", inst_num),
171 next_tracer_(s_class_name, "Next", inst_num),
172 prev_tracer_(s_class_name, "Prev", inst_num),
173 key_tracer_(s_class_name, "Key", inst_num),
174 value_tracer_(s_class_name, "Value", inst_num) {}
175 ~LevelDBTraceIteratorImpl() override {}
177 private:
178 static const std::string s_class_name;
180 bool IsValid() const override {
181 is_valid_tracer_.log_call();
182 return LevelDBIteratorImpl::IsValid();
184 leveldb::Status SeekToLast() override {
185 seek_to_last_tracer_.log_call();
186 return LevelDBIteratorImpl::SeekToLast();
188 leveldb::Status Seek(const base::StringPiece& target) override {
189 seek_tracer_.log_call();
190 return LevelDBIteratorImpl::Seek(target);
192 leveldb::Status Next() override {
193 next_tracer_.log_call();
194 return LevelDBIteratorImpl::Next();
196 leveldb::Status Prev() override {
197 prev_tracer_.log_call();
198 return LevelDBIteratorImpl::Prev();
200 base::StringPiece Key() const override {
201 key_tracer_.log_call();
202 return LevelDBIteratorImpl::Key();
204 base::StringPiece Value() const override {
205 value_tracer_.log_call();
206 return LevelDBIteratorImpl::Value();
209 mutable FunctionTracer is_valid_tracer_;
210 mutable FunctionTracer seek_to_last_tracer_;
211 mutable FunctionTracer seek_tracer_;
212 mutable FunctionTracer next_tracer_;
213 mutable FunctionTracer prev_tracer_;
214 mutable FunctionTracer key_tracer_;
215 mutable FunctionTracer value_tracer_;
218 const std::string LevelDBTraceIteratorImpl::s_class_name = "LevelDBIterator";
220 class LevelDBTestIteratorImpl : public content::LevelDBIteratorImpl {
221 public:
222 LevelDBTestIteratorImpl(scoped_ptr<leveldb::Iterator> iterator,
223 FailMethod fail_method,
224 int fail_on_call_num)
225 : LevelDBIteratorImpl(iterator.Pass()),
226 fail_method_(fail_method),
227 fail_on_call_num_(fail_on_call_num),
228 current_call_num_(0) {}
229 ~LevelDBTestIteratorImpl() override {}
231 private:
232 leveldb::Status Seek(const base::StringPiece& target) override {
233 if (fail_method_ != FAIL_METHOD_SEEK ||
234 ++current_call_num_ != fail_on_call_num_)
235 return LevelDBIteratorImpl::Seek(target);
236 return leveldb::Status::Corruption("Corrupted for test");
239 FailMethod fail_method_;
240 int fail_on_call_num_;
241 int current_call_num_;
244 MockBrowserTestIndexedDBClassFactory::MockBrowserTestIndexedDBClassFactory()
245 : failure_class_(FAIL_CLASS_NOTHING),
246 failure_method_(FAIL_METHOD_NOTHING),
247 only_trace_calls_(false) {
250 MockBrowserTestIndexedDBClassFactory::~MockBrowserTestIndexedDBClassFactory() {
253 IndexedDBDatabase*
254 MockBrowserTestIndexedDBClassFactory::CreateIndexedDBDatabase(
255 const base::string16& name,
256 IndexedDBBackingStore* backing_store,
257 IndexedDBFactory* factory,
258 const IndexedDBDatabase::Identifier& unique_identifier) {
259 return new IndexedDBTestDatabase(name, backing_store, factory,
260 unique_identifier);
263 IndexedDBTransaction*
264 MockBrowserTestIndexedDBClassFactory::CreateIndexedDBTransaction(
265 int64 id,
266 scoped_refptr<IndexedDBDatabaseCallbacks> callbacks,
267 const std::set<int64>& scope,
268 blink::WebIDBTransactionMode mode,
269 IndexedDBDatabase* db,
270 IndexedDBBackingStore::Transaction* backing_store_transaction) {
271 return new IndexedDBTestTransaction(id, callbacks, scope, mode, db,
272 backing_store_transaction);
275 LevelDBTransaction*
276 MockBrowserTestIndexedDBClassFactory::CreateLevelDBTransaction(
277 LevelDBDatabase* db) {
278 instance_count_[FAIL_CLASS_LEVELDB_TRANSACTION] =
279 instance_count_[FAIL_CLASS_LEVELDB_TRANSACTION] + 1;
280 if (only_trace_calls_) {
281 return new LevelDBTraceTransaction(
282 db, instance_count_[FAIL_CLASS_LEVELDB_TRANSACTION]);
283 } else {
284 if (failure_class_ == FAIL_CLASS_LEVELDB_TRANSACTION &&
285 instance_count_[FAIL_CLASS_LEVELDB_TRANSACTION] ==
286 fail_on_instance_num_[FAIL_CLASS_LEVELDB_TRANSACTION]) {
287 return new LevelDBTestTransaction(
289 failure_method_,
290 fail_on_call_num_[FAIL_CLASS_LEVELDB_TRANSACTION]);
291 } else {
292 return IndexedDBClassFactory::CreateLevelDBTransaction(db);
297 LevelDBIteratorImpl* MockBrowserTestIndexedDBClassFactory::CreateIteratorImpl(
298 scoped_ptr<leveldb::Iterator> iterator) {
299 instance_count_[FAIL_CLASS_LEVELDB_ITERATOR] =
300 instance_count_[FAIL_CLASS_LEVELDB_ITERATOR] + 1;
301 if (only_trace_calls_) {
302 return new LevelDBTraceIteratorImpl(
303 iterator.Pass(), instance_count_[FAIL_CLASS_LEVELDB_ITERATOR]);
304 } else {
305 if (failure_class_ == FAIL_CLASS_LEVELDB_ITERATOR &&
306 instance_count_[FAIL_CLASS_LEVELDB_ITERATOR] ==
307 fail_on_instance_num_[FAIL_CLASS_LEVELDB_ITERATOR]) {
308 return new LevelDBTestIteratorImpl(
309 iterator.Pass(),
310 failure_method_,
311 fail_on_call_num_[FAIL_CLASS_LEVELDB_ITERATOR]);
312 } else {
313 return new LevelDBIteratorImpl(iterator.Pass());
318 void MockBrowserTestIndexedDBClassFactory::FailOperation(
319 FailClass failure_class,
320 FailMethod failure_method,
321 int fail_on_instance_num,
322 int fail_on_call_num) {
323 VLOG(0) << "FailOperation: class=" << failure_class
324 << ", method=" << failure_method
325 << ", instanceNum=" << fail_on_instance_num
326 << ", callNum=" << fail_on_call_num;
327 DCHECK(failure_class != FAIL_CLASS_NOTHING);
328 DCHECK(failure_method != FAIL_METHOD_NOTHING);
329 failure_class_ = failure_class;
330 failure_method_ = failure_method;
331 fail_on_instance_num_[failure_class_] = fail_on_instance_num;
332 fail_on_call_num_[failure_class_] = fail_on_call_num;
333 instance_count_.clear();
336 void MockBrowserTestIndexedDBClassFactory::Reset() {
337 failure_class_ = FAIL_CLASS_NOTHING;
338 failure_method_ = FAIL_METHOD_NOTHING;
339 instance_count_.clear();
340 fail_on_instance_num_.clear();
341 fail_on_call_num_.clear();
344 } // namespace content