diff options
author | joi@chromium.org <joi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-17 15:35:07 +0000 |
---|---|---|
committer | joi@chromium.org <joi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-17 15:35:07 +0000 |
commit | cade5686b5ec6a116543bbc29dc4f6a1068d5c17 (patch) | |
tree | d0f59d8c3218ca749c6378fcab26431df24e723d /net/url_request | |
parent | 47f1c5806ddbdf336db68b4274a7d9f3fba5b3ba (diff) | |
download | chromium_src-cade5686b5ec6a116543bbc29dc4f6a1068d5c17.zip chromium_src-cade5686b5ec6a116543bbc29dc4f6a1068d5c17.tar.gz chromium_src-cade5686b5ec6a116543bbc29dc4f6a1068d5c17.tar.bz2 |
Extracting core back-off logic into a separate class,
BackoffEntry. Simplifying the logic slightly while I'm there,
removing special support for "after the fact" malformed
bodies (the error count doesn't need to be 100% accurate) and
removing a constant value added to back-off times (it was only
being added once anyway, had close to zero effect).
Modifying URLRequestThrottlerEntry and related tests to use the
new class instead of co-mingling sliding window logic and
exponential back-off logic.
Removing now-unnecessary StressTest and associated ugly
wart "SetEntryLifetimeMsForTest" method on the
URLRequestThrottlerEntryInterface class.
Fixing up a few minor things e.g. #pragma once while I'm in
there.
BUG=none
TEST=net_unittests.exe, unit_tests.exe
Review URL: http://codereview.chromium.org/6697001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@78548 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/url_request')
-rw-r--r-- | net/url_request/url_request_throttler_entry.cc | 152 | ||||
-rw-r--r-- | net/url_request/url_request_throttler_entry.h | 48 | ||||
-rw-r--r-- | net/url_request/url_request_throttler_entry_interface.h | 4 | ||||
-rw-r--r-- | net/url_request/url_request_throttler_header_adapter.h | 1 | ||||
-rw-r--r-- | net/url_request/url_request_throttler_manager.h | 1 | ||||
-rw-r--r-- | net/url_request/url_request_throttler_unittest.cc | 109 |
6 files changed, 107 insertions, 208 deletions
diff --git a/net/url_request/url_request_throttler_entry.cc b/net/url_request/url_request_throttler_entry.cc index 033787b..05b2af2 100644 --- a/net/url_request/url_request_throttler_entry.cc +++ b/net/url_request/url_request_throttler_entry.cc @@ -16,7 +16,6 @@ namespace net { const int URLRequestThrottlerEntry::kDefaultSlidingWindowPeriodMs = 2000; const int URLRequestThrottlerEntry::kDefaultMaxSendThreshold = 20; const int URLRequestThrottlerEntry::kDefaultInitialBackoffMs = 700; -const int URLRequestThrottlerEntry::kDefaultAdditionalConstantMs = 100; const double URLRequestThrottlerEntry::kDefaultMultiplyFactor = 1.4; const double URLRequestThrottlerEntry::kDefaultJitterFactor = 0.4; const int URLRequestThrottlerEntry::kDefaultMaximumBackoffMs = 60 * 60 * 1000; @@ -27,12 +26,7 @@ URLRequestThrottlerEntry::URLRequestThrottlerEntry() : sliding_window_period_( base::TimeDelta::FromMilliseconds(kDefaultSlidingWindowPeriodMs)), max_send_threshold_(kDefaultMaxSendThreshold), - initial_backoff_ms_(kDefaultInitialBackoffMs), - additional_constant_ms_(kDefaultAdditionalConstantMs), - multiply_factor_(kDefaultMultiplyFactor), - jitter_factor_(kDefaultJitterFactor), - maximum_backoff_ms_(kDefaultMaximumBackoffMs), - entry_lifetime_ms_(kDefaultEntryLifetimeMs) { + backoff_entry_(&backoff_policy_) { Initialize(); } @@ -40,77 +34,54 @@ URLRequestThrottlerEntry::URLRequestThrottlerEntry( int sliding_window_period_ms, int max_send_threshold, int initial_backoff_ms, - int additional_constant_ms, double multiply_factor, double jitter_factor, int maximum_backoff_ms) : sliding_window_period_( base::TimeDelta::FromMilliseconds(sliding_window_period_ms)), max_send_threshold_(max_send_threshold), - initial_backoff_ms_(initial_backoff_ms), - additional_constant_ms_(additional_constant_ms), - multiply_factor_(multiply_factor), - jitter_factor_(jitter_factor), - maximum_backoff_ms_(maximum_backoff_ms), - entry_lifetime_ms_(-1) { + backoff_entry_(&backoff_policy_) { DCHECK_GT(sliding_window_period_ms, 0); DCHECK_GT(max_send_threshold_, 0); - DCHECK_GE(initial_backoff_ms_, 0); - DCHECK_GE(additional_constant_ms_, 0); - DCHECK_GT(multiply_factor_, 0); - DCHECK_GE(jitter_factor_, 0); - DCHECK_LT(jitter_factor_, 1); - DCHECK_GE(maximum_backoff_ms_, 0); + DCHECK_GE(initial_backoff_ms, 0); + DCHECK_GT(multiply_factor, 0); + DCHECK_GE(jitter_factor, 0.0); + DCHECK_LT(jitter_factor, 1.0); + DCHECK_GE(maximum_backoff_ms, 0); Initialize(); + backoff_policy_.initial_backoff_ms = initial_backoff_ms; + backoff_policy_.multiply_factor = multiply_factor; + backoff_policy_.jitter_factor = jitter_factor; + backoff_policy_.maximum_backoff_ms = maximum_backoff_ms; + backoff_policy_.entry_lifetime_ms = -1; } bool URLRequestThrottlerEntry::IsEntryOutdated() const { - CHECK(this); // to help track crbug.com/71721 - if (entry_lifetime_ms_ == -1) - return false; - - base::TimeTicks now = GetTimeNow(); - // If there are send events in the sliding window period, we still need this // entry. if (!send_log_.empty() && - send_log_.back() + sliding_window_period_ > now) { + send_log_.back() + sliding_window_period_ > GetTimeNow()) { return false; } - int64 unused_since_ms = - (now - exponential_backoff_release_time_).InMilliseconds(); - - // Release time is further than now, we are managing it. - if (unused_since_ms < 0) - return false; - - // latest_response_was_failure_ is true indicates that the latest one or - // more requests encountered server errors or had malformed response bodies. - // In that case, we don't want to collect the entry unless it hasn't been used - // for longer than the maximum allowed back-off. - if (latest_response_was_failure_) - return unused_since_ms > std::max(maximum_backoff_ms_, entry_lifetime_ms_); - - // Otherwise, consider the entry is outdated if it hasn't been used for the - // specified lifetime period. - return unused_since_ms > entry_lifetime_ms_; + return GetBackoffEntry()->CanDiscard(); } bool URLRequestThrottlerEntry::IsDuringExponentialBackoff() const { - return exponential_backoff_release_time_ > GetTimeNow(); + return GetBackoffEntry()->ShouldRejectRequest(); } int64 URLRequestThrottlerEntry::ReserveSendingTimeForNextRequest( const base::TimeTicks& earliest_time) { base::TimeTicks now = GetTimeNow(); + // If a lot of requests were successfully made recently, // sliding_window_release_time_ may be greater than // exponential_backoff_release_time_. base::TimeTicks recommended_sending_time = std::max(std::max(now, earliest_time), - std::max(exponential_backoff_release_time_, + std::max(GetBackoffEntry()->GetReleaseTime(), sliding_window_release_time_)); DCHECK(send_log_.empty() || @@ -138,34 +109,15 @@ int64 URLRequestThrottlerEntry::ReserveSendingTimeForNextRequest( base::TimeTicks URLRequestThrottlerEntry::GetExponentialBackoffReleaseTime() const { - return exponential_backoff_release_time_; + return GetBackoffEntry()->GetReleaseTime(); } void URLRequestThrottlerEntry::UpdateWithResponse( const URLRequestThrottlerHeaderInterface* response) { if (response->GetResponseCode() >= 500) { - failure_count_++; - latest_response_was_failure_ = true; - exponential_backoff_release_time_ = - CalculateExponentialBackoffReleaseTime(); + GetBackoffEntry()->InformOfRequest(false); } else { - // We slowly decay the number of times delayed instead of resetting it to 0 - // in order to stay stable if we received lots of requests with - // malformed bodies at the same time. - if (failure_count_ > 0) - failure_count_--; - - latest_response_was_failure_ = false; - - // The reason why we are not just cutting the release time to GetTimeNow() - // is on the one hand, it would unset delay put by our custom retry-after - // header and on the other we would like to push every request up to our - // "horizon" when dealing with multiple in-flight requests. Ex: If we send - // three requests and we receive 2 failures and 1 success. The success that - // follows those failures will not reset the release time, further requests - // will then need to wait the delay caused by the 2 failures. - exponential_backoff_release_time_ = std::max( - GetTimeNow(), exponential_backoff_release_time_); + GetBackoffEntry()->InformOfRequest(true); std::string retry_header = response->GetNormalizedValue(kRetryHeaderName); if (!retry_header.empty()) @@ -174,49 +126,26 @@ void URLRequestThrottlerEntry::UpdateWithResponse( } void URLRequestThrottlerEntry::ReceivedContentWasMalformed() { - // For any response that is marked as malformed now, we have probably - // considered it as a success when receiving it and decreased the failure - // count by 1. As a result, we increase the failure count by 2 here to undo - // the effect and record a failure. + // We keep this simple and just count it as a single error. // - // Please note that this may lead to a larger failure count than expected, - // because we don't decrease the failure count for successful responses when - // it has already reached 0. - failure_count_ += 2; - latest_response_was_failure_ = true; - exponential_backoff_release_time_ = CalculateExponentialBackoffReleaseTime(); -} - -void URLRequestThrottlerEntry::SetEntryLifetimeMsForTest(int lifetime_ms) { - entry_lifetime_ms_ = lifetime_ms; + // If we wanted to get fancy, we would count two errors here, and decrease + // the error count only by one when we receive a successful (by status + // code) response. Instead, we keep things simple by always resetting the + // error count on success, and therefore counting only a single error here. + GetBackoffEntry()->InformOfRequest(false); } URLRequestThrottlerEntry::~URLRequestThrottlerEntry() { } void URLRequestThrottlerEntry::Initialize() { - // Since this method is called by the constructors, GetTimeNow() (a virtual - // method) is not used. - exponential_backoff_release_time_ = base::TimeTicks::Now(); - failure_count_ = 0; - latest_response_was_failure_ = false; - sliding_window_release_time_ = base::TimeTicks::Now(); -} - -base::TimeTicks - URLRequestThrottlerEntry::CalculateExponentialBackoffReleaseTime() { - double delay = initial_backoff_ms_; - delay *= pow(multiply_factor_, failure_count_); - delay += additional_constant_ms_; - delay -= base::RandDouble() * jitter_factor_ * delay; - - // Ensure that we do not exceed maximum delay. - int64 delay_int = static_cast<int64>(delay + 0.5); - delay_int = std::min(delay_int, static_cast<int64>(maximum_backoff_ms_)); - - return std::max(GetTimeNow() + base::TimeDelta::FromMilliseconds(delay_int), - exponential_backoff_release_time_); + backoff_policy_.num_errors_to_ignore = 0; + backoff_policy_.initial_backoff_ms = kDefaultInitialBackoffMs; + backoff_policy_.multiply_factor = kDefaultMultiplyFactor; + backoff_policy_.jitter_factor = kDefaultJitterFactor; + backoff_policy_.maximum_backoff_ms = kDefaultMaximumBackoffMs; + backoff_policy_.entry_lifetime_ms = kDefaultEntryLifetimeMs; } base::TimeTicks URLRequestThrottlerEntry::GetTimeNow() const { @@ -236,12 +165,21 @@ void URLRequestThrottlerEntry::HandleCustomRetryAfter( // We must use an int value later so we transform this in milliseconds. int64 value_ms = static_cast<int64>(0.5 + time_in_sec * 1000); - if (maximum_backoff_ms_ < value_ms || value_ms < 0) + // We do not check for an upper bound; the server can set any Retry-After it + // desires. Recovery from error would involve restarting the browser. + if (value_ms < 0) return; - exponential_backoff_release_time_ = std::max( - (GetTimeNow() + base::TimeDelta::FromMilliseconds(value_ms)), - exponential_backoff_release_time_); + GetBackoffEntry()->SetCustomReleaseTime( + GetTimeNow() + base::TimeDelta::FromMilliseconds(value_ms)); +} + +const BackoffEntry* URLRequestThrottlerEntry::GetBackoffEntry() const { + return &backoff_entry_; +} + +BackoffEntry* URLRequestThrottlerEntry::GetBackoffEntry() { + return &backoff_entry_; } } // namespace net diff --git a/net/url_request/url_request_throttler_entry.h b/net/url_request/url_request_throttler_entry.h index cefe8d2..ddea919 100644 --- a/net/url_request/url_request_throttler_entry.h +++ b/net/url_request/url_request_throttler_entry.h @@ -4,11 +4,13 @@ #ifndef NET_URL_REQUEST_URL_REQUEST_THROTTLER_ENTRY_H_ #define NET_URL_REQUEST_URL_REQUEST_THROTTLER_ENTRY_H_ +#pragma once #include <queue> #include <string> #include "base/basictypes.h" +#include "net/base/backoff_entry.h" #include "net/url_request/url_request_throttler_entry_interface.h" namespace net { @@ -35,9 +37,6 @@ class URLRequestThrottlerEntry : public URLRequestThrottlerEntryInterface { // Initial delay for exponential back-off. static const int kDefaultInitialBackoffMs; - // Additional constant to adjust back-off. - static const int kDefaultAdditionalConstantMs; - // Factor by which the waiting time will be multiplied. static const double kDefaultMultiplyFactor; @@ -63,7 +62,6 @@ class URLRequestThrottlerEntry : public URLRequestThrottlerEntryInterface { URLRequestThrottlerEntry(int sliding_window_period_ms, int max_send_threshold, int initial_backoff_ms, - int additional_constant_ms, double multiply_factor, double jitter_factor, int maximum_backoff_ms); @@ -80,27 +78,22 @@ class URLRequestThrottlerEntry : public URLRequestThrottlerEntryInterface { virtual void UpdateWithResponse( const URLRequestThrottlerHeaderInterface* response); virtual void ReceivedContentWasMalformed(); - virtual void SetEntryLifetimeMsForTest(int lifetime_ms); protected: virtual ~URLRequestThrottlerEntry(); void Initialize(); - // Calculates the release time for exponential back-off. - base::TimeTicks CalculateExponentialBackoffReleaseTime(); - // Equivalent to TimeTicks::Now(), virtual to be mockable for testing purpose. virtual base::TimeTicks GetTimeNow() const; // Used internally to increase release time following a retry-after header. void HandleCustomRetryAfter(const std::string& header_value); - // Used by tests. - void set_exponential_backoff_release_time( - const base::TimeTicks& release_time) { - exponential_backoff_release_time_ = release_time; - } + // Retrieves the backoff entry object we're using. Used to enable a + // unit testing seam for dependency injection in tests. + virtual const BackoffEntry* GetBackoffEntry() const; + virtual BackoffEntry* GetBackoffEntry(); // Used by tests. base::TimeTicks sliding_window_release_time() const { @@ -112,25 +105,10 @@ class URLRequestThrottlerEntry : public URLRequestThrottlerEntryInterface { sliding_window_release_time_ = release_time; } - // Used by tests. - void set_failure_count(int failure_count) { - failure_count_ = failure_count; - } + // Valid and immutable after construction time. + BackoffEntry::Policy backoff_policy_; private: - // Timestamp calculated by the exponential back-off algorithm at which we are - // allowed to start sending requests again. - base::TimeTicks exponential_backoff_release_time_; - - // Number of times we encounter server errors or malformed response bodies. - int failure_count_; - - // If true, the last request response was a failure. - // Note that this member can be false at the same time as failure_count_ can - // be greater than 0, since we gradually decrease failure_count_, instead of - // resetting it to 0 directly, when we receive successful responses. - bool latest_response_was_failure_; - // Timestamp calculated by the sliding window algorithm for when we advise // clients the next request should be made, at the earliest. Advisory only, // not used to deny requests. @@ -142,13 +120,9 @@ class URLRequestThrottlerEntry : public URLRequestThrottlerEntryInterface { const base::TimeDelta sliding_window_period_; const int max_send_threshold_; - const int initial_backoff_ms_; - const int additional_constant_ms_; - const double multiply_factor_; - const double jitter_factor_; - const int maximum_backoff_ms_; - // Set to -1 if the entry never expires. - int entry_lifetime_ms_; + + // Access it through GetBackoffEntry() to allow a unit test seam. + BackoffEntry backoff_entry_; DISALLOW_COPY_AND_ASSIGN(URLRequestThrottlerEntry); }; diff --git a/net/url_request/url_request_throttler_entry_interface.h b/net/url_request/url_request_throttler_entry_interface.h index e3fc5ba..63dd14c 100644 --- a/net/url_request/url_request_throttler_entry_interface.h +++ b/net/url_request/url_request_throttler_entry_interface.h @@ -4,6 +4,7 @@ #ifndef NET_URL_REQUEST_URL_REQUEST_THROTTLER_ENTRY_INTERFACE_H_ #define NET_URL_REQUEST_URL_REQUEST_THROTTLER_ENTRY_INTERFACE_H_ +#pragma once #include "base/basictypes.h" #include "base/ref_counted.h" @@ -50,9 +51,6 @@ class URLRequestThrottlerEntryInterface // the request, i.e. it will count as a failure. virtual void ReceivedContentWasMalformed() = 0; - // For unit testing only. - virtual void SetEntryLifetimeMsForTest(int lifetime_ms) = 0; - protected: friend class base::RefCountedThreadSafe<URLRequestThrottlerEntryInterface>; virtual ~URLRequestThrottlerEntryInterface() {} diff --git a/net/url_request/url_request_throttler_header_adapter.h b/net/url_request/url_request_throttler_header_adapter.h index 35d363e..a360747 100644 --- a/net/url_request/url_request_throttler_header_adapter.h +++ b/net/url_request/url_request_throttler_header_adapter.h @@ -4,6 +4,7 @@ #ifndef NET_URL_REQUEST_URL_REQUEST_THROTTLER_HEADER_ADAPTER_H_ #define NET_URL_REQUEST_URL_REQUEST_THROTTLER_HEADER_ADAPTER_H_ +#pragma once #include <string> diff --git a/net/url_request/url_request_throttler_manager.h b/net/url_request/url_request_throttler_manager.h index d1ede1d..1cd2b5c 100644 --- a/net/url_request/url_request_throttler_manager.h +++ b/net/url_request/url_request_throttler_manager.h @@ -4,6 +4,7 @@ #ifndef NET_URL_REQUEST_URL_REQUEST_THROTTLER_MANAGER_H_ #define NET_URL_REQUEST_URL_REQUEST_THROTTLER_MANAGER_H_ +#pragma once #include <map> #include <string> diff --git a/net/url_request/url_request_throttler_unittest.cc b/net/url_request/url_request_throttler_unittest.cc index 7d4e739..4aed38c 100644 --- a/net/url_request/url_request_throttler_unittest.cc +++ b/net/url_request/url_request_throttler_unittest.cc @@ -19,23 +19,61 @@ using base::TimeTicks; namespace { class MockURLRequestThrottlerManager; +class MockBackoffEntry : public net::BackoffEntry { + public: + explicit MockBackoffEntry(const net::BackoffEntry::Policy* const policy) + : net::BackoffEntry(policy), fake_now_(TimeTicks()) { + } + + virtual ~MockBackoffEntry() {} + + TimeTicks GetTimeNow() const { + return fake_now_; + } + + void SetFakeNow(TimeTicks now) { + fake_now_ = now; + } + + private: + TimeTicks fake_now_; +}; + class MockURLRequestThrottlerEntry : public net::URLRequestThrottlerEntry { public : - MockURLRequestThrottlerEntry() {} + MockURLRequestThrottlerEntry() : mock_backoff_entry_(&backoff_policy_) { + // Some tests become flaky if we have jitter. + backoff_policy_.jitter_factor = 0.0; + } MockURLRequestThrottlerEntry( const TimeTicks& exponential_backoff_release_time, const TimeTicks& sliding_window_release_time, const TimeTicks& fake_now) - : fake_time_now_(fake_now) { + : fake_time_now_(fake_now), + mock_backoff_entry_(&backoff_policy_) { + // Some tests become flaky if we have jitter. + backoff_policy_.jitter_factor = 0.0; + + mock_backoff_entry_.SetFakeNow(fake_now); set_exponential_backoff_release_time(exponential_backoff_release_time); set_sliding_window_release_time(sliding_window_release_time); } virtual ~MockURLRequestThrottlerEntry() {} + const net::BackoffEntry* GetBackoffEntry() const { + return &mock_backoff_entry_; + } + + net::BackoffEntry* GetBackoffEntry() { + return &mock_backoff_entry_; + } + void ResetToBlank(const TimeTicks& time_now) { fake_time_now_ = time_now; - set_exponential_backoff_release_time(time_now); - set_failure_count(0); + mock_backoff_entry_.SetFakeNow(time_now); + + GetBackoffEntry()->InformOfRequest(true); // Sets failure count to 0. + GetBackoffEntry()->SetCustomReleaseTime(time_now); set_sliding_window_release_time(time_now); } @@ -44,8 +82,7 @@ class MockURLRequestThrottlerEntry : public net::URLRequestThrottlerEntry { void set_exponential_backoff_release_time( const base::TimeTicks& release_time) { - net::URLRequestThrottlerEntry::set_exponential_backoff_release_time( - release_time); + GetBackoffEntry()->SetCustomReleaseTime(release_time); } base::TimeTicks sliding_window_release_time() const { @@ -59,6 +96,7 @@ class MockURLRequestThrottlerEntry : public net::URLRequestThrottlerEntry { } TimeTicks fake_time_now_; + MockBackoffEntry mock_backoff_entry_; }; class MockURLRequestThrottlerHeaderAdapter @@ -226,7 +264,8 @@ TEST_F(URLRequestThrottlerEntryTest, IsEntryReallyOutdated) { TimeAndBool(now_, false, __LINE__), TimeAndBool(now_ - kFiveMs, false, __LINE__), TimeAndBool(now_ + kFiveMs, false, __LINE__), - TimeAndBool(now_ - lifetime, false, __LINE__), + TimeAndBool(now_ - (lifetime - kFiveMs), false, __LINE__), + TimeAndBool(now_ - lifetime, true, __LINE__), TimeAndBool(now_ - (lifetime + kFiveMs), true, __LINE__)}; for (unsigned int i = 0; i < arraysize(test_values); ++i) { @@ -352,59 +391,7 @@ TEST(URLRequestThrottlerManager, IsHostBeingRegistered) { EXPECT_EQ(3, manager.GetNumberOfEntries()); } -class DummyResponseHeaders : public net::URLRequestThrottlerHeaderInterface { - public: - DummyResponseHeaders(int response_code) : response_code_(response_code) {} - - std::string GetNormalizedValue(const std::string& key) const { - return ""; - } - - // Returns the HTTP response code associated with the request. - int GetResponseCode() const { - return response_code_; - } - - private: - int response_code_; -}; - -TEST(URLRequestThrottlerManager, StressTest) { - MockURLRequestThrottlerManager manager; - - for (int i = 0; i < 10000; ++i) { - // Make some entries duplicates or triplicates. - int entry_number = i + 2; - if (i % 17 == 0) { - entry_number = i - 1; - } else if ((i - 1) % 17 == 0) { - entry_number = i - 2; - } else if (i % 13 == 0) { - entry_number = i - 1; - } - - scoped_refptr<net::URLRequestThrottlerEntryInterface> entry = - manager.RegisterRequestUrl(GURL(StringPrintf( - "http://bingourl.com/%d", entry_number))); - entry->IsDuringExponentialBackoff(); - entry->GetExponentialBackoffReleaseTime(); - - DummyResponseHeaders headers(i % 7 == 0 ? 500 : 200); - entry->UpdateWithResponse(&headers); - entry->SetEntryLifetimeMsForTest(1); - - entry->IsDuringExponentialBackoff(); - entry->GetExponentialBackoffReleaseTime(); - entry->ReserveSendingTimeForNextRequest(base::TimeTicks::Now()); - - if (i % 11 == 0) { - manager.DoGarbageCollectEntries(); - } - } -} - -// TODO(joi): Remove the debug-only condition after M11 branch point. -#if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG) +#if defined(GTEST_HAS_DEATH_TEST) TEST(URLRequestThrottlerManager, NullHandlingTest) { MockURLRequestThrottlerManager manager; manager.OverrideEntryForTests(GURL("http://www.foo.com/"), NULL); @@ -412,4 +399,4 @@ TEST(URLRequestThrottlerManager, NullHandlingTest) { manager.DoGarbageCollectEntries(); }, ""); } -#endif // defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG) +#endif // defined(GTEST_HAS_DEATH_TEST) |