Upstream version 8.37.180.0
[platform/framework/web/crosswalk.git] / src / content / browser / indexed_db / mock_browsertest_indexed_db_class_factory.cc
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 <string>
6
7 #include "base/logging.h"
8 #include "content/browser/indexed_db/leveldb/leveldb_transaction.h"
9 #include "content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.h"
10 #include "third_party/leveldatabase/src/include/leveldb/status.h"
11
12 namespace {
13
14 class FunctionTracer {
15  public:
16   FunctionTracer(const std::string& class_name,
17                  const std::string& method_name,
18                  int instance_num)
19       : class_name_(class_name),
20         method_name_(method_name),
21         instance_count_(instance_num),
22         current_call_num_(0) {}
23
24   void log_call() {
25     current_call_num_++;
26     VLOG(0) << class_name_ << '[' << instance_count_ << "]::" << method_name_
27             << "()[" << current_call_num_ << ']';
28   }
29
30  private:
31   std::string class_name_;
32   std::string method_name_;
33   int instance_count_;
34   int current_call_num_;
35 };
36
37 }  // namespace
38
39 namespace content {
40
41 class LevelDBTestTansaction : public LevelDBTransaction {
42  public:
43   LevelDBTestTansaction(LevelDBDatabase* db,
44                         FailMethod fail_method,
45                         int fail_on_call_num)
46       : LevelDBTransaction(db),
47         fail_method_(fail_method),
48         fail_on_call_num_(fail_on_call_num),
49         current_call_num_(0) {
50     DCHECK(fail_method != FAIL_METHOD_NOTHING);
51     DCHECK_GT(fail_on_call_num, 0);
52   }
53
54   virtual leveldb::Status Get(const base::StringPiece& key,
55                               std::string* value,
56                               bool* found) OVERRIDE {
57     if (fail_method_ != FAIL_METHOD_GET ||
58         ++current_call_num_ != fail_on_call_num_)
59       return LevelDBTransaction::Get(key, value, found);
60
61     *found = false;
62     return leveldb::Status::Corruption("Corrupted for the test");
63   }
64
65   virtual leveldb::Status Commit() OVERRIDE {
66     if (fail_method_ != FAIL_METHOD_COMMIT ||
67         ++current_call_num_ != fail_on_call_num_)
68       return LevelDBTransaction::Commit();
69
70     return leveldb::Status::Corruption("Corrupted for the test");
71   }
72
73  private:
74   virtual ~LevelDBTestTansaction() {}
75
76   FailMethod fail_method_;
77   int fail_on_call_num_;
78   int current_call_num_;
79 };
80
81 class LevelDBTraceTansaction : public LevelDBTransaction {
82  public:
83   LevelDBTraceTansaction(LevelDBDatabase* db, int tx_num)
84       : LevelDBTransaction(db),
85         commit_tracer_(s_class_name, "Commit", tx_num),
86         get_tracer_(s_class_name, "Get", tx_num) {}
87
88   virtual leveldb::Status Get(const base::StringPiece& key,
89                               std::string* value,
90                               bool* found) OVERRIDE {
91     get_tracer_.log_call();
92     return LevelDBTransaction::Get(key, value, found);
93   }
94
95   virtual leveldb::Status Commit() OVERRIDE {
96     commit_tracer_.log_call();
97     return LevelDBTransaction::Commit();
98   }
99
100  private:
101   virtual ~LevelDBTraceTansaction() {}
102
103   const static std::string s_class_name;
104
105   FunctionTracer commit_tracer_;
106   FunctionTracer get_tracer_;
107 };
108
109 const std::string LevelDBTraceTansaction::s_class_name = "LevelDBTransaction";
110
111 MockBrowserTestIndexedDBClassFactory::MockBrowserTestIndexedDBClassFactory()
112     : failure_class_(FAIL_CLASS_NOTHING),
113       failure_method_(FAIL_METHOD_NOTHING),
114       only_trace_calls_(false) {
115 }
116
117 MockBrowserTestIndexedDBClassFactory::~MockBrowserTestIndexedDBClassFactory() {
118 }
119
120 LevelDBTransaction*
121 MockBrowserTestIndexedDBClassFactory::CreateLevelDBTransaction(
122     LevelDBDatabase* db) {
123   instance_count_[FAIL_CLASS_LEVELDB_TRANSACTION] =
124       instance_count_[FAIL_CLASS_LEVELDB_TRANSACTION] + 1;
125   if (only_trace_calls_) {
126     return new LevelDBTraceTansaction(
127         db, instance_count_[FAIL_CLASS_LEVELDB_TRANSACTION]);
128   } else {
129     if (failure_class_ == FAIL_CLASS_LEVELDB_TRANSACTION &&
130         instance_count_[FAIL_CLASS_LEVELDB_TRANSACTION] ==
131             fail_on_instance_num_[FAIL_CLASS_LEVELDB_TRANSACTION]) {
132       return new LevelDBTestTansaction(
133           db,
134           failure_method_,
135           fail_on_call_num_[FAIL_CLASS_LEVELDB_TRANSACTION]);
136     } else {
137       return IndexedDBClassFactory::CreateLevelDBTransaction(db);
138     }
139   }
140 }
141
142 void MockBrowserTestIndexedDBClassFactory::FailOperation(
143     FailClass failure_class,
144     FailMethod failure_method,
145     int fail_on_instance_num,
146     int fail_on_call_num) {
147   VLOG(0) << "FailOperation: class=" << failure_class
148           << ", method=" << failure_method
149           << ", instanceNum=" << fail_on_instance_num
150           << ", callNum=" << fail_on_call_num;
151   DCHECK(failure_class != FAIL_CLASS_NOTHING);
152   DCHECK(failure_method != FAIL_METHOD_NOTHING);
153   failure_class_ = failure_class;
154   failure_method_ = failure_method;
155   fail_on_instance_num_[failure_class_] = fail_on_instance_num;
156   fail_on_call_num_[failure_class_] = fail_on_call_num;
157   instance_count_.clear();
158 }
159
160 void MockBrowserTestIndexedDBClassFactory::Reset() {
161   failure_class_ = FAIL_CLASS_NOTHING;
162   failure_method_ = FAIL_METHOD_NOTHING;
163   instance_count_.clear();
164   fail_on_instance_num_.clear();
165   fail_on_call_num_.clear();
166 }
167
168 }  // namespace content