15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_throttler_manager.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram_samples.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/pickle.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_number_conversions.h"
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/strings/stringprintf.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/test/statistics_delta_reader.h"
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/load_flags.h"
160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "net/base/request_priority.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/test_completion_callback.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_test_util.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_throttler_header_interface.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_throttler_test_support.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeTicks;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kRequestThrottledHistogramName[] = "Throttling.RequestThrottled";
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockURLRequestThrottlerEntry : public URLRequestThrottlerEntry {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit MockURLRequestThrottlerEntry(
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::URLRequestThrottlerManager* manager)
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : net::URLRequestThrottlerEntry(manager, std::string()),
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mock_backoff_entry_(&backoff_policy_) {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InitPolicy();
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockURLRequestThrottlerEntry(
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::URLRequestThrottlerManager* manager,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const TimeTicks& exponential_backoff_release_time,
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const TimeTicks& sliding_window_release_time,
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const TimeTicks& fake_now)
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : net::URLRequestThrottlerEntry(manager, std::string()),
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fake_time_now_(fake_now),
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mock_backoff_entry_(&backoff_policy_) {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InitPolicy();
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_backoff_entry_.set_fake_now(fake_now);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    set_exponential_backoff_release_time(exponential_backoff_release_time);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    set_sliding_window_release_time(sliding_window_release_time);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InitPolicy() {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Some tests become flaky if we have jitter.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backoff_policy_.jitter_factor = 0.0;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This lets us avoid having to make multiple failures initially (this
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // logic is already tested in the BackoffEntry unit tests).
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backoff_policy_.num_errors_to_ignore = 0;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual const BackoffEntry* GetBackoffEntry() const OVERRIDE {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return &mock_backoff_entry_;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual BackoffEntry* GetBackoffEntry() OVERRIDE {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return &mock_backoff_entry_;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool ExplicitUserRequest(int load_flags) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return URLRequestThrottlerEntry::ExplicitUserRequest(load_flags);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ResetToBlank(const TimeTicks& time_now) {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fake_time_now_ = time_now;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_backoff_entry_.set_fake_now(time_now);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetBackoffEntry()->Reset();
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetBackoffEntry()->SetCustomReleaseTime(time_now);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    set_sliding_window_release_time(time_now);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden for tests.
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual TimeTicks ImplGetTimeNow() const OVERRIDE { return fake_time_now_; }
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_exponential_backoff_release_time(
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const base::TimeTicks& release_time) {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetBackoffEntry()->SetCustomReleaseTime(release_time);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeTicks sliding_window_release_time() const {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return URLRequestThrottlerEntry::sliding_window_release_time();
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_sliding_window_release_time(
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const base::TimeTicks& release_time) {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    URLRequestThrottlerEntry::set_sliding_window_release_time(
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        release_time);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks fake_time_now_;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockBackoffEntry mock_backoff_entry_;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~MockURLRequestThrottlerEntry() {}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockURLRequestThrottlerManager : public URLRequestThrottlerManager {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockURLRequestThrottlerManager() : create_entry_index_(0) {}
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Method to process the URL using URLRequestThrottlerManager protected
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // method.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string DoGetUrlIdFromUrl(const GURL& url) { return GetIdFromUrl(url); }
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Method to use the garbage collecting method of URLRequestThrottlerManager.
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DoGarbageCollectEntries() { GarbageCollectEntries(); }
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the number of entries in the map.
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int GetNumberOfEntries() const { return GetNumberOfEntriesForTests(); }
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CreateEntry(bool is_outdated) {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TimeTicks time = TimeTicks::Now();
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (is_outdated) {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      time -= TimeDelta::FromMilliseconds(
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          MockURLRequestThrottlerEntry::kDefaultEntryLifetimeMs + 1000);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string fake_url_string("http://www.fakeurl.com/");
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fake_url_string.append(base::IntToString(create_entry_index_++));
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL fake_url(fake_url_string);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OverrideEntryForTests(
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fake_url,
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new MockURLRequestThrottlerEntry(this, time, TimeTicks::Now(),
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         TimeTicks::Now()));
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int create_entry_index_;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct TimeAndBool {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeAndBool(const TimeTicks& time_value, bool expected, int line_num) {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    time = time_value;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result = expected;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    line = line_num;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks time;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int line;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct GurlAndString {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GurlAndString(const GURL& url_value,
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                const std::string& expected,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                int line_num) {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url = url_value;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result = expected;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    line = line_num;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string result;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int line;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class URLRequestThrottlerEntryTest : public testing::Test {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  URLRequestThrottlerEntryTest()
1730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      : request_(GURL(), DEFAULT_PRIORITY, NULL, &context_) {}
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void SetUp();
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks now_;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockURLRequestThrottlerManager manager_;  // Dummy object, not used.
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockURLRequestThrottlerEntry> entry_;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestURLRequestContext context_;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestURLRequest request_;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestThrottlerEntryTest::SetUp() {
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  request_.SetLoadFlags(0);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  now_ = TimeTicks::Now();
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry_ = new MockURLRequestThrottlerEntry(&manager_);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry_->ResetToBlank(now_);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::ostream& operator<<(std::ostream& out, const base::TimeTicks& time) {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return out << time.ToInternalValue();
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(URLRequestThrottlerEntryTest, CanThrottleRequest) {
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  TestNetworkDelegate d;
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  context_.set_network_delegate(&d);
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  entry_->set_exponential_backoff_release_time(
201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      entry_->fake_time_now_ + TimeDelta::FromMilliseconds(1));
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  d.set_can_throttle_requests(false);
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(entry_->ShouldRejectRequest(request_));
205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  d.set_can_throttle_requests(true);
206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(entry_->ShouldRejectRequest(request_));
207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(URLRequestThrottlerEntryTest, InterfaceDuringExponentialBackoff) {
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::StatisticsDeltaReader statistics_delta_reader;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry_->set_exponential_backoff_release_time(
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entry_->fake_time_now_ + TimeDelta::FromMilliseconds(1));
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry_->ShouldRejectRequest(request_));
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Also end-to-end test the load flags exceptions.
216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  request_.SetLoadFlags(LOAD_MAYBE_USER_GESTURE);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(entry_->ShouldRejectRequest(request_));
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<base::HistogramSamples> samples(
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      statistics_delta_reader.GetHistogramSamplesSinceCreation(
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          kRequestThrottledHistogramName));
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(1, samples->GetCount(0));
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(1, samples->GetCount(1));
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(URLRequestThrottlerEntryTest, InterfaceNotDuringExponentialBackoff) {
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::StatisticsDeltaReader statistics_delta_reader;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry_->set_exponential_backoff_release_time(entry_->fake_time_now_);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(entry_->ShouldRejectRequest(request_));
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry_->set_exponential_backoff_release_time(
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entry_->fake_time_now_ - TimeDelta::FromMilliseconds(1));
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(entry_->ShouldRejectRequest(request_));
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<base::HistogramSamples> samples(
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      statistics_delta_reader.GetHistogramSamplesSinceCreation(
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          kRequestThrottledHistogramName));
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(2, samples->GetCount(0));
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(0, samples->GetCount(1));
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(URLRequestThrottlerEntryTest, InterfaceUpdateFailure) {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockURLRequestThrottlerHeaderAdapter failure_response(503);
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  entry_->UpdateWithResponse(std::string(), &failure_response);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(entry_->GetExponentialBackoffReleaseTime(), entry_->fake_time_now_)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << "A failure should increase the release_time";
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(URLRequestThrottlerEntryTest, InterfaceUpdateSuccess) {
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockURLRequestThrottlerHeaderAdapter success_response(200);
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  entry_->UpdateWithResponse(std::string(), &success_response);
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(entry_->GetExponentialBackoffReleaseTime(), entry_->fake_time_now_)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << "A success should not add any delay";
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(URLRequestThrottlerEntryTest, InterfaceUpdateSuccessThenFailure) {
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockURLRequestThrottlerHeaderAdapter failure_response(503);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockURLRequestThrottlerHeaderAdapter success_response(200);
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  entry_->UpdateWithResponse(std::string(), &success_response);
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  entry_->UpdateWithResponse(std::string(), &failure_response);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(entry_->GetExponentialBackoffReleaseTime(), entry_->fake_time_now_)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << "This scenario should add delay";
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  entry_->UpdateWithResponse(std::string(), &success_response);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(URLRequestThrottlerEntryTest, IsEntryReallyOutdated) {
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta lifetime = TimeDelta::FromMilliseconds(
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockURLRequestThrottlerEntry::kDefaultEntryLifetimeMs);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TimeDelta kFiveMs = TimeDelta::FromMilliseconds(5);
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeAndBool test_values[] = {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TimeAndBool(now_, false, __LINE__),
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TimeAndBool(now_ - kFiveMs, false, __LINE__),
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TimeAndBool(now_ + kFiveMs, false, __LINE__),
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TimeAndBool(now_ - (lifetime - kFiveMs), false, __LINE__),
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TimeAndBool(now_ - lifetime, true, __LINE__),
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TimeAndBool(now_ - (lifetime + kFiveMs), true, __LINE__)};
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (unsigned int i = 0; i < arraysize(test_values); ++i) {
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entry_->set_exponential_backoff_release_time(test_values[i].time);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(entry_->IsEntryOutdated(), test_values[i].result) <<
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "Test case #" << i << " line " << test_values[i].line << " failed";
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(URLRequestThrottlerEntryTest, MaxAllowedBackoff) {
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 30; ++i) {
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockURLRequestThrottlerHeaderAdapter response_adapter(503);
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    entry_->UpdateWithResponse(std::string(), &response_adapter);
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta delay = entry_->GetExponentialBackoffReleaseTime() - now_;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(delay.InMilliseconds(),
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            MockURLRequestThrottlerEntry::kDefaultMaximumBackoffMs);
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(URLRequestThrottlerEntryTest, MalformedContent) {
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockURLRequestThrottlerHeaderAdapter response_adapter(503);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 5; ++i)
299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    entry_->UpdateWithResponse(std::string(), &response_adapter);
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks release_after_failures = entry_->GetExponentialBackoffReleaseTime();
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Inform the entry that a response body was malformed, which is supposed to
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // increase the back-off time.  Note that we also submit a successful
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // UpdateWithResponse to pair with ReceivedContentWasMalformed() since that
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is what happens in practice (if a body is received, then a non-500
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // response must also have been received).
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry_->ReceivedContentWasMalformed(200);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockURLRequestThrottlerHeaderAdapter success_adapter(200);
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  entry_->UpdateWithResponse(std::string(), &success_adapter);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(entry_->GetExponentialBackoffReleaseTime(), release_after_failures);
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(URLRequestThrottlerEntryTest, SlidingWindow) {
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int max_send = URLRequestThrottlerEntry::kDefaultMaxSendThreshold;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int sliding_window =
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      URLRequestThrottlerEntry::kDefaultSlidingWindowPeriodMs;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks time_1 = entry_->fake_time_now_ +
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TimeDelta::FromMilliseconds(sliding_window / 3);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks time_2 = entry_->fake_time_now_ +
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TimeDelta::FromMilliseconds(2 * sliding_window / 3);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks time_3 = entry_->fake_time_now_ +
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TimeDelta::FromMilliseconds(sliding_window);
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks time_4 = entry_->fake_time_now_ +
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TimeDelta::FromMilliseconds(sliding_window + 2 * sliding_window / 3);
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry_->set_exponential_backoff_release_time(time_1);
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < max_send / 2; ++i) {
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(2 * sliding_window / 3,
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              entry_->ReserveSendingTimeForNextRequest(time_2));
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(time_2, entry_->sliding_window_release_time());
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry_->fake_time_now_ = time_3;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < (max_send + 1) / 2; ++i)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, entry_->ReserveSendingTimeForNextRequest(TimeTicks()));
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(time_4, entry_->sliding_window_release_time());
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(URLRequestThrottlerEntryTest, ExplicitUserRequest) {
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(MockURLRequestThrottlerEntry::ExplicitUserRequest(0));
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(MockURLRequestThrottlerEntry::ExplicitUserRequest(
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOAD_MAYBE_USER_GESTURE));
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(MockURLRequestThrottlerEntry::ExplicitUserRequest(
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ~LOAD_MAYBE_USER_GESTURE));
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class URLRequestThrottlerManagerTest : public testing::Test {
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestThrottlerManagerTest()
3550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      : request_(GURL(), DEFAULT_PRIORITY, NULL, &context_) {}
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    request_.SetLoadFlags(0);
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // context_ must be declared before request_.
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestURLRequestContext context_;
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestURLRequest request_;
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(URLRequestThrottlerManagerTest, IsUrlStandardised) {
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockURLRequestThrottlerManager manager;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GurlAndString test_values[] = {
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GurlAndString(GURL("http://www.example.com"),
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    std::string("http://www.example.com/"),
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    __LINE__),
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GurlAndString(GURL("http://www.Example.com"),
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    std::string("http://www.example.com/"),
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    __LINE__),
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GurlAndString(GURL("http://www.ex4mple.com/Pr4c71c41"),
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    std::string("http://www.ex4mple.com/pr4c71c41"),
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    __LINE__),
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GurlAndString(GURL("http://www.example.com/0/token/false"),
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    std::string("http://www.example.com/0/token/false"),
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    __LINE__),
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GurlAndString(GURL("http://www.example.com/index.php?code=javascript"),
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    std::string("http://www.example.com/index.php"),
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    __LINE__),
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GurlAndString(GURL("http://www.example.com/index.php?code=1#superEntry"),
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    std::string("http://www.example.com/index.php"),
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    __LINE__),
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GurlAndString(GURL("http://www.example.com/index.php#superEntry"),
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    std::string("http://www.example.com/index.php"),
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    __LINE__),
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GurlAndString(GURL("http://www.example.com:1234/"),
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    std::string("http://www.example.com:1234/"),
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    __LINE__)};
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (unsigned int i = 0; i < arraysize(test_values); ++i) {
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string temp = manager.DoGetUrlIdFromUrl(test_values[i].url);
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(temp, test_values[i].result) <<
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "Test case #" << i << " line " << test_values[i].line << " failed";
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(URLRequestThrottlerManagerTest, AreEntriesBeingCollected) {
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockURLRequestThrottlerManager manager;
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manager.CreateEntry(true);  // true = Entry is outdated.
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manager.CreateEntry(true);
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manager.CreateEntry(true);
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manager.DoGarbageCollectEntries();
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, manager.GetNumberOfEntries());
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manager.CreateEntry(false);
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manager.CreateEntry(false);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manager.CreateEntry(false);
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manager.CreateEntry(true);
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manager.DoGarbageCollectEntries();
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, manager.GetNumberOfEntries());
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(URLRequestThrottlerManagerTest, IsHostBeingRegistered) {
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockURLRequestThrottlerManager manager;
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manager.RegisterRequestUrl(GURL("http://www.example.com/"));
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manager.RegisterRequestUrl(GURL("http://www.google.com/"));
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manager.RegisterRequestUrl(GURL("http://www.google.com/index/0"));
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manager.RegisterRequestUrl(GURL("http://www.google.com/index/0?code=1"));
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manager.RegisterRequestUrl(GURL("http://www.google.com/index/0#lolsaure"));
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, manager.GetNumberOfEntries());
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExpectEntryAllowsAllOnErrorIfOptedOut(
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::URLRequestThrottlerEntryInterface* entry,
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool opted_out,
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const URLRequest& request) {
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(entry->ShouldRejectRequest(request));
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockURLRequestThrottlerHeaderAdapter failure_adapter(503);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 10; ++i) {
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Host doesn't really matter in this scenario so we skip it.
438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    entry->UpdateWithResponse(std::string(), &failure_adapter);
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(opted_out, entry->ShouldRejectRequest(request));
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (opted_out) {
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We're not mocking out GetTimeNow() in this scenario
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // so add a 100 ms buffer to avoid flakiness (that should always
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // give enough time to get from the TimeTicks::Now() call here
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // to the TimeTicks::Now() call in the entry class).
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_GT(TimeTicks::Now() + TimeDelta::FromMilliseconds(100),
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              entry->GetExponentialBackoffReleaseTime());
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // As above, add 100 ms.
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_LT(TimeTicks::Now() + TimeDelta::FromMilliseconds(100),
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              entry->GetExponentialBackoffReleaseTime());
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(URLRequestThrottlerManagerTest, OptOutHeader) {
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockURLRequestThrottlerManager manager;
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<net::URLRequestThrottlerEntryInterface> entry =
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      manager.RegisterRequestUrl(GURL("http://www.google.com/yodude"));
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fake a response with the opt-out header.
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockURLRequestThrottlerHeaderAdapter response_adapter(
463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      std::string(),
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockURLRequestThrottlerEntry::kExponentialThrottlingDisableValue,
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      200);
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry->UpdateWithResponse("www.google.com", &response_adapter);
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that the same entry on error always allows everything.
469868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ExpectEntryAllowsAllOnErrorIfOptedOut(entry.get(), true, request_);
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that a freshly created entry (for a different URL on an
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // already opted-out host) also gets "always allow" behavior.
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<net::URLRequestThrottlerEntryInterface> other_entry =
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      manager.RegisterRequestUrl(GURL("http://www.google.com/bingobob"));
475868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ExpectEntryAllowsAllOnErrorIfOptedOut(other_entry.get(), true, request_);
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fake a response with the opt-out header incorrectly specified.
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<net::URLRequestThrottlerEntryInterface> no_opt_out_entry =
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      manager.RegisterRequestUrl(GURL("http://www.nike.com/justdoit"));
480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockURLRequestThrottlerHeaderAdapter wrong_adapter(
481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      std::string(), "yesplease", 200);
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  no_opt_out_entry->UpdateWithResponse("www.nike.com", &wrong_adapter);
483868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ExpectEntryAllowsAllOnErrorIfOptedOut(
484868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      no_opt_out_entry.get(), false, request_);
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A localhost entry should always be opted out.
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<net::URLRequestThrottlerEntryInterface> localhost_entry =
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      manager.RegisterRequestUrl(GURL("http://localhost/hello"));
489868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ExpectEntryAllowsAllOnErrorIfOptedOut(localhost_entry.get(), true, request_);
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(URLRequestThrottlerManagerTest, ClearOnNetworkChange) {
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 3; ++i) {
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockURLRequestThrottlerManager manager;
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::URLRequestThrottlerEntryInterface> entry_before =
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        manager.RegisterRequestUrl(GURL("http://www.example.com/"));
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockURLRequestThrottlerHeaderAdapter failure_adapter(503);
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int j = 0; j < 10; ++j) {
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Host doesn't really matter in this scenario so we skip it.
500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      entry_before->UpdateWithResponse(std::string(), &failure_adapter);
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(entry_before->ShouldRejectRequest(request_));
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (i) {
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case 0:
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        manager.OnIPAddressChanged();
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case 1:
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        manager.OnConnectionTypeChanged(
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            net::NetworkChangeNotifier::CONNECTION_UNKNOWN);
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case 2:
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        manager.OnConnectionTypeChanged(
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            net::NetworkChangeNotifier::CONNECTION_NONE);
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FAIL();
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::URLRequestThrottlerEntryInterface> entry_after =
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        manager.RegisterRequestUrl(GURL("http://www.example.com/"));
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(entry_after->ShouldRejectRequest(request_));
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
527