Process Alt-Svc headers.
[chromium-blink-merge.git] / content / child / indexed_db / webidbcursor_impl_unittest.cc
bloba21babd8b8c20e063eaa3819dfd319bf0bff25d8
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.
5 #include "base/memory/scoped_ptr.h"
6 #include "base/thread_task_runner_handle.h"
7 #include "base/values.h"
8 #include "content/child/indexed_db/indexed_db_dispatcher.h"
9 #include "content/child/indexed_db/indexed_db_key_builders.h"
10 #include "content/child/indexed_db/webidbcursor_impl.h"
11 #include "content/child/thread_safe_sender.h"
12 #include "content/common/indexed_db/indexed_db_key.h"
13 #include "ipc/ipc_sync_message_filter.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "third_party/WebKit/public/platform/WebData.h"
16 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBCallbacks.h"
18 using blink::WebBlobInfo;
19 using blink::WebData;
20 using blink::WebIDBCallbacks;
21 using blink::WebIDBDatabase;
22 using blink::WebIDBKey;
23 using blink::WebIDBKeyTypeNumber;
24 using blink::WebVector;
26 namespace content {
28 namespace {
30 class MockDispatcher : public IndexedDBDispatcher {
31 public:
32 explicit MockDispatcher(ThreadSafeSender* thread_safe_sender)
33 : IndexedDBDispatcher(thread_safe_sender),
34 prefetch_calls_(0),
35 last_prefetch_count_(0),
36 reset_calls_(0),
37 last_used_count_(0),
38 advance_calls_(0),
39 continue_calls_(0),
40 destroyed_cursor_id_(0) {}
42 void RequestIDBCursorPrefetch(int n,
43 WebIDBCallbacks* callbacks,
44 int32 ipc_cursor_id) override {
45 ++prefetch_calls_;
46 last_prefetch_count_ = n;
47 callbacks_.reset(callbacks);
50 void RequestIDBCursorPrefetchReset(int used_prefetches,
51 int unused_prefetches,
52 int32 ipc_cursor_id) override {
53 ++reset_calls_;
54 last_used_count_ = used_prefetches;
57 void RequestIDBCursorAdvance(unsigned long count,
58 WebIDBCallbacks* callbacks,
59 int32 ipc_cursor_id,
60 int64 transaction_id) override {
61 ++advance_calls_;
62 callbacks_.reset(callbacks);
65 void RequestIDBCursorContinue(const IndexedDBKey& key,
66 const IndexedDBKey& primary_key,
67 WebIDBCallbacks* callbacks,
68 int32 ipc_cursor_id,
69 int64 transaction_id) override {
70 ++continue_calls_;
71 callbacks_.reset(callbacks);
74 void CursorDestroyed(int32 ipc_cursor_id) override {
75 destroyed_cursor_id_ = ipc_cursor_id;
78 int prefetch_calls() { return prefetch_calls_; }
79 int last_prefetch_count() { return last_prefetch_count_; }
80 int reset_calls() { return reset_calls_; }
81 int last_used_count() { return last_used_count_; }
82 int advance_calls() { return advance_calls_; }
83 int continue_calls() { return continue_calls_; }
84 int32 destroyed_cursor_id() { return destroyed_cursor_id_; }
86 private:
87 int prefetch_calls_;
88 int last_prefetch_count_;
89 int reset_calls_;
90 int last_used_count_;
91 int advance_calls_;
92 int continue_calls_;
93 int32 destroyed_cursor_id_;
94 scoped_ptr<WebIDBCallbacks> callbacks_;
97 class MockContinueCallbacks : public WebIDBCallbacks {
98 public:
99 MockContinueCallbacks(IndexedDBKey* key = 0,
100 WebVector<WebBlobInfo>* webBlobInfo = 0)
101 : key_(key), web_blob_info_(webBlobInfo) {}
103 void onSuccess(const WebIDBKey& key,
104 const WebIDBKey& primaryKey,
105 const WebData& value,
106 const WebVector<WebBlobInfo>& webBlobInfo) override {
107 if (key_)
108 *key_ = IndexedDBKeyBuilder::Build(key);
109 if (web_blob_info_)
110 *web_blob_info_ = webBlobInfo;
113 private:
114 IndexedDBKey* key_;
115 WebVector<WebBlobInfo>* web_blob_info_;
118 } // namespace
120 class WebIDBCursorImplTest : public testing::Test {
121 public:
122 WebIDBCursorImplTest() {
123 null_key_.assignNull();
124 sync_message_filter_ = new IPC::SyncMessageFilter(NULL);
125 thread_safe_sender_ = new ThreadSafeSender(
126 base::ThreadTaskRunnerHandle::Get(), sync_message_filter_.get());
127 dispatcher_ =
128 make_scoped_ptr(new MockDispatcher(thread_safe_sender_.get()));
131 protected:
132 base::MessageLoop message_loop_;
133 WebIDBKey null_key_;
134 scoped_refptr<ThreadSafeSender> thread_safe_sender_;
135 scoped_ptr<MockDispatcher> dispatcher_;
137 private:
138 scoped_refptr<IPC::SyncMessageFilter> sync_message_filter_;
140 DISALLOW_COPY_AND_ASSIGN(WebIDBCursorImplTest);
143 TEST_F(WebIDBCursorImplTest, PrefetchTest) {
144 const int64 transaction_id = 1;
146 WebIDBCursorImpl cursor(WebIDBCursorImpl::kInvalidCursorId,
147 transaction_id,
148 thread_safe_sender_.get());
150 // Call continue() until prefetching should kick in.
151 int continue_calls = 0;
152 EXPECT_EQ(dispatcher_->continue_calls(), 0);
153 for (int i = 0; i < WebIDBCursorImpl::kPrefetchContinueThreshold; ++i) {
154 cursor.continueFunction(null_key_, new MockContinueCallbacks());
155 EXPECT_EQ(++continue_calls, dispatcher_->continue_calls());
156 EXPECT_EQ(0, dispatcher_->prefetch_calls());
159 // Do enough repetitions to verify that the count grows each time,
160 // but not so many that the maximum limit is hit.
161 const int kPrefetchRepetitions = 5;
163 int expected_key = 0;
164 int last_prefetch_count = 0;
165 for (int repetitions = 0; repetitions < kPrefetchRepetitions;
166 ++repetitions) {
167 // Initiate the prefetch
168 cursor.continueFunction(null_key_, new MockContinueCallbacks());
169 EXPECT_EQ(continue_calls, dispatcher_->continue_calls());
170 EXPECT_EQ(repetitions + 1, dispatcher_->prefetch_calls());
172 // Verify that the requested count has increased since last time.
173 int prefetch_count = dispatcher_->last_prefetch_count();
174 EXPECT_GT(prefetch_count, last_prefetch_count);
175 last_prefetch_count = prefetch_count;
177 // Fill the prefetch cache as requested.
178 std::vector<IndexedDBKey> keys;
179 std::vector<IndexedDBKey> primary_keys(prefetch_count);
180 std::vector<WebData> values(prefetch_count);
181 std::vector<WebVector<WebBlobInfo> > blob_info;
182 for (int i = 0; i < prefetch_count; ++i) {
183 keys.push_back(IndexedDBKey(expected_key + i, WebIDBKeyTypeNumber));
184 blob_info.push_back(
185 WebVector<WebBlobInfo>(static_cast<size_t>(expected_key + i)));
187 cursor.SetPrefetchData(keys, primary_keys, values, blob_info);
189 // Note that the real dispatcher would call cursor->CachedContinue()
190 // immediately after cursor->SetPrefetchData() to service the request
191 // that initiated the prefetch.
193 // Verify that the cache is used for subsequent continue() calls.
194 for (int i = 0; i < prefetch_count; ++i) {
195 IndexedDBKey key;
196 WebVector<WebBlobInfo> web_blob_info;
197 cursor.continueFunction(
198 null_key_, new MockContinueCallbacks(&key, &web_blob_info));
199 EXPECT_EQ(continue_calls, dispatcher_->continue_calls());
200 EXPECT_EQ(repetitions + 1, dispatcher_->prefetch_calls());
202 EXPECT_EQ(WebIDBKeyTypeNumber, key.type());
203 EXPECT_EQ(expected_key, static_cast<int>(web_blob_info.size()));
204 EXPECT_EQ(expected_key++, key.number());
209 EXPECT_EQ(dispatcher_->destroyed_cursor_id(),
210 WebIDBCursorImpl::kInvalidCursorId);
213 TEST_F(WebIDBCursorImplTest, AdvancePrefetchTest) {
214 const int64 transaction_id = 1;
215 WebIDBCursorImpl cursor(WebIDBCursorImpl::kInvalidCursorId,
216 transaction_id,
217 thread_safe_sender_.get());
219 // Call continue() until prefetching should kick in.
220 EXPECT_EQ(0, dispatcher_->continue_calls());
221 for (int i = 0; i < WebIDBCursorImpl::kPrefetchContinueThreshold; ++i) {
222 cursor.continueFunction(null_key_, new MockContinueCallbacks());
224 EXPECT_EQ(0, dispatcher_->prefetch_calls());
226 // Initiate the prefetch
227 cursor.continueFunction(null_key_, new MockContinueCallbacks());
229 EXPECT_EQ(1, dispatcher_->prefetch_calls());
230 EXPECT_EQ(static_cast<int>(WebIDBCursorImpl::kPrefetchContinueThreshold),
231 dispatcher_->continue_calls());
232 EXPECT_EQ(0, dispatcher_->advance_calls());
234 const int prefetch_count = dispatcher_->last_prefetch_count();
236 // Fill the prefetch cache as requested.
237 int expected_key = 0;
238 std::vector<IndexedDBKey> keys;
239 std::vector<IndexedDBKey> primary_keys(prefetch_count);
240 std::vector<WebData> values(prefetch_count);
241 std::vector<WebVector<WebBlobInfo> > blob_info;
242 for (int i = 0; i < prefetch_count; ++i) {
243 keys.push_back(IndexedDBKey(expected_key + i, WebIDBKeyTypeNumber));
244 blob_info.push_back(
245 WebVector<WebBlobInfo>(static_cast<size_t>(expected_key + i)));
247 cursor.SetPrefetchData(keys, primary_keys, values, blob_info);
249 // Note that the real dispatcher would call cursor->CachedContinue()
250 // immediately after cursor->SetPrefetchData() to service the request
251 // that initiated the prefetch.
253 // Need at least this many in the cache for the test steps.
254 ASSERT_GE(prefetch_count, 5);
256 // IDBCursor.continue()
257 IndexedDBKey key;
258 cursor.continueFunction(null_key_, new MockContinueCallbacks(&key));
259 EXPECT_EQ(0, key.number());
261 // IDBCursor.advance(1)
262 cursor.advance(1, new MockContinueCallbacks(&key));
263 EXPECT_EQ(1, key.number());
265 // IDBCursor.continue()
266 cursor.continueFunction(null_key_, new MockContinueCallbacks(&key));
267 EXPECT_EQ(2, key.number());
269 // IDBCursor.advance(2)
270 cursor.advance(2, new MockContinueCallbacks(&key));
271 EXPECT_EQ(4, key.number());
273 EXPECT_EQ(0, dispatcher_->advance_calls());
275 // IDBCursor.advance(lots) - beyond the fetched amount
276 cursor.advance(WebIDBCursorImpl::kMaxPrefetchAmount,
277 new MockContinueCallbacks(&key));
278 EXPECT_EQ(1, dispatcher_->advance_calls());
279 EXPECT_EQ(1, dispatcher_->prefetch_calls());
280 EXPECT_EQ(static_cast<int>(WebIDBCursorImpl::kPrefetchContinueThreshold),
281 dispatcher_->continue_calls());
284 TEST_F(WebIDBCursorImplTest, PrefetchReset) {
285 const int64 transaction_id = 1;
286 WebIDBCursorImpl cursor(WebIDBCursorImpl::kInvalidCursorId,
287 transaction_id,
288 thread_safe_sender_.get());
290 // Call continue() until prefetching should kick in.
291 int continue_calls = 0;
292 EXPECT_EQ(dispatcher_->continue_calls(), 0);
293 for (int i = 0; i < WebIDBCursorImpl::kPrefetchContinueThreshold; ++i) {
294 cursor.continueFunction(null_key_, new MockContinueCallbacks());
295 EXPECT_EQ(++continue_calls, dispatcher_->continue_calls());
296 EXPECT_EQ(0, dispatcher_->prefetch_calls());
299 // Initiate the prefetch
300 cursor.continueFunction(null_key_, new MockContinueCallbacks());
301 EXPECT_EQ(continue_calls, dispatcher_->continue_calls());
302 EXPECT_EQ(1, dispatcher_->prefetch_calls());
303 EXPECT_EQ(0, dispatcher_->reset_calls());
305 // Now invalidate it
306 cursor.ResetPrefetchCache();
308 // No reset should have been sent since nothing has been received yet.
309 EXPECT_EQ(0, dispatcher_->reset_calls());
311 // Fill the prefetch cache as requested.
312 int prefetch_count = dispatcher_->last_prefetch_count();
313 std::vector<IndexedDBKey> keys(prefetch_count);
314 std::vector<IndexedDBKey> primary_keys(prefetch_count);
315 std::vector<WebData> values(prefetch_count);
316 std::vector<WebVector<WebBlobInfo> > blob_info(prefetch_count);
317 cursor.SetPrefetchData(keys, primary_keys, values, blob_info);
319 // No reset should have been sent since prefetch data hasn't been used.
320 EXPECT_EQ(0, dispatcher_->reset_calls());
322 // The real dispatcher would call cursor->CachedContinue(), so do that:
323 scoped_ptr<WebIDBCallbacks> callbacks(new MockContinueCallbacks());
324 cursor.CachedContinue(callbacks.get());
326 // Now the cursor should have reset the rest of the cache.
327 EXPECT_EQ(1, dispatcher_->reset_calls());
328 EXPECT_EQ(1, dispatcher_->last_used_count());
331 } // namespace content