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