Index: android_webview/browser/global_tile_manager_unittest.cc |
diff --git a/android_webview/browser/global_tile_manager_unittest.cc b/android_webview/browser/global_tile_manager_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9f090842f033b08992b80bcc5e44f5ece59fb618 |
--- /dev/null |
+++ b/android_webview/browser/global_tile_manager_unittest.cc |
@@ -0,0 +1,157 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include <algorithm> |
+#include "android_webview/browser/global_tile_manager.h" |
+#include "android_webview/browser/global_tile_manager_client.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace { |
+// This should be the same as the one defined global_tile_manager.cc |
+const size_t kNumTilesLimit = 450; |
+const size_t kDefaultNumTiles = 150; |
+ |
+} // namespace |
+ |
+using android_webview::GlobalTileManager; |
+using android_webview::GlobalTileManagerClient; |
+using testing::Test; |
+ |
+class MockGlobalTileManagerClient : public GlobalTileManagerClient { |
+ public: |
+ virtual size_t GetNumTiles() const OVERRIDE { return num_tiles_; } |
+ virtual void SetNumTiles(size_t num_tiles, |
+ bool effective_immediately) OVERRIDE { |
+ num_tiles_ = num_tiles; |
+ } |
+ |
+ MockGlobalTileManagerClient() { |
+ num_tiles_ = 0; |
+ tile_request_ = kDefaultNumTiles; |
+ key_ = GlobalTileManager::GetInstance()->PushBack(this); |
+ } |
+ |
+ virtual ~MockGlobalTileManagerClient() { |
+ GlobalTileManager::GetInstance()->Remove(key_); |
+ } |
+ |
+ size_t GetTileRequest() { return tile_request_; } |
+ GlobalTileManager::Key GetKey() { return key_; } |
+ |
+ private: |
+ size_t num_tiles_; |
+ size_t tile_request_; |
+ GlobalTileManager::Key key_; |
+}; |
+ |
+class GlobalTileManagerTest : public Test { |
+ public: |
+ virtual void SetUp() {} |
+ |
+ GlobalTileManager* manager() { return GlobalTileManager::GetInstance(); } |
+}; |
+ |
+TEST_F(GlobalTileManagerTest, RequestTilesUnderLimit) { |
+ MockGlobalTileManagerClient clients[2]; |
+ |
+ for (size_t i = 0; i < 2; i++) { |
+ manager()->RequestTiles(clients[i].GetTileRequest(), clients[i].GetKey()); |
+ manager()->DidUse(clients[i].GetKey()); |
+ |
+ // Ensure clients get what they asked for when the manager is under tile |
+ // limit. |
+ EXPECT_EQ(clients[i].GetNumTiles(), kDefaultNumTiles); |
+ } |
+} |
+ |
+TEST_F(GlobalTileManagerTest, EvictHappensWhenOverLimit) { |
+ MockGlobalTileManagerClient clients[4]; |
+ |
+ for (size_t i = 0; i < 4; i++) { |
+ manager()->RequestTiles(clients[i].GetTileRequest(), clients[i].GetKey()); |
+ manager()->DidUse(clients[i].GetKey()); |
+ } |
+ |
+ size_t total_tiles = 0; |
+ for (size_t i = 0; i < 4; i++) { |
+ total_tiles += clients[i].GetNumTiles(); |
+ } |
+ |
+ // Ensure that eviction happened and kept the total number of tiles within |
+ // kNumTilesLimit. |
+ EXPECT_LE(total_tiles, kNumTilesLimit); |
+} |
+ |
+TEST_F(GlobalTileManagerTest, RandomizedStressRequests) { |
+ MockGlobalTileManagerClient clients[100]; |
+ size_t index[100]; |
+ for (size_t i = 0; i < 100; i++) { |
+ index[i] = i; |
+ } |
+ |
+ // Simulate a random request order of clients. |
+ std::random_shuffle(&index[0], &index[99]); |
+ |
+ for (size_t i = 0; i < 100; i++) { |
+ size_t j = index[i]; |
+ manager()->RequestTiles(clients[j].GetTileRequest(), clients[j].GetKey()); |
+ manager()->DidUse(clients[j].GetKey()); |
+ } |
+ |
+ size_t total_tiles = 0; |
+ for (size_t i = 0; i < 100; i++) { |
+ total_tiles += clients[i].GetNumTiles(); |
+ } |
+ |
+ // Ensure that eviction happened and kept the total number of tiles within |
+ // kNumTilesLimit. |
+ EXPECT_LE(total_tiles, kNumTilesLimit); |
+} |
+ |
+TEST_F(GlobalTileManagerTest, FixedOrderedRequests) { |
+ MockGlobalTileManagerClient clients[10]; |
+ |
+ // 10 clients requesting resources in a fixed order. Do that for 5 rounds. |
+ for (int round = 0; round < 5; round++) { |
+ for (size_t i = 0; i < 10; i++) { |
+ manager()->RequestTiles(clients[i].GetTileRequest(), clients[i].GetKey()); |
+ manager()->DidUse(clients[i].GetKey()); |
+ } |
+ } |
+ |
+ // Ensure that the total tiles are divided evenly among all clients. |
+ for (size_t i = 0; i < 10; i++) { |
+ EXPECT_EQ(clients[i].GetNumTiles(), kNumTilesLimit / 10); |
+ } |
+} |
+ |
+TEST_F(GlobalTileManagerTest, FixedOrderedRequestsWithInactiveClients) { |
+ MockGlobalTileManagerClient clients[20]; |
+ |
+ // 20 clients request resources. |
+ for (size_t i = 0; i < 20; i++) { |
+ manager()->RequestTiles(clients[i].GetTileRequest(), clients[i].GetKey()); |
+ manager()->DidUse(clients[i].GetKey()); |
+ } |
+ |
+ // Now the last 10 clients become inactive. Only the first 10 clients remain |
+ // active resource requesters. |
+ // 10 clients requesting resources in a fixed order. Do that for 5 rounds. |
+ for (int round = 0; round < 5; round++) { |
+ for (size_t i = 0; i < 10; i++) { |
+ manager()->RequestTiles(clients[i].GetTileRequest(), clients[i].GetKey()); |
+ manager()->DidUse(clients[i].GetKey()); |
+ } |
+ } |
+ |
+ // Ensure that the total tiles are divided evenly among all clients. |
+ for (size_t i = 0; i < 10; i++) { |
+ EXPECT_EQ(clients[i].GetNumTiles(), kNumTilesLimit / 10); |
+ } |
+ |
+ // Ensure that the inactive tiles are evicted. |
+ for (size_t i = 11; i < 20; i++) { |
+ EXPECT_EQ(clients[i].GetNumTiles(), 0u); |
+ } |
+} |