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
34namespace content {
35
36namespace {
37
38class TestRequestFactory;
39
40const int kChildId = 30;
41const int kRouteId = 75;
42const int kChildId2 = 43;
43const int kRouteId2 = 67;
44const int kBackgroundChildId = 35;
45const int kBackgroundRouteId = 43;
46const int kBackgroundChildId2 = 54;
47const int kBackgroundRouteId2 = 82;
48
49class 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
87class 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
106class FakeResourceContext : public ResourceContext {
107 private:
108  virtual net::HostResolver* GetHostResolver() OVERRIDE { return NULL; }
109  virtual net::URLRequestContext* GetRequestContext() OVERRIDE { return NULL; }
110};
111
112class 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
139class 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
287TEST_F(ResourceSchedulerTest, OneIsolatedLowRequest) {
288  scoped_ptr<TestRequest> request(NewRequest("http://host/1", net::LOWEST));
289  EXPECT_TRUE(request->started());
290}
291
292TEST_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
303TEST_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
315TEST_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
328TEST_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
345TEST_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
356TEST_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
363TEST_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
378TEST_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
402TEST_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
448TEST_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
460TEST_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
488TEST_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
519TEST_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
549TEST_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
572TEST_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
582TEST_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
597TEST_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
614TEST_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
628TEST_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
659TEST_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
672TEST_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
686TEST_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
703TEST_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
720TEST_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
738TEST_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
758TEST_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
778TEST_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
803TEST_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
830TEST_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
851TEST_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
874TEST_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
900TEST_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
925TEST_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
941TEST_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
962TEST_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
978TEST_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
1000TEST_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
1043TEST_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
1099TEST_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
1156TEST_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
1211TEST_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
1268TEST_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
1336TEST_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
1406TEST_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
1474TEST_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
1545TEST_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
1615TEST_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
1669TEST_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
1734TEST_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
1785TEST_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
1799TEST_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
1827TEST_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
1854TEST_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
1873TEST_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
1902TEST_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
1933TEST_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
1963TEST_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
1990TEST_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
2014TEST_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
2083TEST_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
2117TEST_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
2181