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.
4 
5 #include "content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.h"
6 
7 #include <stddef.h>
8 #include <string>
9 #include <utility>
10 
11 #include "base/logging.h"
12 #include "base/memory/ptr_util.h"
13 #include "components/services/storage/indexed_db/scopes/leveldb_scope.h"
14 #include "components/services/storage/indexed_db/scopes/leveldb_scopes.h"
15 #include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_database.h"
16 #include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_iterator.h"
17 #include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_transaction.h"
18 #include "content/browser/indexed_db/indexed_db_factory.h"
19 #include "content/browser/indexed_db/indexed_db_metadata_coding.h"
20 #include "content/browser/indexed_db/indexed_db_transaction.h"
21 #include "third_party/leveldatabase/env_chromium.h"
22 #include "third_party/leveldatabase/src/include/leveldb/status.h"
23 
24 using storage::mojom::FailClass;
25 using storage::mojom::FailMethod;
26 
27 namespace {
28 
29 class FunctionTracer {
30  public:
FunctionTracer(const std::string & class_name,const std::string & method_name,int instance_num)31   FunctionTracer(const std::string& class_name,
32                  const std::string& method_name,
33                  int instance_num)
34       : class_name_(class_name),
35         method_name_(method_name),
36         instance_count_(instance_num),
37         current_call_num_(0) {}
38 
log_call()39   void log_call() {
40     current_call_num_++;
41     VLOG(0) << class_name_ << '[' << instance_count_ << "]::" << method_name_
42             << "()[" << current_call_num_ << ']';
43   }
44 
45  private:
46   std::string class_name_;
47   std::string method_name_;
48   int instance_count_;
49   int current_call_num_;
50 };
51 
52 }  // namespace
53 
54 namespace content {
55 
56 class IndexedDBTestDatabase : public IndexedDBDatabase {
57  public:
IndexedDBTestDatabase(const base::string16 & name,IndexedDBBackingStore * backing_store,IndexedDBFactory * factory,IndexedDBClassFactory * class_factory,TasksAvailableCallback tasks_available_callback,std::unique_ptr<IndexedDBMetadataCoding> metadata_coding,const Identifier & unique_identifier,ScopesLockManager * transaction_lock_manager)58   IndexedDBTestDatabase(
59       const base::string16& name,
60       IndexedDBBackingStore* backing_store,
61       IndexedDBFactory* factory,
62       IndexedDBClassFactory* class_factory,
63       TasksAvailableCallback tasks_available_callback,
64       std::unique_ptr<IndexedDBMetadataCoding> metadata_coding,
65       const Identifier& unique_identifier,
66       ScopesLockManager* transaction_lock_manager)
67       : IndexedDBDatabase(name,
68                           backing_store,
69                           factory,
70                           class_factory,
71                           std::move(tasks_available_callback),
72                           std::move(metadata_coding),
73                           unique_identifier,
74                           transaction_lock_manager) {}
~IndexedDBTestDatabase()75   ~IndexedDBTestDatabase() override {}
76 
77  protected:
GetUsableMessageSizeInBytes() const78   size_t GetUsableMessageSizeInBytes() const override {
79     return 10 * 1024 * 1024;  // 10MB
80   }
81 };
82 
83 class IndexedDBTestTransaction : public IndexedDBTransaction {
84  public:
IndexedDBTestTransaction(int64_t id,IndexedDBConnection * connection,const std::set<int64_t> & scope,blink::mojom::IDBTransactionMode mode,TasksAvailableCallback tasks_available_callback,IndexedDBTransaction::TearDownCallback tear_down_callback,IndexedDBBackingStore::Transaction * backing_store_transaction)85   IndexedDBTestTransaction(
86       int64_t id,
87       IndexedDBConnection* connection,
88       const std::set<int64_t>& scope,
89       blink::mojom::IDBTransactionMode mode,
90       TasksAvailableCallback tasks_available_callback,
91       IndexedDBTransaction::TearDownCallback tear_down_callback,
92       IndexedDBBackingStore::Transaction* backing_store_transaction)
93       : IndexedDBTransaction(id,
94                              connection,
95                              scope,
96                              mode,
97                              std::move(tasks_available_callback),
98                              std::move(tear_down_callback),
99                              backing_store_transaction) {}
~IndexedDBTestTransaction()100   ~IndexedDBTestTransaction() override {}
101 
102  protected:
103   // Browser tests run under memory/address sanitizers (etc) may trip the
104   // default 60s timeout, so relax it during tests.
GetInactivityTimeout() const105   base::TimeDelta GetInactivityTimeout() const override {
106     return base::TimeDelta::FromSeconds(60 * 60);
107   }
108 };
109 
110 class LevelDBTestDatabase : public TransactionalLevelDBDatabase {
111  public:
LevelDBTestDatabase(scoped_refptr<LevelDBState> level_db_state,std::unique_ptr<LevelDBScopes> leveldb_scopes,TransactionalLevelDBFactory * factory,scoped_refptr<base::SequencedTaskRunner> task_runner,size_t max_open_iterators,FailMethod fail_method,int fail_on_call_num)112   LevelDBTestDatabase(scoped_refptr<LevelDBState> level_db_state,
113                       std::unique_ptr<LevelDBScopes> leveldb_scopes,
114                       TransactionalLevelDBFactory* factory,
115                       scoped_refptr<base::SequencedTaskRunner> task_runner,
116                       size_t max_open_iterators,
117                       FailMethod fail_method,
118                       int fail_on_call_num)
119       : TransactionalLevelDBDatabase(std::move(level_db_state),
120                                      std::move(leveldb_scopes),
121                                      factory,
122                                      std::move(task_runner),
123                                      max_open_iterators),
124         fail_method_(fail_method),
125         fail_on_call_num_(fail_on_call_num),
126         current_call_num_(0) {
127     DCHECK(fail_method != FailMethod::NOTHING);
128     DCHECK_GT(fail_on_call_num, 0);
129   }
130   ~LevelDBTestDatabase() override = default;
131 
Get(const base::StringPiece & key,std::string * value,bool * found)132   leveldb::Status Get(const base::StringPiece& key,
133                       std::string* value,
134                       bool* found) override {
135     if (fail_method_ != FailMethod::GET ||
136         ++current_call_num_ != fail_on_call_num_)
137       return TransactionalLevelDBDatabase::Get(key, value, found);
138     *found = false;
139     return leveldb::Status::Corruption("Corrupted for the test");
140   }
141 
Write(LevelDBWriteBatch * write_batch)142   leveldb::Status Write(LevelDBWriteBatch* write_batch) override {
143     if ((fail_method_ != FailMethod::WRITE) ||
144         ++current_call_num_ != fail_on_call_num_)
145       return TransactionalLevelDBDatabase::Write(write_batch);
146     return leveldb::Status::Corruption("Corrupted for the test");
147   }
148 
149  private:
150   FailMethod fail_method_;
151   int fail_on_call_num_;
152   int current_call_num_;
153 };
154 
155 class LevelDBTestDirectTransaction : public LevelDBDirectTransaction {
156  public:
LevelDBTestDirectTransaction(TransactionalLevelDBDatabase * db,FailMethod fail_method,int fail_on_call_num)157   LevelDBTestDirectTransaction(TransactionalLevelDBDatabase* db,
158                                FailMethod fail_method,
159                                int fail_on_call_num)
160       : LevelDBDirectTransaction(db),
161         fail_method_(fail_method),
162         fail_on_call_num_(fail_on_call_num),
163         current_call_num_(0) {
164     DCHECK(fail_method != FailMethod::NOTHING);
165     DCHECK_GT(fail_on_call_num, 0);
166   }
167   ~LevelDBTestDirectTransaction() override = default;
168 
Get(const base::StringPiece & key,std::string * value,bool * found)169   leveldb::Status Get(const base::StringPiece& key,
170                       std::string* value,
171                       bool* found) override {
172     if (fail_method_ != FailMethod::GET ||
173         ++current_call_num_ != fail_on_call_num_)
174       return LevelDBTestDirectTransaction::Get(key, value, found);
175 
176     *found = false;
177     return leveldb::Status::Corruption("Corrupted for the test");
178   }
179 
180  private:
181   FailMethod fail_method_;
182   int fail_on_call_num_;
183   int current_call_num_;
184 };
185 
186 class LevelDBTestTransaction : public TransactionalLevelDBTransaction {
187  public:
LevelDBTestTransaction(TransactionalLevelDBDatabase * db,std::unique_ptr<LevelDBScope> scope,FailMethod fail_method,int fail_on_call_num)188   LevelDBTestTransaction(TransactionalLevelDBDatabase* db,
189                          std::unique_ptr<LevelDBScope> scope,
190                          FailMethod fail_method,
191                          int fail_on_call_num)
192       : TransactionalLevelDBTransaction(db, std::move(scope)),
193         fail_method_(fail_method),
194         fail_on_call_num_(fail_on_call_num),
195         current_call_num_(0) {
196     DCHECK(fail_method != FailMethod::NOTHING);
197     DCHECK_GT(fail_on_call_num, 0);
198   }
199 
Get(const base::StringPiece & key,std::string * value,bool * found)200   leveldb::Status Get(const base::StringPiece& key,
201                       std::string* value,
202                       bool* found) override {
203     if (fail_method_ != FailMethod::GET ||
204         ++current_call_num_ != fail_on_call_num_)
205       return TransactionalLevelDBTransaction::Get(key, value, found);
206 
207     *found = false;
208     return leveldb::Status::Corruption("Corrupted for the test");
209   }
210 
Commit(bool sync_on_commit)211   leveldb::Status Commit(bool sync_on_commit) override {
212     if ((fail_method_ != FailMethod::COMMIT &&
213          fail_method_ != FailMethod::COMMIT_DISK_FULL) ||
214         ++current_call_num_ != fail_on_call_num_)
215       return TransactionalLevelDBTransaction::Commit(sync_on_commit);
216 
217     // TODO(jsbell): Consider parameterizing the failure mode.
218     if (fail_method_ == FailMethod::COMMIT_DISK_FULL) {
219       return leveldb_env::MakeIOError("dummy filename", "Disk Full",
220                                       leveldb_env::kWritableFileAppend,
221                                       base::File::FILE_ERROR_NO_SPACE);
222     }
223 
224     return leveldb::Status::Corruption("Corrupted for the test");
225   }
226 
227  private:
~LevelDBTestTransaction()228   ~LevelDBTestTransaction() override {}
229 
230   FailMethod fail_method_;
231   int fail_on_call_num_;
232   int current_call_num_;
233 };
234 
235 class LevelDBTraceTransaction : public TransactionalLevelDBTransaction {
236  public:
LevelDBTraceTransaction(TransactionalLevelDBDatabase * db,std::unique_ptr<LevelDBScope> scope,int tx_num)237   LevelDBTraceTransaction(TransactionalLevelDBDatabase* db,
238                           std::unique_ptr<LevelDBScope> scope,
239                           int tx_num)
240       : TransactionalLevelDBTransaction(db, std::move(scope)),
241         class_name_("LevelDBTransaction"),
242         commit_tracer_(class_name_, "Commit", tx_num),
243         get_tracer_(class_name_, "Get", tx_num) {}
244 
Get(const base::StringPiece & key,std::string * value,bool * found)245   leveldb::Status Get(const base::StringPiece& key,
246                       std::string* value,
247                       bool* found) override {
248     get_tracer_.log_call();
249     return TransactionalLevelDBTransaction::Get(key, value, found);
250   }
251 
Commit(bool sync_on_commit)252   leveldb::Status Commit(bool sync_on_commit) override {
253     commit_tracer_.log_call();
254     return TransactionalLevelDBTransaction::Commit(sync_on_commit);
255   }
256 
257  private:
258   const std::string class_name_;
259 
260   ~LevelDBTraceTransaction() override = default;
261 
262   FunctionTracer commit_tracer_;
263   FunctionTracer get_tracer_;
264 };
265 
266 class LevelDBTraceIterator : public TransactionalLevelDBIterator {
267  public:
LevelDBTraceIterator(std::unique_ptr<leveldb::Iterator> iterator,base::WeakPtr<TransactionalLevelDBDatabase> db,base::WeakPtr<TransactionalLevelDBTransaction> txn,std::unique_ptr<LevelDBSnapshot> snapshot,int inst_num)268   LevelDBTraceIterator(std::unique_ptr<leveldb::Iterator> iterator,
269                        base::WeakPtr<TransactionalLevelDBDatabase> db,
270                        base::WeakPtr<TransactionalLevelDBTransaction> txn,
271                        std::unique_ptr<LevelDBSnapshot> snapshot,
272                        int inst_num)
273       : TransactionalLevelDBIterator(std::move(iterator),
274                                      std::move(db),
275                                      std::move(txn),
276                                      std::move(snapshot)),
277         class_name_("LevelDBIterator"),
278         is_valid_tracer_(class_name_, "IsValid", inst_num),
279         seek_to_last_tracer_(class_name_, "SeekToLast", inst_num),
280         seek_tracer_(class_name_, "Seek", inst_num),
281         next_tracer_(class_name_, "Next", inst_num),
282         prev_tracer_(class_name_, "Prev", inst_num),
283         key_tracer_(class_name_, "Key", inst_num),
284         value_tracer_(class_name_, "Value", inst_num) {}
285   ~LevelDBTraceIterator() override = default;
286 
287  private:
288   const std::string class_name_;
289 
IsValid() const290   bool IsValid() const override {
291     is_valid_tracer_.log_call();
292     return TransactionalLevelDBIterator::IsValid();
293   }
SeekToLast()294   leveldb::Status SeekToLast() override {
295     seek_to_last_tracer_.log_call();
296     return TransactionalLevelDBIterator::SeekToLast();
297   }
Seek(const base::StringPiece & target)298   leveldb::Status Seek(const base::StringPiece& target) override {
299     seek_tracer_.log_call();
300     return TransactionalLevelDBIterator::Seek(target);
301   }
Next()302   leveldb::Status Next() override {
303     next_tracer_.log_call();
304     return TransactionalLevelDBIterator::Next();
305   }
Prev()306   leveldb::Status Prev() override {
307     prev_tracer_.log_call();
308     return TransactionalLevelDBIterator::Prev();
309   }
Key() const310   base::StringPiece Key() const override {
311     key_tracer_.log_call();
312     return TransactionalLevelDBIterator::Key();
313   }
Value() const314   base::StringPiece Value() const override {
315     value_tracer_.log_call();
316     return TransactionalLevelDBIterator::Value();
317   }
318 
319   mutable FunctionTracer is_valid_tracer_;
320   mutable FunctionTracer seek_to_last_tracer_;
321   mutable FunctionTracer seek_tracer_;
322   mutable FunctionTracer next_tracer_;
323   mutable FunctionTracer prev_tracer_;
324   mutable FunctionTracer key_tracer_;
325   mutable FunctionTracer value_tracer_;
326 };
327 
328 class LevelDBTestIterator : public content::TransactionalLevelDBIterator {
329  public:
LevelDBTestIterator(std::unique_ptr<leveldb::Iterator> iterator,base::WeakPtr<TransactionalLevelDBDatabase> db,base::WeakPtr<TransactionalLevelDBTransaction> txn,std::unique_ptr<LevelDBSnapshot> snapshot,FailMethod fail_method,int fail_on_call_num)330   LevelDBTestIterator(std::unique_ptr<leveldb::Iterator> iterator,
331                       base::WeakPtr<TransactionalLevelDBDatabase> db,
332                       base::WeakPtr<TransactionalLevelDBTransaction> txn,
333                       std::unique_ptr<LevelDBSnapshot> snapshot,
334                       FailMethod fail_method,
335                       int fail_on_call_num)
336       : TransactionalLevelDBIterator(std::move(iterator),
337                                      std::move(db),
338                                      std::move(txn),
339                                      std::move(snapshot)),
340         fail_method_(fail_method),
341         fail_on_call_num_(fail_on_call_num),
342         current_call_num_(0) {}
~LevelDBTestIterator()343   ~LevelDBTestIterator() override {}
344 
345  private:
Seek(const base::StringPiece & target)346   leveldb::Status Seek(const base::StringPiece& target) override {
347     if (fail_method_ != FailMethod::SEEK ||
348         ++current_call_num_ != fail_on_call_num_)
349       return TransactionalLevelDBIterator::Seek(target);
350     return leveldb::Status::Corruption("Corrupted for test");
351   }
352 
353   FailMethod fail_method_;
354   int fail_on_call_num_;
355   int current_call_num_;
356 };
357 
MockBrowserTestIndexedDBClassFactory()358 MockBrowserTestIndexedDBClassFactory::MockBrowserTestIndexedDBClassFactory()
359     : failure_class_(FailClass::NOTHING),
360       failure_method_(FailMethod::NOTHING),
361       only_trace_calls_(false) {}
362 
363 MockBrowserTestIndexedDBClassFactory::~MockBrowserTestIndexedDBClassFactory() =
364     default;
365 
366 TransactionalLevelDBFactory&
transactional_leveldb_factory()367 MockBrowserTestIndexedDBClassFactory::transactional_leveldb_factory() {
368   return *this;
369 }
370 
371 std::pair<std::unique_ptr<IndexedDBDatabase>, leveldb::Status>
CreateIndexedDBDatabase(const base::string16 & name,IndexedDBBackingStore * backing_store,IndexedDBFactory * factory,TasksAvailableCallback tasks_available_callback,std::unique_ptr<IndexedDBMetadataCoding> metadata_coding,const IndexedDBDatabase::Identifier & unique_identifier,ScopesLockManager * transaction_lock_manager)372 MockBrowserTestIndexedDBClassFactory::CreateIndexedDBDatabase(
373     const base::string16& name,
374     IndexedDBBackingStore* backing_store,
375     IndexedDBFactory* factory,
376     TasksAvailableCallback tasks_available_callback,
377     std::unique_ptr<IndexedDBMetadataCoding> metadata_coding,
378     const IndexedDBDatabase::Identifier& unique_identifier,
379     ScopesLockManager* transaction_lock_manager) {
380   std::unique_ptr<IndexedDBTestDatabase> database =
381       std::make_unique<IndexedDBTestDatabase>(
382           name, backing_store, factory, this,
383           std::move(tasks_available_callback), std::move(metadata_coding),
384           unique_identifier, transaction_lock_manager);
385   leveldb::Status s = database->OpenInternal();
386   if (!s.ok())
387     database.reset();
388   return {std::move(database), s};
389 }
390 
391 std::unique_ptr<IndexedDBTransaction>
CreateIndexedDBTransaction(int64_t id,IndexedDBConnection * connection,const std::set<int64_t> & scope,blink::mojom::IDBTransactionMode mode,TasksAvailableCallback tasks_available_callback,IndexedDBTransaction::TearDownCallback tear_down_callback,IndexedDBBackingStore::Transaction * backing_store_transaction)392 MockBrowserTestIndexedDBClassFactory::CreateIndexedDBTransaction(
393     int64_t id,
394     IndexedDBConnection* connection,
395     const std::set<int64_t>& scope,
396     blink::mojom::IDBTransactionMode mode,
397     TasksAvailableCallback tasks_available_callback,
398     IndexedDBTransaction::TearDownCallback tear_down_callback,
399     IndexedDBBackingStore::Transaction* backing_store_transaction) {
400   return std::make_unique<IndexedDBTestTransaction>(
401       id, connection, scope, mode, std::move(tasks_available_callback),
402       std::move(tear_down_callback), backing_store_transaction);
403 }
404 
405 std::unique_ptr<TransactionalLevelDBDatabase>
CreateLevelDBDatabase(scoped_refptr<LevelDBState> state,std::unique_ptr<LevelDBScopes> scopes,scoped_refptr<base::SequencedTaskRunner> task_runner,size_t max_open_iterators)406 MockBrowserTestIndexedDBClassFactory::CreateLevelDBDatabase(
407     scoped_refptr<LevelDBState> state,
408     std::unique_ptr<LevelDBScopes> scopes,
409     scoped_refptr<base::SequencedTaskRunner> task_runner,
410     size_t max_open_iterators) {
411   instance_count_[FailClass::LEVELDB_DATABASE] =
412       instance_count_[FailClass::LEVELDB_DATABASE] + 1;
413   if (failure_class_ == FailClass::LEVELDB_DATABASE &&
414       instance_count_[FailClass::LEVELDB_DATABASE] ==
415           fail_on_instance_num_[FailClass::LEVELDB_DATABASE]) {
416     return std::make_unique<LevelDBTestDatabase>(
417         std::move(state), std::move(scopes), this, std::move(task_runner),
418         max_open_iterators, failure_method_,
419         fail_on_call_num_[FailClass::LEVELDB_DATABASE]);
420   } else {
421     return DefaultTransactionalLevelDBFactory::CreateLevelDBDatabase(
422         std::move(state), std::move(scopes), std::move(task_runner),
423         max_open_iterators);
424   }
425 }
426 
427 std::unique_ptr<LevelDBDirectTransaction>
CreateLevelDBDirectTransaction(TransactionalLevelDBDatabase * db)428 MockBrowserTestIndexedDBClassFactory::CreateLevelDBDirectTransaction(
429     TransactionalLevelDBDatabase* db) {
430   instance_count_[FailClass::LEVELDB_DIRECT_TRANSACTION] =
431       instance_count_[FailClass::LEVELDB_DIRECT_TRANSACTION] + 1;
432   if (failure_class_ == FailClass::LEVELDB_DIRECT_TRANSACTION &&
433       instance_count_[FailClass::LEVELDB_DIRECT_TRANSACTION] ==
434           fail_on_instance_num_[FailClass::LEVELDB_DIRECT_TRANSACTION]) {
435     return std::make_unique<LevelDBTestDirectTransaction>(
436         db, failure_method_,
437         fail_on_call_num_[FailClass::LEVELDB_DIRECT_TRANSACTION]);
438   } else {
439     return DefaultTransactionalLevelDBFactory::CreateLevelDBDirectTransaction(
440         db);
441   }
442 }
443 
444 scoped_refptr<TransactionalLevelDBTransaction>
CreateLevelDBTransaction(TransactionalLevelDBDatabase * db,std::unique_ptr<LevelDBScope> scope)445 MockBrowserTestIndexedDBClassFactory::CreateLevelDBTransaction(
446     TransactionalLevelDBDatabase* db,
447     std::unique_ptr<LevelDBScope> scope) {
448   instance_count_[FailClass::LEVELDB_TRANSACTION] =
449       instance_count_[FailClass::LEVELDB_TRANSACTION] + 1;
450   if (only_trace_calls_) {
451     return base::MakeRefCounted<LevelDBTraceTransaction>(
452         db, std::move(scope), instance_count_[FailClass::LEVELDB_TRANSACTION]);
453   } else {
454     if (failure_class_ == FailClass::LEVELDB_TRANSACTION &&
455         instance_count_[FailClass::LEVELDB_TRANSACTION] ==
456             fail_on_instance_num_[FailClass::LEVELDB_TRANSACTION]) {
457       return base::MakeRefCounted<LevelDBTestTransaction>(
458           db, std::move(scope), failure_method_,
459           fail_on_call_num_[FailClass::LEVELDB_TRANSACTION]);
460     } else {
461       return DefaultTransactionalLevelDBFactory::CreateLevelDBTransaction(
462           db, std::move(scope));
463     }
464   }
465 }
466 
467 std::unique_ptr<TransactionalLevelDBIterator>
CreateIterator(std::unique_ptr<leveldb::Iterator> iterator,base::WeakPtr<TransactionalLevelDBDatabase> db,base::WeakPtr<TransactionalLevelDBTransaction> txn,std::unique_ptr<LevelDBSnapshot> snapshot)468 MockBrowserTestIndexedDBClassFactory::CreateIterator(
469     std::unique_ptr<leveldb::Iterator> iterator,
470     base::WeakPtr<TransactionalLevelDBDatabase> db,
471     base::WeakPtr<TransactionalLevelDBTransaction> txn,
472     std::unique_ptr<LevelDBSnapshot> snapshot) {
473   instance_count_[FailClass::LEVELDB_ITERATOR] =
474       instance_count_[FailClass::LEVELDB_ITERATOR] + 1;
475   if (only_trace_calls_) {
476     return std::make_unique<LevelDBTraceIterator>(
477         std::move(iterator), db, std::move(txn), std::move(snapshot),
478         instance_count_[FailClass::LEVELDB_ITERATOR]);
479   } else {
480     if (failure_class_ == FailClass::LEVELDB_ITERATOR &&
481         instance_count_[FailClass::LEVELDB_ITERATOR] ==
482             fail_on_instance_num_[FailClass::LEVELDB_ITERATOR]) {
483       return std::make_unique<LevelDBTestIterator>(
484           std::move(iterator), db, std::move(txn), std::move(snapshot),
485           failure_method_, fail_on_call_num_[FailClass::LEVELDB_ITERATOR]);
486     } else {
487       return DefaultTransactionalLevelDBFactory::CreateIterator(
488           std::move(iterator), db, std::move(txn), std::move(snapshot));
489     }
490   }
491 }
492 
FailOperation(storage::mojom::FailClass failure_class,storage::mojom::FailMethod failure_method,int fail_on_instance_num,int fail_on_call_num,base::OnceClosure callback)493 void MockBrowserTestIndexedDBClassFactory::FailOperation(
494     storage::mojom::FailClass failure_class,
495     storage::mojom::FailMethod failure_method,
496     int fail_on_instance_num,
497     int fail_on_call_num,
498     base::OnceClosure callback) {
499   VLOG(0) << "FailOperation: class=" << failure_class
500           << ", method=" << failure_method
501           << ", instanceNum=" << fail_on_instance_num
502           << ", callNum=" << fail_on_call_num;
503   DCHECK(failure_class != FailClass::NOTHING);
504   DCHECK(failure_method != FailMethod::NOTHING);
505   failure_class_ = failure_class;
506   failure_method_ = failure_method;
507   fail_on_instance_num_[failure_class_] = fail_on_instance_num;
508   fail_on_call_num_[failure_class_] = fail_on_call_num;
509   instance_count_.clear();
510 
511   std::move(callback).Run();
512 }
513 
Reset()514 void MockBrowserTestIndexedDBClassFactory::Reset() {
515   failure_class_ = FailClass::NOTHING;
516   failure_method_ = FailMethod::NOTHING;
517   instance_count_.clear();
518   fail_on_instance_num_.clear();
519   fail_on_call_num_.clear();
520 }
521 
522 }  // namespace content
523