OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/login/screens/update_screen.h" | 5 #include "chrome/browser/chromeos/login/screens/update_screen.h" |
6 #include "base/command_line.h" | 6 #include "base/command_line.h" |
7 #include "base/message_loop/message_loop.h" | 7 #include "base/message_loop/message_loop.h" |
8 #include "base/test/scoped_mock_time_message_loop_task_runner.h" | 8 #include "base/test/scoped_mock_time_message_loop_task_runner.h" |
9 #include "chrome/browser/chromeos/login/screens/mock_base_screen_delegate.h" | 9 #include "chrome/browser/chromeos/login/screens/mock_base_screen_delegate.h" |
10 #include "chrome/browser/chromeos/login/screens/mock_error_screen.h" | 10 #include "chrome/browser/chromeos/login/screens/mock_error_screen.h" |
(...skipping 19 matching lines...) Expand all Loading... |
30 using testing::Return; | 30 using testing::Return; |
31 | 31 |
32 namespace chromeos { | 32 namespace chromeos { |
33 | 33 |
34 class UpdateScreenUnitTest : public testing::Test { | 34 class UpdateScreenUnitTest : public testing::Test { |
35 public: | 35 public: |
36 UpdateScreenUnitTest() | 36 UpdateScreenUnitTest() |
37 : fake_controller_(""), | 37 : fake_controller_(""), |
38 local_state_(TestingBrowserProcess::GetGlobal()) {} | 38 local_state_(TestingBrowserProcess::GetGlobal()) {} |
39 | 39 |
40 // Fast-forwards time by the specified amount. | |
41 void FastForwardTime(base::TimeDelta time) { | |
42 base::Time last = StartupUtils::GetTimeOfLastUpdateCheckWithoutUpdate(); | |
43 ASSERT_FALSE(last.is_null()); | |
44 base::Time modified_last = last - time; | |
45 StartupUtils::SaveTimeOfLastUpdateCheckWithoutUpdate(modified_last); | |
46 } | |
47 | |
48 // Simulates an update being available (or not). | 40 // Simulates an update being available (or not). |
49 // The parameter "update_screen" points to the currently active UpdateScreen. | 41 // The parameter "update_screen" points to the currently active UpdateScreen. |
50 // The parameter "available" indicates whether an update is available. | 42 // The parameter "available" indicates whether an update is available. |
51 // The parameter "critical" indicates whether that update is critical. | 43 // The parameter "critical" indicates whether that update is critical. |
52 void SimulateUpdateAvailable( | 44 void SimulateUpdateAvailable( |
53 const std::unique_ptr<UpdateScreen>& update_screen, | 45 const std::unique_ptr<UpdateScreen>& update_screen, |
54 bool available, | 46 bool available, |
55 bool critical) { | 47 bool critical) { |
56 update_engine_status_.status = | 48 update_engine_status_.status = |
57 UpdateEngineClient::UPDATE_STATUS_CHECKING_FOR_UPDATE; | 49 UpdateEngineClient::UPDATE_STATUS_CHECKING_FOR_UPDATE; |
(...skipping 10 matching lines...) Expand all Loading... |
68 fake_update_engine_client_->NotifyObserversThatStatusChanged( | 60 fake_update_engine_client_->NotifyObserversThatStatusChanged( |
69 update_engine_status_); | 61 update_engine_status_); |
70 } | 62 } |
71 | 63 |
72 // testing::Test: | 64 // testing::Test: |
73 void SetUp() override { | 65 void SetUp() override { |
74 // Configure the browser to use Hands-Off Enrollment. | 66 // Configure the browser to use Hands-Off Enrollment. |
75 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( | 67 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( |
76 switches::kEnterpriseEnableZeroTouchEnrollment, "hands-off"); | 68 switches::kEnterpriseEnableZeroTouchEnrollment, "hands-off"); |
77 | 69 |
78 // Initialize objects needed by UpdateScreen | 70 // Initialize objects needed by UpdateScreen. |
79 fake_update_engine_client_ = new FakeUpdateEngineClient(); | 71 fake_update_engine_client_ = new FakeUpdateEngineClient(); |
80 DBusThreadManager::GetSetterForTesting()->SetUpdateEngineClient( | 72 DBusThreadManager::GetSetterForTesting()->SetUpdateEngineClient( |
81 std::unique_ptr<UpdateEngineClient>(fake_update_engine_client_)); | 73 std::unique_ptr<UpdateEngineClient>(fake_update_engine_client_)); |
82 NetworkHandler::Initialize(); | 74 NetworkHandler::Initialize(); |
83 mock_network_portal_detector_ = new MockNetworkPortalDetector(); | 75 mock_network_portal_detector_ = new MockNetworkPortalDetector(); |
84 network_portal_detector::SetNetworkPortalDetector( | 76 network_portal_detector::SetNetworkPortalDetector( |
85 mock_network_portal_detector_); | 77 mock_network_portal_detector_); |
86 mock_error_screen_.reset( | 78 mock_error_screen_.reset( |
87 new MockErrorScreen(&mock_base_screen_delegate_, &mock_error_view_)); | 79 new MockErrorScreen(&mock_base_screen_delegate_, &mock_error_view_)); |
88 | 80 |
89 // Ensure proper behavior of UpdateScreen's supporting objects. | 81 // Ensure proper behavior of UpdateScreen's supporting objects. |
90 EXPECT_CALL(*mock_network_portal_detector_, IsEnabled()) | 82 EXPECT_CALL(*mock_network_portal_detector_, IsEnabled()) |
91 .Times(AnyNumber()) | 83 .Times(AnyNumber()) |
92 .WillRepeatedly(Return(false)); | 84 .WillRepeatedly(Return(false)); |
93 EXPECT_CALL(mock_base_screen_delegate_, GetErrorScreen()) | 85 EXPECT_CALL(mock_base_screen_delegate_, GetErrorScreen()) |
94 .Times(AnyNumber()) | 86 .Times(AnyNumber()) |
95 .WillRepeatedly(Return(mock_error_screen_.get())); | 87 .WillRepeatedly(Return(mock_error_screen_.get())); |
96 | |
97 // Later verifies that UpdateScreen successfully exits both times. | |
98 EXPECT_CALL(mock_base_screen_delegate_, | |
99 OnExit(_, ScreenExitCode::UPDATE_NOUPDATE, _)) | |
100 .Times(2); | |
101 } | 88 } |
102 | 89 |
103 void TearDown() override { | 90 void TearDown() override { |
104 TestingBrowserProcess::GetGlobal()->SetShuttingDown(true); | 91 TestingBrowserProcess::GetGlobal()->SetShuttingDown(true); |
105 first_update_screen_.reset(); | 92 update_screen_.reset(); |
106 second_update_screen_.reset(); | |
107 mock_error_screen_.reset(); | 93 mock_error_screen_.reset(); |
108 network_portal_detector::Shutdown(); | 94 network_portal_detector::Shutdown(); |
109 NetworkHandler::Shutdown(); | 95 NetworkHandler::Shutdown(); |
110 DBusThreadManager::Shutdown(); | 96 DBusThreadManager::Shutdown(); |
111 } | 97 } |
112 | 98 |
113 protected: | 99 protected: |
114 // A pointer to the UpdateScreen that shows up during the first OOBE. | 100 // A pointer to the UpdateScreen used in this test. |
115 std::unique_ptr<UpdateScreen> first_update_screen_; | 101 std::unique_ptr<UpdateScreen> update_screen_; |
116 | |
117 // A pointer to the UpdateScreen which shows up during the second OOBE. | |
118 // This test verifies proper behavior if the device is restarted before | |
119 // OOBE is complete, which is why there is a second OOBE. | |
120 std::unique_ptr<UpdateScreen> second_update_screen_; | |
121 | 102 |
122 // Accessory objects needed by UpdateScreen. | 103 // Accessory objects needed by UpdateScreen. |
123 MockBaseScreenDelegate mock_base_screen_delegate_; | 104 MockBaseScreenDelegate mock_base_screen_delegate_; |
124 MockUpdateView mock_view_; | 105 MockUpdateView mock_view_; |
125 MockNetworkErrorView mock_error_view_; | 106 MockNetworkErrorView mock_error_view_; |
126 UpdateEngineClient::Status update_engine_status_; | 107 UpdateEngineClient::Status update_engine_status_; |
127 pairing_chromeos::FakeHostPairingController fake_controller_; | 108 pairing_chromeos::FakeHostPairingController fake_controller_; |
128 std::unique_ptr<MockErrorScreen> mock_error_screen_; | 109 std::unique_ptr<MockErrorScreen> mock_error_screen_; |
129 MockNetworkPortalDetector* mock_network_portal_detector_; | 110 MockNetworkPortalDetector* mock_network_portal_detector_; |
130 FakeUpdateEngineClient* fake_update_engine_client_; | 111 FakeUpdateEngineClient* fake_update_engine_client_; |
131 | 112 |
132 private: | 113 private: |
133 // Test versions of core browser infrastructure. | 114 // Test versions of core browser infrastructure. |
134 content::TestBrowserThreadBundle threads_; | 115 content::TestBrowserThreadBundle threads_; |
135 ScopedTestingLocalState local_state_; | 116 ScopedTestingLocalState local_state_; |
136 | 117 |
137 DISALLOW_COPY_AND_ASSIGN(UpdateScreenUnitTest); | 118 DISALLOW_COPY_AND_ASSIGN(UpdateScreenUnitTest); |
138 }; | 119 }; |
139 | 120 |
140 // Test Scenario Description: | 121 TEST_F(UpdateScreenUnitTest, HandlesNoUpdate) { |
141 // In this description, "will" refers to an external event, and "should" refers | 122 // Set expectation that UpdateScreen will exit successfully |
142 // to the expected behavior of the DUT in response to external events. | 123 // with code UPDATE_NOUPDATE. |
143 // | 124 EXPECT_CALL(mock_base_screen_delegate_, |
144 // The DUT boots up and starts OOBE. Since it is a Hands-Off device, it | 125 OnExit(_, ScreenExitCode::UPDATE_NOUPDATE, _)) |
145 // proceeds through OOBE automatically. When it hits the UpdateScreen, | 126 .Times(1); |
146 // it checks for updates. It will find that there is indeed an update | 127 |
147 // available, will then install it. After installing the update, it should | 128 // DUT reaches UpdateScreen. |
148 // continue with Hands-Off OOBE. Then, before OOBE is complete, something | 129 update_screen_.reset(new UpdateScreen(&mock_base_screen_delegate_, |
149 // (could be user, environment, anything) will cause the DUT to reboot. | 130 &mock_view_, &fake_controller_)); |
150 // Since OOBE is not complete, the DUT goes through OOBE again. | 131 update_screen_->StartNetworkCheck(); |
151 // When the DUT hits the UpdateScreen during this second OOBE run-through, | |
152 // it should check for updates again. | |
153 TEST_F(UpdateScreenUnitTest, ChecksForUpdateBothTimesIfFirstIsInstalled) { | |
154 // DUT reaches UpdateScreen for the first time. | |
155 first_update_screen_.reset(new UpdateScreen(&mock_base_screen_delegate_, | |
156 &mock_view_, &fake_controller_)); | |
157 first_update_screen_->StartNetworkCheck(); | |
158 | 132 |
159 // Verify that the DUT checks for an update. | 133 // Verify that the DUT checks for an update. |
160 EXPECT_EQ(fake_update_engine_client_->request_update_check_call_count(), 1); | 134 EXPECT_EQ(fake_update_engine_client_->request_update_check_call_count(), 1); |
161 | 135 |
162 // An update is available. | 136 // No updates are available. |
163 SimulateUpdateAvailable(first_update_screen_, true /* available */, | 137 SimulateUpdateAvailable(update_screen_, false /* available */, |
164 false /* critical */); | |
165 | |
166 // DUT reboots... | |
167 // After rebooting, the DUT reaches UpdateScreen for the second time. | |
168 second_update_screen_.reset(new UpdateScreen(&mock_base_screen_delegate_, | |
169 &mock_view_, &fake_controller_)); | |
170 second_update_screen_->StartNetworkCheck(); | |
171 | |
172 // Verify that the DUT checks for updates again. | |
173 EXPECT_EQ(fake_update_engine_client_->request_update_check_call_count(), 2); | |
174 | |
175 // No updates available this time. | |
176 SimulateUpdateAvailable(second_update_screen_, false /* available */, | |
177 false /* critical */); | 138 false /* critical */); |
178 } | 139 } |
179 | 140 |
180 // Test Scenario Description: | 141 TEST_F(UpdateScreenUnitTest, HandlesNonCriticalUpdate) { |
181 // In this description, "will" refers to an external event, and "should" refers | 142 // Set expectation that UpdateScreen will exit successfully |
182 // to the expected behavior of the DUT in response to external events. | 143 // with code UPDATE_NOUPDATE. No, this is not a typo. |
183 // | 144 // UPDATE_NOUPDATE means that either there was no update |
184 // The DUT boots up and starts OOBE. Since it is a Hands-Off device, it | 145 // or there was a non-critical update. |
185 // proceeds through OOBE automatically. When it hits the UpdateScreen, | 146 EXPECT_CALL(mock_base_screen_delegate_, |
186 // it checks for updates. It will find that there are no updates | 147 OnExit(_, ScreenExitCode::UPDATE_NOUPDATE, _)) |
187 // available, and it should leave the UpdateScreen without installing any | 148 .Times(1); |
188 // updates. It continues with OOBE. Then, before OOBE is complete, something | |
189 // (could be user, environment, anything) will cause the DUT to reboot. | |
190 // Since OOBE is not complete, the DUT goes through OOBE again. | |
191 // When the DUT hits the UpdateScreen during this second OOBE run-through, | |
192 // more than one hour will have passed since the previous update check. | |
193 // Therefore, the DUT should check for updates again. | |
194 TEST_F(UpdateScreenUnitTest, ChecksForUpdateBothTimesIfEnoughTimePasses) { | |
195 // DUT reaches UpdateScreen for the first time. | |
196 first_update_screen_.reset(new UpdateScreen(&mock_base_screen_delegate_, | |
197 &mock_view_, &fake_controller_)); | |
198 first_update_screen_->StartNetworkCheck(); | |
199 | 149 |
200 // Verify that the DUT checks for updates. | 150 // DUT reaches UpdateScreen. |
| 151 update_screen_.reset(new UpdateScreen(&mock_base_screen_delegate_, |
| 152 &mock_view_, &fake_controller_)); |
| 153 update_screen_->StartNetworkCheck(); |
| 154 |
| 155 // Verify that the DUT checks for an update. |
201 EXPECT_EQ(fake_update_engine_client_->request_update_check_call_count(), 1); | 156 EXPECT_EQ(fake_update_engine_client_->request_update_check_call_count(), 1); |
202 | 157 |
203 // No updates are available. | 158 // A non-critical update is available. |
204 SimulateUpdateAvailable(first_update_screen_, false /* available */, | 159 SimulateUpdateAvailable(update_screen_, true /* available */, |
205 false /* critical */); | |
206 | |
207 // Fast-forward time by one hour. | |
208 FastForwardTime(base::TimeDelta::FromHours(1)); | |
209 | |
210 // DUT reboots... | |
211 // After rebooting, the DUT reaches UpdateScreen for the second time. | |
212 second_update_screen_.reset(new UpdateScreen(&mock_base_screen_delegate_, | |
213 &mock_view_, &fake_controller_)); | |
214 second_update_screen_->StartNetworkCheck(); | |
215 | |
216 // Verify that the DUT checks for updates again. | |
217 EXPECT_EQ(fake_update_engine_client_->request_update_check_call_count(), 2); | |
218 | |
219 // No updates available this time either. | |
220 SimulateUpdateAvailable(second_update_screen_, false /* available */, | |
221 false /* critical */); | 160 false /* critical */); |
222 } | 161 } |
223 | 162 |
224 // Test Scenario Description: | 163 TEST_F(UpdateScreenUnitTest, HandlesCriticalUpdate) { |
225 // In this description, "will" refers to an external event, and "should" refers | 164 // Set expectation that UpdateScreen does not exit. |
226 // to the expected behavior of the DUT in response to external events. | 165 // This is the case because a critical update mandates reboot. |
227 // | 166 EXPECT_CALL(mock_base_screen_delegate_, OnExit(_, _, _)).Times(0); |
228 // The DUT boots up and starts OOBE. Since it is a Hands-Off device, it | |
229 // proceeds through OOBE automatically. When it hits the UpdateScreen, | |
230 // it checks for updates. It will find that there are no updates | |
231 // available, and it should leave the UpdateScreen without installing any | |
232 // updates. It continues with OOBE. Then, before OOBE is complete, something | |
233 // (could be user, environment, anything) will cause the DUT to reboot. | |
234 // Since OOBE is not complete, the DUT goes through OOBE again. | |
235 // When the DUT hits the UpdateScreen during this second OOBE run-through, | |
236 // less than one hour will have passed since the previous update check. | |
237 // Therefore, the DUT should not check for updates again. | |
238 TEST_F(UpdateScreenUnitTest, ChecksForUpdateOnceButNotAgainIfTooSoon) { | |
239 // DUT reaches UpdateScreen for the first time. | |
240 first_update_screen_.reset(new UpdateScreen(&mock_base_screen_delegate_, | |
241 &mock_view_, &fake_controller_)); | |
242 first_update_screen_->StartNetworkCheck(); | |
243 | 167 |
244 // Verify that the DUT checks for updates. | 168 // DUT reaches UpdateScreen. |
245 EXPECT_EQ(fake_update_engine_client_->request_update_check_call_count(), 1); | 169 update_screen_.reset(new UpdateScreen(&mock_base_screen_delegate_, |
| 170 &mock_view_, &fake_controller_)); |
| 171 update_screen_->StartNetworkCheck(); |
246 | 172 |
247 // No update available. | 173 // Verify that the DUT checks for an update. |
248 SimulateUpdateAvailable(first_update_screen_, false /* available */, | |
249 false /* critical */); | |
250 | |
251 // DUT reboots... | |
252 // After rebooting, the DUT reaches UpdateScreen for the second time. | |
253 second_update_screen_.reset(new UpdateScreen(&mock_base_screen_delegate_, | |
254 &mock_view_, &fake_controller_)); | |
255 second_update_screen_->StartNetworkCheck(); | |
256 | |
257 // Verify that the DUT did not check for updates again. | |
258 EXPECT_EQ(fake_update_engine_client_->request_update_check_call_count(), 1); | |
259 | |
260 // No update available this time either. | |
261 SimulateUpdateAvailable(second_update_screen_, false /* available */, | |
262 false /* critical */); | |
263 } | |
264 | |
265 // Test Scenario Description: | |
266 // In this description, "will" refers to an external event, and "should" refers | |
267 // to the expected behavior of the DUT in response to external events. | |
268 // | |
269 // The DUT boots up and starts OOBE. Since it is a Hands-Off device, it | |
270 // proceeds through OOBE automatically. When it hits the UpdateScreen, | |
271 // it checks for updates. It will find that a critical update is available. | |
272 // The DUT installs the update, and because the update is critical, it reboots. | |
273 // Since OOBE is not complete, the DUT goes through OOBE again after reboot. | |
274 // When the DUT hits the UpdateScreen during this second OOBE run-through, | |
275 // it should check for updates again. | |
276 TEST_F(UpdateScreenUnitTest, ChecksForUpdateBothTimesIfCriticalUpdate) { | |
277 // DUT reaches UpdateScreen for the first time. | |
278 first_update_screen_.reset(new UpdateScreen(&mock_base_screen_delegate_, | |
279 &mock_view_, &fake_controller_)); | |
280 first_update_screen_->StartNetworkCheck(); | |
281 | |
282 // Verify that the DUT checks for updates. | |
283 EXPECT_EQ(fake_update_engine_client_->request_update_check_call_count(), 1); | 174 EXPECT_EQ(fake_update_engine_client_->request_update_check_call_count(), 1); |
284 | 175 |
285 // An update is available, and it's critical! | 176 // An update is available, and it's critical! |
286 SimulateUpdateAvailable(first_update_screen_, true /* available */, | 177 SimulateUpdateAvailable(update_screen_, true /* available */, |
287 true /* critical */); | 178 true /* critical */); |
288 | |
289 // DUT reboots... | |
290 // After rebooting, the DUT reaches UpdateScreen for the second time. | |
291 second_update_screen_.reset(new UpdateScreen(&mock_base_screen_delegate_, | |
292 &mock_view_, &fake_controller_)); | |
293 second_update_screen_->StartNetworkCheck(); | |
294 | |
295 // Verify that the DUT checks for updates again. | |
296 EXPECT_EQ(fake_update_engine_client_->request_update_check_call_count(), 2); | |
297 | |
298 // No update available this time. | |
299 SimulateUpdateAvailable(second_update_screen_, false /* available */, | |
300 false /* critical */); | |
301 } | 179 } |
302 | 180 |
303 } // namespace chromeos | 181 } // namespace chromeos |
OLD | NEW |