blob: 559eb1a9a4514c5b3640307b426a6d6302bed124 [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"
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;
26using base::Unretained;
Darin Petkove7cb7f82011-06-03 13:21:51 -070027using std::string;
28using std::vector;
Darin Petkovf7897bc2011-06-08 17:13:36 -070029using testing::_;
mukesh agrawal1835e772013-01-15 18:35:03 -080030using testing::AnyNumber;
31using testing::ContainsRegex;
Darin Petkovf7897bc2011-06-08 17:13:36 -070032using testing::Return;
33using testing::SetArgumentPointee;
Darin Petkove7cb7f82011-06-03 13:21:51 -070034using testing::Test;
35
36namespace shill {
37
Darin Petkov92c43902011-06-09 20:46:06 -070038namespace {
Darin Petkova7b89492011-07-27 12:48:17 -070039const char kDeviceName[] = "eth0";
Paul Stewartd32f4842012-01-11 16:08:13 -080040const char kHostName[] = "hostname";
Paul Stewartd408fdf2012-05-07 17:15:57 -070041const char kLeaseFileSuffix[] = "leasefilesuffix";
42const bool kArpGateway = true;
Darin Petkov92c43902011-06-09 20:46:06 -070043} // namespace {}
44
Chris Masone43b48a12011-07-01 13:37:07 -070045class DHCPConfigTest : public PropertyStoreTest {
Darin Petkove7cb7f82011-06-03 13:21:51 -070046 public:
Darin Petkovf7897bc2011-06-08 17:13:36 -070047 DHCPConfigTest()
Darin Petkovf65e9282011-06-21 14:29:56 -070048 : proxy_(new MockDHCPProxy()),
Darin Petkova7b89492011-07-27 12:48:17 -070049 proxy_factory_(this),
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070050 minijail_(new MockMinijail()),
Chris Masone19e30402011-07-19 15:48:47 -070051 config_(new DHCPConfig(&control_,
Chris Masone2176a882011-09-14 22:29:15 -070052 dispatcher(),
Chris Masone19e30402011-07-19 15:48:47 -070053 DHCPProvider::GetInstance(),
Darin Petkov92c43902011-06-09 20:46:06 -070054 kDeviceName,
Paul Stewartd32f4842012-01-11 16:08:13 -080055 kHostName,
Paul Stewartd408fdf2012-05-07 17:15:57 -070056 kLeaseFileSuffix,
57 kArpGateway,
Chris Masone2176a882011-09-14 22:29:15 -070058 glib())) {}
Darin Petkova7b89492011-07-27 12:48:17 -070059
60 virtual void SetUp() {
Darin Petkovab565bb2011-10-06 02:55:51 -070061 config_->proxy_factory_ = &proxy_factory_;
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070062 config_->minijail_ = minijail_.get();
Darin Petkova7b89492011-07-27 12:48:17 -070063 }
64
65 virtual void TearDown() {
Darin Petkovab565bb2011-10-06 02:55:51 -070066 config_->proxy_factory_ = NULL;
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070067 config_->minijail_ = NULL;
Darin Petkov98dd6a02011-06-10 15:12:57 -070068 }
Darin Petkove7cb7f82011-06-03 13:21:51 -070069
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070070 DHCPConfigRefPtr CreateMockMinijailConfig(const string &hostname,
71 const string &lease_suffix,
72 bool arp_gateway);
Paul Stewartd408fdf2012-05-07 17:15:57 -070073 DHCPConfigRefPtr CreateRunningConfig(const string &hostname,
74 const string &lease_suffix,
75 bool arp_gateway);
76 void StopRunningConfigAndExpect(DHCPConfigRefPtr config,
77 bool lease_file_exists);
78
Darin Petkove7cb7f82011-06-03 13:21:51 -070079 protected:
Darin Petkova7b89492011-07-27 12:48:17 -070080 class TestProxyFactory : public ProxyFactory {
81 public:
Paul Stewart7355ce12011-09-02 10:47:01 -070082 explicit TestProxyFactory(DHCPConfigTest *test) : test_(test) {}
Darin Petkova7b89492011-07-27 12:48:17 -070083
mukesh agrawal1830fa12011-09-26 14:31:40 -070084 virtual DHCPProxyInterface *CreateDHCPProxy(const string &/*service*/) {
Darin Petkova7b89492011-07-27 12:48:17 -070085 return test_->proxy_.release();
86 }
87
88 private:
89 DHCPConfigTest *test_;
90 };
91
Paul Stewartd408fdf2012-05-07 17:15:57 -070092 static const int kPID;
93 static const unsigned int kTag;
94
95 FilePath lease_file_;
96 FilePath pid_file_;
97 ScopedTempDir temp_dir_;
Darin Petkova7b89492011-07-27 12:48:17 -070098 scoped_ptr<MockDHCPProxy> proxy_;
99 TestProxyFactory proxy_factory_;
Chris Masone19e30402011-07-19 15:48:47 -0700100 MockControl control_;
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700101 scoped_ptr<MockMinijail> minijail_;
Darin Petkovf7897bc2011-06-08 17:13:36 -0700102 DHCPConfigRefPtr config_;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700103};
104
Paul Stewartd408fdf2012-05-07 17:15:57 -0700105const int DHCPConfigTest::kPID = 123456;
106const unsigned int DHCPConfigTest::kTag = 77;
107
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700108DHCPConfigRefPtr DHCPConfigTest::CreateMockMinijailConfig(
109 const string &hostname,
110 const string &lease_suffix,
111 bool arp_gateway) {
112 DHCPConfigRefPtr config(new DHCPConfig(&control_,
113 dispatcher(),
114 DHCPProvider::GetInstance(),
115 kDeviceName,
116 hostname,
117 lease_suffix,
118 arp_gateway,
119 glib()));
120 config->minijail_ = minijail_.get();
121 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(false));
122
123 return config;
124}
125
Paul Stewartd408fdf2012-05-07 17:15:57 -0700126DHCPConfigRefPtr DHCPConfigTest::CreateRunningConfig(const string &hostname,
127 const string &lease_suffix,
128 bool arp_gateway) {
129 DHCPConfigRefPtr config(new DHCPConfig(&control_,
130 dispatcher(),
131 DHCPProvider::GetInstance(),
132 kDeviceName,
133 hostname,
134 lease_suffix,
135 arp_gateway,
136 glib()));
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700137 config->minijail_ = minijail_.get();
138 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _))
139 .WillOnce(DoAll(SetArgumentPointee<2>(kPID), Return(true)));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700140 EXPECT_CALL(*glib(), ChildWatchAdd(kPID, _, _)).WillOnce(Return(kTag));
141 EXPECT_TRUE(config->Start());
142 EXPECT_EQ(kPID, config->pid_);
143 EXPECT_EQ(config.get(), DHCPProvider::GetInstance()->GetConfig(kPID).get());
144 EXPECT_EQ(kTag, config->child_watch_tag_);
145
146 EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
147 config->root_ = temp_dir_.path();
Jorge Lucangeli Obes2f3169d2012-04-25 11:38:25 -0700148 FilePath varrun = temp_dir_.path().Append("var/run/dhcpcd");
Paul Stewartd408fdf2012-05-07 17:15:57 -0700149 EXPECT_TRUE(file_util::CreateDirectory(varrun));
150 pid_file_ = varrun.Append(base::StringPrintf("dhcpcd-%s.pid", kDeviceName));
151 FilePath varlib = temp_dir_.path().Append("var/lib/dhcpcd");
152 EXPECT_TRUE(file_util::CreateDirectory(varlib));
153 lease_file_ =
154 varlib.Append(base::StringPrintf("dhcpcd-%s.lease", kDeviceName));
155 EXPECT_EQ(0, file_util::WriteFile(pid_file_, "", 0));
156 EXPECT_EQ(0, file_util::WriteFile(lease_file_, "", 0));
157 EXPECT_TRUE(file_util::PathExists(pid_file_));
158 EXPECT_TRUE(file_util::PathExists(lease_file_));
159
160 return config;
161}
162
163void DHCPConfigTest::StopRunningConfigAndExpect(DHCPConfigRefPtr config,
164 bool lease_file_exists) {
mukesh agrawal6c6655d2012-12-06 14:49:50 -0800165 ScopedMockLog log;
166 // We use a non-zero exit status so that we get the log message.
167 EXPECT_CALL(log, Log(_, _, ::testing::EndsWith("status 10")));
168 DHCPConfig::ChildWatchCallback(kPID, 10, config.get());
Paul Stewartd408fdf2012-05-07 17:15:57 -0700169 EXPECT_EQ(NULL, DHCPProvider::GetInstance()->GetConfig(kPID).get());
170
171 EXPECT_FALSE(file_util::PathExists(pid_file_));
172 EXPECT_EQ(lease_file_exists, file_util::PathExists(lease_file_));
173}
174
Darin Petkove7cb7f82011-06-03 13:21:51 -0700175TEST_F(DHCPConfigTest, GetIPv4AddressString) {
Darin Petkovf7897bc2011-06-08 17:13:36 -0700176 EXPECT_EQ("255.255.255.255", config_->GetIPv4AddressString(0xffffffff));
177 EXPECT_EQ("0.0.0.0", config_->GetIPv4AddressString(0));
178 EXPECT_EQ("1.2.3.4", config_->GetIPv4AddressString(0x04030201));
Darin Petkove7cb7f82011-06-03 13:21:51 -0700179}
180
Darin Petkova7b89492011-07-27 12:48:17 -0700181TEST_F(DHCPConfigTest, InitProxy) {
182 static const char kService[] = ":1.200";
Darin Petkova7b89492011-07-27 12:48:17 -0700183 EXPECT_TRUE(proxy_.get());
184 EXPECT_FALSE(config_->proxy_.get());
Eric Shienbrood9a245532012-03-07 14:20:39 -0500185 config_->InitProxy(kService);
Darin Petkova7b89492011-07-27 12:48:17 -0700186 EXPECT_FALSE(proxy_.get());
187 EXPECT_TRUE(config_->proxy_.get());
188
189 config_->InitProxy(kService);
Darin Petkova7b89492011-07-27 12:48:17 -0700190}
191
Paul Stewart65bcd082012-11-16 09:37:14 -0800192TEST_F(DHCPConfigTest, ParseClasslessStaticRoutes) {
193 const string kDefaultAddress = "0.0.0.0";
194 const string kDefaultDestination = kDefaultAddress + "/0";
195 const string kRouter0 = "10.0.0.254";
196 const string kAddress1 = "192.168.1.0";
197 const string kDestination1 = kAddress1 + "/24";
198 // Last gateway missing, leaving an odd number of parameters.
199 const string kBrokenClasslessRoutes0 = kDefaultDestination + " " + kRouter0 +
200 " " + kDestination1;
201 IPConfig::Properties properties;
202 EXPECT_FALSE(DHCPConfig::ParseClasslessStaticRoutes(kBrokenClasslessRoutes0,
203 &properties));
204 EXPECT_TRUE(properties.routes.empty());
205 EXPECT_TRUE(properties.gateway.empty());
206
207 // Gateway argument for the second route is malformed, but we were able
208 // to salvage a default gateway.
209 const string kBrokenRouter1 = "10.0.0";
210 const string kBrokenClasslessRoutes1 = kBrokenClasslessRoutes0 + " " +
211 kBrokenRouter1;
212 EXPECT_FALSE(DHCPConfig::ParseClasslessStaticRoutes(kBrokenClasslessRoutes1,
213 &properties));
214 EXPECT_TRUE(properties.routes.empty());
215 EXPECT_EQ(kRouter0, properties.gateway);
216
217 const string kRouter1 = "10.0.0.253";
218 const string kRouter2 = "10.0.0.252";
219 const string kClasslessRoutes0 = kDefaultDestination + " " + kRouter2 + " " +
220 kDestination1 + " " + kRouter1;
221 EXPECT_TRUE(DHCPConfig::ParseClasslessStaticRoutes(kClasslessRoutes0,
222 &properties));
223 // The old default route is preserved.
224 EXPECT_EQ(kRouter0, properties.gateway);
225
226 // The two routes (including the one which would have otherwise been
227 // classified as a default route) are added to the routing table.
228 EXPECT_EQ(2, properties.routes.size());
229 const IPConfig::Route &route0 = properties.routes[0];
230 EXPECT_EQ(kDefaultAddress, route0.host);
231 EXPECT_EQ("0.0.0.0", route0.netmask);
232 EXPECT_EQ(kRouter2, route0.gateway);
233
234 const IPConfig::Route &route1 = properties.routes[1];
235 EXPECT_EQ(kAddress1, route1.host);
236 EXPECT_EQ("255.255.255.0", route1.netmask);
237 EXPECT_EQ(kRouter1, route1.gateway);
238
239 // A malformed routing table should not affect the current table.
240 EXPECT_FALSE(DHCPConfig::ParseClasslessStaticRoutes(kBrokenClasslessRoutes1,
241 &properties));
242 EXPECT_EQ(2, properties.routes.size());
243 EXPECT_EQ(kRouter0, properties.gateway);
244}
245
Darin Petkove7cb7f82011-06-03 13:21:51 -0700246TEST_F(DHCPConfigTest, ParseConfiguration) {
247 DHCPConfig::Configuration conf;
248 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
249 0x01020304);
250 conf[DHCPConfig::kConfigurationKeySubnetCIDR].writer().append_byte(
251 16);
252 conf[DHCPConfig::kConfigurationKeyBroadcastAddress].writer().append_uint32(
253 0x10203040);
254 {
Darin Petkove7cb7f82011-06-03 13:21:51 -0700255 vector<unsigned int> routers;
256 routers.push_back(0x02040608);
257 routers.push_back(0x03050709);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700258 DBus::MessageIter writer =
259 conf[DHCPConfig::kConfigurationKeyRouters].writer();
Darin Petkove7cb7f82011-06-03 13:21:51 -0700260 writer << routers;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700261 }
262 {
Darin Petkove7cb7f82011-06-03 13:21:51 -0700263 vector<unsigned int> dns;
264 dns.push_back(0x09070503);
265 dns.push_back(0x08060402);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700266 DBus::MessageIter writer = conf[DHCPConfig::kConfigurationKeyDNS].writer();
Darin Petkove7cb7f82011-06-03 13:21:51 -0700267 writer << dns;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700268 }
269 conf[DHCPConfig::kConfigurationKeyDomainName].writer().append_string(
270 "domain-name");
271 {
Darin Petkove7cb7f82011-06-03 13:21:51 -0700272 vector<string> search;
273 search.push_back("foo.com");
274 search.push_back("bar.com");
Darin Petkovf7897bc2011-06-08 17:13:36 -0700275 DBus::MessageIter writer =
276 conf[DHCPConfig::kConfigurationKeyDomainSearch].writer();
Darin Petkove7cb7f82011-06-03 13:21:51 -0700277 writer << search;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700278 }
279 conf[DHCPConfig::kConfigurationKeyMTU].writer().append_uint16(600);
280 conf["UnknownKey"] = DBus::Variant();
281
Darin Petkove7cb7f82011-06-03 13:21:51 -0700282 IPConfig::Properties properties;
Darin Petkovf7897bc2011-06-08 17:13:36 -0700283 ASSERT_TRUE(config_->ParseConfiguration(conf, &properties));
Darin Petkove7cb7f82011-06-03 13:21:51 -0700284 EXPECT_EQ("4.3.2.1", properties.address);
Paul Stewart48100b02012-03-19 07:53:52 -0700285 EXPECT_EQ(16, properties.subnet_prefix);
Darin Petkove7cb7f82011-06-03 13:21:51 -0700286 EXPECT_EQ("64.48.32.16", properties.broadcast_address);
287 EXPECT_EQ("8.6.4.2", properties.gateway);
288 ASSERT_EQ(2, properties.dns_servers.size());
289 EXPECT_EQ("3.5.7.9", properties.dns_servers[0]);
290 EXPECT_EQ("2.4.6.8", properties.dns_servers[1]);
291 EXPECT_EQ("domain-name", properties.domain_name);
292 ASSERT_EQ(2, properties.domain_search.size());
293 EXPECT_EQ("foo.com", properties.domain_search[0]);
294 EXPECT_EQ("bar.com", properties.domain_search[1]);
295 EXPECT_EQ(600, properties.mtu);
296}
297
Darin Petkov92c43902011-06-09 20:46:06 -0700298TEST_F(DHCPConfigTest, StartFail) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700299 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(false));
Chris Masone2176a882011-09-14 22:29:15 -0700300 EXPECT_CALL(*glib(), ChildWatchAdd(_, _, _)).Times(0);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700301 EXPECT_FALSE(config_->Start());
302 EXPECT_EQ(0, config_->pid_);
Darin Petkov92c43902011-06-09 20:46:06 -0700303}
Darin Petkovf7897bc2011-06-08 17:13:36 -0700304
Paul Stewartd408fdf2012-05-07 17:15:57 -0700305MATCHER_P3(IsDHCPCDArgs, has_hostname, has_arp_gateway, has_lease_suffix, "") {
Paul Stewartd32f4842012-01-11 16:08:13 -0800306 if (string(arg[0]) != "/sbin/dhcpcd" ||
Paul Stewartd408fdf2012-05-07 17:15:57 -0700307 string(arg[1]) != "-B") {
Paul Stewartd32f4842012-01-11 16:08:13 -0800308 return false;
309 }
310
Paul Stewartd408fdf2012-05-07 17:15:57 -0700311 int end_offset = 2;
Paul Stewartd32f4842012-01-11 16:08:13 -0800312 if (has_hostname) {
Paul Stewartd408fdf2012-05-07 17:15:57 -0700313 if (string(arg[end_offset]) != "-h" ||
314 string(arg[end_offset + 1]) != kHostName) {
Paul Stewartd32f4842012-01-11 16:08:13 -0800315 return false;
316 }
Paul Stewartd408fdf2012-05-07 17:15:57 -0700317 end_offset += 2;
Paul Stewartd32f4842012-01-11 16:08:13 -0800318 }
319
Paul Stewartd408fdf2012-05-07 17:15:57 -0700320 if (has_arp_gateway) {
321 if (string(arg[end_offset]) != "-R")
322 return false;
323 ++end_offset;
324 }
325
326 string device_arg = has_lease_suffix ?
327 string(kDeviceName) + "=" + string(kLeaseFileSuffix) : kDeviceName;
328 return string(arg[end_offset]) == device_arg && arg[end_offset + 1] == NULL;
Paul Stewartd32f4842012-01-11 16:08:13 -0800329}
330
331TEST_F(DHCPConfigTest, StartWithHostname) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700332 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(false));
Paul Stewartd32f4842012-01-11 16:08:13 -0800333 EXPECT_FALSE(config_->Start());
334}
335
336TEST_F(DHCPConfigTest, StartWithoutHostname) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700337 DHCPConfigRefPtr config = CreateMockMinijailConfig("",
338 kLeaseFileSuffix,
339 kArpGateway);
Paul Stewartd408fdf2012-05-07 17:15:57 -0700340 EXPECT_FALSE(config->Start());
341}
342
343TEST_F(DHCPConfigTest, StartWithoutArpGateway) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700344 DHCPConfigRefPtr config = CreateMockMinijailConfig(kHostName,
345 kLeaseFileSuffix,
346 false);
Paul Stewartd408fdf2012-05-07 17:15:57 -0700347 EXPECT_FALSE(config->Start());
348}
349
350TEST_F(DHCPConfigTest, StartWithoutLeaseSuffix) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700351 DHCPConfigRefPtr config = CreateMockMinijailConfig(kHostName,
352 kDeviceName,
353 kArpGateway);
Paul Stewartd32f4842012-01-11 16:08:13 -0800354 EXPECT_FALSE(config->Start());
355}
356
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700357namespace {
358
359class UpdateCallbackTest {
360 public:
361 UpdateCallbackTest(const string &message,
Chris Masone2b105542011-06-22 10:58:09 -0700362 const IPConfigRefPtr &ipconfig,
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700363 bool success)
364 : message_(message),
365 ipconfig_(ipconfig),
366 success_(success),
367 called_(false) {}
368
Chris Masone2b105542011-06-22 10:58:09 -0700369 void Callback(const IPConfigRefPtr &ipconfig, bool success) {
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700370 called_ = true;
371 EXPECT_EQ(ipconfig_.get(), ipconfig.get()) << message_;
372 EXPECT_EQ(success_, success) << message_;
373 }
374
375 bool called() const { return called_; }
376
377 private:
378 const string message_;
379 IPConfigRefPtr ipconfig_;
380 bool success_;
381 bool called_;
382};
383
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700384void DoNothing() {}
385
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700386} // namespace {}
387
388TEST_F(DHCPConfigTest, ProcessEventSignalFail) {
389 DHCPConfig::Configuration conf;
390 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
391 0x01020304);
392 UpdateCallbackTest callback_test(DHCPConfig::kReasonFail, config_, false);
393 config_->RegisterUpdateCallback(
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500394 Bind(&UpdateCallbackTest::Callback, Unretained(&callback_test)));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700395 config_->lease_acquisition_timeout_callback_.Reset(base::Bind(&DoNothing));
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700396 config_->ProcessEventSignal(DHCPConfig::kReasonFail, conf);
397 EXPECT_TRUE(callback_test.called());
398 EXPECT_TRUE(config_->properties().address.empty());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700399 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700400}
401
402TEST_F(DHCPConfigTest, ProcessEventSignalSuccess) {
403 static const char * const kReasons[] = {
404 DHCPConfig::kReasonBound,
405 DHCPConfig::kReasonRebind,
406 DHCPConfig::kReasonReboot,
407 DHCPConfig::kReasonRenew
408 };
409 for (size_t r = 0; r < arraysize(kReasons); r++) {
410 DHCPConfig::Configuration conf;
411 string message = string(kReasons[r]) + " failed";
412 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(r);
413 UpdateCallbackTest callback_test(message, config_, true);
414 config_->RegisterUpdateCallback(
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500415 Bind(&UpdateCallbackTest::Callback, Unretained(&callback_test)));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700416 config_->lease_acquisition_timeout_callback_.Reset(base::Bind(&DoNothing));
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700417 config_->ProcessEventSignal(kReasons[r], conf);
418 EXPECT_TRUE(callback_test.called()) << message;
Paul Stewart83224402011-11-30 14:52:30 -0800419 EXPECT_EQ(base::StringPrintf("%zu.0.0.0", r), config_->properties().address)
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700420 << message;
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700421 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700422 }
423}
424
425TEST_F(DHCPConfigTest, ProcessEventSignalUnknown) {
426 DHCPConfig::Configuration conf;
427 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
428 0x01020304);
429 static const char kReasonUnknown[] = "UNKNOWN_REASON";
430 UpdateCallbackTest callback_test(kReasonUnknown, config_, false);
431 config_->RegisterUpdateCallback(
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500432 Bind(&UpdateCallbackTest::Callback, Unretained(&callback_test)));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700433 config_->lease_acquisition_timeout_callback_.Reset(base::Bind(&DoNothing));
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700434 config_->ProcessEventSignal(kReasonUnknown, conf);
435 EXPECT_FALSE(callback_test.called());
436 EXPECT_TRUE(config_->properties().address.empty());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700437 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700438}
439
440
Darin Petkov98dd6a02011-06-10 15:12:57 -0700441TEST_F(DHCPConfigTest, ReleaseIP) {
442 config_->pid_ = 1 << 18; // Ensure unknown positive PID.
Paul Stewarta02ee492012-05-16 10:04:53 -0700443 config_->arp_gateway_ = false;
Darin Petkovaceede32011-07-18 15:32:38 -0700444 EXPECT_CALL(*proxy_, Release(kDeviceName)).Times(1);
Darin Petkova7b89492011-07-27 12:48:17 -0700445 config_->proxy_.reset(proxy_.release());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700446 EXPECT_TRUE(config_->ReleaseIP());
447 config_->pid_ = 0;
448}
449
Paul Stewarta02ee492012-05-16 10:04:53 -0700450TEST_F(DHCPConfigTest, ReleaseIPArpGW) {
451 config_->pid_ = 1 << 18; // Ensure unknown positive PID.
452 config_->arp_gateway_ = true;
453 EXPECT_CALL(*proxy_, Release(kDeviceName)).Times(0);
454 config_->proxy_.reset(proxy_.release());
455 EXPECT_TRUE(config_->ReleaseIP());
456 config_->pid_ = 0;
457}
458
Darin Petkov98dd6a02011-06-10 15:12:57 -0700459TEST_F(DHCPConfigTest, RenewIP) {
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700460 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700461 config_->pid_ = 456;
Paul Stewartc02344a2012-08-17 16:57:37 -0700462 EXPECT_FALSE(config_->RenewIP()); // Expect no crash with NULL proxy.
Darin Petkovaceede32011-07-18 15:32:38 -0700463 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
Darin Petkova7b89492011-07-27 12:48:17 -0700464 config_->proxy_.reset(proxy_.release());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700465 EXPECT_TRUE(config_->RenewIP());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700466 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700467 config_->pid_ = 0;
468}
469
470TEST_F(DHCPConfigTest, RequestIP) {
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700471 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700472 config_->pid_ = 567;
Darin Petkovaceede32011-07-18 15:32:38 -0700473 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
Darin Petkova7b89492011-07-27 12:48:17 -0700474 config_->proxy_.reset(proxy_.release());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700475 EXPECT_TRUE(config_->RenewIP());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700476 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
477 config_->pid_ = 0;
478}
479
480TEST_F(DHCPConfigTest, RequestIPTimeout) {
481 UpdateCallbackTest callback_test(DHCPConfig::kReasonFail, config_, false);
482 config_->RegisterUpdateCallback(
483 Bind(&UpdateCallbackTest::Callback, Unretained(&callback_test)));
484 config_->lease_acquisition_timeout_seconds_ = 0;
485 config_->pid_ = 567;
486 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
487 config_->proxy_.reset(proxy_.release());
488 config_->RenewIP();
489 config_->dispatcher_->DispatchPendingEvents();
490 EXPECT_TRUE(callback_test.called());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700491 config_->pid_ = 0;
492}
493
494TEST_F(DHCPConfigTest, Restart) {
495 const int kPID1 = 1 << 17; // Ensure unknown positive PID.
496 const int kPID2 = 987;
497 const unsigned int kTag1 = 11;
498 const unsigned int kTag2 = 22;
499 config_->pid_ = kPID1;
500 config_->child_watch_tag_ = kTag1;
501 DHCPProvider::GetInstance()->BindPID(kPID1, config_);
Chris Masone2176a882011-09-14 22:29:15 -0700502 EXPECT_CALL(*glib(), SourceRemove(kTag1)).WillOnce(Return(true));
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700503 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(
504 DoAll(SetArgumentPointee<2>(kPID2), Return(true)));
Chris Masone2176a882011-09-14 22:29:15 -0700505 EXPECT_CALL(*glib(), ChildWatchAdd(kPID2, _, _)).WillOnce(Return(kTag2));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700506 EXPECT_TRUE(config_->Restart());
507 EXPECT_EQ(kPID2, config_->pid_);
508 EXPECT_EQ(config_.get(), DHCPProvider::GetInstance()->GetConfig(kPID2).get());
509 EXPECT_EQ(kTag2, config_->child_watch_tag_);
510 DHCPProvider::GetInstance()->UnbindPID(kPID2);
511 config_->pid_ = 0;
512 config_->child_watch_tag_ = 0;
513}
514
515TEST_F(DHCPConfigTest, RestartNoClient) {
516 const int kPID = 777;
517 const unsigned int kTag = 66;
Chris Masone2176a882011-09-14 22:29:15 -0700518 EXPECT_CALL(*glib(), SourceRemove(_)).Times(0);
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700519 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(
520 DoAll(SetArgumentPointee<2>(kPID), Return(true)));
Chris Masone2176a882011-09-14 22:29:15 -0700521 EXPECT_CALL(*glib(), ChildWatchAdd(kPID, _, _)).WillOnce(Return(kTag));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700522 EXPECT_TRUE(config_->Restart());
523 EXPECT_EQ(kPID, config_->pid_);
524 EXPECT_EQ(config_.get(), DHCPProvider::GetInstance()->GetConfig(kPID).get());
525 EXPECT_EQ(kTag, config_->child_watch_tag_);
526 DHCPProvider::GetInstance()->UnbindPID(kPID);
527 config_->pid_ = 0;
528 config_->child_watch_tag_ = 0;
529}
530
Paul Stewartd408fdf2012-05-07 17:15:57 -0700531TEST_F(DHCPConfigTest, StartSuccessEphemeral) {
532 DHCPConfigRefPtr config =
533 CreateRunningConfig(kHostName, kDeviceName, kArpGateway);
534 StopRunningConfigAndExpect(config, false);
535}
Darin Petkov92c43902011-06-09 20:46:06 -0700536
Paul Stewartd408fdf2012-05-07 17:15:57 -0700537TEST_F(DHCPConfigTest, StartSuccessPersistent) {
538 DHCPConfigRefPtr config =
539 CreateRunningConfig(kHostName, kLeaseFileSuffix, kArpGateway);
540 StopRunningConfigAndExpect(config, true);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700541}
542
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700543TEST_F(DHCPConfigTest, StartTimeout) {
544 UpdateCallbackTest callback_test(DHCPConfig::kReasonFail, config_, false);
545 config_->RegisterUpdateCallback(
546 Bind(&UpdateCallbackTest::Callback, Unretained(&callback_test)));
547 config_->lease_acquisition_timeout_seconds_ = 0;
548 config_->proxy_.reset(proxy_.release());
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700549 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(true));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700550 config_->Start();
551 config_->dispatcher_->DispatchPendingEvents();
552 EXPECT_TRUE(callback_test.called());
553}
554
Darin Petkov98dd6a02011-06-10 15:12:57 -0700555TEST_F(DHCPConfigTest, Stop) {
556 // Ensure no crashes.
557 const int kPID = 1 << 17; // Ensure unknown positive PID.
mukesh agrawal1835e772013-01-15 18:35:03 -0800558 ScopedMockLog log;
559 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
560 EXPECT_CALL(log, Log(_, _, ContainsRegex(
561 base::StringPrintf("Terminating.+%s", __func__))));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700562 config_->pid_ = kPID;
mukesh agrawal1835e772013-01-15 18:35:03 -0800563 config_->Stop(__func__);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700564 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
565}
566
567TEST_F(DHCPConfigTest, StopDuringRequestIP) {
568 config_->pid_ = 567;
569 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
570 config_->proxy_.reset(proxy_.release());
571 EXPECT_TRUE(config_->RenewIP());
572 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
573 config_->pid_ = 0; // Keep Stop from killing a real process.
mukesh agrawal1835e772013-01-15 18:35:03 -0800574 config_->Stop(__func__);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700575 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700576}
577
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800578TEST_F(DHCPConfigTest, SetProperty) {
Chris Masone43b48a12011-07-01 13:37:07 -0700579 ::DBus::Error error;
580 // Ensure that an attempt to write a R/O property returns InvalidArgs error.
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800581 EXPECT_FALSE(DBusAdaptor::SetProperty(config_->mutable_store(),
582 flimflam::kAddressProperty,
583 PropertyStoreTest::kStringV,
584 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700585 EXPECT_EQ(invalid_args(), error.name());
Chris Masone43b48a12011-07-01 13:37:07 -0700586}
587
Darin Petkove7cb7f82011-06-03 13:21:51 -0700588} // namespace shill