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:
StaticIpParametersTest()58 StaticIpParametersTest() {}
59
ExpectEmptyIPConfig()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.
VersionedAddress(const string & address,int version)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 }
ExpectPopulatedIPConfigWithVersion(int version)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 }
ExpectPopulatedIPConfig()89 void ExpectPopulatedIPConfig() { ExpectPopulatedIPConfigWithVersion(0); }
ExpectPropertiesWithVersion(PropertyStore * store,const string & property_prefix,int version)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 }
ExpectProperties(PropertyStore * store,const string & property_prefix)122 void ExpectProperties(PropertyStore* store, const string& property_prefix) {
123 ExpectPropertiesWithVersion(store, property_prefix, 0);
124 }
PopulateIPConfig()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 }
SetStaticPropertiesWithVersion(PropertyStore * store,int version)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 }
SetStaticProperties(PropertyStore * store)153 void SetStaticProperties(PropertyStore* store) {
154 SetStaticPropertiesWithVersion(store, 0);
155 }
SetStaticDictPropertiesWithVersion(PropertyStore * store,int version)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
TEST_F(StaticIpParametersTest,InitState)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
TEST_F(StaticIpParametersTest,ApplyEmptyParameters)186 TEST_F(StaticIpParametersTest, ApplyEmptyParameters) {
187 PopulateIPConfig();
188 static_params_.ApplyTo(&ipconfig_props_);
189 ExpectPopulatedIPConfig();
190 }
191
TEST_F(StaticIpParametersTest,ControlInterface)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
TEST_F(StaticIpParametersTest,Profile)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
TEST_F(StaticIpParametersTest,SavedParameters)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
TEST_F(StaticIpParametersTest,SavedParametersDict)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