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/static_ip_parameters.h"
     18 
     19 #include <base/strings/string_number_conversions.h>
     20 #if defined(__ANDROID__)
     21 #include <dbus/service_constants.h>
     22 #else
     23 #include <chromeos/dbus/service_constants.h>
     24 #endif  // __ANDROID__
     25 #include <gtest/gtest.h>
     26 
     27 #include "shill/ipconfig.h"
     28 #include "shill/mock_store.h"
     29 #include "shill/property_store.h"
     30 
     31 using base::IntToString;
     32 using std::string;
     33 using std::vector;
     34 using testing::_;
     35 using testing::DoAll;
     36 using testing::Return;
     37 using testing::SetArgumentPointee;
     38 using testing::StrictMock;
     39 using testing::Test;
     40 
     41 namespace shill {
     42 
     43 namespace {
     44 
     45 const char kAddress[] = "10.0.0.1";
     46 const char kGateway[] = "10.0.0.254";
     47 const int32_t kMtu = 512;
     48 const char kNameServer0[] = "10.0.1.253";
     49 const char kNameServer1[] = "10.0.1.252";
     50 const char kNameServers[] = "10.0.1.253,10.0.1.252";
     51 const char kPeerAddress[] = "10.0.0.2";
     52 const int32_t kPrefixLen = 24;
     53 
     54 }  // namespace
     55 
     56 class StaticIpParametersTest : public Test {
     57  public:
     58   StaticIpParametersTest() {}
     59 
     60   void ExpectEmptyIPConfig() {
     61     EXPECT_TRUE(ipconfig_props_.address.empty());
     62     EXPECT_TRUE(ipconfig_props_.gateway.empty());
     63     EXPECT_EQ(IPConfig::kUndefinedMTU, ipconfig_props_.mtu);
     64     EXPECT_TRUE(ipconfig_props_.dns_servers.empty());
     65     EXPECT_TRUE(ipconfig_props_.peer_address.empty());
     66     EXPECT_FALSE(ipconfig_props_.subnet_prefix);
     67   }
     68   // Modify an IP address string in some predictable way.  There's no need
     69   // for the output string to be valid from a networking perspective.
     70   string VersionedAddress(const string& address, int version) {
     71     string returned_address = address;
     72     CHECK(returned_address.length());
     73     returned_address[returned_address.length() - 1] += version;
     74     return returned_address;
     75   }
     76   void ExpectPopulatedIPConfigWithVersion(int version) {
     77     EXPECT_EQ(VersionedAddress(kAddress, version), ipconfig_props_.address);
     78     EXPECT_EQ(VersionedAddress(kGateway, version), ipconfig_props_.gateway);
     79     EXPECT_EQ(kMtu + version, ipconfig_props_.mtu);
     80     EXPECT_EQ(2, ipconfig_props_.dns_servers.size());
     81     EXPECT_EQ(VersionedAddress(kNameServer0, version),
     82               ipconfig_props_.dns_servers[0]);
     83     EXPECT_EQ(VersionedAddress(kNameServer1, version),
     84               ipconfig_props_.dns_servers[1]);
     85     EXPECT_EQ(VersionedAddress(kPeerAddress, version),
     86               ipconfig_props_.peer_address);
     87     EXPECT_EQ(kPrefixLen + version, ipconfig_props_.subnet_prefix);
     88   }
     89   void ExpectPopulatedIPConfig() { ExpectPopulatedIPConfigWithVersion(0); }
     90   void ExpectPropertiesWithVersion(PropertyStore* store,
     91                                         const string& property_prefix,
     92                                         int version) {
     93     string string_value;
     94     Error unused_error;
     95     EXPECT_TRUE(store->GetStringProperty(property_prefix + ".Address",
     96                                          &string_value,
     97                                          &unused_error));
     98     EXPECT_EQ(VersionedAddress(kAddress, version), string_value);
     99     EXPECT_TRUE(store->GetStringProperty(property_prefix + ".Gateway",
    100                                          &string_value,
    101                                          &unused_error));
    102     EXPECT_EQ(VersionedAddress(kGateway, version), string_value);
    103     int32_t int_value;
    104     EXPECT_TRUE(store->GetInt32Property(property_prefix + ".Mtu", &int_value,
    105                                         &unused_error));
    106     EXPECT_EQ(kMtu + version, int_value);
    107     EXPECT_TRUE(store->GetStringProperty(property_prefix + ".NameServers",
    108                                          &string_value,
    109                                          &unused_error));
    110     EXPECT_EQ(VersionedAddress(kNameServer0, version) + "," +
    111               VersionedAddress(kNameServer1, version),
    112               string_value);
    113     EXPECT_TRUE(store->GetStringProperty(property_prefix + ".PeerAddress",
    114                                          &string_value,
    115                                          &unused_error));
    116     EXPECT_EQ(VersionedAddress(kPeerAddress, version), string_value);
    117     EXPECT_TRUE(store->GetInt32Property(property_prefix + ".Prefixlen",
    118                                         &int_value,
    119                                         &unused_error));
    120     EXPECT_EQ(kPrefixLen + version, int_value);
    121   }
    122   void ExpectProperties(PropertyStore* store, const string& property_prefix) {
    123     ExpectPropertiesWithVersion(store, property_prefix, 0);
    124   }
    125   void PopulateIPConfig() {
    126     ipconfig_props_.address = kAddress;
    127     ipconfig_props_.gateway = kGateway;
    128     ipconfig_props_.mtu = kMtu;
    129     ipconfig_props_.dns_servers.push_back(kNameServer0);
    130     ipconfig_props_.dns_servers.push_back(kNameServer1);
    131     ipconfig_props_.peer_address = kPeerAddress;
    132     ipconfig_props_.subnet_prefix = kPrefixLen;
    133   }
    134   void SetStaticPropertiesWithVersion(PropertyStore* store, int version) {
    135     Error error;
    136     store->SetStringProperty(
    137         "StaticIP.Address", VersionedAddress(kAddress, version), &error);
    138     store->SetStringProperty(
    139         "StaticIP.Gateway", VersionedAddress(kGateway, version), &error);
    140     store->SetInt32Property(
    141         "StaticIP.Mtu", kMtu + version, &error);
    142     store->SetStringProperty(
    143         "StaticIP.NameServers",
    144         VersionedAddress(kNameServer0, version) + "," +
    145         VersionedAddress(kNameServer1, version),
    146         &error);
    147     store->SetStringProperty(
    148         "StaticIP.PeerAddress",
    149         VersionedAddress(kPeerAddress, version),
    150         &error);
    151     store->SetInt32Property("StaticIP.Prefixlen", kPrefixLen + version, &error);
    152   }
    153   void SetStaticProperties(PropertyStore* store) {
    154     SetStaticPropertiesWithVersion(store, 0);
    155   }
    156   void SetStaticDictPropertiesWithVersion(PropertyStore* store, int version) {
    157     KeyValueStore args;
    158     args.SetString(kAddressProperty, VersionedAddress(kAddress, version));
    159     args.SetString(kGatewayProperty, VersionedAddress(kGateway, version));
    160     args.SetInt(kMtuProperty, kMtu + version);
    161     vector<string> name_servers;
    162     name_servers.push_back(VersionedAddress(kNameServer0, version));
    163     name_servers.push_back(VersionedAddress(kNameServer1, version));
    164     args.SetStrings(kNameServersProperty, name_servers);
    165     args.SetString(kPeerAddressProperty,
    166                    VersionedAddress(kPeerAddress, version));
    167     args.SetInt(kPrefixlenProperty, kPrefixLen + version);
    168     Error error;
    169     store->SetKeyValueStoreProperty(kStaticIPConfigProperty, args, &error);
    170   }
    171 
    172  protected:
    173   StaticIPParameters static_params_;
    174   IPConfig::Properties ipconfig_props_;
    175 };
    176 
    177 TEST_F(StaticIpParametersTest, InitState) {
    178   ExpectEmptyIPConfig();
    179 
    180   // Applying an empty set of parameters on an empty set of properties should
    181   // be a no-op.
    182   static_params_.ApplyTo(&ipconfig_props_);
    183   ExpectEmptyIPConfig();
    184 }
    185 
    186 TEST_F(StaticIpParametersTest, ApplyEmptyParameters) {
    187   PopulateIPConfig();
    188   static_params_.ApplyTo(&ipconfig_props_);
    189   ExpectPopulatedIPConfig();
    190 }
    191 
    192 TEST_F(StaticIpParametersTest, ControlInterface) {
    193   PropertyStore store;
    194   static_params_.PlumbPropertyStore(&store);
    195   SetStaticProperties(&store);
    196   static_params_.ApplyTo(&ipconfig_props_);
    197   ExpectPopulatedIPConfig();
    198 
    199   EXPECT_TRUE(static_params_.ContainsAddress());
    200   Error unused_error;
    201   store.ClearProperty("StaticIP.Address", &unused_error);
    202   EXPECT_FALSE(static_params_.ContainsAddress());
    203   store.ClearProperty("StaticIP.Mtu", &unused_error);
    204   IPConfig::Properties props;
    205   const string kTestAddress("test_address");
    206   props.address = kTestAddress;
    207   const int32_t kTestMtu = 256;
    208   props.mtu = kTestMtu;
    209   static_params_.ApplyTo(&props);
    210   EXPECT_EQ(kTestAddress, props.address);
    211   EXPECT_EQ(kTestMtu, props.mtu);
    212 
    213   {
    214     Error error;
    215     EXPECT_FALSE(store.GetStringProperty("StaticIP.Address", nullptr, &error));
    216     EXPECT_EQ(Error::kNotFound, error.type());
    217   }
    218   string string_value;
    219   EXPECT_TRUE(store.GetStringProperty("StaticIP.Gateway", &string_value,
    220                                       &unused_error));
    221   EXPECT_EQ(kGateway, string_value);
    222   {
    223     Error error;
    224     EXPECT_FALSE(store.GetInt32Property("StaticIP.Mtu", nullptr, &error));
    225     EXPECT_EQ(Error::kNotFound, error.type());
    226   }
    227   EXPECT_TRUE(store.GetStringProperty("StaticIP.NameServers", &string_value,
    228                                       &unused_error));
    229   EXPECT_EQ(kNameServers, string_value);
    230   EXPECT_TRUE(store.GetStringProperty("StaticIP.PeerAddress", &string_value,
    231                                       &unused_error));
    232   EXPECT_EQ(kPeerAddress, string_value);
    233   int32_t int_value;
    234   EXPECT_TRUE(store.GetInt32Property("StaticIP.Prefixlen", &int_value,
    235                                      &unused_error));
    236   EXPECT_EQ(kPrefixLen, int_value);
    237 }
    238 
    239 TEST_F(StaticIpParametersTest, Profile) {
    240   StrictMock<MockStore> store;
    241   const string kID = "storage_id";
    242   EXPECT_CALL(store, GetString(kID, "StaticIP.Address", _))
    243       .WillOnce(DoAll(SetArgumentPointee<2>(string(kAddress)), Return(true)));
    244   EXPECT_CALL(store, GetString(kID, "StaticIP.Gateway", _))
    245       .WillOnce(DoAll(SetArgumentPointee<2>(string(kGateway)), Return(true)));
    246   EXPECT_CALL(store, GetInt(kID, "StaticIP.Mtu", _))
    247       .WillOnce(DoAll(SetArgumentPointee<2>(kMtu), Return(true)));
    248   EXPECT_CALL(store, GetString(kID, "StaticIP.NameServers", _))
    249       .WillOnce(DoAll(SetArgumentPointee<2>(string(kNameServers)),
    250                       Return(true)));
    251   EXPECT_CALL(store, GetString(kID, "StaticIP.PeerAddress", _))
    252       .WillOnce(DoAll(SetArgumentPointee<2>(string(kPeerAddress)),
    253                       Return(true)));
    254   EXPECT_CALL(store, GetInt(kID, "StaticIP.Prefixlen", _))
    255       .WillOnce(DoAll(SetArgumentPointee<2>(kPrefixLen), Return(true)));
    256   static_params_.Load(&store, kID);
    257   static_params_.ApplyTo(&ipconfig_props_);
    258   ExpectPopulatedIPConfig();
    259 
    260   EXPECT_CALL(store, SetString(kID, "StaticIP.Address", kAddress))
    261       .WillOnce(Return(true));
    262   EXPECT_CALL(store, SetString(kID, "StaticIP.Gateway", kGateway))
    263       .WillOnce(Return(true));
    264   EXPECT_CALL(store, SetInt(kID, "StaticIP.Mtu", kMtu))
    265       .WillOnce(Return(true));
    266   EXPECT_CALL(store, SetString(kID, "StaticIP.NameServers", kNameServers))
    267       .WillOnce(Return(true));
    268   EXPECT_CALL(store, SetString(kID, "StaticIP.PeerAddress", kPeerAddress))
    269       .WillOnce(Return(true));
    270   EXPECT_CALL(store, SetInt(kID, "StaticIP.Prefixlen", kPrefixLen))
    271       .WillOnce(Return(true));
    272   static_params_.Save(&store, kID);
    273 }
    274 
    275 TEST_F(StaticIpParametersTest, SavedParameters) {
    276   // Calling RestoreTo() when no parameters are set should not crash or
    277   // add any entries.
    278   static_params_.RestoreTo(&ipconfig_props_);
    279   ExpectEmptyIPConfig();
    280 
    281   PopulateIPConfig();
    282   PropertyStore static_params_props;
    283   static_params_.PlumbPropertyStore(&static_params_props);
    284   SetStaticPropertiesWithVersion(&static_params_props, 1);
    285   static_params_.ApplyTo(&ipconfig_props_);
    286 
    287   // The version 0 properties in |ipconfig_props_| are now in SavedIP.*
    288   // properties, while the version 1 StaticIP parameters are now in
    289   // |ipconfig_props_|.
    290   ExpectPropertiesWithVersion(&static_params_props, "SavedIP", 0);
    291   ExpectPopulatedIPConfigWithVersion(1);
    292 
    293   // Clear all "StaticIP" parameters.
    294   static_params_.args_.Clear();
    295 
    296   // Another ApplyTo() call rotates the version 1 properties in
    297   // |ipconfig_props_| over to SavedIP.*.  Since there are no StaticIP
    298   // parameters, |ipconfig_props_| should remain populated with version 1
    299   // parameters.
    300   static_params_.ApplyTo(&ipconfig_props_);
    301   ExpectPropertiesWithVersion(&static_params_props, "SavedIP", 1);
    302   ExpectPopulatedIPConfigWithVersion(1);
    303 
    304   // Reset |ipconfig_props_| to version 0.
    305   PopulateIPConfig();
    306 
    307   // A RestoreTo() call moves the version 1 "SavedIP" parameters into
    308   // |ipconfig_props_|.
    309   SetStaticPropertiesWithVersion(&static_params_props, 2);
    310   static_params_.RestoreTo(&ipconfig_props_);
    311   ExpectPopulatedIPConfigWithVersion(1);
    312 
    313   // All "SavedIP" parameters should be cleared.
    314   EXPECT_TRUE(static_params_.saved_args_.IsEmpty());
    315 
    316   // Static IP parameters should be unchanged.
    317   ExpectPropertiesWithVersion(&static_params_props, "StaticIP", 2);
    318 }
    319 
    320 TEST_F(StaticIpParametersTest, SavedParametersDict) {
    321   // Calling RestoreTo() when no parameters are set should not crash or
    322   // add any entries.
    323   static_params_.RestoreTo(&ipconfig_props_);
    324   ExpectEmptyIPConfig();
    325 
    326   PopulateIPConfig();
    327   PropertyStore static_params_props;
    328   static_params_.PlumbPropertyStore(&static_params_props);
    329   SetStaticDictPropertiesWithVersion(&static_params_props, 1);
    330   static_params_.ApplyTo(&ipconfig_props_);
    331 
    332   // The version 0 properties in |ipconfig_props_| are now in SavedIP.*
    333   // properties, while the version 1 StaticIP parameters are now in
    334   // |ipconfig_props_|.
    335   ExpectPropertiesWithVersion(&static_params_props, "SavedIP", 0);
    336   ExpectPopulatedIPConfigWithVersion(1);
    337 
    338   // Clear all "StaticIP" parameters.
    339   static_params_.args_.Clear();
    340 
    341   // Another ApplyTo() call rotates the version 1 properties in
    342   // |ipconfig_props_| over to SavedIP.*.  Since there are no StaticIP
    343   // parameters, |ipconfig_props_| should remain populated with version 1
    344   // parameters.
    345   static_params_.ApplyTo(&ipconfig_props_);
    346   ExpectPropertiesWithVersion(&static_params_props, "SavedIP", 1);
    347   ExpectPopulatedIPConfigWithVersion(1);
    348 
    349   // Reset |ipconfig_props_| to version 0.
    350   PopulateIPConfig();
    351 
    352   // A RestoreTo() call moves the version 1 "SavedIP" parameters into
    353   // |ipconfig_props_|.
    354   SetStaticDictPropertiesWithVersion(&static_params_props, 2);
    355   static_params_.RestoreTo(&ipconfig_props_);
    356   ExpectPopulatedIPConfigWithVersion(1);
    357 
    358   // All "SavedIP" parameters should be cleared.
    359   EXPECT_TRUE(static_params_.saved_args_.IsEmpty());
    360 
    361   // Static IP parameters should be unchanged.
    362   ExpectPropertiesWithVersion(&static_params_props, "StaticIP", 2);
    363 }
    364 
    365 }  // namespace shill
    366