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