365 lines
14 KiB
C++
365 lines
14 KiB
C++
//
|
|
// Copyright (C) 2012 The Android Open Source Project
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
//
|
|
|
|
#include "shill/static_ip_parameters.h"
|
|
|
|
#include <base/strings/string_number_conversions.h>
|
|
#if defined(__ANDROID__)
|
|
#include <dbus/service_constants.h>
|
|
#else
|
|
#include <chromeos/dbus/service_constants.h>
|
|
#endif // __ANDROID__
|
|
#include <gtest/gtest.h>
|
|
|
|
#include "shill/ipconfig.h"
|
|
#include "shill/mock_store.h"
|
|
#include "shill/property_store.h"
|
|
|
|
using base::IntToString;
|
|
using std::string;
|
|
using std::vector;
|
|
using testing::_;
|
|
using testing::DoAll;
|
|
using testing::Return;
|
|
using testing::SetArgumentPointee;
|
|
using testing::StrictMock;
|
|
using testing::Test;
|
|
|
|
namespace shill {
|
|
|
|
namespace {
|
|
|
|
const char kAddress[] = "10.0.0.1";
|
|
const char kGateway[] = "10.0.0.254";
|
|
const int32_t kMtu = 512;
|
|
const char kNameServer0[] = "10.0.1.253";
|
|
const char kNameServer1[] = "10.0.1.252";
|
|
const char kNameServers[] = "10.0.1.253,10.0.1.252";
|
|
const char kPeerAddress[] = "10.0.0.2";
|
|
const int32_t kPrefixLen = 24;
|
|
|
|
} // namespace
|
|
|
|
class StaticIpParametersTest : public Test {
|
|
public:
|
|
StaticIpParametersTest() {}
|
|
|
|
void ExpectEmptyIPConfig() {
|
|
EXPECT_TRUE(ipconfig_props_.address.empty());
|
|
EXPECT_TRUE(ipconfig_props_.gateway.empty());
|
|
EXPECT_EQ(IPConfig::kUndefinedMTU, ipconfig_props_.mtu);
|
|
EXPECT_TRUE(ipconfig_props_.dns_servers.empty());
|
|
EXPECT_TRUE(ipconfig_props_.peer_address.empty());
|
|
EXPECT_FALSE(ipconfig_props_.subnet_prefix);
|
|
}
|
|
// Modify an IP address string in some predictable way. There's no need
|
|
// for the output string to be valid from a networking perspective.
|
|
string VersionedAddress(const string& address, int version) {
|
|
string returned_address = address;
|
|
CHECK(returned_address.length());
|
|
returned_address[returned_address.length() - 1] += version;
|
|
return returned_address;
|
|
}
|
|
void ExpectPopulatedIPConfigWithVersion(int version) {
|
|
EXPECT_EQ(VersionedAddress(kAddress, version), ipconfig_props_.address);
|
|
EXPECT_EQ(VersionedAddress(kGateway, version), ipconfig_props_.gateway);
|
|
EXPECT_EQ(kMtu + version, ipconfig_props_.mtu);
|
|
EXPECT_EQ(2, ipconfig_props_.dns_servers.size());
|
|
EXPECT_EQ(VersionedAddress(kNameServer0, version),
|
|
ipconfig_props_.dns_servers[0]);
|
|
EXPECT_EQ(VersionedAddress(kNameServer1, version),
|
|
ipconfig_props_.dns_servers[1]);
|
|
EXPECT_EQ(VersionedAddress(kPeerAddress, version),
|
|
ipconfig_props_.peer_address);
|
|
EXPECT_EQ(kPrefixLen + version, ipconfig_props_.subnet_prefix);
|
|
}
|
|
void ExpectPopulatedIPConfig() { ExpectPopulatedIPConfigWithVersion(0); }
|
|
void ExpectPropertiesWithVersion(PropertyStore* store,
|
|
const string& property_prefix,
|
|
int version) {
|
|
string string_value;
|
|
Error unused_error;
|
|
EXPECT_TRUE(store->GetStringProperty(property_prefix + ".Address",
|
|
&string_value,
|
|
&unused_error));
|
|
EXPECT_EQ(VersionedAddress(kAddress, version), string_value);
|
|
EXPECT_TRUE(store->GetStringProperty(property_prefix + ".Gateway",
|
|
&string_value,
|
|
&unused_error));
|
|
EXPECT_EQ(VersionedAddress(kGateway, version), string_value);
|
|
int32_t int_value;
|
|
EXPECT_TRUE(store->GetInt32Property(property_prefix + ".Mtu", &int_value,
|
|
&unused_error));
|
|
EXPECT_EQ(kMtu + version, int_value);
|
|
EXPECT_TRUE(store->GetStringProperty(property_prefix + ".NameServers",
|
|
&string_value,
|
|
&unused_error));
|
|
EXPECT_EQ(VersionedAddress(kNameServer0, version) + "," +
|
|
VersionedAddress(kNameServer1, version),
|
|
string_value);
|
|
EXPECT_TRUE(store->GetStringProperty(property_prefix + ".PeerAddress",
|
|
&string_value,
|
|
&unused_error));
|
|
EXPECT_EQ(VersionedAddress(kPeerAddress, version), string_value);
|
|
EXPECT_TRUE(store->GetInt32Property(property_prefix + ".Prefixlen",
|
|
&int_value,
|
|
&unused_error));
|
|
EXPECT_EQ(kPrefixLen + version, int_value);
|
|
}
|
|
void ExpectProperties(PropertyStore* store, const string& property_prefix) {
|
|
ExpectPropertiesWithVersion(store, property_prefix, 0);
|
|
}
|
|
void PopulateIPConfig() {
|
|
ipconfig_props_.address = kAddress;
|
|
ipconfig_props_.gateway = kGateway;
|
|
ipconfig_props_.mtu = kMtu;
|
|
ipconfig_props_.dns_servers.push_back(kNameServer0);
|
|
ipconfig_props_.dns_servers.push_back(kNameServer1);
|
|
ipconfig_props_.peer_address = kPeerAddress;
|
|
ipconfig_props_.subnet_prefix = kPrefixLen;
|
|
}
|
|
void SetStaticPropertiesWithVersion(PropertyStore* store, int version) {
|
|
Error error;
|
|
store->SetStringProperty(
|
|
"StaticIP.Address", VersionedAddress(kAddress, version), &error);
|
|
store->SetStringProperty(
|
|
"StaticIP.Gateway", VersionedAddress(kGateway, version), &error);
|
|
store->SetInt32Property(
|
|
"StaticIP.Mtu", kMtu + version, &error);
|
|
store->SetStringProperty(
|
|
"StaticIP.NameServers",
|
|
VersionedAddress(kNameServer0, version) + "," +
|
|
VersionedAddress(kNameServer1, version),
|
|
&error);
|
|
store->SetStringProperty(
|
|
"StaticIP.PeerAddress",
|
|
VersionedAddress(kPeerAddress, version),
|
|
&error);
|
|
store->SetInt32Property("StaticIP.Prefixlen", kPrefixLen + version, &error);
|
|
}
|
|
void SetStaticProperties(PropertyStore* store) {
|
|
SetStaticPropertiesWithVersion(store, 0);
|
|
}
|
|
void SetStaticDictPropertiesWithVersion(PropertyStore* store, int version) {
|
|
KeyValueStore args;
|
|
args.SetString(kAddressProperty, VersionedAddress(kAddress, version));
|
|
args.SetString(kGatewayProperty, VersionedAddress(kGateway, version));
|
|
args.SetInt(kMtuProperty, kMtu + version);
|
|
vector<string> name_servers;
|
|
name_servers.push_back(VersionedAddress(kNameServer0, version));
|
|
name_servers.push_back(VersionedAddress(kNameServer1, version));
|
|
args.SetStrings(kNameServersProperty, name_servers);
|
|
args.SetString(kPeerAddressProperty,
|
|
VersionedAddress(kPeerAddress, version));
|
|
args.SetInt(kPrefixlenProperty, kPrefixLen + version);
|
|
Error error;
|
|
store->SetKeyValueStoreProperty(kStaticIPConfigProperty, args, &error);
|
|
}
|
|
|
|
protected:
|
|
StaticIPParameters static_params_;
|
|
IPConfig::Properties ipconfig_props_;
|
|
};
|
|
|
|
TEST_F(StaticIpParametersTest, InitState) {
|
|
ExpectEmptyIPConfig();
|
|
|
|
// Applying an empty set of parameters on an empty set of properties should
|
|
// be a no-op.
|
|
static_params_.ApplyTo(&ipconfig_props_);
|
|
ExpectEmptyIPConfig();
|
|
}
|
|
|
|
TEST_F(StaticIpParametersTest, ApplyEmptyParameters) {
|
|
PopulateIPConfig();
|
|
static_params_.ApplyTo(&ipconfig_props_);
|
|
ExpectPopulatedIPConfig();
|
|
}
|
|
|
|
TEST_F(StaticIpParametersTest, ControlInterface) {
|
|
PropertyStore store;
|
|
static_params_.PlumbPropertyStore(&store);
|
|
SetStaticProperties(&store);
|
|
static_params_.ApplyTo(&ipconfig_props_);
|
|
ExpectPopulatedIPConfig();
|
|
|
|
EXPECT_TRUE(static_params_.ContainsAddress());
|
|
Error unused_error;
|
|
store.ClearProperty("StaticIP.Address", &unused_error);
|
|
EXPECT_FALSE(static_params_.ContainsAddress());
|
|
store.ClearProperty("StaticIP.Mtu", &unused_error);
|
|
IPConfig::Properties props;
|
|
const string kTestAddress("test_address");
|
|
props.address = kTestAddress;
|
|
const int32_t kTestMtu = 256;
|
|
props.mtu = kTestMtu;
|
|
static_params_.ApplyTo(&props);
|
|
EXPECT_EQ(kTestAddress, props.address);
|
|
EXPECT_EQ(kTestMtu, props.mtu);
|
|
|
|
{
|
|
Error error;
|
|
EXPECT_FALSE(store.GetStringProperty("StaticIP.Address", nullptr, &error));
|
|
EXPECT_EQ(Error::kNotFound, error.type());
|
|
}
|
|
string string_value;
|
|
EXPECT_TRUE(store.GetStringProperty("StaticIP.Gateway", &string_value,
|
|
&unused_error));
|
|
EXPECT_EQ(kGateway, string_value);
|
|
{
|
|
Error error;
|
|
EXPECT_FALSE(store.GetInt32Property("StaticIP.Mtu", nullptr, &error));
|
|
EXPECT_EQ(Error::kNotFound, error.type());
|
|
}
|
|
EXPECT_TRUE(store.GetStringProperty("StaticIP.NameServers", &string_value,
|
|
&unused_error));
|
|
EXPECT_EQ(kNameServers, string_value);
|
|
EXPECT_TRUE(store.GetStringProperty("StaticIP.PeerAddress", &string_value,
|
|
&unused_error));
|
|
EXPECT_EQ(kPeerAddress, string_value);
|
|
int32_t int_value;
|
|
EXPECT_TRUE(store.GetInt32Property("StaticIP.Prefixlen", &int_value,
|
|
&unused_error));
|
|
EXPECT_EQ(kPrefixLen, int_value);
|
|
}
|
|
|
|
TEST_F(StaticIpParametersTest, Profile) {
|
|
StrictMock<MockStore> store;
|
|
const string kID = "storage_id";
|
|
EXPECT_CALL(store, GetString(kID, "StaticIP.Address", _))
|
|
.WillOnce(DoAll(SetArgumentPointee<2>(string(kAddress)), Return(true)));
|
|
EXPECT_CALL(store, GetString(kID, "StaticIP.Gateway", _))
|
|
.WillOnce(DoAll(SetArgumentPointee<2>(string(kGateway)), Return(true)));
|
|
EXPECT_CALL(store, GetInt(kID, "StaticIP.Mtu", _))
|
|
.WillOnce(DoAll(SetArgumentPointee<2>(kMtu), Return(true)));
|
|
EXPECT_CALL(store, GetString(kID, "StaticIP.NameServers", _))
|
|
.WillOnce(DoAll(SetArgumentPointee<2>(string(kNameServers)),
|
|
Return(true)));
|
|
EXPECT_CALL(store, GetString(kID, "StaticIP.PeerAddress", _))
|
|
.WillOnce(DoAll(SetArgumentPointee<2>(string(kPeerAddress)),
|
|
Return(true)));
|
|
EXPECT_CALL(store, GetInt(kID, "StaticIP.Prefixlen", _))
|
|
.WillOnce(DoAll(SetArgumentPointee<2>(kPrefixLen), Return(true)));
|
|
static_params_.Load(&store, kID);
|
|
static_params_.ApplyTo(&ipconfig_props_);
|
|
ExpectPopulatedIPConfig();
|
|
|
|
EXPECT_CALL(store, SetString(kID, "StaticIP.Address", kAddress))
|
|
.WillOnce(Return(true));
|
|
EXPECT_CALL(store, SetString(kID, "StaticIP.Gateway", kGateway))
|
|
.WillOnce(Return(true));
|
|
EXPECT_CALL(store, SetInt(kID, "StaticIP.Mtu", kMtu))
|
|
.WillOnce(Return(true));
|
|
EXPECT_CALL(store, SetString(kID, "StaticIP.NameServers", kNameServers))
|
|
.WillOnce(Return(true));
|
|
EXPECT_CALL(store, SetString(kID, "StaticIP.PeerAddress", kPeerAddress))
|
|
.WillOnce(Return(true));
|
|
EXPECT_CALL(store, SetInt(kID, "StaticIP.Prefixlen", kPrefixLen))
|
|
.WillOnce(Return(true));
|
|
static_params_.Save(&store, kID);
|
|
}
|
|
|
|
TEST_F(StaticIpParametersTest, SavedParameters) {
|
|
// Calling RestoreTo() when no parameters are set should not crash or
|
|
// add any entries.
|
|
static_params_.RestoreTo(&ipconfig_props_);
|
|
ExpectEmptyIPConfig();
|
|
|
|
PopulateIPConfig();
|
|
PropertyStore static_params_props;
|
|
static_params_.PlumbPropertyStore(&static_params_props);
|
|
SetStaticPropertiesWithVersion(&static_params_props, 1);
|
|
static_params_.ApplyTo(&ipconfig_props_);
|
|
|
|
// The version 0 properties in |ipconfig_props_| are now in SavedIP.*
|
|
// properties, while the version 1 StaticIP parameters are now in
|
|
// |ipconfig_props_|.
|
|
ExpectPropertiesWithVersion(&static_params_props, "SavedIP", 0);
|
|
ExpectPopulatedIPConfigWithVersion(1);
|
|
|
|
// Clear all "StaticIP" parameters.
|
|
static_params_.args_.Clear();
|
|
|
|
// Another ApplyTo() call rotates the version 1 properties in
|
|
// |ipconfig_props_| over to SavedIP.*. Since there are no StaticIP
|
|
// parameters, |ipconfig_props_| should remain populated with version 1
|
|
// parameters.
|
|
static_params_.ApplyTo(&ipconfig_props_);
|
|
ExpectPropertiesWithVersion(&static_params_props, "SavedIP", 1);
|
|
ExpectPopulatedIPConfigWithVersion(1);
|
|
|
|
// Reset |ipconfig_props_| to version 0.
|
|
PopulateIPConfig();
|
|
|
|
// A RestoreTo() call moves the version 1 "SavedIP" parameters into
|
|
// |ipconfig_props_|.
|
|
SetStaticPropertiesWithVersion(&static_params_props, 2);
|
|
static_params_.RestoreTo(&ipconfig_props_);
|
|
ExpectPopulatedIPConfigWithVersion(1);
|
|
|
|
// All "SavedIP" parameters should be cleared.
|
|
EXPECT_TRUE(static_params_.saved_args_.IsEmpty());
|
|
|
|
// Static IP parameters should be unchanged.
|
|
ExpectPropertiesWithVersion(&static_params_props, "StaticIP", 2);
|
|
}
|
|
|
|
TEST_F(StaticIpParametersTest, SavedParametersDict) {
|
|
// Calling RestoreTo() when no parameters are set should not crash or
|
|
// add any entries.
|
|
static_params_.RestoreTo(&ipconfig_props_);
|
|
ExpectEmptyIPConfig();
|
|
|
|
PopulateIPConfig();
|
|
PropertyStore static_params_props;
|
|
static_params_.PlumbPropertyStore(&static_params_props);
|
|
SetStaticDictPropertiesWithVersion(&static_params_props, 1);
|
|
static_params_.ApplyTo(&ipconfig_props_);
|
|
|
|
// The version 0 properties in |ipconfig_props_| are now in SavedIP.*
|
|
// properties, while the version 1 StaticIP parameters are now in
|
|
// |ipconfig_props_|.
|
|
ExpectPropertiesWithVersion(&static_params_props, "SavedIP", 0);
|
|
ExpectPopulatedIPConfigWithVersion(1);
|
|
|
|
// Clear all "StaticIP" parameters.
|
|
static_params_.args_.Clear();
|
|
|
|
// Another ApplyTo() call rotates the version 1 properties in
|
|
// |ipconfig_props_| over to SavedIP.*. Since there are no StaticIP
|
|
// parameters, |ipconfig_props_| should remain populated with version 1
|
|
// parameters.
|
|
static_params_.ApplyTo(&ipconfig_props_);
|
|
ExpectPropertiesWithVersion(&static_params_props, "SavedIP", 1);
|
|
ExpectPopulatedIPConfigWithVersion(1);
|
|
|
|
// Reset |ipconfig_props_| to version 0.
|
|
PopulateIPConfig();
|
|
|
|
// A RestoreTo() call moves the version 1 "SavedIP" parameters into
|
|
// |ipconfig_props_|.
|
|
SetStaticDictPropertiesWithVersion(&static_params_props, 2);
|
|
static_params_.RestoreTo(&ipconfig_props_);
|
|
ExpectPopulatedIPConfigWithVersion(1);
|
|
|
|
// All "SavedIP" parameters should be cleared.
|
|
EXPECT_TRUE(static_params_.saved_args_.IsEmpty());
|
|
|
|
// Static IP parameters should be unchanged.
|
|
ExpectPropertiesWithVersion(&static_params_props, "StaticIP", 2);
|
|
}
|
|
|
|
} // namespace shill
|