• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 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 <algorithm>
6 #include "android_webview/browser/global_tile_manager.h"
7 #include "android_webview/browser/global_tile_manager_client.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 
10 namespace {
11 // This should be the same as the one defined global_tile_manager.cc
12 const size_t kNumTilesLimit = 450;
13 const size_t kDefaultNumTiles = 150;
14 
15 }  // namespace
16 
17 using android_webview::GlobalTileManager;
18 using android_webview::GlobalTileManagerClient;
19 using testing::Test;
20 
21 class MockGlobalTileManagerClient : public GlobalTileManagerClient {
22  public:
GetNumTiles() const23   virtual size_t GetNumTiles() const OVERRIDE { return num_tiles_; }
SetNumTiles(size_t num_tiles,bool effective_immediately)24   virtual void SetNumTiles(size_t num_tiles,
25                            bool effective_immediately) OVERRIDE {
26     num_tiles_ = num_tiles;
27   }
28 
MockGlobalTileManagerClient()29   MockGlobalTileManagerClient() {
30     num_tiles_ = 0;
31     tile_request_ = kDefaultNumTiles;
32     key_ = GlobalTileManager::GetInstance()->PushBack(this);
33   }
34 
~MockGlobalTileManagerClient()35   virtual ~MockGlobalTileManagerClient() {
36     GlobalTileManager::GetInstance()->Remove(key_);
37   }
38 
GetTileRequest()39   size_t GetTileRequest() { return tile_request_; }
GetKey()40   GlobalTileManager::Key GetKey() { return key_; }
41 
42  private:
43   size_t num_tiles_;
44   size_t tile_request_;
45   GlobalTileManager::Key key_;
46 };
47 
48 class GlobalTileManagerTest : public Test {
49  public:
SetUp()50   virtual void SetUp() {}
51 
manager()52   GlobalTileManager* manager() { return GlobalTileManager::GetInstance(); }
53 };
54 
TEST_F(GlobalTileManagerTest,RequestTilesUnderLimit)55 TEST_F(GlobalTileManagerTest, RequestTilesUnderLimit) {
56   MockGlobalTileManagerClient clients[2];
57 
58   for (size_t i = 0; i < 2; i++) {
59     manager()->RequestTiles(clients[i].GetTileRequest(), clients[i].GetKey());
60     manager()->DidUse(clients[i].GetKey());
61 
62     // Ensure clients get what they asked for when the manager is under tile
63     // limit.
64     EXPECT_EQ(clients[i].GetNumTiles(), kDefaultNumTiles);
65   }
66 }
67 
TEST_F(GlobalTileManagerTest,EvictHappensWhenOverLimit)68 TEST_F(GlobalTileManagerTest, EvictHappensWhenOverLimit) {
69   MockGlobalTileManagerClient clients[4];
70 
71   for (size_t i = 0; i < 4; i++) {
72     manager()->RequestTiles(clients[i].GetTileRequest(), clients[i].GetKey());
73     manager()->DidUse(clients[i].GetKey());
74   }
75 
76   size_t total_tiles = 0;
77   for (size_t i = 0; i < 4; i++) {
78     total_tiles += clients[i].GetNumTiles();
79   }
80 
81   // Ensure that eviction happened and kept the total number of tiles within
82   // kNumTilesLimit.
83   EXPECT_LE(total_tiles, kNumTilesLimit);
84 }
85 
TEST_F(GlobalTileManagerTest,RandomizedStressRequests)86 TEST_F(GlobalTileManagerTest, RandomizedStressRequests) {
87   MockGlobalTileManagerClient clients[100];
88   size_t index[100];
89   for (size_t i = 0; i < 100; i++) {
90     index[i] = i;
91   }
92 
93   // Fix the seed so that tests are reproducible.
94   std::srand(1);
95   // Simulate a random request order of clients.
96   std::random_shuffle(&index[0], &index[99]);
97 
98   for (size_t i = 0; i < 100; i++) {
99     size_t j = index[i];
100     manager()->RequestTiles(clients[j].GetTileRequest(), clients[j].GetKey());
101     manager()->DidUse(clients[j].GetKey());
102   }
103 
104   size_t total_tiles = 0;
105   for (size_t i = 0; i < 100; i++) {
106     total_tiles += clients[i].GetNumTiles();
107   }
108 
109   // Ensure that eviction happened and kept the total number of tiles within
110   // kNumTilesLimit.
111   EXPECT_LE(total_tiles, kNumTilesLimit);
112 }
113 
TEST_F(GlobalTileManagerTest,FixedOrderedRequests)114 TEST_F(GlobalTileManagerTest, FixedOrderedRequests) {
115   MockGlobalTileManagerClient clients[10];
116 
117   // 10 clients requesting resources in a fixed order. Do that for 5 rounds.
118   for (int round = 0; round < 5; round++) {
119     for (size_t i = 0; i < 10; i++) {
120       manager()->RequestTiles(clients[i].GetTileRequest(), clients[i].GetKey());
121       manager()->DidUse(clients[i].GetKey());
122     }
123   }
124 
125   // Ensure that the total tiles are divided evenly among all clients.
126   for (size_t i = 0; i < 10; i++) {
127     EXPECT_EQ(clients[i].GetNumTiles(), kNumTilesLimit / 10);
128   }
129 }
130 
TEST_F(GlobalTileManagerTest,FixedOrderedRequestsWithInactiveClients)131 TEST_F(GlobalTileManagerTest, FixedOrderedRequestsWithInactiveClients) {
132   MockGlobalTileManagerClient clients[20];
133 
134   // 20 clients request resources.
135   for (size_t i = 0; i < 20; i++) {
136     manager()->RequestTiles(clients[i].GetTileRequest(), clients[i].GetKey());
137     manager()->DidUse(clients[i].GetKey());
138   }
139 
140   // Now the last 10 clients become inactive. Only the first 10 clients remain
141   // active resource requesters.
142   // 10 clients requesting resources in a fixed order. Do that for 5 rounds.
143   for (int round = 0; round < 5; round++) {
144     for (size_t i = 0; i < 10; i++) {
145       manager()->RequestTiles(clients[i].GetTileRequest(), clients[i].GetKey());
146       manager()->DidUse(clients[i].GetKey());
147     }
148   }
149 
150   // Ensure that the total tiles are divided evenly among all clients.
151   for (size_t i = 0; i < 10; i++) {
152     EXPECT_EQ(clients[i].GetNumTiles(), kNumTilesLimit / 10);
153   }
154 
155   // Ensure that the inactive tiles are evicted.
156   for (size_t i = 11; i < 20; i++) {
157     EXPECT_EQ(clients[i].GetNumTiles(), 0u);
158   }
159 }
160