blob: dc7bb00aa18b961255766cdc5301baf7dfdf1fe6 [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>
Eric Shienbrood3e20a232012-02-16 11:35:56 -05009#include <base/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"
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070020#include "shill/mock_minijail.h"
Chris Masone43b48a12011-07-01 13:37:07 -070021#include "shill/property_store_unittest.h"
Darin Petkova7b89492011-07-27 12:48:17 -070022#include "shill/proxy_factory.h"
Darin Petkove7cb7f82011-06-03 13:21:51 -070023
Eric Shienbrood3e20a232012-02-16 11:35:56 -050024using base::Bind;
25using base::Unretained;
Darin Petkove7cb7f82011-06-03 13:21:51 -070026using std::string;
27using std::vector;
Darin Petkovf7897bc2011-06-08 17:13:36 -070028using testing::_;
29using testing::Return;
30using testing::SetArgumentPointee;
Darin Petkove7cb7f82011-06-03 13:21:51 -070031using testing::Test;
32
33namespace shill {
34
Darin Petkov92c43902011-06-09 20:46:06 -070035namespace {
Darin Petkova7b89492011-07-27 12:48:17 -070036const char kDeviceName[] = "eth0";
Paul Stewartd32f4842012-01-11 16:08:13 -080037const char kHostName[] = "hostname";
Paul Stewartd408fdf2012-05-07 17:15:57 -070038const char kLeaseFileSuffix[] = "leasefilesuffix";
39const bool kArpGateway = true;
Darin Petkov92c43902011-06-09 20:46:06 -070040} // namespace {}
41
Chris Masone43b48a12011-07-01 13:37:07 -070042class DHCPConfigTest : public PropertyStoreTest {
Darin Petkove7cb7f82011-06-03 13:21:51 -070043 public:
Darin Petkovf7897bc2011-06-08 17:13:36 -070044 DHCPConfigTest()
Darin Petkovf65e9282011-06-21 14:29:56 -070045 : proxy_(new MockDHCPProxy()),
Darin Petkova7b89492011-07-27 12:48:17 -070046 proxy_factory_(this),
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070047 minijail_(new MockMinijail()),
Chris Masone19e30402011-07-19 15:48:47 -070048 config_(new DHCPConfig(&control_,
Chris Masone2176a882011-09-14 22:29:15 -070049 dispatcher(),
Chris Masone19e30402011-07-19 15:48:47 -070050 DHCPProvider::GetInstance(),
Darin Petkov92c43902011-06-09 20:46:06 -070051 kDeviceName,
Paul Stewartd32f4842012-01-11 16:08:13 -080052 kHostName,
Paul Stewartd408fdf2012-05-07 17:15:57 -070053 kLeaseFileSuffix,
54 kArpGateway,
Chris Masone2176a882011-09-14 22:29:15 -070055 glib())) {}
Darin Petkova7b89492011-07-27 12:48:17 -070056
57 virtual void SetUp() {
Darin Petkovab565bb2011-10-06 02:55:51 -070058 config_->proxy_factory_ = &proxy_factory_;
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070059 config_->minijail_ = minijail_.get();
Darin Petkova7b89492011-07-27 12:48:17 -070060 }
61
62 virtual void TearDown() {
Darin Petkovab565bb2011-10-06 02:55:51 -070063 config_->proxy_factory_ = NULL;
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070064 config_->minijail_ = NULL;
Darin Petkov98dd6a02011-06-10 15:12:57 -070065 }
Darin Petkove7cb7f82011-06-03 13:21:51 -070066
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070067 DHCPConfigRefPtr CreateMockMinijailConfig(const string &hostname,
68 const string &lease_suffix,
69 bool arp_gateway);
Paul Stewartd408fdf2012-05-07 17:15:57 -070070 DHCPConfigRefPtr CreateRunningConfig(const string &hostname,
71 const string &lease_suffix,
72 bool arp_gateway);
73 void StopRunningConfigAndExpect(DHCPConfigRefPtr config,
74 bool lease_file_exists);
75
Darin Petkove7cb7f82011-06-03 13:21:51 -070076 protected:
Darin Petkova7b89492011-07-27 12:48:17 -070077 class TestProxyFactory : public ProxyFactory {
78 public:
Paul Stewart7355ce12011-09-02 10:47:01 -070079 explicit TestProxyFactory(DHCPConfigTest *test) : test_(test) {}
Darin Petkova7b89492011-07-27 12:48:17 -070080
mukesh agrawal1830fa12011-09-26 14:31:40 -070081 virtual DHCPProxyInterface *CreateDHCPProxy(const string &/*service*/) {
Darin Petkova7b89492011-07-27 12:48:17 -070082 return test_->proxy_.release();
83 }
84
85 private:
86 DHCPConfigTest *test_;
87 };
88
Paul Stewartd408fdf2012-05-07 17:15:57 -070089 static const int kPID;
90 static const unsigned int kTag;
91
92 FilePath lease_file_;
93 FilePath pid_file_;
94 ScopedTempDir temp_dir_;
Darin Petkova7b89492011-07-27 12:48:17 -070095 scoped_ptr<MockDHCPProxy> proxy_;
96 TestProxyFactory proxy_factory_;
Chris Masone19e30402011-07-19 15:48:47 -070097 MockControl control_;
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070098 scoped_ptr<MockMinijail> minijail_;
Darin Petkovf7897bc2011-06-08 17:13:36 -070099 DHCPConfigRefPtr config_;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700100};
101
Paul Stewartd408fdf2012-05-07 17:15:57 -0700102const int DHCPConfigTest::kPID = 123456;
103const unsigned int DHCPConfigTest::kTag = 77;
104
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700105DHCPConfigRefPtr DHCPConfigTest::CreateMockMinijailConfig(
106 const string &hostname,
107 const string &lease_suffix,
108 bool arp_gateway) {
109 DHCPConfigRefPtr config(new DHCPConfig(&control_,
110 dispatcher(),
111 DHCPProvider::GetInstance(),
112 kDeviceName,
113 hostname,
114 lease_suffix,
115 arp_gateway,
116 glib()));
117 config->minijail_ = minijail_.get();
118 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(false));
119
120 return config;
121}
122
Paul Stewartd408fdf2012-05-07 17:15:57 -0700123DHCPConfigRefPtr DHCPConfigTest::CreateRunningConfig(const string &hostname,
124 const string &lease_suffix,
125 bool arp_gateway) {
126 DHCPConfigRefPtr config(new DHCPConfig(&control_,
127 dispatcher(),
128 DHCPProvider::GetInstance(),
129 kDeviceName,
130 hostname,
131 lease_suffix,
132 arp_gateway,
133 glib()));
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700134 config->minijail_ = minijail_.get();
135 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _))
136 .WillOnce(DoAll(SetArgumentPointee<2>(kPID), Return(true)));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700137 EXPECT_CALL(*glib(), ChildWatchAdd(kPID, _, _)).WillOnce(Return(kTag));
138 EXPECT_TRUE(config->Start());
139 EXPECT_EQ(kPID, config->pid_);
140 EXPECT_EQ(config.get(), DHCPProvider::GetInstance()->GetConfig(kPID).get());
141 EXPECT_EQ(kTag, config->child_watch_tag_);
142
143 EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
144 config->root_ = temp_dir_.path();
Jorge Lucangeli Obes2f3169d2012-04-25 11:38:25 -0700145 FilePath varrun = temp_dir_.path().Append("var/run/dhcpcd");
Paul Stewartd408fdf2012-05-07 17:15:57 -0700146 EXPECT_TRUE(file_util::CreateDirectory(varrun));
147 pid_file_ = varrun.Append(base::StringPrintf("dhcpcd-%s.pid", kDeviceName));
148 FilePath varlib = temp_dir_.path().Append("var/lib/dhcpcd");
149 EXPECT_TRUE(file_util::CreateDirectory(varlib));
150 lease_file_ =
151 varlib.Append(base::StringPrintf("dhcpcd-%s.lease", kDeviceName));
152 EXPECT_EQ(0, file_util::WriteFile(pid_file_, "", 0));
153 EXPECT_EQ(0, file_util::WriteFile(lease_file_, "", 0));
154 EXPECT_TRUE(file_util::PathExists(pid_file_));
155 EXPECT_TRUE(file_util::PathExists(lease_file_));
156
157 return config;
158}
159
160void DHCPConfigTest::StopRunningConfigAndExpect(DHCPConfigRefPtr config,
161 bool lease_file_exists) {
Paul Stewartd408fdf2012-05-07 17:15:57 -0700162 DHCPConfig::ChildWatchCallback(kPID, 0, config.get());
163 EXPECT_EQ(NULL, DHCPProvider::GetInstance()->GetConfig(kPID).get());
164
165 EXPECT_FALSE(file_util::PathExists(pid_file_));
166 EXPECT_EQ(lease_file_exists, file_util::PathExists(lease_file_));
167}
168
Darin Petkove7cb7f82011-06-03 13:21:51 -0700169TEST_F(DHCPConfigTest, GetIPv4AddressString) {
Darin Petkovf7897bc2011-06-08 17:13:36 -0700170 EXPECT_EQ("255.255.255.255", config_->GetIPv4AddressString(0xffffffff));
171 EXPECT_EQ("0.0.0.0", config_->GetIPv4AddressString(0));
172 EXPECT_EQ("1.2.3.4", config_->GetIPv4AddressString(0x04030201));
Darin Petkove7cb7f82011-06-03 13:21:51 -0700173}
174
Darin Petkova7b89492011-07-27 12:48:17 -0700175TEST_F(DHCPConfigTest, InitProxy) {
176 static const char kService[] = ":1.200";
Darin Petkova7b89492011-07-27 12:48:17 -0700177 EXPECT_TRUE(proxy_.get());
178 EXPECT_FALSE(config_->proxy_.get());
Eric Shienbrood9a245532012-03-07 14:20:39 -0500179 config_->InitProxy(kService);
Darin Petkova7b89492011-07-27 12:48:17 -0700180 EXPECT_FALSE(proxy_.get());
181 EXPECT_TRUE(config_->proxy_.get());
182
183 config_->InitProxy(kService);
Darin Petkova7b89492011-07-27 12:48:17 -0700184}
185
Paul Stewart65bcd082012-11-16 09:37:14 -0800186TEST_F(DHCPConfigTest, ParseClasslessStaticRoutes) {
187 const string kDefaultAddress = "0.0.0.0";
188 const string kDefaultDestination = kDefaultAddress + "/0";
189 const string kRouter0 = "10.0.0.254";
190 const string kAddress1 = "192.168.1.0";
191 const string kDestination1 = kAddress1 + "/24";
192 // Last gateway missing, leaving an odd number of parameters.
193 const string kBrokenClasslessRoutes0 = kDefaultDestination + " " + kRouter0 +
194 " " + kDestination1;
195 IPConfig::Properties properties;
196 EXPECT_FALSE(DHCPConfig::ParseClasslessStaticRoutes(kBrokenClasslessRoutes0,
197 &properties));
198 EXPECT_TRUE(properties.routes.empty());
199 EXPECT_TRUE(properties.gateway.empty());
200
201 // Gateway argument for the second route is malformed, but we were able
202 // to salvage a default gateway.
203 const string kBrokenRouter1 = "10.0.0";
204 const string kBrokenClasslessRoutes1 = kBrokenClasslessRoutes0 + " " +
205 kBrokenRouter1;
206 EXPECT_FALSE(DHCPConfig::ParseClasslessStaticRoutes(kBrokenClasslessRoutes1,
207 &properties));
208 EXPECT_TRUE(properties.routes.empty());
209 EXPECT_EQ(kRouter0, properties.gateway);
210
211 const string kRouter1 = "10.0.0.253";
212 const string kRouter2 = "10.0.0.252";
213 const string kClasslessRoutes0 = kDefaultDestination + " " + kRouter2 + " " +
214 kDestination1 + " " + kRouter1;
215 EXPECT_TRUE(DHCPConfig::ParseClasslessStaticRoutes(kClasslessRoutes0,
216 &properties));
217 // The old default route is preserved.
218 EXPECT_EQ(kRouter0, properties.gateway);
219
220 // The two routes (including the one which would have otherwise been
221 // classified as a default route) are added to the routing table.
222 EXPECT_EQ(2, properties.routes.size());
223 const IPConfig::Route &route0 = properties.routes[0];
224 EXPECT_EQ(kDefaultAddress, route0.host);
225 EXPECT_EQ("0.0.0.0", route0.netmask);
226 EXPECT_EQ(kRouter2, route0.gateway);
227
228 const IPConfig::Route &route1 = properties.routes[1];
229 EXPECT_EQ(kAddress1, route1.host);
230 EXPECT_EQ("255.255.255.0", route1.netmask);
231 EXPECT_EQ(kRouter1, route1.gateway);
232
233 // A malformed routing table should not affect the current table.
234 EXPECT_FALSE(DHCPConfig::ParseClasslessStaticRoutes(kBrokenClasslessRoutes1,
235 &properties));
236 EXPECT_EQ(2, properties.routes.size());
237 EXPECT_EQ(kRouter0, properties.gateway);
238}
239
Darin Petkove7cb7f82011-06-03 13:21:51 -0700240TEST_F(DHCPConfigTest, ParseConfiguration) {
241 DHCPConfig::Configuration conf;
242 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
243 0x01020304);
244 conf[DHCPConfig::kConfigurationKeySubnetCIDR].writer().append_byte(
245 16);
246 conf[DHCPConfig::kConfigurationKeyBroadcastAddress].writer().append_uint32(
247 0x10203040);
248 {
Darin Petkove7cb7f82011-06-03 13:21:51 -0700249 vector<unsigned int> routers;
250 routers.push_back(0x02040608);
251 routers.push_back(0x03050709);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700252 DBus::MessageIter writer =
253 conf[DHCPConfig::kConfigurationKeyRouters].writer();
Darin Petkove7cb7f82011-06-03 13:21:51 -0700254 writer << routers;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700255 }
256 {
Darin Petkove7cb7f82011-06-03 13:21:51 -0700257 vector<unsigned int> dns;
258 dns.push_back(0x09070503);
259 dns.push_back(0x08060402);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700260 DBus::MessageIter writer = conf[DHCPConfig::kConfigurationKeyDNS].writer();
Darin Petkove7cb7f82011-06-03 13:21:51 -0700261 writer << dns;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700262 }
263 conf[DHCPConfig::kConfigurationKeyDomainName].writer().append_string(
264 "domain-name");
265 {
Darin Petkove7cb7f82011-06-03 13:21:51 -0700266 vector<string> search;
267 search.push_back("foo.com");
268 search.push_back("bar.com");
Darin Petkovf7897bc2011-06-08 17:13:36 -0700269 DBus::MessageIter writer =
270 conf[DHCPConfig::kConfigurationKeyDomainSearch].writer();
Darin Petkove7cb7f82011-06-03 13:21:51 -0700271 writer << search;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700272 }
273 conf[DHCPConfig::kConfigurationKeyMTU].writer().append_uint16(600);
274 conf["UnknownKey"] = DBus::Variant();
275
Darin Petkove7cb7f82011-06-03 13:21:51 -0700276 IPConfig::Properties properties;
Darin Petkovf7897bc2011-06-08 17:13:36 -0700277 ASSERT_TRUE(config_->ParseConfiguration(conf, &properties));
Darin Petkove7cb7f82011-06-03 13:21:51 -0700278 EXPECT_EQ("4.3.2.1", properties.address);
Paul Stewart48100b02012-03-19 07:53:52 -0700279 EXPECT_EQ(16, properties.subnet_prefix);
Darin Petkove7cb7f82011-06-03 13:21:51 -0700280 EXPECT_EQ("64.48.32.16", properties.broadcast_address);
281 EXPECT_EQ("8.6.4.2", properties.gateway);
282 ASSERT_EQ(2, properties.dns_servers.size());
283 EXPECT_EQ("3.5.7.9", properties.dns_servers[0]);
284 EXPECT_EQ("2.4.6.8", properties.dns_servers[1]);
285 EXPECT_EQ("domain-name", properties.domain_name);
286 ASSERT_EQ(2, properties.domain_search.size());
287 EXPECT_EQ("foo.com", properties.domain_search[0]);
288 EXPECT_EQ("bar.com", properties.domain_search[1]);
289 EXPECT_EQ(600, properties.mtu);
290}
291
Darin Petkov92c43902011-06-09 20:46:06 -0700292TEST_F(DHCPConfigTest, StartFail) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700293 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(false));
Chris Masone2176a882011-09-14 22:29:15 -0700294 EXPECT_CALL(*glib(), ChildWatchAdd(_, _, _)).Times(0);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700295 EXPECT_FALSE(config_->Start());
296 EXPECT_EQ(0, config_->pid_);
Darin Petkov92c43902011-06-09 20:46:06 -0700297}
Darin Petkovf7897bc2011-06-08 17:13:36 -0700298
Paul Stewartd408fdf2012-05-07 17:15:57 -0700299MATCHER_P3(IsDHCPCDArgs, has_hostname, has_arp_gateway, has_lease_suffix, "") {
Paul Stewartd32f4842012-01-11 16:08:13 -0800300 if (string(arg[0]) != "/sbin/dhcpcd" ||
Paul Stewartd408fdf2012-05-07 17:15:57 -0700301 string(arg[1]) != "-B") {
Paul Stewartd32f4842012-01-11 16:08:13 -0800302 return false;
303 }
304
Paul Stewartd408fdf2012-05-07 17:15:57 -0700305 int end_offset = 2;
Paul Stewartd32f4842012-01-11 16:08:13 -0800306 if (has_hostname) {
Paul Stewartd408fdf2012-05-07 17:15:57 -0700307 if (string(arg[end_offset]) != "-h" ||
308 string(arg[end_offset + 1]) != kHostName) {
Paul Stewartd32f4842012-01-11 16:08:13 -0800309 return false;
310 }
Paul Stewartd408fdf2012-05-07 17:15:57 -0700311 end_offset += 2;
Paul Stewartd32f4842012-01-11 16:08:13 -0800312 }
313
Paul Stewartd408fdf2012-05-07 17:15:57 -0700314 if (has_arp_gateway) {
315 if (string(arg[end_offset]) != "-R")
316 return false;
317 ++end_offset;
318 }
319
320 string device_arg = has_lease_suffix ?
321 string(kDeviceName) + "=" + string(kLeaseFileSuffix) : kDeviceName;
322 return string(arg[end_offset]) == device_arg && arg[end_offset + 1] == NULL;
Paul Stewartd32f4842012-01-11 16:08:13 -0800323}
324
325TEST_F(DHCPConfigTest, StartWithHostname) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700326 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(false));
Paul Stewartd32f4842012-01-11 16:08:13 -0800327 EXPECT_FALSE(config_->Start());
328}
329
330TEST_F(DHCPConfigTest, StartWithoutHostname) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700331 DHCPConfigRefPtr config = CreateMockMinijailConfig("",
332 kLeaseFileSuffix,
333 kArpGateway);
Paul Stewartd408fdf2012-05-07 17:15:57 -0700334 EXPECT_FALSE(config->Start());
335}
336
337TEST_F(DHCPConfigTest, StartWithoutArpGateway) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700338 DHCPConfigRefPtr config = CreateMockMinijailConfig(kHostName,
339 kLeaseFileSuffix,
340 false);
Paul Stewartd408fdf2012-05-07 17:15:57 -0700341 EXPECT_FALSE(config->Start());
342}
343
344TEST_F(DHCPConfigTest, StartWithoutLeaseSuffix) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700345 DHCPConfigRefPtr config = CreateMockMinijailConfig(kHostName,
346 kDeviceName,
347 kArpGateway);
Paul Stewartd32f4842012-01-11 16:08:13 -0800348 EXPECT_FALSE(config->Start());
349}
350
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700351namespace {
352
353class UpdateCallbackTest {
354 public:
355 UpdateCallbackTest(const string &message,
Chris Masone2b105542011-06-22 10:58:09 -0700356 const IPConfigRefPtr &ipconfig,
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700357 bool success)
358 : message_(message),
359 ipconfig_(ipconfig),
360 success_(success),
361 called_(false) {}
362
Chris Masone2b105542011-06-22 10:58:09 -0700363 void Callback(const IPConfigRefPtr &ipconfig, bool success) {
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700364 called_ = true;
365 EXPECT_EQ(ipconfig_.get(), ipconfig.get()) << message_;
366 EXPECT_EQ(success_, success) << message_;
367 }
368
369 bool called() const { return called_; }
370
371 private:
372 const string message_;
373 IPConfigRefPtr ipconfig_;
374 bool success_;
375 bool called_;
376};
377
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700378void DoNothing() {}
379
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700380} // namespace {}
381
382TEST_F(DHCPConfigTest, ProcessEventSignalFail) {
383 DHCPConfig::Configuration conf;
384 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
385 0x01020304);
386 UpdateCallbackTest callback_test(DHCPConfig::kReasonFail, config_, false);
387 config_->RegisterUpdateCallback(
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500388 Bind(&UpdateCallbackTest::Callback, Unretained(&callback_test)));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700389 config_->lease_acquisition_timeout_callback_.Reset(base::Bind(&DoNothing));
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700390 config_->ProcessEventSignal(DHCPConfig::kReasonFail, conf);
391 EXPECT_TRUE(callback_test.called());
392 EXPECT_TRUE(config_->properties().address.empty());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700393 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700394}
395
396TEST_F(DHCPConfigTest, ProcessEventSignalSuccess) {
397 static const char * const kReasons[] = {
398 DHCPConfig::kReasonBound,
399 DHCPConfig::kReasonRebind,
400 DHCPConfig::kReasonReboot,
401 DHCPConfig::kReasonRenew
402 };
403 for (size_t r = 0; r < arraysize(kReasons); r++) {
404 DHCPConfig::Configuration conf;
405 string message = string(kReasons[r]) + " failed";
406 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(r);
407 UpdateCallbackTest callback_test(message, config_, true);
408 config_->RegisterUpdateCallback(
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500409 Bind(&UpdateCallbackTest::Callback, Unretained(&callback_test)));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700410 config_->lease_acquisition_timeout_callback_.Reset(base::Bind(&DoNothing));
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700411 config_->ProcessEventSignal(kReasons[r], conf);
412 EXPECT_TRUE(callback_test.called()) << message;
Paul Stewart83224402011-11-30 14:52:30 -0800413 EXPECT_EQ(base::StringPrintf("%zu.0.0.0", r), config_->properties().address)
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700414 << message;
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700415 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700416 }
417}
418
419TEST_F(DHCPConfigTest, ProcessEventSignalUnknown) {
420 DHCPConfig::Configuration conf;
421 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
422 0x01020304);
423 static const char kReasonUnknown[] = "UNKNOWN_REASON";
424 UpdateCallbackTest callback_test(kReasonUnknown, config_, false);
425 config_->RegisterUpdateCallback(
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500426 Bind(&UpdateCallbackTest::Callback, Unretained(&callback_test)));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700427 config_->lease_acquisition_timeout_callback_.Reset(base::Bind(&DoNothing));
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700428 config_->ProcessEventSignal(kReasonUnknown, conf);
429 EXPECT_FALSE(callback_test.called());
430 EXPECT_TRUE(config_->properties().address.empty());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700431 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700432}
433
434
Darin Petkov98dd6a02011-06-10 15:12:57 -0700435TEST_F(DHCPConfigTest, ReleaseIP) {
436 config_->pid_ = 1 << 18; // Ensure unknown positive PID.
Paul Stewarta02ee492012-05-16 10:04:53 -0700437 config_->arp_gateway_ = false;
Darin Petkovaceede32011-07-18 15:32:38 -0700438 EXPECT_CALL(*proxy_, Release(kDeviceName)).Times(1);
Darin Petkova7b89492011-07-27 12:48:17 -0700439 config_->proxy_.reset(proxy_.release());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700440 EXPECT_TRUE(config_->ReleaseIP());
441 config_->pid_ = 0;
442}
443
Paul Stewarta02ee492012-05-16 10:04:53 -0700444TEST_F(DHCPConfigTest, ReleaseIPArpGW) {
445 config_->pid_ = 1 << 18; // Ensure unknown positive PID.
446 config_->arp_gateway_ = true;
447 EXPECT_CALL(*proxy_, Release(kDeviceName)).Times(0);
448 config_->proxy_.reset(proxy_.release());
449 EXPECT_TRUE(config_->ReleaseIP());
450 config_->pid_ = 0;
451}
452
Darin Petkov98dd6a02011-06-10 15:12:57 -0700453TEST_F(DHCPConfigTest, RenewIP) {
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700454 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700455 config_->pid_ = 456;
Paul Stewartc02344a2012-08-17 16:57:37 -0700456 EXPECT_FALSE(config_->RenewIP()); // Expect no crash with NULL proxy.
Darin Petkovaceede32011-07-18 15:32:38 -0700457 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
Darin Petkova7b89492011-07-27 12:48:17 -0700458 config_->proxy_.reset(proxy_.release());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700459 EXPECT_TRUE(config_->RenewIP());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700460 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700461 config_->pid_ = 0;
462}
463
464TEST_F(DHCPConfigTest, RequestIP) {
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700465 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700466 config_->pid_ = 567;
Darin Petkovaceede32011-07-18 15:32:38 -0700467 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
Darin Petkova7b89492011-07-27 12:48:17 -0700468 config_->proxy_.reset(proxy_.release());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700469 EXPECT_TRUE(config_->RenewIP());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700470 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
471 config_->pid_ = 0;
472}
473
474TEST_F(DHCPConfigTest, RequestIPTimeout) {
475 UpdateCallbackTest callback_test(DHCPConfig::kReasonFail, config_, false);
476 config_->RegisterUpdateCallback(
477 Bind(&UpdateCallbackTest::Callback, Unretained(&callback_test)));
478 config_->lease_acquisition_timeout_seconds_ = 0;
479 config_->pid_ = 567;
480 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
481 config_->proxy_.reset(proxy_.release());
482 config_->RenewIP();
483 config_->dispatcher_->DispatchPendingEvents();
484 EXPECT_TRUE(callback_test.called());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700485 config_->pid_ = 0;
486}
487
488TEST_F(DHCPConfigTest, Restart) {
489 const int kPID1 = 1 << 17; // Ensure unknown positive PID.
490 const int kPID2 = 987;
491 const unsigned int kTag1 = 11;
492 const unsigned int kTag2 = 22;
493 config_->pid_ = kPID1;
494 config_->child_watch_tag_ = kTag1;
495 DHCPProvider::GetInstance()->BindPID(kPID1, config_);
Chris Masone2176a882011-09-14 22:29:15 -0700496 EXPECT_CALL(*glib(), SourceRemove(kTag1)).WillOnce(Return(true));
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700497 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(
498 DoAll(SetArgumentPointee<2>(kPID2), Return(true)));
Chris Masone2176a882011-09-14 22:29:15 -0700499 EXPECT_CALL(*glib(), ChildWatchAdd(kPID2, _, _)).WillOnce(Return(kTag2));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700500 EXPECT_TRUE(config_->Restart());
501 EXPECT_EQ(kPID2, config_->pid_);
502 EXPECT_EQ(config_.get(), DHCPProvider::GetInstance()->GetConfig(kPID2).get());
503 EXPECT_EQ(kTag2, config_->child_watch_tag_);
504 DHCPProvider::GetInstance()->UnbindPID(kPID2);
505 config_->pid_ = 0;
506 config_->child_watch_tag_ = 0;
507}
508
509TEST_F(DHCPConfigTest, RestartNoClient) {
510 const int kPID = 777;
511 const unsigned int kTag = 66;
Chris Masone2176a882011-09-14 22:29:15 -0700512 EXPECT_CALL(*glib(), SourceRemove(_)).Times(0);
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700513 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(
514 DoAll(SetArgumentPointee<2>(kPID), Return(true)));
Chris Masone2176a882011-09-14 22:29:15 -0700515 EXPECT_CALL(*glib(), ChildWatchAdd(kPID, _, _)).WillOnce(Return(kTag));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700516 EXPECT_TRUE(config_->Restart());
517 EXPECT_EQ(kPID, config_->pid_);
518 EXPECT_EQ(config_.get(), DHCPProvider::GetInstance()->GetConfig(kPID).get());
519 EXPECT_EQ(kTag, config_->child_watch_tag_);
520 DHCPProvider::GetInstance()->UnbindPID(kPID);
521 config_->pid_ = 0;
522 config_->child_watch_tag_ = 0;
523}
524
Paul Stewartd408fdf2012-05-07 17:15:57 -0700525TEST_F(DHCPConfigTest, StartSuccessEphemeral) {
526 DHCPConfigRefPtr config =
527 CreateRunningConfig(kHostName, kDeviceName, kArpGateway);
528 StopRunningConfigAndExpect(config, false);
529}
Darin Petkov92c43902011-06-09 20:46:06 -0700530
Paul Stewartd408fdf2012-05-07 17:15:57 -0700531TEST_F(DHCPConfigTest, StartSuccessPersistent) {
532 DHCPConfigRefPtr config =
533 CreateRunningConfig(kHostName, kLeaseFileSuffix, kArpGateway);
534 StopRunningConfigAndExpect(config, true);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700535}
536
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700537TEST_F(DHCPConfigTest, StartTimeout) {
538 UpdateCallbackTest callback_test(DHCPConfig::kReasonFail, config_, false);
539 config_->RegisterUpdateCallback(
540 Bind(&UpdateCallbackTest::Callback, Unretained(&callback_test)));
541 config_->lease_acquisition_timeout_seconds_ = 0;
542 config_->proxy_.reset(proxy_.release());
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700543 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(true));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700544 config_->Start();
545 config_->dispatcher_->DispatchPendingEvents();
546 EXPECT_TRUE(callback_test.called());
547}
548
Darin Petkov98dd6a02011-06-10 15:12:57 -0700549TEST_F(DHCPConfigTest, Stop) {
550 // Ensure no crashes.
551 const int kPID = 1 << 17; // Ensure unknown positive PID.
Darin Petkov98dd6a02011-06-10 15:12:57 -0700552 config_->pid_ = kPID;
553 config_->Stop();
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700554 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
555}
556
557TEST_F(DHCPConfigTest, StopDuringRequestIP) {
558 config_->pid_ = 567;
559 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
560 config_->proxy_.reset(proxy_.release());
561 EXPECT_TRUE(config_->RenewIP());
562 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
563 config_->pid_ = 0; // Keep Stop from killing a real process.
564 config_->Stop();
565 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700566}
567
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800568TEST_F(DHCPConfigTest, SetProperty) {
Chris Masone43b48a12011-07-01 13:37:07 -0700569 ::DBus::Error error;
570 // Ensure that an attempt to write a R/O property returns InvalidArgs error.
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800571 EXPECT_FALSE(DBusAdaptor::SetProperty(config_->mutable_store(),
572 flimflam::kAddressProperty,
573 PropertyStoreTest::kStringV,
574 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700575 EXPECT_EQ(invalid_args(), error.name());
Chris Masone43b48a12011-07-01 13:37:07 -0700576}
577
Darin Petkove7cb7f82011-06-03 13:21:51 -0700578} // namespace shill