a7baed109358fda5a0663ff5462aee710587e015
[platform/framework/web/crosswalk.git] / src / content / browser / loader / resource_scheduler_unittest.cc
1 // Copyright (c) 2012 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 "content/browser/loader/resource_scheduler.h"
6
7 #include "base/memory/scoped_vector.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/run_loop.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/timer/mock_timer.h"
12 #include "base/timer/timer.h"
13 #include "content/browser/browser_thread_impl.h"
14 #include "content/browser/loader/resource_dispatcher_host_impl.h"
15 #include "content/browser/loader/resource_message_filter.h"
16 #include "content/browser/loader/resource_request_info_impl.h"
17 #include "content/common/resource_messages.h"
18 #include "content/public/browser/resource_context.h"
19 #include "content/public/browser/resource_controller.h"
20 #include "content/public/browser/resource_throttle.h"
21 #include "content/public/common/process_type.h"
22 #include "content/public/common/resource_type.h"
23 #include "content/public/test/mock_render_process_host.h"
24 #include "content/public/test/test_browser_context.h"
25 #include "content/test/test_web_contents.h"
26 #include "net/base/host_port_pair.h"
27 #include "net/base/request_priority.h"
28 #include "net/http/http_server_properties_impl.h"
29 #include "net/url_request/url_request.h"
30 #include "net/url_request/url_request_test_util.h"
31 #include "testing/gtest/include/gtest/gtest.h"
32 #include "ui/events/latency_info.h"
33
34 namespace content {
35
36 namespace {
37
38 class TestRequestFactory;
39
40 const int kChildId = 30;
41 const int kRouteId = 75;
42 const int kChildId2 = 43;
43 const int kRouteId2 = 67;
44 const int kBackgroundChildId = 35;
45 const int kBackgroundRouteId = 43;
46 const int kBackgroundChildId2 = 54;
47 const int kBackgroundRouteId2 = 82;
48
49 class TestRequest : public ResourceController {
50  public:
51   TestRequest(scoped_ptr<ResourceThrottle> throttle,
52               scoped_ptr<net::URLRequest> url_request)
53       : started_(false),
54         throttle_(throttle.Pass()),
55         url_request_(url_request.Pass()) {
56     throttle_->set_controller_for_testing(this);
57   }
58   virtual ~TestRequest() {}
59
60   bool started() const { return started_; }
61
62   void Start() {
63     bool deferred = false;
64     throttle_->WillStartRequest(&deferred);
65     started_ = !deferred;
66   }
67
68   virtual void Cancel() OVERRIDE {
69     // Alert the scheduler that the request can be deleted.
70     throttle_.reset(0);
71   }
72
73   const net::URLRequest* url_request() const { return url_request_.get(); }
74
75  protected:
76   // ResourceController interface:
77   virtual void CancelAndIgnore() OVERRIDE {}
78   virtual void CancelWithError(int error_code) OVERRIDE {}
79   virtual void Resume() OVERRIDE { started_ = true; }
80
81  private:
82   bool started_;
83   scoped_ptr<ResourceThrottle> throttle_;
84   scoped_ptr<net::URLRequest> url_request_;
85 };
86
87 class CancelingTestRequest : public TestRequest {
88  public:
89   CancelingTestRequest(scoped_ptr<ResourceThrottle> throttle,
90                        scoped_ptr<net::URLRequest> url_request)
91       : TestRequest(throttle.Pass(), url_request.Pass()) {}
92
93   void set_request_to_cancel(scoped_ptr<TestRequest> request_to_cancel) {
94     request_to_cancel_ = request_to_cancel.Pass();
95   }
96
97  private:
98   virtual void Resume() OVERRIDE {
99     TestRequest::Resume();
100     request_to_cancel_.reset();
101   }
102
103   scoped_ptr<TestRequest> request_to_cancel_;
104 };
105
106 class FakeResourceContext : public ResourceContext {
107  private:
108   virtual net::HostResolver* GetHostResolver() OVERRIDE { return NULL; }
109   virtual net::URLRequestContext* GetRequestContext() OVERRIDE { return NULL; }
110 };
111
112 class FakeResourceMessageFilter : public ResourceMessageFilter {
113  public:
114   FakeResourceMessageFilter(int child_id)
115       : ResourceMessageFilter(
116           child_id,
117           PROCESS_TYPE_RENDERER,
118           NULL  /* appcache_service */,
119           NULL  /* blob_storage_context */,
120           NULL  /* file_system_context */,
121           NULL  /* service_worker_context */,
122           base::Bind(&FakeResourceMessageFilter::GetContexts,
123                      base::Unretained(this))) {
124   }
125
126  private:
127   virtual ~FakeResourceMessageFilter() {}
128
129   void GetContexts(const ResourceHostMsg_Request& request,
130                    ResourceContext** resource_context,
131                    net::URLRequestContext** request_context) {
132     *resource_context = &context_;
133     *request_context = NULL;
134   }
135
136   FakeResourceContext context_;
137 };
138
139 class ResourceSchedulerTest : public testing::Test {
140  protected:
141   ResourceSchedulerTest()
142       : next_request_id_(0),
143         ui_thread_(BrowserThread::UI, &message_loop_),
144         io_thread_(BrowserThread::IO, &message_loop_),
145         mock_timer_(new base::MockTimer(true, true)) {
146     scheduler_.set_timer_for_testing(scoped_ptr<base::Timer>(mock_timer_));
147
148     // TODO(aiolos): Remove when throttling and coalescing have both landed.
149     scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
150                                             false /* should_coalesce */);
151
152     scheduler_.OnClientCreated(kChildId, kRouteId, true);
153     scheduler_.OnClientCreated(kBackgroundChildId, kBackgroundRouteId, false);
154     context_.set_http_server_properties(http_server_properties_.GetWeakPtr());
155   }
156
157   virtual ~ResourceSchedulerTest() {
158     scheduler_.OnClientDeleted(kChildId, kRouteId);
159     scheduler_.OnClientDeleted(kBackgroundChildId, kBackgroundRouteId);
160   }
161
162   scoped_ptr<net::URLRequest> NewURLRequestWithChildAndRoute(
163       const char* url,
164       net::RequestPriority priority,
165       int child_id,
166       int route_id,
167       bool is_async) {
168     scoped_ptr<net::URLRequest> url_request(
169         context_.CreateRequest(GURL(url), priority, NULL, NULL));
170     ResourceRequestInfoImpl* info = new ResourceRequestInfoImpl(
171         PROCESS_TYPE_RENDERER,                   // process_type
172         child_id,                                // child_id
173         route_id,                                // route_id
174         0,                                       // origin_pid
175         ++next_request_id_,                      // request_id
176         MSG_ROUTING_NONE,                        // render_frame_id
177         false,                                   // is_main_frame
178         false,                                   // parent_is_main_frame
179         0,                                       // parent_render_frame_id
180         RESOURCE_TYPE_SUB_RESOURCE,              // resource_type
181         ui::PAGE_TRANSITION_LINK,                // transition_type
182         false,                                   // should_replace_current_entry
183         false,                                   // is_download
184         false,                                   // is_stream
185         true,                                    // allow_download
186         false,                                   // has_user_gesture
187         false,                                   // enable_load_timing
188         blink::WebReferrerPolicyDefault,         // referrer_policy
189         blink::WebPageVisibilityStateVisible,    // visibility_state
190         NULL,                                    // context
191         base::WeakPtr<ResourceMessageFilter>(),  // filter
192         is_async);                               // is_async
193     info->AssociateWithRequest(url_request.get());
194     return url_request.Pass();
195   }
196
197   scoped_ptr<net::URLRequest> NewURLRequest(const char* url,
198                                             net::RequestPriority priority) {
199     return NewURLRequestWithChildAndRoute(
200         url, priority, kChildId, kRouteId, true);
201   }
202
203   TestRequest* NewRequestWithRoute(const char* url,
204                                    net::RequestPriority priority,
205                                    int route_id) {
206     return NewRequestWithChildAndRoute(url, priority, route_id, kChildId);
207   }
208
209   TestRequest* NewRequestWithChildAndRoute(const char* url,
210                                            net::RequestPriority priority,
211                                            int child_id,
212                                            int route_id) {
213     return GetNewTestRequest(url, priority, child_id, route_id, true);
214   }
215
216   TestRequest* NewRequest(const char* url, net::RequestPriority priority) {
217     return NewRequestWithChildAndRoute(url, priority, kChildId, kRouteId);
218   }
219
220   TestRequest* NewBackgroundRequest(const char* url,
221                                     net::RequestPriority priority) {
222     return NewRequestWithChildAndRoute(
223         url, priority, kBackgroundChildId, kBackgroundRouteId);
224   }
225
226   TestRequest* NewSyncRequest(const char* url, net::RequestPriority priority) {
227     return NewSyncRequestWithChildAndRoute(url, priority, kChildId, kRouteId);
228   }
229
230   TestRequest* NewBackgroundSyncRequest(const char* url,
231                                         net::RequestPriority priority) {
232     return NewSyncRequestWithChildAndRoute(
233         url, priority, kBackgroundChildId, kBackgroundRouteId);
234   }
235
236   TestRequest* NewSyncRequestWithChildAndRoute(const char* url,
237                                                net::RequestPriority priority,
238                                                int child_id,
239                                                int route_id) {
240     return GetNewTestRequest(url, priority, child_id, route_id, false);
241   }
242
243   TestRequest* GetNewTestRequest(const char* url,
244                                  net::RequestPriority priority,
245                                  int child_id,
246                                  int route_id,
247                                  bool is_async) {
248     scoped_ptr<net::URLRequest> url_request(NewURLRequestWithChildAndRoute(
249         url, priority, child_id, route_id, is_async));
250     scoped_ptr<ResourceThrottle> throttle(
251         scheduler_.ScheduleRequest(child_id, route_id, url_request.get()));
252     TestRequest* request = new TestRequest(throttle.Pass(), url_request.Pass());
253     request->Start();
254     return request;
255   }
256
257
258   void ChangeRequestPriority(TestRequest* request,
259                              net::RequestPriority new_priority,
260                              int intra_priority = 0) {
261     scoped_refptr<FakeResourceMessageFilter> filter(
262         new FakeResourceMessageFilter(kChildId));
263     const ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
264         request->url_request());
265     const GlobalRequestID& id = info->GetGlobalRequestID();
266     ResourceHostMsg_DidChangePriority msg(id.request_id, new_priority,
267                                           intra_priority);
268     rdh_.OnMessageReceived(msg, filter.get());
269   }
270
271   void FireCoalescingTimer() {
272     EXPECT_TRUE(mock_timer_->IsRunning());
273     mock_timer_->Fire();
274   }
275
276   int next_request_id_;
277   base::MessageLoopForIO message_loop_;
278   BrowserThreadImpl ui_thread_;
279   BrowserThreadImpl io_thread_;
280   ResourceDispatcherHostImpl rdh_;
281   ResourceScheduler scheduler_;
282   base::MockTimer* mock_timer_;
283   net::HttpServerPropertiesImpl http_server_properties_;
284   net::TestURLRequestContext context_;
285 };
286
287 TEST_F(ResourceSchedulerTest, OneIsolatedLowRequest) {
288   scoped_ptr<TestRequest> request(NewRequest("http://host/1", net::LOWEST));
289   EXPECT_TRUE(request->started());
290 }
291
292 TEST_F(ResourceSchedulerTest, OneLowLoadsUntilIdle) {
293   scoped_ptr<TestRequest> high(NewRequest("http://host/high", net::HIGHEST));
294   scoped_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
295   scoped_ptr<TestRequest> low2(NewRequest("http://host/low", net::LOWEST));
296   EXPECT_TRUE(high->started());
297   EXPECT_TRUE(low->started());
298   EXPECT_FALSE(low2->started());
299   high.reset();
300   EXPECT_TRUE(low2->started());
301 }
302
303 TEST_F(ResourceSchedulerTest, OneLowLoadsUntilBodyInserted) {
304   scoped_ptr<TestRequest> high(NewRequest("http://host/high", net::HIGHEST));
305   scoped_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
306   scoped_ptr<TestRequest> low2(NewRequest("http://host/low", net::LOWEST));
307   EXPECT_TRUE(high->started());
308   EXPECT_TRUE(low->started());
309   EXPECT_FALSE(low2->started());
310   high.reset();
311   scheduler_.OnWillInsertBody(kChildId, kRouteId);
312   EXPECT_TRUE(low2->started());
313 }
314
315 TEST_F(ResourceSchedulerTest, OneLowLoadsUntilCriticalComplete) {
316   scoped_ptr<TestRequest> high(NewRequest("http://host/high", net::HIGHEST));
317   scoped_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
318   scoped_ptr<TestRequest> low2(NewRequest("http://host/low", net::LOWEST));
319   EXPECT_TRUE(high->started());
320   EXPECT_TRUE(low->started());
321   EXPECT_FALSE(low2->started());
322   scheduler_.OnWillInsertBody(kChildId, kRouteId);
323   EXPECT_FALSE(low2->started());
324   high.reset();
325   EXPECT_TRUE(low2->started());
326 }
327
328 TEST_F(ResourceSchedulerTest, OneLowLoadsUntilBodyInsertedExceptSpdy) {
329   http_server_properties_.SetSupportsSpdy(
330       net::HostPortPair("spdyhost", 443), true);
331   scoped_ptr<TestRequest> high(NewRequest("http://host/high", net::HIGHEST));
332   scoped_ptr<TestRequest> low_spdy(
333       NewRequest("https://spdyhost/low", net::LOWEST));
334   scoped_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
335   scoped_ptr<TestRequest> low2(NewRequest("http://host/low", net::LOWEST));
336   EXPECT_TRUE(high->started());
337   EXPECT_TRUE(low_spdy->started());
338   EXPECT_TRUE(low->started());
339   EXPECT_FALSE(low2->started());
340   scheduler_.OnWillInsertBody(kChildId, kRouteId);
341   high.reset();
342   EXPECT_TRUE(low2->started());
343 }
344
345 TEST_F(ResourceSchedulerTest, NavigationResetsState) {
346   scheduler_.OnWillInsertBody(kChildId, kRouteId);
347   scheduler_.OnNavigate(kChildId, kRouteId);
348   scoped_ptr<TestRequest> high(NewRequest("http://host/high", net::HIGHEST));
349   scoped_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
350   scoped_ptr<TestRequest> low2(NewRequest("http://host/low", net::LOWEST));
351   EXPECT_TRUE(high->started());
352   EXPECT_TRUE(low->started());
353   EXPECT_FALSE(low2->started());
354 }
355
356 TEST_F(ResourceSchedulerTest, BackgroundRequestStartsImmediately) {
357   const int route_id = 0;  // Indicates a background request.
358   scoped_ptr<TestRequest> request(NewRequestWithRoute("http://host/1",
359                                                       net::LOWEST, route_id));
360   EXPECT_TRUE(request->started());
361 }
362
363 TEST_F(ResourceSchedulerTest, StartMultipleLowRequestsWhenIdle) {
364   scoped_ptr<TestRequest> high1(NewRequest("http://host/high1", net::HIGHEST));
365   scoped_ptr<TestRequest> high2(NewRequest("http://host/high2", net::HIGHEST));
366   scoped_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
367   scoped_ptr<TestRequest> low2(NewRequest("http://host/low", net::LOWEST));
368   EXPECT_TRUE(high1->started());
369   EXPECT_TRUE(high2->started());
370   EXPECT_TRUE(low->started());
371   EXPECT_FALSE(low2->started());
372   high1.reset();
373   EXPECT_FALSE(low2->started());
374   high2.reset();
375   EXPECT_TRUE(low2->started());
376 }
377
378 TEST_F(ResourceSchedulerTest, CancelOtherRequestsWhileResuming) {
379   scoped_ptr<TestRequest> high(NewRequest("http://host/high", net::HIGHEST));
380   scoped_ptr<TestRequest> low1(NewRequest("http://host/low1", net::LOWEST));
381
382   scoped_ptr<net::URLRequest> url_request(
383       NewURLRequest("http://host/low2", net::LOWEST));
384   scoped_ptr<ResourceThrottle> throttle(
385       scheduler_.ScheduleRequest(kChildId, kRouteId, url_request.get()));
386   scoped_ptr<CancelingTestRequest> low2(new CancelingTestRequest(
387       throttle.Pass(), url_request.Pass()));
388   low2->Start();
389
390   scoped_ptr<TestRequest> low3(NewRequest("http://host/low3", net::LOWEST));
391   low2->set_request_to_cancel(low3.Pass());
392   scoped_ptr<TestRequest> low4(NewRequest("http://host/low4", net::LOWEST));
393
394   EXPECT_TRUE(high->started());
395   EXPECT_FALSE(low2->started());
396   high.reset();
397   EXPECT_TRUE(low1->started());
398   EXPECT_TRUE(low2->started());
399   EXPECT_TRUE(low4->started());
400 }
401
402 TEST_F(ResourceSchedulerTest, LimitedNumberOfDelayableRequestsInFlight) {
403   // We only load low priority resources if there's a body.
404   scheduler_.OnWillInsertBody(kChildId, kRouteId);
405
406   // Throw in one high priority request to make sure that's not a factor.
407   scoped_ptr<TestRequest> high(NewRequest("http://host/high", net::HIGHEST));
408   EXPECT_TRUE(high->started());
409
410   const int kMaxNumDelayableRequestsPerClient = 10;  // Should match the .cc.
411   const int kMaxNumDelayableRequestsPerHost = 6;
412   ScopedVector<TestRequest> lows_singlehost;
413   // Queue up to the per-host limit (we subtract the current high-pri request).
414   for (int i = 0; i < kMaxNumDelayableRequestsPerHost - 1; ++i) {
415     string url = "http://host/low" + base::IntToString(i);
416     lows_singlehost.push_back(NewRequest(url.c_str(), net::LOWEST));
417     EXPECT_TRUE(lows_singlehost[i]->started());
418   }
419
420   scoped_ptr<TestRequest> second_last_singlehost(NewRequest("http://host/last",
421                                                             net::LOWEST));
422   scoped_ptr<TestRequest> last_singlehost(NewRequest("http://host/s_last",
423                                                      net::LOWEST));
424
425   EXPECT_FALSE(second_last_singlehost->started());
426   high.reset();
427   EXPECT_TRUE(second_last_singlehost->started());
428   EXPECT_FALSE(last_singlehost->started());
429   lows_singlehost.erase(lows_singlehost.begin());
430   EXPECT_TRUE(last_singlehost->started());
431
432   // Queue more requests from different hosts until we reach the total limit.
433   int expected_slots_left =
434       kMaxNumDelayableRequestsPerClient - kMaxNumDelayableRequestsPerHost;
435   EXPECT_GT(expected_slots_left, 0);
436   ScopedVector<TestRequest> lows_differenthosts;
437   for (int i = 0; i < expected_slots_left; ++i) {
438     string url = "http://host" + base::IntToString(i) + "/low";
439     lows_differenthosts.push_back(NewRequest(url.c_str(), net::LOWEST));
440     EXPECT_TRUE(lows_differenthosts[i]->started());
441   }
442
443   scoped_ptr<TestRequest> last_differenthost(NewRequest("http://host_new/last",
444                                                         net::LOWEST));
445   EXPECT_FALSE(last_differenthost->started());
446 }
447
448 TEST_F(ResourceSchedulerTest, RaisePriorityAndStart) {
449   // Dummies to enforce scheduling.
450   scoped_ptr<TestRequest> high(NewRequest("http://host/high", net::HIGHEST));
451   scoped_ptr<TestRequest> low(NewRequest("http://host/req", net::LOWEST));
452
453   scoped_ptr<TestRequest> request(NewRequest("http://host/req", net::LOWEST));
454   EXPECT_FALSE(request->started());
455
456   ChangeRequestPriority(request.get(), net::HIGHEST);
457   EXPECT_TRUE(request->started());
458 }
459
460 TEST_F(ResourceSchedulerTest, RaisePriorityInQueue) {
461   // Dummies to enforce scheduling.
462   scoped_ptr<TestRequest> high(NewRequest("http://host/high", net::HIGHEST));
463   scoped_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
464
465   scoped_ptr<TestRequest> request(NewRequest("http://host/req", net::IDLE));
466   scoped_ptr<TestRequest> idle(NewRequest("http://host/idle", net::IDLE));
467   EXPECT_FALSE(request->started());
468   EXPECT_FALSE(idle->started());
469
470   ChangeRequestPriority(request.get(), net::LOWEST);
471   EXPECT_FALSE(request->started());
472   EXPECT_FALSE(idle->started());
473
474   const int kMaxNumDelayableRequestsPerClient = 10;  // Should match the .cc.
475   ScopedVector<TestRequest> lows;
476   for (int i = 0; i < kMaxNumDelayableRequestsPerClient - 1; ++i) {
477     string url = "http://host/low" + base::IntToString(i);
478     lows.push_back(NewRequest(url.c_str(), net::LOWEST));
479   }
480
481   scheduler_.OnWillInsertBody(kChildId, kRouteId);
482   high.reset();
483
484   EXPECT_TRUE(request->started());
485   EXPECT_FALSE(idle->started());
486 }
487
488 TEST_F(ResourceSchedulerTest, LowerPriority) {
489   // Dummies to enforce scheduling.
490   scoped_ptr<TestRequest> high(NewRequest("http://host/high", net::HIGHEST));
491   scoped_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
492
493   scoped_ptr<TestRequest> request(NewRequest("http://host/req", net::LOWEST));
494   scoped_ptr<TestRequest> idle(NewRequest("http://host/idle", net::IDLE));
495   EXPECT_FALSE(request->started());
496   EXPECT_FALSE(idle->started());
497
498   ChangeRequestPriority(request.get(), net::IDLE);
499   EXPECT_FALSE(request->started());
500   EXPECT_FALSE(idle->started());
501
502   const int kMaxNumDelayableRequestsPerClient = 10;  // Should match the .cc.
503   // 2 fewer filler requests: 1 for the "low" dummy at the start, and 1 for the
504   // one at the end, which will be tested.
505   const int kNumFillerRequests = kMaxNumDelayableRequestsPerClient - 2;
506   ScopedVector<TestRequest> lows;
507   for (int i = 0; i < kNumFillerRequests; ++i) {
508     string url = "http://host" + base::IntToString(i) + "/low";
509     lows.push_back(NewRequest(url.c_str(), net::LOWEST));
510   }
511
512   scheduler_.OnWillInsertBody(kChildId, kRouteId);
513   high.reset();
514
515   EXPECT_FALSE(request->started());
516   EXPECT_TRUE(idle->started());
517 }
518
519 TEST_F(ResourceSchedulerTest, ReprioritizedRequestGoesToBackOfQueue) {
520   // Dummies to enforce scheduling.
521   scoped_ptr<TestRequest> high(NewRequest("http://host/high", net::HIGHEST));
522   scoped_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
523
524   scoped_ptr<TestRequest> request(NewRequest("http://host/req", net::LOWEST));
525   scoped_ptr<TestRequest> idle(NewRequest("http://host/idle", net::IDLE));
526   EXPECT_FALSE(request->started());
527   EXPECT_FALSE(idle->started());
528
529   const int kMaxNumDelayableRequestsPerClient = 10;  // Should match the .cc.
530   ScopedVector<TestRequest> lows;
531   for (int i = 0; i < kMaxNumDelayableRequestsPerClient; ++i) {
532     string url = "http://host/low" + base::IntToString(i);
533     lows.push_back(NewRequest(url.c_str(), net::LOWEST));
534   }
535
536   ChangeRequestPriority(request.get(), net::IDLE);
537   EXPECT_FALSE(request->started());
538   EXPECT_FALSE(idle->started());
539
540   ChangeRequestPriority(request.get(), net::LOWEST);
541   EXPECT_FALSE(request->started());
542   EXPECT_FALSE(idle->started());
543
544   scheduler_.OnWillInsertBody(kChildId, kRouteId);
545   EXPECT_FALSE(request->started());
546   EXPECT_FALSE(idle->started());
547 }
548
549 TEST_F(ResourceSchedulerTest, HigherIntraPriorityGoesToFrontOfQueue) {
550   // Dummies to enforce scheduling.
551   scoped_ptr<TestRequest> high(NewRequest("http://host/high", net::HIGHEST));
552   scoped_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
553
554   const int kMaxNumDelayableRequestsPerClient = 10;  // Should match the .cc.
555   ScopedVector<TestRequest> lows;
556   for (int i = 0; i < kMaxNumDelayableRequestsPerClient; ++i) {
557     string url = "http://host/low" + base::IntToString(i);
558     lows.push_back(NewRequest(url.c_str(), net::IDLE));
559   }
560
561   scoped_ptr<TestRequest> request(NewRequest("http://host/req", net::IDLE));
562   EXPECT_FALSE(request->started());
563
564   ChangeRequestPriority(request.get(), net::IDLE, 1);
565   EXPECT_FALSE(request->started());
566
567   scheduler_.OnWillInsertBody(kChildId, kRouteId);
568   high.reset();
569   EXPECT_TRUE(request->started());
570 }
571
572 TEST_F(ResourceSchedulerTest, NonHTTPSchedulesImmediately) {
573   // Dummies to enforce scheduling.
574   scoped_ptr<TestRequest> high(NewRequest("http://host/high", net::HIGHEST));
575   scoped_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
576
577   scoped_ptr<TestRequest> request(
578       NewRequest("chrome-extension://req", net::LOWEST));
579   EXPECT_TRUE(request->started());
580 }
581
582 TEST_F(ResourceSchedulerTest, ActiveLoadingSyncSchedulesImmediately) {
583   // TODO(aiolos): remove when throttling and coalescing have both landed
584   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
585                                           false /* should_coalesce */);
586   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
587             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
588   // Dummies to enforce scheduling.
589   scoped_ptr<TestRequest> high(NewRequest("http://host/high", net::HIGHEST));
590   scoped_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
591
592   scoped_ptr<TestRequest> request(
593       NewSyncRequest("http://host/req", net::LOWEST));
594   EXPECT_TRUE(request->started());
595 }
596
597 TEST_F(ResourceSchedulerTest, UnthrottledSyncSchedulesImmediately) {
598   // TODO(aiolos): remove when throttling and coalescing have both landed
599   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
600                                           false /* should_coalesce */);
601   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, true);
602   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
603             scheduler_.GetClientStateForTesting(kBackgroundChildId,
604                                                 kBackgroundRouteId));
605   // Dummies to enforce scheduling.
606   scoped_ptr<TestRequest> high(NewRequest("http://host/high", net::HIGHEST));
607   scoped_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
608
609   scoped_ptr<TestRequest> request(
610       NewBackgroundSyncRequest("http://host/req", net::LOWEST));
611   EXPECT_TRUE(request->started());
612 }
613
614 TEST_F(ResourceSchedulerTest, SpdyProxySchedulesImmediately) {
615   scoped_ptr<TestRequest> high(NewRequest("http://host/high", net::HIGHEST));
616   scoped_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
617
618   scoped_ptr<TestRequest> request(NewRequest("http://host/req", net::IDLE));
619   EXPECT_FALSE(request->started());
620
621   scheduler_.OnReceivedSpdyProxiedHttpResponse(kChildId, kRouteId);
622   EXPECT_TRUE(request->started());
623
624   scoped_ptr<TestRequest> after(NewRequest("http://host/after", net::IDLE));
625   EXPECT_TRUE(after->started());
626 }
627
628 TEST_F(ResourceSchedulerTest, NewSpdyHostInDelayableRequests) {
629   scheduler_.OnWillInsertBody(kChildId, kRouteId);
630   const int kMaxNumDelayableRequestsPerClient = 10;  // Should match the .cc.
631
632   scoped_ptr<TestRequest> low1_spdy(
633       NewRequest("http://spdyhost1:8080/low", net::LOWEST));
634   // Cancel a request after we learn the server supports SPDY.
635   ScopedVector<TestRequest> lows;
636   for (int i = 0; i < kMaxNumDelayableRequestsPerClient - 1; ++i) {
637     string url = "http://host" + base::IntToString(i) + "/low";
638     lows.push_back(NewRequest(url.c_str(), net::LOWEST));
639   }
640   scoped_ptr<TestRequest> low1(NewRequest("http://host/low", net::LOWEST));
641   EXPECT_FALSE(low1->started());
642   http_server_properties_.SetSupportsSpdy(
643       net::HostPortPair("spdyhost1", 8080), true);
644   low1_spdy.reset();
645   EXPECT_TRUE(low1->started());
646
647   low1.reset();
648   scoped_ptr<TestRequest> low2_spdy(
649       NewRequest("http://spdyhost2:8080/low", net::IDLE));
650   // Reprioritize a request after we learn the server supports SPDY.
651   EXPECT_TRUE(low2_spdy->started());
652   http_server_properties_.SetSupportsSpdy(
653       net::HostPortPair("spdyhost2", 8080), true);
654   ChangeRequestPriority(low2_spdy.get(), net::LOWEST);
655   scoped_ptr<TestRequest> low2(NewRequest("http://host/low", net::LOWEST));
656   EXPECT_TRUE(low2->started());
657 }
658
659 TEST_F(ResourceSchedulerTest, ThrottledClientCreation) {
660   // TODO(aiolos): remove when throttling and coalescing have both landed
661   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
662                                           false /* should_coalesce */);
663   EXPECT_TRUE(scheduler_.should_throttle());
664   scheduler_.OnClientCreated(kBackgroundChildId2, kBackgroundRouteId2, false);
665
666   EXPECT_EQ(ResourceScheduler::THROTTLED,
667             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
668                                                 kBackgroundRouteId2));
669   scheduler_.OnClientDeleted(kBackgroundChildId2, kBackgroundRouteId2);
670 }
671
672 TEST_F(ResourceSchedulerTest, ActiveClientThrottleUpdateOnLoadingChange) {
673   // TODO(aiolos): remove when throttling and coalescing have both landed
674   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
675                                           false /* should_coalesce */);
676   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
677             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
678   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, true);
679   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
680             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
681   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, false);
682   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
683             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
684 }
685
686 TEST_F(ResourceSchedulerTest, CoalesceBackgroundClientOnLoadCompletion) {
687   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
688                                           true /* should_coalesce */);
689   EXPECT_EQ(ResourceScheduler::THROTTLED,
690             scheduler_.GetClientStateForTesting(kBackgroundChildId,
691                                                 kBackgroundRouteId));
692   scheduler_.OnLoadingStateChanged(
693       kBackgroundChildId, kBackgroundRouteId, true);
694   EXPECT_EQ(ResourceScheduler::THROTTLED,
695             scheduler_.GetClientStateForTesting(kBackgroundChildId,
696                                                 kBackgroundRouteId));
697   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, true);
698   EXPECT_EQ(ResourceScheduler::COALESCED,
699             scheduler_.GetClientStateForTesting(kBackgroundChildId,
700                                                 kBackgroundRouteId));
701 }
702
703 TEST_F(ResourceSchedulerTest, UnthrottleBackgroundClientOnLoadingStarted) {
704   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
705                                           true /* should_coalesce */);
706   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, true);
707   scheduler_.OnLoadingStateChanged(
708       kBackgroundChildId, kBackgroundRouteId, true);
709   EXPECT_EQ(ResourceScheduler::COALESCED,
710             scheduler_.GetClientStateForTesting(kBackgroundChildId,
711                                                 kBackgroundRouteId));
712
713   scheduler_.OnLoadingStateChanged(
714       kBackgroundChildId, kBackgroundRouteId, false);
715   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
716             scheduler_.GetClientStateForTesting(kBackgroundChildId,
717                                                 kBackgroundRouteId));
718 }
719
720 TEST_F(ResourceSchedulerTest, OneRequestPerThrottledClient) {
721   // TODO(aiolos): remove when throttling and coalescing have both landed
722   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
723                                           false /* should_coalesce */);
724   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
725             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
726   EXPECT_EQ(ResourceScheduler::THROTTLED,
727             scheduler_.GetClientStateForTesting(kBackgroundChildId,
728                                                 kBackgroundRouteId));
729   scoped_ptr<TestRequest> high(
730       NewBackgroundRequest("http://host/high", net::HIGHEST));
731   scoped_ptr<TestRequest> request(
732       NewBackgroundRequest("http://host/req", net::IDLE));
733
734   EXPECT_TRUE(high->started());
735   EXPECT_FALSE(request->started());
736 }
737
738 TEST_F(ResourceSchedulerTest, UnthrottleNewlyVisibleClient) {
739   // TODO(aiolos): remove when throttling and coalescing have both landed
740   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
741                                           false /* should_coalesce */);
742   EXPECT_EQ(ResourceScheduler::THROTTLED,
743             scheduler_.GetClientStateForTesting(kBackgroundChildId,
744                                                 kBackgroundRouteId));
745   scoped_ptr<TestRequest> high(
746       NewBackgroundRequest("http://host/high", net::HIGHEST));
747   scoped_ptr<TestRequest> request(
748       NewBackgroundRequest("http://host/req", net::IDLE));
749   EXPECT_FALSE(request->started());
750
751   scheduler_.OnVisibilityChanged(kBackgroundChildId, kBackgroundRouteId, true);
752   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
753             scheduler_.GetClientStateForTesting(kBackgroundChildId,
754                                                 kBackgroundRouteId));
755   EXPECT_TRUE(request->started());
756 }
757
758 TEST_F(ResourceSchedulerTest, UnthrottleNewlyAudibleClient) {
759   // TODO(aiolos): remove when throttling and coalescing have both landed
760   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
761                                           false /* should_coalesce */);
762   EXPECT_EQ(ResourceScheduler::THROTTLED,
763             scheduler_.GetClientStateForTesting(kBackgroundChildId,
764                                                 kBackgroundRouteId));
765   scoped_ptr<TestRequest> high(
766       NewBackgroundRequest("http://host/high", net::HIGHEST));
767   scoped_ptr<TestRequest> request(
768       NewBackgroundRequest("http://host/req", net::IDLE));
769   EXPECT_FALSE(request->started());
770
771   scheduler_.OnAudibilityChanged(kBackgroundChildId, kBackgroundRouteId, true);
772   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
773             scheduler_.GetClientStateForTesting(kBackgroundChildId,
774                                                 kBackgroundRouteId));
775   EXPECT_TRUE(request->started());
776 }
777
778 TEST_F(ResourceSchedulerTest, VisibleClientStillUnthrottledOnAudabilityChange) {
779   // TODO(aiolos): remove when throttling and coalescing have both landed
780   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
781                                           false /* should_coalesce */);
782   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
783             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
784   EXPECT_EQ(ResourceScheduler::THROTTLED,
785             scheduler_.GetClientStateForTesting(kBackgroundChildId,
786                                                 kBackgroundRouteId));
787
788   scheduler_.OnAudibilityChanged(kChildId, kRouteId, true);
789   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
790             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
791   EXPECT_EQ(ResourceScheduler::THROTTLED,
792             scheduler_.GetClientStateForTesting(kBackgroundChildId,
793                                                 kBackgroundRouteId));
794
795   scheduler_.OnAudibilityChanged(kChildId, kRouteId, false);
796   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
797             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
798   EXPECT_EQ(ResourceScheduler::THROTTLED,
799             scheduler_.GetClientStateForTesting(kBackgroundChildId,
800                                                 kBackgroundRouteId));
801 }
802
803 TEST_F(ResourceSchedulerTest, AudibleClientStillUnthrottledOnVisabilityChange) {
804   // TODO(aiolos): remove when throttling and coalescing have both landed
805   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
806                                           false /* should_coalesce */);
807   scheduler_.OnVisibilityChanged(kChildId, kRouteId, false);
808   scheduler_.OnAudibilityChanged(kChildId, kRouteId, true);
809   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
810             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
811   EXPECT_EQ(ResourceScheduler::THROTTLED,
812             scheduler_.GetClientStateForTesting(kBackgroundChildId,
813                                                 kBackgroundRouteId));
814
815   scheduler_.OnVisibilityChanged(kChildId, kRouteId, true);
816   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
817             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
818   EXPECT_EQ(ResourceScheduler::THROTTLED,
819             scheduler_.GetClientStateForTesting(kBackgroundChildId,
820                                                 kBackgroundRouteId));
821
822   scheduler_.OnVisibilityChanged(kChildId, kRouteId, false);
823   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
824             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
825   EXPECT_EQ(ResourceScheduler::THROTTLED,
826             scheduler_.GetClientStateForTesting(kBackgroundChildId,
827                                                 kBackgroundRouteId));
828 }
829
830 TEST_F(ResourceSchedulerTest, ThrottledClientStartsNextHighestPriorityRequest) {
831   // TODO(aiolos): remove when throttling and coalescing have both landed
832   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
833                                           false /* should_coalesce */);
834   scoped_ptr<TestRequest> request(
835       NewBackgroundRequest("http://host/req", net::IDLE));
836   // Lower priority request started first to test request prioritizaton.
837   scoped_ptr<TestRequest> low(
838       NewBackgroundRequest("http://host/high", net::IDLE));
839   scoped_ptr<TestRequest> high(
840       NewBackgroundRequest("http://host/high", net::HIGHEST));
841
842   EXPECT_FALSE(low->started());
843   EXPECT_FALSE(high->started());
844
845   // request->CancelRequest();
846   request->Cancel();
847   EXPECT_TRUE(high->started());
848   EXPECT_FALSE(low->started());
849 }
850
851 TEST_F(ResourceSchedulerTest, ThrottledSpdyProxySchedulesImmediately) {
852   // TODO(aiolos): remove when throttling and coalescing have both landed
853   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
854                                           false /* should_coalesce */);
855   EXPECT_EQ(ResourceScheduler::THROTTLED,
856             scheduler_.GetClientStateForTesting(kBackgroundChildId,
857                                                 kBackgroundRouteId));
858   scoped_ptr<TestRequest> high(
859       NewBackgroundRequest("http://host/high", net::HIGHEST));
860   scoped_ptr<TestRequest> request(
861       NewBackgroundRequest("http://host/req", net::IDLE));
862
863   EXPECT_FALSE(request->started());
864
865   scheduler_.OnReceivedSpdyProxiedHttpResponse(kBackgroundChildId,
866                                                kBackgroundRouteId);
867   EXPECT_TRUE(request->started());
868
869   scoped_ptr<TestRequest> after(
870       NewBackgroundRequest("http://host/after", net::IDLE));
871   EXPECT_TRUE(after->started());
872 }
873
874 TEST_F(ResourceSchedulerTest, CoalescedClientIssuesNoRequests) {
875   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
876                                           true /* should_coalesce */);
877   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, true);
878   scheduler_.OnLoadingStateChanged(
879       kBackgroundChildId, kBackgroundRouteId, true);
880   EXPECT_EQ(ResourceScheduler::COALESCED,
881             scheduler_.GetClientStateForTesting(kBackgroundChildId,
882                                                 kBackgroundRouteId));
883   scoped_ptr<TestRequest> high(
884       NewBackgroundRequest("http://host/high", net::HIGHEST));
885   scoped_ptr<TestRequest> request(
886       NewBackgroundRequest("http://host/req", net::IDLE));
887
888   EXPECT_FALSE(high->started());
889   EXPECT_FALSE(request->started());
890
891   scheduler_.OnReceivedSpdyProxiedHttpResponse(kBackgroundChildId,
892                                                kBackgroundRouteId);
893   EXPECT_FALSE(high->started());
894
895   scoped_ptr<TestRequest> after(
896       NewBackgroundRequest("http://host/after", net::HIGHEST));
897   EXPECT_FALSE(after->started());
898 }
899
900 TEST_F(ResourceSchedulerTest, CoalescedSpdyProxyWaits) {
901   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
902                                           true /* should_coalesce */);
903   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, true);
904   scheduler_.OnLoadingStateChanged(
905       kBackgroundChildId, kBackgroundRouteId, true);
906   EXPECT_EQ(ResourceScheduler::COALESCED,
907             scheduler_.GetClientStateForTesting(kBackgroundChildId,
908                                                 kBackgroundRouteId));
909   scoped_ptr<TestRequest> high(
910       NewBackgroundRequest("http://host/high", net::HIGHEST));
911   scoped_ptr<TestRequest> request(
912       NewBackgroundRequest("http://host/req", net::IDLE));
913
914   EXPECT_FALSE(request->started());
915
916   scheduler_.OnReceivedSpdyProxiedHttpResponse(kBackgroundChildId,
917                                                kBackgroundRouteId);
918   EXPECT_FALSE(request->started());
919
920   scoped_ptr<TestRequest> after(
921       NewBackgroundRequest("http://host/after", net::IDLE));
922   EXPECT_FALSE(after->started());
923 }
924
925 TEST_F(ResourceSchedulerTest, ThrottledNonHTTPSchedulesImmediately) {
926   // TODO(aiolos): remove when throttling and coalescing have both landed
927   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
928                                           false /* should_coalesce */);
929   // Dummies to enforce scheduling.
930   scoped_ptr<TestRequest> high(
931       NewBackgroundRequest("http://host/high", net::HIGHEST));
932   scoped_ptr<TestRequest> low(
933       NewBackgroundRequest("http://host/low", net::LOWEST));
934
935   scoped_ptr<TestRequest> request(
936       NewBackgroundRequest("chrome-extension://req", net::LOWEST));
937   EXPECT_TRUE(request->started());
938   EXPECT_FALSE(low->started());
939 }
940
941 TEST_F(ResourceSchedulerTest, CoalescedNonHTTPSchedulesImmediately) {
942   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
943                                           true /* should_coalesce */);
944   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, true);
945   scheduler_.OnLoadingStateChanged(
946       kBackgroundChildId, kBackgroundRouteId, true);
947   EXPECT_EQ(ResourceScheduler::COALESCED,
948             scheduler_.GetClientStateForTesting(kBackgroundChildId,
949                                                 kBackgroundRouteId));
950   // Dummies to enforce scheduling.
951   scoped_ptr<TestRequest> high(
952       NewBackgroundRequest("http://host/high", net::HIGHEST));
953   scoped_ptr<TestRequest> low(
954       NewBackgroundRequest("http://host/low", net::LOWEST));
955
956   scoped_ptr<TestRequest> request(
957       NewBackgroundRequest("chrome-extension://req", net::LOWEST));
958   EXPECT_TRUE(request->started());
959   EXPECT_FALSE(low->started());
960 }
961
962 TEST_F(ResourceSchedulerTest, ThrottledSyncSchedulesImmediately) {
963   // TODO(aiolos): remove when throttling and coalescing have both landed
964   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
965                                           false /* should_coalesce */);
966   // Dummies to enforce scheduling.
967   scoped_ptr<TestRequest> high(
968       NewBackgroundRequest("http://host/high", net::HIGHEST));
969   scoped_ptr<TestRequest> low(
970       NewBackgroundRequest("http://host/low", net::LOWEST));
971
972   scoped_ptr<TestRequest> request(
973       NewBackgroundSyncRequest("http://host/req", net::LOWEST));
974   EXPECT_TRUE(request->started());
975   EXPECT_FALSE(low->started());
976 }
977
978 TEST_F(ResourceSchedulerTest, CoalescedSyncSchedulesImmediately) {
979   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
980                                           true /* should_coalesce */);
981   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, true);
982   scheduler_.OnLoadingStateChanged(
983       kBackgroundChildId, kBackgroundRouteId, true);
984   EXPECT_EQ(ResourceScheduler::COALESCED,
985             scheduler_.GetClientStateForTesting(kBackgroundChildId,
986                                                 kBackgroundRouteId));
987   // Dummies to enforce scheduling.
988   scoped_ptr<TestRequest> high(
989       NewBackgroundRequest("http://host/high", net::HIGHEST));
990   scoped_ptr<TestRequest> low(
991       NewBackgroundRequest("http://host/low", net::LOWEST));
992
993   scoped_ptr<TestRequest> request(
994       NewBackgroundSyncRequest("http://host/req", net::LOWEST));
995   EXPECT_TRUE(request->started());
996   EXPECT_FALSE(low->started());
997   EXPECT_FALSE(high->started());
998 }
999
1000 TEST_F(ResourceSchedulerTest, AllBackgroundClientsUnthrottle) {
1001   // TODO(aiolos): remove when throttling and coalescing have both landed
1002   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
1003                                           false /* should_coalesce */);
1004   EXPECT_EQ(ResourceScheduler::THROTTLED,
1005             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1006                                                 kBackgroundRouteId));
1007   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1008             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1009   EXPECT_FALSE(scheduler_.active_clients_loaded());
1010
1011   scheduler_.OnVisibilityChanged(kChildId, kRouteId, false);
1012   EXPECT_TRUE(scheduler_.active_clients_loaded());
1013   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1014             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1015   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1016             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1017                                                 kBackgroundRouteId));
1018
1019   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, true);
1020   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1021             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1022   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1023             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1024                                                 kBackgroundRouteId));
1025
1026   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, false);
1027   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1028             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1029   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1030             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1031                                                 kBackgroundRouteId));
1032
1033   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, true);
1034   scheduler_.OnLoadingStateChanged(
1035       kBackgroundChildId, kBackgroundRouteId, true);
1036   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1037             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1038   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1039             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1040                                                 kBackgroundRouteId));
1041 }
1042
1043 TEST_F(ResourceSchedulerTest,
1044        UnloadedClientVisibilityChangedCorrectlyUnthrottles) {
1045   // TODO(aiolos): remove when throttling and coalescing have both landed
1046   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
1047                                           false /* should_coalesce */);
1048   scheduler_.OnClientCreated(kChildId2, kRouteId2, false);
1049   scheduler_.OnClientCreated(kBackgroundChildId2, kBackgroundRouteId2, false);
1050   scheduler_.OnLoadingStateChanged(kChildId2, kRouteId2, true);
1051   scheduler_.OnLoadingStateChanged(
1052       kBackgroundChildId2, kBackgroundRouteId2, true);
1053
1054   // 1 visible, 3 hidden
1055   EXPECT_FALSE(scheduler_.active_clients_loaded());
1056   EXPECT_EQ(ResourceScheduler::THROTTLED,
1057             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1058                                                 kBackgroundRouteId));
1059   EXPECT_EQ(ResourceScheduler::THROTTLED,
1060             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1061                                                 kBackgroundRouteId2));
1062   EXPECT_EQ(ResourceScheduler::THROTTLED,
1063             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1064   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1065             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1066
1067   // 2 visible, 2 hidden
1068   scheduler_.OnVisibilityChanged(kChildId2, kRouteId2, true);
1069   EXPECT_FALSE(scheduler_.active_clients_loaded());
1070   EXPECT_EQ(ResourceScheduler::THROTTLED,
1071             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1072                                                 kBackgroundRouteId));
1073   EXPECT_EQ(ResourceScheduler::THROTTLED,
1074             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1075                                                 kBackgroundRouteId2));
1076   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1077             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1078   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1079             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1080
1081   // 1 visible, 3 hidden
1082   scheduler_.OnVisibilityChanged(kChildId2, kRouteId2, false);
1083   EXPECT_FALSE(scheduler_.active_clients_loaded());
1084   EXPECT_EQ(ResourceScheduler::THROTTLED,
1085             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1086                                                 kBackgroundRouteId));
1087   EXPECT_EQ(ResourceScheduler::THROTTLED,
1088             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1089                                                 kBackgroundRouteId2));
1090   EXPECT_EQ(ResourceScheduler::THROTTLED,
1091             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1092   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1093             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1094
1095   scheduler_.OnClientDeleted(kChildId2, kRouteId2);
1096   scheduler_.OnClientDeleted(kBackgroundChildId2, kBackgroundRouteId2);
1097 }
1098
1099 TEST_F(ResourceSchedulerTest,
1100        UnloadedClientAudibilityChangedCorrectlyUnthrottles) {
1101   // TODO(aiolos): remove when throttling and coalescing have both landed
1102   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
1103                                           false /* should_coalesce */);
1104   scheduler_.OnClientCreated(kChildId2, kRouteId2, false);
1105   scheduler_.OnClientCreated(kBackgroundChildId2, kBackgroundRouteId2, false);
1106   scheduler_.OnLoadingStateChanged(
1107       kBackgroundChildId2, kBackgroundRouteId2, true);
1108   scheduler_.OnVisibilityChanged(kChildId, kRouteId, false);
1109   scheduler_.OnAudibilityChanged(kChildId, kRouteId, true);
1110
1111   // 1 audible, 3 hidden
1112   EXPECT_FALSE(scheduler_.active_clients_loaded());
1113   EXPECT_EQ(ResourceScheduler::THROTTLED,
1114             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1115                                                 kBackgroundRouteId));
1116   EXPECT_EQ(ResourceScheduler::THROTTLED,
1117             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1118                                                 kBackgroundRouteId2));
1119   EXPECT_EQ(ResourceScheduler::THROTTLED,
1120             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1121   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1122             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1123
1124   // 2 audible, 2 hidden
1125   scheduler_.OnAudibilityChanged(kChildId2, kRouteId2, true);
1126   EXPECT_FALSE(scheduler_.active_clients_loaded());
1127   EXPECT_EQ(ResourceScheduler::THROTTLED,
1128             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1129                                                 kBackgroundRouteId));
1130   EXPECT_EQ(ResourceScheduler::THROTTLED,
1131             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1132                                                 kBackgroundRouteId2));
1133   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1134             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1135   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1136             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1137
1138   // 1 audible, 3 hidden
1139   scheduler_.OnAudibilityChanged(kChildId2, kRouteId2, false);
1140   EXPECT_FALSE(scheduler_.active_clients_loaded());
1141   EXPECT_EQ(ResourceScheduler::THROTTLED,
1142             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1143                                                 kBackgroundRouteId));
1144   EXPECT_EQ(ResourceScheduler::THROTTLED,
1145             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1146                                                 kBackgroundRouteId2));
1147   EXPECT_EQ(ResourceScheduler::THROTTLED,
1148             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1149   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1150             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1151
1152   scheduler_.OnClientDeleted(kChildId2, kRouteId2);
1153   scheduler_.OnClientDeleted(kBackgroundChildId2, kBackgroundRouteId2);
1154 }
1155
1156 TEST_F(ResourceSchedulerTest,
1157        LoadedClientVisibilityChangedCorrectlyUnthrottles) {
1158   // TODO(aiolos): remove when throttling and coalescing have both landed
1159   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
1160                                           false /* should_coalesce */);
1161   scheduler_.OnClientCreated(kChildId2, kRouteId2, false);
1162   scheduler_.OnClientCreated(kBackgroundChildId2, kBackgroundRouteId2, false);
1163   scheduler_.OnLoadingStateChanged(kChildId2, kRouteId2, true);
1164   scheduler_.OnLoadingStateChanged(
1165       kBackgroundChildId2, kBackgroundRouteId2, true);
1166   // 1 visible, 3 hidden
1167   EXPECT_FALSE(scheduler_.active_clients_loaded());
1168   EXPECT_EQ(ResourceScheduler::THROTTLED,
1169             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1170                                                 kBackgroundRouteId));
1171   EXPECT_EQ(ResourceScheduler::THROTTLED,
1172             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1173                                                 kBackgroundRouteId2));
1174   EXPECT_EQ(ResourceScheduler::THROTTLED,
1175             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1176   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1177             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1178
1179   // 2 visible, 2 hidden
1180   scheduler_.OnVisibilityChanged(kChildId2, kRouteId2, true);
1181   EXPECT_FALSE(scheduler_.active_clients_loaded());
1182   EXPECT_EQ(ResourceScheduler::THROTTLED,
1183             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1184                                                 kBackgroundRouteId));
1185   EXPECT_EQ(ResourceScheduler::THROTTLED,
1186             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1187                                                 kBackgroundRouteId2));
1188   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1189             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1190   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1191             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1192
1193   // 1 visible, 3 hidden
1194   scheduler_.OnVisibilityChanged(kChildId2, kRouteId2, false);
1195   EXPECT_FALSE(scheduler_.active_clients_loaded());
1196   EXPECT_EQ(ResourceScheduler::THROTTLED,
1197             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1198                                                 kBackgroundRouteId));
1199   EXPECT_EQ(ResourceScheduler::THROTTLED,
1200             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1201                                                 kBackgroundRouteId2));
1202   EXPECT_EQ(ResourceScheduler::THROTTLED,
1203             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1204   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1205             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1206
1207   scheduler_.OnClientDeleted(kChildId2, kRouteId2);
1208   scheduler_.OnClientDeleted(kBackgroundChildId2, kBackgroundRouteId2);
1209 }
1210
1211 TEST_F(ResourceSchedulerTest,
1212        LoadedClientAudibilityChangedCorrectlyUnthrottles) {
1213   // TODO(aiolos): remove when throttling and coalescing have both landed
1214   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
1215                                           false /* should_coalesce */);
1216   scheduler_.OnClientCreated(kChildId2, kRouteId2, false);
1217   scheduler_.OnClientCreated(kBackgroundChildId2, kBackgroundRouteId2, false);
1218   scheduler_.OnLoadingStateChanged(kChildId2, kRouteId2, true);
1219   scheduler_.OnLoadingStateChanged(
1220       kBackgroundChildId2, kBackgroundRouteId2, true);
1221   scheduler_.OnVisibilityChanged(kChildId, kRouteId, false);
1222   scheduler_.OnAudibilityChanged(kChildId, kRouteId, true);
1223   // 1 audible, 3 hidden
1224   EXPECT_FALSE(scheduler_.active_clients_loaded());
1225   EXPECT_EQ(ResourceScheduler::THROTTLED,
1226             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1227                                                 kBackgroundRouteId));
1228   EXPECT_EQ(ResourceScheduler::THROTTLED,
1229             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1230                                                 kBackgroundRouteId2));
1231   EXPECT_EQ(ResourceScheduler::THROTTLED,
1232             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1233   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1234             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1235
1236   // 2 audible, 2 hidden
1237   scheduler_.OnAudibilityChanged(kChildId2, kRouteId2, true);
1238   EXPECT_FALSE(scheduler_.active_clients_loaded());
1239   EXPECT_EQ(ResourceScheduler::THROTTLED,
1240             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1241                                                 kBackgroundRouteId));
1242   EXPECT_EQ(ResourceScheduler::THROTTLED,
1243             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1244                                                 kBackgroundRouteId2));
1245   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1246             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1247   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1248             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1249
1250   // 1 audible, 3 hidden
1251   scheduler_.OnAudibilityChanged(kChildId2, kRouteId2, false);
1252   EXPECT_FALSE(scheduler_.active_clients_loaded());
1253   EXPECT_EQ(ResourceScheduler::THROTTLED,
1254             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1255                                                 kBackgroundRouteId));
1256   EXPECT_EQ(ResourceScheduler::THROTTLED,
1257             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1258                                                 kBackgroundRouteId2));
1259   EXPECT_EQ(ResourceScheduler::THROTTLED,
1260             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1261   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1262             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1263
1264   scheduler_.OnClientDeleted(kChildId2, kRouteId2);
1265   scheduler_.OnClientDeleted(kBackgroundChildId2, kBackgroundRouteId2);
1266 }
1267
1268 TEST_F(ResourceSchedulerTest, UnloadedClientBecomesHiddenCorrectlyUnthrottles) {
1269   // TODO(aiolos): remove when throttling and coalescing have both landed
1270   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
1271                                           false /* should_coalesce */);
1272   scheduler_.OnClientCreated(kChildId2, kRouteId2, true);
1273   scheduler_.OnClientCreated(kBackgroundChildId2, kBackgroundRouteId2, false);
1274   scheduler_.OnLoadingStateChanged(
1275       kBackgroundChildId2, kBackgroundRouteId2, true);
1276
1277   // 2 visible, 2 hidden
1278   EXPECT_FALSE(scheduler_.active_clients_loaded());
1279   EXPECT_EQ(ResourceScheduler::THROTTLED,
1280             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1281                                                 kBackgroundRouteId));
1282   EXPECT_EQ(ResourceScheduler::THROTTLED,
1283             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1284                                                 kBackgroundRouteId2));
1285   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1286             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1287   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1288             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1289
1290   // 1 visible, 3 hidden
1291   scheduler_.OnVisibilityChanged(kChildId2, kRouteId2, false);
1292   EXPECT_FALSE(scheduler_.active_clients_loaded());
1293   EXPECT_EQ(ResourceScheduler::THROTTLED,
1294             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1295                                                 kBackgroundRouteId));
1296   EXPECT_EQ(ResourceScheduler::THROTTLED,
1297             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1298                                                 kBackgroundRouteId2));
1299   EXPECT_EQ(ResourceScheduler::THROTTLED,
1300             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1301   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1302             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1303
1304   // 0 visible, 4 hidden
1305   scheduler_.OnVisibilityChanged(kChildId, kRouteId, false);
1306   EXPECT_TRUE(scheduler_.active_clients_loaded());
1307   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1308             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1309                                                 kBackgroundRouteId));
1310   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1311             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1312                                                 kBackgroundRouteId2));
1313   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1314             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1315   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1316             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1317
1318   // 1 visible, 3 hidden
1319   scheduler_.OnVisibilityChanged(kChildId, kRouteId, true);
1320   EXPECT_FALSE(scheduler_.active_clients_loaded());
1321   EXPECT_EQ(ResourceScheduler::THROTTLED,
1322             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1323                                                 kBackgroundRouteId));
1324   EXPECT_EQ(ResourceScheduler::THROTTLED,
1325             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1326                                                 kBackgroundRouteId2));
1327   EXPECT_EQ(ResourceScheduler::THROTTLED,
1328             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1329   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1330             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1331
1332   scheduler_.OnClientDeleted(kChildId2, kRouteId2);
1333   scheduler_.OnClientDeleted(kBackgroundChildId2, kBackgroundRouteId2);
1334 }
1335
1336 TEST_F(ResourceSchedulerTest, UnloadedClientBecomesSilentCorrectlyUnthrottles) {
1337   // TODO(aiolos): remove when throttling and coalescing have both landed
1338   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
1339                                           false /* should_coalesce */);
1340   scheduler_.OnClientCreated(kChildId2, kRouteId2, false);
1341   scheduler_.OnClientCreated(kBackgroundChildId2, kBackgroundRouteId2, false);
1342   scheduler_.OnLoadingStateChanged(
1343       kBackgroundChildId2, kBackgroundRouteId2, true);
1344   scheduler_.OnAudibilityChanged(kChildId, kRouteId, true);
1345   scheduler_.OnVisibilityChanged(kChildId, kRouteId, false);
1346   scheduler_.OnAudibilityChanged(kChildId2, kRouteId2, true);
1347   // 2 audible, 2 hidden
1348   EXPECT_FALSE(scheduler_.active_clients_loaded());
1349   EXPECT_EQ(ResourceScheduler::THROTTLED,
1350             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1351                                                 kBackgroundRouteId));
1352   EXPECT_EQ(ResourceScheduler::THROTTLED,
1353             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1354                                                 kBackgroundRouteId2));
1355   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1356             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1357   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1358             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1359
1360   // 1 audible, 3 hidden
1361   scheduler_.OnAudibilityChanged(kChildId2, kRouteId2, false);
1362   EXPECT_FALSE(scheduler_.active_clients_loaded());
1363   EXPECT_EQ(ResourceScheduler::THROTTLED,
1364             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1365                                                 kBackgroundRouteId));
1366   EXPECT_EQ(ResourceScheduler::THROTTLED,
1367             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1368                                                 kBackgroundRouteId2));
1369   EXPECT_EQ(ResourceScheduler::THROTTLED,
1370             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1371   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1372             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1373
1374   // 0 audible, 4 hidden
1375   scheduler_.OnAudibilityChanged(kChildId, kRouteId, false);
1376   EXPECT_TRUE(scheduler_.active_clients_loaded());
1377   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1378             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1379                                                 kBackgroundRouteId));
1380   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1381             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1382                                                 kBackgroundRouteId2));
1383   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1384             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1385   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1386             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1387
1388   // 1 audible, 3 hidden
1389   scheduler_.OnAudibilityChanged(kChildId, kRouteId, true);
1390   EXPECT_FALSE(scheduler_.active_clients_loaded());
1391   EXPECT_EQ(ResourceScheduler::THROTTLED,
1392             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1393                                                 kBackgroundRouteId));
1394   EXPECT_EQ(ResourceScheduler::THROTTLED,
1395             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1396                                                 kBackgroundRouteId2));
1397   EXPECT_EQ(ResourceScheduler::THROTTLED,
1398             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1399   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1400             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1401
1402   scheduler_.OnClientDeleted(kChildId2, kRouteId2);
1403   scheduler_.OnClientDeleted(kBackgroundChildId2, kBackgroundRouteId2);
1404 }
1405
1406 TEST_F(ResourceSchedulerTest, LoadedClientBecomesHiddenCorrectlyThrottles) {
1407   // TODO(aiolos): remove when throttling and coalescing have both landed
1408   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
1409                                           false /* should_coalesce */);
1410   scheduler_.OnClientCreated(kChildId2, kRouteId2, true);
1411   scheduler_.OnClientCreated(kBackgroundChildId2, kBackgroundRouteId2, false);
1412   scheduler_.OnLoadingStateChanged(
1413       kBackgroundChildId2, kBackgroundRouteId2, true);
1414   scheduler_.OnLoadingStateChanged(kChildId2, kRouteId2, true);
1415   // 2 visible, 2 hidden
1416   EXPECT_FALSE(scheduler_.active_clients_loaded());
1417   EXPECT_EQ(ResourceScheduler::THROTTLED,
1418             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1419                                                 kBackgroundRouteId));
1420   EXPECT_EQ(ResourceScheduler::THROTTLED,
1421             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1422                                                 kBackgroundRouteId2));
1423   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1424             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1425   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1426             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1427
1428   // 1 visible, 3 hidden
1429   scheduler_.OnVisibilityChanged(kChildId2, kRouteId2, false);
1430   EXPECT_FALSE(scheduler_.active_clients_loaded());
1431   EXPECT_EQ(ResourceScheduler::THROTTLED,
1432             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1433                                                 kBackgroundRouteId));
1434   EXPECT_EQ(ResourceScheduler::THROTTLED,
1435             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1436                                                 kBackgroundRouteId2));
1437   EXPECT_EQ(ResourceScheduler::THROTTLED,
1438             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1439   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1440             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1441
1442   // 0 visible, 4 hidden
1443   scheduler_.OnVisibilityChanged(kChildId, kRouteId, false);
1444   EXPECT_TRUE(scheduler_.active_clients_loaded());
1445   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1446             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1447                                                 kBackgroundRouteId));
1448   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1449             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1450                                                 kBackgroundRouteId2));
1451   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1452             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1453   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1454             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1455
1456   // 1 visible, 3 hidden
1457   scheduler_.OnVisibilityChanged(kChildId2, kRouteId2, true);
1458   EXPECT_TRUE(scheduler_.active_clients_loaded());
1459   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1460             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1461                                                 kBackgroundRouteId));
1462   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1463             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1464                                                 kBackgroundRouteId2));
1465   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1466             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1467   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1468             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1469
1470   scheduler_.OnClientDeleted(kChildId2, kRouteId2);
1471   scheduler_.OnClientDeleted(kBackgroundChildId2, kBackgroundRouteId2);
1472 }
1473
1474 TEST_F(ResourceSchedulerTest, LoadedClientBecomesSilentCorrectlyThrottles) {
1475   // TODO(aiolos): remove when throttling and coalescing have both landed
1476   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
1477                                           false /* should_coalesce */);
1478   scheduler_.OnClientCreated(kChildId2, kRouteId2, false);
1479   scheduler_.OnClientCreated(kBackgroundChildId2, kBackgroundRouteId2, false);
1480   scheduler_.OnLoadingStateChanged(
1481       kBackgroundChildId2, kBackgroundRouteId2, true);
1482   scheduler_.OnLoadingStateChanged(kChildId2, kRouteId2, true);
1483   scheduler_.OnVisibilityChanged(kChildId, kRouteId, false);
1484   scheduler_.OnAudibilityChanged(kChildId, kRouteId, true);
1485   scheduler_.OnAudibilityChanged(kChildId2, kRouteId2, true);
1486   // 2 audible, 2 hidden
1487   EXPECT_FALSE(scheduler_.active_clients_loaded());
1488   EXPECT_EQ(ResourceScheduler::THROTTLED,
1489             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1490                                                 kBackgroundRouteId));
1491   EXPECT_EQ(ResourceScheduler::THROTTLED,
1492             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1493                                                 kBackgroundRouteId2));
1494   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1495             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1496   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1497             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1498
1499   // 1 audible, 3 hidden
1500   scheduler_.OnAudibilityChanged(kChildId2, kRouteId2, false);
1501   EXPECT_FALSE(scheduler_.active_clients_loaded());
1502   EXPECT_EQ(ResourceScheduler::THROTTLED,
1503             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1504                                                 kBackgroundRouteId));
1505   EXPECT_EQ(ResourceScheduler::THROTTLED,
1506             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1507                                                 kBackgroundRouteId2));
1508   EXPECT_EQ(ResourceScheduler::THROTTLED,
1509             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1510   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1511             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1512
1513   // 0 audible, 4 hidden
1514   scheduler_.OnAudibilityChanged(kChildId, kRouteId, false);
1515   EXPECT_TRUE(scheduler_.active_clients_loaded());
1516   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1517             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1518                                                 kBackgroundRouteId));
1519   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1520             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1521                                                 kBackgroundRouteId2));
1522   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1523             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1524   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1525             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1526
1527   // 1 audible, 3 hidden
1528   scheduler_.OnAudibilityChanged(kChildId2, kRouteId2, true);
1529   EXPECT_TRUE(scheduler_.active_clients_loaded());
1530   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1531             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1532                                                 kBackgroundRouteId));
1533   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1534             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1535                                                 kBackgroundRouteId2));
1536   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1537             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1538   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1539             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1540
1541   scheduler_.OnClientDeleted(kChildId2, kRouteId2);
1542   scheduler_.OnClientDeleted(kBackgroundChildId2, kBackgroundRouteId2);
1543 }
1544
1545 TEST_F(ResourceSchedulerTest, HiddenLoadedChangesCorrectlyStayThrottled) {
1546   // TODO(aiolos): remove when throttling and coalescing have both landed
1547   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
1548                                           false /* should_coalesce */);
1549   scheduler_.OnClientCreated(kChildId2, kRouteId2, true);
1550   scheduler_.OnClientCreated(kBackgroundChildId2, kBackgroundRouteId2, false);
1551
1552   // 1 visible and 2 hidden loading, 1 visible loaded
1553   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, true);
1554   EXPECT_FALSE(scheduler_.active_clients_loaded());
1555   EXPECT_EQ(ResourceScheduler::THROTTLED,
1556             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1557                                                 kBackgroundRouteId));
1558   EXPECT_EQ(ResourceScheduler::THROTTLED,
1559             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1560                                                 kBackgroundRouteId2));
1561   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1562             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1563   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1564             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1565
1566   // 1 visible and 1 hidden loading, 1 visible and 1 hidden loaded
1567   scheduler_.OnLoadingStateChanged(
1568       kBackgroundChildId2, kBackgroundRouteId2, true);
1569   EXPECT_FALSE(scheduler_.active_clients_loaded());
1570   EXPECT_EQ(ResourceScheduler::THROTTLED,
1571             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1572                                                 kBackgroundRouteId));
1573   EXPECT_EQ(ResourceScheduler::THROTTLED,
1574             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1575                                                 kBackgroundRouteId2));
1576   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1577             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1578   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1579             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1580
1581   // 1 visible loading, 1 visible and 2 hidden loaded
1582   scheduler_.OnLoadingStateChanged(
1583       kBackgroundChildId, kBackgroundRouteId, true);
1584   EXPECT_FALSE(scheduler_.active_clients_loaded());
1585   EXPECT_EQ(ResourceScheduler::THROTTLED,
1586             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1587                                                 kBackgroundRouteId));
1588   EXPECT_EQ(ResourceScheduler::THROTTLED,
1589             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1590                                                 kBackgroundRouteId2));
1591   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1592             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1593   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1594             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1595
1596   // 1 visible and 1 hidden loading, 1 visible and 1 hidden loaded
1597   scheduler_.OnLoadingStateChanged(
1598       kBackgroundChildId2, kBackgroundRouteId2, true);
1599   EXPECT_FALSE(scheduler_.active_clients_loaded());
1600   EXPECT_EQ(ResourceScheduler::THROTTLED,
1601             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1602                                                 kBackgroundRouteId));
1603   EXPECT_EQ(ResourceScheduler::THROTTLED,
1604             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1605                                                 kBackgroundRouteId2));
1606   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1607             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1608   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1609             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1610
1611   scheduler_.OnClientDeleted(kChildId2, kRouteId2);
1612   scheduler_.OnClientDeleted(kBackgroundChildId2, kBackgroundRouteId2);
1613 }
1614
1615 TEST_F(ResourceSchedulerTest, PartialVisibleClientLoadedDoesNotUnthrottle) {
1616   // TODO(aiolos): remove when throttling and coalescing have both landed
1617   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
1618                                           false /* should_coalesce */);
1619   scheduler_.OnClientCreated(kChildId2, kRouteId2, true);
1620   scheduler_.OnClientCreated(kBackgroundChildId2, kBackgroundRouteId2, false);
1621
1622   // 2 visible loading, 1 hidden loading, 1 hidden loaded
1623   scheduler_.OnLoadingStateChanged(
1624       kBackgroundChildId2, kBackgroundRouteId2, true);
1625   EXPECT_FALSE(scheduler_.active_clients_loaded());
1626   EXPECT_EQ(ResourceScheduler::THROTTLED,
1627             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1628                                                 kBackgroundRouteId));
1629   EXPECT_EQ(ResourceScheduler::THROTTLED,
1630             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1631                                                 kBackgroundRouteId2));
1632   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1633             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1634   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1635             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1636
1637   // 1 visible and 1 hidden loaded, 1 visible and 1 hidden loading
1638   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, true);
1639   EXPECT_FALSE(scheduler_.active_clients_loaded());
1640   EXPECT_EQ(ResourceScheduler::THROTTLED,
1641             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1642                                                 kBackgroundRouteId));
1643   EXPECT_EQ(ResourceScheduler::THROTTLED,
1644             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1645                                                 kBackgroundRouteId2));
1646   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1647             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1648   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1649             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1650
1651   // 2 visible loading, 1 hidden loading, 1 hidden loaded
1652   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, false);
1653   EXPECT_FALSE(scheduler_.active_clients_loaded());
1654   EXPECT_EQ(ResourceScheduler::THROTTLED,
1655             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1656                                                 kBackgroundRouteId));
1657   EXPECT_EQ(ResourceScheduler::THROTTLED,
1658             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1659                                                 kBackgroundRouteId2));
1660   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1661             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1662   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1663             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1664
1665   scheduler_.OnClientDeleted(kChildId2, kRouteId2);
1666   scheduler_.OnClientDeleted(kBackgroundChildId2, kBackgroundRouteId2);
1667 }
1668
1669 TEST_F(ResourceSchedulerTest, FullVisibleLoadedCorrectlyUnthrottle) {
1670   // TODO(aiolos): remove when throttling and coalescing have both landed
1671   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
1672                                           false /* should_coalesce */);
1673   scheduler_.OnClientCreated(kChildId2, kRouteId2, true);
1674   scheduler_.OnClientCreated(kBackgroundChildId2, kBackgroundRouteId2, false);
1675
1676   // 1 visible and 1 hidden loaded, 1 visible and 1 hidden loading
1677   scheduler_.OnLoadingStateChanged(
1678       kBackgroundChildId2, kBackgroundRouteId2, true);
1679   scheduler_.OnLoadingStateChanged(kChildId2, kRouteId2, true);
1680   EXPECT_FALSE(scheduler_.active_clients_loaded());
1681   EXPECT_EQ(ResourceScheduler::THROTTLED,
1682             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1683                                                 kBackgroundRouteId));
1684   EXPECT_EQ(ResourceScheduler::THROTTLED,
1685             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1686                                                 kBackgroundRouteId2));
1687   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1688             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1689   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1690             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1691
1692   scoped_ptr<TestRequest> high(
1693       NewBackgroundRequest("http://host/high", net::HIGHEST));
1694   scoped_ptr<TestRequest> low(
1695       NewBackgroundRequest("http://host/low", net::LOWEST));
1696
1697   EXPECT_TRUE(high->started());
1698   EXPECT_FALSE(low->started());
1699
1700   // 2 visible loaded, 1 hidden loading, 1 hidden loaded
1701   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, true);
1702   EXPECT_TRUE(scheduler_.active_clients_loaded());
1703   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1704             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1705                                                 kBackgroundRouteId));
1706   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1707             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1708                                                 kBackgroundRouteId2));
1709   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1710             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1711   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1712             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1713   // kBackgroundClientId unthrottling should unthrottle it's request.
1714   EXPECT_TRUE(low->started());
1715
1716   // 1 visible and 1 hidden loaded, 1 visible and 1 hidden loading
1717   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, false);
1718   EXPECT_FALSE(scheduler_.active_clients_loaded());
1719   EXPECT_EQ(ResourceScheduler::THROTTLED,
1720             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1721                                                 kBackgroundRouteId));
1722   EXPECT_EQ(ResourceScheduler::THROTTLED,
1723             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1724                                                 kBackgroundRouteId2));
1725   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1726             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1727   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1728             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1729
1730   scheduler_.OnClientDeleted(kChildId2, kRouteId2);
1731   scheduler_.OnClientDeleted(kBackgroundChildId2, kBackgroundRouteId2);
1732 }
1733
1734 TEST_F(ResourceSchedulerTest,
1735        ActiveAndLoadingClientDeletedCorrectlyUnthrottle) {
1736   // TODO(aiolos): remove when throttling and coalescing have both landed
1737   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
1738                                           false /* should_coalesce */);
1739   scheduler_.OnClientCreated(kChildId2, kRouteId2, true);
1740   scheduler_.OnClientCreated(kBackgroundChildId2, kBackgroundRouteId2, false);
1741
1742   // 1 visible and 1 hidden loaded, 1 visible and 1 hidden loading
1743   scheduler_.OnLoadingStateChanged(
1744       kBackgroundChildId2, kBackgroundRouteId2, true);
1745   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, true);
1746   EXPECT_FALSE(scheduler_.active_clients_loaded());
1747   EXPECT_EQ(ResourceScheduler::THROTTLED,
1748             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1749                                                 kBackgroundRouteId));
1750   EXPECT_EQ(ResourceScheduler::THROTTLED,
1751             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1752                                                 kBackgroundRouteId2));
1753   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1754             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1755   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1756             scheduler_.GetClientStateForTesting(kChildId2, kRouteId2));
1757
1758   // 1 visible loaded, 1 hidden loading, 1 hidden loaded
1759   scheduler_.OnClientDeleted(kChildId2, kRouteId2);
1760   EXPECT_TRUE(scheduler_.active_clients_loaded());
1761   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1762             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1763                                                 kBackgroundRouteId));
1764   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1765             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1766                                                 kBackgroundRouteId2));
1767   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1768             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1769
1770   // 1 visible and 1 hidden loaded, 1 visible and 1 hidden loading
1771   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, false);
1772   EXPECT_FALSE(scheduler_.active_clients_loaded());
1773   EXPECT_EQ(ResourceScheduler::THROTTLED,
1774             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1775                                                 kBackgroundRouteId));
1776   EXPECT_EQ(ResourceScheduler::THROTTLED,
1777             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1778                                                 kBackgroundRouteId2));
1779   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1780             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1781
1782   scheduler_.OnClientDeleted(kBackgroundChildId2, kBackgroundRouteId2);
1783 }
1784
1785 TEST_F(ResourceSchedulerTest, CoalescedClientCreationStartsTimer) {
1786   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
1787                                           true /* should_coalesce */);
1788   EXPECT_FALSE(mock_timer_->IsRunning());
1789   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, true);
1790   EXPECT_FALSE(mock_timer_->IsRunning());
1791   scheduler_.OnLoadingStateChanged(
1792       kBackgroundChildId, kBackgroundRouteId, true);
1793   EXPECT_EQ(ResourceScheduler::COALESCED,
1794             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1795                                                 kBackgroundRouteId));
1796   EXPECT_TRUE(mock_timer_->IsRunning());
1797 }
1798
1799 TEST_F(ResourceSchedulerTest, ActiveLoadingClientLoadedAndHiddenStartsTimer) {
1800   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
1801                                           true /* should_coalesce */);
1802   EXPECT_FALSE(mock_timer_->IsRunning());
1803   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1804             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1805   EXPECT_EQ(ResourceScheduler::THROTTLED,
1806             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1807                                                 kBackgroundRouteId));
1808   EXPECT_FALSE(mock_timer_->IsRunning());
1809
1810   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, true);
1811   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1812             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1813   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1814             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1815                                                 kBackgroundRouteId));
1816   EXPECT_FALSE(mock_timer_->IsRunning());
1817
1818   scheduler_.OnVisibilityChanged(kChildId, kRouteId, false);
1819   EXPECT_EQ(ResourceScheduler::COALESCED,
1820             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1821   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1822             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1823                                                 kBackgroundRouteId));
1824   EXPECT_TRUE(mock_timer_->IsRunning());
1825 }
1826
1827 TEST_F(ResourceSchedulerTest, ActiveLoadingClientHiddenAndLoadedStartsTimer) {
1828   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
1829                                           true /* should_coalesce */);
1830   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1831             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1832   EXPECT_EQ(ResourceScheduler::THROTTLED,
1833             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1834                                                 kBackgroundRouteId));
1835   EXPECT_FALSE(mock_timer_->IsRunning());
1836
1837   scheduler_.OnVisibilityChanged(kChildId, kRouteId, false);
1838   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1839             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1840   EXPECT_FALSE(mock_timer_->IsRunning());
1841
1842   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, true);
1843   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1844             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1845                                                 kBackgroundRouteId));
1846   EXPECT_EQ(ResourceScheduler::COALESCED,
1847             scheduler_.GetClientStateForTesting(kChildId, kRouteId));
1848   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1849             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1850                                                 kBackgroundRouteId));
1851   EXPECT_TRUE(mock_timer_->IsRunning());
1852 }
1853
1854 TEST_F(ResourceSchedulerTest, CoalescedClientBecomesAudibleStopsTimer) {
1855   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
1856                                           true /* should_coalesce */);
1857   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, true);
1858   EXPECT_FALSE(mock_timer_->IsRunning());
1859   scheduler_.OnLoadingStateChanged(
1860       kBackgroundChildId, kBackgroundRouteId, true);
1861   EXPECT_EQ(ResourceScheduler::COALESCED,
1862             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1863                                                 kBackgroundRouteId));
1864   EXPECT_TRUE(mock_timer_->IsRunning());
1865
1866   scheduler_.OnAudibilityChanged(kBackgroundChildId, kBackgroundRouteId, true);
1867   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1868             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1869                                                 kBackgroundRouteId));
1870   EXPECT_FALSE(mock_timer_->IsRunning());
1871 }
1872
1873 TEST_F(ResourceSchedulerTest, LastCoalescedClientDeletionStopsTimer) {
1874   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
1875                                           true /* should_coalesce */);
1876   scheduler_.OnClientCreated(kBackgroundChildId2, kBackgroundRouteId2, false);
1877   EXPECT_FALSE(mock_timer_->IsRunning());
1878   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, true);
1879   EXPECT_FALSE(mock_timer_->IsRunning());
1880   scheduler_.OnLoadingStateChanged(
1881       kBackgroundChildId, kBackgroundRouteId, true);
1882   EXPECT_EQ(ResourceScheduler::COALESCED,
1883             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1884                                                 kBackgroundRouteId));
1885   scheduler_.OnLoadingStateChanged(
1886       kBackgroundChildId2, kBackgroundRouteId2, true);
1887   EXPECT_EQ(ResourceScheduler::COALESCED,
1888             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1889                                                 kBackgroundRouteId2));
1890   EXPECT_TRUE(mock_timer_->IsRunning());
1891
1892   scheduler_.OnClientDeleted(kBackgroundChildId, kBackgroundRouteId);
1893   EXPECT_TRUE(mock_timer_->IsRunning());
1894
1895   scheduler_.OnClientDeleted(kBackgroundChildId2, kBackgroundRouteId2);
1896   EXPECT_FALSE(mock_timer_->IsRunning());
1897
1898   // To avoid errors on test tear down.
1899   scheduler_.OnClientCreated(kBackgroundChildId, kBackgroundRouteId, false);
1900 }
1901
1902 TEST_F(ResourceSchedulerTest, LastCoalescedClientStartsLoadingStopsTimer) {
1903   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
1904                                           true /* should_coalesce */);
1905   scheduler_.OnClientCreated(kBackgroundChildId2, kBackgroundRouteId2, false);
1906   EXPECT_FALSE(mock_timer_->IsRunning());
1907   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, true);
1908   EXPECT_FALSE(mock_timer_->IsRunning());
1909   scheduler_.OnLoadingStateChanged(
1910       kBackgroundChildId, kBackgroundRouteId, true);
1911   EXPECT_EQ(ResourceScheduler::COALESCED,
1912             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1913                                                 kBackgroundRouteId));
1914   scheduler_.OnLoadingStateChanged(
1915       kBackgroundChildId2, kBackgroundRouteId2, true);
1916   EXPECT_EQ(ResourceScheduler::COALESCED,
1917             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1918                                                 kBackgroundRouteId2));
1919   EXPECT_TRUE(mock_timer_->IsRunning());
1920
1921   scheduler_.OnLoadingStateChanged(
1922       kBackgroundChildId, kBackgroundRouteId, false);
1923   EXPECT_TRUE(mock_timer_->IsRunning());
1924
1925   scheduler_.OnLoadingStateChanged(
1926       kBackgroundChildId2, kBackgroundRouteId2, false);
1927   EXPECT_FALSE(mock_timer_->IsRunning());
1928
1929   // This is needed to avoid errors on test tear down.
1930   scheduler_.OnClientDeleted(kBackgroundChildId2, kBackgroundRouteId2);
1931 }
1932
1933 TEST_F(ResourceSchedulerTest, LastCoalescedClientBecomesVisibleStopsTimer) {
1934   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
1935                                           true /* should_coalesce */);
1936   scheduler_.OnClientCreated(kBackgroundChildId2, kBackgroundRouteId2, false);
1937   EXPECT_FALSE(mock_timer_->IsRunning());
1938   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, true);
1939   EXPECT_FALSE(mock_timer_->IsRunning());
1940   scheduler_.OnLoadingStateChanged(
1941       kBackgroundChildId, kBackgroundRouteId, true);
1942   EXPECT_EQ(ResourceScheduler::COALESCED,
1943             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1944                                                 kBackgroundRouteId));
1945   scheduler_.OnLoadingStateChanged(
1946       kBackgroundChildId2, kBackgroundRouteId2, true);
1947   EXPECT_EQ(ResourceScheduler::COALESCED,
1948             scheduler_.GetClientStateForTesting(kBackgroundChildId2,
1949                                                 kBackgroundRouteId2));
1950   EXPECT_TRUE(mock_timer_->IsRunning());
1951
1952   scheduler_.OnVisibilityChanged(kBackgroundChildId, kBackgroundRouteId, true);
1953   EXPECT_TRUE(mock_timer_->IsRunning());
1954
1955   scheduler_.OnVisibilityChanged(
1956       kBackgroundChildId2, kBackgroundRouteId2, true);
1957   EXPECT_FALSE(mock_timer_->IsRunning());
1958
1959   // To avoid errors on test tear down.
1960   scheduler_.OnClientDeleted(kBackgroundChildId2, kBackgroundRouteId2);
1961 }
1962
1963 TEST_F(ResourceSchedulerTest,
1964        CoalescedClientBecomesLoadingAndVisibleStopsTimer) {
1965   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
1966                                           true /* should_coalesce */);
1967   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, true);
1968   EXPECT_FALSE(mock_timer_->IsRunning());
1969   scheduler_.OnLoadingStateChanged(
1970       kBackgroundChildId, kBackgroundRouteId, true);
1971   EXPECT_EQ(ResourceScheduler::COALESCED,
1972             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1973                                                 kBackgroundRouteId));
1974   EXPECT_TRUE(mock_timer_->IsRunning());
1975
1976   scheduler_.OnLoadingStateChanged(
1977       kBackgroundChildId, kBackgroundRouteId, false);
1978   EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
1979             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1980                                                 kBackgroundRouteId));
1981   EXPECT_FALSE(mock_timer_->IsRunning());
1982
1983   scheduler_.OnVisibilityChanged(kBackgroundChildId, kBackgroundRouteId, true);
1984   EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
1985             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1986                                                 kBackgroundRouteId));
1987   EXPECT_FALSE(mock_timer_->IsRunning());
1988 }
1989
1990 TEST_F(ResourceSchedulerTest, CoalescedRequestsIssueOnTimer) {
1991   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
1992                                           true /* should_coalesce */);
1993   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, true);
1994   scheduler_.OnLoadingStateChanged(
1995       kBackgroundChildId, kBackgroundRouteId, true);
1996   EXPECT_EQ(ResourceScheduler::COALESCED,
1997             scheduler_.GetClientStateForTesting(kBackgroundChildId,
1998                                                 kBackgroundRouteId));
1999   EXPECT_TRUE(scheduler_.active_clients_loaded());
2000
2001   scoped_ptr<TestRequest> high(
2002       NewBackgroundRequest("http://host/high", net::HIGHEST));
2003   scoped_ptr<TestRequest> low(
2004       NewBackgroundRequest("http://host/low", net::LOWEST));
2005   EXPECT_FALSE(high->started());
2006   EXPECT_FALSE(low->started());
2007
2008   FireCoalescingTimer();
2009
2010   EXPECT_TRUE(high->started());
2011   EXPECT_TRUE(low->started());
2012 }
2013
2014 TEST_F(ResourceSchedulerTest, CoalescedRequestsUnthrottleCorrectlyOnTimer) {
2015   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
2016                                           true /* should_coalesce */);
2017   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, true);
2018   scheduler_.OnLoadingStateChanged(
2019       kBackgroundChildId, kBackgroundRouteId, true);
2020   EXPECT_EQ(ResourceScheduler::COALESCED,
2021             scheduler_.GetClientStateForTesting(kBackgroundChildId,
2022                                                 kBackgroundRouteId));
2023   EXPECT_TRUE(scheduler_.active_clients_loaded());
2024
2025   scoped_ptr<TestRequest> high(
2026       NewBackgroundRequest("http://host/high", net::HIGHEST));
2027   scoped_ptr<TestRequest> high2(
2028       NewBackgroundRequest("http://host/high", net::HIGHEST));
2029   scoped_ptr<TestRequest> high3(
2030       NewBackgroundRequest("http://host/high", net::HIGHEST));
2031   scoped_ptr<TestRequest> high4(
2032       NewBackgroundRequest("http://host/high", net::HIGHEST));
2033   scoped_ptr<TestRequest> low(
2034       NewBackgroundRequest("http://host/low", net::LOWEST));
2035   scoped_ptr<TestRequest> low2(
2036       NewBackgroundRequest("http://host/low", net::LOWEST));
2037   scoped_ptr<TestRequest> low3(
2038       NewBackgroundRequest("http://host/low", net::LOWEST));
2039   scoped_ptr<TestRequest> low4(
2040       NewBackgroundRequest("http://host/low", net::LOWEST));
2041
2042   http_server_properties_.SetSupportsSpdy(net::HostPortPair("spdyhost", 443),
2043                                           true);
2044   scoped_ptr<TestRequest> low_spdy(
2045       NewBackgroundRequest("https://spdyhost/low", net::LOW));
2046   scoped_ptr<TestRequest> sync_request(
2047       NewBackgroundSyncRequest("http://host/req", net::LOW));
2048   scoped_ptr<TestRequest> non_http_request(
2049       NewBackgroundRequest("chrome-extension://req", net::LOW));
2050
2051   // Sync requests should issue immediately.
2052   EXPECT_TRUE(sync_request->started());
2053   // Non-http(s) requests should issue immediately.
2054   EXPECT_TRUE(non_http_request->started());
2055   // Nothing else should issue without a timer fire.
2056   EXPECT_FALSE(high->started());
2057   EXPECT_FALSE(high2->started());
2058   EXPECT_FALSE(high3->started());
2059   EXPECT_FALSE(high4->started());
2060   EXPECT_FALSE(low->started());
2061   EXPECT_FALSE(low2->started());
2062   EXPECT_FALSE(low3->started());
2063   EXPECT_FALSE(low4->started());
2064   EXPECT_FALSE(low_spdy->started());
2065
2066   FireCoalescingTimer();
2067
2068   // All high priority requests should issue.
2069   EXPECT_TRUE(high->started());
2070   EXPECT_TRUE(high2->started());
2071   EXPECT_TRUE(high3->started());
2072   EXPECT_TRUE(high4->started());
2073   // There should only be one net::LOWEST priority request issued with
2074   // non-delayable requests in flight.
2075   EXPECT_TRUE(low->started());
2076   EXPECT_FALSE(low2->started());
2077   EXPECT_FALSE(low3->started());
2078   EXPECT_FALSE(low4->started());
2079   // Spdy-Enable requests should issue regardless of priority.
2080   EXPECT_TRUE(low_spdy->started());
2081 }
2082
2083 TEST_F(ResourceSchedulerTest, CoalescedRequestsWaitForNextTimer) {
2084   scheduler_.SetThrottleOptionsForTesting(true /* should_throttle */,
2085                                           true /* should_coalesce */);
2086   scheduler_.OnLoadingStateChanged(kChildId, kRouteId, true);
2087   scheduler_.OnLoadingStateChanged(
2088       kBackgroundChildId, kBackgroundRouteId, true);
2089
2090   EXPECT_EQ(ResourceScheduler::COALESCED,
2091             scheduler_.GetClientStateForTesting(kBackgroundChildId,
2092                                                 kBackgroundRouteId));
2093   EXPECT_TRUE(scheduler_.active_clients_loaded());
2094
2095   scoped_ptr<TestRequest> high(
2096       NewBackgroundRequest("http://host/high", net::HIGHEST));
2097   EXPECT_FALSE(high->started());
2098
2099   FireCoalescingTimer();
2100
2101   scoped_ptr<TestRequest> high2(
2102       NewBackgroundRequest("http://host/high2", net::HIGHEST));
2103   scoped_ptr<TestRequest> low(
2104       NewBackgroundRequest("http://host/low", net::LOWEST));
2105
2106   EXPECT_TRUE(high->started());
2107   EXPECT_FALSE(high2->started());
2108   EXPECT_FALSE(low->started());
2109
2110   FireCoalescingTimer();
2111
2112   EXPECT_TRUE(high->started());
2113   EXPECT_TRUE(high2->started());
2114   EXPECT_TRUE(low->started());
2115 }
2116
2117 TEST_F(ResourceSchedulerTest, GetVisualSignalFromRenderViewHost) {
2118   scoped_ptr<MockRenderProcessHostFactory> render_process_host_factory;
2119   scoped_ptr<TestBrowserContext> browser_context;
2120   scoped_ptr<TestWebContents> web_contents_1;
2121   scoped_ptr<TestWebContents> web_contents_2;
2122
2123   render_process_host_factory.reset(new MockRenderProcessHostFactory());
2124   browser_context.reset(new TestBrowserContext());
2125   scoped_refptr<SiteInstance> site_instance_1 =
2126       SiteInstance::Create(browser_context.get());
2127   scoped_refptr<SiteInstance> site_instance_2 =
2128       SiteInstance::Create(browser_context.get());
2129   SiteInstanceImpl::set_render_process_host_factory(
2130           render_process_host_factory.get());
2131
2132   web_contents_1.reset(
2133       TestWebContents::Create(browser_context.get(), site_instance_1.get()));
2134   web_contents_2.reset(
2135       TestWebContents::Create(browser_context.get(), site_instance_2.get()));
2136   base::RunLoop().RunUntilIdle();
2137
2138   RenderViewHostImpl* rvh1 = web_contents_1->GetRenderViewHost();
2139   RenderViewHostImpl* rvh2 = web_contents_2->GetRenderViewHost();
2140   ResourceScheduler* scheduler = ResourceDispatcherHostImpl::Get()->scheduler();
2141
2142   // Check initial visibility is set correctly.
2143   EXPECT_EQ(scheduler->IsClientVisibleForTesting(rvh1->GetProcess()->GetID(),
2144                                                  rvh1->GetRoutingID()),
2145             !rvh1->is_hidden());
2146   EXPECT_EQ(scheduler->IsClientVisibleForTesting(rvh2->GetProcess()->GetID(),
2147                                                  rvh1->GetRoutingID()),
2148             !rvh2->is_hidden());
2149
2150   // 1 visible, 1 hidden
2151   rvh1->WasShown(ui::LatencyInfo());
2152   rvh2->WasHidden();
2153   base::RunLoop().RunUntilIdle();
2154
2155   EXPECT_TRUE(scheduler->IsClientVisibleForTesting(rvh1->GetProcess()->GetID(),
2156                                                    rvh1->GetRoutingID()));
2157   EXPECT_FALSE(scheduler->IsClientVisibleForTesting(rvh2->GetProcess()->GetID(),
2158                                                     rvh2->GetRoutingID()));
2159
2160   // Flip the visibility and check again.
2161   rvh1->WasHidden();
2162   rvh2->WasShown(ui::LatencyInfo());
2163   base::RunLoop().RunUntilIdle();
2164
2165   EXPECT_FALSE(scheduler->IsClientVisibleForTesting(rvh1->GetProcess()->GetID(),
2166                                                     rvh1->GetRoutingID()));
2167   EXPECT_TRUE(scheduler->IsClientVisibleForTesting(rvh2->GetProcess()->GetID(),
2168                                                    rvh2->GetRoutingID()));
2169   // Clean up.
2170   web_contents_1.reset();
2171   web_contents_2.reset();
2172   base::RunLoop().RunUntilIdle();
2173
2174   browser_context.reset();
2175   render_process_host_factory.reset();
2176 }
2177
2178 }  // unnamed namespace
2179
2180 }  // namespace content