update_screen_browsertest.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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.h" 16#include "chrome/browser/chromeos/net/network_portal_detector_test_impl.h" 17#include "chrome/common/pref_names.h" 18#include "chromeos/chromeos_switches.h" 19#include "chromeos/dbus/fake_dbus_thread_manager.h" 20#include "chromeos/dbus/fake_update_engine_client.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 kStubEthernetServicePath[] = "eth0"; 36const char kStubWifiServicePath[] = "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 SetDefaultNetworkPath(kStubEthernetServicePath); 68 SetDetectionResults(kStubEthernetServicePath, online_state); 69 SetDetectionResults(kStubWifiServicePath, 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 SetDefaultNetworkPath(const std::string& service_path) { 106 DCHECK(network_portal_detector_); 107 network_portal_detector_->SetDefaultNetworkPathForTesting( 108 service_path); 109 } 110 111 void SetDetectionResults( 112 const std::string& service_path, 113 const NetworkPortalDetector::CaptivePortalState& state) { 114 DCHECK(network_portal_detector_); 115 network_portal_detector_->SetDetectionResultsForTesting(service_path, 116 state); 117 } 118 119 void NotifyPortalDetectionCompleted() { 120 DCHECK(network_portal_detector_); 121 network_portal_detector_->NotifyObserversForTesting(); 122 } 123 124 FakeUpdateEngineClient* fake_update_engine_client_; 125 scoped_ptr<MockScreenObserver> mock_screen_observer_; 126 scoped_ptr<MockErrorScreenActor> mock_error_screen_actor_; 127 scoped_ptr<MockErrorScreen> mock_error_screen_; 128 UpdateScreen* update_screen_; 129 NetworkPortalDetectorTestImpl* network_portal_detector_; 130 131 private: 132 DISALLOW_COPY_AND_ASSIGN(UpdateScreenTest); 133}; 134 135IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestBasic) { 136 ASSERT_TRUE(update_screen_->actor_ != NULL); 137} 138 139IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestNoUpdate) { 140 update_screen_->SetIgnoreIdleStatus(true); 141 UpdateEngineClient::Status status; 142 status.status = UpdateEngineClient::UPDATE_STATUS_IDLE; 143 update_screen_->UpdateStatusChanged(status); 144 status.status = UpdateEngineClient::UPDATE_STATUS_CHECKING_FOR_UPDATE; 145 update_screen_->UpdateStatusChanged(status); 146 status.status = UpdateEngineClient::UPDATE_STATUS_IDLE; 147 // GetLastStatus() will be called via ExitUpdate() called from 148 // UpdateStatusChanged(). 149 fake_update_engine_client_->set_default_status(status); 150 151 EXPECT_CALL(*mock_screen_observer_, OnExit(ScreenObserver::UPDATE_NOUPDATE)) 152 .Times(1); 153 update_screen_->UpdateStatusChanged(status); 154} 155 156IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestUpdateAvailable) { 157 update_screen_->is_ignore_update_deadlines_ = true; 158 159 UpdateEngineClient::Status status; 160 status.status = UpdateEngineClient::UPDATE_STATUS_UPDATE_AVAILABLE; 161 status.new_version = "latest and greatest"; 162 update_screen_->UpdateStatusChanged(status); 163 164 status.status = UpdateEngineClient::UPDATE_STATUS_DOWNLOADING; 165 status.download_progress = 0.0; 166 update_screen_->UpdateStatusChanged(status); 167 168 status.download_progress = 0.5; 169 update_screen_->UpdateStatusChanged(status); 170 171 status.download_progress = 1.0; 172 update_screen_->UpdateStatusChanged(status); 173 174 status.status = UpdateEngineClient::UPDATE_STATUS_VERIFYING; 175 update_screen_->UpdateStatusChanged(status); 176 177 status.status = UpdateEngineClient::UPDATE_STATUS_FINALIZING; 178 update_screen_->UpdateStatusChanged(status); 179 180 status.status = UpdateEngineClient::UPDATE_STATUS_UPDATED_NEED_REBOOT; 181 update_screen_->UpdateStatusChanged(status); 182 // UpdateStatusChanged(status) calls RebootAfterUpdate(). 183 EXPECT_EQ(1, fake_update_engine_client_->reboot_after_update_call_count()); 184 // Check that OOBE will resume back at this screen. 185 base::MessageLoop::current()->RunUntilIdle(); 186 EXPECT_FALSE(StartupUtils::IsOobeCompleted()); 187 EXPECT_EQ(update_screen_->GetName(), 188 g_browser_process->local_state()->GetString(prefs::kOobeScreenPending)); 189} 190 191IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestErrorIssuingUpdateCheck) { 192 // First, cancel the update that is already in progress. 193 EXPECT_CALL(*mock_screen_observer_, 194 OnExit(ScreenObserver::UPDATE_NOUPDATE)) 195 .Times(1); 196 update_screen_->CancelUpdate(); 197 198 fake_update_engine_client_->set_update_check_result( 199 chromeos::UpdateEngineClient::UPDATE_RESULT_FAILED); 200 EXPECT_CALL(*mock_screen_observer_, 201 OnExit(ScreenObserver::UPDATE_ERROR_CHECKING_FOR_UPDATE)) 202 .Times(1); 203 update_screen_->StartNetworkCheck(); 204} 205 206IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestErrorCheckingForUpdate) { 207 UpdateEngineClient::Status status; 208 status.status = UpdateEngineClient::UPDATE_STATUS_ERROR; 209 // GetLastStatus() will be called via ExitUpdate() called from 210 // UpdateStatusChanged(). 211 fake_update_engine_client_->set_default_status(status); 212 213 EXPECT_CALL(*mock_screen_observer_, 214 OnExit(ScreenObserver::UPDATE_ERROR_CHECKING_FOR_UPDATE)) 215 .Times(1); 216 update_screen_->UpdateStatusChanged(status); 217} 218 219IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestErrorUpdating) { 220 UpdateEngineClient::Status status; 221 status.status = UpdateEngineClient::UPDATE_STATUS_UPDATE_AVAILABLE; 222 status.new_version = "latest and greatest"; 223 // GetLastStatus() will be called via ExitUpdate() called from 224 // UpdateStatusChanged(). 225 fake_update_engine_client_->set_default_status(status); 226 227 update_screen_->UpdateStatusChanged(status); 228 229 status.status = UpdateEngineClient::UPDATE_STATUS_ERROR; 230 // GetLastStatus() will be called via ExitUpdate() called from 231 // UpdateStatusChanged(). 232 fake_update_engine_client_->set_default_status(status); 233 234 EXPECT_CALL(*mock_screen_observer_, 235 OnExit(ScreenObserver::UPDATE_ERROR_UPDATING)) 236 .Times(1); 237 update_screen_->UpdateStatusChanged(status); 238} 239 240IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestTemproraryOfflineNetwork) { 241 EXPECT_CALL(*mock_screen_observer_, 242 OnExit(ScreenObserver::UPDATE_NOUPDATE)) 243 .Times(1); 244 update_screen_->CancelUpdate(); 245 246 // Change ethernet state to portal. 247 NetworkPortalDetector::CaptivePortalState portal_state; 248 portal_state.status = NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL; 249 portal_state.response_code = 200; 250 SetDetectionResults(kStubEthernetServicePath, portal_state); 251 252 // Update screen will show error message about portal state because 253 // ethernet is behind captive portal. 254 EXPECT_CALL(*mock_error_screen_actor_, 255 SetUIState(ErrorScreen::UI_STATE_UPDATE)) 256 .Times(1); 257 EXPECT_CALL(*mock_error_screen_actor_, 258 SetErrorState(ErrorScreen::ERROR_STATE_PORTAL, std::string())) 259 .Times(1); 260 EXPECT_CALL(*mock_error_screen_actor_, FixCaptivePortal()) 261 .Times(1); 262 EXPECT_CALL(*mock_screen_observer_, ShowErrorScreen()) 263 .Times(1); 264 265 update_screen_->StartNetworkCheck(); 266 267 NetworkPortalDetector::CaptivePortalState online_state; 268 online_state.status = NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE; 269 online_state.response_code = 204; 270 SetDetectionResults(kStubEthernetServicePath, online_state); 271 272 // Second notification from portal detector will be about online state, 273 // so update screen will hide error message and proceed to update. 274 EXPECT_CALL(*mock_screen_observer_, HideErrorScreen(update_screen_)) 275 .Times(1); 276 fake_update_engine_client_->set_update_check_result( 277 chromeos::UpdateEngineClient::UPDATE_RESULT_FAILED); 278 279 EXPECT_CALL(*mock_screen_observer_, 280 OnExit(ScreenObserver::UPDATE_ERROR_CHECKING_FOR_UPDATE)) 281 .Times(1); 282 283 NotifyPortalDetectionCompleted(); 284} 285 286IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestTwoOfflineNetworks) { 287 EXPECT_CALL(*mock_screen_observer_, 288 OnExit(ScreenObserver::UPDATE_NOUPDATE)) 289 .Times(1); 290 update_screen_->CancelUpdate(); 291 292 // Change ethernet state to portal. 293 NetworkPortalDetector::CaptivePortalState portal_state; 294 portal_state.status = NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL; 295 portal_state.response_code = 200; 296 SetDetectionResults(kStubEthernetServicePath, portal_state); 297 298 // Update screen will show error message about portal state because 299 // ethernet is behind captive portal. 300 EXPECT_CALL(*mock_error_screen_actor_, 301 SetUIState(ErrorScreen::UI_STATE_UPDATE)) 302 .Times(1); 303 EXPECT_CALL(*mock_error_screen_actor_, 304 SetErrorState(ErrorScreen::ERROR_STATE_PORTAL, std::string())) 305 .Times(1); 306 EXPECT_CALL(*mock_error_screen_actor_, FixCaptivePortal()) 307 .Times(1); 308 EXPECT_CALL(*mock_screen_observer_, ShowErrorScreen()) 309 .Times(1); 310 311 update_screen_->StartNetworkCheck(); 312 313 // Change active network to the wifi behind proxy. 314 NetworkPortalDetector::CaptivePortalState proxy_state; 315 proxy_state.status = 316 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED; 317 proxy_state.response_code = -1; 318 SetDefaultNetworkPath(kStubWifiServicePath); 319 SetDetectionResults(kStubWifiServicePath, proxy_state); 320 321 // Update screen will show message about proxy error because wifie 322 // network requires proxy authentication. 323 EXPECT_CALL(*mock_error_screen_actor_, 324 SetErrorState(ErrorScreen::ERROR_STATE_PROXY, std::string())) 325 .Times(1); 326 327 NotifyPortalDetectionCompleted(); 328} 329 330IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestVoidNetwork) { 331 SetDefaultNetworkPath(""); 332 333 // Cancels pending update request. 334 EXPECT_CALL(*mock_screen_observer_, 335 OnExit(ScreenObserver::UPDATE_NOUPDATE)) 336 .Times(1); 337 update_screen_->CancelUpdate(); 338 339 // First portal detection attempt returns NULL network and undefined 340 // results, so detection is restarted. 341 EXPECT_CALL(*mock_error_screen_actor_, 342 SetUIState(_)) 343 .Times(Exactly(0)); 344 EXPECT_CALL(*mock_error_screen_actor_, 345 SetErrorState(_, _)) 346 .Times(Exactly(0)); 347 EXPECT_CALL(*mock_screen_observer_, ShowErrorScreen()) 348 .Times(Exactly(0)); 349 update_screen_->StartNetworkCheck(); 350 351 // Second portal detection also returns NULL network and undefined 352 // results. In this case, offline message should be displayed. 353 EXPECT_CALL(*mock_error_screen_actor_, 354 SetUIState(ErrorScreen::UI_STATE_UPDATE)) 355 .Times(1); 356 EXPECT_CALL(*mock_error_screen_actor_, 357 SetErrorState(ErrorScreen::ERROR_STATE_OFFLINE, std::string())) 358 .Times(1); 359 EXPECT_CALL(*mock_screen_observer_, ShowErrorScreen()) 360 .Times(1); 361 base::MessageLoop::current()->RunUntilIdle(); 362 NotifyPortalDetectionCompleted(); 363} 364 365IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestAPReselection) { 366 EXPECT_CALL(*mock_screen_observer_, 367 OnExit(ScreenObserver::UPDATE_NOUPDATE)) 368 .Times(1); 369 update_screen_->CancelUpdate(); 370 371 // Change ethernet state to portal. 372 NetworkPortalDetector::CaptivePortalState portal_state; 373 portal_state.status = NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL; 374 portal_state.response_code = 200; 375 SetDetectionResults(kStubEthernetServicePath, portal_state); 376 377 // Update screen will show error message about portal state because 378 // ethernet is behind captive portal. 379 EXPECT_CALL(*mock_error_screen_actor_, 380 SetUIState(ErrorScreen::UI_STATE_UPDATE)) 381 .Times(1); 382 EXPECT_CALL(*mock_error_screen_actor_, 383 SetErrorState(ErrorScreen::ERROR_STATE_PORTAL, std::string())) 384 .Times(1); 385 EXPECT_CALL(*mock_error_screen_actor_, FixCaptivePortal()) 386 .Times(1); 387 EXPECT_CALL(*mock_screen_observer_, ShowErrorScreen()) 388 .Times(1); 389 390 update_screen_->StartNetworkCheck(); 391 392 // User re-selects the same network manually. In this case, hide 393 // offline message and skip network check. Since ethernet is still 394 // behind portal, update engine fails to update. 395 EXPECT_CALL(*mock_screen_observer_, HideErrorScreen(update_screen_)) 396 .Times(1); 397 fake_update_engine_client_->set_update_check_result( 398 chromeos::UpdateEngineClient::UPDATE_RESULT_FAILED); 399 EXPECT_CALL(*mock_screen_observer_, 400 OnExit(ScreenObserver::UPDATE_ERROR_CHECKING_FOR_UPDATE)) 401 .Times(1); 402 403 update_screen_->OnConnectToNetworkRequested(kStubEthernetServicePath); 404 base::MessageLoop::current()->RunUntilIdle(); 405} 406 407} // namespace chromeos 408