OLD | NEW |
| (Empty) |
1 // Copyright (c) 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 "base/memory/scoped_ptr.h" | |
6 #include "base/values.h" | |
7 #include "content/common/indexed_db/indexed_db_key.h" | |
8 #include "content/common_child/indexed_db/indexed_db_dispatcher.h" | |
9 #include "content/common_child/indexed_db/proxy_webidbcursor_impl.h" | |
10 #include "testing/gtest/include/gtest/gtest.h" | |
11 #include "third_party/WebKit/public/platform/WebData.h" | |
12 #include "third_party/WebKit/public/platform/WebIDBCallbacks.h" | |
13 | |
14 using WebKit::WebData; | |
15 using WebKit::WebIDBCallbacks; | |
16 using WebKit::WebIDBDatabase; | |
17 using WebKit::WebIDBDatabaseError; | |
18 using WebKit::WebIDBKey; | |
19 | |
20 namespace content { | |
21 | |
22 namespace { | |
23 | |
24 class MockDispatcher : public IndexedDBDispatcher { | |
25 public: | |
26 MockDispatcher() | |
27 : prefetch_calls_(0), | |
28 last_prefetch_count_(0), | |
29 continue_calls_(0), | |
30 destroyed_cursor_id_(0) {} | |
31 | |
32 virtual void RequestIDBCursorPrefetch(int n, | |
33 WebIDBCallbacks* callbacks, | |
34 int32 ipc_cursor_id) OVERRIDE { | |
35 ++prefetch_calls_; | |
36 last_prefetch_count_ = n; | |
37 callbacks_.reset(callbacks); | |
38 } | |
39 | |
40 virtual void RequestIDBCursorContinue(const IndexedDBKey&, | |
41 WebIDBCallbacks* callbacks, | |
42 int32 ipc_cursor_id) OVERRIDE { | |
43 ++continue_calls_; | |
44 callbacks_.reset(callbacks); | |
45 } | |
46 | |
47 virtual void CursorDestroyed(int32 ipc_cursor_id) OVERRIDE { | |
48 destroyed_cursor_id_ = ipc_cursor_id; | |
49 } | |
50 | |
51 int prefetch_calls() { return prefetch_calls_; } | |
52 int continue_calls() { return continue_calls_; } | |
53 int last_prefetch_count() { return last_prefetch_count_; } | |
54 int32 destroyed_cursor_id() { return destroyed_cursor_id_; } | |
55 | |
56 private: | |
57 int prefetch_calls_; | |
58 int last_prefetch_count_; | |
59 int continue_calls_; | |
60 int32 destroyed_cursor_id_; | |
61 scoped_ptr<WebIDBCallbacks> callbacks_; | |
62 }; | |
63 | |
64 class MockContinueCallbacks : public WebIDBCallbacks { | |
65 public: | |
66 MockContinueCallbacks(IndexedDBKey* key = 0) : key_(key) {} | |
67 | |
68 virtual void onSuccess(const WebIDBKey& key, | |
69 const WebIDBKey& primaryKey, | |
70 const WebData& value) { | |
71 | |
72 if (key_) | |
73 *key_ = IndexedDBKey(key); | |
74 } | |
75 | |
76 private: | |
77 IndexedDBKey* key_; | |
78 }; | |
79 | |
80 } // namespace | |
81 | |
82 TEST(RendererWebIDBCursorImplTest, PrefetchTest) { | |
83 | |
84 WebIDBKey null_key; | |
85 null_key.assignNull(); | |
86 | |
87 MockDispatcher dispatcher; | |
88 | |
89 { | |
90 RendererWebIDBCursorImpl cursor(RendererWebIDBCursorImpl::kInvalidCursorId); | |
91 | |
92 // Call continue() until prefetching should kick in. | |
93 int continue_calls = 0; | |
94 EXPECT_EQ(dispatcher.continue_calls(), 0); | |
95 for (int i = 0; i < RendererWebIDBCursorImpl::kPrefetchContinueThreshold; | |
96 ++i) { | |
97 cursor.continueFunction(null_key, new MockContinueCallbacks()); | |
98 EXPECT_EQ(++continue_calls, dispatcher.continue_calls()); | |
99 EXPECT_EQ(0, dispatcher.prefetch_calls()); | |
100 } | |
101 | |
102 // Do enough repetitions to verify that the count grows each time, | |
103 // but not so many that the maximum limit is hit. | |
104 const int kPrefetchRepetitions = 5; | |
105 | |
106 int expected_key = 0; | |
107 int last_prefetch_count = 0; | |
108 for (int repetitions = 0; repetitions < kPrefetchRepetitions; | |
109 ++repetitions) { | |
110 | |
111 // Initiate the prefetch | |
112 cursor.continueFunction(null_key, new MockContinueCallbacks()); | |
113 EXPECT_EQ(continue_calls, dispatcher.continue_calls()); | |
114 EXPECT_EQ(repetitions + 1, dispatcher.prefetch_calls()); | |
115 | |
116 // Verify that the requested count has increased since last time. | |
117 int prefetch_count = dispatcher.last_prefetch_count(); | |
118 EXPECT_GT(prefetch_count, last_prefetch_count); | |
119 last_prefetch_count = prefetch_count; | |
120 | |
121 // Fill the prefetch cache as requested. | |
122 std::vector<IndexedDBKey> keys; | |
123 std::vector<IndexedDBKey> primary_keys(prefetch_count); | |
124 std::vector<WebData> values(prefetch_count); | |
125 for (int i = 0; i < prefetch_count; ++i) { | |
126 keys.push_back(IndexedDBKey(expected_key + i, WebIDBKey::NumberType)); | |
127 } | |
128 cursor.SetPrefetchData(keys, primary_keys, values); | |
129 | |
130 // Note that the real dispatcher would call cursor->CachedContinue() | |
131 // immediately after cursor->SetPrefetchData() to service the request | |
132 // that initiated the prefetch. | |
133 | |
134 // Verify that the cache is used for subsequent continue() calls. | |
135 for (int i = 0; i < prefetch_count; ++i) { | |
136 IndexedDBKey key; | |
137 cursor.continueFunction(null_key, new MockContinueCallbacks(&key)); | |
138 EXPECT_EQ(continue_calls, dispatcher.continue_calls()); | |
139 EXPECT_EQ(repetitions + 1, dispatcher.prefetch_calls()); | |
140 | |
141 EXPECT_EQ(WebIDBKey::NumberType, key.type()); | |
142 EXPECT_EQ(expected_key++, key.number()); | |
143 } | |
144 } | |
145 } | |
146 | |
147 EXPECT_EQ(dispatcher.destroyed_cursor_id(), | |
148 RendererWebIDBCursorImpl::kInvalidCursorId); | |
149 } | |
150 | |
151 } // namespace content | |
OLD | NEW |