Ben Chan | 26692bd | 2014-02-03 16:34:55 -0800 | [diff] [blame] | 1 | // Copyright (c) 2014 The Chromium OS Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
Ben Chan | c54afe5 | 2014-11-05 10:28:08 -0800 | [diff] [blame] | 5 | #include "shill/cellular/cellular_bearer.h" |
Ben Chan | 26692bd | 2014-02-03 16:34:55 -0800 | [diff] [blame] | 6 | |
| 7 | #include <ModemManager/ModemManager.h> |
| 8 | |
| 9 | #include "shill/mock_dbus_properties_proxy.h" |
| 10 | #include "shill/mock_proxy_factory.h" |
| 11 | #include "shill/testing.h" |
| 12 | |
| 13 | using std::string; |
| 14 | using std::vector; |
| 15 | using testing::Return; |
| 16 | using testing::ReturnNull; |
| 17 | using testing::_; |
| 18 | |
| 19 | namespace shill { |
| 20 | |
| 21 | namespace { |
| 22 | |
| 23 | const char kBearerDBusPath[] = "/org/freedesktop/ModemManager/Bearer/0"; |
| 24 | const char kBearerDBusService[] = "org.freedesktop.ModemManager"; |
| 25 | const char kDataInterface[] = "/dev/ppp0"; |
| 26 | const char kIPv4Address[] = "10.0.0.1"; |
| 27 | const char kIPv4Gateway[] = "10.0.0.254"; |
| 28 | const int kIPv4SubnetPrefix = 8; |
Paul Stewart | 2f6c789 | 2015-06-16 13:13:10 -0700 | [diff] [blame^] | 29 | const char* const kIPv4DNS[] = { "10.0.0.2", "8.8.4.4", "8.8.8.8" }; |
Ben Chan | 26692bd | 2014-02-03 16:34:55 -0800 | [diff] [blame] | 30 | const char kIPv6Address[] = "0:0:0:0:0:ffff:a00:1"; |
| 31 | const char kIPv6Gateway[] = "0:0:0:0:0:ffff:a00:fe"; |
| 32 | const int kIPv6SubnetPrefix = 16; |
Paul Stewart | 2f6c789 | 2015-06-16 13:13:10 -0700 | [diff] [blame^] | 33 | const char* const kIPv6DNS[] = { |
Ben Chan | 26692bd | 2014-02-03 16:34:55 -0800 | [diff] [blame] | 34 | "0:0:0:0:0:ffff:a00:fe", "0:0:0:0:0:ffff:808:404", "0:0:0:0:0:ffff:808:808" |
| 35 | }; |
| 36 | |
| 37 | } // namespace |
| 38 | |
| 39 | class CellularBearerTest : public testing::Test { |
| 40 | public: |
| 41 | CellularBearerTest() |
| 42 | : proxy_factory_(new MockProxyFactory()), |
| 43 | bearer_(proxy_factory_.get(), kBearerDBusPath, kBearerDBusService) {} |
| 44 | |
| 45 | protected: |
| 46 | void VerifyDefaultProperties() { |
| 47 | EXPECT_EQ(kBearerDBusPath, bearer_.dbus_path()); |
| 48 | EXPECT_EQ(kBearerDBusService, bearer_.dbus_service()); |
| 49 | EXPECT_FALSE(bearer_.connected()); |
| 50 | EXPECT_EQ("", bearer_.data_interface()); |
| 51 | EXPECT_EQ(IPConfig::kMethodUnknown, bearer_.ipv4_config_method()); |
Ben Chan | ea18c6c | 2014-09-30 13:08:26 -0700 | [diff] [blame] | 52 | EXPECT_EQ(nullptr, bearer_.ipv4_config_properties());; |
Ben Chan | 26692bd | 2014-02-03 16:34:55 -0800 | [diff] [blame] | 53 | EXPECT_EQ(IPConfig::kMethodUnknown, bearer_.ipv6_config_method()); |
Ben Chan | ea18c6c | 2014-09-30 13:08:26 -0700 | [diff] [blame] | 54 | EXPECT_EQ(nullptr, bearer_.ipv6_config_properties());; |
Ben Chan | 26692bd | 2014-02-03 16:34:55 -0800 | [diff] [blame] | 55 | } |
| 56 | |
| 57 | static DBusPropertiesMap ConstructIPv4ConfigProperties( |
| 58 | MMBearerIpMethod ipconfig_method) { |
| 59 | DBusPropertiesMap ipconfig_properties; |
| 60 | ipconfig_properties["method"].writer().append_uint32(ipconfig_method); |
| 61 | if (ipconfig_method == MM_BEARER_IP_METHOD_STATIC) { |
| 62 | ipconfig_properties["address"].writer().append_string(kIPv4Address); |
| 63 | ipconfig_properties["gateway"].writer().append_string(kIPv4Gateway); |
| 64 | ipconfig_properties["prefix"].writer().append_uint32(kIPv4SubnetPrefix); |
| 65 | ipconfig_properties["dns1"].writer().append_string(kIPv4DNS[0]); |
| 66 | ipconfig_properties["dns2"].writer().append_string(kIPv4DNS[1]); |
| 67 | ipconfig_properties["dns3"].writer().append_string(kIPv4DNS[2]); |
| 68 | } |
| 69 | return ipconfig_properties; |
| 70 | } |
| 71 | |
| 72 | static DBusPropertiesMap ConstructIPv6ConfigProperties( |
| 73 | MMBearerIpMethod ipconfig_method) { |
| 74 | DBusPropertiesMap ipconfig_properties; |
| 75 | ipconfig_properties["method"].writer().append_uint32(ipconfig_method); |
| 76 | if (ipconfig_method == MM_BEARER_IP_METHOD_STATIC) { |
| 77 | ipconfig_properties["address"].writer().append_string(kIPv6Address); |
| 78 | ipconfig_properties["gateway"].writer().append_string(kIPv6Gateway); |
| 79 | ipconfig_properties["prefix"].writer().append_uint32(kIPv6SubnetPrefix); |
| 80 | ipconfig_properties["dns1"].writer().append_string(kIPv6DNS[0]); |
| 81 | ipconfig_properties["dns2"].writer().append_string(kIPv6DNS[1]); |
| 82 | ipconfig_properties["dns3"].writer().append_string(kIPv6DNS[2]); |
| 83 | } |
| 84 | return ipconfig_properties; |
| 85 | } |
| 86 | |
| 87 | static DBusPropertiesMap ConstructBearerProperties( |
Paul Stewart | 2f6c789 | 2015-06-16 13:13:10 -0700 | [diff] [blame^] | 88 | bool connected, const string& data_interface, |
Ben Chan | 26692bd | 2014-02-03 16:34:55 -0800 | [diff] [blame] | 89 | MMBearerIpMethod ipv4_config_method, |
| 90 | MMBearerIpMethod ipv6_config_method) { |
| 91 | DBusPropertiesMap properties; |
| 92 | properties[MM_BEARER_PROPERTY_CONNECTED].writer().append_bool(connected); |
| 93 | properties[MM_BEARER_PROPERTY_INTERFACE].writer().append_string( |
| 94 | data_interface.c_str()); |
| 95 | |
| 96 | DBus::MessageIter writer; |
| 97 | writer = properties[MM_BEARER_PROPERTY_IP4CONFIG].writer(); |
| 98 | writer << ConstructIPv4ConfigProperties(ipv4_config_method); |
| 99 | writer = properties[MM_BEARER_PROPERTY_IP6CONFIG].writer(); |
| 100 | writer << ConstructIPv6ConfigProperties(ipv6_config_method); |
| 101 | return properties; |
| 102 | } |
| 103 | |
| 104 | void VerifyStaticIPv4ConfigMethodAndProperties() { |
| 105 | EXPECT_EQ(IPConfig::kMethodStatic, bearer_.ipv4_config_method()); |
Paul Stewart | 2f6c789 | 2015-06-16 13:13:10 -0700 | [diff] [blame^] | 106 | const IPConfig::Properties* ipv4_config_properties = |
Ben Chan | 26692bd | 2014-02-03 16:34:55 -0800 | [diff] [blame] | 107 | bearer_.ipv4_config_properties(); |
Ben Chan | ea18c6c | 2014-09-30 13:08:26 -0700 | [diff] [blame] | 108 | ASSERT_NE(nullptr, ipv4_config_properties);; |
Ben Chan | 26692bd | 2014-02-03 16:34:55 -0800 | [diff] [blame] | 109 | EXPECT_EQ(IPAddress::kFamilyIPv4, ipv4_config_properties->address_family); |
| 110 | EXPECT_EQ(kIPv4Address, ipv4_config_properties->address); |
| 111 | EXPECT_EQ(kIPv4Gateway, ipv4_config_properties->gateway); |
| 112 | EXPECT_EQ(kIPv4SubnetPrefix, ipv4_config_properties->subnet_prefix); |
| 113 | ASSERT_EQ(3, ipv4_config_properties->dns_servers.size()); |
| 114 | EXPECT_EQ(kIPv4DNS[0], ipv4_config_properties->dns_servers[0]); |
| 115 | EXPECT_EQ(kIPv4DNS[1], ipv4_config_properties->dns_servers[1]); |
| 116 | EXPECT_EQ(kIPv4DNS[2], ipv4_config_properties->dns_servers[2]); |
| 117 | } |
| 118 | |
| 119 | void VerifyStaticIPv6ConfigMethodAndProperties() { |
| 120 | EXPECT_EQ(IPConfig::kMethodStatic, bearer_.ipv6_config_method()); |
Paul Stewart | 2f6c789 | 2015-06-16 13:13:10 -0700 | [diff] [blame^] | 121 | const IPConfig::Properties* ipv6_config_properties = |
Ben Chan | 26692bd | 2014-02-03 16:34:55 -0800 | [diff] [blame] | 122 | bearer_.ipv6_config_properties(); |
Ben Chan | ea18c6c | 2014-09-30 13:08:26 -0700 | [diff] [blame] | 123 | ASSERT_NE(nullptr, ipv6_config_properties);; |
Ben Chan | 26692bd | 2014-02-03 16:34:55 -0800 | [diff] [blame] | 124 | EXPECT_EQ(IPAddress::kFamilyIPv6, ipv6_config_properties->address_family); |
| 125 | EXPECT_EQ(kIPv6Address, ipv6_config_properties->address); |
| 126 | EXPECT_EQ(kIPv6Gateway, ipv6_config_properties->gateway); |
| 127 | EXPECT_EQ(kIPv6SubnetPrefix, ipv6_config_properties->subnet_prefix); |
| 128 | ASSERT_EQ(3, ipv6_config_properties->dns_servers.size()); |
| 129 | EXPECT_EQ(kIPv6DNS[0], ipv6_config_properties->dns_servers[0]); |
| 130 | EXPECT_EQ(kIPv6DNS[1], ipv6_config_properties->dns_servers[1]); |
| 131 | EXPECT_EQ(kIPv6DNS[2], ipv6_config_properties->dns_servers[2]); |
| 132 | } |
| 133 | |
Ben Chan | c20ed13 | 2014-10-16 12:25:03 -0700 | [diff] [blame] | 134 | std::unique_ptr<MockProxyFactory> proxy_factory_; |
Ben Chan | 26692bd | 2014-02-03 16:34:55 -0800 | [diff] [blame] | 135 | CellularBearer bearer_; |
| 136 | }; |
| 137 | |
| 138 | TEST_F(CellularBearerTest, Constructor) { |
| 139 | VerifyDefaultProperties(); |
| 140 | } |
| 141 | |
| 142 | TEST_F(CellularBearerTest, Init) { |
| 143 | // Ownership of |properties_proxy| is transferred to |bearer_| via |
| 144 | // |proxy_factory_|. |
Ben Chan | c20ed13 | 2014-10-16 12:25:03 -0700 | [diff] [blame] | 145 | std::unique_ptr<MockDBusPropertiesProxy> properties_proxy( |
Ben Chan | 26692bd | 2014-02-03 16:34:55 -0800 | [diff] [blame] | 146 | new MockDBusPropertiesProxy); |
| 147 | EXPECT_CALL(*proxy_factory_.get(), |
| 148 | CreateDBusPropertiesProxy(kBearerDBusPath, kBearerDBusService)) |
| 149 | .WillOnce(ReturnAndReleasePointee(&properties_proxy)); |
| 150 | EXPECT_CALL(*properties_proxy.get(), set_properties_changed_callback(_)) |
| 151 | .Times(1); |
| 152 | EXPECT_CALL(*properties_proxy.get(), GetAll(MM_DBUS_INTERFACE_BEARER)) |
| 153 | .WillOnce(Return(ConstructBearerProperties(true, kDataInterface, |
| 154 | MM_BEARER_IP_METHOD_STATIC, |
| 155 | MM_BEARER_IP_METHOD_STATIC))); |
| 156 | bearer_.Init(); |
| 157 | EXPECT_TRUE(bearer_.connected()); |
| 158 | EXPECT_EQ(kDataInterface, bearer_.data_interface()); |
| 159 | VerifyStaticIPv4ConfigMethodAndProperties(); |
| 160 | VerifyStaticIPv6ConfigMethodAndProperties(); |
| 161 | } |
| 162 | |
| 163 | TEST_F(CellularBearerTest, InitAndCreateDBusPropertiesProxyFails) { |
| 164 | EXPECT_CALL(*proxy_factory_.get(), |
| 165 | CreateDBusPropertiesProxy(kBearerDBusPath, kBearerDBusService)) |
| 166 | .WillOnce(ReturnNull()); |
| 167 | bearer_.Init(); |
| 168 | VerifyDefaultProperties(); |
| 169 | } |
| 170 | |
| 171 | TEST_F(CellularBearerTest, OnDBusPropertiesChanged) { |
| 172 | DBusPropertiesMap properties; |
| 173 | |
| 174 | // If interface is not MM_DBUS_INTERFACE_BEARER, no updates should be done. |
| 175 | bearer_.OnDBusPropertiesChanged("", properties, vector<string>()); |
| 176 | VerifyDefaultProperties(); |
| 177 | |
| 178 | properties[MM_BEARER_PROPERTY_CONNECTED].writer().append_bool(true); |
| 179 | bearer_.OnDBusPropertiesChanged("", properties, vector<string>()); |
| 180 | VerifyDefaultProperties(); |
| 181 | |
| 182 | // Update 'interface' property. |
| 183 | properties.clear(); |
| 184 | properties[MM_BEARER_PROPERTY_INTERFACE].writer().append_string( |
| 185 | kDataInterface); |
| 186 | bearer_.OnDBusPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties, |
| 187 | vector<string>()); |
| 188 | EXPECT_EQ(kDataInterface, bearer_.data_interface()); |
| 189 | |
| 190 | // Update 'connected' property. |
| 191 | properties.clear(); |
| 192 | properties[MM_BEARER_PROPERTY_CONNECTED].writer().append_bool(true); |
| 193 | bearer_.OnDBusPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties, |
| 194 | vector<string>()); |
| 195 | EXPECT_TRUE(bearer_.connected()); |
| 196 | // 'interface' property remains unchanged. |
| 197 | EXPECT_EQ(kDataInterface, bearer_.data_interface()); |
| 198 | |
| 199 | DBus::MessageIter writer; |
| 200 | |
| 201 | // Update 'ip4config' property. |
| 202 | properties.clear(); |
| 203 | writer = properties[MM_BEARER_PROPERTY_IP4CONFIG].writer(); |
| 204 | writer << ConstructIPv4ConfigProperties(MM_BEARER_IP_METHOD_UNKNOWN); |
| 205 | bearer_.OnDBusPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties, |
| 206 | vector<string>()); |
| 207 | EXPECT_EQ(IPConfig::kMethodUnknown, bearer_.ipv4_config_method()); |
| 208 | |
| 209 | properties.clear(); |
| 210 | writer = properties[MM_BEARER_PROPERTY_IP4CONFIG].writer(); |
| 211 | writer << ConstructIPv4ConfigProperties(MM_BEARER_IP_METHOD_PPP); |
| 212 | bearer_.OnDBusPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties, |
| 213 | vector<string>()); |
| 214 | EXPECT_EQ(IPConfig::kMethodPPP, bearer_.ipv4_config_method()); |
| 215 | |
| 216 | properties.clear(); |
| 217 | writer = properties[MM_BEARER_PROPERTY_IP4CONFIG].writer(); |
| 218 | writer << ConstructIPv4ConfigProperties(MM_BEARER_IP_METHOD_STATIC); |
| 219 | bearer_.OnDBusPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties, |
| 220 | vector<string>()); |
| 221 | EXPECT_EQ(IPConfig::kMethodStatic, bearer_.ipv4_config_method()); |
| 222 | VerifyStaticIPv4ConfigMethodAndProperties(); |
| 223 | |
| 224 | properties.clear(); |
| 225 | writer = properties[MM_BEARER_PROPERTY_IP4CONFIG].writer(); |
| 226 | writer << ConstructIPv4ConfigProperties(MM_BEARER_IP_METHOD_DHCP); |
| 227 | bearer_.OnDBusPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties, |
| 228 | vector<string>()); |
| 229 | EXPECT_EQ(IPConfig::kMethodDHCP, bearer_.ipv4_config_method()); |
| 230 | |
| 231 | // Update 'ip6config' property. |
| 232 | properties.clear(); |
| 233 | writer = properties[MM_BEARER_PROPERTY_IP6CONFIG].writer(); |
| 234 | writer << ConstructIPv6ConfigProperties(MM_BEARER_IP_METHOD_UNKNOWN); |
| 235 | bearer_.OnDBusPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties, |
| 236 | vector<string>()); |
| 237 | EXPECT_EQ(IPConfig::kMethodUnknown, bearer_.ipv6_config_method()); |
| 238 | |
| 239 | properties.clear(); |
| 240 | writer = properties[MM_BEARER_PROPERTY_IP6CONFIG].writer(); |
| 241 | writer << ConstructIPv6ConfigProperties(MM_BEARER_IP_METHOD_PPP); |
| 242 | bearer_.OnDBusPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties, |
| 243 | vector<string>()); |
| 244 | EXPECT_EQ(IPConfig::kMethodPPP, bearer_.ipv6_config_method()); |
| 245 | |
| 246 | properties.clear(); |
| 247 | writer = properties[MM_BEARER_PROPERTY_IP6CONFIG].writer(); |
| 248 | writer << ConstructIPv6ConfigProperties(MM_BEARER_IP_METHOD_STATIC); |
| 249 | bearer_.OnDBusPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties, |
| 250 | vector<string>()); |
| 251 | EXPECT_EQ(IPConfig::kMethodStatic, bearer_.ipv6_config_method()); |
| 252 | VerifyStaticIPv6ConfigMethodAndProperties(); |
| 253 | |
| 254 | properties.clear(); |
| 255 | writer = properties[MM_BEARER_PROPERTY_IP6CONFIG].writer(); |
| 256 | writer << ConstructIPv6ConfigProperties(MM_BEARER_IP_METHOD_DHCP); |
| 257 | bearer_.OnDBusPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties, |
| 258 | vector<string>()); |
| 259 | EXPECT_EQ(IPConfig::kMethodDHCP, bearer_.ipv6_config_method()); |
| 260 | } |
| 261 | |
| 262 | } // namespace shill |