blob: 728f347f69ad78be6f7b25244649448a107da4ef [file] [log] [blame]
Thieu Le3426c8f2012-01-11 17:35:11 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Paul Stewartdd60e452011-08-08 11:38:36 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Paul Stewart9a908082011-08-31 12:18:48 -07005#include <arpa/inet.h>
6#include <linux/rtnetlink.h>
7
Paul Stewartc8f4bef2011-12-13 09:45:51 -08008#include <string>
Paul Stewart9a908082011-08-31 12:18:48 -07009#include <vector>
10
11#include <base/memory/scoped_ptr.h>
Paul Stewartdd60e452011-08-08 11:38:36 -070012#include <gtest/gtest.h>
13#include <gmock/gmock.h>
14
15#include "shill/connection.h"
Paul Stewartdd60e452011-08-08 11:38:36 -070016#include "shill/ipconfig.h"
17#include "shill/mock_control.h"
Paul Stewartc8f4bef2011-12-13 09:45:51 -080018#include "shill/mock_device.h"
Paul Stewart9a908082011-08-31 12:18:48 -070019#include "shill/mock_device_info.h"
Paul Stewartdd60e452011-08-08 11:38:36 -070020#include "shill/mock_resolver.h"
21#include "shill/mock_routing_table.h"
22#include "shill/mock_rtnl_handler.h"
23#include "shill/routing_table_entry.h"
24
Paul Stewartc8f4bef2011-12-13 09:45:51 -080025using std::string;
Paul Stewart9a908082011-08-31 12:18:48 -070026using std::vector;
Paul Stewartdd60e452011-08-08 11:38:36 -070027using testing::_;
28using testing::NiceMock;
29using testing::Return;
30using testing::StrictMock;
31using testing::Test;
32
33namespace shill {
34
35namespace {
36const char kTestDeviceName0[] = "netdev0";
37const int kTestDeviceInterfaceIndex0 = 123;
38const char kTestDeviceName1[] = "netdev1";
39const int kTestDeviceInterfaceIndex1 = 321;
40const char kIPAddress0[] = "192.168.1.1";
41const char kGatewayAddress0[] = "192.168.1.254";
Paul Stewart9a908082011-08-31 12:18:48 -070042const char kBroadcastAddress0[] = "192.168.1.255";
Paul Stewartdd60e452011-08-08 11:38:36 -070043const char kNameServer0[] = "8.8.8.8";
44const char kNameServer1[] = "8.8.9.9";
45const char kSearchDomain0[] = "chromium.org";
46const char kSearchDomain1[] = "google.com";
47} // namespace {}
48
49class ConnectionTest : public Test {
50 public:
51 ConnectionTest()
Paul Stewart9a908082011-08-31 12:18:48 -070052 : device_info_(new StrictMock<MockDeviceInfo>(
53 &control_,
54 static_cast<EventDispatcher*>(NULL),
Thieu Le3426c8f2012-01-11 17:35:11 -080055 static_cast<Metrics*>(NULL),
Paul Stewart9a908082011-08-31 12:18:48 -070056 static_cast<Manager*>(NULL))),
57 connection_(new Connection(
58 kTestDeviceInterfaceIndex0,
59 kTestDeviceName0,
Paul Stewarte00600e2012-03-16 07:08:00 -070060 Technology::kUnknown,
Paul Stewart9a908082011-08-31 12:18:48 -070061 device_info_.get())),
Paul Stewartdd60e452011-08-08 11:38:36 -070062 ipconfig_(new IPConfig(&control_, kTestDeviceName0)) {}
63
64 virtual void SetUp() {
Paul Stewartc8f4bef2011-12-13 09:45:51 -080065 ReplaceSingletons(connection_);
Paul Stewartdd60e452011-08-08 11:38:36 -070066 IPConfig::Properties properties;
67 properties.address = kIPAddress0;
68 properties.gateway = kGatewayAddress0;
Paul Stewart9a908082011-08-31 12:18:48 -070069 properties.broadcast_address = kBroadcastAddress0;
Paul Stewartdd60e452011-08-08 11:38:36 -070070 properties.dns_servers.push_back(kNameServer0);
71 properties.dns_servers.push_back(kNameServer1);
72 properties.domain_search.push_back(kSearchDomain0);
73 properties.domain_search.push_back(kSearchDomain1);
Paul Stewart7355ce12011-09-02 10:47:01 -070074 properties.address_family = IPAddress::kFamilyIPv4;
Paul Stewartdd60e452011-08-08 11:38:36 -070075 ipconfig_->UpdateProperties(properties, true);
76 }
77
Paul Stewart9a908082011-08-31 12:18:48 -070078 virtual void TearDown() {
79 EXPECT_CALL(*device_info_, FlushAddresses(kTestDeviceInterfaceIndex0));
80 }
81
Paul Stewartc8f4bef2011-12-13 09:45:51 -080082 void ReplaceSingletons(ConnectionRefPtr connection) {
83 connection->resolver_ = &resolver_;
84 connection->routing_table_ = &routing_table_;
85 connection->rtnl_handler_ = &rtnl_handler_;
86 }
87
Paul Stewartdd60e452011-08-08 11:38:36 -070088 protected:
Paul Stewart9a908082011-08-31 12:18:48 -070089 scoped_ptr<StrictMock<MockDeviceInfo> > device_info_;
Paul Stewartdd60e452011-08-08 11:38:36 -070090 ConnectionRefPtr connection_;
91 MockControl control_;
92 IPConfigRefPtr ipconfig_;
93 StrictMock<MockResolver> resolver_;
94 StrictMock<MockRoutingTable> routing_table_;
95 StrictMock<MockRTNLHandler> rtnl_handler_;
96};
97
98TEST_F(ConnectionTest, InitState) {
99 EXPECT_EQ(kTestDeviceInterfaceIndex0, connection_->interface_index_);
100 EXPECT_EQ(kTestDeviceName0, connection_->interface_name_);
101 EXPECT_FALSE(connection_->is_default());
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800102 EXPECT_FALSE(connection_->routing_request_count_);
Paul Stewartdd60e452011-08-08 11:38:36 -0700103}
104
105TEST_F(ConnectionTest, AddConfig) {
106 EXPECT_CALL(rtnl_handler_,
Paul Stewart9a908082011-08-31 12:18:48 -0700107 AddInterfaceAddress(kTestDeviceInterfaceIndex0, _, _));
Paul Stewart7cfca042011-12-08 14:18:17 -0800108 EXPECT_CALL(routing_table_,
109 SetDefaultRoute(kTestDeviceInterfaceIndex0,
110 ipconfig_,
111 Connection::kNonDefaultMetricBase +
112 kTestDeviceInterfaceIndex0));
Paul Stewart3f68bb12012-03-15 13:33:10 -0700113 EXPECT_CALL(routing_table_,
114 ConfigureRoutes(kTestDeviceInterfaceIndex0,
115 ipconfig_,
116 Connection::kDefaultMetric));
Paul Stewartdd60e452011-08-08 11:38:36 -0700117 connection_->UpdateFromIPConfig(ipconfig_);
118
119 EXPECT_CALL(routing_table_, SetDefaultMetric(kTestDeviceInterfaceIndex0,
120 Connection::kDefaultMetric));
121 EXPECT_CALL(resolver_, SetDNSFromLists(
122 ipconfig_->properties().dns_servers,
123 ipconfig_->properties().domain_search));
124
Paul Stewartc681fa02012-03-02 19:40:04 -0800125 scoped_refptr<MockDevice> device(new StrictMock<MockDevice>(
126 &control_,
127 reinterpret_cast<EventDispatcher *>(NULL),
128 reinterpret_cast<Metrics *>(NULL),
129 reinterpret_cast<Manager *>(NULL),
130 kTestDeviceName0,
131 string(),
132 kTestDeviceInterfaceIndex0));
133 EXPECT_CALL(*device_info_, GetDevice(kTestDeviceInterfaceIndex0))
134 .WillOnce(Return(device));
135 EXPECT_CALL(*device.get(), RequestPortalDetection())
136 .WillOnce(Return(true));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800137 connection_->SetIsDefault(true);
Paul Stewartdd60e452011-08-08 11:38:36 -0700138 EXPECT_TRUE(connection_->is_default());
139
Paul Stewart7cfca042011-12-08 14:18:17 -0800140 EXPECT_CALL(routing_table_,
141 SetDefaultMetric(kTestDeviceInterfaceIndex0,
142 Connection::kNonDefaultMetricBase +
143 kTestDeviceInterfaceIndex0));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800144 connection_->SetIsDefault(false);
Paul Stewartdd60e452011-08-08 11:38:36 -0700145 EXPECT_FALSE(connection_->is_default());
146}
147
148TEST_F(ConnectionTest, AddConfigReverse) {
149 EXPECT_CALL(routing_table_, SetDefaultMetric(kTestDeviceInterfaceIndex0,
150 Connection::kDefaultMetric));
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800151 vector<string> empty_list;
Paul Stewartdd60e452011-08-08 11:38:36 -0700152 EXPECT_CALL(resolver_, SetDNSFromLists(empty_list, empty_list));
Paul Stewartc681fa02012-03-02 19:40:04 -0800153 scoped_refptr<MockDevice> device(new StrictMock<MockDevice>(
154 &control_,
155 reinterpret_cast<EventDispatcher *>(NULL),
156 reinterpret_cast<Metrics *>(NULL),
157 reinterpret_cast<Manager *>(NULL),
158 kTestDeviceName0,
159 string(),
160 kTestDeviceInterfaceIndex0));
161 EXPECT_CALL(*device_info_, GetDevice(kTestDeviceInterfaceIndex0))
162 .WillOnce(Return(device));
163 EXPECT_CALL(*device.get(), RequestPortalDetection())
164 .WillOnce(Return(true));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800165 connection_->SetIsDefault(true);
Paul Stewartdd60e452011-08-08 11:38:36 -0700166
167 EXPECT_CALL(rtnl_handler_,
Paul Stewart9a908082011-08-31 12:18:48 -0700168 AddInterfaceAddress(kTestDeviceInterfaceIndex0, _, _));
Paul Stewartdd60e452011-08-08 11:38:36 -0700169 EXPECT_CALL(routing_table_, SetDefaultRoute(kTestDeviceInterfaceIndex0,
170 ipconfig_,
171 Connection::kDefaultMetric));
Paul Stewart3f68bb12012-03-15 13:33:10 -0700172 EXPECT_CALL(routing_table_,
173 ConfigureRoutes(kTestDeviceInterfaceIndex0,
174 ipconfig_,
175 Connection::kDefaultMetric));
Paul Stewartdd60e452011-08-08 11:38:36 -0700176 EXPECT_CALL(resolver_, SetDNSFromIPConfig(ipconfig_));
177
178 connection_->UpdateFromIPConfig(ipconfig_);
179}
180
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800181TEST_F(ConnectionTest, RouteRequest) {
Paul Stewartf748a362012-03-07 12:01:20 -0800182 ConnectionRefPtr connection(new Connection(kTestDeviceInterfaceIndex0,
183 kTestDeviceName0,
Paul Stewarte00600e2012-03-16 07:08:00 -0700184 Technology::kUnknown,
Paul Stewartf748a362012-03-07 12:01:20 -0800185 device_info_.get()));
186 ReplaceSingletons(connection);
187 scoped_refptr<MockDevice> device(new StrictMock<MockDevice>(
188 &control_,
189 reinterpret_cast<EventDispatcher *>(NULL),
190 reinterpret_cast<Metrics *>(NULL),
191 reinterpret_cast<Manager *>(NULL),
192 kTestDeviceName0,
193 string(),
194 kTestDeviceInterfaceIndex0));
195 EXPECT_CALL(*device_info_, GetDevice(kTestDeviceInterfaceIndex0))
196 .WillRepeatedly(Return(device));
197 EXPECT_CALL(*device.get(), DisableReversePathFilter()).Times(1);
198 connection->RequestRouting();
199 connection->RequestRouting();
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800200
Paul Stewartf748a362012-03-07 12:01:20 -0800201 // The first release should only decrement the reference counter.
202 connection->ReleaseRouting();
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800203
Paul Stewartf748a362012-03-07 12:01:20 -0800204 // Another release will re-enable reverse-path filter.
205 EXPECT_CALL(*device.get(), EnableReversePathFilter());
206 EXPECT_CALL(routing_table_, FlushCache());
207 connection->ReleaseRouting();
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800208
Paul Stewartf748a362012-03-07 12:01:20 -0800209 // The destructor will remove the routes and addresses.
210 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceInterfaceIndex0));
211 EXPECT_CALL(*device_info_.get(),
212 FlushAddresses(kTestDeviceInterfaceIndex0));
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800213}
214
Paul Stewartdd60e452011-08-08 11:38:36 -0700215TEST_F(ConnectionTest, Destructor) {
Thieu Lefb46caf2012-03-08 11:57:15 -0800216 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceInterfaceIndex1));
Paul Stewart9a908082011-08-31 12:18:48 -0700217 EXPECT_CALL(*device_info_, FlushAddresses(kTestDeviceInterfaceIndex1));
Paul Stewartdd60e452011-08-08 11:38:36 -0700218 {
219 ConnectionRefPtr connection(new Connection(kTestDeviceInterfaceIndex1,
Paul Stewart9a908082011-08-31 12:18:48 -0700220 kTestDeviceName1,
Paul Stewarte00600e2012-03-16 07:08:00 -0700221 Technology::kUnknown,
Paul Stewart9a908082011-08-31 12:18:48 -0700222 device_info_.get()));
Paul Stewartdd60e452011-08-08 11:38:36 -0700223 connection->resolver_ = &resolver_;
224 connection->routing_table_ = &routing_table_;
225 connection->rtnl_handler_ = &rtnl_handler_;
226 }
227}
228
Paul Stewartf748a362012-03-07 12:01:20 -0800229MATCHER_P2(IsIPAddress, address, prefix, "") {
230 IPAddress match_address(address);
231 match_address.set_prefix(prefix);
232 return match_address.Equals(arg);
233}
234
235TEST_F(ConnectionTest, RequestHostRoute) {
236 ConnectionRefPtr connection(new Connection(kTestDeviceInterfaceIndex0,
237 kTestDeviceName0,
Paul Stewarte00600e2012-03-16 07:08:00 -0700238 Technology::kUnknown,
Paul Stewartf748a362012-03-07 12:01:20 -0800239 device_info_.get()));
240 ReplaceSingletons(connection);
241 IPAddress address(IPAddress::kFamilyIPv4);
242 ASSERT_TRUE(address.SetAddressFromString(kIPAddress0));
243 size_t prefix_len = address.GetLength() * 8;
244 EXPECT_CALL(routing_table_, RequestRouteToHost(
245 IsIPAddress(address, prefix_len), kTestDeviceInterfaceIndex0))
246 .WillOnce(Return(true));
247 EXPECT_TRUE(connection->RequestHostRoute(address));
248
249 // The destructor will remove the routes and addresses.
250 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceInterfaceIndex0));
251 EXPECT_CALL(*device_info_.get(),
252 FlushAddresses(kTestDeviceInterfaceIndex0));
253}
254
Paul Stewartdd60e452011-08-08 11:38:36 -0700255} // namespace shill