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