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 <brillo/make_unique_ptr.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 brillo::make_unique_ptr(session_manager_proxy_mock), 67 &mock_policy_provider_)); 68 #else 69 provider_.reset(new RealDevicePolicyProvider(&mock_policy_provider_)); 70 #endif // USE_DBUS 71 // By default, we have a device policy loaded. Tests can call 72 // SetUpNonExistentDevicePolicy() to override this. 73 SetUpExistentDevicePolicy(); 74 75 #if USE_DBUS 76 // Setup the session manager_proxy such that it will accept the signal 77 // handler and store it in the |property_change_complete_| once registered. 78 MOCK_SIGNAL_HANDLER_EXPECT_SIGNAL_HANDLER(property_change_complete_, 79 *session_manager_proxy_mock, 80 PropertyChangeComplete); 81 #endif // USE_DBUS 82 } 83 84 void TearDown() override { 85 provider_.reset(); 86 // Check for leaked callbacks on the main loop. 87 EXPECT_FALSE(loop_.PendingTasks()); 88 } 89 90 void SetUpNonExistentDevicePolicy() { 91 ON_CALL(mock_policy_provider_, Reload()) 92 .WillByDefault(Return(false)); 93 ON_CALL(mock_policy_provider_, device_policy_is_loaded()) 94 .WillByDefault(Return(false)); 95 EXPECT_CALL(mock_policy_provider_, GetDevicePolicy()).Times(0); 96 } 97 98 void SetUpExistentDevicePolicy() { 99 // Setup the default behavior of the mocked PolicyProvider. 100 ON_CALL(mock_policy_provider_, Reload()) 101 .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(provider_->var_scatter_factor()); 183 UmTestUtils::ExpectVariableNotSet( 184 provider_->var_allowed_connection_types_for_update()); 185 UmTestUtils::ExpectVariableNotSet(provider_->var_owner()); 186 UmTestUtils::ExpectVariableNotSet(provider_->var_http_downloads_enabled()); 187 UmTestUtils::ExpectVariableNotSet(provider_->var_au_p2p_enabled()); 188 UmTestUtils::ExpectVariableNotSet( 189 provider_->var_allow_kiosk_app_control_chrome_version()); 190 } 191 192 TEST_F(UmRealDevicePolicyProviderTest, ValuesUpdated) { 193 SetUpNonExistentDevicePolicy(); 194 EXPECT_TRUE(provider_->Init()); 195 loop_.RunOnce(false); 196 Mock::VerifyAndClearExpectations(&mock_policy_provider_); 197 198 // Reload the policy with a good one and set some values as present. The 199 // remaining values are false. 200 SetUpExistentDevicePolicy(); 201 EXPECT_CALL(mock_device_policy_, GetReleaseChannel(_)) 202 .WillOnce(DoAll(SetArgPointee<0>(string("mychannel")), Return(true))); 203 EXPECT_CALL(mock_device_policy_, GetAllowedConnectionTypesForUpdate(_)) 204 .WillOnce(Return(false)); 205 EXPECT_CALL(mock_device_policy_, GetAllowKioskAppControlChromeVersion(_)) 206 .WillOnce(DoAll(SetArgPointee<0>(true), Return(true))); 207 208 provider_->RefreshDevicePolicy(); 209 210 UmTestUtils::ExpectVariableHasValue(true, 211 provider_->var_device_policy_is_loaded()); 212 213 // Test that at least one variable is set, to ensure the refresh occurred. 214 UmTestUtils::ExpectVariableHasValue(string("mychannel"), 215 provider_->var_release_channel()); 216 UmTestUtils::ExpectVariableNotSet( 217 provider_->var_allowed_connection_types_for_update()); 218 UmTestUtils::ExpectVariableHasValue( 219 true, provider_->var_allow_kiosk_app_control_chrome_version()); 220 } 221 222 TEST_F(UmRealDevicePolicyProviderTest, ScatterFactorConverted) { 223 SetUpExistentDevicePolicy(); 224 EXPECT_CALL(mock_device_policy_, GetScatterFactorInSeconds(_)) 225 #if USE_DBUS 226 .Times(2) 227 #else 228 .Times(1) 229 #endif // USE_DBUS 230 .WillRepeatedly(DoAll(SetArgPointee<0>(1234), Return(true))); 231 EXPECT_TRUE(provider_->Init()); 232 loop_.RunOnce(false); 233 234 UmTestUtils::ExpectVariableHasValue(TimeDelta::FromSeconds(1234), 235 provider_->var_scatter_factor()); 236 } 237 238 TEST_F(UmRealDevicePolicyProviderTest, NegativeScatterFactorIgnored) { 239 SetUpExistentDevicePolicy(); 240 EXPECT_CALL(mock_device_policy_, GetScatterFactorInSeconds(_)) 241 #if USE_DBUS 242 .Times(2) 243 #else 244 .Times(1) 245 #endif // USE_DBUS 246 .WillRepeatedly(DoAll(SetArgPointee<0>(-1), Return(true))); 247 EXPECT_TRUE(provider_->Init()); 248 loop_.RunOnce(false); 249 250 UmTestUtils::ExpectVariableNotSet(provider_->var_scatter_factor()); 251 } 252 253 TEST_F(UmRealDevicePolicyProviderTest, AllowedTypesConverted) { 254 SetUpExistentDevicePolicy(); 255 EXPECT_CALL(mock_device_policy_, GetAllowedConnectionTypesForUpdate(_)) 256 #if USE_DBUS 257 .Times(2) 258 #else 259 .Times(1) 260 #endif // USE_DBUS 261 .WillRepeatedly(DoAll( 262 SetArgPointee<0>(set<string>{"bluetooth", "wifi", "not-a-type"}), 263 Return(true))); 264 EXPECT_TRUE(provider_->Init()); 265 loop_.RunOnce(false); 266 267 UmTestUtils::ExpectVariableHasValue( 268 set<ConnectionType>{ConnectionType::kWifi, ConnectionType::kBluetooth}, 269 provider_->var_allowed_connection_types_for_update()); 270 } 271 272 } // namespace chromeos_update_manager 273