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