• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
24 using ::testing::AnyNumber;
25 using ::testing::AtLeast;
26 using ::testing::Exactly;
27 using ::testing::Invoke;
28 using ::testing::Return;
29 using ::testing::_;
30 
31 namespace chromeos {
32 
33 namespace {
34 
35 const char kStubEthernetServicePath[] = "eth0";
36 const char kStubWifiServicePath[] = "wlan0";
37 
38 }  // namespace
39 
40 class UpdateScreenTest : public WizardInProcessBrowserTest {
41  public:
UpdateScreenTest()42   UpdateScreenTest() : WizardInProcessBrowserTest("update"),
43                        fake_update_engine_client_(NULL),
44                        network_portal_detector_(NULL) {
45   }
46 
47  protected:
SetUpInProcessBrowserTestFixture()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 
SetUpOnMainThread()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 
CleanUpOnMainThread()94   virtual void CleanUpOnMainThread() OVERRIDE {
95     mock_error_screen_.reset();
96     mock_error_screen_actor_.reset();
97     WizardInProcessBrowserTest::CleanUpOnMainThread();
98   }
99 
TearDownInProcessBrowserTestFixture()100   virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
101     NetworkPortalDetector::Shutdown();
102     WizardInProcessBrowserTest::TearDownInProcessBrowserTestFixture();
103   }
104 
SetDefaultNetworkPath(const std::string & service_path)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 
SetDetectionResults(const std::string & service_path,const NetworkPortalDetector::CaptivePortalState & state)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 
NotifyPortalDetectionCompleted()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 
IN_PROC_BROWSER_TEST_F(UpdateScreenTest,TestBasic)136 IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestBasic) {
137   ASSERT_TRUE(update_screen_->actor_ != NULL);
138 }
139 
IN_PROC_BROWSER_TEST_F(UpdateScreenTest,TestNoUpdate)140 IN_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 
IN_PROC_BROWSER_TEST_F(UpdateScreenTest,TestUpdateAvailable)157 IN_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 
IN_PROC_BROWSER_TEST_F(UpdateScreenTest,TestErrorIssuingUpdateCheck)192 IN_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 
IN_PROC_BROWSER_TEST_F(UpdateScreenTest,TestErrorCheckingForUpdate)207 IN_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 
IN_PROC_BROWSER_TEST_F(UpdateScreenTest,TestErrorUpdating)220 IN_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 
IN_PROC_BROWSER_TEST_F(UpdateScreenTest,TestTemproraryOfflineNetwork)241 IN_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 
IN_PROC_BROWSER_TEST_F(UpdateScreenTest,TestTwoOfflineNetworks)287 IN_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 
IN_PROC_BROWSER_TEST_F(UpdateScreenTest,TestVoidNetwork)331 IN_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 
IN_PROC_BROWSER_TEST_F(UpdateScreenTest,TestAPReselection)366 IN_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