1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
|
// 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 content::SynchronousCompositorMemoryPolicy;
using testing::Test;
class MockGlobalTileManagerClient : public GlobalTileManagerClient {
public:
virtual SynchronousCompositorMemoryPolicy GetMemoryPolicy() const OVERRIDE {
return memory_policy_;
}
virtual void SetMemoryPolicy(SynchronousCompositorMemoryPolicy new_policy,
bool effective_immediately) OVERRIDE {
memory_policy_ = new_policy;
}
MockGlobalTileManagerClient() {
tile_request_.num_resources_limit = kDefaultNumTiles;
key_ = GlobalTileManager::GetInstance()->PushBack(this);
}
virtual ~MockGlobalTileManagerClient() {
GlobalTileManager::GetInstance()->Remove(key_);
}
SynchronousCompositorMemoryPolicy GetTileRequest() { return tile_request_; }
GlobalTileManager::Key GetKey() { return key_; }
private:
SynchronousCompositorMemoryPolicy memory_policy_;
SynchronousCompositorMemoryPolicy 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].GetMemoryPolicy().num_resources_limit,
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].GetMemoryPolicy().num_resources_limit;
}
// 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;
}
// Fix the seed so that tests are reproducible.
std::srand(1);
// 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].GetMemoryPolicy().num_resources_limit;
}
// 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].GetMemoryPolicy().num_resources_limit,
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].GetMemoryPolicy().num_resources_limit,
kNumTilesLimit / 10);
}
// Ensure that the inactive tiles are evicted.
for (size_t i = 11; i < 20; i++) {
EXPECT_EQ(clients[i].GetMemoryPolicy().num_resources_limit, 0u);
}
}
|