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/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: 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 86 void TearDown() override { 87 provider_.reset(); 88 // Check for leaked callbacks on the main loop. 89 EXPECT_FALSE(loop_.PendingTasks()); 90 } 91 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 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 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 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 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 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 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_update_disabled()); 181 UmTestUtils::ExpectVariableNotSet(provider_->var_target_version_prefix()); 182 UmTestUtils::ExpectVariableNotSet( 183 provider_->var_rollback_to_target_version()); 184 UmTestUtils::ExpectVariableNotSet( 185 provider_->var_rollback_allowed_milestones()); 186 UmTestUtils::ExpectVariableNotSet(provider_->var_scatter_factor()); 187 UmTestUtils::ExpectVariableNotSet( 188 provider_->var_allowed_connection_types_for_update()); 189 UmTestUtils::ExpectVariableNotSet(provider_->var_owner()); 190 UmTestUtils::ExpectVariableNotSet(provider_->var_http_downloads_enabled()); 191 UmTestUtils::ExpectVariableNotSet(provider_->var_au_p2p_enabled()); 192 UmTestUtils::ExpectVariableNotSet( 193 provider_->var_allow_kiosk_app_control_chrome_version()); 194 UmTestUtils::ExpectVariableNotSet( 195 provider_->var_auto_launched_kiosk_app_id()); 196 UmTestUtils::ExpectVariableNotSet(provider_->var_disallowed_time_intervals()); 197 } 198 199 TEST_F(UmRealDevicePolicyProviderTest, ValuesUpdated) { 200 SetUpNonExistentDevicePolicy(); 201 EXPECT_TRUE(provider_->Init()); 202 loop_.RunOnce(false); 203 Mock::VerifyAndClearExpectations(&mock_policy_provider_); 204 205 // Reload the policy with a good one and set some values as present. The 206 // remaining values are false. 207 SetUpExistentDevicePolicy(); 208 EXPECT_CALL(mock_device_policy_, GetReleaseChannel(_)) 209 .WillOnce(DoAll(SetArgPointee<0>(string("mychannel")), Return(true))); 210 EXPECT_CALL(mock_device_policy_, GetAllowedConnectionTypesForUpdate(_)) 211 .WillOnce(Return(false)); 212 EXPECT_CALL(mock_device_policy_, GetAllowKioskAppControlChromeVersion(_)) 213 .WillOnce(DoAll(SetArgPointee<0>(true), Return(true))); 214 EXPECT_CALL(mock_device_policy_, GetAutoLaunchedKioskAppId(_)) 215 .WillOnce(DoAll(SetArgPointee<0>(string("myapp")), Return(true))); 216 217 provider_->RefreshDevicePolicy(); 218 219 UmTestUtils::ExpectVariableHasValue(true, 220 provider_->var_device_policy_is_loaded()); 221 222 // Test that at least one variable is set, to ensure the refresh occurred. 223 UmTestUtils::ExpectVariableHasValue(string("mychannel"), 224 provider_->var_release_channel()); 225 UmTestUtils::ExpectVariableNotSet( 226 provider_->var_allowed_connection_types_for_update()); 227 UmTestUtils::ExpectVariableHasValue( 228 true, provider_->var_allow_kiosk_app_control_chrome_version()); 229 UmTestUtils::ExpectVariableHasValue( 230 string("myapp"), provider_->var_auto_launched_kiosk_app_id()); 231 } 232 233 TEST_F(UmRealDevicePolicyProviderTest, RollbackToTargetVersionConverted) { 234 SetUpExistentDevicePolicy(); 235 EXPECT_CALL(mock_device_policy_, GetRollbackToTargetVersion(_)) 236 #if USE_DBUS 237 .Times(2) 238 #else 239 .Times(1) 240 #endif // USE_DBUS 241 .WillRepeatedly(DoAll(SetArgPointee<0>(2), Return(true))); 242 EXPECT_TRUE(provider_->Init()); 243 loop_.RunOnce(false); 244 245 UmTestUtils::ExpectVariableHasValue( 246 RollbackToTargetVersion::kRollbackAndPowerwash, 247 provider_->var_rollback_to_target_version()); 248 } 249 250 TEST_F(UmRealDevicePolicyProviderTest, RollbackAllowedMilestonesOobe) { 251 SetUpNonExistentDevicePolicy(); 252 EXPECT_CALL(mock_device_policy_, GetRollbackAllowedMilestones(_)).Times(0); 253 ON_CALL(mock_policy_provider_, IsConsumerDevice()) 254 .WillByDefault(Return(false)); 255 EXPECT_TRUE(provider_->Init()); 256 loop_.RunOnce(false); 257 258 UmTestUtils::ExpectVariableNotSet( 259 provider_->var_rollback_allowed_milestones()); 260 } 261 262 TEST_F(UmRealDevicePolicyProviderTest, RollbackAllowedMilestonesConsumer) { 263 SetUpNonExistentDevicePolicy(); 264 EXPECT_CALL(mock_device_policy_, GetRollbackAllowedMilestones(_)).Times(0); 265 ON_CALL(mock_policy_provider_, IsConsumerDevice()) 266 .WillByDefault(Return(true)); 267 EXPECT_TRUE(provider_->Init()); 268 loop_.RunOnce(false); 269 270 UmTestUtils::ExpectVariableHasValue( 271 0, provider_->var_rollback_allowed_milestones()); 272 } 273 274 TEST_F(UmRealDevicePolicyProviderTest, 275 RollbackAllowedMilestonesEnterprisePolicySet) { 276 SetUpExistentDevicePolicy(); 277 ON_CALL(mock_device_policy_, GetRollbackAllowedMilestones(_)) 278 .WillByDefault(DoAll(SetArgPointee<0>(2), Return(true))); 279 ON_CALL(mock_policy_provider_, IsConsumerDevice()) 280 .WillByDefault(Return(false)); 281 EXPECT_TRUE(provider_->Init()); 282 loop_.RunOnce(false); 283 284 UmTestUtils::ExpectVariableHasValue( 285 2, provider_->var_rollback_allowed_milestones()); 286 } 287 288 TEST_F(UmRealDevicePolicyProviderTest, ScatterFactorConverted) { 289 SetUpExistentDevicePolicy(); 290 EXPECT_CALL(mock_device_policy_, GetScatterFactorInSeconds(_)) 291 #if USE_DBUS 292 .Times(2) 293 #else 294 .Times(1) 295 #endif // USE_DBUS 296 .WillRepeatedly(DoAll(SetArgPointee<0>(1234), Return(true))); 297 EXPECT_TRUE(provider_->Init()); 298 loop_.RunOnce(false); 299 300 UmTestUtils::ExpectVariableHasValue(TimeDelta::FromSeconds(1234), 301 provider_->var_scatter_factor()); 302 } 303 304 TEST_F(UmRealDevicePolicyProviderTest, NegativeScatterFactorIgnored) { 305 SetUpExistentDevicePolicy(); 306 EXPECT_CALL(mock_device_policy_, GetScatterFactorInSeconds(_)) 307 #if USE_DBUS 308 .Times(2) 309 #else 310 .Times(1) 311 #endif // USE_DBUS 312 .WillRepeatedly(DoAll(SetArgPointee<0>(-1), Return(true))); 313 EXPECT_TRUE(provider_->Init()); 314 loop_.RunOnce(false); 315 316 UmTestUtils::ExpectVariableNotSet(provider_->var_scatter_factor()); 317 } 318 319 TEST_F(UmRealDevicePolicyProviderTest, AllowedTypesConverted) { 320 SetUpExistentDevicePolicy(); 321 EXPECT_CALL(mock_device_policy_, GetAllowedConnectionTypesForUpdate(_)) 322 #if USE_DBUS 323 .Times(2) 324 #else 325 .Times(1) 326 #endif // USE_DBUS 327 .WillRepeatedly(DoAll( 328 SetArgPointee<0>(set<string>{"bluetooth", "wifi", "not-a-type"}), 329 Return(true))); 330 EXPECT_TRUE(provider_->Init()); 331 loop_.RunOnce(false); 332 333 UmTestUtils::ExpectVariableHasValue( 334 set<ConnectionType>{ConnectionType::kWifi, ConnectionType::kBluetooth}, 335 provider_->var_allowed_connection_types_for_update()); 336 } 337 338 TEST_F(UmRealDevicePolicyProviderTest, DisallowedIntervalsConverted) { 339 SetUpExistentDevicePolicy(); 340 341 vector<DevicePolicy::WeeklyTimeInterval> intervals = { 342 {5, TimeDelta::FromHours(5), 6, TimeDelta::FromHours(8)}, 343 {1, TimeDelta::FromHours(1), 3, TimeDelta::FromHours(10)}}; 344 345 EXPECT_CALL(mock_device_policy_, GetDisallowedTimeIntervals(_)) 346 .WillRepeatedly(DoAll(SetArgPointee<0>(intervals), Return(true))); 347 EXPECT_TRUE(provider_->Init()); 348 loop_.RunOnce(false); 349 350 UmTestUtils::ExpectVariableHasValue( 351 WeeklyTimeIntervalVector{ 352 WeeklyTimeInterval(WeeklyTime(5, TimeDelta::FromHours(5)), 353 WeeklyTime(6, TimeDelta::FromHours(8))), 354 WeeklyTimeInterval(WeeklyTime(1, TimeDelta::FromHours(1)), 355 WeeklyTime(3, TimeDelta::FromHours(10)))}, 356 provider_->var_disallowed_time_intervals()); 357 } 358 359 } // namespace chromeos_update_manager 360