blob: dacafbfcb8cc16d3b01ee6dacc32eaf66b52ab97 [file] [log] [blame]
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Darin Petkove7cb7f82011-06-03 13:21:51 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Chris Masone8a7b8be2011-07-22 12:43:37 -07005#include "shill/dhcp_config.h"
6
Eric Shienbrood3e20a232012-02-16 11:35:56 -05007#include <base/bind.h>
Darin Petkov92c43902011-06-09 20:46:06 -07008#include <base/file_util.h>
Paul Stewart5ad16062013-02-21 18:10:48 -08009#include <base/files/scoped_temp_dir.h>
Darin Petkov92c43902011-06-09 20:46:06 -070010#include <base/stringprintf.h>
Chris Masone43b48a12011-07-01 13:37:07 -070011#include <chromeos/dbus/service_constants.h>
Chris Masone8a7b8be2011-07-22 12:43:37 -070012#include <gtest/gtest.h>
Darin Petkov92c43902011-06-09 20:46:06 -070013
Chris Masone43b48a12011-07-01 13:37:07 -070014#include "shill/dbus_adaptor.h"
Darin Petkovf7897bc2011-06-08 17:13:36 -070015#include "shill/dhcp_provider.h"
Paul Stewart26b327e2011-10-19 11:38:09 -070016#include "shill/event_dispatcher.h"
Chris Masone19e30402011-07-19 15:48:47 -070017#include "shill/mock_control.h"
Darin Petkov98dd6a02011-06-10 15:12:57 -070018#include "shill/mock_dhcp_proxy.h"
Darin Petkovf7897bc2011-06-08 17:13:36 -070019#include "shill/mock_glib.h"
mukesh agrawal6c6655d2012-12-06 14:49:50 -080020#include "shill/mock_log.h"
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070021#include "shill/mock_minijail.h"
Chris Masone43b48a12011-07-01 13:37:07 -070022#include "shill/property_store_unittest.h"
Darin Petkova7b89492011-07-27 12:48:17 -070023#include "shill/proxy_factory.h"
Darin Petkove7cb7f82011-06-03 13:21:51 -070024
Eric Shienbrood3e20a232012-02-16 11:35:56 -050025using base::Bind;
Albert Chaulk0e1cdea2013-02-27 15:32:55 -080026using base::FilePath;
Paul Stewart5ad16062013-02-21 18:10:48 -080027using base::ScopedTempDir;
Eric Shienbrood3e20a232012-02-16 11:35:56 -050028using base::Unretained;
Darin Petkove7cb7f82011-06-03 13:21:51 -070029using std::string;
30using std::vector;
Darin Petkovf7897bc2011-06-08 17:13:36 -070031using testing::_;
mukesh agrawal1835e772013-01-15 18:35:03 -080032using testing::AnyNumber;
33using testing::ContainsRegex;
Darin Petkovf7897bc2011-06-08 17:13:36 -070034using testing::Return;
35using testing::SetArgumentPointee;
Darin Petkove7cb7f82011-06-03 13:21:51 -070036using testing::Test;
37
38namespace shill {
39
Darin Petkov92c43902011-06-09 20:46:06 -070040namespace {
Darin Petkova7b89492011-07-27 12:48:17 -070041const char kDeviceName[] = "eth0";
Paul Stewartd32f4842012-01-11 16:08:13 -080042const char kHostName[] = "hostname";
Paul Stewartd408fdf2012-05-07 17:15:57 -070043const char kLeaseFileSuffix[] = "leasefilesuffix";
44const bool kArpGateway = true;
Darin Petkov92c43902011-06-09 20:46:06 -070045} // namespace {}
46
Chris Masone43b48a12011-07-01 13:37:07 -070047class DHCPConfigTest : public PropertyStoreTest {
Darin Petkove7cb7f82011-06-03 13:21:51 -070048 public:
Darin Petkovf7897bc2011-06-08 17:13:36 -070049 DHCPConfigTest()
Darin Petkovf65e9282011-06-21 14:29:56 -070050 : proxy_(new MockDHCPProxy()),
Darin Petkova7b89492011-07-27 12:48:17 -070051 proxy_factory_(this),
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070052 minijail_(new MockMinijail()),
Chris Masone19e30402011-07-19 15:48:47 -070053 config_(new DHCPConfig(&control_,
Chris Masone2176a882011-09-14 22:29:15 -070054 dispatcher(),
Chris Masone19e30402011-07-19 15:48:47 -070055 DHCPProvider::GetInstance(),
Darin Petkov92c43902011-06-09 20:46:06 -070056 kDeviceName,
Paul Stewartd32f4842012-01-11 16:08:13 -080057 kHostName,
Paul Stewartd408fdf2012-05-07 17:15:57 -070058 kLeaseFileSuffix,
59 kArpGateway,
Chris Masone2176a882011-09-14 22:29:15 -070060 glib())) {}
Darin Petkova7b89492011-07-27 12:48:17 -070061
62 virtual void SetUp() {
Darin Petkovab565bb2011-10-06 02:55:51 -070063 config_->proxy_factory_ = &proxy_factory_;
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070064 config_->minijail_ = minijail_.get();
Darin Petkova7b89492011-07-27 12:48:17 -070065 }
66
67 virtual void TearDown() {
Darin Petkovab565bb2011-10-06 02:55:51 -070068 config_->proxy_factory_ = NULL;
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070069 config_->minijail_ = NULL;
Darin Petkov98dd6a02011-06-10 15:12:57 -070070 }
Darin Petkove7cb7f82011-06-03 13:21:51 -070071
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070072 DHCPConfigRefPtr CreateMockMinijailConfig(const string &hostname,
73 const string &lease_suffix,
74 bool arp_gateway);
Paul Stewartd408fdf2012-05-07 17:15:57 -070075 DHCPConfigRefPtr CreateRunningConfig(const string &hostname,
76 const string &lease_suffix,
77 bool arp_gateway);
78 void StopRunningConfigAndExpect(DHCPConfigRefPtr config,
79 bool lease_file_exists);
80
Darin Petkove7cb7f82011-06-03 13:21:51 -070081 protected:
Darin Petkova7b89492011-07-27 12:48:17 -070082 class TestProxyFactory : public ProxyFactory {
83 public:
Paul Stewart7355ce12011-09-02 10:47:01 -070084 explicit TestProxyFactory(DHCPConfigTest *test) : test_(test) {}
Darin Petkova7b89492011-07-27 12:48:17 -070085
mukesh agrawal1830fa12011-09-26 14:31:40 -070086 virtual DHCPProxyInterface *CreateDHCPProxy(const string &/*service*/) {
Darin Petkova7b89492011-07-27 12:48:17 -070087 return test_->proxy_.release();
88 }
89
90 private:
91 DHCPConfigTest *test_;
92 };
93
Paul Stewartd408fdf2012-05-07 17:15:57 -070094 static const int kPID;
95 static const unsigned int kTag;
96
97 FilePath lease_file_;
98 FilePath pid_file_;
99 ScopedTempDir temp_dir_;
Darin Petkova7b89492011-07-27 12:48:17 -0700100 scoped_ptr<MockDHCPProxy> proxy_;
101 TestProxyFactory proxy_factory_;
Chris Masone19e30402011-07-19 15:48:47 -0700102 MockControl control_;
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700103 scoped_ptr<MockMinijail> minijail_;
Darin Petkovf7897bc2011-06-08 17:13:36 -0700104 DHCPConfigRefPtr config_;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700105};
106
Paul Stewartd408fdf2012-05-07 17:15:57 -0700107const int DHCPConfigTest::kPID = 123456;
108const unsigned int DHCPConfigTest::kTag = 77;
109
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700110DHCPConfigRefPtr DHCPConfigTest::CreateMockMinijailConfig(
111 const string &hostname,
112 const string &lease_suffix,
113 bool arp_gateway) {
114 DHCPConfigRefPtr config(new DHCPConfig(&control_,
115 dispatcher(),
116 DHCPProvider::GetInstance(),
117 kDeviceName,
118 hostname,
119 lease_suffix,
120 arp_gateway,
121 glib()));
122 config->minijail_ = minijail_.get();
123 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(false));
124
125 return config;
126}
127
Paul Stewartd408fdf2012-05-07 17:15:57 -0700128DHCPConfigRefPtr DHCPConfigTest::CreateRunningConfig(const string &hostname,
129 const string &lease_suffix,
130 bool arp_gateway) {
131 DHCPConfigRefPtr config(new DHCPConfig(&control_,
132 dispatcher(),
133 DHCPProvider::GetInstance(),
134 kDeviceName,
135 hostname,
136 lease_suffix,
137 arp_gateway,
138 glib()));
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700139 config->minijail_ = minijail_.get();
140 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _))
141 .WillOnce(DoAll(SetArgumentPointee<2>(kPID), Return(true)));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700142 EXPECT_CALL(*glib(), ChildWatchAdd(kPID, _, _)).WillOnce(Return(kTag));
143 EXPECT_TRUE(config->Start());
144 EXPECT_EQ(kPID, config->pid_);
145 EXPECT_EQ(config.get(), DHCPProvider::GetInstance()->GetConfig(kPID).get());
146 EXPECT_EQ(kTag, config->child_watch_tag_);
147
148 EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
149 config->root_ = temp_dir_.path();
Jorge Lucangeli Obes2f3169d2012-04-25 11:38:25 -0700150 FilePath varrun = temp_dir_.path().Append("var/run/dhcpcd");
Paul Stewartd408fdf2012-05-07 17:15:57 -0700151 EXPECT_TRUE(file_util::CreateDirectory(varrun));
152 pid_file_ = varrun.Append(base::StringPrintf("dhcpcd-%s.pid", kDeviceName));
153 FilePath varlib = temp_dir_.path().Append("var/lib/dhcpcd");
154 EXPECT_TRUE(file_util::CreateDirectory(varlib));
155 lease_file_ =
156 varlib.Append(base::StringPrintf("dhcpcd-%s.lease", kDeviceName));
157 EXPECT_EQ(0, file_util::WriteFile(pid_file_, "", 0));
158 EXPECT_EQ(0, file_util::WriteFile(lease_file_, "", 0));
159 EXPECT_TRUE(file_util::PathExists(pid_file_));
160 EXPECT_TRUE(file_util::PathExists(lease_file_));
161
162 return config;
163}
164
165void DHCPConfigTest::StopRunningConfigAndExpect(DHCPConfigRefPtr config,
166 bool lease_file_exists) {
mukesh agrawal6c6655d2012-12-06 14:49:50 -0800167 ScopedMockLog log;
168 // We use a non-zero exit status so that we get the log message.
169 EXPECT_CALL(log, Log(_, _, ::testing::EndsWith("status 10")));
170 DHCPConfig::ChildWatchCallback(kPID, 10, config.get());
Paul Stewartd408fdf2012-05-07 17:15:57 -0700171 EXPECT_EQ(NULL, DHCPProvider::GetInstance()->GetConfig(kPID).get());
172
173 EXPECT_FALSE(file_util::PathExists(pid_file_));
174 EXPECT_EQ(lease_file_exists, file_util::PathExists(lease_file_));
175}
176
Darin Petkove7cb7f82011-06-03 13:21:51 -0700177TEST_F(DHCPConfigTest, GetIPv4AddressString) {
Darin Petkovf7897bc2011-06-08 17:13:36 -0700178 EXPECT_EQ("255.255.255.255", config_->GetIPv4AddressString(0xffffffff));
179 EXPECT_EQ("0.0.0.0", config_->GetIPv4AddressString(0));
180 EXPECT_EQ("1.2.3.4", config_->GetIPv4AddressString(0x04030201));
Darin Petkove7cb7f82011-06-03 13:21:51 -0700181}
182
Darin Petkova7b89492011-07-27 12:48:17 -0700183TEST_F(DHCPConfigTest, InitProxy) {
184 static const char kService[] = ":1.200";
Darin Petkova7b89492011-07-27 12:48:17 -0700185 EXPECT_TRUE(proxy_.get());
186 EXPECT_FALSE(config_->proxy_.get());
Eric Shienbrood9a245532012-03-07 14:20:39 -0500187 config_->InitProxy(kService);
Darin Petkova7b89492011-07-27 12:48:17 -0700188 EXPECT_FALSE(proxy_.get());
189 EXPECT_TRUE(config_->proxy_.get());
190
191 config_->InitProxy(kService);
Darin Petkova7b89492011-07-27 12:48:17 -0700192}
193
Paul Stewart65bcd082012-11-16 09:37:14 -0800194TEST_F(DHCPConfigTest, ParseClasslessStaticRoutes) {
195 const string kDefaultAddress = "0.0.0.0";
196 const string kDefaultDestination = kDefaultAddress + "/0";
197 const string kRouter0 = "10.0.0.254";
198 const string kAddress1 = "192.168.1.0";
199 const string kDestination1 = kAddress1 + "/24";
200 // Last gateway missing, leaving an odd number of parameters.
201 const string kBrokenClasslessRoutes0 = kDefaultDestination + " " + kRouter0 +
202 " " + kDestination1;
203 IPConfig::Properties properties;
204 EXPECT_FALSE(DHCPConfig::ParseClasslessStaticRoutes(kBrokenClasslessRoutes0,
205 &properties));
206 EXPECT_TRUE(properties.routes.empty());
207 EXPECT_TRUE(properties.gateway.empty());
208
209 // Gateway argument for the second route is malformed, but we were able
210 // to salvage a default gateway.
211 const string kBrokenRouter1 = "10.0.0";
212 const string kBrokenClasslessRoutes1 = kBrokenClasslessRoutes0 + " " +
213 kBrokenRouter1;
214 EXPECT_FALSE(DHCPConfig::ParseClasslessStaticRoutes(kBrokenClasslessRoutes1,
215 &properties));
216 EXPECT_TRUE(properties.routes.empty());
217 EXPECT_EQ(kRouter0, properties.gateway);
218
219 const string kRouter1 = "10.0.0.253";
220 const string kRouter2 = "10.0.0.252";
221 const string kClasslessRoutes0 = kDefaultDestination + " " + kRouter2 + " " +
222 kDestination1 + " " + kRouter1;
223 EXPECT_TRUE(DHCPConfig::ParseClasslessStaticRoutes(kClasslessRoutes0,
224 &properties));
225 // The old default route is preserved.
226 EXPECT_EQ(kRouter0, properties.gateway);
227
228 // The two routes (including the one which would have otherwise been
229 // classified as a default route) are added to the routing table.
230 EXPECT_EQ(2, properties.routes.size());
231 const IPConfig::Route &route0 = properties.routes[0];
232 EXPECT_EQ(kDefaultAddress, route0.host);
233 EXPECT_EQ("0.0.0.0", route0.netmask);
234 EXPECT_EQ(kRouter2, route0.gateway);
235
236 const IPConfig::Route &route1 = properties.routes[1];
237 EXPECT_EQ(kAddress1, route1.host);
238 EXPECT_EQ("255.255.255.0", route1.netmask);
239 EXPECT_EQ(kRouter1, route1.gateway);
240
241 // A malformed routing table should not affect the current table.
242 EXPECT_FALSE(DHCPConfig::ParseClasslessStaticRoutes(kBrokenClasslessRoutes1,
243 &properties));
244 EXPECT_EQ(2, properties.routes.size());
245 EXPECT_EQ(kRouter0, properties.gateway);
246}
247
Darin Petkove7cb7f82011-06-03 13:21:51 -0700248TEST_F(DHCPConfigTest, ParseConfiguration) {
249 DHCPConfig::Configuration conf;
250 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
251 0x01020304);
252 conf[DHCPConfig::kConfigurationKeySubnetCIDR].writer().append_byte(
253 16);
254 conf[DHCPConfig::kConfigurationKeyBroadcastAddress].writer().append_uint32(
255 0x10203040);
256 {
Darin Petkove7cb7f82011-06-03 13:21:51 -0700257 vector<unsigned int> routers;
258 routers.push_back(0x02040608);
259 routers.push_back(0x03050709);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700260 DBus::MessageIter writer =
261 conf[DHCPConfig::kConfigurationKeyRouters].writer();
Darin Petkove7cb7f82011-06-03 13:21:51 -0700262 writer << routers;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700263 }
264 {
Darin Petkove7cb7f82011-06-03 13:21:51 -0700265 vector<unsigned int> dns;
266 dns.push_back(0x09070503);
267 dns.push_back(0x08060402);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700268 DBus::MessageIter writer = conf[DHCPConfig::kConfigurationKeyDNS].writer();
Darin Petkove7cb7f82011-06-03 13:21:51 -0700269 writer << dns;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700270 }
271 conf[DHCPConfig::kConfigurationKeyDomainName].writer().append_string(
272 "domain-name");
273 {
Darin Petkove7cb7f82011-06-03 13:21:51 -0700274 vector<string> search;
275 search.push_back("foo.com");
276 search.push_back("bar.com");
Darin Petkovf7897bc2011-06-08 17:13:36 -0700277 DBus::MessageIter writer =
278 conf[DHCPConfig::kConfigurationKeyDomainSearch].writer();
Darin Petkove7cb7f82011-06-03 13:21:51 -0700279 writer << search;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700280 }
281 conf[DHCPConfig::kConfigurationKeyMTU].writer().append_uint16(600);
282 conf["UnknownKey"] = DBus::Variant();
283
Darin Petkove7cb7f82011-06-03 13:21:51 -0700284 IPConfig::Properties properties;
Darin Petkovf7897bc2011-06-08 17:13:36 -0700285 ASSERT_TRUE(config_->ParseConfiguration(conf, &properties));
Darin Petkove7cb7f82011-06-03 13:21:51 -0700286 EXPECT_EQ("4.3.2.1", properties.address);
Paul Stewart48100b02012-03-19 07:53:52 -0700287 EXPECT_EQ(16, properties.subnet_prefix);
Darin Petkove7cb7f82011-06-03 13:21:51 -0700288 EXPECT_EQ("64.48.32.16", properties.broadcast_address);
289 EXPECT_EQ("8.6.4.2", properties.gateway);
290 ASSERT_EQ(2, properties.dns_servers.size());
291 EXPECT_EQ("3.5.7.9", properties.dns_servers[0]);
292 EXPECT_EQ("2.4.6.8", properties.dns_servers[1]);
293 EXPECT_EQ("domain-name", properties.domain_name);
294 ASSERT_EQ(2, properties.domain_search.size());
295 EXPECT_EQ("foo.com", properties.domain_search[0]);
296 EXPECT_EQ("bar.com", properties.domain_search[1]);
297 EXPECT_EQ(600, properties.mtu);
298}
299
Darin Petkov92c43902011-06-09 20:46:06 -0700300TEST_F(DHCPConfigTest, StartFail) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700301 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(false));
Chris Masone2176a882011-09-14 22:29:15 -0700302 EXPECT_CALL(*glib(), ChildWatchAdd(_, _, _)).Times(0);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700303 EXPECT_FALSE(config_->Start());
304 EXPECT_EQ(0, config_->pid_);
Darin Petkov92c43902011-06-09 20:46:06 -0700305}
Darin Petkovf7897bc2011-06-08 17:13:36 -0700306
Paul Stewartd408fdf2012-05-07 17:15:57 -0700307MATCHER_P3(IsDHCPCDArgs, has_hostname, has_arp_gateway, has_lease_suffix, "") {
Paul Stewartd32f4842012-01-11 16:08:13 -0800308 if (string(arg[0]) != "/sbin/dhcpcd" ||
Paul Stewartd408fdf2012-05-07 17:15:57 -0700309 string(arg[1]) != "-B") {
Paul Stewartd32f4842012-01-11 16:08:13 -0800310 return false;
311 }
312
Paul Stewartd408fdf2012-05-07 17:15:57 -0700313 int end_offset = 2;
Paul Stewartd32f4842012-01-11 16:08:13 -0800314 if (has_hostname) {
Paul Stewartd408fdf2012-05-07 17:15:57 -0700315 if (string(arg[end_offset]) != "-h" ||
316 string(arg[end_offset + 1]) != kHostName) {
Paul Stewartd32f4842012-01-11 16:08:13 -0800317 return false;
318 }
Paul Stewartd408fdf2012-05-07 17:15:57 -0700319 end_offset += 2;
Paul Stewartd32f4842012-01-11 16:08:13 -0800320 }
321
Paul Stewartd408fdf2012-05-07 17:15:57 -0700322 if (has_arp_gateway) {
323 if (string(arg[end_offset]) != "-R")
324 return false;
325 ++end_offset;
326 }
327
328 string device_arg = has_lease_suffix ?
329 string(kDeviceName) + "=" + string(kLeaseFileSuffix) : kDeviceName;
330 return string(arg[end_offset]) == device_arg && arg[end_offset + 1] == NULL;
Paul Stewartd32f4842012-01-11 16:08:13 -0800331}
332
333TEST_F(DHCPConfigTest, StartWithHostname) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700334 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(false));
Paul Stewartd32f4842012-01-11 16:08:13 -0800335 EXPECT_FALSE(config_->Start());
336}
337
338TEST_F(DHCPConfigTest, StartWithoutHostname) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700339 DHCPConfigRefPtr config = CreateMockMinijailConfig("",
340 kLeaseFileSuffix,
341 kArpGateway);
Paul Stewartd408fdf2012-05-07 17:15:57 -0700342 EXPECT_FALSE(config->Start());
343}
344
345TEST_F(DHCPConfigTest, StartWithoutArpGateway) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700346 DHCPConfigRefPtr config = CreateMockMinijailConfig(kHostName,
347 kLeaseFileSuffix,
348 false);
Paul Stewartd408fdf2012-05-07 17:15:57 -0700349 EXPECT_FALSE(config->Start());
350}
351
352TEST_F(DHCPConfigTest, StartWithoutLeaseSuffix) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700353 DHCPConfigRefPtr config = CreateMockMinijailConfig(kHostName,
354 kDeviceName,
355 kArpGateway);
Paul Stewartd32f4842012-01-11 16:08:13 -0800356 EXPECT_FALSE(config->Start());
357}
358
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700359namespace {
360
361class UpdateCallbackTest {
362 public:
363 UpdateCallbackTest(const string &message,
Chris Masone2b105542011-06-22 10:58:09 -0700364 const IPConfigRefPtr &ipconfig,
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700365 bool success)
366 : message_(message),
367 ipconfig_(ipconfig),
368 success_(success),
369 called_(false) {}
370
Chris Masone2b105542011-06-22 10:58:09 -0700371 void Callback(const IPConfigRefPtr &ipconfig, bool success) {
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700372 called_ = true;
373 EXPECT_EQ(ipconfig_.get(), ipconfig.get()) << message_;
374 EXPECT_EQ(success_, success) << message_;
375 }
376
377 bool called() const { return called_; }
378
379 private:
380 const string message_;
381 IPConfigRefPtr ipconfig_;
382 bool success_;
383 bool called_;
384};
385
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700386void DoNothing() {}
387
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700388} // namespace {}
389
390TEST_F(DHCPConfigTest, ProcessEventSignalFail) {
391 DHCPConfig::Configuration conf;
392 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
393 0x01020304);
394 UpdateCallbackTest callback_test(DHCPConfig::kReasonFail, config_, false);
395 config_->RegisterUpdateCallback(
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500396 Bind(&UpdateCallbackTest::Callback, Unretained(&callback_test)));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700397 config_->lease_acquisition_timeout_callback_.Reset(base::Bind(&DoNothing));
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700398 config_->ProcessEventSignal(DHCPConfig::kReasonFail, conf);
399 EXPECT_TRUE(callback_test.called());
400 EXPECT_TRUE(config_->properties().address.empty());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700401 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700402}
403
404TEST_F(DHCPConfigTest, ProcessEventSignalSuccess) {
405 static const char * const kReasons[] = {
406 DHCPConfig::kReasonBound,
407 DHCPConfig::kReasonRebind,
408 DHCPConfig::kReasonReboot,
409 DHCPConfig::kReasonRenew
410 };
411 for (size_t r = 0; r < arraysize(kReasons); r++) {
412 DHCPConfig::Configuration conf;
413 string message = string(kReasons[r]) + " failed";
414 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(r);
415 UpdateCallbackTest callback_test(message, config_, true);
416 config_->RegisterUpdateCallback(
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500417 Bind(&UpdateCallbackTest::Callback, Unretained(&callback_test)));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700418 config_->lease_acquisition_timeout_callback_.Reset(base::Bind(&DoNothing));
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700419 config_->ProcessEventSignal(kReasons[r], conf);
420 EXPECT_TRUE(callback_test.called()) << message;
Paul Stewart83224402011-11-30 14:52:30 -0800421 EXPECT_EQ(base::StringPrintf("%zu.0.0.0", r), config_->properties().address)
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700422 << message;
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700423 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700424 }
425}
426
427TEST_F(DHCPConfigTest, ProcessEventSignalUnknown) {
428 DHCPConfig::Configuration conf;
429 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
430 0x01020304);
431 static const char kReasonUnknown[] = "UNKNOWN_REASON";
432 UpdateCallbackTest callback_test(kReasonUnknown, config_, false);
433 config_->RegisterUpdateCallback(
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500434 Bind(&UpdateCallbackTest::Callback, Unretained(&callback_test)));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700435 config_->lease_acquisition_timeout_callback_.Reset(base::Bind(&DoNothing));
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700436 config_->ProcessEventSignal(kReasonUnknown, conf);
437 EXPECT_FALSE(callback_test.called());
438 EXPECT_TRUE(config_->properties().address.empty());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700439 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700440}
441
442
Darin Petkov98dd6a02011-06-10 15:12:57 -0700443TEST_F(DHCPConfigTest, ReleaseIP) {
444 config_->pid_ = 1 << 18; // Ensure unknown positive PID.
Paul Stewarta02ee492012-05-16 10:04:53 -0700445 config_->arp_gateway_ = false;
Darin Petkovaceede32011-07-18 15:32:38 -0700446 EXPECT_CALL(*proxy_, Release(kDeviceName)).Times(1);
Darin Petkova7b89492011-07-27 12:48:17 -0700447 config_->proxy_.reset(proxy_.release());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700448 EXPECT_TRUE(config_->ReleaseIP());
449 config_->pid_ = 0;
450}
451
Paul Stewarta02ee492012-05-16 10:04:53 -0700452TEST_F(DHCPConfigTest, ReleaseIPArpGW) {
453 config_->pid_ = 1 << 18; // Ensure unknown positive PID.
454 config_->arp_gateway_ = true;
455 EXPECT_CALL(*proxy_, Release(kDeviceName)).Times(0);
456 config_->proxy_.reset(proxy_.release());
457 EXPECT_TRUE(config_->ReleaseIP());
458 config_->pid_ = 0;
459}
460
Darin Petkov98dd6a02011-06-10 15:12:57 -0700461TEST_F(DHCPConfigTest, RenewIP) {
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700462 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700463 config_->pid_ = 456;
Paul Stewartc02344a2012-08-17 16:57:37 -0700464 EXPECT_FALSE(config_->RenewIP()); // Expect no crash with NULL proxy.
Darin Petkovaceede32011-07-18 15:32:38 -0700465 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
Darin Petkova7b89492011-07-27 12:48:17 -0700466 config_->proxy_.reset(proxy_.release());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700467 EXPECT_TRUE(config_->RenewIP());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700468 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700469 config_->pid_ = 0;
470}
471
472TEST_F(DHCPConfigTest, RequestIP) {
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700473 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700474 config_->pid_ = 567;
Darin Petkovaceede32011-07-18 15:32:38 -0700475 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
Darin Petkova7b89492011-07-27 12:48:17 -0700476 config_->proxy_.reset(proxy_.release());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700477 EXPECT_TRUE(config_->RenewIP());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700478 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
479 config_->pid_ = 0;
480}
481
482TEST_F(DHCPConfigTest, RequestIPTimeout) {
483 UpdateCallbackTest callback_test(DHCPConfig::kReasonFail, config_, false);
484 config_->RegisterUpdateCallback(
485 Bind(&UpdateCallbackTest::Callback, Unretained(&callback_test)));
486 config_->lease_acquisition_timeout_seconds_ = 0;
487 config_->pid_ = 567;
488 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
489 config_->proxy_.reset(proxy_.release());
490 config_->RenewIP();
491 config_->dispatcher_->DispatchPendingEvents();
492 EXPECT_TRUE(callback_test.called());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700493 config_->pid_ = 0;
494}
495
496TEST_F(DHCPConfigTest, Restart) {
497 const int kPID1 = 1 << 17; // Ensure unknown positive PID.
498 const int kPID2 = 987;
499 const unsigned int kTag1 = 11;
500 const unsigned int kTag2 = 22;
501 config_->pid_ = kPID1;
502 config_->child_watch_tag_ = kTag1;
503 DHCPProvider::GetInstance()->BindPID(kPID1, config_);
Chris Masone2176a882011-09-14 22:29:15 -0700504 EXPECT_CALL(*glib(), SourceRemove(kTag1)).WillOnce(Return(true));
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700505 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(
506 DoAll(SetArgumentPointee<2>(kPID2), Return(true)));
Chris Masone2176a882011-09-14 22:29:15 -0700507 EXPECT_CALL(*glib(), ChildWatchAdd(kPID2, _, _)).WillOnce(Return(kTag2));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700508 EXPECT_TRUE(config_->Restart());
509 EXPECT_EQ(kPID2, config_->pid_);
510 EXPECT_EQ(config_.get(), DHCPProvider::GetInstance()->GetConfig(kPID2).get());
511 EXPECT_EQ(kTag2, config_->child_watch_tag_);
512 DHCPProvider::GetInstance()->UnbindPID(kPID2);
513 config_->pid_ = 0;
514 config_->child_watch_tag_ = 0;
515}
516
517TEST_F(DHCPConfigTest, RestartNoClient) {
518 const int kPID = 777;
519 const unsigned int kTag = 66;
Chris Masone2176a882011-09-14 22:29:15 -0700520 EXPECT_CALL(*glib(), SourceRemove(_)).Times(0);
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700521 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(
522 DoAll(SetArgumentPointee<2>(kPID), Return(true)));
Chris Masone2176a882011-09-14 22:29:15 -0700523 EXPECT_CALL(*glib(), ChildWatchAdd(kPID, _, _)).WillOnce(Return(kTag));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700524 EXPECT_TRUE(config_->Restart());
525 EXPECT_EQ(kPID, config_->pid_);
526 EXPECT_EQ(config_.get(), DHCPProvider::GetInstance()->GetConfig(kPID).get());
527 EXPECT_EQ(kTag, config_->child_watch_tag_);
528 DHCPProvider::GetInstance()->UnbindPID(kPID);
529 config_->pid_ = 0;
530 config_->child_watch_tag_ = 0;
531}
532
Paul Stewartd408fdf2012-05-07 17:15:57 -0700533TEST_F(DHCPConfigTest, StartSuccessEphemeral) {
534 DHCPConfigRefPtr config =
535 CreateRunningConfig(kHostName, kDeviceName, kArpGateway);
536 StopRunningConfigAndExpect(config, false);
537}
Darin Petkov92c43902011-06-09 20:46:06 -0700538
Paul Stewartd408fdf2012-05-07 17:15:57 -0700539TEST_F(DHCPConfigTest, StartSuccessPersistent) {
540 DHCPConfigRefPtr config =
541 CreateRunningConfig(kHostName, kLeaseFileSuffix, kArpGateway);
542 StopRunningConfigAndExpect(config, true);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700543}
544
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700545TEST_F(DHCPConfigTest, StartTimeout) {
546 UpdateCallbackTest callback_test(DHCPConfig::kReasonFail, config_, false);
547 config_->RegisterUpdateCallback(
548 Bind(&UpdateCallbackTest::Callback, Unretained(&callback_test)));
549 config_->lease_acquisition_timeout_seconds_ = 0;
550 config_->proxy_.reset(proxy_.release());
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700551 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(true));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700552 config_->Start();
553 config_->dispatcher_->DispatchPendingEvents();
554 EXPECT_TRUE(callback_test.called());
555}
556
Darin Petkov98dd6a02011-06-10 15:12:57 -0700557TEST_F(DHCPConfigTest, Stop) {
Darin Petkov98dd6a02011-06-10 15:12:57 -0700558 const int kPID = 1 << 17; // Ensure unknown positive PID.
mukesh agrawal1835e772013-01-15 18:35:03 -0800559 ScopedMockLog log;
560 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
561 EXPECT_CALL(log, Log(_, _, ContainsRegex(
Darin Petkov3fe17662013-02-04 14:19:08 +0100562 base::StringPrintf("Stopping.+%s", __func__))));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700563 config_->pid_ = kPID;
Darin Petkov3fe17662013-02-04 14:19:08 +0100564 DHCPProvider::GetInstance()->BindPID(kPID, config_);
mukesh agrawal1835e772013-01-15 18:35:03 -0800565 config_->Stop(__func__);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700566 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkov3fe17662013-02-04 14:19:08 +0100567 EXPECT_FALSE(DHCPProvider::GetInstance()->GetConfig(kPID));
568 EXPECT_FALSE(config_->pid_);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700569}
570
571TEST_F(DHCPConfigTest, StopDuringRequestIP) {
572 config_->pid_ = 567;
573 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
574 config_->proxy_.reset(proxy_.release());
575 EXPECT_TRUE(config_->RenewIP());
576 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
577 config_->pid_ = 0; // Keep Stop from killing a real process.
mukesh agrawal1835e772013-01-15 18:35:03 -0800578 config_->Stop(__func__);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700579 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700580}
581
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800582TEST_F(DHCPConfigTest, SetProperty) {
Chris Masone43b48a12011-07-01 13:37:07 -0700583 ::DBus::Error error;
584 // Ensure that an attempt to write a R/O property returns InvalidArgs error.
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800585 EXPECT_FALSE(DBusAdaptor::SetProperty(config_->mutable_store(),
586 flimflam::kAddressProperty,
587 PropertyStoreTest::kStringV,
588 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700589 EXPECT_EQ(invalid_args(), error.name());
Chris Masone43b48a12011-07-01 13:37:07 -0700590}
591
Darin Petkove7cb7f82011-06-03 13:21:51 -0700592} // namespace shill