Home | History | Annotate | Download | only in shill
      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