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 "shill/default_profile.h" 18 19 #include <map> 20 #include <memory> 21 #include <set> 22 #include <string> 23 #include <vector> 24 25 #include <base/files/file_path.h> 26 #if defined(__ANDROID__) 27 #include <dbus/service_constants.h> 28 #else 29 #include <chromeos/dbus/service_constants.h> 30 #endif // __ANDROID__ 31 #include <gtest/gtest.h> 32 #include <gmock/gmock.h> 33 34 #include "shill/connectivity_trial.h" 35 #include "shill/link_monitor.h" 36 #include "shill/manager.h" 37 #include "shill/mock_control.h" 38 #include "shill/mock_device.h" 39 #include "shill/mock_dhcp_properties.h" 40 #include "shill/mock_service.h" 41 #include "shill/mock_store.h" 42 #include "shill/portal_detector.h" 43 #include "shill/property_store_unittest.h" 44 #include "shill/resolver.h" 45 46 #if !defined(DISABLE_WIFI) 47 #include "shill/wifi/mock_wifi_provider.h" 48 #include "shill/wifi/wifi_service.h" 49 #endif // DISABLE_WIFI 50 51 using base::FilePath; 52 using std::map; 53 using std::set; 54 using std::string; 55 using std::unique_ptr; 56 using std::vector; 57 using ::testing::_; 58 using ::testing::DoAll; 59 using ::testing::NiceMock; 60 using ::testing::Return; 61 using ::testing::SetArgumentPointee; 62 63 namespace shill { 64 65 class DefaultProfileTest : public PropertyStoreTest { 66 public: 67 DefaultProfileTest() 68 : profile_(new DefaultProfile(control_interface(), 69 metrics(), 70 manager(), 71 FilePath(storage_path()), 72 DefaultProfile::kDefaultId, 73 properties_)), 74 device_(new MockDevice(control_interface(), 75 dispatcher(), 76 metrics(), 77 manager(), 78 "null0", 79 "addr0", 80 0)) { 81 } 82 83 virtual ~DefaultProfileTest() {} 84 85 protected: 86 static const char kTestStoragePath[]; 87 88 scoped_refptr<DefaultProfile> profile_; 89 scoped_refptr<MockDevice> device_; 90 Manager::Properties properties_; 91 }; 92 93 const char DefaultProfileTest::kTestStoragePath[] = "/no/where"; 94 95 TEST_F(DefaultProfileTest, GetProperties) { 96 // DBusAdaptor::GetProperties() will iterate over all the accessors 97 // provided by Profile. The |kEntriesProperty| accessor calls 98 // GetGroups() on the StoreInterface. 99 unique_ptr<MockStore> storage(new MockStore()); 100 set<string> empty_group_set; 101 EXPECT_CALL(*storage.get(), GetGroups()) 102 .WillRepeatedly(Return(empty_group_set)); 103 profile_->set_storage(storage.release()); 104 105 Error error(Error::kInvalidProperty, ""); 106 { 107 brillo::VariantDictionary props; 108 Error error; 109 profile_->store().GetProperties(&props, &error); 110 ASSERT_FALSE(props.find(kOfflineModeProperty) == props.end()); 111 EXPECT_TRUE(props[kOfflineModeProperty].IsTypeCompatible<bool>()); 112 EXPECT_FALSE(props[kOfflineModeProperty].Get<bool>()); 113 } 114 properties_.offline_mode = true; 115 { 116 brillo::VariantDictionary props; 117 Error error; 118 profile_->store().GetProperties(&props, &error); 119 ASSERT_FALSE(props.find(kOfflineModeProperty) == props.end()); 120 EXPECT_TRUE(props[kOfflineModeProperty].IsTypeCompatible<bool>()); 121 EXPECT_TRUE(props[kOfflineModeProperty].Get<bool>()); 122 } 123 { 124 Error error(Error::kInvalidProperty, ""); 125 EXPECT_FALSE( 126 profile_->mutable_store()->SetBoolProperty( 127 kOfflineModeProperty, 128 true, 129 &error)); 130 } 131 } 132 133 TEST_F(DefaultProfileTest, Save) { 134 unique_ptr<MockStore> storage(new MockStore()); 135 EXPECT_CALL(*storage.get(), SetBool(DefaultProfile::kStorageId, 136 DefaultProfile::kStorageArpGateway, 137 true)) 138 .WillOnce(Return(true)); 139 EXPECT_CALL(*storage.get(), SetString(DefaultProfile::kStorageId, 140 DefaultProfile::kStorageName, 141 DefaultProfile::kDefaultId)) 142 .WillOnce(Return(true)); 143 EXPECT_CALL(*storage.get(), SetString(DefaultProfile::kStorageId, 144 DefaultProfile::kStorageHostName, 145 "")) 146 .WillOnce(Return(true)); 147 EXPECT_CALL(*storage.get(), SetBool(DefaultProfile::kStorageId, 148 DefaultProfile::kStorageOfflineMode, 149 false)) 150 .WillOnce(Return(true)); 151 EXPECT_CALL(*storage.get(), SetString(DefaultProfile::kStorageId, 152 DefaultProfile::kStorageCheckPortalList, 153 "")) 154 .WillOnce(Return(true)); 155 EXPECT_CALL(*storage.get(), 156 SetString(DefaultProfile::kStorageId, 157 DefaultProfile::kStorageIgnoredDNSSearchPaths, 158 "")) 159 .WillOnce(Return(true)); 160 EXPECT_CALL(*storage.get(), 161 SetString(DefaultProfile::kStorageId, 162 DefaultProfile::kStorageLinkMonitorTechnologies, 163 "")) 164 .WillOnce(Return(true)); 165 EXPECT_CALL(*storage.get(), 166 SetString(DefaultProfile::kStorageId, 167 DefaultProfile::kStorageNoAutoConnectTechnologies, 168 "")) 169 .WillOnce(Return(true)); 170 EXPECT_CALL(*storage.get(), 171 SetString(DefaultProfile::kStorageId, 172 DefaultProfile::kStorageProhibitedTechnologies, 173 "")) 174 .WillOnce(Return(true)); 175 EXPECT_CALL(*storage.get(), SetString(DefaultProfile::kStorageId, 176 DefaultProfile::kStoragePortalURL, 177 "")) 178 .WillOnce(Return(true)); 179 EXPECT_CALL(*storage.get(), 180 SetString(DefaultProfile::kStorageId, 181 DefaultProfile::kStoragePortalCheckInterval, 182 "0")) 183 .WillOnce(Return(true)); 184 EXPECT_CALL(*storage.get(), Flush()).WillOnce(Return(true)); 185 186 EXPECT_CALL(*device_.get(), Save(storage.get())).Times(0); 187 profile_->set_storage(storage.release()); 188 unique_ptr<MockDhcpProperties> dhcp_props(new MockDhcpProperties()); 189 EXPECT_CALL(*dhcp_props.get(), Save(_,_)); 190 manager()->dhcp_properties_ = std::move(dhcp_props); 191 192 manager()->RegisterDevice(device_); 193 ASSERT_TRUE(profile_->Save()); 194 manager()->DeregisterDevice(device_); 195 } 196 197 TEST_F(DefaultProfileTest, LoadManagerDefaultProperties) { 198 unique_ptr<MockStore> storage(new MockStore()); 199 Manager::Properties manager_props; 200 EXPECT_CALL(*storage.get(), GetBool(DefaultProfile::kStorageId, 201 DefaultProfile::kStorageArpGateway, 202 &manager_props.arp_gateway)) 203 .WillOnce(Return(false)); 204 EXPECT_CALL(*storage.get(), GetString(DefaultProfile::kStorageId, 205 DefaultProfile::kStorageHostName, 206 &manager_props.host_name)) 207 .WillOnce(Return(false)); 208 EXPECT_CALL(*storage.get(), GetBool(DefaultProfile::kStorageId, 209 DefaultProfile::kStorageOfflineMode, 210 &manager_props.offline_mode)) 211 .WillOnce(Return(false)); 212 EXPECT_CALL(*storage.get(), GetString(DefaultProfile::kStorageId, 213 DefaultProfile::kStorageCheckPortalList, 214 &manager_props.check_portal_list)) 215 .WillOnce(Return(false)); 216 EXPECT_CALL(*storage.get(), 217 GetString(DefaultProfile::kStorageId, 218 DefaultProfile::kStorageIgnoredDNSSearchPaths, 219 &manager_props.ignored_dns_search_paths)) 220 .WillOnce(Return(false)); 221 EXPECT_CALL(*storage.get(), 222 GetString(DefaultProfile::kStorageId, 223 DefaultProfile::kStorageLinkMonitorTechnologies, 224 _)) 225 .WillOnce(Return(false)); 226 EXPECT_CALL(*storage.get(), 227 GetString(DefaultProfile::kStorageId, 228 DefaultProfile::kStorageNoAutoConnectTechnologies, 229 _)) 230 .WillOnce(Return(false)); 231 EXPECT_CALL(*storage.get(), 232 GetString(DefaultProfile::kStorageId, 233 DefaultProfile::kStorageProhibitedTechnologies, 234 _)) 235 .WillOnce(Return(false)); 236 EXPECT_CALL(*storage.get(), GetString(DefaultProfile::kStorageId, 237 DefaultProfile::kStoragePortalURL, 238 &manager_props.portal_url)) 239 .WillOnce(Return(false)); 240 EXPECT_CALL(*storage.get(), 241 GetString(DefaultProfile::kStorageId, 242 DefaultProfile::kStoragePortalCheckInterval, 243 _)) 244 .WillOnce(Return(false)); 245 unique_ptr<MockDhcpProperties> dhcp_props(new MockDhcpProperties()); 246 EXPECT_CALL(*dhcp_props.get(), Load(_, DefaultProfile::kStorageId)); 247 manager()->dhcp_properties_ = std::move(dhcp_props); 248 profile_->set_storage(storage.release()); 249 250 profile_->LoadManagerProperties(&manager_props, 251 manager()->dhcp_properties_.get()); 252 EXPECT_TRUE(manager_props.arp_gateway); 253 EXPECT_EQ("", manager_props.host_name); 254 EXPECT_FALSE(manager_props.offline_mode); 255 EXPECT_EQ(PortalDetector::kDefaultCheckPortalList, 256 manager_props.check_portal_list); 257 EXPECT_EQ(Resolver::kDefaultIgnoredSearchList, 258 manager_props.ignored_dns_search_paths); 259 EXPECT_EQ(LinkMonitor::kDefaultLinkMonitorTechnologies, 260 manager_props.link_monitor_technologies); 261 EXPECT_EQ("", manager_props.no_auto_connect_technologies); 262 EXPECT_EQ(ConnectivityTrial::kDefaultURL, manager_props.portal_url); 263 EXPECT_EQ(PortalDetector::kDefaultCheckIntervalSeconds, 264 manager_props.portal_check_interval_seconds); 265 EXPECT_EQ("", manager_props.prohibited_technologies); 266 } 267 268 TEST_F(DefaultProfileTest, LoadManagerProperties) { 269 unique_ptr<MockStore> storage(new MockStore()); 270 const string host_name("hostname"); 271 EXPECT_CALL(*storage.get(), GetBool(DefaultProfile::kStorageId, 272 DefaultProfile::kStorageArpGateway, 273 _)) 274 .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true))); 275 EXPECT_CALL(*storage.get(), GetString(DefaultProfile::kStorageId, 276 DefaultProfile::kStorageHostName, 277 _)) 278 .WillOnce(DoAll(SetArgumentPointee<2>(host_name), Return(true))); 279 EXPECT_CALL(*storage.get(), GetBool(DefaultProfile::kStorageId, 280 DefaultProfile::kStorageOfflineMode, 281 _)) 282 .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true))); 283 const string portal_list("technology1,technology2"); 284 EXPECT_CALL(*storage.get(), GetString(DefaultProfile::kStorageId, 285 DefaultProfile::kStorageCheckPortalList, 286 _)) 287 .WillOnce(DoAll(SetArgumentPointee<2>(portal_list), Return(true))); 288 const string ignored_paths("chromium.org,google.com"); 289 EXPECT_CALL(*storage.get(), 290 GetString(DefaultProfile::kStorageId, 291 DefaultProfile::kStorageIgnoredDNSSearchPaths, 292 _)) 293 .WillOnce(DoAll(SetArgumentPointee<2>(ignored_paths), Return(true))); 294 const string link_monitor_technologies("ethernet,wimax"); 295 EXPECT_CALL(*storage.get(), 296 GetString(DefaultProfile::kStorageId, 297 DefaultProfile::kStorageLinkMonitorTechnologies, 298 _)) 299 .WillOnce(DoAll(SetArgumentPointee<2>(link_monitor_technologies), 300 Return(true))); 301 const string no_auto_connect_technologies("wifi,cellular"); 302 EXPECT_CALL(*storage.get(), 303 GetString(DefaultProfile::kStorageId, 304 DefaultProfile::kStorageNoAutoConnectTechnologies, 305 _)) 306 .WillOnce(DoAll(SetArgumentPointee<2>(no_auto_connect_technologies), 307 Return(true))); 308 const string portal_url("http://www.chromium.org"); 309 EXPECT_CALL(*storage.get(), GetString(DefaultProfile::kStorageId, 310 DefaultProfile::kStoragePortalURL, 311 _)) 312 .WillOnce(DoAll(SetArgumentPointee<2>(portal_url), Return(true))); 313 const string portal_check_interval_string("10"); 314 const int portal_check_interval_int = 10; 315 EXPECT_CALL(*storage.get(), 316 GetString(DefaultProfile::kStorageId, 317 DefaultProfile::kStoragePortalCheckInterval, 318 _)) 319 .WillOnce(DoAll(SetArgumentPointee<2>(portal_check_interval_string), 320 Return(true))); 321 const string prohibited_technologies("vpn,wimax"); 322 EXPECT_CALL(*storage.get(), 323 GetString(DefaultProfile::kStorageId, 324 DefaultProfile::kStorageProhibitedTechnologies, 325 _)) 326 .WillOnce(DoAll(SetArgumentPointee<2>(prohibited_technologies), 327 Return(true))); 328 profile_->set_storage(storage.release()); 329 Manager::Properties manager_props; 330 unique_ptr<MockDhcpProperties> dhcp_props(new MockDhcpProperties()); 331 EXPECT_CALL(*dhcp_props.get(), Load(_, DefaultProfile::kStorageId)); 332 manager()->dhcp_properties_ = std::move(dhcp_props); 333 334 profile_->LoadManagerProperties(&manager_props, 335 manager()->dhcp_properties_.get()); 336 EXPECT_FALSE(manager_props.arp_gateway); 337 EXPECT_EQ(host_name, manager_props.host_name); 338 EXPECT_TRUE(manager_props.offline_mode); 339 EXPECT_EQ(portal_list, manager_props.check_portal_list); 340 EXPECT_EQ(ignored_paths, manager_props.ignored_dns_search_paths); 341 EXPECT_EQ(link_monitor_technologies, 342 manager_props.link_monitor_technologies); 343 EXPECT_EQ(no_auto_connect_technologies, 344 manager_props.no_auto_connect_technologies); 345 EXPECT_EQ(portal_url, manager_props.portal_url); 346 EXPECT_EQ(portal_check_interval_int, 347 manager_props.portal_check_interval_seconds); 348 EXPECT_EQ(prohibited_technologies, manager_props.prohibited_technologies); 349 } 350 351 TEST_F(DefaultProfileTest, GetStoragePath) { 352 #if defined(ENABLE_JSON_STORE) 353 EXPECT_EQ(storage_path() + "/default.profile.json", 354 profile_->persistent_profile_path().value()); 355 #else 356 EXPECT_EQ(storage_path() + "/default.profile", 357 profile_->persistent_profile_path().value()); 358 #endif 359 } 360 361 TEST_F(DefaultProfileTest, ConfigureService) { 362 unique_ptr<MockStore> storage(new MockStore()); 363 EXPECT_CALL(*storage, ContainsGroup(_)) 364 .WillRepeatedly(Return(false)); 365 EXPECT_CALL(*storage, Flush()) 366 .WillOnce(Return(true)); 367 368 scoped_refptr<MockService> unknown_service(new MockService( 369 control_interface(), 370 dispatcher(), 371 metrics(), 372 manager())); 373 EXPECT_CALL(*unknown_service, technology()) 374 .WillOnce(Return(Technology::kUnknown)); 375 EXPECT_CALL(*unknown_service, Save(_)) .Times(0); 376 377 scoped_refptr<MockService> ethernet_service(new MockService( 378 control_interface(), 379 dispatcher(), 380 metrics(), 381 manager())); 382 EXPECT_CALL(*ethernet_service, technology()) 383 .WillOnce(Return(Technology::kEthernet)); 384 EXPECT_CALL(*ethernet_service, Save(storage.get())) 385 .WillOnce(Return(true)); 386 387 profile_->set_storage(storage.release()); 388 EXPECT_FALSE(profile_->ConfigureService(unknown_service)); 389 EXPECT_TRUE(profile_->ConfigureService(ethernet_service)); 390 } 391 392 TEST_F(DefaultProfileTest, UpdateDevice) { 393 unique_ptr<MockStore> storage(new MockStore()); 394 EXPECT_CALL(*storage, Flush()).WillOnce(Return(true)); 395 EXPECT_CALL(*device_, Save(storage.get())) 396 .WillOnce(Return(true)) 397 .WillOnce(Return(false)); 398 profile_->set_storage(storage.release()); 399 EXPECT_TRUE(profile_->UpdateDevice(device_)); 400 EXPECT_FALSE(profile_->UpdateDevice(device_)); 401 } 402 403 #if !defined(DISABLE_WIFI) 404 TEST_F(DefaultProfileTest, UpdateWiFiProvider) { 405 MockWiFiProvider wifi_provider; 406 407 { 408 unique_ptr<MockStore> storage(new MockStore()); 409 EXPECT_CALL(*storage, Flush()).Times(0); 410 EXPECT_CALL(wifi_provider, Save(storage.get())).WillOnce(Return(false)); 411 profile_->set_storage(storage.release()); 412 EXPECT_FALSE(profile_->UpdateWiFiProvider(wifi_provider)); 413 } 414 415 { 416 unique_ptr<MockStore> storage(new MockStore()); 417 EXPECT_CALL(*storage, Flush()).WillOnce(Return(false)); 418 EXPECT_CALL(wifi_provider, Save(storage.get())).WillOnce(Return(true)); 419 profile_->set_storage(storage.release()); 420 EXPECT_FALSE(profile_->UpdateWiFiProvider(wifi_provider)); 421 } 422 423 { 424 unique_ptr<MockStore> storage(new MockStore()); 425 EXPECT_CALL(*storage, Flush()).WillOnce(Return(true)); 426 EXPECT_CALL(wifi_provider, Save(storage.get())).WillOnce(Return(true)); 427 profile_->set_storage(storage.release()); 428 EXPECT_TRUE(profile_->UpdateWiFiProvider(wifi_provider)); 429 } 430 } 431 #endif // DISABLE_WIFI 432 433 } // namespace shill 434