1 // Copyright 2015 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.
7 #include "base/run_loop.h"
8 #include "content/public/test/test_browser_thread_bundle.h"
9 #include "extensions/browser/deferred_start_render_host.h"
10 #include "extensions/browser/extensions_test.h"
11 #include "extensions/browser/load_monitoring_extension_host_queue.h"
12 #include "extensions/browser/serial_extension_host_queue.h"
14 namespace extensions
{
18 class StubDeferredStartRenderHost
: public DeferredStartRenderHost
{
20 void AddDeferredStartRenderHostObserver(
21 DeferredStartRenderHostObserver
* observer
) override
{}
22 void RemoveDeferredStartRenderHostObserver(
23 DeferredStartRenderHostObserver
* observer
) override
{}
24 void CreateRenderViewNow() override
{}
27 const size_t g_invalid_size_t
= std::numeric_limits
<size_t>::max();
31 class LoadMonitoringExtensionHostQueueTest
: public ExtensionsTest
{
33 LoadMonitoringExtensionHostQueueTest()
35 // Arbitrary choice of an invalid size_t.
36 num_queued_(g_invalid_size_t
),
37 num_loaded_(g_invalid_size_t
),
38 max_in_queue_(g_invalid_size_t
),
39 max_active_loading_(g_invalid_size_t
) {}
41 void SetUp() override
{
42 queue_
.reset(new LoadMonitoringExtensionHostQueue(
43 // Use a SerialExtensionHostQueue because it's simple.
44 scoped_ptr
<ExtensionHostQueue
>(new SerialExtensionHostQueue()),
45 base::TimeDelta(), // no delay, easier to test
46 base::Bind(&LoadMonitoringExtensionHostQueueTest::Finished
,
47 base::Unretained(this))));
51 // Creates a new DeferredStartRenderHost. Ownership is held by this class,
52 // not passed to caller.
53 DeferredStartRenderHost
* CreateHost() {
54 StubDeferredStartRenderHost
* stub
= new StubDeferredStartRenderHost();
55 stubs_
.push_back(stub
);
59 // Our single LoadMonitoringExtensionHostQueue instance.
60 LoadMonitoringExtensionHostQueue
* queue() { return queue_
.get(); }
62 // Returns true if the queue has finished monitoring.
63 bool finished() { return finished_
; }
65 // These are available after the queue has finished (in which case finished()
67 size_t num_queued() { return num_queued_
; }
68 size_t num_loaded() { return num_loaded_
; }
69 size_t max_in_queue() { return max_in_queue_
; }
70 size_t max_active_loading() { return max_active_loading_
; }
73 // Callback when queue has finished monitoring.
74 void Finished(size_t num_queued
,
77 size_t max_active_loading
) {
79 num_queued_
= num_queued
;
80 num_loaded_
= num_loaded
;
81 max_in_queue_
= max_in_queue
;
82 max_active_loading_
= max_active_loading
;
85 content::TestBrowserThreadBundle thread_bundle_
;
86 scoped_ptr
<LoadMonitoringExtensionHostQueue
> queue_
;
87 ScopedVector
<StubDeferredStartRenderHost
> stubs_
;
89 // Set after the queue has finished monitoring.
94 size_t max_active_loading_
;
97 // Tests that if monitoring is never started, nor any hosts added, nothing is
99 TEST_F(LoadMonitoringExtensionHostQueueTest
, NeverStarted
) {
100 base::RunLoop().RunUntilIdle();
101 ASSERT_FALSE(finished());
104 // Tests that if monitoring has started but no hosts added, it's recorded as 0.
105 TEST_F(LoadMonitoringExtensionHostQueueTest
, NoHosts
) {
106 queue()->StartMonitoring();
108 base::RunLoop().RunUntilIdle();
109 ASSERT_TRUE(finished());
110 EXPECT_EQ(0u, num_queued());
111 EXPECT_EQ(0u, num_loaded());
112 EXPECT_EQ(0u, max_in_queue());
113 EXPECT_EQ(0u, max_active_loading());
116 // Tests that adding a host starts monitoring.
117 TEST_F(LoadMonitoringExtensionHostQueueTest
, AddOneHost
) {
118 queue()->Add(CreateHost());
120 base::RunLoop().RunUntilIdle();
121 ASSERT_TRUE(finished());
122 EXPECT_EQ(1u, num_queued());
123 EXPECT_EQ(0u, num_loaded());
124 EXPECT_EQ(1u, max_in_queue());
125 EXPECT_EQ(0u, max_active_loading());
128 // Tests that a host added and removed is still recorded, but not as a load
130 TEST_F(LoadMonitoringExtensionHostQueueTest
, AddAndRemoveOneHost
) {
131 DeferredStartRenderHost
* host
= CreateHost();
133 queue()->Remove(host
);
135 base::RunLoop().RunUntilIdle();
136 ASSERT_TRUE(finished());
137 EXPECT_EQ(1u, num_queued());
138 EXPECT_EQ(0u, num_loaded());
139 EXPECT_EQ(1u, max_in_queue());
140 EXPECT_EQ(0u, max_active_loading());
143 // Tests adding and starting a single host.
144 TEST_F(LoadMonitoringExtensionHostQueueTest
, AddAndStartOneHost
) {
145 DeferredStartRenderHost
* host
= CreateHost();
147 queue()->OnDeferredStartRenderHostDidStartLoading(host
);
149 base::RunLoop().RunUntilIdle();
150 ASSERT_TRUE(finished());
151 EXPECT_EQ(1u, num_queued());
152 EXPECT_EQ(0u, num_loaded());
153 EXPECT_EQ(1u, max_in_queue());
154 EXPECT_EQ(1u, max_active_loading());
156 // Sanity check: stopping/destroying at this point doesn't crash.
157 queue()->OnDeferredStartRenderHostDidStopLoading(host
);
158 queue()->OnDeferredStartRenderHostDestroyed(host
);
161 // Tests adding and destroying a single host without starting it.
162 TEST_F(LoadMonitoringExtensionHostQueueTest
, AddAndDestroyOneHost
) {
163 DeferredStartRenderHost
* host
= CreateHost();
165 queue()->OnDeferredStartRenderHostDestroyed(host
);
167 base::RunLoop().RunUntilIdle();
168 ASSERT_TRUE(finished());
169 EXPECT_EQ(1u, num_queued());
170 EXPECT_EQ(0u, num_loaded());
171 EXPECT_EQ(1u, max_in_queue());
172 EXPECT_EQ(0u, max_active_loading());
174 // Sanity check: stopping/destroying at this point doesn't crash.
175 queue()->OnDeferredStartRenderHostDidStopLoading(host
);
176 queue()->OnDeferredStartRenderHostDestroyed(host
);
179 // Tests adding, starting, and stopping a single host.
180 TEST_F(LoadMonitoringExtensionHostQueueTest
, AddAndStartAndStopOneHost
) {
181 DeferredStartRenderHost
* host
= CreateHost();
183 queue()->OnDeferredStartRenderHostDidStartLoading(host
);
184 queue()->OnDeferredStartRenderHostDidStopLoading(host
);
186 base::RunLoop().RunUntilIdle();
187 ASSERT_TRUE(finished());
188 EXPECT_EQ(1u, num_queued());
189 EXPECT_EQ(1u, num_loaded());
190 EXPECT_EQ(1u, max_in_queue());
191 EXPECT_EQ(1u, max_active_loading());
193 // Sanity check: destroying at this point doesn't crash.
194 queue()->OnDeferredStartRenderHostDestroyed(host
);
197 // Tests adding, starting, and destroying (i.e. an implicit stop) a single host.
198 TEST_F(LoadMonitoringExtensionHostQueueTest
, AddAndStartAndDestroyOneHost
) {
199 DeferredStartRenderHost
* host
= CreateHost();
201 queue()->OnDeferredStartRenderHostDidStartLoading(host
);
202 queue()->OnDeferredStartRenderHostDestroyed(host
);
204 base::RunLoop().RunUntilIdle();
205 ASSERT_TRUE(finished());
206 EXPECT_EQ(1u, num_queued());
207 EXPECT_EQ(1u, num_loaded());
208 EXPECT_EQ(1u, max_in_queue());
209 EXPECT_EQ(1u, max_active_loading());
212 // Tests adding, starting, and removing a single host.
213 TEST_F(LoadMonitoringExtensionHostQueueTest
, AddAndStartAndRemoveOneHost
) {
214 DeferredStartRenderHost
* host
= CreateHost();
216 queue()->OnDeferredStartRenderHostDidStartLoading(host
);
217 queue()->Remove(host
);
219 base::RunLoop().RunUntilIdle();
220 ASSERT_TRUE(finished());
221 EXPECT_EQ(1u, num_queued());
222 EXPECT_EQ(0u, num_loaded());
223 EXPECT_EQ(1u, max_in_queue());
224 EXPECT_EQ(1u, max_active_loading());
227 // Tests monitoring a sequence of hosts.
228 TEST_F(LoadMonitoringExtensionHostQueueTest
, Sequence
) {
231 // 6 hosts will be added, only 5 will start loading, with a maximum of 4 in
232 // the queue and 3 loading at any time. Only 2 will finish.
233 DeferredStartRenderHost
* host1
= CreateHost();
234 DeferredStartRenderHost
* host2
= CreateHost();
235 DeferredStartRenderHost
* host3
= CreateHost();
236 DeferredStartRenderHost
* host4
= CreateHost();
237 DeferredStartRenderHost
* host5
= CreateHost();
238 DeferredStartRenderHost
* host6
= CreateHost();
244 queue()->OnDeferredStartRenderHostDidStartLoading(host1
);
245 queue()->OnDeferredStartRenderHostDidStartLoading(host2
);
246 queue()->OnDeferredStartRenderHostDidStopLoading(host1
);
252 queue()->OnDeferredStartRenderHostDidStartLoading(host3
);
253 queue()->OnDeferredStartRenderHostDidStartLoading(host4
);
254 queue()->OnDeferredStartRenderHostDidStopLoading(host4
);
255 queue()->OnDeferredStartRenderHostDidStartLoading(host5
);
257 base::RunLoop().RunUntilIdle();
258 ASSERT_TRUE(finished());
259 EXPECT_EQ(6u, num_queued());
260 EXPECT_EQ(2u, num_loaded());
261 EXPECT_EQ(4u, max_in_queue());
262 EXPECT_EQ(3u, max_active_loading());
264 // Sanity check: complete a realistic sequence by stopping and/or destroying
265 // all of the hosts. It shouldn't crash.
266 queue()->OnDeferredStartRenderHostDestroyed(host1
);
267 queue()->OnDeferredStartRenderHostDidStopLoading(host2
);
268 queue()->OnDeferredStartRenderHostDestroyed(host2
);
269 queue()->OnDeferredStartRenderHostDidStopLoading(host3
);
270 queue()->OnDeferredStartRenderHostDestroyed(host3
);
271 queue()->OnDeferredStartRenderHostDestroyed(host4
);
272 queue()->OnDeferredStartRenderHostDestroyed(host5
); // never stopped
273 queue()->OnDeferredStartRenderHostDestroyed(host6
); // never started/stopped
276 } // namespace extensions