| 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 |