Update To 11.40.268.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_iterator_impl.h"
9 #include "content/browser/indexed_db/leveldb/leveldb_transaction.h"
10 #include "content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.h"
11 #include "third_party/leveldatabase/src/include/leveldb/status.h"
12
13 namespace {
14
15 class FunctionTracer {
16  public:
17   FunctionTracer(const std::string& class_name,
18                  const std::string& method_name,
19                  int instance_num)
20       : class_name_(class_name),
21         method_name_(method_name),
22         instance_count_(instance_num),
23         current_call_num_(0) {}
24
25   void log_call() {
26     current_call_num_++;
27     VLOG(0) << class_name_ << '[' << instance_count_ << "]::" << method_name_
28             << "()[" << current_call_num_ << ']';
29   }
30
31  private:
32   std::string class_name_;
33   std::string method_name_;
34   int instance_count_;
35   int current_call_num_;
36 };
37
38 }  // namespace
39
40 namespace content {
41
42 class LevelDBTestTansaction : public LevelDBTransaction {
43  public:
44   LevelDBTestTansaction(LevelDBDatabase* db,
45                         FailMethod fail_method,
46                         int fail_on_call_num)
47       : LevelDBTransaction(db),
48         fail_method_(fail_method),
49         fail_on_call_num_(fail_on_call_num),
50         current_call_num_(0) {
51     DCHECK(fail_method != FAIL_METHOD_NOTHING);
52     DCHECK_GT(fail_on_call_num, 0);
53   }
54
55   leveldb::Status Get(const base::StringPiece& key,
56                       std::string* value,
57                       bool* found) override {
58     if (fail_method_ != FAIL_METHOD_GET ||
59         ++current_call_num_ != fail_on_call_num_)
60       return LevelDBTransaction::Get(key, value, found);
61
62     *found = false;
63     return leveldb::Status::Corruption("Corrupted for the test");
64   }
65
66   leveldb::Status Commit() override {
67     if (fail_method_ != FAIL_METHOD_COMMIT ||
68         ++current_call_num_ != fail_on_call_num_)
69       return LevelDBTransaction::Commit();
70
71     return leveldb::Status::Corruption("Corrupted for the test");
72   }
73
74  private:
75   ~LevelDBTestTansaction() override {}
76
77   FailMethod fail_method_;
78   int fail_on_call_num_;
79   int current_call_num_;
80 };
81
82 class LevelDBTraceTansaction : public LevelDBTransaction {
83  public:
84   LevelDBTraceTansaction(LevelDBDatabase* db, int tx_num)
85       : LevelDBTransaction(db),
86         commit_tracer_(s_class_name, "Commit", tx_num),
87         get_tracer_(s_class_name, "Get", tx_num) {}
88
89   leveldb::Status Get(const base::StringPiece& key,
90                       std::string* value,
91                       bool* found) override {
92     get_tracer_.log_call();
93     return LevelDBTransaction::Get(key, value, found);
94   }
95
96   leveldb::Status Commit() override {
97     commit_tracer_.log_call();
98     return LevelDBTransaction::Commit();
99   }
100
101  private:
102   static const std::string s_class_name;
103
104   ~LevelDBTraceTansaction() override {}
105
106   FunctionTracer commit_tracer_;
107   FunctionTracer get_tracer_;
108 };
109
110 const std::string LevelDBTraceTansaction::s_class_name = "LevelDBTransaction";
111
112 class LevelDBTraceIteratorImpl : public LevelDBIteratorImpl {
113  public:
114   LevelDBTraceIteratorImpl(scoped_ptr<leveldb::Iterator> iterator, int inst_num)
115       : LevelDBIteratorImpl(iterator.Pass()),
116         is_valid_tracer_(s_class_name, "IsValid", inst_num),
117         seek_to_last_tracer_(s_class_name, "SeekToLast", inst_num),
118         seek_tracer_(s_class_name, "Seek", inst_num),
119         next_tracer_(s_class_name, "Next", inst_num),
120         prev_tracer_(s_class_name, "Prev", inst_num),
121         key_tracer_(s_class_name, "Key", inst_num),
122         value_tracer_(s_class_name, "Value", inst_num) {}
123   ~LevelDBTraceIteratorImpl() override {}
124
125  private:
126   static const std::string s_class_name;
127
128   bool IsValid() const override {
129     is_valid_tracer_.log_call();
130     return LevelDBIteratorImpl::IsValid();
131   }
132   leveldb::Status SeekToLast() override {
133     seek_to_last_tracer_.log_call();
134     return LevelDBIteratorImpl::SeekToLast();
135   }
136   leveldb::Status Seek(const base::StringPiece& target) override {
137     seek_tracer_.log_call();
138     return LevelDBIteratorImpl::Seek(target);
139   }
140   leveldb::Status Next() override {
141     next_tracer_.log_call();
142     return LevelDBIteratorImpl::Next();
143   }
144   leveldb::Status Prev() override {
145     prev_tracer_.log_call();
146     return LevelDBIteratorImpl::Prev();
147   }
148   base::StringPiece Key() const override {
149     key_tracer_.log_call();
150     return LevelDBIteratorImpl::Key();
151   }
152   base::StringPiece Value() const override {
153     value_tracer_.log_call();
154     return LevelDBIteratorImpl::Value();
155   }
156
157   mutable FunctionTracer is_valid_tracer_;
158   mutable FunctionTracer seek_to_last_tracer_;
159   mutable FunctionTracer seek_tracer_;
160   mutable FunctionTracer next_tracer_;
161   mutable FunctionTracer prev_tracer_;
162   mutable FunctionTracer key_tracer_;
163   mutable FunctionTracer value_tracer_;
164 };
165
166 const std::string LevelDBTraceIteratorImpl::s_class_name = "LevelDBIterator";
167
168 class LevelDBTestIteratorImpl : public content::LevelDBIteratorImpl {
169  public:
170   LevelDBTestIteratorImpl(scoped_ptr<leveldb::Iterator> iterator,
171                           FailMethod fail_method,
172                           int fail_on_call_num)
173       : LevelDBIteratorImpl(iterator.Pass()),
174         fail_method_(fail_method),
175         fail_on_call_num_(fail_on_call_num),
176         current_call_num_(0) {}
177   ~LevelDBTestIteratorImpl() override {}
178
179  private:
180   leveldb::Status Seek(const base::StringPiece& target) override {
181     if (fail_method_ != FAIL_METHOD_SEEK ||
182         ++current_call_num_ != fail_on_call_num_)
183       return LevelDBIteratorImpl::Seek(target);
184     return leveldb::Status::Corruption("Corrupted for test");
185   }
186
187   FailMethod fail_method_;
188   int fail_on_call_num_;
189   int current_call_num_;
190 };
191
192 MockBrowserTestIndexedDBClassFactory::MockBrowserTestIndexedDBClassFactory()
193     : failure_class_(FAIL_CLASS_NOTHING),
194       failure_method_(FAIL_METHOD_NOTHING),
195       only_trace_calls_(false) {
196 }
197
198 MockBrowserTestIndexedDBClassFactory::~MockBrowserTestIndexedDBClassFactory() {
199 }
200
201 LevelDBTransaction*
202 MockBrowserTestIndexedDBClassFactory::CreateLevelDBTransaction(
203     LevelDBDatabase* db) {
204   instance_count_[FAIL_CLASS_LEVELDB_TRANSACTION] =
205       instance_count_[FAIL_CLASS_LEVELDB_TRANSACTION] + 1;
206   if (only_trace_calls_) {
207     return new LevelDBTraceTansaction(
208         db, instance_count_[FAIL_CLASS_LEVELDB_TRANSACTION]);
209   } else {
210     if (failure_class_ == FAIL_CLASS_LEVELDB_TRANSACTION &&
211         instance_count_[FAIL_CLASS_LEVELDB_TRANSACTION] ==
212             fail_on_instance_num_[FAIL_CLASS_LEVELDB_TRANSACTION]) {
213       return new LevelDBTestTansaction(
214           db,
215           failure_method_,
216           fail_on_call_num_[FAIL_CLASS_LEVELDB_TRANSACTION]);
217     } else {
218       return IndexedDBClassFactory::CreateLevelDBTransaction(db);
219     }
220   }
221 }
222
223 LevelDBIteratorImpl* MockBrowserTestIndexedDBClassFactory::CreateIteratorImpl(
224     scoped_ptr<leveldb::Iterator> iterator) {
225   instance_count_[FAIL_CLASS_LEVELDB_ITERATOR] =
226       instance_count_[FAIL_CLASS_LEVELDB_ITERATOR] + 1;
227   if (only_trace_calls_) {
228     return new LevelDBTraceIteratorImpl(
229         iterator.Pass(), instance_count_[FAIL_CLASS_LEVELDB_ITERATOR]);
230   } else {
231     if (failure_class_ == FAIL_CLASS_LEVELDB_ITERATOR &&
232         instance_count_[FAIL_CLASS_LEVELDB_ITERATOR] ==
233             fail_on_instance_num_[FAIL_CLASS_LEVELDB_ITERATOR]) {
234       return new LevelDBTestIteratorImpl(
235           iterator.Pass(),
236           failure_method_,
237           fail_on_call_num_[FAIL_CLASS_LEVELDB_ITERATOR]);
238     } else {
239       return new LevelDBIteratorImpl(iterator.Pass());
240     }
241   }
242 }
243
244 void MockBrowserTestIndexedDBClassFactory::FailOperation(
245     FailClass failure_class,
246     FailMethod failure_method,
247     int fail_on_instance_num,
248     int fail_on_call_num) {
249   VLOG(0) << "FailOperation: class=" << failure_class
250           << ", method=" << failure_method
251           << ", instanceNum=" << fail_on_instance_num
252           << ", callNum=" << fail_on_call_num;
253   DCHECK(failure_class != FAIL_CLASS_NOTHING);
254   DCHECK(failure_method != FAIL_METHOD_NOTHING);
255   failure_class_ = failure_class;
256   failure_method_ = failure_method;
257   fail_on_instance_num_[failure_class_] = fail_on_instance_num;
258   fail_on_call_num_[failure_class_] = fail_on_call_num;
259   instance_count_.clear();
260 }
261
262 void MockBrowserTestIndexedDBClassFactory::Reset() {
263   failure_class_ = FAIL_CLASS_NOTHING;
264   failure_method_ = FAIL_METHOD_NOTHING;
265   instance_count_.clear();
266   fail_on_instance_num_.clear();
267   fail_on_call_num_.clear();
268 }
269
270 }  // namespace content