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