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 31using base::IntToString; 32using std::string; 33using std::vector; 34using testing::_; 35using testing::DoAll; 36using testing::Return; 37using testing::SetArgumentPointee; 38using testing::StrictMock; 39using testing::Test; 40 41namespace shill { 42 43namespace { 44 45const char kAddress[] = "10.0.0.1"; 46const char kGateway[] = "10.0.0.254"; 47const int32_t kMtu = 512; 48const char kNameServer0[] = "10.0.1.253"; 49const char kNameServer1[] = "10.0.1.252"; 50const char kNameServers[] = "10.0.1.253,10.0.1.252"; 51const char kPeerAddress[] = "10.0.0.2"; 52const int32_t kPrefixLen = 24; 53 54} // namespace 55 56class 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 177TEST_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 186TEST_F(StaticIpParametersTest, ApplyEmptyParameters) { 187 PopulateIPConfig(); 188 static_params_.ApplyTo(&ipconfig_props_); 189 ExpectPopulatedIPConfig(); 190} 191 192TEST_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 239TEST_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 275TEST_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 320TEST_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