1 // 2 // Copyright (C) 2012 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/connection_manager.h" 18 19 #include <set> 20 #include <string> 21 22 #include <base/logging.h> 23 #include <brillo/any.h> 24 #include <brillo/make_unique_ptr.h> 25 #include <brillo/message_loops/fake_message_loop.h> 26 #include <brillo/variant_dictionary.h> 27 #include <gmock/gmock.h> 28 #include <gtest/gtest.h> 29 #include <shill/dbus-constants.h> 30 #include <shill/dbus-proxies.h> 31 #include <shill/dbus-proxy-mocks.h> 32 33 #include "update_engine/common/test_utils.h" 34 #include "update_engine/fake_shill_proxy.h" 35 #include "update_engine/fake_system_state.h" 36 37 using org::chromium::flimflam::ManagerProxyMock; 38 using org::chromium::flimflam::ServiceProxyMock; 39 using std::set; 40 using std::string; 41 using testing::Return; 42 using testing::SetArgPointee; 43 using testing::_; 44 45 namespace chromeos_update_engine { 46 47 class ConnectionManagerTest : public ::testing::Test { 48 public: 49 void SetUp() override { 50 loop_.SetAsCurrent(); 51 fake_system_state_.set_connection_manager(&cmut_); 52 } 53 54 void TearDown() override { EXPECT_FALSE(loop_.PendingTasks()); } 55 56 protected: 57 // Sets the default_service object path in the response from the 58 // ManagerProxyMock instance. 59 void SetManagerReply(const char* default_service, bool reply_succeeds); 60 61 // Sets the |service_type|, |physical_technology| and |service_tethering| 62 // properties in the mocked service |service_path|. If any of the three 63 // const char* is a nullptr, the corresponding property will not be included 64 // in the response. 65 void SetServiceReply(const string& service_path, 66 const char* service_type, 67 const char* physical_technology, 68 const char* service_tethering); 69 70 void TestWithServiceType( 71 const char* service_type, 72 const char* physical_technology, 73 NetworkConnectionType expected_type); 74 void TestWithServiceTethering( 75 const char* service_tethering, 76 NetworkTethering expected_tethering); 77 78 brillo::FakeMessageLoop loop_{nullptr}; 79 FakeSystemState fake_system_state_; 80 FakeShillProxy fake_shill_proxy_; 81 82 // ConnectionManager under test. 83 ConnectionManager cmut_{&fake_shill_proxy_, &fake_system_state_}; 84 }; 85 86 void ConnectionManagerTest::SetManagerReply(const char* default_service, 87 bool reply_succeeds) { 88 ManagerProxyMock* manager_proxy_mock = fake_shill_proxy_.GetManagerProxy(); 89 if (!reply_succeeds) { 90 EXPECT_CALL(*manager_proxy_mock, GetProperties(_, _, _)) 91 .WillOnce(Return(false)); 92 return; 93 } 94 95 // Create a dictionary of properties and optionally include the default 96 // service. 97 brillo::VariantDictionary reply_dict; 98 reply_dict["SomeOtherProperty"] = 0xC0FFEE; 99 100 if (default_service) { 101 reply_dict[shill::kDefaultServiceProperty] = 102 dbus::ObjectPath(default_service); 103 } 104 EXPECT_CALL(*manager_proxy_mock, GetProperties(_, _, _)) 105 .WillOnce(DoAll(SetArgPointee<0>(reply_dict), Return(true))); 106 } 107 108 void ConnectionManagerTest::SetServiceReply(const string& service_path, 109 const char* service_type, 110 const char* physical_technology, 111 const char* service_tethering) { 112 brillo::VariantDictionary reply_dict; 113 reply_dict["SomeOtherProperty"] = 0xC0FFEE; 114 115 if (service_type) 116 reply_dict[shill::kTypeProperty] = string(service_type); 117 118 if (physical_technology) { 119 reply_dict[shill::kPhysicalTechnologyProperty] = 120 string(physical_technology); 121 } 122 123 if (service_tethering) 124 reply_dict[shill::kTetheringProperty] = string(service_tethering); 125 126 std::unique_ptr<ServiceProxyMock> service_proxy_mock(new ServiceProxyMock()); 127 128 // Plumb return value into mock object. 129 EXPECT_CALL(*service_proxy_mock.get(), GetProperties(_, _, _)) 130 .WillOnce(DoAll(SetArgPointee<0>(reply_dict), Return(true))); 131 132 fake_shill_proxy_.SetServiceForPath(dbus::ObjectPath(service_path), 133 std::move(service_proxy_mock)); 134 } 135 136 void ConnectionManagerTest::TestWithServiceType( 137 const char* service_type, 138 const char* physical_technology, 139 NetworkConnectionType expected_type) { 140 SetManagerReply("/service/guest/network", true); 141 SetServiceReply("/service/guest/network", 142 service_type, 143 physical_technology, 144 shill::kTetheringNotDetectedState); 145 146 NetworkConnectionType type; 147 NetworkTethering tethering; 148 EXPECT_TRUE(cmut_.GetConnectionProperties(&type, &tethering)); 149 EXPECT_EQ(expected_type, type); 150 testing::Mock::VerifyAndClearExpectations( 151 fake_shill_proxy_.GetManagerProxy()); 152 } 153 154 void ConnectionManagerTest::TestWithServiceTethering( 155 const char* service_tethering, 156 NetworkTethering expected_tethering) { 157 SetManagerReply("/service/guest/network", true); 158 SetServiceReply( 159 "/service/guest/network", shill::kTypeWifi, nullptr, service_tethering); 160 161 NetworkConnectionType type; 162 NetworkTethering tethering; 163 EXPECT_TRUE(cmut_.GetConnectionProperties(&type, &tethering)); 164 EXPECT_EQ(expected_tethering, tethering); 165 testing::Mock::VerifyAndClearExpectations( 166 fake_shill_proxy_.GetManagerProxy()); 167 } 168 169 TEST_F(ConnectionManagerTest, SimpleTest) { 170 TestWithServiceType(shill::kTypeEthernet, nullptr, 171 NetworkConnectionType::kEthernet); 172 TestWithServiceType(shill::kTypeWifi, nullptr, 173 NetworkConnectionType::kWifi); 174 TestWithServiceType(shill::kTypeWimax, nullptr, 175 NetworkConnectionType::kWimax); 176 TestWithServiceType(shill::kTypeBluetooth, nullptr, 177 NetworkConnectionType::kBluetooth); 178 TestWithServiceType(shill::kTypeCellular, nullptr, 179 NetworkConnectionType::kCellular); 180 } 181 182 TEST_F(ConnectionManagerTest, PhysicalTechnologyTest) { 183 TestWithServiceType(shill::kTypeVPN, nullptr, 184 NetworkConnectionType::kUnknown); 185 TestWithServiceType(shill::kTypeVPN, shill::kTypeVPN, 186 NetworkConnectionType::kUnknown); 187 TestWithServiceType(shill::kTypeVPN, shill::kTypeWifi, 188 NetworkConnectionType::kWifi); 189 TestWithServiceType(shill::kTypeVPN, shill::kTypeWimax, 190 NetworkConnectionType::kWimax); 191 } 192 193 TEST_F(ConnectionManagerTest, TetheringTest) { 194 TestWithServiceTethering(shill::kTetheringConfirmedState, 195 NetworkTethering::kConfirmed); 196 TestWithServiceTethering(shill::kTetheringNotDetectedState, 197 NetworkTethering::kNotDetected); 198 TestWithServiceTethering(shill::kTetheringSuspectedState, 199 NetworkTethering::kSuspected); 200 TestWithServiceTethering("I'm not a valid property value =)", 201 NetworkTethering::kUnknown); 202 } 203 204 TEST_F(ConnectionManagerTest, UnknownTest) { 205 TestWithServiceType("foo", nullptr, NetworkConnectionType::kUnknown); 206 } 207 208 TEST_F(ConnectionManagerTest, AllowUpdatesOverEthernetTest) { 209 // Updates over Ethernet are allowed even if there's no policy. 210 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kEthernet, 211 NetworkTethering::kUnknown)); 212 } 213 214 TEST_F(ConnectionManagerTest, AllowUpdatesOverWifiTest) { 215 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kWifi, 216 NetworkTethering::kUnknown)); 217 } 218 219 TEST_F(ConnectionManagerTest, AllowUpdatesOverWimaxTest) { 220 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kWimax, 221 NetworkTethering::kUnknown)); 222 } 223 224 TEST_F(ConnectionManagerTest, BlockUpdatesOverBluetoothTest) { 225 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kBluetooth, 226 NetworkTethering::kUnknown)); 227 } 228 229 TEST_F(ConnectionManagerTest, AllowUpdatesOnlyOver3GPerPolicyTest) { 230 policy::MockDevicePolicy allow_3g_policy; 231 232 fake_system_state_.set_device_policy(&allow_3g_policy); 233 234 // This test tests cellular (3G) being the only connection type being allowed. 235 set<string> allowed_set; 236 allowed_set.insert( 237 cmut_.StringForConnectionType(NetworkConnectionType::kCellular)); 238 239 EXPECT_CALL(allow_3g_policy, GetAllowedConnectionTypesForUpdate(_)) 240 .Times(1) 241 .WillOnce(DoAll(SetArgPointee<0>(allowed_set), Return(true))); 242 243 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kCellular, 244 NetworkTethering::kUnknown)); 245 } 246 247 TEST_F(ConnectionManagerTest, AllowUpdatesOver3GAndOtherTypesPerPolicyTest) { 248 policy::MockDevicePolicy allow_3g_policy; 249 250 fake_system_state_.set_device_policy(&allow_3g_policy); 251 252 // This test tests multiple connection types being allowed, with 253 // 3G one among them. Only Cellular is currently enforced by the policy 254 // setting, the others are ignored (see Bluetooth for example). 255 set<string> allowed_set; 256 allowed_set.insert( 257 cmut_.StringForConnectionType(NetworkConnectionType::kCellular)); 258 allowed_set.insert( 259 cmut_.StringForConnectionType(NetworkConnectionType::kBluetooth)); 260 261 EXPECT_CALL(allow_3g_policy, GetAllowedConnectionTypesForUpdate(_)) 262 .Times(3) 263 .WillRepeatedly(DoAll(SetArgPointee<0>(allowed_set), Return(true))); 264 265 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kEthernet, 266 NetworkTethering::kUnknown)); 267 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kEthernet, 268 NetworkTethering::kNotDetected)); 269 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kCellular, 270 NetworkTethering::kUnknown)); 271 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kWifi, 272 NetworkTethering::kUnknown)); 273 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kWimax, 274 NetworkTethering::kUnknown)); 275 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kBluetooth, 276 NetworkTethering::kUnknown)); 277 278 // Tethered networks are treated in the same way as Cellular networks and 279 // thus allowed. 280 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kEthernet, 281 NetworkTethering::kConfirmed)); 282 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kWifi, 283 NetworkTethering::kConfirmed)); 284 } 285 286 TEST_F(ConnectionManagerTest, BlockUpdatesOverCellularByDefaultTest) { 287 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kCellular, 288 NetworkTethering::kUnknown)); 289 } 290 291 TEST_F(ConnectionManagerTest, BlockUpdatesOverTetheredNetworkByDefaultTest) { 292 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kWifi, 293 NetworkTethering::kConfirmed)); 294 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kEthernet, 295 NetworkTethering::kConfirmed)); 296 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kWifi, 297 NetworkTethering::kSuspected)); 298 } 299 300 TEST_F(ConnectionManagerTest, BlockUpdatesOver3GPerPolicyTest) { 301 policy::MockDevicePolicy block_3g_policy; 302 303 fake_system_state_.set_device_policy(&block_3g_policy); 304 305 // Test that updates for 3G are blocked while updates are allowed 306 // over several other types. 307 set<string> allowed_set; 308 allowed_set.insert( 309 cmut_.StringForConnectionType(NetworkConnectionType::kEthernet)); 310 allowed_set.insert( 311 cmut_.StringForConnectionType(NetworkConnectionType::kWifi)); 312 allowed_set.insert( 313 cmut_.StringForConnectionType(NetworkConnectionType::kWimax)); 314 315 EXPECT_CALL(block_3g_policy, GetAllowedConnectionTypesForUpdate(_)) 316 .Times(1) 317 .WillOnce(DoAll(SetArgPointee<0>(allowed_set), Return(true))); 318 319 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kCellular, 320 NetworkTethering::kUnknown)); 321 } 322 323 TEST_F(ConnectionManagerTest, BlockUpdatesOver3GIfErrorInPolicyFetchTest) { 324 policy::MockDevicePolicy allow_3g_policy; 325 326 fake_system_state_.set_device_policy(&allow_3g_policy); 327 328 set<string> allowed_set; 329 allowed_set.insert( 330 cmut_.StringForConnectionType(NetworkConnectionType::kCellular)); 331 332 // Return false for GetAllowedConnectionTypesForUpdate and see 333 // that updates are still blocked for 3G despite the value being in 334 // the string set above. 335 EXPECT_CALL(allow_3g_policy, GetAllowedConnectionTypesForUpdate(_)) 336 .Times(1) 337 .WillOnce(DoAll(SetArgPointee<0>(allowed_set), Return(false))); 338 339 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kCellular, 340 NetworkTethering::kUnknown)); 341 } 342 343 TEST_F(ConnectionManagerTest, UseUserPrefForUpdatesOverCellularIfNoPolicyTest) { 344 policy::MockDevicePolicy no_policy; 345 testing::NiceMock<MockPrefs>* prefs = fake_system_state_.mock_prefs(); 346 347 fake_system_state_.set_device_policy(&no_policy); 348 349 // No setting enforced by the device policy, user prefs should be used. 350 EXPECT_CALL(no_policy, GetAllowedConnectionTypesForUpdate(_)) 351 .Times(3) 352 .WillRepeatedly(Return(false)); 353 354 // No user pref: block. 355 EXPECT_CALL(*prefs, Exists(kPrefsUpdateOverCellularPermission)) 356 .Times(1) 357 .WillOnce(Return(false)); 358 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kCellular, 359 NetworkTethering::kUnknown)); 360 361 // Allow per user pref. 362 EXPECT_CALL(*prefs, Exists(kPrefsUpdateOverCellularPermission)) 363 .Times(1) 364 .WillOnce(Return(true)); 365 EXPECT_CALL(*prefs, GetBoolean(kPrefsUpdateOverCellularPermission, _)) 366 .Times(1) 367 .WillOnce(DoAll(SetArgPointee<1>(true), Return(true))); 368 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kCellular, 369 NetworkTethering::kUnknown)); 370 371 // Block per user pref. 372 EXPECT_CALL(*prefs, Exists(kPrefsUpdateOverCellularPermission)) 373 .Times(1) 374 .WillOnce(Return(true)); 375 EXPECT_CALL(*prefs, GetBoolean(kPrefsUpdateOverCellularPermission, _)) 376 .Times(1) 377 .WillOnce(DoAll(SetArgPointee<1>(false), Return(true))); 378 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kCellular, 379 NetworkTethering::kUnknown)); 380 } 381 382 TEST_F(ConnectionManagerTest, StringForConnectionTypeTest) { 383 EXPECT_STREQ(shill::kTypeEthernet, 384 cmut_.StringForConnectionType(NetworkConnectionType::kEthernet)); 385 EXPECT_STREQ(shill::kTypeWifi, 386 cmut_.StringForConnectionType(NetworkConnectionType::kWifi)); 387 EXPECT_STREQ(shill::kTypeWimax, 388 cmut_.StringForConnectionType(NetworkConnectionType::kWimax)); 389 EXPECT_STREQ(shill::kTypeBluetooth, 390 cmut_.StringForConnectionType( 391 NetworkConnectionType::kBluetooth)); 392 EXPECT_STREQ(shill::kTypeCellular, 393 cmut_.StringForConnectionType(NetworkConnectionType::kCellular)); 394 EXPECT_STREQ("Unknown", 395 cmut_.StringForConnectionType(NetworkConnectionType::kUnknown)); 396 EXPECT_STREQ("Unknown", 397 cmut_.StringForConnectionType( 398 static_cast<NetworkConnectionType>(999999))); 399 } 400 401 TEST_F(ConnectionManagerTest, MalformedServiceList) { 402 SetManagerReply("/service/guest/network", false); 403 404 NetworkConnectionType type; 405 NetworkTethering tethering; 406 EXPECT_FALSE(cmut_.GetConnectionProperties(&type, &tethering)); 407 } 408 409 } // namespace chromeos_update_engine 410