blob: 5dbaa70dd961222af0041610cb8e2fbb3481e804 [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
Alex Vakulenko8a532292014-06-16 17:18:44 -07007#include <string>
8#include <vector>
9
Eric Shienbrood3e20a232012-02-16 11:35:56 -050010#include <base/bind.h>
Darin Petkov92c43902011-06-09 20:46:06 -070011#include <base/file_util.h>
Paul Stewart5ad16062013-02-21 18:10:48 -080012#include <base/files/scoped_temp_dir.h>
Ben Chana0ddf462014-02-06 11:32:42 -080013#include <base/strings/stringprintf.h>
Chris Masone43b48a12011-07-01 13:37:07 -070014#include <chromeos/dbus/service_constants.h>
Darin Petkov92c43902011-06-09 20:46:06 -070015
Chris Masone43b48a12011-07-01 13:37:07 -070016#include "shill/dbus_adaptor.h"
Darin Petkovf7897bc2011-06-08 17:13:36 -070017#include "shill/dhcp_provider.h"
Paul Stewart26b327e2011-10-19 11:38:09 -070018#include "shill/event_dispatcher.h"
Chris Masone19e30402011-07-19 15:48:47 -070019#include "shill/mock_control.h"
Darin Petkov98dd6a02011-06-10 15:12:57 -070020#include "shill/mock_dhcp_proxy.h"
Darin Petkovf7897bc2011-06-08 17:13:36 -070021#include "shill/mock_glib.h"
mukesh agrawal6c6655d2012-12-06 14:49:50 -080022#include "shill/mock_log.h"
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070023#include "shill/mock_minijail.h"
Ben Chana55469d2014-01-27 16:35:29 -080024#include "shill/mock_proxy_factory.h"
Chris Masone43b48a12011-07-01 13:37:07 -070025#include "shill/property_store_unittest.h"
Ben Chana55469d2014-01-27 16:35:29 -080026#include "shill/testing.h"
Darin Petkove7cb7f82011-06-03 13:21:51 -070027
Eric Shienbrood3e20a232012-02-16 11:35:56 -050028using base::Bind;
Albert Chaulk0e1cdea2013-02-27 15:32:55 -080029using base::FilePath;
Paul Stewart5ad16062013-02-21 18:10:48 -080030using base::ScopedTempDir;
Eric Shienbrood3e20a232012-02-16 11:35:56 -050031using base::Unretained;
Darin Petkove7cb7f82011-06-03 13:21:51 -070032using std::string;
33using std::vector;
Darin Petkovf7897bc2011-06-08 17:13:36 -070034using testing::_;
mukesh agrawal1835e772013-01-15 18:35:03 -080035using testing::AnyNumber;
36using testing::ContainsRegex;
Paul Stewart475c0722014-04-18 08:52:00 -070037using testing::InvokeWithoutArgs;
Paul Stewart21f7b342013-11-19 10:15:58 -080038using testing::Mock;
Darin Petkovf7897bc2011-06-08 17:13:36 -070039using testing::Return;
40using testing::SetArgumentPointee;
Darin Petkove7cb7f82011-06-03 13:21:51 -070041using testing::Test;
42
43namespace shill {
44
Darin Petkov92c43902011-06-09 20:46:06 -070045namespace {
Darin Petkova7b89492011-07-27 12:48:17 -070046const char kDeviceName[] = "eth0";
Paul Stewartd32f4842012-01-11 16:08:13 -080047const char kHostName[] = "hostname";
Paul Stewartd408fdf2012-05-07 17:15:57 -070048const char kLeaseFileSuffix[] = "leasefilesuffix";
49const bool kArpGateway = true;
Paul Stewart75a68b92013-10-24 10:50:27 -070050const bool kHasHostname = true;
51const bool kHasLeaseSuffix = true;
52const bool kMinimalConfig = true;
Alex Vakulenko8a532292014-06-16 17:18:44 -070053} // namespace
Darin Petkov92c43902011-06-09 20:46:06 -070054
Chris Masone43b48a12011-07-01 13:37:07 -070055class DHCPConfigTest : public PropertyStoreTest {
Darin Petkove7cb7f82011-06-03 13:21:51 -070056 public:
Darin Petkovf7897bc2011-06-08 17:13:36 -070057 DHCPConfigTest()
Darin Petkovf65e9282011-06-21 14:29:56 -070058 : proxy_(new MockDHCPProxy()),
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070059 minijail_(new MockMinijail()),
Chris Masone19e30402011-07-19 15:48:47 -070060 config_(new DHCPConfig(&control_,
Chris Masone2176a882011-09-14 22:29:15 -070061 dispatcher(),
Chris Masone19e30402011-07-19 15:48:47 -070062 DHCPProvider::GetInstance(),
Darin Petkov92c43902011-06-09 20:46:06 -070063 kDeviceName,
Paul Stewartd32f4842012-01-11 16:08:13 -080064 kHostName,
Paul Stewartd408fdf2012-05-07 17:15:57 -070065 kLeaseFileSuffix,
66 kArpGateway,
Paul Stewart75a68b92013-10-24 10:50:27 -070067 !kMinimalConfig,
Chris Masone2176a882011-09-14 22:29:15 -070068 glib())) {}
Darin Petkova7b89492011-07-27 12:48:17 -070069
70 virtual void SetUp() {
Darin Petkovab565bb2011-10-06 02:55:51 -070071 config_->proxy_factory_ = &proxy_factory_;
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070072 config_->minijail_ = minijail_.get();
Darin Petkova7b89492011-07-27 12:48:17 -070073 }
74
75 virtual void TearDown() {
Darin Petkovab565bb2011-10-06 02:55:51 -070076 config_->proxy_factory_ = NULL;
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070077 config_->minijail_ = NULL;
Darin Petkov98dd6a02011-06-10 15:12:57 -070078 }
Darin Petkove7cb7f82011-06-03 13:21:51 -070079
Paul Stewart475c0722014-04-18 08:52:00 -070080 void StopInstance() {
81 config_->Stop("In test");
82 }
83
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070084 DHCPConfigRefPtr CreateMockMinijailConfig(const string &hostname,
Paul Stewart75a68b92013-10-24 10:50:27 -070085 const string &lease_suffix,
86 bool arp_gateway,
87 bool minimal_config);
Paul Stewartd408fdf2012-05-07 17:15:57 -070088 DHCPConfigRefPtr CreateRunningConfig(const string &hostname,
89 const string &lease_suffix,
Paul Stewart75a68b92013-10-24 10:50:27 -070090 bool arp_gateway,
91 bool minimal_config);
Paul Stewartd408fdf2012-05-07 17:15:57 -070092 void StopRunningConfigAndExpect(DHCPConfigRefPtr config,
93 bool lease_file_exists);
94
Darin Petkove7cb7f82011-06-03 13:21:51 -070095 protected:
Paul Stewartd408fdf2012-05-07 17:15:57 -070096 static const int kPID;
97 static const unsigned int kTag;
98
99 FilePath lease_file_;
100 FilePath pid_file_;
101 ScopedTempDir temp_dir_;
Darin Petkova7b89492011-07-27 12:48:17 -0700102 scoped_ptr<MockDHCPProxy> proxy_;
Ben Chana55469d2014-01-27 16:35:29 -0800103 MockProxyFactory proxy_factory_;
Chris Masone19e30402011-07-19 15:48:47 -0700104 MockControl control_;
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700105 scoped_ptr<MockMinijail> minijail_;
Darin Petkovf7897bc2011-06-08 17:13:36 -0700106 DHCPConfigRefPtr config_;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700107};
108
Paul Stewartd408fdf2012-05-07 17:15:57 -0700109const int DHCPConfigTest::kPID = 123456;
110const unsigned int DHCPConfigTest::kTag = 77;
111
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700112DHCPConfigRefPtr DHCPConfigTest::CreateMockMinijailConfig(
Paul Stewart75a68b92013-10-24 10:50:27 -0700113 const string &hostname,
114 const string &lease_suffix,
115 bool arp_gateway,
116 bool minimal_config) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700117 DHCPConfigRefPtr config(new DHCPConfig(&control_,
118 dispatcher(),
119 DHCPProvider::GetInstance(),
120 kDeviceName,
121 hostname,
122 lease_suffix,
123 arp_gateway,
Paul Stewart75a68b92013-10-24 10:50:27 -0700124 minimal_config,
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700125 glib()));
126 config->minijail_ = minijail_.get();
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700127
128 return config;
129}
130
Paul Stewart75a68b92013-10-24 10:50:27 -0700131DHCPConfigRefPtr DHCPConfigTest::CreateRunningConfig(
132 const string &hostname,
133 const string &lease_suffix,
134 bool arp_gateway,
135 bool minimal_config) {
Paul Stewartd408fdf2012-05-07 17:15:57 -0700136 DHCPConfigRefPtr config(new DHCPConfig(&control_,
137 dispatcher(),
138 DHCPProvider::GetInstance(),
139 kDeviceName,
140 hostname,
141 lease_suffix,
142 arp_gateway,
Paul Stewart75a68b92013-10-24 10:50:27 -0700143 minimal_config,
Paul Stewartd408fdf2012-05-07 17:15:57 -0700144 glib()));
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700145 config->minijail_ = minijail_.get();
146 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _))
147 .WillOnce(DoAll(SetArgumentPointee<2>(kPID), Return(true)));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700148 EXPECT_CALL(*glib(), ChildWatchAdd(kPID, _, _)).WillOnce(Return(kTag));
149 EXPECT_TRUE(config->Start());
150 EXPECT_EQ(kPID, config->pid_);
151 EXPECT_EQ(config.get(), DHCPProvider::GetInstance()->GetConfig(kPID).get());
152 EXPECT_EQ(kTag, config->child_watch_tag_);
153
154 EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
155 config->root_ = temp_dir_.path();
Jorge Lucangeli Obes2f3169d2012-04-25 11:38:25 -0700156 FilePath varrun = temp_dir_.path().Append("var/run/dhcpcd");
Ben Chana0ddf462014-02-06 11:32:42 -0800157 EXPECT_TRUE(base::CreateDirectory(varrun));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700158 pid_file_ = varrun.Append(base::StringPrintf("dhcpcd-%s.pid", kDeviceName));
159 FilePath varlib = temp_dir_.path().Append("var/lib/dhcpcd");
Ben Chana0ddf462014-02-06 11:32:42 -0800160 EXPECT_TRUE(base::CreateDirectory(varlib));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700161 lease_file_ =
162 varlib.Append(base::StringPrintf("dhcpcd-%s.lease", kDeviceName));
Ben Chan6fbf64f2014-05-21 18:07:01 -0700163 EXPECT_EQ(0, base::WriteFile(pid_file_, "", 0));
164 EXPECT_EQ(0, base::WriteFile(lease_file_, "", 0));
Ben Chana0ddf462014-02-06 11:32:42 -0800165 EXPECT_TRUE(base::PathExists(pid_file_));
166 EXPECT_TRUE(base::PathExists(lease_file_));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700167
168 return config;
169}
170
171void DHCPConfigTest::StopRunningConfigAndExpect(DHCPConfigRefPtr config,
172 bool lease_file_exists) {
mukesh agrawal6c6655d2012-12-06 14:49:50 -0800173 ScopedMockLog log;
174 // We use a non-zero exit status so that we get the log message.
175 EXPECT_CALL(log, Log(_, _, ::testing::EndsWith("status 10")));
176 DHCPConfig::ChildWatchCallback(kPID, 10, config.get());
Paul Stewartd408fdf2012-05-07 17:15:57 -0700177 EXPECT_EQ(NULL, DHCPProvider::GetInstance()->GetConfig(kPID).get());
178
Ben Chana0ddf462014-02-06 11:32:42 -0800179 EXPECT_FALSE(base::PathExists(pid_file_));
180 EXPECT_EQ(lease_file_exists, base::PathExists(lease_file_));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700181}
182
Darin Petkove7cb7f82011-06-03 13:21:51 -0700183TEST_F(DHCPConfigTest, GetIPv4AddressString) {
Darin Petkovf7897bc2011-06-08 17:13:36 -0700184 EXPECT_EQ("255.255.255.255", config_->GetIPv4AddressString(0xffffffff));
185 EXPECT_EQ("0.0.0.0", config_->GetIPv4AddressString(0));
186 EXPECT_EQ("1.2.3.4", config_->GetIPv4AddressString(0x04030201));
Darin Petkove7cb7f82011-06-03 13:21:51 -0700187}
188
Darin Petkova7b89492011-07-27 12:48:17 -0700189TEST_F(DHCPConfigTest, InitProxy) {
190 static const char kService[] = ":1.200";
Darin Petkova7b89492011-07-27 12:48:17 -0700191 EXPECT_TRUE(proxy_.get());
192 EXPECT_FALSE(config_->proxy_.get());
Ben Chana55469d2014-01-27 16:35:29 -0800193 EXPECT_CALL(proxy_factory_, CreateDHCPProxy(kService))
194 .WillOnce(ReturnAndReleasePointee(&proxy_));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500195 config_->InitProxy(kService);
Darin Petkova7b89492011-07-27 12:48:17 -0700196 EXPECT_FALSE(proxy_.get());
197 EXPECT_TRUE(config_->proxy_.get());
198
199 config_->InitProxy(kService);
Darin Petkova7b89492011-07-27 12:48:17 -0700200}
201
Paul Stewart65bcd082012-11-16 09:37:14 -0800202TEST_F(DHCPConfigTest, ParseClasslessStaticRoutes) {
203 const string kDefaultAddress = "0.0.0.0";
204 const string kDefaultDestination = kDefaultAddress + "/0";
205 const string kRouter0 = "10.0.0.254";
206 const string kAddress1 = "192.168.1.0";
207 const string kDestination1 = kAddress1 + "/24";
208 // Last gateway missing, leaving an odd number of parameters.
209 const string kBrokenClasslessRoutes0 = kDefaultDestination + " " + kRouter0 +
210 " " + kDestination1;
211 IPConfig::Properties properties;
212 EXPECT_FALSE(DHCPConfig::ParseClasslessStaticRoutes(kBrokenClasslessRoutes0,
213 &properties));
214 EXPECT_TRUE(properties.routes.empty());
215 EXPECT_TRUE(properties.gateway.empty());
216
217 // Gateway argument for the second route is malformed, but we were able
218 // to salvage a default gateway.
219 const string kBrokenRouter1 = "10.0.0";
220 const string kBrokenClasslessRoutes1 = kBrokenClasslessRoutes0 + " " +
221 kBrokenRouter1;
222 EXPECT_FALSE(DHCPConfig::ParseClasslessStaticRoutes(kBrokenClasslessRoutes1,
223 &properties));
224 EXPECT_TRUE(properties.routes.empty());
225 EXPECT_EQ(kRouter0, properties.gateway);
226
227 const string kRouter1 = "10.0.0.253";
228 const string kRouter2 = "10.0.0.252";
229 const string kClasslessRoutes0 = kDefaultDestination + " " + kRouter2 + " " +
230 kDestination1 + " " + kRouter1;
231 EXPECT_TRUE(DHCPConfig::ParseClasslessStaticRoutes(kClasslessRoutes0,
232 &properties));
233 // The old default route is preserved.
234 EXPECT_EQ(kRouter0, properties.gateway);
235
236 // The two routes (including the one which would have otherwise been
237 // classified as a default route) are added to the routing table.
238 EXPECT_EQ(2, properties.routes.size());
239 const IPConfig::Route &route0 = properties.routes[0];
240 EXPECT_EQ(kDefaultAddress, route0.host);
241 EXPECT_EQ("0.0.0.0", route0.netmask);
242 EXPECT_EQ(kRouter2, route0.gateway);
243
244 const IPConfig::Route &route1 = properties.routes[1];
245 EXPECT_EQ(kAddress1, route1.host);
246 EXPECT_EQ("255.255.255.0", route1.netmask);
247 EXPECT_EQ(kRouter1, route1.gateway);
248
249 // A malformed routing table should not affect the current table.
250 EXPECT_FALSE(DHCPConfig::ParseClasslessStaticRoutes(kBrokenClasslessRoutes1,
251 &properties));
252 EXPECT_EQ(2, properties.routes.size());
253 EXPECT_EQ(kRouter0, properties.gateway);
254}
255
Darin Petkove7cb7f82011-06-03 13:21:51 -0700256TEST_F(DHCPConfigTest, ParseConfiguration) {
257 DHCPConfig::Configuration conf;
258 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
259 0x01020304);
260 conf[DHCPConfig::kConfigurationKeySubnetCIDR].writer().append_byte(
261 16);
262 conf[DHCPConfig::kConfigurationKeyBroadcastAddress].writer().append_uint32(
263 0x10203040);
264 {
Darin Petkove7cb7f82011-06-03 13:21:51 -0700265 vector<unsigned int> routers;
266 routers.push_back(0x02040608);
267 routers.push_back(0x03050709);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700268 DBus::MessageIter writer =
269 conf[DHCPConfig::kConfigurationKeyRouters].writer();
Darin Petkove7cb7f82011-06-03 13:21:51 -0700270 writer << routers;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700271 }
272 {
Darin Petkove7cb7f82011-06-03 13:21:51 -0700273 vector<unsigned int> dns;
274 dns.push_back(0x09070503);
275 dns.push_back(0x08060402);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700276 DBus::MessageIter writer = conf[DHCPConfig::kConfigurationKeyDNS].writer();
Darin Petkove7cb7f82011-06-03 13:21:51 -0700277 writer << dns;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700278 }
279 conf[DHCPConfig::kConfigurationKeyDomainName].writer().append_string(
280 "domain-name");
281 {
Darin Petkove7cb7f82011-06-03 13:21:51 -0700282 vector<string> search;
283 search.push_back("foo.com");
284 search.push_back("bar.com");
Darin Petkovf7897bc2011-06-08 17:13:36 -0700285 DBus::MessageIter writer =
286 conf[DHCPConfig::kConfigurationKeyDomainSearch].writer();
Darin Petkove7cb7f82011-06-03 13:21:51 -0700287 writer << search;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700288 }
289 conf[DHCPConfig::kConfigurationKeyMTU].writer().append_uint16(600);
290 conf["UnknownKey"] = DBus::Variant();
291
Darin Petkove7cb7f82011-06-03 13:21:51 -0700292 IPConfig::Properties properties;
Darin Petkovf7897bc2011-06-08 17:13:36 -0700293 ASSERT_TRUE(config_->ParseConfiguration(conf, &properties));
Darin Petkove7cb7f82011-06-03 13:21:51 -0700294 EXPECT_EQ("4.3.2.1", properties.address);
Paul Stewart48100b02012-03-19 07:53:52 -0700295 EXPECT_EQ(16, properties.subnet_prefix);
Darin Petkove7cb7f82011-06-03 13:21:51 -0700296 EXPECT_EQ("64.48.32.16", properties.broadcast_address);
297 EXPECT_EQ("8.6.4.2", properties.gateway);
298 ASSERT_EQ(2, properties.dns_servers.size());
299 EXPECT_EQ("3.5.7.9", properties.dns_servers[0]);
300 EXPECT_EQ("2.4.6.8", properties.dns_servers[1]);
301 EXPECT_EQ("domain-name", properties.domain_name);
302 ASSERT_EQ(2, properties.domain_search.size());
303 EXPECT_EQ("foo.com", properties.domain_search[0]);
304 EXPECT_EQ("bar.com", properties.domain_search[1]);
305 EXPECT_EQ(600, properties.mtu);
306}
307
Darin Petkov92c43902011-06-09 20:46:06 -0700308TEST_F(DHCPConfigTest, StartFail) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700309 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(false));
Chris Masone2176a882011-09-14 22:29:15 -0700310 EXPECT_CALL(*glib(), ChildWatchAdd(_, _, _)).Times(0);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700311 EXPECT_FALSE(config_->Start());
312 EXPECT_EQ(0, config_->pid_);
Darin Petkov92c43902011-06-09 20:46:06 -0700313}
Darin Petkovf7897bc2011-06-08 17:13:36 -0700314
Paul Stewart75a68b92013-10-24 10:50:27 -0700315MATCHER_P4(IsDHCPCDArgs, has_hostname, has_arp_gateway, has_lease_suffix,
316 has_minimal_config, "") {
Paul Stewartd32f4842012-01-11 16:08:13 -0800317 if (string(arg[0]) != "/sbin/dhcpcd" ||
Paul Stewart75a68b92013-10-24 10:50:27 -0700318 string(arg[1]) != "-B" ||
319 string(arg[2]) != "-q") {
Paul Stewartd32f4842012-01-11 16:08:13 -0800320 return false;
321 }
322
Paul Stewart75a68b92013-10-24 10:50:27 -0700323 int end_offset = 3;
Paul Stewartd32f4842012-01-11 16:08:13 -0800324 if (has_hostname) {
Paul Stewartd408fdf2012-05-07 17:15:57 -0700325 if (string(arg[end_offset]) != "-h" ||
326 string(arg[end_offset + 1]) != kHostName) {
Paul Stewartd32f4842012-01-11 16:08:13 -0800327 return false;
328 }
Paul Stewartd408fdf2012-05-07 17:15:57 -0700329 end_offset += 2;
Paul Stewartd32f4842012-01-11 16:08:13 -0800330 }
331
Paul Stewartd408fdf2012-05-07 17:15:57 -0700332 if (has_arp_gateway) {
Paul Stewart75a68b92013-10-24 10:50:27 -0700333 if (string(arg[end_offset]) != "-R" ||
334 string(arg[end_offset + 1]) != "-U") {
Paul Stewartd408fdf2012-05-07 17:15:57 -0700335 return false;
Paul Stewart75a68b92013-10-24 10:50:27 -0700336 }
337 end_offset += 2;
338 }
339
340 if (has_minimal_config) {
341 if (string(arg[end_offset]) != "-f" ||
342 string(arg[end_offset + 1]) != "/etc/dhcpcd-minimal.conf") {
343 return false;
344 }
345 end_offset += 2;
Paul Stewartd408fdf2012-05-07 17:15:57 -0700346 }
347
348 string device_arg = has_lease_suffix ?
349 string(kDeviceName) + "=" + string(kLeaseFileSuffix) : kDeviceName;
350 return string(arg[end_offset]) == device_arg && arg[end_offset + 1] == NULL;
Paul Stewartd32f4842012-01-11 16:08:13 -0800351}
352
353TEST_F(DHCPConfigTest, StartWithHostname) {
Paul Stewart75a68b92013-10-24 10:50:27 -0700354 EXPECT_CALL(*minijail_, RunAndDestroy(_, IsDHCPCDArgs(kHasHostname,
355 kArpGateway,
356 kHasLeaseSuffix,
357 !kMinimalConfig), _))
358 .WillOnce(Return(false));
Paul Stewartd32f4842012-01-11 16:08:13 -0800359 EXPECT_FALSE(config_->Start());
360}
361
362TEST_F(DHCPConfigTest, StartWithoutHostname) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700363 DHCPConfigRefPtr config = CreateMockMinijailConfig("",
364 kLeaseFileSuffix,
Paul Stewart75a68b92013-10-24 10:50:27 -0700365 kArpGateway,
366 !kMinimalConfig);
367 EXPECT_CALL(*minijail_, RunAndDestroy(_, IsDHCPCDArgs(!kHasHostname,
368 kArpGateway,
369 kHasLeaseSuffix,
370 !kMinimalConfig), _))
371 .WillOnce(Return(false));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700372 EXPECT_FALSE(config->Start());
373}
374
375TEST_F(DHCPConfigTest, StartWithoutArpGateway) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700376 DHCPConfigRefPtr config = CreateMockMinijailConfig(kHostName,
377 kLeaseFileSuffix,
Paul Stewart75a68b92013-10-24 10:50:27 -0700378 !kArpGateway,
379 !kMinimalConfig);
380 EXPECT_CALL(*minijail_, RunAndDestroy(_, IsDHCPCDArgs(kHasHostname,
381 !kArpGateway,
382 kHasLeaseSuffix,
383 !kMinimalConfig), _))
384 .WillOnce(Return(false));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700385 EXPECT_FALSE(config->Start());
386}
387
388TEST_F(DHCPConfigTest, StartWithoutLeaseSuffix) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700389 DHCPConfigRefPtr config = CreateMockMinijailConfig(kHostName,
390 kDeviceName,
Paul Stewart75a68b92013-10-24 10:50:27 -0700391 kArpGateway,
392 !kMinimalConfig);
393 EXPECT_CALL(*minijail_, RunAndDestroy(_, IsDHCPCDArgs(kHasHostname,
394 kArpGateway,
395 !kHasLeaseSuffix,
396 !kMinimalConfig), _))
397 .WillOnce(Return(false));
398 EXPECT_FALSE(config->Start());
399}
400
401TEST_F(DHCPConfigTest, StartWithMinimalConfig) {
402 DHCPConfigRefPtr config = CreateMockMinijailConfig(kHostName,
403 kLeaseFileSuffix,
404 kArpGateway,
405 kMinimalConfig);
406 EXPECT_CALL(*minijail_, RunAndDestroy(_, IsDHCPCDArgs(kHasHostname,
407 kArpGateway,
408 kHasLeaseSuffix,
409 kMinimalConfig), _))
410 .WillOnce(Return(false));
Paul Stewartd32f4842012-01-11 16:08:13 -0800411 EXPECT_FALSE(config->Start());
412}
413
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700414namespace {
415
Paul Stewartc5099532013-12-12 07:53:15 -0800416class DHCPConfigCallbackTest : public DHCPConfigTest {
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700417 public:
Paul Stewartc5099532013-12-12 07:53:15 -0800418 virtual void SetUp() {
419 DHCPConfigTest::SetUp();
420 config_->RegisterUpdateCallback(
421 Bind(&DHCPConfigCallbackTest::SuccessCallback, Unretained(this)));
422 config_->RegisterFailureCallback(
423 Bind(&DHCPConfigCallbackTest::FailureCallback, Unretained(this)));
424 ip_config_ = config_;
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700425 }
426
Paul Stewartc5099532013-12-12 07:53:15 -0800427 MOCK_METHOD1(SuccessCallback, void(const IPConfigRefPtr &ipconfig));
428 MOCK_METHOD1(FailureCallback, void(const IPConfigRefPtr &ipconfig));
429
430 // The mock methods above take IPConfigRefPtr because this is the type
431 // that the registered callbacks take. This conversion of the DHCP
432 // config ref pointer eases our work in setting up expectations.
433 const IPConfigRefPtr &ConfigRef() { return ip_config_; }
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700434
435 private:
Paul Stewartc5099532013-12-12 07:53:15 -0800436 IPConfigRefPtr ip_config_;
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700437};
438
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700439void DoNothing() {}
440
Alex Vakulenko8a532292014-06-16 17:18:44 -0700441} // namespace
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700442
Paul Stewartc5099532013-12-12 07:53:15 -0800443TEST_F(DHCPConfigCallbackTest, ProcessEventSignalFail) {
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700444 DHCPConfig::Configuration conf;
445 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
446 0x01020304);
Paul Stewartc5099532013-12-12 07:53:15 -0800447 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
448 EXPECT_CALL(*this, FailureCallback(ConfigRef()));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700449 config_->lease_acquisition_timeout_callback_.Reset(base::Bind(&DoNothing));
Paul Stewart1f916e42013-12-23 09:52:54 -0800450 config_->lease_expiration_callback_.Reset(base::Bind(&DoNothing));
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700451 config_->ProcessEventSignal(DHCPConfig::kReasonFail, conf);
Paul Stewartc5099532013-12-12 07:53:15 -0800452 Mock::VerifyAndClearExpectations(this);
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700453 EXPECT_TRUE(config_->properties().address.empty());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700454 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Paul Stewart1f916e42013-12-23 09:52:54 -0800455 EXPECT_TRUE(config_->lease_expiration_callback_.IsCancelled());
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700456}
457
Paul Stewartc5099532013-12-12 07:53:15 -0800458TEST_F(DHCPConfigCallbackTest, ProcessEventSignalSuccess) {
Paul Stewart1f916e42013-12-23 09:52:54 -0800459 for (const auto &reason : { DHCPConfig::kReasonBound,
460 DHCPConfig::kReasonRebind,
461 DHCPConfig::kReasonReboot,
462 DHCPConfig::kReasonRenew }) {
463 int address_octet = 0;
464 for (const auto lease_time_given : { false, true }) {
465 DHCPConfig::Configuration conf;
466 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
467 ++address_octet);
468 if (lease_time_given) {
469 const uint32 kLeaseTime = 1;
470 conf[DHCPConfig::kConfigurationKeyLeaseTime].writer().append_uint32(
471 kLeaseTime);
472 config_->lease_expiration_callback_.Cancel();
473 } else {
474 config_->lease_expiration_callback_.Reset(base::Bind(&DoNothing));
475 }
476 config_->lease_acquisition_timeout_callback_.Reset(
477 base::Bind(&DoNothing));
478 EXPECT_CALL(*this, SuccessCallback(ConfigRef()));
479 EXPECT_CALL(*this, FailureCallback(_)).Times(0);
480 config_->ProcessEventSignal(reason, conf);
481 string failure_message = string(reason) + " failed with lease time " +
482 (lease_time_given ? "given" : "not given");
483 EXPECT_TRUE(Mock::VerifyAndClearExpectations(this)) << failure_message;
484 EXPECT_EQ(base::StringPrintf("%d.0.0.0", address_octet),
485 config_->properties().address) << failure_message;
486 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled())
487 << failure_message;
488 // With no lease time given, the expiration callback will be cancelled.
489 // With a lease time given, the expiration callback should be started.
490 EXPECT_EQ(!lease_time_given,
491 config_->lease_expiration_callback_.IsCancelled())
492 << failure_message;
493 }
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700494 }
495}
496
Paul Stewart475c0722014-04-18 08:52:00 -0700497TEST_F(DHCPConfigCallbackTest, StoppedDuringFailureCallback) {
498 DHCPConfig::Configuration conf;
499 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
500 0x01020304);
501 // Stop the DHCP config while it is calling the failure callback. We
502 // need to ensure that no callbacks are left running inadvertently as
503 // a result.
504 EXPECT_CALL(*this, FailureCallback(ConfigRef()))
505 .WillOnce(InvokeWithoutArgs(this, &DHCPConfigTest::StopInstance));
506 config_->ProcessEventSignal(DHCPConfig::kReasonFail, conf);
507 EXPECT_TRUE(Mock::VerifyAndClearExpectations(this));
508 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
509 EXPECT_TRUE(config_->lease_expiration_callback_.IsCancelled());
510}
511
512TEST_F(DHCPConfigCallbackTest, StoppedDuringSuccessCallback) {
513 DHCPConfig::Configuration conf;
514 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
515 0x01020304);
516 const uint32 kLeaseTime = 1;
517 conf[DHCPConfig::kConfigurationKeyLeaseTime].writer().append_uint32(
518 kLeaseTime);
519 // Stop the DHCP config while it is calling the success callback. This
520 // can happen if the device has a static IP configuration and releases
521 // the lease after accepting other network parameters from the DHCP
522 // IPConfig properties. We need to ensure that no callbacks are left
523 // running inadvertently as a result.
524 EXPECT_CALL(*this, SuccessCallback(ConfigRef()))
525 .WillOnce(InvokeWithoutArgs(this, &DHCPConfigTest::StopInstance));
526 config_->ProcessEventSignal(DHCPConfig::kReasonBound, conf);
527 EXPECT_TRUE(Mock::VerifyAndClearExpectations(this));
528 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
529 EXPECT_TRUE(config_->lease_expiration_callback_.IsCancelled());
530}
531
Paul Stewartc5099532013-12-12 07:53:15 -0800532TEST_F(DHCPConfigCallbackTest, ProcessEventSignalUnknown) {
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700533 DHCPConfig::Configuration conf;
534 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
535 0x01020304);
536 static const char kReasonUnknown[] = "UNKNOWN_REASON";
Paul Stewartc5099532013-12-12 07:53:15 -0800537 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
538 EXPECT_CALL(*this, FailureCallback(_)).Times(0);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700539 config_->lease_acquisition_timeout_callback_.Reset(base::Bind(&DoNothing));
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700540 config_->ProcessEventSignal(kReasonUnknown, conf);
Paul Stewartc5099532013-12-12 07:53:15 -0800541 Mock::VerifyAndClearExpectations(this);
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700542 EXPECT_TRUE(config_->properties().address.empty());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700543 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700544}
545
Paul Stewartc5099532013-12-12 07:53:15 -0800546TEST_F(DHCPConfigCallbackTest, ProcessEventSignalGatewayArp) {
Paul Stewart94571f12013-09-10 17:26:07 -0700547 DHCPConfig::Configuration conf;
548 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
549 0x01020304);
Paul Stewartc5099532013-12-12 07:53:15 -0800550 EXPECT_CALL(*this, SuccessCallback(ConfigRef()));
551 EXPECT_CALL(*this, FailureCallback(_)).Times(0);
Paul Stewart94571f12013-09-10 17:26:07 -0700552 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(true));
553 config_->Start();
554 config_->ProcessEventSignal(DHCPConfig::kReasonGatewayArp, conf);
Paul Stewartc5099532013-12-12 07:53:15 -0800555 Mock::VerifyAndClearExpectations(this);
Paul Stewart94571f12013-09-10 17:26:07 -0700556 EXPECT_EQ("4.3.2.1", config_->properties().address);
557 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
558 EXPECT_TRUE(config_->is_gateway_arp_active_);
559
560 // If the timeout gets called, we shouldn't lose the lease since GatewayArp
561 // is active.
562 ScopedMockLog log;
563 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
564 EXPECT_CALL(log, Log(_, _, ::testing::EndsWith(
565 "Continuing to use our previous lease, due to gateway-ARP.")));
Paul Stewartc5099532013-12-12 07:53:15 -0800566 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
567 EXPECT_CALL(*this, FailureCallback(_)).Times(0);
Paul Stewart94571f12013-09-10 17:26:07 -0700568 config_->lease_acquisition_timeout_callback_.callback().Run();
Paul Stewartc5099532013-12-12 07:53:15 -0800569 Mock::VerifyAndClearExpectations(this);
Paul Stewart94571f12013-09-10 17:26:07 -0700570 EXPECT_TRUE(config_->is_gateway_arp_active_);
571
572 // An official reply from a DHCP server should reset our GatewayArp state.
Paul Stewartc5099532013-12-12 07:53:15 -0800573 EXPECT_CALL(*this, SuccessCallback(ConfigRef()));
574 EXPECT_CALL(*this, FailureCallback(_)).Times(0);
Paul Stewart94571f12013-09-10 17:26:07 -0700575 config_->ProcessEventSignal(DHCPConfig::kReasonRenew, conf);
Paul Stewartc5099532013-12-12 07:53:15 -0800576 Mock::VerifyAndClearExpectations(this);
Paul Stewart94571f12013-09-10 17:26:07 -0700577 EXPECT_FALSE(config_->is_gateway_arp_active_);
578}
579
Paul Stewartc5099532013-12-12 07:53:15 -0800580TEST_F(DHCPConfigCallbackTest, ProcessEventSignalGatewayArpNak) {
Paul Stewart94571f12013-09-10 17:26:07 -0700581 DHCPConfig::Configuration conf;
582 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
583 0x01020304);
Paul Stewart94571f12013-09-10 17:26:07 -0700584 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(true));
585 config_->Start();
586 config_->ProcessEventSignal(DHCPConfig::kReasonGatewayArp, conf);
587 EXPECT_TRUE(config_->is_gateway_arp_active_);
588
589 // Sending a NAK should clear is_gateway_arp_active_.
590 config_->ProcessEventSignal(DHCPConfig::kReasonNak, conf);
591 EXPECT_FALSE(config_->is_gateway_arp_active_);
Paul Stewartc5099532013-12-12 07:53:15 -0800592 Mock::VerifyAndClearExpectations(this);
Paul Stewart94571f12013-09-10 17:26:07 -0700593
594 // If the timeout gets called, we should lose the lease since GatewayArp
595 // is not active any more.
Paul Stewartc5099532013-12-12 07:53:15 -0800596 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
597 EXPECT_CALL(*this, FailureCallback(ConfigRef()));
Paul Stewart94571f12013-09-10 17:26:07 -0700598 config_->lease_acquisition_timeout_callback_.callback().Run();
Paul Stewartc5099532013-12-12 07:53:15 -0800599 Mock::VerifyAndClearExpectations(this);
Paul Stewart94571f12013-09-10 17:26:07 -0700600}
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700601
Darin Petkov98dd6a02011-06-10 15:12:57 -0700602TEST_F(DHCPConfigTest, ReleaseIP) {
603 config_->pid_ = 1 << 18; // Ensure unknown positive PID.
Paul Stewarta02ee492012-05-16 10:04:53 -0700604 config_->arp_gateway_ = false;
Darin Petkovaceede32011-07-18 15:32:38 -0700605 EXPECT_CALL(*proxy_, Release(kDeviceName)).Times(1);
Darin Petkova7b89492011-07-27 12:48:17 -0700606 config_->proxy_.reset(proxy_.release());
Paul Stewart217c61d2013-06-13 15:12:02 -0700607 EXPECT_TRUE(config_->ReleaseIP(IPConfig::kReleaseReasonDisconnect));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700608 config_->pid_ = 0;
609}
610
Paul Stewarta02ee492012-05-16 10:04:53 -0700611TEST_F(DHCPConfigTest, ReleaseIPArpGW) {
612 config_->pid_ = 1 << 18; // Ensure unknown positive PID.
613 config_->arp_gateway_ = true;
614 EXPECT_CALL(*proxy_, Release(kDeviceName)).Times(0);
615 config_->proxy_.reset(proxy_.release());
Paul Stewart217c61d2013-06-13 15:12:02 -0700616 EXPECT_TRUE(config_->ReleaseIP(IPConfig::kReleaseReasonDisconnect));
617 config_->pid_ = 0;
618}
619
620TEST_F(DHCPConfigTest, ReleaseIPStaticIPWithLease) {
621 config_->pid_ = 1 << 18; // Ensure unknown positive PID.
622 config_->arp_gateway_ = true;
623 config_->is_lease_active_ = true;
624 EXPECT_CALL(*proxy_, Release(kDeviceName));
625 config_->proxy_.reset(proxy_.release());
626 EXPECT_TRUE(config_->ReleaseIP(IPConfig::kReleaseReasonStaticIP));
627 EXPECT_EQ(NULL, config_->proxy_.get());
628 config_->pid_ = 0;
629}
630
631TEST_F(DHCPConfigTest, ReleaseIPStaticIPWithoutLease) {
632 config_->pid_ = 1 << 18; // Ensure unknown positive PID.
633 config_->arp_gateway_ = true;
634 config_->is_lease_active_ = false;
635 EXPECT_CALL(*proxy_, Release(kDeviceName)).Times(0);
636 MockDHCPProxy *proxy_pointer = proxy_.get();
637 config_->proxy_.reset(proxy_.release());
638 EXPECT_TRUE(config_->ReleaseIP(IPConfig::kReleaseReasonStaticIP));
639 // Expect that proxy has not been released.
640 EXPECT_EQ(proxy_pointer, config_->proxy_.get());
Paul Stewarta02ee492012-05-16 10:04:53 -0700641 config_->pid_ = 0;
642}
643
Darin Petkov98dd6a02011-06-10 15:12:57 -0700644TEST_F(DHCPConfigTest, RenewIP) {
Paul Stewart21f7b342013-11-19 10:15:58 -0800645 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(false));
646 config_->pid_ = 0;
647 EXPECT_FALSE(config_->RenewIP()); // Expect a call to Start() if pid_ is 0.
648 Mock::VerifyAndClearExpectations(minijail_.get());
649 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).Times(0);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700650 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Paul Stewart1f916e42013-12-23 09:52:54 -0800651 config_->lease_expiration_callback_.Reset(base::Bind(&DoNothing));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700652 config_->pid_ = 456;
Paul Stewartc02344a2012-08-17 16:57:37 -0700653 EXPECT_FALSE(config_->RenewIP()); // Expect no crash with NULL proxy.
Darin Petkovaceede32011-07-18 15:32:38 -0700654 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
Darin Petkova7b89492011-07-27 12:48:17 -0700655 config_->proxy_.reset(proxy_.release());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700656 EXPECT_TRUE(config_->RenewIP());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700657 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Paul Stewart1f916e42013-12-23 09:52:54 -0800658 EXPECT_TRUE(config_->lease_expiration_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700659 config_->pid_ = 0;
660}
661
662TEST_F(DHCPConfigTest, RequestIP) {
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700663 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700664 config_->pid_ = 567;
Darin Petkovaceede32011-07-18 15:32:38 -0700665 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
Darin Petkova7b89492011-07-27 12:48:17 -0700666 config_->proxy_.reset(proxy_.release());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700667 EXPECT_TRUE(config_->RenewIP());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700668 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
669 config_->pid_ = 0;
670}
671
Paul Stewartc5099532013-12-12 07:53:15 -0800672TEST_F(DHCPConfigCallbackTest, RequestIPTimeout) {
673 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
674 EXPECT_CALL(*this, FailureCallback(ConfigRef()));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700675 config_->lease_acquisition_timeout_seconds_ = 0;
676 config_->pid_ = 567;
677 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
678 config_->proxy_.reset(proxy_.release());
679 config_->RenewIP();
680 config_->dispatcher_->DispatchPendingEvents();
Paul Stewartc5099532013-12-12 07:53:15 -0800681 Mock::VerifyAndClearExpectations(this);
Darin Petkov98dd6a02011-06-10 15:12:57 -0700682 config_->pid_ = 0;
683}
684
685TEST_F(DHCPConfigTest, Restart) {
686 const int kPID1 = 1 << 17; // Ensure unknown positive PID.
687 const int kPID2 = 987;
688 const unsigned int kTag1 = 11;
689 const unsigned int kTag2 = 22;
690 config_->pid_ = kPID1;
691 config_->child_watch_tag_ = kTag1;
692 DHCPProvider::GetInstance()->BindPID(kPID1, config_);
Chris Masone2176a882011-09-14 22:29:15 -0700693 EXPECT_CALL(*glib(), SourceRemove(kTag1)).WillOnce(Return(true));
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700694 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(
695 DoAll(SetArgumentPointee<2>(kPID2), Return(true)));
Chris Masone2176a882011-09-14 22:29:15 -0700696 EXPECT_CALL(*glib(), ChildWatchAdd(kPID2, _, _)).WillOnce(Return(kTag2));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700697 EXPECT_TRUE(config_->Restart());
698 EXPECT_EQ(kPID2, config_->pid_);
699 EXPECT_EQ(config_.get(), DHCPProvider::GetInstance()->GetConfig(kPID2).get());
700 EXPECT_EQ(kTag2, config_->child_watch_tag_);
701 DHCPProvider::GetInstance()->UnbindPID(kPID2);
702 config_->pid_ = 0;
703 config_->child_watch_tag_ = 0;
704}
705
706TEST_F(DHCPConfigTest, RestartNoClient) {
707 const int kPID = 777;
708 const unsigned int kTag = 66;
Chris Masone2176a882011-09-14 22:29:15 -0700709 EXPECT_CALL(*glib(), SourceRemove(_)).Times(0);
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700710 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(
711 DoAll(SetArgumentPointee<2>(kPID), Return(true)));
Chris Masone2176a882011-09-14 22:29:15 -0700712 EXPECT_CALL(*glib(), ChildWatchAdd(kPID, _, _)).WillOnce(Return(kTag));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700713 EXPECT_TRUE(config_->Restart());
714 EXPECT_EQ(kPID, config_->pid_);
715 EXPECT_EQ(config_.get(), DHCPProvider::GetInstance()->GetConfig(kPID).get());
716 EXPECT_EQ(kTag, config_->child_watch_tag_);
717 DHCPProvider::GetInstance()->UnbindPID(kPID);
718 config_->pid_ = 0;
719 config_->child_watch_tag_ = 0;
720}
721
Paul Stewartd408fdf2012-05-07 17:15:57 -0700722TEST_F(DHCPConfigTest, StartSuccessEphemeral) {
723 DHCPConfigRefPtr config =
Paul Stewart75a68b92013-10-24 10:50:27 -0700724 CreateRunningConfig(kHostName, kDeviceName, kArpGateway, !kMinimalConfig);
Paul Stewartd408fdf2012-05-07 17:15:57 -0700725 StopRunningConfigAndExpect(config, false);
726}
Darin Petkov92c43902011-06-09 20:46:06 -0700727
Paul Stewartd408fdf2012-05-07 17:15:57 -0700728TEST_F(DHCPConfigTest, StartSuccessPersistent) {
729 DHCPConfigRefPtr config =
Paul Stewart75a68b92013-10-24 10:50:27 -0700730 CreateRunningConfig(kHostName, kLeaseFileSuffix, kArpGateway,
731 !kMinimalConfig);
Paul Stewartd408fdf2012-05-07 17:15:57 -0700732 StopRunningConfigAndExpect(config, true);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700733}
734
Paul Stewartc5099532013-12-12 07:53:15 -0800735TEST_F(DHCPConfigCallbackTest, StartTimeout) {
736 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
737 EXPECT_CALL(*this, FailureCallback(ConfigRef()));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700738 config_->lease_acquisition_timeout_seconds_ = 0;
739 config_->proxy_.reset(proxy_.release());
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700740 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(true));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700741 config_->Start();
742 config_->dispatcher_->DispatchPendingEvents();
Paul Stewartc5099532013-12-12 07:53:15 -0800743 Mock::VerifyAndClearExpectations(this);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700744}
745
Darin Petkov98dd6a02011-06-10 15:12:57 -0700746TEST_F(DHCPConfigTest, Stop) {
Darin Petkov98dd6a02011-06-10 15:12:57 -0700747 const int kPID = 1 << 17; // Ensure unknown positive PID.
mukesh agrawal1835e772013-01-15 18:35:03 -0800748 ScopedMockLog log;
749 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
750 EXPECT_CALL(log, Log(_, _, ContainsRegex(
Darin Petkov3fe17662013-02-04 14:19:08 +0100751 base::StringPrintf("Stopping.+%s", __func__))));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700752 config_->pid_ = kPID;
Darin Petkov3fe17662013-02-04 14:19:08 +0100753 DHCPProvider::GetInstance()->BindPID(kPID, config_);
Paul Stewart1f916e42013-12-23 09:52:54 -0800754 config_->lease_acquisition_timeout_callback_.Reset(base::Bind(&DoNothing));
755 config_->lease_expiration_callback_.Reset(base::Bind(&DoNothing));
mukesh agrawal1835e772013-01-15 18:35:03 -0800756 config_->Stop(__func__);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700757 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Paul Stewart1f916e42013-12-23 09:52:54 -0800758 EXPECT_TRUE(config_->lease_expiration_callback_.IsCancelled());
Darin Petkov3fe17662013-02-04 14:19:08 +0100759 EXPECT_FALSE(DHCPProvider::GetInstance()->GetConfig(kPID));
760 EXPECT_FALSE(config_->pid_);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700761}
762
763TEST_F(DHCPConfigTest, StopDuringRequestIP) {
764 config_->pid_ = 567;
765 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
766 config_->proxy_.reset(proxy_.release());
767 EXPECT_TRUE(config_->RenewIP());
768 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
769 config_->pid_ = 0; // Keep Stop from killing a real process.
mukesh agrawal1835e772013-01-15 18:35:03 -0800770 config_->Stop(__func__);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700771 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700772}
773
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800774TEST_F(DHCPConfigTest, SetProperty) {
Chris Masone43b48a12011-07-01 13:37:07 -0700775 ::DBus::Error error;
776 // Ensure that an attempt to write a R/O property returns InvalidArgs error.
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800777 EXPECT_FALSE(DBusAdaptor::SetProperty(config_->mutable_store(),
Ben Chan0295e0f2013-09-20 13:47:29 -0700778 kAddressProperty,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800779 PropertyStoreTest::kStringV,
780 &error));
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700781 ASSERT_TRUE(error.is_set()); // name() may be invalid otherwise
Chris Masone9d779932011-08-25 16:33:41 -0700782 EXPECT_EQ(invalid_args(), error.name());
Chris Masone43b48a12011-07-01 13:37:07 -0700783}
784
Darin Petkove7cb7f82011-06-03 13:21:51 -0700785} // namespace shill