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