1 //
2 // Copyright (C) 2014 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include "update_engine/update_manager/real_device_policy_provider.h"
18
19 #include <memory>
20 #include <vector>
21
22 #include <base/memory/ptr_util.h>
23 #include <brillo/message_loops/fake_message_loop.h>
24 #include <brillo/message_loops/message_loop.h>
25 #include <brillo/message_loops/message_loop_utils.h>
26 #include <gmock/gmock.h>
27 #include <gtest/gtest.h>
28 #include <policy/mock_device_policy.h>
29 #include <policy/mock_libpolicy.h>
30 #if USE_DBUS
31 #include <session_manager/dbus-proxies.h>
32 #include <session_manager/dbus-proxy-mocks.h>
33 #endif // USE_DBUS
34
35 #include "update_engine/common/test_utils.h"
36 #if USE_DBUS
37 #include "update_engine/cros/dbus_test_utils.h"
38 #endif // USE_DBUS
39 #include "update_engine/update_manager/umtest_utils.h"
40
41 using base::TimeDelta;
42 using brillo::MessageLoop;
43 using chromeos_update_engine::ConnectionType;
44 using policy::DevicePolicy;
45 #if USE_DBUS
46 using chromeos_update_engine::dbus_test_utils::MockSignalHandler;
47 #endif // USE_DBUS
48 using std::set;
49 using std::string;
50 using std::unique_ptr;
51 using std::vector;
52 using testing::_;
53 using testing::DoAll;
54 using testing::Mock;
55 using testing::Return;
56 using testing::ReturnRef;
57 using testing::SetArgPointee;
58
59 namespace chromeos_update_manager {
60
61 class UmRealDevicePolicyProviderTest : public ::testing::Test {
62 protected:
SetUp()63 void SetUp() override {
64 loop_.SetAsCurrent();
65 #if USE_DBUS
66 auto session_manager_proxy_mock =
67 new org::chromium::SessionManagerInterfaceProxyMock();
68 provider_.reset(new RealDevicePolicyProvider(
69 base::WrapUnique(session_manager_proxy_mock), &mock_policy_provider_));
70 #else
71 provider_.reset(new RealDevicePolicyProvider(&mock_policy_provider_));
72 #endif // USE_DBUS
73 // By default, we have a device policy loaded. Tests can call
74 // SetUpNonExistentDevicePolicy() to override this.
75 SetUpExistentDevicePolicy();
76
77 #if USE_DBUS
78 // Setup the session manager_proxy such that it will accept the signal
79 // handler and store it in the |property_change_complete_| once registered.
80 MOCK_SIGNAL_HANDLER_EXPECT_SIGNAL_HANDLER(property_change_complete_,
81 *session_manager_proxy_mock,
82 PropertyChangeComplete);
83 #endif // USE_DBUS
84 }
85
TearDown()86 void TearDown() override {
87 provider_.reset();
88 // Check for leaked callbacks on the main loop.
89 EXPECT_FALSE(loop_.PendingTasks());
90 }
91
SetUpNonExistentDevicePolicy()92 void SetUpNonExistentDevicePolicy() {
93 ON_CALL(mock_policy_provider_, Reload()).WillByDefault(Return(false));
94 ON_CALL(mock_policy_provider_, device_policy_is_loaded())
95 .WillByDefault(Return(false));
96 EXPECT_CALL(mock_policy_provider_, GetDevicePolicy()).Times(0);
97 }
98
SetUpExistentDevicePolicy()99 void SetUpExistentDevicePolicy() {
100 // Setup the default behavior of the mocked PolicyProvider.
101 ON_CALL(mock_policy_provider_, Reload()).WillByDefault(Return(true));
102 ON_CALL(mock_policy_provider_, device_policy_is_loaded())
103 .WillByDefault(Return(true));
104 ON_CALL(mock_policy_provider_, GetDevicePolicy())
105 .WillByDefault(ReturnRef(mock_device_policy_));
106 }
107
108 brillo::FakeMessageLoop loop_{nullptr};
109 testing::NiceMock<policy::MockDevicePolicy> mock_device_policy_;
110 testing::NiceMock<policy::MockPolicyProvider> mock_policy_provider_;
111 unique_ptr<RealDevicePolicyProvider> provider_;
112
113 #if USE_DBUS
114 // The registered signal handler for the signal.
115 MockSignalHandler<void(const string&)> property_change_complete_;
116 #endif // USE_DBUS
117 };
118
TEST_F(UmRealDevicePolicyProviderTest,RefreshScheduledTest)119 TEST_F(UmRealDevicePolicyProviderTest, RefreshScheduledTest) {
120 // Check that the RefreshPolicy gets scheduled by checking the TaskId.
121 EXPECT_TRUE(provider_->Init());
122 EXPECT_NE(MessageLoop::kTaskIdNull, provider_->scheduled_refresh_);
123 loop_.RunOnce(false);
124 }
125
TEST_F(UmRealDevicePolicyProviderTest,FirstReload)126 TEST_F(UmRealDevicePolicyProviderTest, FirstReload) {
127 // Checks that the policy is reloaded and the DevicePolicy is consulted twice:
128 // once on Init() and once again when the signal is connected.
129 EXPECT_CALL(mock_policy_provider_, Reload());
130 EXPECT_TRUE(provider_->Init());
131 Mock::VerifyAndClearExpectations(&mock_policy_provider_);
132 // We won't be notified that signal is connected without DBus.
133 #if USE_DBUS
134 EXPECT_CALL(mock_policy_provider_, Reload());
135 #endif // USE_DBUS
136 loop_.RunOnce(false);
137 }
138
TEST_F(UmRealDevicePolicyProviderTest,NonExistentDevicePolicyReloaded)139 TEST_F(UmRealDevicePolicyProviderTest, NonExistentDevicePolicyReloaded) {
140 // Checks that the policy is reloaded by RefreshDevicePolicy().
141 SetUpNonExistentDevicePolicy();
142 // We won't be notified that signal is connected without DBus.
143 #if USE_DBUS
144 EXPECT_CALL(mock_policy_provider_, Reload()).Times(3);
145 #else
146 EXPECT_CALL(mock_policy_provider_, Reload()).Times(2);
147 #endif // USE_DBUS
148 EXPECT_TRUE(provider_->Init());
149 loop_.RunOnce(false);
150 // Force the policy refresh.
151 provider_->RefreshDevicePolicy();
152 }
153
154 #if USE_DBUS
TEST_F(UmRealDevicePolicyProviderTest,SessionManagerSignalForcesReload)155 TEST_F(UmRealDevicePolicyProviderTest, SessionManagerSignalForcesReload) {
156 // Checks that a signal from the SessionManager forces a reload.
157 SetUpNonExistentDevicePolicy();
158 EXPECT_CALL(mock_policy_provider_, Reload()).Times(2);
159 EXPECT_TRUE(provider_->Init());
160 loop_.RunOnce(false);
161 Mock::VerifyAndClearExpectations(&mock_policy_provider_);
162
163 EXPECT_CALL(mock_policy_provider_, Reload());
164 ASSERT_TRUE(property_change_complete_.IsHandlerRegistered());
165 property_change_complete_.signal_callback().Run("success");
166 }
167 #endif // USE_DBUS
168
TEST_F(UmRealDevicePolicyProviderTest,NonExistentDevicePolicyEmptyVariables)169 TEST_F(UmRealDevicePolicyProviderTest, NonExistentDevicePolicyEmptyVariables) {
170 SetUpNonExistentDevicePolicy();
171 EXPECT_CALL(mock_policy_provider_, GetDevicePolicy()).Times(0);
172 EXPECT_TRUE(provider_->Init());
173 loop_.RunOnce(false);
174
175 UmTestUtils::ExpectVariableHasValue(false,
176 provider_->var_device_policy_is_loaded());
177
178 UmTestUtils::ExpectVariableNotSet(provider_->var_release_channel());
179 UmTestUtils::ExpectVariableNotSet(provider_->var_release_channel_delegated());
180 UmTestUtils::ExpectVariableNotSet(provider_->var_release_lts_tag());
181 UmTestUtils::ExpectVariableNotSet(provider_->var_update_disabled());
182 UmTestUtils::ExpectVariableNotSet(provider_->var_target_version_prefix());
183 UmTestUtils::ExpectVariableNotSet(
184 provider_->var_rollback_to_target_version());
185 UmTestUtils::ExpectVariableNotSet(
186 provider_->var_rollback_allowed_milestones());
187 UmTestUtils::ExpectVariableNotSet(provider_->var_scatter_factor());
188 UmTestUtils::ExpectVariableNotSet(
189 provider_->var_allowed_connection_types_for_update());
190 UmTestUtils::ExpectVariableNotSet(provider_->var_has_owner());
191 UmTestUtils::ExpectVariableNotSet(provider_->var_http_downloads_enabled());
192 UmTestUtils::ExpectVariableNotSet(provider_->var_au_p2p_enabled());
193 UmTestUtils::ExpectVariableNotSet(
194 provider_->var_allow_kiosk_app_control_chrome_version());
195 UmTestUtils::ExpectVariableNotSet(
196 provider_->var_auto_launched_kiosk_app_id());
197 UmTestUtils::ExpectVariableNotSet(provider_->var_disallowed_time_intervals());
198 UmTestUtils::ExpectVariableNotSet(
199 provider_->var_channel_downgrade_behavior());
200 UmTestUtils::ExpectVariableNotSet(provider_->var_quick_fix_build_token());
201 }
202
TEST_F(UmRealDevicePolicyProviderTest,ValuesUpdated)203 TEST_F(UmRealDevicePolicyProviderTest, ValuesUpdated) {
204 SetUpNonExistentDevicePolicy();
205 EXPECT_TRUE(provider_->Init());
206 loop_.RunOnce(false);
207 Mock::VerifyAndClearExpectations(&mock_policy_provider_);
208
209 // Reload the policy with a good one and set some values as present. The
210 // remaining values are false.
211 SetUpExistentDevicePolicy();
212 EXPECT_CALL(mock_device_policy_, GetReleaseChannel(_))
213 .WillOnce(DoAll(SetArgPointee<0>(string("mychannel")), Return(true)));
214 EXPECT_CALL(mock_device_policy_, GetAllowedConnectionTypesForUpdate(_))
215 .WillOnce(Return(false));
216 EXPECT_CALL(mock_device_policy_, GetAllowKioskAppControlChromeVersion(_))
217 .WillOnce(DoAll(SetArgPointee<0>(true), Return(true)));
218 EXPECT_CALL(mock_device_policy_, GetAutoLaunchedKioskAppId(_))
219 .WillOnce(DoAll(SetArgPointee<0>(string("myapp")), Return(true)));
220
221 provider_->RefreshDevicePolicy();
222
223 UmTestUtils::ExpectVariableHasValue(true,
224 provider_->var_device_policy_is_loaded());
225
226 // Test that at least one variable is set, to ensure the refresh occurred.
227 UmTestUtils::ExpectVariableHasValue(string("mychannel"),
228 provider_->var_release_channel());
229 UmTestUtils::ExpectVariableNotSet(
230 provider_->var_allowed_connection_types_for_update());
231 UmTestUtils::ExpectVariableHasValue(
232 true, provider_->var_allow_kiosk_app_control_chrome_version());
233 UmTestUtils::ExpectVariableHasValue(
234 string("myapp"), provider_->var_auto_launched_kiosk_app_id());
235 }
236
TEST_F(UmRealDevicePolicyProviderTest,HasOwnerConverted)237 TEST_F(UmRealDevicePolicyProviderTest, HasOwnerConverted) {
238 SetUpExistentDevicePolicy();
239 EXPECT_TRUE(provider_->Init());
240 loop_.RunOnce(false);
241 Mock::VerifyAndClearExpectations(&mock_policy_provider_);
242
243 EXPECT_CALL(mock_device_policy_, GetOwner(_))
244 .Times(2)
245 .WillOnce(DoAll(SetArgPointee<0>(string("")), Return(true)))
246 .WillOnce(DoAll(SetArgPointee<0>(string("abc@test.org")), Return(true)));
247
248 // Enterprise enrolled device.
249 provider_->RefreshDevicePolicy();
250 UmTestUtils::ExpectVariableHasValue(false, provider_->var_has_owner());
251
252 // Has a device owner.
253 provider_->RefreshDevicePolicy();
254 UmTestUtils::ExpectVariableHasValue(true, provider_->var_has_owner());
255 }
256
TEST_F(UmRealDevicePolicyProviderTest,RollbackToTargetVersionConverted)257 TEST_F(UmRealDevicePolicyProviderTest, RollbackToTargetVersionConverted) {
258 SetUpExistentDevicePolicy();
259 EXPECT_CALL(mock_device_policy_, GetRollbackToTargetVersion(_))
260 #if USE_DBUS
261 .Times(2)
262 #else
263 .Times(1)
264 #endif // USE_DBUS
265 .WillRepeatedly(DoAll(SetArgPointee<0>(2), Return(true)));
266 EXPECT_TRUE(provider_->Init());
267 loop_.RunOnce(false);
268
269 UmTestUtils::ExpectVariableHasValue(
270 RollbackToTargetVersion::kRollbackAndPowerwash,
271 provider_->var_rollback_to_target_version());
272 }
273
TEST_F(UmRealDevicePolicyProviderTest,RollbackAllowedMilestonesOobe)274 TEST_F(UmRealDevicePolicyProviderTest, RollbackAllowedMilestonesOobe) {
275 SetUpNonExistentDevicePolicy();
276 EXPECT_CALL(mock_device_policy_, GetRollbackAllowedMilestones(_)).Times(0);
277 ON_CALL(mock_policy_provider_, IsConsumerDevice())
278 .WillByDefault(Return(false));
279 EXPECT_TRUE(provider_->Init());
280 loop_.RunOnce(false);
281
282 UmTestUtils::ExpectVariableNotSet(
283 provider_->var_rollback_allowed_milestones());
284 }
285
TEST_F(UmRealDevicePolicyProviderTest,RollbackAllowedMilestonesConsumer)286 TEST_F(UmRealDevicePolicyProviderTest, RollbackAllowedMilestonesConsumer) {
287 SetUpNonExistentDevicePolicy();
288 EXPECT_CALL(mock_device_policy_, GetRollbackAllowedMilestones(_)).Times(0);
289 ON_CALL(mock_policy_provider_, IsConsumerDevice())
290 .WillByDefault(Return(true));
291 EXPECT_TRUE(provider_->Init());
292 loop_.RunOnce(false);
293
294 UmTestUtils::ExpectVariableHasValue(
295 0, provider_->var_rollback_allowed_milestones());
296 }
297
TEST_F(UmRealDevicePolicyProviderTest,RollbackAllowedMilestonesEnterprisePolicySet)298 TEST_F(UmRealDevicePolicyProviderTest,
299 RollbackAllowedMilestonesEnterprisePolicySet) {
300 SetUpExistentDevicePolicy();
301 ON_CALL(mock_device_policy_, GetRollbackAllowedMilestones(_))
302 .WillByDefault(DoAll(SetArgPointee<0>(2), Return(true)));
303 ON_CALL(mock_policy_provider_, IsConsumerDevice())
304 .WillByDefault(Return(false));
305 EXPECT_TRUE(provider_->Init());
306 loop_.RunOnce(false);
307
308 UmTestUtils::ExpectVariableHasValue(
309 2, provider_->var_rollback_allowed_milestones());
310 }
311
TEST_F(UmRealDevicePolicyProviderTest,ScatterFactorConverted)312 TEST_F(UmRealDevicePolicyProviderTest, ScatterFactorConverted) {
313 SetUpExistentDevicePolicy();
314 EXPECT_CALL(mock_device_policy_, GetScatterFactorInSeconds(_))
315 #if USE_DBUS
316 .Times(2)
317 #else
318 .Times(1)
319 #endif // USE_DBUS
320 .WillRepeatedly(DoAll(SetArgPointee<0>(1234), Return(true)));
321 EXPECT_TRUE(provider_->Init());
322 loop_.RunOnce(false);
323
324 UmTestUtils::ExpectVariableHasValue(TimeDelta::FromSeconds(1234),
325 provider_->var_scatter_factor());
326 }
327
TEST_F(UmRealDevicePolicyProviderTest,NegativeScatterFactorIgnored)328 TEST_F(UmRealDevicePolicyProviderTest, NegativeScatterFactorIgnored) {
329 SetUpExistentDevicePolicy();
330 EXPECT_CALL(mock_device_policy_, GetScatterFactorInSeconds(_))
331 #if USE_DBUS
332 .Times(2)
333 #else
334 .Times(1)
335 #endif // USE_DBUS
336 .WillRepeatedly(DoAll(SetArgPointee<0>(-1), Return(true)));
337 EXPECT_TRUE(provider_->Init());
338 loop_.RunOnce(false);
339
340 UmTestUtils::ExpectVariableNotSet(provider_->var_scatter_factor());
341 }
342
TEST_F(UmRealDevicePolicyProviderTest,AllowedTypesConverted)343 TEST_F(UmRealDevicePolicyProviderTest, AllowedTypesConverted) {
344 SetUpExistentDevicePolicy();
345 EXPECT_CALL(mock_device_policy_, GetAllowedConnectionTypesForUpdate(_))
346 #if USE_DBUS
347 .Times(2)
348 #else
349 .Times(1)
350 #endif // USE_DBUS
351 .WillRepeatedly(
352 DoAll(SetArgPointee<0>(set<string>{"ethernet", "wifi", "not-a-type"}),
353 Return(true)));
354 EXPECT_TRUE(provider_->Init());
355 loop_.RunOnce(false);
356
357 UmTestUtils::ExpectVariableHasValue(
358 set<ConnectionType>{ConnectionType::kWifi, ConnectionType::kEthernet},
359 provider_->var_allowed_connection_types_for_update());
360 }
361
TEST_F(UmRealDevicePolicyProviderTest,DisallowedIntervalsConverted)362 TEST_F(UmRealDevicePolicyProviderTest, DisallowedIntervalsConverted) {
363 SetUpExistentDevicePolicy();
364
365 vector<DevicePolicy::WeeklyTimeInterval> intervals = {
366 {5, TimeDelta::FromHours(5), 6, TimeDelta::FromHours(8)},
367 {1, TimeDelta::FromHours(1), 3, TimeDelta::FromHours(10)}};
368
369 EXPECT_CALL(mock_device_policy_, GetDisallowedTimeIntervals(_))
370 .WillRepeatedly(DoAll(SetArgPointee<0>(intervals), Return(true)));
371 EXPECT_TRUE(provider_->Init());
372 loop_.RunOnce(false);
373
374 UmTestUtils::ExpectVariableHasValue(
375 WeeklyTimeIntervalVector{
376 WeeklyTimeInterval(WeeklyTime(5, TimeDelta::FromHours(5)),
377 WeeklyTime(6, TimeDelta::FromHours(8))),
378 WeeklyTimeInterval(WeeklyTime(1, TimeDelta::FromHours(1)),
379 WeeklyTime(3, TimeDelta::FromHours(10)))},
380 provider_->var_disallowed_time_intervals());
381 }
382
TEST_F(UmRealDevicePolicyProviderTest,ChannelDowngradeBehaviorConverted)383 TEST_F(UmRealDevicePolicyProviderTest, ChannelDowngradeBehaviorConverted) {
384 SetUpExistentDevicePolicy();
385 EXPECT_CALL(mock_device_policy_, GetChannelDowngradeBehavior(_))
386 #if USE_DBUS
387 .Times(2)
388 #else
389 .Times(1)
390 #endif // USE_DBUS
391 .WillRepeatedly(DoAll(SetArgPointee<0>(static_cast<int>(
392 ChannelDowngradeBehavior::kRollback)),
393 Return(true)));
394 EXPECT_TRUE(provider_->Init());
395 loop_.RunOnce(false);
396
397 UmTestUtils::ExpectVariableHasValue(
398 ChannelDowngradeBehavior::kRollback,
399 provider_->var_channel_downgrade_behavior());
400 }
401
TEST_F(UmRealDevicePolicyProviderTest,ChannelDowngradeBehaviorTooSmall)402 TEST_F(UmRealDevicePolicyProviderTest, ChannelDowngradeBehaviorTooSmall) {
403 SetUpExistentDevicePolicy();
404 EXPECT_CALL(mock_device_policy_, GetChannelDowngradeBehavior(_))
405 #if USE_DBUS
406 .Times(2)
407 #else
408 .Times(1)
409 #endif // USE_DBUS
410 .WillRepeatedly(DoAll(SetArgPointee<0>(-1), Return(true)));
411 EXPECT_TRUE(provider_->Init());
412 loop_.RunOnce(false);
413
414 UmTestUtils::ExpectVariableNotSet(
415 provider_->var_channel_downgrade_behavior());
416 }
417
TEST_F(UmRealDevicePolicyProviderTest,ChannelDowngradeBehaviorTooLarge)418 TEST_F(UmRealDevicePolicyProviderTest, ChannelDowngradeBehaviorTooLarge) {
419 SetUpExistentDevicePolicy();
420 EXPECT_CALL(mock_device_policy_, GetChannelDowngradeBehavior(_))
421 #if USE_DBUS
422 .Times(2)
423 #else
424 .Times(1)
425 #endif // USE_DBUS
426 .WillRepeatedly(DoAll(SetArgPointee<0>(10), Return(true)));
427 EXPECT_TRUE(provider_->Init());
428 loop_.RunOnce(false);
429
430 UmTestUtils::ExpectVariableNotSet(
431 provider_->var_channel_downgrade_behavior());
432 }
433
TEST_F(UmRealDevicePolicyProviderTest,DeviceMinimumVersionPolicySet)434 TEST_F(UmRealDevicePolicyProviderTest, DeviceMinimumVersionPolicySet) {
435 SetUpExistentDevicePolicy();
436
437 base::Version device_minimum_version("13315.60.12");
438
439 EXPECT_CALL(mock_device_policy_, GetHighestDeviceMinimumVersion(_))
440 .WillRepeatedly(
441 DoAll(SetArgPointee<0>(device_minimum_version), Return(true)));
442 EXPECT_TRUE(provider_->Init());
443 loop_.RunOnce(false);
444
445 UmTestUtils::ExpectVariableHasValue(device_minimum_version,
446 provider_->var_device_minimum_version());
447 }
448
TEST_F(UmRealDevicePolicyProviderTest,DeviceQuickFixBuildTokenSet)449 TEST_F(UmRealDevicePolicyProviderTest, DeviceQuickFixBuildTokenSet) {
450 SetUpExistentDevicePolicy();
451
452 EXPECT_CALL(mock_device_policy_, GetDeviceQuickFixBuildToken(_))
453 .WillRepeatedly(
454 DoAll(SetArgPointee<0>(string("some_token")), Return(true)));
455 EXPECT_TRUE(provider_->Init());
456 loop_.RunOnce(false);
457
458 UmTestUtils::ExpectVariableHasValue(string("some_token"),
459 provider_->var_quick_fix_build_token());
460 }
461
462 } // namespace chromeos_update_manager
463