279 lines
11 KiB
C++
279 lines
11 KiB
C++
//
|
|
// Copyright (C) 2014 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/cellular/cellular_bearer.h"
|
|
|
|
#include <ModemManager/ModemManager.h>
|
|
|
|
#include "shill/mock_control.h"
|
|
#include "shill/mock_dbus_properties_proxy.h"
|
|
#include "shill/testing.h"
|
|
|
|
using std::string;
|
|
using std::vector;
|
|
using testing::Return;
|
|
using testing::ReturnNull;
|
|
using testing::_;
|
|
|
|
namespace shill {
|
|
|
|
namespace {
|
|
|
|
const char kBearerDBusPath[] = "/org/freedesktop/ModemManager/Bearer/0";
|
|
const char kBearerDBusService[] = "org.freedesktop.ModemManager";
|
|
const char kDataInterface[] = "/dev/ppp0";
|
|
const char kIPv4Address[] = "10.0.0.1";
|
|
const char kIPv4Gateway[] = "10.0.0.254";
|
|
const int kIPv4SubnetPrefix = 8;
|
|
const char* const kIPv4DNS[] = { "10.0.0.2", "8.8.4.4", "8.8.8.8" };
|
|
const char kIPv6Address[] = "0:0:0:0:0:ffff:a00:1";
|
|
const char kIPv6Gateway[] = "0:0:0:0:0:ffff:a00:fe";
|
|
const int kIPv6SubnetPrefix = 16;
|
|
const char* const kIPv6DNS[] = {
|
|
"0:0:0:0:0:ffff:a00:fe", "0:0:0:0:0:ffff:808:404", "0:0:0:0:0:ffff:808:808"
|
|
};
|
|
|
|
} // namespace
|
|
|
|
class CellularBearerTest : public testing::Test {
|
|
public:
|
|
CellularBearerTest()
|
|
: control_(new MockControl()),
|
|
bearer_(control_.get(), kBearerDBusPath, kBearerDBusService) {}
|
|
|
|
protected:
|
|
void VerifyDefaultProperties() {
|
|
EXPECT_EQ(kBearerDBusPath, bearer_.dbus_path());
|
|
EXPECT_EQ(kBearerDBusService, bearer_.dbus_service());
|
|
EXPECT_FALSE(bearer_.connected());
|
|
EXPECT_EQ("", bearer_.data_interface());
|
|
EXPECT_EQ(IPConfig::kMethodUnknown, bearer_.ipv4_config_method());
|
|
EXPECT_EQ(nullptr, bearer_.ipv4_config_properties());;
|
|
EXPECT_EQ(IPConfig::kMethodUnknown, bearer_.ipv6_config_method());
|
|
EXPECT_EQ(nullptr, bearer_.ipv6_config_properties());;
|
|
}
|
|
|
|
static KeyValueStore ConstructIPv4ConfigProperties(
|
|
MMBearerIpMethod ipconfig_method) {
|
|
KeyValueStore ipconfig_properties;
|
|
ipconfig_properties.SetUint("method", ipconfig_method);
|
|
if (ipconfig_method == MM_BEARER_IP_METHOD_STATIC) {
|
|
ipconfig_properties.SetString("address", kIPv4Address);
|
|
ipconfig_properties.SetString("gateway", kIPv4Gateway);
|
|
ipconfig_properties.SetUint("prefix", kIPv4SubnetPrefix);
|
|
ipconfig_properties.SetString("dns1", kIPv4DNS[0]);
|
|
ipconfig_properties.SetString("dns2", kIPv4DNS[1]);
|
|
ipconfig_properties.SetString("dns3", kIPv4DNS[2]);
|
|
}
|
|
return ipconfig_properties;
|
|
}
|
|
|
|
static KeyValueStore ConstructIPv6ConfigProperties(
|
|
MMBearerIpMethod ipconfig_method) {
|
|
KeyValueStore ipconfig_properties;
|
|
ipconfig_properties.SetUint("method", ipconfig_method);
|
|
if (ipconfig_method == MM_BEARER_IP_METHOD_STATIC) {
|
|
ipconfig_properties.SetString("address", kIPv6Address);
|
|
ipconfig_properties.SetString("gateway", kIPv6Gateway);
|
|
ipconfig_properties.SetUint("prefix", kIPv6SubnetPrefix);
|
|
ipconfig_properties.SetString("dns1", kIPv6DNS[0]);
|
|
ipconfig_properties.SetString("dns2", kIPv6DNS[1]);
|
|
ipconfig_properties.SetString("dns3", kIPv6DNS[2]);
|
|
}
|
|
return ipconfig_properties;
|
|
}
|
|
|
|
static KeyValueStore ConstructBearerProperties(
|
|
bool connected, const string& data_interface,
|
|
MMBearerIpMethod ipv4_config_method,
|
|
MMBearerIpMethod ipv6_config_method) {
|
|
KeyValueStore properties;
|
|
properties.SetBool(MM_BEARER_PROPERTY_CONNECTED, connected);
|
|
properties.SetString(MM_BEARER_PROPERTY_INTERFACE, data_interface);
|
|
|
|
properties.SetKeyValueStore(
|
|
MM_BEARER_PROPERTY_IP4CONFIG,
|
|
ConstructIPv4ConfigProperties(ipv4_config_method));
|
|
properties.SetKeyValueStore(
|
|
MM_BEARER_PROPERTY_IP6CONFIG,
|
|
ConstructIPv6ConfigProperties(ipv6_config_method));
|
|
return properties;
|
|
}
|
|
|
|
void VerifyStaticIPv4ConfigMethodAndProperties() {
|
|
EXPECT_EQ(IPConfig::kMethodStatic, bearer_.ipv4_config_method());
|
|
const IPConfig::Properties* ipv4_config_properties =
|
|
bearer_.ipv4_config_properties();
|
|
ASSERT_NE(nullptr, ipv4_config_properties);;
|
|
EXPECT_EQ(IPAddress::kFamilyIPv4, ipv4_config_properties->address_family);
|
|
EXPECT_EQ(kIPv4Address, ipv4_config_properties->address);
|
|
EXPECT_EQ(kIPv4Gateway, ipv4_config_properties->gateway);
|
|
EXPECT_EQ(kIPv4SubnetPrefix, ipv4_config_properties->subnet_prefix);
|
|
ASSERT_EQ(3, ipv4_config_properties->dns_servers.size());
|
|
EXPECT_EQ(kIPv4DNS[0], ipv4_config_properties->dns_servers[0]);
|
|
EXPECT_EQ(kIPv4DNS[1], ipv4_config_properties->dns_servers[1]);
|
|
EXPECT_EQ(kIPv4DNS[2], ipv4_config_properties->dns_servers[2]);
|
|
}
|
|
|
|
void VerifyStaticIPv6ConfigMethodAndProperties() {
|
|
EXPECT_EQ(IPConfig::kMethodStatic, bearer_.ipv6_config_method());
|
|
const IPConfig::Properties* ipv6_config_properties =
|
|
bearer_.ipv6_config_properties();
|
|
ASSERT_NE(nullptr, ipv6_config_properties);;
|
|
EXPECT_EQ(IPAddress::kFamilyIPv6, ipv6_config_properties->address_family);
|
|
EXPECT_EQ(kIPv6Address, ipv6_config_properties->address);
|
|
EXPECT_EQ(kIPv6Gateway, ipv6_config_properties->gateway);
|
|
EXPECT_EQ(kIPv6SubnetPrefix, ipv6_config_properties->subnet_prefix);
|
|
ASSERT_EQ(3, ipv6_config_properties->dns_servers.size());
|
|
EXPECT_EQ(kIPv6DNS[0], ipv6_config_properties->dns_servers[0]);
|
|
EXPECT_EQ(kIPv6DNS[1], ipv6_config_properties->dns_servers[1]);
|
|
EXPECT_EQ(kIPv6DNS[2], ipv6_config_properties->dns_servers[2]);
|
|
}
|
|
|
|
std::unique_ptr<MockControl> control_;
|
|
CellularBearer bearer_;
|
|
};
|
|
|
|
TEST_F(CellularBearerTest, Constructor) {
|
|
VerifyDefaultProperties();
|
|
}
|
|
|
|
TEST_F(CellularBearerTest, Init) {
|
|
// Ownership of |properties_proxy| is transferred to |bearer_| via
|
|
// |control_|.
|
|
std::unique_ptr<MockDBusPropertiesProxy> properties_proxy(
|
|
new MockDBusPropertiesProxy);
|
|
EXPECT_CALL(*control_.get(),
|
|
CreateDBusPropertiesProxy(kBearerDBusPath, kBearerDBusService))
|
|
.WillOnce(ReturnAndReleasePointee(&properties_proxy));
|
|
EXPECT_CALL(*properties_proxy.get(), set_properties_changed_callback(_))
|
|
.Times(1);
|
|
EXPECT_CALL(*properties_proxy.get(), GetAll(MM_DBUS_INTERFACE_BEARER))
|
|
.WillOnce(Return(ConstructBearerProperties(true, kDataInterface,
|
|
MM_BEARER_IP_METHOD_STATIC,
|
|
MM_BEARER_IP_METHOD_STATIC)));
|
|
bearer_.Init();
|
|
EXPECT_TRUE(bearer_.connected());
|
|
EXPECT_EQ(kDataInterface, bearer_.data_interface());
|
|
VerifyStaticIPv4ConfigMethodAndProperties();
|
|
VerifyStaticIPv6ConfigMethodAndProperties();
|
|
}
|
|
|
|
TEST_F(CellularBearerTest, InitAndCreateDBusPropertiesProxyFails) {
|
|
EXPECT_CALL(*control_.get(),
|
|
CreateDBusPropertiesProxy(kBearerDBusPath, kBearerDBusService))
|
|
.WillOnce(ReturnNull());
|
|
bearer_.Init();
|
|
VerifyDefaultProperties();
|
|
}
|
|
|
|
TEST_F(CellularBearerTest, OnPropertiesChanged) {
|
|
KeyValueStore properties;
|
|
|
|
// If interface is not MM_DBUS_INTERFACE_BEARER, no updates should be done.
|
|
bearer_.OnPropertiesChanged("", properties, vector<string>());
|
|
VerifyDefaultProperties();
|
|
|
|
properties.SetBool(MM_BEARER_PROPERTY_CONNECTED, true);
|
|
bearer_.OnPropertiesChanged("", properties, vector<string>());
|
|
VerifyDefaultProperties();
|
|
|
|
// Update 'interface' property.
|
|
properties.Clear();
|
|
properties.SetString(MM_BEARER_PROPERTY_INTERFACE, kDataInterface);
|
|
bearer_.OnPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties,
|
|
vector<string>());
|
|
EXPECT_EQ(kDataInterface, bearer_.data_interface());
|
|
|
|
// Update 'connected' property.
|
|
properties.Clear();
|
|
properties.SetBool(MM_BEARER_PROPERTY_CONNECTED, true);
|
|
bearer_.OnPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties,
|
|
vector<string>());
|
|
EXPECT_TRUE(bearer_.connected());
|
|
// 'interface' property remains unchanged.
|
|
EXPECT_EQ(kDataInterface, bearer_.data_interface());
|
|
|
|
// Update 'ip4config' property.
|
|
properties.Clear();
|
|
properties.SetKeyValueStore(
|
|
MM_BEARER_PROPERTY_IP4CONFIG,
|
|
ConstructIPv4ConfigProperties(MM_BEARER_IP_METHOD_UNKNOWN));
|
|
bearer_.OnPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties,
|
|
vector<string>());
|
|
EXPECT_EQ(IPConfig::kMethodUnknown, bearer_.ipv4_config_method());
|
|
|
|
properties.Clear();
|
|
properties.SetKeyValueStore(
|
|
MM_BEARER_PROPERTY_IP4CONFIG,
|
|
ConstructIPv4ConfigProperties(MM_BEARER_IP_METHOD_PPP));
|
|
bearer_.OnPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties,
|
|
vector<string>());
|
|
EXPECT_EQ(IPConfig::kMethodPPP, bearer_.ipv4_config_method());
|
|
|
|
properties.Clear();
|
|
properties.SetKeyValueStore(
|
|
MM_BEARER_PROPERTY_IP4CONFIG,
|
|
ConstructIPv4ConfigProperties(MM_BEARER_IP_METHOD_STATIC));
|
|
bearer_.OnPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties,
|
|
vector<string>());
|
|
EXPECT_EQ(IPConfig::kMethodStatic, bearer_.ipv4_config_method());
|
|
VerifyStaticIPv4ConfigMethodAndProperties();
|
|
|
|
properties.Clear();
|
|
properties.SetKeyValueStore(
|
|
MM_BEARER_PROPERTY_IP4CONFIG,
|
|
ConstructIPv4ConfigProperties(MM_BEARER_IP_METHOD_DHCP));
|
|
bearer_.OnPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties,
|
|
vector<string>());
|
|
EXPECT_EQ(IPConfig::kMethodDHCP, bearer_.ipv4_config_method());
|
|
|
|
// Update 'ip6config' property.
|
|
properties.Clear();
|
|
properties.SetKeyValueStore(
|
|
MM_BEARER_PROPERTY_IP6CONFIG,
|
|
ConstructIPv6ConfigProperties(MM_BEARER_IP_METHOD_UNKNOWN));
|
|
bearer_.OnPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties,
|
|
vector<string>());
|
|
EXPECT_EQ(IPConfig::kMethodUnknown, bearer_.ipv6_config_method());
|
|
|
|
properties.Clear();
|
|
properties.SetKeyValueStore(
|
|
MM_BEARER_PROPERTY_IP6CONFIG,
|
|
ConstructIPv6ConfigProperties(MM_BEARER_IP_METHOD_PPP));
|
|
bearer_.OnPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties,
|
|
vector<string>());
|
|
EXPECT_EQ(IPConfig::kMethodPPP, bearer_.ipv6_config_method());
|
|
|
|
properties.Clear();
|
|
properties.SetKeyValueStore(
|
|
MM_BEARER_PROPERTY_IP6CONFIG,
|
|
ConstructIPv6ConfigProperties(MM_BEARER_IP_METHOD_STATIC));
|
|
bearer_.OnPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties,
|
|
vector<string>());
|
|
EXPECT_EQ(IPConfig::kMethodStatic, bearer_.ipv6_config_method());
|
|
VerifyStaticIPv6ConfigMethodAndProperties();
|
|
|
|
properties.Clear();
|
|
properties.SetKeyValueStore(
|
|
MM_BEARER_PROPERTY_IP6CONFIG,
|
|
ConstructIPv6ConfigProperties(MM_BEARER_IP_METHOD_DHCP));
|
|
bearer_.OnPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties,
|
|
vector<string>());
|
|
EXPECT_EQ(IPConfig::kMethodDHCP, bearer_.ipv6_config_method());
|
|
}
|
|
|
|
} // namespace shill
|