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 21 #include <base/memory/ptr_util.h> 22 #include <brillo/message_loops/fake_message_loop.h> 23 #include <brillo/message_loops/message_loop.h> 24 #include <brillo/message_loops/message_loop_utils.h> 25 #include <gmock/gmock.h> 26 #include <gtest/gtest.h> 27 #include <policy/mock_device_policy.h> 28 #include <policy/mock_libpolicy.h> 29 #if USE_DBUS 30 #include <session_manager/dbus-proxies.h> 31 #include <session_manager/dbus-proxy-mocks.h> 32 #endif // USE_DBUS 33 34 #include "update_engine/common/test_utils.h" 35 #if USE_DBUS 36 #include "update_engine/dbus_test_utils.h" 37 #endif // USE_DBUS 38 #include "update_engine/update_manager/umtest_utils.h" 39 40 using base::TimeDelta; 41 using brillo::MessageLoop; 42 using chromeos_update_engine::ConnectionType; 43 #if USE_DBUS 44 using chromeos_update_engine::dbus_test_utils::MockSignalHandler; 45 #endif // USE_DBUS 46 using std::set; 47 using std::string; 48 using std::unique_ptr; 49 using testing::DoAll; 50 using testing::Mock; 51 using testing::Return; 52 using testing::ReturnRef; 53 using testing::SetArgPointee; 54 using testing::_; 55 56 namespace chromeos_update_manager { 57 58 class UmRealDevicePolicyProviderTest : public ::testing::Test { 59 protected: 60 void SetUp() override { 61 loop_.SetAsCurrent(); 62 #if USE_DBUS 63 auto session_manager_proxy_mock = 64 new org::chromium::SessionManagerInterfaceProxyMock(); 65 provider_.reset(new RealDevicePolicyProvider( 66 base::WrapUnique(session_manager_proxy_mock), &mock_policy_provider_)); 67 #else 68 provider_.reset(new RealDevicePolicyProvider(&mock_policy_provider_)); 69 #endif // USE_DBUS 70 // By default, we have a device policy loaded. Tests can call 71 // SetUpNonExistentDevicePolicy() to override this. 72 SetUpExistentDevicePolicy(); 73 74 #if USE_DBUS 75 // Setup the session manager_proxy such that it will accept the signal 76 // handler and store it in the |property_change_complete_| once registered. 77 MOCK_SIGNAL_HANDLER_EXPECT_SIGNAL_HANDLER(property_change_complete_, 78 *session_manager_proxy_mock, 79 PropertyChangeComplete); 80 #endif // USE_DBUS 81 } 82 83 void TearDown() override { 84 provider_.reset(); 85 // Check for leaked callbacks on the main loop. 86 EXPECT_FALSE(loop_.PendingTasks()); 87 } 88 89 void SetUpNonExistentDevicePolicy() { 90 ON_CALL(mock_policy_provider_, Reload()) 91 .WillByDefault(Return(false)); 92 ON_CALL(mock_policy_provider_, device_policy_is_loaded()) 93 .WillByDefault(Return(false)); 94 EXPECT_CALL(mock_policy_provider_, GetDevicePolicy()).Times(0); 95 } 96 97 void SetUpExistentDevicePolicy() { 98 // Setup the default behavior of the mocked PolicyProvider. 99 ON_CALL(mock_policy_provider_, Reload()) 100 .WillByDefault(Return(true)); 101 ON_CALL(mock_policy_provider_, device_policy_is_loaded()) 102 .WillByDefault(Return(true)); 103 ON_CALL(mock_policy_provider_, GetDevicePolicy()) 104 .WillByDefault(ReturnRef(mock_device_policy_)); 105 } 106 107 brillo::FakeMessageLoop loop_{nullptr}; 108 testing::NiceMock<policy::MockDevicePolicy> mock_device_policy_; 109 testing::NiceMock<policy::MockPolicyProvider> mock_policy_provider_; 110 unique_ptr<RealDevicePolicyProvider> provider_; 111 112 #if USE_DBUS 113 // The registered signal handler for the signal. 114 MockSignalHandler<void(const string&)> property_change_complete_; 115 #endif // USE_DBUS 116 }; 117 118 TEST_F(UmRealDevicePolicyProviderTest, RefreshScheduledTest) { 119 // Check that the RefreshPolicy gets scheduled by checking the TaskId. 120 EXPECT_TRUE(provider_->Init()); 121 EXPECT_NE(MessageLoop::kTaskIdNull, provider_->scheduled_refresh_); 122 loop_.RunOnce(false); 123 } 124 125 TEST_F(UmRealDevicePolicyProviderTest, FirstReload) { 126 // Checks that the policy is reloaded and the DevicePolicy is consulted twice: 127 // once on Init() and once again when the signal is connected. 128 EXPECT_CALL(mock_policy_provider_, Reload()); 129 EXPECT_TRUE(provider_->Init()); 130 Mock::VerifyAndClearExpectations(&mock_policy_provider_); 131 // We won't be notified that signal is connected without DBus. 132 #if USE_DBUS 133 EXPECT_CALL(mock_policy_provider_, Reload()); 134 #endif // USE_DBUS 135 loop_.RunOnce(false); 136 } 137 138 TEST_F(UmRealDevicePolicyProviderTest, NonExistentDevicePolicyReloaded) { 139 // Checks that the policy is reloaded by RefreshDevicePolicy(). 140 SetUpNonExistentDevicePolicy(); 141 // We won't be notified that signal is connected without DBus. 142 #if USE_DBUS 143 EXPECT_CALL(mock_policy_provider_, Reload()).Times(3); 144 #else 145 EXPECT_CALL(mock_policy_provider_, Reload()).Times(2); 146 #endif // USE_DBUS 147 EXPECT_TRUE(provider_->Init()); 148 loop_.RunOnce(false); 149 // Force the policy refresh. 150 provider_->RefreshDevicePolicy(); 151 } 152 153 #if USE_DBUS 154 TEST_F(UmRealDevicePolicyProviderTest, SessionManagerSignalForcesReload) { 155 // Checks that a signal from the SessionManager forces a reload. 156 SetUpNonExistentDevicePolicy(); 157 EXPECT_CALL(mock_policy_provider_, Reload()).Times(2); 158 EXPECT_TRUE(provider_->Init()); 159 loop_.RunOnce(false); 160 Mock::VerifyAndClearExpectations(&mock_policy_provider_); 161 162 EXPECT_CALL(mock_policy_provider_, Reload()); 163 ASSERT_TRUE(property_change_complete_.IsHandlerRegistered()); 164 property_change_complete_.signal_callback().Run("success"); 165 } 166 #endif // USE_DBUS 167 168 TEST_F(UmRealDevicePolicyProviderTest, NonExistentDevicePolicyEmptyVariables) { 169 SetUpNonExistentDevicePolicy(); 170 EXPECT_CALL(mock_policy_provider_, GetDevicePolicy()).Times(0); 171 EXPECT_TRUE(provider_->Init()); 172 loop_.RunOnce(false); 173 174 UmTestUtils::ExpectVariableHasValue(false, 175 provider_->var_device_policy_is_loaded()); 176 177 UmTestUtils::ExpectVariableNotSet(provider_->var_release_channel()); 178 UmTestUtils::ExpectVariableNotSet(provider_->var_release_channel_delegated()); 179 UmTestUtils::ExpectVariableNotSet(provider_->var_update_disabled()); 180 UmTestUtils::ExpectVariableNotSet(provider_->var_target_version_prefix()); 181 UmTestUtils::ExpectVariableNotSet(provider_->var_scatter_factor()); 182 UmTestUtils::ExpectVariableNotSet( 183 provider_->var_allowed_connection_types_for_update()); 184 UmTestUtils::ExpectVariableNotSet(provider_->var_owner()); 185 UmTestUtils::ExpectVariableNotSet(provider_->var_http_downloads_enabled()); 186 UmTestUtils::ExpectVariableNotSet(provider_->var_au_p2p_enabled()); 187 UmTestUtils::ExpectVariableNotSet( 188 provider_->var_allow_kiosk_app_control_chrome_version()); 189 } 190 191 TEST_F(UmRealDevicePolicyProviderTest, ValuesUpdated) { 192 SetUpNonExistentDevicePolicy(); 193 EXPECT_TRUE(provider_->Init()); 194 loop_.RunOnce(false); 195 Mock::VerifyAndClearExpectations(&mock_policy_provider_); 196 197 // Reload the policy with a good one and set some values as present. The 198 // remaining values are false. 199 SetUpExistentDevicePolicy(); 200 EXPECT_CALL(mock_device_policy_, GetReleaseChannel(_)) 201 .WillOnce(DoAll(SetArgPointee<0>(string("mychannel")), Return(true))); 202 EXPECT_CALL(mock_device_policy_, GetAllowedConnectionTypesForUpdate(_)) 203 .WillOnce(Return(false)); 204 EXPECT_CALL(mock_device_policy_, GetAllowKioskAppControlChromeVersion(_)) 205 .WillOnce(DoAll(SetArgPointee<0>(true), Return(true))); 206 207 provider_->RefreshDevicePolicy(); 208 209 UmTestUtils::ExpectVariableHasValue(true, 210 provider_->var_device_policy_is_loaded()); 211 212 // Test that at least one variable is set, to ensure the refresh occurred. 213 UmTestUtils::ExpectVariableHasValue(string("mychannel"), 214 provider_->var_release_channel()); 215 UmTestUtils::ExpectVariableNotSet( 216 provider_->var_allowed_connection_types_for_update()); 217 UmTestUtils::ExpectVariableHasValue( 218 true, provider_->var_allow_kiosk_app_control_chrome_version()); 219 } 220 221 TEST_F(UmRealDevicePolicyProviderTest, ScatterFactorConverted) { 222 SetUpExistentDevicePolicy(); 223 EXPECT_CALL(mock_device_policy_, GetScatterFactorInSeconds(_)) 224 #if USE_DBUS 225 .Times(2) 226 #else 227 .Times(1) 228 #endif // USE_DBUS 229 .WillRepeatedly(DoAll(SetArgPointee<0>(1234), Return(true))); 230 EXPECT_TRUE(provider_->Init()); 231 loop_.RunOnce(false); 232 233 UmTestUtils::ExpectVariableHasValue(TimeDelta::FromSeconds(1234), 234 provider_->var_scatter_factor()); 235 } 236 237 TEST_F(UmRealDevicePolicyProviderTest, NegativeScatterFactorIgnored) { 238 SetUpExistentDevicePolicy(); 239 EXPECT_CALL(mock_device_policy_, GetScatterFactorInSeconds(_)) 240 #if USE_DBUS 241 .Times(2) 242 #else 243 .Times(1) 244 #endif // USE_DBUS 245 .WillRepeatedly(DoAll(SetArgPointee<0>(-1), Return(true))); 246 EXPECT_TRUE(provider_->Init()); 247 loop_.RunOnce(false); 248 249 UmTestUtils::ExpectVariableNotSet(provider_->var_scatter_factor()); 250 } 251 252 TEST_F(UmRealDevicePolicyProviderTest, AllowedTypesConverted) { 253 SetUpExistentDevicePolicy(); 254 EXPECT_CALL(mock_device_policy_, GetAllowedConnectionTypesForUpdate(_)) 255 #if USE_DBUS 256 .Times(2) 257 #else 258 .Times(1) 259 #endif // USE_DBUS 260 .WillRepeatedly(DoAll( 261 SetArgPointee<0>(set<string>{"bluetooth", "wifi", "not-a-type"}), 262 Return(true))); 263 EXPECT_TRUE(provider_->Init()); 264 loop_.RunOnce(false); 265 266 UmTestUtils::ExpectVariableHasValue( 267 set<ConnectionType>{ConnectionType::kWifi, ConnectionType::kBluetooth}, 268 provider_->var_allowed_connection_types_for_update()); 269 } 270 271 } // namespace chromeos_update_manager 272