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

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

Powered by Google App Engine
This is Rietveld 408576698