update_screen_browsertest.cc revision 116680a4aac90f2aa7413d9095a592090648e557
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "base/command_line.h" 6#include "base/memory/scoped_ptr.h" 7#include "base/prefs/pref_service.h" 8#include "chrome/browser/browser_process.h" 9#include "chrome/browser/chromeos/login/screens/mock_error_screen.h" 10#include "chrome/browser/chromeos/login/screens/mock_screen_observer.h" 11#include "chrome/browser/chromeos/login/screens/update_screen.h" 12#include "chrome/browser/chromeos/login/startup_utils.h" 13#include "chrome/browser/chromeos/login/test/wizard_in_process_browser_test.h" 14#include "chrome/browser/chromeos/login/wizard_controller.h" 15#include "chrome/browser/chromeos/net/network_portal_detector_test_impl.h" 16#include "chrome/common/pref_names.h" 17#include "chromeos/chromeos_switches.h" 18#include "chromeos/dbus/fake_dbus_thread_manager.h" 19#include "chromeos/dbus/fake_update_engine_client.h" 20#include "chromeos/network/portal_detector/network_portal_detector.h" 21#include "testing/gmock/include/gmock/gmock.h" 22#include "testing/gtest/include/gtest/gtest.h" 23 24using ::testing::AnyNumber; 25using ::testing::AtLeast; 26using ::testing::Exactly; 27using ::testing::Invoke; 28using ::testing::Return; 29using ::testing::_; 30 31namespace chromeos { 32 33namespace { 34 35const char kStubEthernetGuid[] = "eth0"; 36const char kStubWifiGuid[] = "wlan0"; 37 38} // namespace 39 40class UpdateScreenTest : public WizardInProcessBrowserTest { 41 public: 42 UpdateScreenTest() : WizardInProcessBrowserTest("update"), 43 fake_update_engine_client_(NULL), 44 network_portal_detector_(NULL) { 45 } 46 47 protected: 48 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { 49 FakeDBusThreadManager* fake_dbus_thread_manager = 50 new FakeDBusThreadManager; 51 fake_dbus_thread_manager->SetFakeClients(); 52 fake_update_engine_client_ = new FakeUpdateEngineClient; 53 fake_dbus_thread_manager->SetUpdateEngineClient( 54 scoped_ptr<UpdateEngineClient>(fake_update_engine_client_)); 55 56 DBusThreadManager::SetInstanceForTesting(fake_dbus_thread_manager); 57 WizardInProcessBrowserTest::SetUpInProcessBrowserTestFixture(); 58 59 // Setup network portal detector to return online state for both 60 // ethernet and wifi networks. Ethernet is an active network by 61 // default. 62 network_portal_detector_ = new NetworkPortalDetectorTestImpl(); 63 NetworkPortalDetector::InitializeForTesting(network_portal_detector_); 64 NetworkPortalDetector::CaptivePortalState online_state; 65 online_state.status = NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE; 66 online_state.response_code = 204; 67 SetDefaultNetwork(kStubEthernetGuid); 68 SetDetectionResults(kStubEthernetGuid, online_state); 69 SetDetectionResults(kStubWifiGuid, online_state); 70 } 71 72 virtual void SetUpOnMainThread() OVERRIDE { 73 WizardInProcessBrowserTest::SetUpOnMainThread(); 74 75 mock_screen_observer_.reset(new MockScreenObserver()); 76 mock_error_screen_actor_.reset(new MockErrorScreenActor()); 77 mock_error_screen_.reset( 78 new MockErrorScreen(mock_screen_observer_.get(), 79 mock_error_screen_actor_.get())); 80 EXPECT_CALL(*mock_screen_observer_, ShowCurrentScreen()) 81 .Times(AnyNumber()); 82 EXPECT_CALL(*mock_screen_observer_, GetErrorScreen()) 83 .Times(AnyNumber()) 84 .WillRepeatedly(Return(mock_error_screen_.get())); 85 86 ASSERT_TRUE(WizardController::default_controller() != NULL); 87 update_screen_ = WizardController::default_controller()->GetUpdateScreen(); 88 ASSERT_TRUE(update_screen_ != NULL); 89 ASSERT_EQ(WizardController::default_controller()->current_screen(), 90 update_screen_); 91 update_screen_->screen_observer_ = mock_screen_observer_.get(); 92 } 93 94 virtual void CleanUpOnMainThread() OVERRIDE { 95 mock_error_screen_.reset(); 96 mock_error_screen_actor_.reset(); 97 WizardInProcessBrowserTest::CleanUpOnMainThread(); 98 } 99 100 virtual void TearDownInProcessBrowserTestFixture() OVERRIDE { 101 NetworkPortalDetector::Shutdown(); 102 WizardInProcessBrowserTest::TearDownInProcessBrowserTestFixture(); 103 } 104 105 void SetDefaultNetwork(const std::string& guid) { 106 DCHECK(network_portal_detector_); 107 network_portal_detector_->SetDefaultNetworkForTesting(guid); 108 } 109 110 void SetDetectionResults( 111 const std::string& guid, 112 const NetworkPortalDetector::CaptivePortalState& state) { 113 DCHECK(network_portal_detector_); 114 network_portal_detector_->SetDetectionResultsForTesting(guid, state); 115 } 116 117 void NotifyPortalDetectionCompleted() { 118 DCHECK(network_portal_detector_); 119 network_portal_detector_->NotifyObserversForTesting(); 120 } 121 122 FakeUpdateEngineClient* fake_update_engine_client_; 123 scoped_ptr<MockScreenObserver> mock_screen_observer_; 124 scoped_ptr<MockErrorScreenActor> mock_error_screen_actor_; 125 scoped_ptr<MockErrorScreen> mock_error_screen_; 126 UpdateScreen* update_screen_; 127 NetworkPortalDetectorTestImpl* network_portal_detector_; 128 129 private: 130 DISALLOW_COPY_AND_ASSIGN(UpdateScreenTest); 131}; 132 133IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestBasic) { 134 ASSERT_TRUE(update_screen_->actor_ != NULL); 135} 136 137IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestNoUpdate) { 138 update_screen_->SetIgnoreIdleStatus(true); 139 UpdateEngineClient::Status status; 140 status.status = UpdateEngineClient::UPDATE_STATUS_IDLE; 141 update_screen_->UpdateStatusChanged(status); 142 status.status = UpdateEngineClient::UPDATE_STATUS_CHECKING_FOR_UPDATE; 143 update_screen_->UpdateStatusChanged(status); 144 status.status = UpdateEngineClient::UPDATE_STATUS_IDLE; 145 // GetLastStatus() will be called via ExitUpdate() called from 146 // UpdateStatusChanged(). 147 fake_update_engine_client_->set_default_status(status); 148 149 EXPECT_CALL(*mock_screen_observer_, OnExit(ScreenObserver::UPDATE_NOUPDATE)) 150 .Times(1); 151 update_screen_->UpdateStatusChanged(status); 152} 153 154IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestUpdateAvailable) { 155 update_screen_->is_ignore_update_deadlines_ = true; 156 157 UpdateEngineClient::Status status; 158 status.status = UpdateEngineClient::UPDATE_STATUS_UPDATE_AVAILABLE; 159 status.new_version = "latest and greatest"; 160 update_screen_->UpdateStatusChanged(status); 161 162 status.status = UpdateEngineClient::UPDATE_STATUS_DOWNLOADING; 163 status.download_progress = 0.0; 164 update_screen_->UpdateStatusChanged(status); 165 166 status.download_progress = 0.5; 167 update_screen_->UpdateStatusChanged(status); 168 169 status.download_progress = 1.0; 170 update_screen_->UpdateStatusChanged(status); 171 172 status.status = UpdateEngineClient::UPDATE_STATUS_VERIFYING; 173 update_screen_->UpdateStatusChanged(status); 174 175 status.status = UpdateEngineClient::UPDATE_STATUS_FINALIZING; 176 update_screen_->UpdateStatusChanged(status); 177 178 status.status = UpdateEngineClient::UPDATE_STATUS_UPDATED_NEED_REBOOT; 179 update_screen_->UpdateStatusChanged(status); 180 // UpdateStatusChanged(status) calls RebootAfterUpdate(). 181 EXPECT_EQ(1, fake_update_engine_client_->reboot_after_update_call_count()); 182 // Check that OOBE will resume back at this screen. 183 base::MessageLoop::current()->RunUntilIdle(); 184 EXPECT_FALSE(StartupUtils::IsOobeCompleted()); 185 EXPECT_EQ(update_screen_->GetName(), 186 g_browser_process->local_state()->GetString(prefs::kOobeScreenPending)); 187} 188 189IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestErrorIssuingUpdateCheck) { 190 // First, cancel the update that is already in progress. 191 EXPECT_CALL(*mock_screen_observer_, 192 OnExit(ScreenObserver::UPDATE_NOUPDATE)) 193 .Times(1); 194 update_screen_->CancelUpdate(); 195 196 fake_update_engine_client_->set_update_check_result( 197 chromeos::UpdateEngineClient::UPDATE_RESULT_FAILED); 198 EXPECT_CALL(*mock_screen_observer_, 199 OnExit(ScreenObserver::UPDATE_ERROR_CHECKING_FOR_UPDATE)) 200 .Times(1); 201 update_screen_->StartNetworkCheck(); 202} 203 204IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestErrorCheckingForUpdate) { 205 UpdateEngineClient::Status status; 206 status.status = UpdateEngineClient::UPDATE_STATUS_ERROR; 207 // GetLastStatus() will be called via ExitUpdate() called from 208 // UpdateStatusChanged(). 209 fake_update_engine_client_->set_default_status(status); 210 211 EXPECT_CALL(*mock_screen_observer_, 212 OnExit(ScreenObserver::UPDATE_ERROR_CHECKING_FOR_UPDATE)) 213 .Times(1); 214 update_screen_->UpdateStatusChanged(status); 215} 216 217IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestErrorUpdating) { 218 UpdateEngineClient::Status status; 219 status.status = UpdateEngineClient::UPDATE_STATUS_UPDATE_AVAILABLE; 220 status.new_version = "latest and greatest"; 221 // GetLastStatus() will be called via ExitUpdate() called from 222 // UpdateStatusChanged(). 223 fake_update_engine_client_->set_default_status(status); 224 225 update_screen_->UpdateStatusChanged(status); 226 227 status.status = UpdateEngineClient::UPDATE_STATUS_ERROR; 228 // GetLastStatus() will be called via ExitUpdate() called from 229 // UpdateStatusChanged(). 230 fake_update_engine_client_->set_default_status(status); 231 232 EXPECT_CALL(*mock_screen_observer_, 233 OnExit(ScreenObserver::UPDATE_ERROR_UPDATING)) 234 .Times(1); 235 update_screen_->UpdateStatusChanged(status); 236} 237 238IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestTemproraryOfflineNetwork) { 239 EXPECT_CALL(*mock_screen_observer_, 240 OnExit(ScreenObserver::UPDATE_NOUPDATE)) 241 .Times(1); 242 update_screen_->CancelUpdate(); 243 244 // Change ethernet state to portal. 245 NetworkPortalDetector::CaptivePortalState portal_state; 246 portal_state.status = NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL; 247 portal_state.response_code = 200; 248 SetDetectionResults(kStubEthernetGuid, portal_state); 249 250 // Update screen will show error message about portal state because 251 // ethernet is behind captive portal. 252 EXPECT_CALL(*mock_error_screen_actor_, 253 SetUIState(ErrorScreen::UI_STATE_UPDATE)) 254 .Times(1); 255 EXPECT_CALL(*mock_error_screen_actor_, 256 SetErrorState(ErrorScreen::ERROR_STATE_PORTAL, std::string())) 257 .Times(1); 258 EXPECT_CALL(*mock_error_screen_actor_, FixCaptivePortal()) 259 .Times(1); 260 EXPECT_CALL(*mock_screen_observer_, ShowErrorScreen()) 261 .Times(1); 262 263 update_screen_->StartNetworkCheck(); 264 265 NetworkPortalDetector::CaptivePortalState online_state; 266 online_state.status = NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE; 267 online_state.response_code = 204; 268 SetDetectionResults(kStubEthernetGuid, online_state); 269 270 // Second notification from portal detector will be about online state, 271 // so update screen will hide error message and proceed to update. 272 EXPECT_CALL(*mock_screen_observer_, HideErrorScreen(update_screen_)) 273 .Times(1); 274 fake_update_engine_client_->set_update_check_result( 275 chromeos::UpdateEngineClient::UPDATE_RESULT_FAILED); 276 277 EXPECT_CALL(*mock_screen_observer_, 278 OnExit(ScreenObserver::UPDATE_ERROR_CHECKING_FOR_UPDATE)) 279 .Times(1); 280 281 NotifyPortalDetectionCompleted(); 282} 283 284IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestTwoOfflineNetworks) { 285 EXPECT_CALL(*mock_screen_observer_, 286 OnExit(ScreenObserver::UPDATE_NOUPDATE)) 287 .Times(1); 288 update_screen_->CancelUpdate(); 289 290 // Change ethernet state to portal. 291 NetworkPortalDetector::CaptivePortalState portal_state; 292 portal_state.status = NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL; 293 portal_state.response_code = 200; 294 SetDetectionResults(kStubEthernetGuid, portal_state); 295 296 // Update screen will show error message about portal state because 297 // ethernet is behind captive portal. 298 EXPECT_CALL(*mock_error_screen_actor_, 299 SetUIState(ErrorScreen::UI_STATE_UPDATE)) 300 .Times(1); 301 EXPECT_CALL(*mock_error_screen_actor_, 302 SetErrorState(ErrorScreen::ERROR_STATE_PORTAL, std::string())) 303 .Times(1); 304 EXPECT_CALL(*mock_error_screen_actor_, FixCaptivePortal()) 305 .Times(1); 306 EXPECT_CALL(*mock_screen_observer_, ShowErrorScreen()) 307 .Times(1); 308 309 update_screen_->StartNetworkCheck(); 310 311 // Change active network to the wifi behind proxy. 312 NetworkPortalDetector::CaptivePortalState proxy_state; 313 proxy_state.status = 314 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED; 315 proxy_state.response_code = -1; 316 SetDefaultNetwork(kStubWifiGuid); 317 SetDetectionResults(kStubWifiGuid, proxy_state); 318 319 // Update screen will show message about proxy error because wifie 320 // network requires proxy authentication. 321 EXPECT_CALL(*mock_error_screen_actor_, 322 SetErrorState(ErrorScreen::ERROR_STATE_PROXY, std::string())) 323 .Times(1); 324 325 NotifyPortalDetectionCompleted(); 326} 327 328IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestVoidNetwork) { 329 SetDefaultNetwork(std::string()); 330 331 // Cancels pending update request. 332 EXPECT_CALL(*mock_screen_observer_, 333 OnExit(ScreenObserver::UPDATE_NOUPDATE)) 334 .Times(1); 335 update_screen_->CancelUpdate(); 336 337 // First portal detection attempt returns NULL network and undefined 338 // results, so detection is restarted. 339 EXPECT_CALL(*mock_error_screen_actor_, 340 SetUIState(_)) 341 .Times(Exactly(0)); 342 EXPECT_CALL(*mock_error_screen_actor_, 343 SetErrorState(_, _)) 344 .Times(Exactly(0)); 345 EXPECT_CALL(*mock_screen_observer_, ShowErrorScreen()) 346 .Times(Exactly(0)); 347 update_screen_->StartNetworkCheck(); 348 349 // Second portal detection also returns NULL network and undefined 350 // results. In this case, offline message should be displayed. 351 EXPECT_CALL(*mock_error_screen_actor_, 352 SetUIState(ErrorScreen::UI_STATE_UPDATE)) 353 .Times(1); 354 EXPECT_CALL(*mock_error_screen_actor_, 355 SetErrorState(ErrorScreen::ERROR_STATE_OFFLINE, std::string())) 356 .Times(1); 357 EXPECT_CALL(*mock_screen_observer_, ShowErrorScreen()) 358 .Times(1); 359 base::MessageLoop::current()->RunUntilIdle(); 360 NotifyPortalDetectionCompleted(); 361} 362 363IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestAPReselection) { 364 EXPECT_CALL(*mock_screen_observer_, 365 OnExit(ScreenObserver::UPDATE_NOUPDATE)) 366 .Times(1); 367 update_screen_->CancelUpdate(); 368 369 // Change ethernet state to portal. 370 NetworkPortalDetector::CaptivePortalState portal_state; 371 portal_state.status = NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL; 372 portal_state.response_code = 200; 373 SetDetectionResults(kStubEthernetGuid, portal_state); 374 375 // Update screen will show error message about portal state because 376 // ethernet is behind captive portal. 377 EXPECT_CALL(*mock_error_screen_actor_, 378 SetUIState(ErrorScreen::UI_STATE_UPDATE)) 379 .Times(1); 380 EXPECT_CALL(*mock_error_screen_actor_, 381 SetErrorState(ErrorScreen::ERROR_STATE_PORTAL, std::string())) 382 .Times(1); 383 EXPECT_CALL(*mock_error_screen_actor_, FixCaptivePortal()) 384 .Times(1); 385 EXPECT_CALL(*mock_screen_observer_, ShowErrorScreen()) 386 .Times(1); 387 388 update_screen_->StartNetworkCheck(); 389 390 // User re-selects the same network manually. In this case, hide 391 // offline message and skip network check. Since ethernet is still 392 // behind portal, update engine fails to update. 393 EXPECT_CALL(*mock_screen_observer_, HideErrorScreen(update_screen_)) 394 .Times(1); 395 fake_update_engine_client_->set_update_check_result( 396 chromeos::UpdateEngineClient::UPDATE_RESULT_FAILED); 397 EXPECT_CALL(*mock_screen_observer_, 398 OnExit(ScreenObserver::UPDATE_ERROR_CHECKING_FOR_UPDATE)) 399 .Times(1); 400 401 update_screen_->OnConnectToNetworkRequested(); 402 base::MessageLoop::current()->RunUntilIdle(); 403} 404 405} // namespace chromeos 406