Chromium Code Reviews| Index: chrome/renderer/net/net_error_helper_core_unittest.cc |
| diff --git a/chrome/renderer/net/net_error_helper_core_unittest.cc b/chrome/renderer/net/net_error_helper_core_unittest.cc |
| index fc18323bb5db54540144cabcdbd288a94b25a456..e1afdb223d12dc40b7f6e6b4c035508dcc2f797d 100644 |
| --- a/chrome/renderer/net/net_error_helper_core_unittest.cc |
| +++ b/chrome/renderer/net/net_error_helper_core_unittest.cc |
| @@ -109,12 +109,54 @@ std::string NetErrorString(net::Error net_error) { |
| return ErrorToString(NetError(net_error), false); |
| } |
| +class MockOneShotTimer : public MockableOneShotTimer { |
| + public: |
| + MockOneShotTimer() : running_(false) {} |
| + virtual ~MockOneShotTimer() {} |
| + |
| + virtual void Start(const tracked_objects::Location& posted_from, |
| + base::TimeDelta delay, |
| + const base::Closure& task) OVERRIDE { |
| + EXPECT_FALSE(running_); |
| + task_ = task; |
| + running_ = true; |
| + delay_ = delay; |
| + } |
| + |
| + virtual void Stop() OVERRIDE { |
| + running_ = false; |
| + } |
| + |
| + virtual bool IsRunning() const OVERRIDE { |
| + return running_; |
| + } |
| + |
| + void Fire() { |
| + EXPECT_TRUE(running_); |
| + base::Closure temp_task = task_; |
| + running_ = false; |
| + task_.Reset(); |
| + temp_task.Run(); |
| + } |
| + |
| + base::TimeDelta delay() const { return delay_; } |
| + |
| + private: |
| + base::TimeDelta delay_; |
| + base::Closure task_; |
| + bool running_; |
| +}; |
| + |
| class NetErrorHelperCoreTest : public testing::Test, |
| public NetErrorHelperCore::Delegate { |
| public: |
| - NetErrorHelperCoreTest() : core_(this), |
| + NetErrorHelperCoreTest() : timer_(new MockOneShotTimer()), |
| + core_(this), |
| update_count_(0), |
| - error_html_update_count_(0) { |
| + error_html_update_count_(0), |
| + reload_count_(0) { |
| + core_.set_auto_reload_enabled(false); |
| + core_.set_timer_for_testing(scoped_ptr<MockableOneShotTimer>(timer_)); |
| } |
| virtual ~NetErrorHelperCoreTest() { |
| @@ -127,6 +169,10 @@ class NetErrorHelperCoreTest : public testing::Test, |
| const GURL& url_being_fetched() const { return url_being_fetched_; } |
| bool is_url_being_fetched() const { return !url_being_fetched_.is_empty(); } |
| + int reload_count() const { |
| + return reload_count_; |
| + } |
| + |
| const std::string& last_update_string() const { return last_update_string_; } |
| int update_count() const { return update_count_; } |
| @@ -137,6 +183,8 @@ class NetErrorHelperCoreTest : public testing::Test, |
| return last_error_page_params_.get(); |
| } |
| + MockOneShotTimer* timer() { return timer_; } |
| + |
| void NavigationCorrectionsLoadSuccess( |
| const NavigationCorrection* corrections, int num_corrections) { |
| NavigationCorrectionsLoadFinished( |
| @@ -152,6 +200,33 @@ class NetErrorHelperCoreTest : public testing::Test, |
| core().OnNavigationCorrectionsFetched(result, "en", false); |
| } |
| + void DoErrorLoad(net::Error error) { |
| + core().OnStartLoad(NetErrorHelperCore::MAIN_FRAME, |
| + NetErrorHelperCore::NON_ERROR_PAGE); |
| + std::string html; |
| + core().GetErrorHTML(NetErrorHelperCore::MAIN_FRAME, |
| + NetError(error), false, &html); |
| + EXPECT_FALSE(html.empty()); |
| + EXPECT_EQ(NetErrorString(error), html); |
| + |
| + core().OnStartLoad(NetErrorHelperCore::MAIN_FRAME, |
| + NetErrorHelperCore::ERROR_PAGE); |
| + core().OnCommitLoad(NetErrorHelperCore::MAIN_FRAME); |
| + core().OnFinishLoad(NetErrorHelperCore::MAIN_FRAME); |
| + } |
| + |
| + void DoSuccessLoad() { |
| + core().OnStartLoad(NetErrorHelperCore::MAIN_FRAME, |
| + NetErrorHelperCore::NON_ERROR_PAGE); |
| + core().OnCommitLoad(NetErrorHelperCore::MAIN_FRAME); |
| + core().OnFinishLoad(NetErrorHelperCore::MAIN_FRAME); |
| + } |
| + |
| + void DoDnsProbe(chrome_common_net::DnsProbeStatus final_status) { |
| + core().OnNetErrorInfo(chrome_common_net::DNS_PROBE_STARTED); |
| + core().OnNetErrorInfo(final_status); |
| + } |
| + |
| void EnableNavigationCorrections() { |
| SetNavigationCorrectionURL(GURL(kNavigationCorrectionUrl)); |
| } |
| @@ -215,6 +290,12 @@ class NetErrorHelperCoreTest : public testing::Test, |
| request_body_.clear(); |
| } |
| + virtual void ReloadPage() OVERRIDE { |
| + reload_count_++; |
| + } |
| + |
| + MockOneShotTimer* timer_; |
| + |
| NetErrorHelperCore core_; |
| GURL url_being_fetched_; |
| @@ -233,6 +314,8 @@ class NetErrorHelperCoreTest : public testing::Test, |
| // Mutable because GenerateLocalizedErrorPage is const. |
| mutable scoped_ptr<LocalizedError::ErrorPageParams> last_error_page_params_; |
| + |
| + int reload_count_; |
| }; |
| //------------------------------------------------------------------------------ |
| @@ -1655,3 +1738,267 @@ TEST_F(NetErrorHelperCoreTest, CorrectionServiceReturnsInvalidJsonResult) { |
| core().OnCommitLoad(NetErrorHelperCore::MAIN_FRAME); |
| core().OnFinishLoad(NetErrorHelperCore::MAIN_FRAME); |
| } |
| + |
| +TEST_F(NetErrorHelperCoreTest, AutoReloadDisabled) { |
| + DoErrorLoad(net::ERR_CONNECTION_RESET); |
| + |
| + EXPECT_FALSE(timer()->IsRunning()); |
| + EXPECT_EQ(0, reload_count()); |
| +} |
| + |
| +TEST_F(NetErrorHelperCoreTest, AutoReloadSucceeds) { |
| + core().set_auto_reload_enabled(true); |
| + DoErrorLoad(net::ERR_CONNECTION_RESET); |
| + |
| + EXPECT_TRUE(timer()->IsRunning()); |
| + EXPECT_EQ(0, reload_count()); |
| + |
| + timer()->Fire(); |
| + EXPECT_FALSE(timer()->IsRunning()); |
| + EXPECT_EQ(1, reload_count()); |
| + |
| + DoSuccessLoad(); |
| + |
| + EXPECT_FALSE(timer()->IsRunning()); |
| +} |
| + |
| +TEST_F(NetErrorHelperCoreTest, AutoReloadRetries) { |
| + core().set_auto_reload_enabled(true); |
| + DoErrorLoad(net::ERR_CONNECTION_RESET); |
| + |
| + EXPECT_TRUE(timer()->IsRunning()); |
| + base::TimeDelta first_delay = timer()->delay(); |
| + EXPECT_EQ(0, reload_count()); |
| + |
| + timer()->Fire(); |
| + EXPECT_FALSE(timer()->IsRunning()); |
| + EXPECT_EQ(1, reload_count()); |
| + |
| + DoErrorLoad(net::ERR_CONNECTION_RESET); |
| + |
| + EXPECT_TRUE(timer()->IsRunning()); |
| + EXPECT_GT(timer()->delay(), first_delay); |
| +} |
| + |
| +TEST_F(NetErrorHelperCoreTest, AutoReloadStopsTimerOnStop) { |
| + core().set_auto_reload_enabled(true); |
| + DoErrorLoad(net::ERR_CONNECTION_RESET); |
| + EXPECT_TRUE(timer()->IsRunning()); |
| + core().OnStop(); |
| + EXPECT_FALSE(timer()->IsRunning()); |
| +} |
| + |
| +TEST_F(NetErrorHelperCoreTest, AutoReloadStopsLoadingOnStop) { |
| + core().set_auto_reload_enabled(true); |
| + DoErrorLoad(net::ERR_CONNECTION_RESET); |
| + EXPECT_EQ(1, core().auto_reload_count()); |
| + timer()->Fire(); |
| + EXPECT_EQ(1, reload_count()); |
| + core().OnStop(); |
| + EXPECT_FALSE(timer()->IsRunning()); |
| + EXPECT_EQ(0, core().auto_reload_count()); |
| +} |
| + |
| +TEST_F(NetErrorHelperCoreTest, AutoReloadStopsOnOtherLoadStart) { |
| + core().set_auto_reload_enabled(true); |
| + DoErrorLoad(net::ERR_CONNECTION_RESET); |
| + EXPECT_TRUE(timer()->IsRunning()); |
| + core().OnStartLoad(NetErrorHelperCore::MAIN_FRAME, |
| + NetErrorHelperCore::NON_ERROR_PAGE); |
| + EXPECT_FALSE(timer()->IsRunning()); |
| + EXPECT_EQ(1, core().auto_reload_count()); |
| +} |
| + |
| +TEST_F(NetErrorHelperCoreTest, AutoReloadResetsCountOnSuccess) { |
| + core().set_auto_reload_enabled(true); |
| + DoErrorLoad(net::ERR_CONNECTION_RESET); |
| + base::TimeDelta delay = timer()->delay(); |
| + EXPECT_EQ(1, core().auto_reload_count()); |
| + timer()->Fire(); |
| + EXPECT_EQ(1, reload_count()); |
| + DoSuccessLoad(); |
| + DoErrorLoad(net::ERR_CONNECTION_RESET); |
| + EXPECT_EQ(1, core().auto_reload_count()); |
| + EXPECT_EQ(timer()->delay(), delay); |
| + timer()->Fire(); |
| + EXPECT_EQ(2, reload_count()); |
| + DoSuccessLoad(); |
| + EXPECT_EQ(0, core().auto_reload_count()); |
| +} |
| + |
| +TEST_F(NetErrorHelperCoreTest, AutoReloadRestartsOnOnline) { |
| + core().set_auto_reload_enabled(true); |
| + DoErrorLoad(net::ERR_CONNECTION_RESET); |
| + base::TimeDelta delay = timer()->delay(); |
| + timer()->Fire(); |
| + DoErrorLoad(net::ERR_CONNECTION_RESET); |
| + EXPECT_TRUE(timer()->IsRunning()); |
| + EXPECT_NE(delay, timer()->delay()); |
| + core().NetworkStateChanged(true); |
| + EXPECT_TRUE(timer()->IsRunning()); |
| + EXPECT_EQ(delay, timer()->delay()); |
| +} |
| + |
| +TEST_F(NetErrorHelperCoreTest, AutoReloadDoesNotStartOnOnline) { |
| + core().set_auto_reload_enabled(true); |
| + DoErrorLoad(net::ERR_CONNECTION_RESET); |
| + timer()->Fire(); |
| + DoSuccessLoad(); |
| + EXPECT_FALSE(timer()->IsRunning()); |
| + core().NetworkStateChanged(true); |
| + EXPECT_FALSE(timer()->IsRunning()); |
| +} |
| + |
| +TEST_F(NetErrorHelperCoreTest, AutoReloadStopsOnOffline) { |
| + core().set_auto_reload_enabled(true); |
| + DoErrorLoad(net::ERR_CONNECTION_RESET); |
| + EXPECT_TRUE(timer()->IsRunning()); |
| + core().NetworkStateChanged(false); |
| + EXPECT_FALSE(timer()->IsRunning()); |
|
mmenke
2014/03/13 14:39:13
Check that reload count is 0?
Elly Fong-Jones
2014/03/13 17:56:19
Done.
|
| +} |
| + |
| +TEST_F(NetErrorHelperCoreTest, AutoReloadStopsOnOfflineThenRestartsOnOnline) { |
| + core().set_auto_reload_enabled(true); |
| + DoErrorLoad(net::ERR_CONNECTION_RESET); |
| + EXPECT_TRUE(timer()->IsRunning()); |
| + core().NetworkStateChanged(false); |
| + EXPECT_FALSE(timer()->IsRunning()); |
| + core().NetworkStateChanged(true); |
| + EXPECT_TRUE(timer()->IsRunning()); |
|
mmenke
2014/03/13 14:39:13
Check that reload count is 1?
Elly Fong-Jones
2014/03/13 17:56:19
Done.
|
| +} |
| + |
| +TEST_F(NetErrorHelperCoreTest, AutoReloadDoesNotRestartOnOnlineAfterStop) { |
| + core().set_auto_reload_enabled(true); |
| + DoErrorLoad(net::ERR_CONNECTION_RESET); |
| + timer()->Fire(); |
| + core().OnStop(); |
| + core().NetworkStateChanged(true); |
| + EXPECT_FALSE(timer()->IsRunning()); |
| +} |
| + |
| +TEST_F(NetErrorHelperCoreTest, AutoReloadWithDnsProbes) { |
| + core().set_auto_reload_enabled(true); |
| + DoErrorLoad(net::ERR_CONNECTION_RESET); |
| + DoDnsProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN); |
| + timer()->Fire(); |
| + EXPECT_EQ(1, reload_count()); |
| +} |
| + |
| +TEST_F(NetErrorHelperCoreTest, AutoReloadExponentialBackoffLevelsOff) { |
| + core().set_auto_reload_enabled(true); |
| + base::TimeDelta previous = base::TimeDelta::FromMilliseconds(0); |
| + const int kMaxTries = 50; |
| + int tries = 0; |
| + for (tries = 0; tries < kMaxTries; tries++) { |
| + DoErrorLoad(net::ERR_CONNECTION_RESET); |
| + EXPECT_TRUE(timer()->IsRunning()); |
| + if (previous == timer()->delay()) |
| + break; |
| + previous = timer()->delay(); |
| + timer()->Fire(); |
| + } |
| + |
| + EXPECT_LT(tries, kMaxTries); |
| +} |
| + |
| +TEST_F(NetErrorHelperCoreTest, AutoReloadSlowError) { |
| + core().set_auto_reload_enabled(true); |
| + core().OnStartLoad(NetErrorHelperCore::MAIN_FRAME, |
| + NetErrorHelperCore::NON_ERROR_PAGE); |
| + std::string html; |
| + core().GetErrorHTML(NetErrorHelperCore::MAIN_FRAME, |
| + NetError(net::ERR_CONNECTION_RESET), false, &html); |
| + core().OnStartLoad(NetErrorHelperCore::MAIN_FRAME, |
| + NetErrorHelperCore::ERROR_PAGE); |
| + core().OnCommitLoad(NetErrorHelperCore::MAIN_FRAME); |
| + EXPECT_FALSE(timer()->IsRunning()); |
| + // Start the non-error page load. |
|
mmenke
2014/03/13 14:39:13
nit: Maybe "Start the" -> "Start a new"
Elly Fong-Jones
2014/03/13 17:56:19
Done.
|
| + core().OnStartLoad(NetErrorHelperCore::MAIN_FRAME, |
| + NetErrorHelperCore::NON_ERROR_PAGE); |
| + EXPECT_FALSE(timer()->IsRunning()); |
| + // Finish the error page load. |
| + core().OnFinishLoad(NetErrorHelperCore::MAIN_FRAME); |
| + EXPECT_FALSE(timer()->IsRunning()); |
| + core().OnCommitLoad(NetErrorHelperCore::MAIN_FRAME); |
| + core().OnFinishLoad(NetErrorHelperCore::MAIN_FRAME); |
|
mmenke
2014/03/13 14:39:13
Maybe another "EXPECT_FALSE(timer()->IsRunning());
Elly Fong-Jones
2014/03/13 17:56:19
Done.
|
| +} |
| + |
| +TEST_F(NetErrorHelperCoreTest, AutoReloadOnlineSlowError) { |
| + core().set_auto_reload_enabled(true); |
| + core().NetworkStateChanged(false); |
| + core().OnStartLoad(NetErrorHelperCore::MAIN_FRAME, |
| + NetErrorHelperCore::NON_ERROR_PAGE); |
| + std::string html; |
| + core().GetErrorHTML(NetErrorHelperCore::MAIN_FRAME, |
| + NetError(net::ERR_CONNECTION_RESET), false, &html); |
| + core().OnStartLoad(NetErrorHelperCore::MAIN_FRAME, |
| + NetErrorHelperCore::ERROR_PAGE); |
| + core().OnCommitLoad(NetErrorHelperCore::MAIN_FRAME); |
| + EXPECT_FALSE(timer()->IsRunning()); |
| + core().NetworkStateChanged(true); |
| + EXPECT_FALSE(timer()->IsRunning()); |
| + core().NetworkStateChanged(false); |
| + core().OnFinishLoad(NetErrorHelperCore::MAIN_FRAME); |
| + EXPECT_FALSE(timer()->IsRunning()); |
| + core().NetworkStateChanged(true); |
| + EXPECT_TRUE(timer()->IsRunning()); |
| +} |
| + |
| +TEST_F(NetErrorHelperCoreTest, AutoReloadOnlinePendingError) { |
| + core().set_auto_reload_enabled(true); |
| + core().NetworkStateChanged(false); |
| + core().OnStartLoad(NetErrorHelperCore::MAIN_FRAME, |
| + NetErrorHelperCore::NON_ERROR_PAGE); |
| + std::string html; |
| + core().GetErrorHTML(NetErrorHelperCore::MAIN_FRAME, |
| + NetError(net::ERR_CONNECTION_RESET), false, &html); |
| + core().OnStartLoad(NetErrorHelperCore::MAIN_FRAME, |
| + NetErrorHelperCore::ERROR_PAGE); |
| + EXPECT_FALSE(timer()->IsRunning()); |
| + core().NetworkStateChanged(true); |
| + EXPECT_FALSE(timer()->IsRunning()); |
| + core().NetworkStateChanged(false); |
| + core().OnCommitLoad(NetErrorHelperCore::MAIN_FRAME); |
| + core().OnFinishLoad(NetErrorHelperCore::MAIN_FRAME); |
| + EXPECT_FALSE(timer()->IsRunning()); |
| + core().NetworkStateChanged(true); |
| + EXPECT_TRUE(timer()->IsRunning()); |
| +} |
| + |
| +TEST_F(NetErrorHelperCoreTest, AutoReloadOnlinePartialErrorReplacement) { |
| + core().set_auto_reload_enabled(true); |
| + core().NetworkStateChanged(false); |
| + core().OnStartLoad(NetErrorHelperCore::MAIN_FRAME, |
| + NetErrorHelperCore::NON_ERROR_PAGE); |
| + std::string html; |
| + core().GetErrorHTML(NetErrorHelperCore::MAIN_FRAME, |
| + NetError(net::ERR_CONNECTION_RESET), false, &html); |
| + core().OnStartLoad(NetErrorHelperCore::MAIN_FRAME, |
| + NetErrorHelperCore::ERROR_PAGE); |
| + core().OnCommitLoad(NetErrorHelperCore::MAIN_FRAME); |
| + core().OnFinishLoad(NetErrorHelperCore::MAIN_FRAME); |
| + core().OnStartLoad(NetErrorHelperCore::MAIN_FRAME, |
| + NetErrorHelperCore::NON_ERROR_PAGE); |
| + core().GetErrorHTML(NetErrorHelperCore::MAIN_FRAME, |
| + NetError(net::ERR_CONNECTION_RESET), false, &html); |
| + core().OnStartLoad(NetErrorHelperCore::MAIN_FRAME, |
| + NetErrorHelperCore::ERROR_PAGE); |
| + EXPECT_FALSE(timer()->IsRunning()); |
| + core().NetworkStateChanged(true); |
| + EXPECT_FALSE(timer()->IsRunning()); |
| +} |
| + |
| +TEST_F(NetErrorHelperCoreTest, ShouldSuppressErrorPage) { |
| + // Set up the environment to test ShouldSuppressErrorPage: auto-reload is |
| + // enabled, an error page is loaded, and the auto-reload callback is running. |
| + core().set_auto_reload_enabled(true); |
| + DoErrorLoad(net::ERR_CONNECTION_RESET); |
| + timer()->Fire(); |
| + |
| + EXPECT_FALSE(core().ShouldSuppressErrorPage(NetErrorHelperCore::SUB_FRAME, |
| + GURL(kFailedUrl))); |
| + EXPECT_FALSE(core().ShouldSuppressErrorPage(NetErrorHelperCore::MAIN_FRAME, |
| + GURL("http://some.other.url"))); |
| + EXPECT_TRUE(core().ShouldSuppressErrorPage(NetErrorHelperCore::MAIN_FRAME, |
| + GURL(kFailedUrl))); |
| +} |