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..3bebdb7de048665f8feb385f2177ec82a6183cb6 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,244 @@ 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()); |
+} |
+ |
+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()); |
+} |
+ |
+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. |
+ 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); |
+} |
+ |
+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, 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))); |
+} |