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

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

Issue 2449953008: Port messages sent by WebIDBDatabaseImpl to Mojo. (Closed)
Patch Set: Address more comments from dcheng@. Created 4 years, 1 month 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/indexed_db_dispatcher.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9
10 #include <memory>
11
12 #include "base/macros.h"
13 #include "base/single_thread_task_runner.h"
14 #include "base/threading/thread_task_runner_handle.h"
15 #include "base/values.h"
16 #include "content/child/indexed_db/mock_webidbcallbacks.h"
17 #include "content/child/indexed_db/webidbcursor_impl.h"
18 #include "content/child/thread_safe_sender.h"
19 #include "content/common/indexed_db/indexed_db_key.h"
20 #include "content/common/indexed_db/indexed_db_key_range.h"
21 #include "content/common/indexed_db/indexed_db_messages.h"
22 #include "ipc/ipc_sync_message_filter.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "third_party/WebKit/public/platform/WebBlobInfo.h"
25 #include "third_party/WebKit/public/platform/WebData.h"
26 #include "third_party/WebKit/public/web/WebHeap.h"
27
28 using blink::WebBlobInfo;
29 using blink::WebData;
30 using blink::WebIDBCursor;
31 using blink::WebIDBKey;
32 using blink::WebVector;
33 using testing::_;
34 using testing::Invoke;
35 using testing::StrictMock;
36 using testing::WithArgs;
37
38 namespace content {
39 namespace {
40
41 class MockDispatcher : public IndexedDBDispatcher {
42 public:
43 explicit MockDispatcher(ThreadSafeSender* sender)
44 : IndexedDBDispatcher(sender) {}
45
46 bool Send(IPC::Message* msg) override {
47 delete msg;
48 return true;
49 }
50
51 private:
52 DISALLOW_COPY_AND_ASSIGN(MockDispatcher);
53 };
54
55 class MockSyncMessageFilter : public IPC::SyncMessageFilter {
56 public:
57 MockSyncMessageFilter() : SyncMessageFilter(nullptr) {}
58
59 private:
60 ~MockSyncMessageFilter() override {}
61 };
62
63 } // namespace
64
65 class IndexedDBDispatcherTest : public testing::Test {
66 public:
67 IndexedDBDispatcherTest()
68 : thread_safe_sender_(new ThreadSafeSender(
69 base::ThreadTaskRunnerHandle::Get(), new MockSyncMessageFilter)) {}
70
71 void TearDown() override { blink::WebHeap::collectAllGarbageForTesting(); }
72
73 protected:
74 base::MessageLoop message_loop_;
75 scoped_refptr<ThreadSafeSender> thread_safe_sender_;
76
77 private:
78 DISALLOW_COPY_AND_ASSIGN(IndexedDBDispatcherTest);
79 };
80
81 TEST_F(IndexedDBDispatcherTest, ValueSizeTest) {
82 // For testing use a much smaller maximum size to prevent allocating >100 MB
83 // of memory, which crashes on memory-constrained systems.
84 const size_t kMaxValueSizeForTesting = 10 * 1024 * 1024; // 10 MB
85
86 const std::vector<char> data(kMaxValueSizeForTesting + 1);
87 const WebData value(&data.front(), data.size());
88 const WebVector<WebBlobInfo> web_blob_info;
89 const int32_t ipc_dummy_id = -1;
90 const int64_t transaction_id = 1;
91 const int64_t object_store_id = 2;
92
93 StrictMock<MockWebIDBCallbacks> callbacks;
94 EXPECT_CALL(callbacks, onError(_)).Times(1);
95
96 IndexedDBDispatcher dispatcher(thread_safe_sender_.get());
97 dispatcher.max_put_value_size_ = kMaxValueSizeForTesting;
98 IndexedDBKey key(0, blink::WebIDBKeyTypeNumber);
99 dispatcher.RequestIDBDatabasePut(ipc_dummy_id,
100 transaction_id,
101 object_store_id,
102 value,
103 web_blob_info,
104 key,
105 blink::WebIDBPutModeAddOrUpdate,
106 &callbacks,
107 WebVector<long long>(),
108 WebVector<WebVector<WebIDBKey> >());
109 }
110
111 TEST_F(IndexedDBDispatcherTest, KeyAndValueSizeTest) {
112 // For testing use a much smaller maximum size to prevent allocating >100 MB
113 // of memory, which crashes on memory-constrained systems.
114 const size_t kMaxValueSizeForTesting = 10 * 1024 * 1024; // 10 MB
115 const size_t kKeySize = 1024 * 1024;
116
117 const std::vector<char> data(kMaxValueSizeForTesting - kKeySize);
118 const WebData value(&data.front(), data.size());
119 const WebVector<WebBlobInfo> web_blob_info;
120 const IndexedDBKey key(
121 base::string16(kKeySize / sizeof(base::string16::value_type), 'x'));
122
123 const int32_t ipc_dummy_id = -1;
124 const int64_t transaction_id = 1;
125 const int64_t object_store_id = 2;
126
127 StrictMock<MockWebIDBCallbacks> callbacks;
128 EXPECT_CALL(callbacks, onError(_)).Times(1);
129
130 IndexedDBDispatcher dispatcher(thread_safe_sender_.get());
131 dispatcher.max_put_value_size_ = kMaxValueSizeForTesting;
132 dispatcher.RequestIDBDatabasePut(ipc_dummy_id,
133 transaction_id,
134 object_store_id,
135 value,
136 web_blob_info,
137 key,
138 blink::WebIDBPutModeAddOrUpdate,
139 &callbacks,
140 WebVector<long long>(),
141 WebVector<WebVector<WebIDBKey> >());
142 }
143
144 TEST_F(IndexedDBDispatcherTest, CursorTransactionId) {
145 const int32_t ipc_database_id = -1;
146 const int64_t transaction_id = 1234;
147 const int64_t object_store_id = 2;
148 const int32_t index_id = 3;
149 const blink::WebIDBCursorDirection direction =
150 blink::WebIDBCursorDirectionNext;
151 const bool key_only = false;
152
153 MockDispatcher dispatcher(thread_safe_sender_.get());
154
155 // First case: successful cursor open.
156 {
157 std::unique_ptr<WebIDBCursor> cursor;
158 EXPECT_EQ(0UL, dispatcher.cursor_transaction_ids_.size());
159
160 auto* callbacks = new StrictMock<MockWebIDBCallbacks>();
161 // Reference first param (cursor) to keep it alive.
162 // TODO(cmumford): Cleanup (and below) once std::addressof() is allowed.
163 ON_CALL(*callbacks, onSuccess(testing::A<WebIDBCursor*>(), _, _, _))
164 .WillByDefault(
165 WithArgs<0>(Invoke(&cursor.operator=(nullptr),
166 &std::unique_ptr<WebIDBCursor>::reset)));
167 EXPECT_CALL(*callbacks, onSuccess(testing::A<WebIDBCursor*>(), _, _, _))
168 .Times(1);
169
170 // Make a cursor request. This should record the transaction id.
171 dispatcher.RequestIDBDatabaseOpenCursor(
172 ipc_database_id, transaction_id, object_store_id, index_id,
173 IndexedDBKeyRange(), direction, key_only, blink::WebIDBTaskTypeNormal,
174 callbacks);
175
176 // Verify that the transaction id was captured.
177 EXPECT_EQ(1UL, dispatcher.cursor_transaction_ids_.size());
178 EXPECT_FALSE(cursor.get());
179
180 int32_t ipc_callbacks_id =
181 dispatcher.cursor_transaction_ids_.begin()->first;
182
183 IndexedDBMsg_CallbacksSuccessIDBCursor_Params params;
184 params.ipc_thread_id = dispatcher.CurrentWorkerId();
185 params.ipc_callbacks_id = ipc_callbacks_id;
186
187 // Now simululate the cursor response.
188 params.ipc_cursor_id = WebIDBCursorImpl::kInvalidCursorId;
189 dispatcher.OnSuccessOpenCursor(params);
190
191 EXPECT_EQ(0UL, dispatcher.cursor_transaction_ids_.size());
192
193 EXPECT_TRUE(cursor.get());
194
195 WebIDBCursorImpl* impl = static_cast<WebIDBCursorImpl*>(cursor.get());
196
197 // This is the primary expectation of this test: the transaction id was
198 // applied to the cursor.
199 EXPECT_EQ(transaction_id, impl->transaction_id());
200 }
201
202 // Second case: null cursor (no data in range)
203 {
204 EXPECT_EQ(0UL, dispatcher.cursor_transaction_ids_.size());
205
206 auto* callbacks = new StrictMock<MockWebIDBCallbacks>();
207 EXPECT_CALL(*callbacks, onSuccess(testing::A<const blink::WebIDBValue&>()))
208 .Times(1);
209
210 // Make a cursor request. This should record the transaction id.
211 dispatcher.RequestIDBDatabaseOpenCursor(
212 ipc_database_id, transaction_id, object_store_id, index_id,
213 IndexedDBKeyRange(), direction, key_only, blink::WebIDBTaskTypeNormal,
214 callbacks);
215
216 // Verify that the transaction id was captured.
217 EXPECT_EQ(1UL, dispatcher.cursor_transaction_ids_.size());
218
219 int32_t ipc_callbacks_id =
220 dispatcher.cursor_transaction_ids_.begin()->first;
221
222 // Now simululate a "null cursor" response.
223 IndexedDBMsg_CallbacksSuccessValue_Params params;
224 params.ipc_thread_id = dispatcher.CurrentWorkerId();
225 params.ipc_callbacks_id = ipc_callbacks_id;
226 dispatcher.OnSuccessValue(params);
227
228 // Ensure the map result was deleted.
229 EXPECT_EQ(0UL, dispatcher.cursor_transaction_ids_.size());
230 }
231 }
232
233 namespace {
234
235 class MockCursor : public WebIDBCursorImpl {
236 public:
237 MockCursor(int32_t ipc_cursor_id,
238 int64_t transaction_id,
239 ThreadSafeSender* thread_safe_sender)
240 : WebIDBCursorImpl(ipc_cursor_id, transaction_id, thread_safe_sender),
241 reset_count_(0) {}
242
243 // This method is virtual so it can be overridden in unit tests.
244 void ResetPrefetchCache() override { ++reset_count_; }
245
246 int reset_count() const { return reset_count_; }
247
248 private:
249 int reset_count_;
250
251 DISALLOW_COPY_AND_ASSIGN(MockCursor);
252 };
253
254 } // namespace
255
256 TEST_F(IndexedDBDispatcherTest, CursorReset) {
257 std::unique_ptr<WebIDBCursor> cursor;
258 MockDispatcher dispatcher(thread_safe_sender_.get());
259
260 const int32_t ipc_database_id = 0;
261 const int32_t object_store_id = 0;
262 const int32_t index_id = 0;
263 const bool key_only = false;
264 const int cursor1_ipc_id = 1;
265 const int cursor2_ipc_id = 2;
266 const int other_cursor_ipc_id = 2;
267 const int cursor1_transaction_id = 1;
268 const int cursor2_transaction_id = 2;
269 const int other_transaction_id = 3;
270
271 std::unique_ptr<MockCursor> cursor1(
272 new MockCursor(WebIDBCursorImpl::kInvalidCursorId, cursor1_transaction_id,
273 thread_safe_sender_.get()));
274
275 std::unique_ptr<MockCursor> cursor2(
276 new MockCursor(WebIDBCursorImpl::kInvalidCursorId, cursor2_transaction_id,
277 thread_safe_sender_.get()));
278
279 dispatcher.cursors_[cursor1_ipc_id] = cursor1.get();
280 dispatcher.cursors_[cursor2_ipc_id] = cursor2.get();
281
282 EXPECT_EQ(0, cursor1->reset_count());
283 EXPECT_EQ(0, cursor2->reset_count());
284
285 // Other transaction:
286 dispatcher.RequestIDBDatabaseGet(
287 ipc_database_id, other_transaction_id, object_store_id, index_id,
288 IndexedDBKeyRange(), key_only, new StrictMock<MockWebIDBCallbacks>());
289
290 EXPECT_EQ(0, cursor1->reset_count());
291 EXPECT_EQ(0, cursor2->reset_count());
292
293 // Same transaction:
294 dispatcher.RequestIDBDatabaseGet(
295 ipc_database_id, cursor1_transaction_id, object_store_id, index_id,
296 IndexedDBKeyRange(), key_only, new StrictMock<MockWebIDBCallbacks>());
297
298 EXPECT_EQ(1, cursor1->reset_count());
299 EXPECT_EQ(0, cursor2->reset_count());
300
301 // Same transaction and same cursor:
302 dispatcher.RequestIDBCursorContinue(IndexedDBKey(), IndexedDBKey(),
303 new StrictMock<MockWebIDBCallbacks>(),
304 cursor1_ipc_id, cursor1_transaction_id);
305
306 EXPECT_EQ(1, cursor1->reset_count());
307 EXPECT_EQ(0, cursor2->reset_count());
308
309 // Same transaction and different cursor:
310 dispatcher.RequestIDBCursorContinue(
311 IndexedDBKey(), IndexedDBKey(), new StrictMock<MockWebIDBCallbacks>(),
312 other_cursor_ipc_id, cursor1_transaction_id);
313
314 EXPECT_EQ(2, cursor1->reset_count());
315 EXPECT_EQ(0, cursor2->reset_count());
316
317 cursor1.reset();
318 cursor2.reset();
319 }
320
321 } // namespace content
OLDNEW
« no previous file with comments | « content/child/indexed_db/indexed_db_dispatcher.cc ('k') | content/child/indexed_db/webidbdatabase_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698