Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(353)

Side by Side Diff: content/child/indexed_db/webidbcursor_impl_unittest.cc

Issue 1963293002: Replacing Indexed DB Chromium IPC with Mojo Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Refactoring after Passing URLRequestContextGetter. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2013 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/child/indexed_db/webidbcursor_impl.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9
10 #include <memory>
11
12 #include "base/macros.h"
13 #include "base/memory/ptr_util.h"
14 #include "base/threading/thread_task_runner_handle.h"
15 #include "base/values.h"
16 #include "content/child/indexed_db/indexed_db_dispatcher.h"
17 #include "content/child/indexed_db/indexed_db_key_builders.h"
18 #include "content/child/indexed_db/mock_webidbcallbacks.h"
19 #include "content/child/thread_safe_sender.h"
20 #include "content/common/indexed_db/indexed_db_key.h"
21 #include "ipc/ipc_sync_message_filter.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "third_party/WebKit/public/platform/WebData.h"
24
25 using blink::WebBlobInfo;
26 using blink::WebData;
27 using blink::WebIDBCallbacks;
28 using blink::WebIDBKey;
29 using blink::WebIDBKeyTypeNumber;
30 using blink::WebIDBValue;
31 using blink::WebVector;
32 using testing::StrictMock;
33
34 namespace content {
35
36 namespace {
37
38 class MockDispatcher : public IndexedDBDispatcher {
39 public:
40 explicit MockDispatcher(ThreadSafeSender* thread_safe_sender)
41 : IndexedDBDispatcher(thread_safe_sender),
42 prefetch_calls_(0),
43 last_prefetch_count_(0),
44 reset_calls_(0),
45 last_used_count_(0),
46 advance_calls_(0),
47 continue_calls_(0),
48 destroyed_cursor_id_(0) {}
49
50 void RequestIDBCursorPrefetch(int n,
51 WebIDBCallbacks* callbacks,
52 int32_t ipc_cursor_id) override {
53 ++prefetch_calls_;
54 last_prefetch_count_ = n;
55 callbacks_.reset(callbacks);
56 }
57
58 void RequestIDBCursorPrefetchReset(int used_prefetches,
59 int unused_prefetches,
60 int32_t ipc_cursor_id) override {
61 ++reset_calls_;
62 last_used_count_ = used_prefetches;
63 }
64
65 void RequestIDBCursorAdvance(unsigned long count,
66 WebIDBCallbacks* callbacks,
67 int32_t ipc_cursor_id,
68 int64_t transaction_id) override {
69 ++advance_calls_;
70 callbacks_.reset(callbacks);
71 }
72
73 void RequestIDBCursorContinue(const IndexedDBKey& key,
74 const IndexedDBKey& primary_key,
75 WebIDBCallbacks* callbacks,
76 int32_t ipc_cursor_id,
77 int64_t transaction_id) override {
78 ++continue_calls_;
79 callbacks_.reset(callbacks);
80 }
81
82 void CursorDestroyed(int32_t ipc_cursor_id) override {
83 destroyed_cursor_id_ = ipc_cursor_id;
84 }
85
86 int prefetch_calls() { return prefetch_calls_; }
87 int last_prefetch_count() { return last_prefetch_count_; }
88 int reset_calls() { return reset_calls_; }
89 int last_used_count() { return last_used_count_; }
90 int advance_calls() { return advance_calls_; }
91 int continue_calls() { return continue_calls_; }
92 int32_t destroyed_cursor_id() { return destroyed_cursor_id_; }
93
94 private:
95 int prefetch_calls_;
96 int last_prefetch_count_;
97 int reset_calls_;
98 int last_used_count_;
99 int advance_calls_;
100 int continue_calls_;
101 int32_t destroyed_cursor_id_;
102 std::unique_ptr<WebIDBCallbacks> callbacks_;
103 };
104
105 class MockContinueCallbacks : public StrictMock<MockWebIDBCallbacks> {
106 public:
107 MockContinueCallbacks(IndexedDBKey* key = 0,
108 WebVector<WebBlobInfo>* webBlobInfo = 0)
109 : key_(key), web_blob_info_(webBlobInfo) {}
110
111 void onSuccess(const WebIDBKey& key,
112 const WebIDBKey& primaryKey,
113 const WebIDBValue& value) override {
114 if (key_)
115 *key_ = IndexedDBKeyBuilder::Build(key);
116 if (web_blob_info_)
117 *web_blob_info_ = value.webBlobInfo;
118 }
119
120 private:
121 IndexedDBKey* key_;
122 WebVector<WebBlobInfo>* web_blob_info_;
123 };
124
125 class MockSyncMessageFilter : public IPC::SyncMessageFilter {
126 public:
127 MockSyncMessageFilter()
128 : SyncMessageFilter(nullptr, false /* is_channel_send_thread_safe */) {}
129
130 private:
131 ~MockSyncMessageFilter() override {}
132 };
133
134 } // namespace
135
136 class WebIDBCursorImplTest : public testing::Test {
137 public:
138 WebIDBCursorImplTest() {
139 null_key_.assignNull();
140 thread_safe_sender_ = new ThreadSafeSender(
141 base::ThreadTaskRunnerHandle::Get(), new MockSyncMessageFilter);
142 dispatcher_ =
143 base::WrapUnique(new MockDispatcher(thread_safe_sender_.get()));
144 }
145
146 protected:
147 base::MessageLoop message_loop_;
148 WebIDBKey null_key_;
149 scoped_refptr<ThreadSafeSender> thread_safe_sender_;
150 std::unique_ptr<MockDispatcher> dispatcher_;
151
152 private:
153 DISALLOW_COPY_AND_ASSIGN(WebIDBCursorImplTest);
154 };
155
156 TEST_F(WebIDBCursorImplTest, PrefetchTest) {
157 const int64_t transaction_id = 1;
158 {
159 WebIDBCursorImpl cursor(WebIDBCursorImpl::kInvalidCursorId,
160 transaction_id,
161 thread_safe_sender_.get());
162
163 // Call continue() until prefetching should kick in.
164 int continue_calls = 0;
165 EXPECT_EQ(dispatcher_->continue_calls(), 0);
166 for (int i = 0; i < WebIDBCursorImpl::kPrefetchContinueThreshold; ++i) {
167 cursor.continueFunction(null_key_, new MockContinueCallbacks());
168 EXPECT_EQ(++continue_calls, dispatcher_->continue_calls());
169 EXPECT_EQ(0, dispatcher_->prefetch_calls());
170 }
171
172 // Do enough repetitions to verify that the count grows each time,
173 // but not so many that the maximum limit is hit.
174 const int kPrefetchRepetitions = 5;
175
176 int expected_key = 0;
177 int last_prefetch_count = 0;
178 for (int repetitions = 0; repetitions < kPrefetchRepetitions;
179 ++repetitions) {
180 // Initiate the prefetch
181 cursor.continueFunction(null_key_, new MockContinueCallbacks());
182 EXPECT_EQ(continue_calls, dispatcher_->continue_calls());
183 EXPECT_EQ(repetitions + 1, dispatcher_->prefetch_calls());
184
185 // Verify that the requested count has increased since last time.
186 int prefetch_count = dispatcher_->last_prefetch_count();
187 EXPECT_GT(prefetch_count, last_prefetch_count);
188 last_prefetch_count = prefetch_count;
189
190 // Fill the prefetch cache as requested.
191 std::vector<IndexedDBKey> keys;
192 std::vector<IndexedDBKey> primary_keys(prefetch_count);
193 std::vector<WebIDBValue> values(prefetch_count);
194 for (int i = 0; i < prefetch_count; ++i) {
195 keys.push_back(IndexedDBKey(expected_key + i, WebIDBKeyTypeNumber));
196 values[i].webBlobInfo =
197 WebVector<WebBlobInfo>(static_cast<size_t>(expected_key + i));
198 }
199 cursor.SetPrefetchData(keys, primary_keys, values);
200
201 // Note that the real dispatcher would call cursor->CachedContinue()
202 // immediately after cursor->SetPrefetchData() to service the request
203 // that initiated the prefetch.
204
205 // Verify that the cache is used for subsequent continue() calls.
206 for (int i = 0; i < prefetch_count; ++i) {
207 IndexedDBKey key;
208 WebVector<WebBlobInfo> web_blob_info;
209 cursor.continueFunction(
210 null_key_, new MockContinueCallbacks(&key, &web_blob_info));
211 EXPECT_EQ(continue_calls, dispatcher_->continue_calls());
212 EXPECT_EQ(repetitions + 1, dispatcher_->prefetch_calls());
213
214 EXPECT_EQ(WebIDBKeyTypeNumber, key.type());
215 EXPECT_EQ(expected_key, static_cast<int>(web_blob_info.size()));
216 EXPECT_EQ(expected_key++, key.number());
217 }
218 }
219 }
220
221 EXPECT_EQ(dispatcher_->destroyed_cursor_id(),
222 WebIDBCursorImpl::kInvalidCursorId);
223 }
224
225 TEST_F(WebIDBCursorImplTest, AdvancePrefetchTest) {
226 const int64_t transaction_id = 1;
227 WebIDBCursorImpl cursor(WebIDBCursorImpl::kInvalidCursorId,
228 transaction_id,
229 thread_safe_sender_.get());
230
231 // Call continue() until prefetching should kick in.
232 EXPECT_EQ(0, dispatcher_->continue_calls());
233 for (int i = 0; i < WebIDBCursorImpl::kPrefetchContinueThreshold; ++i) {
234 cursor.continueFunction(null_key_, new MockContinueCallbacks());
235 }
236 EXPECT_EQ(0, dispatcher_->prefetch_calls());
237
238 // Initiate the prefetch
239 cursor.continueFunction(null_key_, new MockContinueCallbacks());
240
241 EXPECT_EQ(1, dispatcher_->prefetch_calls());
242 EXPECT_EQ(static_cast<int>(WebIDBCursorImpl::kPrefetchContinueThreshold),
243 dispatcher_->continue_calls());
244 EXPECT_EQ(0, dispatcher_->advance_calls());
245
246 const int prefetch_count = dispatcher_->last_prefetch_count();
247
248 // Fill the prefetch cache as requested.
249 int expected_key = 0;
250 std::vector<IndexedDBKey> keys;
251 std::vector<IndexedDBKey> primary_keys(prefetch_count);
252 std::vector<WebIDBValue> values(prefetch_count);
253 for (int i = 0; i < prefetch_count; ++i) {
254 keys.push_back(IndexedDBKey(expected_key + i, WebIDBKeyTypeNumber));
255 values[i].webBlobInfo =
256 WebVector<WebBlobInfo>(static_cast<size_t>(expected_key + i));
257 }
258 cursor.SetPrefetchData(keys, primary_keys, values);
259
260 // Note that the real dispatcher would call cursor->CachedContinue()
261 // immediately after cursor->SetPrefetchData() to service the request
262 // that initiated the prefetch.
263
264 // Need at least this many in the cache for the test steps.
265 ASSERT_GE(prefetch_count, 5);
266
267 // IDBCursor.continue()
268 IndexedDBKey key;
269 cursor.continueFunction(null_key_, new MockContinueCallbacks(&key));
270 EXPECT_EQ(0, key.number());
271
272 // IDBCursor.advance(1)
273 cursor.advance(1, new MockContinueCallbacks(&key));
274 EXPECT_EQ(1, key.number());
275
276 // IDBCursor.continue()
277 cursor.continueFunction(null_key_, new MockContinueCallbacks(&key));
278 EXPECT_EQ(2, key.number());
279
280 // IDBCursor.advance(2)
281 cursor.advance(2, new MockContinueCallbacks(&key));
282 EXPECT_EQ(4, key.number());
283
284 EXPECT_EQ(0, dispatcher_->advance_calls());
285
286 // IDBCursor.advance(lots) - beyond the fetched amount
287 cursor.advance(WebIDBCursorImpl::kMaxPrefetchAmount,
288 new MockContinueCallbacks(&key));
289 EXPECT_EQ(1, dispatcher_->advance_calls());
290 EXPECT_EQ(1, dispatcher_->prefetch_calls());
291 EXPECT_EQ(static_cast<int>(WebIDBCursorImpl::kPrefetchContinueThreshold),
292 dispatcher_->continue_calls());
293 }
294
295 TEST_F(WebIDBCursorImplTest, PrefetchReset) {
296 const int64_t transaction_id = 1;
297 WebIDBCursorImpl cursor(WebIDBCursorImpl::kInvalidCursorId,
298 transaction_id,
299 thread_safe_sender_.get());
300
301 // Call continue() until prefetching should kick in.
302 int continue_calls = 0;
303 EXPECT_EQ(dispatcher_->continue_calls(), 0);
304 for (int i = 0; i < WebIDBCursorImpl::kPrefetchContinueThreshold; ++i) {
305 cursor.continueFunction(null_key_, new MockContinueCallbacks());
306 EXPECT_EQ(++continue_calls, dispatcher_->continue_calls());
307 EXPECT_EQ(0, dispatcher_->prefetch_calls());
308 }
309
310 // Initiate the prefetch
311 cursor.continueFunction(null_key_, new MockContinueCallbacks());
312 EXPECT_EQ(continue_calls, dispatcher_->continue_calls());
313 EXPECT_EQ(1, dispatcher_->prefetch_calls());
314 EXPECT_EQ(0, dispatcher_->reset_calls());
315
316 // Now invalidate it
317 cursor.ResetPrefetchCache();
318
319 // No reset should have been sent since nothing has been received yet.
320 EXPECT_EQ(0, dispatcher_->reset_calls());
321
322 // Fill the prefetch cache as requested.
323 int prefetch_count = dispatcher_->last_prefetch_count();
324 std::vector<IndexedDBKey> keys(prefetch_count);
325 std::vector<IndexedDBKey> primary_keys(prefetch_count);
326 std::vector<WebIDBValue> values(prefetch_count);
327 cursor.SetPrefetchData(keys, primary_keys, values);
328
329 // No reset should have been sent since prefetch data hasn't been used.
330 EXPECT_EQ(0, dispatcher_->reset_calls());
331
332 // The real dispatcher would call cursor->CachedContinue(), so do that:
333 MockContinueCallbacks callbacks;
334 cursor.CachedContinue(&callbacks);
335
336 // Now the cursor should have reset the rest of the cache.
337 EXPECT_EQ(1, dispatcher_->reset_calls());
338 EXPECT_EQ(1, dispatcher_->last_used_count());
339 }
340
341 } // namespace content
OLDNEW
« no previous file with comments | « content/child/indexed_db/webidbcursor_impl.cc ('k') | content/child/indexed_db/webidbdatabase_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698