blob: f3aa2750d3949bdd6ddc53acf48408bb430814ae [file] [log] [blame]
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Darin Petkove7cb7f82011-06-03 13:21:51 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Chris Masone8a7b8be2011-07-22 12:43:37 -07005#include "shill/dhcp_config.h"
6
Eric Shienbrood3e20a232012-02-16 11:35:56 -05007#include <base/bind.h>
Darin Petkov92c43902011-06-09 20:46:06 -07008#include <base/file_util.h>
Paul Stewart5ad16062013-02-21 18:10:48 -08009#include <base/files/scoped_temp_dir.h>
Ben Chana0ddf462014-02-06 11:32:42 -080010#include <base/strings/stringprintf.h>
Chris Masone43b48a12011-07-01 13:37:07 -070011#include <chromeos/dbus/service_constants.h>
Darin Petkov92c43902011-06-09 20:46:06 -070012
Chris Masone43b48a12011-07-01 13:37:07 -070013#include "shill/dbus_adaptor.h"
Darin Petkovf7897bc2011-06-08 17:13:36 -070014#include "shill/dhcp_provider.h"
Paul Stewart26b327e2011-10-19 11:38:09 -070015#include "shill/event_dispatcher.h"
Chris Masone19e30402011-07-19 15:48:47 -070016#include "shill/mock_control.h"
Darin Petkov98dd6a02011-06-10 15:12:57 -070017#include "shill/mock_dhcp_proxy.h"
Darin Petkovf7897bc2011-06-08 17:13:36 -070018#include "shill/mock_glib.h"
mukesh agrawal6c6655d2012-12-06 14:49:50 -080019#include "shill/mock_log.h"
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070020#include "shill/mock_minijail.h"
Ben Chana55469d2014-01-27 16:35:29 -080021#include "shill/mock_proxy_factory.h"
Chris Masone43b48a12011-07-01 13:37:07 -070022#include "shill/property_store_unittest.h"
Ben Chana55469d2014-01-27 16:35:29 -080023#include "shill/testing.h"
Darin Petkove7cb7f82011-06-03 13:21:51 -070024
Eric Shienbrood3e20a232012-02-16 11:35:56 -050025using base::Bind;
Albert Chaulk0e1cdea2013-02-27 15:32:55 -080026using base::FilePath;
Paul Stewart5ad16062013-02-21 18:10:48 -080027using base::ScopedTempDir;
Eric Shienbrood3e20a232012-02-16 11:35:56 -050028using base::Unretained;
Darin Petkove7cb7f82011-06-03 13:21:51 -070029using std::string;
30using std::vector;
Darin Petkovf7897bc2011-06-08 17:13:36 -070031using testing::_;
mukesh agrawal1835e772013-01-15 18:35:03 -080032using testing::AnyNumber;
33using testing::ContainsRegex;
Paul Stewart475c0722014-04-18 08:52:00 -070034using testing::InvokeWithoutArgs;
Paul Stewart21f7b342013-11-19 10:15:58 -080035using testing::Mock;
Darin Petkovf7897bc2011-06-08 17:13:36 -070036using testing::Return;
37using testing::SetArgumentPointee;
Darin Petkove7cb7f82011-06-03 13:21:51 -070038using testing::Test;
39
40namespace shill {
41
Darin Petkov92c43902011-06-09 20:46:06 -070042namespace {
Darin Petkova7b89492011-07-27 12:48:17 -070043const char kDeviceName[] = "eth0";
Paul Stewartd32f4842012-01-11 16:08:13 -080044const char kHostName[] = "hostname";
Paul Stewartd408fdf2012-05-07 17:15:57 -070045const char kLeaseFileSuffix[] = "leasefilesuffix";
46const bool kArpGateway = true;
Paul Stewart75a68b92013-10-24 10:50:27 -070047const bool kHasHostname = true;
48const bool kHasLeaseSuffix = true;
49const bool kMinimalConfig = true;
Darin Petkov92c43902011-06-09 20:46:06 -070050} // namespace {}
51
Chris Masone43b48a12011-07-01 13:37:07 -070052class DHCPConfigTest : public PropertyStoreTest {
Darin Petkove7cb7f82011-06-03 13:21:51 -070053 public:
Darin Petkovf7897bc2011-06-08 17:13:36 -070054 DHCPConfigTest()
Darin Petkovf65e9282011-06-21 14:29:56 -070055 : proxy_(new MockDHCPProxy()),
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070056 minijail_(new MockMinijail()),
Chris Masone19e30402011-07-19 15:48:47 -070057 config_(new DHCPConfig(&control_,
Chris Masone2176a882011-09-14 22:29:15 -070058 dispatcher(),
Chris Masone19e30402011-07-19 15:48:47 -070059 DHCPProvider::GetInstance(),
Darin Petkov92c43902011-06-09 20:46:06 -070060 kDeviceName,
Paul Stewartd32f4842012-01-11 16:08:13 -080061 kHostName,
Paul Stewartd408fdf2012-05-07 17:15:57 -070062 kLeaseFileSuffix,
63 kArpGateway,
Paul Stewart75a68b92013-10-24 10:50:27 -070064 !kMinimalConfig,
Chris Masone2176a882011-09-14 22:29:15 -070065 glib())) {}
Darin Petkova7b89492011-07-27 12:48:17 -070066
67 virtual void SetUp() {
Darin Petkovab565bb2011-10-06 02:55:51 -070068 config_->proxy_factory_ = &proxy_factory_;
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070069 config_->minijail_ = minijail_.get();
Darin Petkova7b89492011-07-27 12:48:17 -070070 }
71
72 virtual void TearDown() {
Darin Petkovab565bb2011-10-06 02:55:51 -070073 config_->proxy_factory_ = NULL;
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070074 config_->minijail_ = NULL;
Darin Petkov98dd6a02011-06-10 15:12:57 -070075 }
Darin Petkove7cb7f82011-06-03 13:21:51 -070076
Paul Stewart475c0722014-04-18 08:52:00 -070077 void StopInstance() {
78 config_->Stop("In test");
79 }
80
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070081 DHCPConfigRefPtr CreateMockMinijailConfig(const string &hostname,
Paul Stewart75a68b92013-10-24 10:50:27 -070082 const string &lease_suffix,
83 bool arp_gateway,
84 bool minimal_config);
Paul Stewartd408fdf2012-05-07 17:15:57 -070085 DHCPConfigRefPtr CreateRunningConfig(const string &hostname,
86 const string &lease_suffix,
Paul Stewart75a68b92013-10-24 10:50:27 -070087 bool arp_gateway,
88 bool minimal_config);
Paul Stewartd408fdf2012-05-07 17:15:57 -070089 void StopRunningConfigAndExpect(DHCPConfigRefPtr config,
90 bool lease_file_exists);
91
Darin Petkove7cb7f82011-06-03 13:21:51 -070092 protected:
Paul Stewartd408fdf2012-05-07 17:15:57 -070093 static const int kPID;
94 static const unsigned int kTag;
95
96 FilePath lease_file_;
97 FilePath pid_file_;
98 ScopedTempDir temp_dir_;
Darin Petkova7b89492011-07-27 12:48:17 -070099 scoped_ptr<MockDHCPProxy> proxy_;
Ben Chana55469d2014-01-27 16:35:29 -0800100 MockProxyFactory proxy_factory_;
Chris Masone19e30402011-07-19 15:48:47 -0700101 MockControl control_;
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700102 scoped_ptr<MockMinijail> minijail_;
Darin Petkovf7897bc2011-06-08 17:13:36 -0700103 DHCPConfigRefPtr config_;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700104};
105
Paul Stewartd408fdf2012-05-07 17:15:57 -0700106const int DHCPConfigTest::kPID = 123456;
107const unsigned int DHCPConfigTest::kTag = 77;
108
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700109DHCPConfigRefPtr DHCPConfigTest::CreateMockMinijailConfig(
Paul Stewart75a68b92013-10-24 10:50:27 -0700110 const string &hostname,
111 const string &lease_suffix,
112 bool arp_gateway,
113 bool minimal_config) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700114 DHCPConfigRefPtr config(new DHCPConfig(&control_,
115 dispatcher(),
116 DHCPProvider::GetInstance(),
117 kDeviceName,
118 hostname,
119 lease_suffix,
120 arp_gateway,
Paul Stewart75a68b92013-10-24 10:50:27 -0700121 minimal_config,
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700122 glib()));
123 config->minijail_ = minijail_.get();
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700124
125 return config;
126}
127
Paul Stewart75a68b92013-10-24 10:50:27 -0700128DHCPConfigRefPtr DHCPConfigTest::CreateRunningConfig(
129 const string &hostname,
130 const string &lease_suffix,
131 bool arp_gateway,
132 bool minimal_config) {
Paul Stewartd408fdf2012-05-07 17:15:57 -0700133 DHCPConfigRefPtr config(new DHCPConfig(&control_,
134 dispatcher(),
135 DHCPProvider::GetInstance(),
136 kDeviceName,
137 hostname,
138 lease_suffix,
139 arp_gateway,
Paul Stewart75a68b92013-10-24 10:50:27 -0700140 minimal_config,
Paul Stewartd408fdf2012-05-07 17:15:57 -0700141 glib()));
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700142 config->minijail_ = minijail_.get();
143 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _))
144 .WillOnce(DoAll(SetArgumentPointee<2>(kPID), Return(true)));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700145 EXPECT_CALL(*glib(), ChildWatchAdd(kPID, _, _)).WillOnce(Return(kTag));
146 EXPECT_TRUE(config->Start());
147 EXPECT_EQ(kPID, config->pid_);
148 EXPECT_EQ(config.get(), DHCPProvider::GetInstance()->GetConfig(kPID).get());
149 EXPECT_EQ(kTag, config->child_watch_tag_);
150
151 EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
152 config->root_ = temp_dir_.path();
Jorge Lucangeli Obes2f3169d2012-04-25 11:38:25 -0700153 FilePath varrun = temp_dir_.path().Append("var/run/dhcpcd");
Ben Chana0ddf462014-02-06 11:32:42 -0800154 EXPECT_TRUE(base::CreateDirectory(varrun));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700155 pid_file_ = varrun.Append(base::StringPrintf("dhcpcd-%s.pid", kDeviceName));
156 FilePath varlib = temp_dir_.path().Append("var/lib/dhcpcd");
Ben Chana0ddf462014-02-06 11:32:42 -0800157 EXPECT_TRUE(base::CreateDirectory(varlib));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700158 lease_file_ =
159 varlib.Append(base::StringPrintf("dhcpcd-%s.lease", kDeviceName));
160 EXPECT_EQ(0, file_util::WriteFile(pid_file_, "", 0));
161 EXPECT_EQ(0, file_util::WriteFile(lease_file_, "", 0));
Ben Chana0ddf462014-02-06 11:32:42 -0800162 EXPECT_TRUE(base::PathExists(pid_file_));
163 EXPECT_TRUE(base::PathExists(lease_file_));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700164
165 return config;
166}
167
168void DHCPConfigTest::StopRunningConfigAndExpect(DHCPConfigRefPtr config,
169 bool lease_file_exists) {
mukesh agrawal6c6655d2012-12-06 14:49:50 -0800170 ScopedMockLog log;
171 // We use a non-zero exit status so that we get the log message.
172 EXPECT_CALL(log, Log(_, _, ::testing::EndsWith("status 10")));
173 DHCPConfig::ChildWatchCallback(kPID, 10, config.get());
Paul Stewartd408fdf2012-05-07 17:15:57 -0700174 EXPECT_EQ(NULL, DHCPProvider::GetInstance()->GetConfig(kPID).get());
175
Ben Chana0ddf462014-02-06 11:32:42 -0800176 EXPECT_FALSE(base::PathExists(pid_file_));
177 EXPECT_EQ(lease_file_exists, base::PathExists(lease_file_));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700178}
179
Darin Petkove7cb7f82011-06-03 13:21:51 -0700180TEST_F(DHCPConfigTest, GetIPv4AddressString) {
Darin Petkovf7897bc2011-06-08 17:13:36 -0700181 EXPECT_EQ("255.255.255.255", config_->GetIPv4AddressString(0xffffffff));
182 EXPECT_EQ("0.0.0.0", config_->GetIPv4AddressString(0));
183 EXPECT_EQ("1.2.3.4", config_->GetIPv4AddressString(0x04030201));
Darin Petkove7cb7f82011-06-03 13:21:51 -0700184}
185
Darin Petkova7b89492011-07-27 12:48:17 -0700186TEST_F(DHCPConfigTest, InitProxy) {
187 static const char kService[] = ":1.200";
Darin Petkova7b89492011-07-27 12:48:17 -0700188 EXPECT_TRUE(proxy_.get());
189 EXPECT_FALSE(config_->proxy_.get());
Ben Chana55469d2014-01-27 16:35:29 -0800190 EXPECT_CALL(proxy_factory_, CreateDHCPProxy(kService))
191 .WillOnce(ReturnAndReleasePointee(&proxy_));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500192 config_->InitProxy(kService);
Darin Petkova7b89492011-07-27 12:48:17 -0700193 EXPECT_FALSE(proxy_.get());
194 EXPECT_TRUE(config_->proxy_.get());
195
196 config_->InitProxy(kService);
Darin Petkova7b89492011-07-27 12:48:17 -0700197}
198
Paul Stewart65bcd082012-11-16 09:37:14 -0800199TEST_F(DHCPConfigTest, ParseClasslessStaticRoutes) {
200 const string kDefaultAddress = "0.0.0.0";
201 const string kDefaultDestination = kDefaultAddress + "/0";
202 const string kRouter0 = "10.0.0.254";
203 const string kAddress1 = "192.168.1.0";
204 const string kDestination1 = kAddress1 + "/24";
205 // Last gateway missing, leaving an odd number of parameters.
206 const string kBrokenClasslessRoutes0 = kDefaultDestination + " " + kRouter0 +
207 " " + kDestination1;
208 IPConfig::Properties properties;
209 EXPECT_FALSE(DHCPConfig::ParseClasslessStaticRoutes(kBrokenClasslessRoutes0,
210 &properties));
211 EXPECT_TRUE(properties.routes.empty());
212 EXPECT_TRUE(properties.gateway.empty());
213
214 // Gateway argument for the second route is malformed, but we were able
215 // to salvage a default gateway.
216 const string kBrokenRouter1 = "10.0.0";
217 const string kBrokenClasslessRoutes1 = kBrokenClasslessRoutes0 + " " +
218 kBrokenRouter1;
219 EXPECT_FALSE(DHCPConfig::ParseClasslessStaticRoutes(kBrokenClasslessRoutes1,
220 &properties));
221 EXPECT_TRUE(properties.routes.empty());
222 EXPECT_EQ(kRouter0, properties.gateway);
223
224 const string kRouter1 = "10.0.0.253";
225 const string kRouter2 = "10.0.0.252";
226 const string kClasslessRoutes0 = kDefaultDestination + " " + kRouter2 + " " +
227 kDestination1 + " " + kRouter1;
228 EXPECT_TRUE(DHCPConfig::ParseClasslessStaticRoutes(kClasslessRoutes0,
229 &properties));
230 // The old default route is preserved.
231 EXPECT_EQ(kRouter0, properties.gateway);
232
233 // The two routes (including the one which would have otherwise been
234 // classified as a default route) are added to the routing table.
235 EXPECT_EQ(2, properties.routes.size());
236 const IPConfig::Route &route0 = properties.routes[0];
237 EXPECT_EQ(kDefaultAddress, route0.host);
238 EXPECT_EQ("0.0.0.0", route0.netmask);
239 EXPECT_EQ(kRouter2, route0.gateway);
240
241 const IPConfig::Route &route1 = properties.routes[1];
242 EXPECT_EQ(kAddress1, route1.host);
243 EXPECT_EQ("255.255.255.0", route1.netmask);
244 EXPECT_EQ(kRouter1, route1.gateway);
245
246 // A malformed routing table should not affect the current table.
247 EXPECT_FALSE(DHCPConfig::ParseClasslessStaticRoutes(kBrokenClasslessRoutes1,
248 &properties));
249 EXPECT_EQ(2, properties.routes.size());
250 EXPECT_EQ(kRouter0, properties.gateway);
251}
252
Darin Petkove7cb7f82011-06-03 13:21:51 -0700253TEST_F(DHCPConfigTest, ParseConfiguration) {
254 DHCPConfig::Configuration conf;
255 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
256 0x01020304);
257 conf[DHCPConfig::kConfigurationKeySubnetCIDR].writer().append_byte(
258 16);
259 conf[DHCPConfig::kConfigurationKeyBroadcastAddress].writer().append_uint32(
260 0x10203040);
261 {
Darin Petkove7cb7f82011-06-03 13:21:51 -0700262 vector<unsigned int> routers;
263 routers.push_back(0x02040608);
264 routers.push_back(0x03050709);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700265 DBus::MessageIter writer =
266 conf[DHCPConfig::kConfigurationKeyRouters].writer();
Darin Petkove7cb7f82011-06-03 13:21:51 -0700267 writer << routers;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700268 }
269 {
Darin Petkove7cb7f82011-06-03 13:21:51 -0700270 vector<unsigned int> dns;
271 dns.push_back(0x09070503);
272 dns.push_back(0x08060402);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700273 DBus::MessageIter writer = conf[DHCPConfig::kConfigurationKeyDNS].writer();
Darin Petkove7cb7f82011-06-03 13:21:51 -0700274 writer << dns;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700275 }
276 conf[DHCPConfig::kConfigurationKeyDomainName].writer().append_string(
277 "domain-name");
278 {
Darin Petkove7cb7f82011-06-03 13:21:51 -0700279 vector<string> search;
280 search.push_back("foo.com");
281 search.push_back("bar.com");
Darin Petkovf7897bc2011-06-08 17:13:36 -0700282 DBus::MessageIter writer =
283 conf[DHCPConfig::kConfigurationKeyDomainSearch].writer();
Darin Petkove7cb7f82011-06-03 13:21:51 -0700284 writer << search;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700285 }
286 conf[DHCPConfig::kConfigurationKeyMTU].writer().append_uint16(600);
287 conf["UnknownKey"] = DBus::Variant();
288
Darin Petkove7cb7f82011-06-03 13:21:51 -0700289 IPConfig::Properties properties;
Darin Petkovf7897bc2011-06-08 17:13:36 -0700290 ASSERT_TRUE(config_->ParseConfiguration(conf, &properties));
Darin Petkove7cb7f82011-06-03 13:21:51 -0700291 EXPECT_EQ("4.3.2.1", properties.address);
Paul Stewart48100b02012-03-19 07:53:52 -0700292 EXPECT_EQ(16, properties.subnet_prefix);
Darin Petkove7cb7f82011-06-03 13:21:51 -0700293 EXPECT_EQ("64.48.32.16", properties.broadcast_address);
294 EXPECT_EQ("8.6.4.2", properties.gateway);
295 ASSERT_EQ(2, properties.dns_servers.size());
296 EXPECT_EQ("3.5.7.9", properties.dns_servers[0]);
297 EXPECT_EQ("2.4.6.8", properties.dns_servers[1]);
298 EXPECT_EQ("domain-name", properties.domain_name);
299 ASSERT_EQ(2, properties.domain_search.size());
300 EXPECT_EQ("foo.com", properties.domain_search[0]);
301 EXPECT_EQ("bar.com", properties.domain_search[1]);
302 EXPECT_EQ(600, properties.mtu);
303}
304
Darin Petkov92c43902011-06-09 20:46:06 -0700305TEST_F(DHCPConfigTest, StartFail) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700306 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(false));
Chris Masone2176a882011-09-14 22:29:15 -0700307 EXPECT_CALL(*glib(), ChildWatchAdd(_, _, _)).Times(0);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700308 EXPECT_FALSE(config_->Start());
309 EXPECT_EQ(0, config_->pid_);
Darin Petkov92c43902011-06-09 20:46:06 -0700310}
Darin Petkovf7897bc2011-06-08 17:13:36 -0700311
Paul Stewart75a68b92013-10-24 10:50:27 -0700312MATCHER_P4(IsDHCPCDArgs, has_hostname, has_arp_gateway, has_lease_suffix,
313 has_minimal_config, "") {
Paul Stewartd32f4842012-01-11 16:08:13 -0800314 if (string(arg[0]) != "/sbin/dhcpcd" ||
Paul Stewart75a68b92013-10-24 10:50:27 -0700315 string(arg[1]) != "-B" ||
316 string(arg[2]) != "-q") {
Paul Stewartd32f4842012-01-11 16:08:13 -0800317 return false;
318 }
319
Paul Stewart75a68b92013-10-24 10:50:27 -0700320 int end_offset = 3;
Paul Stewartd32f4842012-01-11 16:08:13 -0800321 if (has_hostname) {
Paul Stewartd408fdf2012-05-07 17:15:57 -0700322 if (string(arg[end_offset]) != "-h" ||
323 string(arg[end_offset + 1]) != kHostName) {
Paul Stewartd32f4842012-01-11 16:08:13 -0800324 return false;
325 }
Paul Stewartd408fdf2012-05-07 17:15:57 -0700326 end_offset += 2;
Paul Stewartd32f4842012-01-11 16:08:13 -0800327 }
328
Paul Stewartd408fdf2012-05-07 17:15:57 -0700329 if (has_arp_gateway) {
Paul Stewart75a68b92013-10-24 10:50:27 -0700330 if (string(arg[end_offset]) != "-R" ||
331 string(arg[end_offset + 1]) != "-U") {
Paul Stewartd408fdf2012-05-07 17:15:57 -0700332 return false;
Paul Stewart75a68b92013-10-24 10:50:27 -0700333 }
334 end_offset += 2;
335 }
336
337 if (has_minimal_config) {
338 if (string(arg[end_offset]) != "-f" ||
339 string(arg[end_offset + 1]) != "/etc/dhcpcd-minimal.conf") {
340 return false;
341 }
342 end_offset += 2;
Paul Stewartd408fdf2012-05-07 17:15:57 -0700343 }
344
345 string device_arg = has_lease_suffix ?
346 string(kDeviceName) + "=" + string(kLeaseFileSuffix) : kDeviceName;
347 return string(arg[end_offset]) == device_arg && arg[end_offset + 1] == NULL;
Paul Stewartd32f4842012-01-11 16:08:13 -0800348}
349
350TEST_F(DHCPConfigTest, StartWithHostname) {
Paul Stewart75a68b92013-10-24 10:50:27 -0700351 EXPECT_CALL(*minijail_, RunAndDestroy(_, IsDHCPCDArgs(kHasHostname,
352 kArpGateway,
353 kHasLeaseSuffix,
354 !kMinimalConfig), _))
355 .WillOnce(Return(false));
Paul Stewartd32f4842012-01-11 16:08:13 -0800356 EXPECT_FALSE(config_->Start());
357}
358
359TEST_F(DHCPConfigTest, StartWithoutHostname) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700360 DHCPConfigRefPtr config = CreateMockMinijailConfig("",
361 kLeaseFileSuffix,
Paul Stewart75a68b92013-10-24 10:50:27 -0700362 kArpGateway,
363 !kMinimalConfig);
364 EXPECT_CALL(*minijail_, RunAndDestroy(_, IsDHCPCDArgs(!kHasHostname,
365 kArpGateway,
366 kHasLeaseSuffix,
367 !kMinimalConfig), _))
368 .WillOnce(Return(false));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700369 EXPECT_FALSE(config->Start());
370}
371
372TEST_F(DHCPConfigTest, StartWithoutArpGateway) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700373 DHCPConfigRefPtr config = CreateMockMinijailConfig(kHostName,
374 kLeaseFileSuffix,
Paul Stewart75a68b92013-10-24 10:50:27 -0700375 !kArpGateway,
376 !kMinimalConfig);
377 EXPECT_CALL(*minijail_, RunAndDestroy(_, IsDHCPCDArgs(kHasHostname,
378 !kArpGateway,
379 kHasLeaseSuffix,
380 !kMinimalConfig), _))
381 .WillOnce(Return(false));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700382 EXPECT_FALSE(config->Start());
383}
384
385TEST_F(DHCPConfigTest, StartWithoutLeaseSuffix) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700386 DHCPConfigRefPtr config = CreateMockMinijailConfig(kHostName,
387 kDeviceName,
Paul Stewart75a68b92013-10-24 10:50:27 -0700388 kArpGateway,
389 !kMinimalConfig);
390 EXPECT_CALL(*minijail_, RunAndDestroy(_, IsDHCPCDArgs(kHasHostname,
391 kArpGateway,
392 !kHasLeaseSuffix,
393 !kMinimalConfig), _))
394 .WillOnce(Return(false));
395 EXPECT_FALSE(config->Start());
396}
397
398TEST_F(DHCPConfigTest, StartWithMinimalConfig) {
399 DHCPConfigRefPtr config = CreateMockMinijailConfig(kHostName,
400 kLeaseFileSuffix,
401 kArpGateway,
402 kMinimalConfig);
403 EXPECT_CALL(*minijail_, RunAndDestroy(_, IsDHCPCDArgs(kHasHostname,
404 kArpGateway,
405 kHasLeaseSuffix,
406 kMinimalConfig), _))
407 .WillOnce(Return(false));
Paul Stewartd32f4842012-01-11 16:08:13 -0800408 EXPECT_FALSE(config->Start());
409}
410
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700411namespace {
412
Paul Stewartc5099532013-12-12 07:53:15 -0800413class DHCPConfigCallbackTest : public DHCPConfigTest {
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700414 public:
Paul Stewartc5099532013-12-12 07:53:15 -0800415 virtual void SetUp() {
416 DHCPConfigTest::SetUp();
417 config_->RegisterUpdateCallback(
418 Bind(&DHCPConfigCallbackTest::SuccessCallback, Unretained(this)));
419 config_->RegisterFailureCallback(
420 Bind(&DHCPConfigCallbackTest::FailureCallback, Unretained(this)));
421 ip_config_ = config_;
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700422 }
423
Paul Stewartc5099532013-12-12 07:53:15 -0800424 MOCK_METHOD1(SuccessCallback, void(const IPConfigRefPtr &ipconfig));
425 MOCK_METHOD1(FailureCallback, void(const IPConfigRefPtr &ipconfig));
426
427 // The mock methods above take IPConfigRefPtr because this is the type
428 // that the registered callbacks take. This conversion of the DHCP
429 // config ref pointer eases our work in setting up expectations.
430 const IPConfigRefPtr &ConfigRef() { return ip_config_; }
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700431
432 private:
Paul Stewartc5099532013-12-12 07:53:15 -0800433 IPConfigRefPtr ip_config_;
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700434};
435
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700436void DoNothing() {}
437
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700438} // namespace {}
439
Paul Stewartc5099532013-12-12 07:53:15 -0800440TEST_F(DHCPConfigCallbackTest, ProcessEventSignalFail) {
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700441 DHCPConfig::Configuration conf;
442 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
443 0x01020304);
Paul Stewartc5099532013-12-12 07:53:15 -0800444 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
445 EXPECT_CALL(*this, FailureCallback(ConfigRef()));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700446 config_->lease_acquisition_timeout_callback_.Reset(base::Bind(&DoNothing));
Paul Stewart1f916e42013-12-23 09:52:54 -0800447 config_->lease_expiration_callback_.Reset(base::Bind(&DoNothing));
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700448 config_->ProcessEventSignal(DHCPConfig::kReasonFail, conf);
Paul Stewartc5099532013-12-12 07:53:15 -0800449 Mock::VerifyAndClearExpectations(this);
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700450 EXPECT_TRUE(config_->properties().address.empty());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700451 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Paul Stewart1f916e42013-12-23 09:52:54 -0800452 EXPECT_TRUE(config_->lease_expiration_callback_.IsCancelled());
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700453}
454
Paul Stewartc5099532013-12-12 07:53:15 -0800455TEST_F(DHCPConfigCallbackTest, ProcessEventSignalSuccess) {
Paul Stewart1f916e42013-12-23 09:52:54 -0800456 for (const auto &reason : { DHCPConfig::kReasonBound,
457 DHCPConfig::kReasonRebind,
458 DHCPConfig::kReasonReboot,
459 DHCPConfig::kReasonRenew }) {
460 int address_octet = 0;
461 for (const auto lease_time_given : { false, true }) {
462 DHCPConfig::Configuration conf;
463 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
464 ++address_octet);
465 if (lease_time_given) {
466 const uint32 kLeaseTime = 1;
467 conf[DHCPConfig::kConfigurationKeyLeaseTime].writer().append_uint32(
468 kLeaseTime);
469 config_->lease_expiration_callback_.Cancel();
470 } else {
471 config_->lease_expiration_callback_.Reset(base::Bind(&DoNothing));
472 }
473 config_->lease_acquisition_timeout_callback_.Reset(
474 base::Bind(&DoNothing));
475 EXPECT_CALL(*this, SuccessCallback(ConfigRef()));
476 EXPECT_CALL(*this, FailureCallback(_)).Times(0);
477 config_->ProcessEventSignal(reason, conf);
478 string failure_message = string(reason) + " failed with lease time " +
479 (lease_time_given ? "given" : "not given");
480 EXPECT_TRUE(Mock::VerifyAndClearExpectations(this)) << failure_message;
481 EXPECT_EQ(base::StringPrintf("%d.0.0.0", address_octet),
482 config_->properties().address) << failure_message;
483 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled())
484 << failure_message;
485 // With no lease time given, the expiration callback will be cancelled.
486 // With a lease time given, the expiration callback should be started.
487 EXPECT_EQ(!lease_time_given,
488 config_->lease_expiration_callback_.IsCancelled())
489 << failure_message;
490 }
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700491 }
492}
493
Paul Stewart475c0722014-04-18 08:52:00 -0700494TEST_F(DHCPConfigCallbackTest, StoppedDuringFailureCallback) {
495 DHCPConfig::Configuration conf;
496 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
497 0x01020304);
498 // Stop the DHCP config while it is calling the failure callback. We
499 // need to ensure that no callbacks are left running inadvertently as
500 // a result.
501 EXPECT_CALL(*this, FailureCallback(ConfigRef()))
502 .WillOnce(InvokeWithoutArgs(this, &DHCPConfigTest::StopInstance));
503 config_->ProcessEventSignal(DHCPConfig::kReasonFail, conf);
504 EXPECT_TRUE(Mock::VerifyAndClearExpectations(this));
505 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
506 EXPECT_TRUE(config_->lease_expiration_callback_.IsCancelled());
507}
508
509TEST_F(DHCPConfigCallbackTest, StoppedDuringSuccessCallback) {
510 DHCPConfig::Configuration conf;
511 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
512 0x01020304);
513 const uint32 kLeaseTime = 1;
514 conf[DHCPConfig::kConfigurationKeyLeaseTime].writer().append_uint32(
515 kLeaseTime);
516 // Stop the DHCP config while it is calling the success callback. This
517 // can happen if the device has a static IP configuration and releases
518 // the lease after accepting other network parameters from the DHCP
519 // IPConfig properties. We need to ensure that no callbacks are left
520 // running inadvertently as a result.
521 EXPECT_CALL(*this, SuccessCallback(ConfigRef()))
522 .WillOnce(InvokeWithoutArgs(this, &DHCPConfigTest::StopInstance));
523 config_->ProcessEventSignal(DHCPConfig::kReasonBound, conf);
524 EXPECT_TRUE(Mock::VerifyAndClearExpectations(this));
525 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
526 EXPECT_TRUE(config_->lease_expiration_callback_.IsCancelled());
527}
528
Paul Stewartc5099532013-12-12 07:53:15 -0800529TEST_F(DHCPConfigCallbackTest, ProcessEventSignalUnknown) {
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700530 DHCPConfig::Configuration conf;
531 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
532 0x01020304);
533 static const char kReasonUnknown[] = "UNKNOWN_REASON";
Paul Stewartc5099532013-12-12 07:53:15 -0800534 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
535 EXPECT_CALL(*this, FailureCallback(_)).Times(0);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700536 config_->lease_acquisition_timeout_callback_.Reset(base::Bind(&DoNothing));
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700537 config_->ProcessEventSignal(kReasonUnknown, conf);
Paul Stewartc5099532013-12-12 07:53:15 -0800538 Mock::VerifyAndClearExpectations(this);
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700539 EXPECT_TRUE(config_->properties().address.empty());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700540 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700541}
542
Paul Stewartc5099532013-12-12 07:53:15 -0800543TEST_F(DHCPConfigCallbackTest, ProcessEventSignalGatewayArp) {
Paul Stewart94571f12013-09-10 17:26:07 -0700544 DHCPConfig::Configuration conf;
545 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
546 0x01020304);
Paul Stewartc5099532013-12-12 07:53:15 -0800547 EXPECT_CALL(*this, SuccessCallback(ConfigRef()));
548 EXPECT_CALL(*this, FailureCallback(_)).Times(0);
Paul Stewart94571f12013-09-10 17:26:07 -0700549 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(true));
550 config_->Start();
551 config_->ProcessEventSignal(DHCPConfig::kReasonGatewayArp, conf);
Paul Stewartc5099532013-12-12 07:53:15 -0800552 Mock::VerifyAndClearExpectations(this);
Paul Stewart94571f12013-09-10 17:26:07 -0700553 EXPECT_EQ("4.3.2.1", config_->properties().address);
554 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
555 EXPECT_TRUE(config_->is_gateway_arp_active_);
556
557 // If the timeout gets called, we shouldn't lose the lease since GatewayArp
558 // is active.
559 ScopedMockLog log;
560 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
561 EXPECT_CALL(log, Log(_, _, ::testing::EndsWith(
562 "Continuing to use our previous lease, due to gateway-ARP.")));
Paul Stewartc5099532013-12-12 07:53:15 -0800563 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
564 EXPECT_CALL(*this, FailureCallback(_)).Times(0);
Paul Stewart94571f12013-09-10 17:26:07 -0700565 config_->lease_acquisition_timeout_callback_.callback().Run();
Paul Stewartc5099532013-12-12 07:53:15 -0800566 Mock::VerifyAndClearExpectations(this);
Paul Stewart94571f12013-09-10 17:26:07 -0700567 EXPECT_TRUE(config_->is_gateway_arp_active_);
568
569 // An official reply from a DHCP server should reset our GatewayArp state.
Paul Stewartc5099532013-12-12 07:53:15 -0800570 EXPECT_CALL(*this, SuccessCallback(ConfigRef()));
571 EXPECT_CALL(*this, FailureCallback(_)).Times(0);
Paul Stewart94571f12013-09-10 17:26:07 -0700572 config_->ProcessEventSignal(DHCPConfig::kReasonRenew, conf);
Paul Stewartc5099532013-12-12 07:53:15 -0800573 Mock::VerifyAndClearExpectations(this);
Paul Stewart94571f12013-09-10 17:26:07 -0700574 EXPECT_FALSE(config_->is_gateway_arp_active_);
575}
576
Paul Stewartc5099532013-12-12 07:53:15 -0800577TEST_F(DHCPConfigCallbackTest, ProcessEventSignalGatewayArpNak) {
Paul Stewart94571f12013-09-10 17:26:07 -0700578 DHCPConfig::Configuration conf;
579 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
580 0x01020304);
Paul Stewart94571f12013-09-10 17:26:07 -0700581 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(true));
582 config_->Start();
583 config_->ProcessEventSignal(DHCPConfig::kReasonGatewayArp, conf);
584 EXPECT_TRUE(config_->is_gateway_arp_active_);
585
586 // Sending a NAK should clear is_gateway_arp_active_.
587 config_->ProcessEventSignal(DHCPConfig::kReasonNak, conf);
588 EXPECT_FALSE(config_->is_gateway_arp_active_);
Paul Stewartc5099532013-12-12 07:53:15 -0800589 Mock::VerifyAndClearExpectations(this);
Paul Stewart94571f12013-09-10 17:26:07 -0700590
591 // If the timeout gets called, we should lose the lease since GatewayArp
592 // is not active any more.
Paul Stewartc5099532013-12-12 07:53:15 -0800593 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
594 EXPECT_CALL(*this, FailureCallback(ConfigRef()));
Paul Stewart94571f12013-09-10 17:26:07 -0700595 config_->lease_acquisition_timeout_callback_.callback().Run();
Paul Stewartc5099532013-12-12 07:53:15 -0800596 Mock::VerifyAndClearExpectations(this);
Paul Stewart94571f12013-09-10 17:26:07 -0700597}
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700598
Darin Petkov98dd6a02011-06-10 15:12:57 -0700599TEST_F(DHCPConfigTest, ReleaseIP) {
600 config_->pid_ = 1 << 18; // Ensure unknown positive PID.
Paul Stewarta02ee492012-05-16 10:04:53 -0700601 config_->arp_gateway_ = false;
Darin Petkovaceede32011-07-18 15:32:38 -0700602 EXPECT_CALL(*proxy_, Release(kDeviceName)).Times(1);
Darin Petkova7b89492011-07-27 12:48:17 -0700603 config_->proxy_.reset(proxy_.release());
Paul Stewart217c61d2013-06-13 15:12:02 -0700604 EXPECT_TRUE(config_->ReleaseIP(IPConfig::kReleaseReasonDisconnect));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700605 config_->pid_ = 0;
606}
607
Paul Stewarta02ee492012-05-16 10:04:53 -0700608TEST_F(DHCPConfigTest, ReleaseIPArpGW) {
609 config_->pid_ = 1 << 18; // Ensure unknown positive PID.
610 config_->arp_gateway_ = true;
611 EXPECT_CALL(*proxy_, Release(kDeviceName)).Times(0);
612 config_->proxy_.reset(proxy_.release());
Paul Stewart217c61d2013-06-13 15:12:02 -0700613 EXPECT_TRUE(config_->ReleaseIP(IPConfig::kReleaseReasonDisconnect));
614 config_->pid_ = 0;
615}
616
617TEST_F(DHCPConfigTest, ReleaseIPStaticIPWithLease) {
618 config_->pid_ = 1 << 18; // Ensure unknown positive PID.
619 config_->arp_gateway_ = true;
620 config_->is_lease_active_ = true;
621 EXPECT_CALL(*proxy_, Release(kDeviceName));
622 config_->proxy_.reset(proxy_.release());
623 EXPECT_TRUE(config_->ReleaseIP(IPConfig::kReleaseReasonStaticIP));
624 EXPECT_EQ(NULL, config_->proxy_.get());
625 config_->pid_ = 0;
626}
627
628TEST_F(DHCPConfigTest, ReleaseIPStaticIPWithoutLease) {
629 config_->pid_ = 1 << 18; // Ensure unknown positive PID.
630 config_->arp_gateway_ = true;
631 config_->is_lease_active_ = false;
632 EXPECT_CALL(*proxy_, Release(kDeviceName)).Times(0);
633 MockDHCPProxy *proxy_pointer = proxy_.get();
634 config_->proxy_.reset(proxy_.release());
635 EXPECT_TRUE(config_->ReleaseIP(IPConfig::kReleaseReasonStaticIP));
636 // Expect that proxy has not been released.
637 EXPECT_EQ(proxy_pointer, config_->proxy_.get());
Paul Stewarta02ee492012-05-16 10:04:53 -0700638 config_->pid_ = 0;
639}
640
Darin Petkov98dd6a02011-06-10 15:12:57 -0700641TEST_F(DHCPConfigTest, RenewIP) {
Paul Stewart21f7b342013-11-19 10:15:58 -0800642 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(false));
643 config_->pid_ = 0;
644 EXPECT_FALSE(config_->RenewIP()); // Expect a call to Start() if pid_ is 0.
645 Mock::VerifyAndClearExpectations(minijail_.get());
646 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).Times(0);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700647 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Paul Stewart1f916e42013-12-23 09:52:54 -0800648 config_->lease_expiration_callback_.Reset(base::Bind(&DoNothing));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700649 config_->pid_ = 456;
Paul Stewartc02344a2012-08-17 16:57:37 -0700650 EXPECT_FALSE(config_->RenewIP()); // Expect no crash with NULL proxy.
Darin Petkovaceede32011-07-18 15:32:38 -0700651 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
Darin Petkova7b89492011-07-27 12:48:17 -0700652 config_->proxy_.reset(proxy_.release());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700653 EXPECT_TRUE(config_->RenewIP());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700654 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Paul Stewart1f916e42013-12-23 09:52:54 -0800655 EXPECT_TRUE(config_->lease_expiration_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700656 config_->pid_ = 0;
657}
658
659TEST_F(DHCPConfigTest, RequestIP) {
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700660 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700661 config_->pid_ = 567;
Darin Petkovaceede32011-07-18 15:32:38 -0700662 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
Darin Petkova7b89492011-07-27 12:48:17 -0700663 config_->proxy_.reset(proxy_.release());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700664 EXPECT_TRUE(config_->RenewIP());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700665 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
666 config_->pid_ = 0;
667}
668
Paul Stewartc5099532013-12-12 07:53:15 -0800669TEST_F(DHCPConfigCallbackTest, RequestIPTimeout) {
670 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
671 EXPECT_CALL(*this, FailureCallback(ConfigRef()));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700672 config_->lease_acquisition_timeout_seconds_ = 0;
673 config_->pid_ = 567;
674 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
675 config_->proxy_.reset(proxy_.release());
676 config_->RenewIP();
677 config_->dispatcher_->DispatchPendingEvents();
Paul Stewartc5099532013-12-12 07:53:15 -0800678 Mock::VerifyAndClearExpectations(this);
Darin Petkov98dd6a02011-06-10 15:12:57 -0700679 config_->pid_ = 0;
680}
681
682TEST_F(DHCPConfigTest, Restart) {
683 const int kPID1 = 1 << 17; // Ensure unknown positive PID.
684 const int kPID2 = 987;
685 const unsigned int kTag1 = 11;
686 const unsigned int kTag2 = 22;
687 config_->pid_ = kPID1;
688 config_->child_watch_tag_ = kTag1;
689 DHCPProvider::GetInstance()->BindPID(kPID1, config_);
Chris Masone2176a882011-09-14 22:29:15 -0700690 EXPECT_CALL(*glib(), SourceRemove(kTag1)).WillOnce(Return(true));
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700691 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(
692 DoAll(SetArgumentPointee<2>(kPID2), Return(true)));
Chris Masone2176a882011-09-14 22:29:15 -0700693 EXPECT_CALL(*glib(), ChildWatchAdd(kPID2, _, _)).WillOnce(Return(kTag2));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700694 EXPECT_TRUE(config_->Restart());
695 EXPECT_EQ(kPID2, config_->pid_);
696 EXPECT_EQ(config_.get(), DHCPProvider::GetInstance()->GetConfig(kPID2).get());
697 EXPECT_EQ(kTag2, config_->child_watch_tag_);
698 DHCPProvider::GetInstance()->UnbindPID(kPID2);
699 config_->pid_ = 0;
700 config_->child_watch_tag_ = 0;
701}
702
703TEST_F(DHCPConfigTest, RestartNoClient) {
704 const int kPID = 777;
705 const unsigned int kTag = 66;
Chris Masone2176a882011-09-14 22:29:15 -0700706 EXPECT_CALL(*glib(), SourceRemove(_)).Times(0);
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700707 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(
708 DoAll(SetArgumentPointee<2>(kPID), Return(true)));
Chris Masone2176a882011-09-14 22:29:15 -0700709 EXPECT_CALL(*glib(), ChildWatchAdd(kPID, _, _)).WillOnce(Return(kTag));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700710 EXPECT_TRUE(config_->Restart());
711 EXPECT_EQ(kPID, config_->pid_);
712 EXPECT_EQ(config_.get(), DHCPProvider::GetInstance()->GetConfig(kPID).get());
713 EXPECT_EQ(kTag, config_->child_watch_tag_);
714 DHCPProvider::GetInstance()->UnbindPID(kPID);
715 config_->pid_ = 0;
716 config_->child_watch_tag_ = 0;
717}
718
Paul Stewartd408fdf2012-05-07 17:15:57 -0700719TEST_F(DHCPConfigTest, StartSuccessEphemeral) {
720 DHCPConfigRefPtr config =
Paul Stewart75a68b92013-10-24 10:50:27 -0700721 CreateRunningConfig(kHostName, kDeviceName, kArpGateway, !kMinimalConfig);
Paul Stewartd408fdf2012-05-07 17:15:57 -0700722 StopRunningConfigAndExpect(config, false);
723}
Darin Petkov92c43902011-06-09 20:46:06 -0700724
Paul Stewartd408fdf2012-05-07 17:15:57 -0700725TEST_F(DHCPConfigTest, StartSuccessPersistent) {
726 DHCPConfigRefPtr config =
Paul Stewart75a68b92013-10-24 10:50:27 -0700727 CreateRunningConfig(kHostName, kLeaseFileSuffix, kArpGateway,
728 !kMinimalConfig);
Paul Stewartd408fdf2012-05-07 17:15:57 -0700729 StopRunningConfigAndExpect(config, true);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700730}
731
Paul Stewartc5099532013-12-12 07:53:15 -0800732TEST_F(DHCPConfigCallbackTest, StartTimeout) {
733 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
734 EXPECT_CALL(*this, FailureCallback(ConfigRef()));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700735 config_->lease_acquisition_timeout_seconds_ = 0;
736 config_->proxy_.reset(proxy_.release());
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700737 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(true));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700738 config_->Start();
739 config_->dispatcher_->DispatchPendingEvents();
Paul Stewartc5099532013-12-12 07:53:15 -0800740 Mock::VerifyAndClearExpectations(this);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700741}
742
Darin Petkov98dd6a02011-06-10 15:12:57 -0700743TEST_F(DHCPConfigTest, Stop) {
Darin Petkov98dd6a02011-06-10 15:12:57 -0700744 const int kPID = 1 << 17; // Ensure unknown positive PID.
mukesh agrawal1835e772013-01-15 18:35:03 -0800745 ScopedMockLog log;
746 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
747 EXPECT_CALL(log, Log(_, _, ContainsRegex(
Darin Petkov3fe17662013-02-04 14:19:08 +0100748 base::StringPrintf("Stopping.+%s", __func__))));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700749 config_->pid_ = kPID;
Darin Petkov3fe17662013-02-04 14:19:08 +0100750 DHCPProvider::GetInstance()->BindPID(kPID, config_);
Paul Stewart1f916e42013-12-23 09:52:54 -0800751 config_->lease_acquisition_timeout_callback_.Reset(base::Bind(&DoNothing));
752 config_->lease_expiration_callback_.Reset(base::Bind(&DoNothing));
mukesh agrawal1835e772013-01-15 18:35:03 -0800753 config_->Stop(__func__);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700754 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Paul Stewart1f916e42013-12-23 09:52:54 -0800755 EXPECT_TRUE(config_->lease_expiration_callback_.IsCancelled());
Darin Petkov3fe17662013-02-04 14:19:08 +0100756 EXPECT_FALSE(DHCPProvider::GetInstance()->GetConfig(kPID));
757 EXPECT_FALSE(config_->pid_);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700758}
759
760TEST_F(DHCPConfigTest, StopDuringRequestIP) {
761 config_->pid_ = 567;
762 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
763 config_->proxy_.reset(proxy_.release());
764 EXPECT_TRUE(config_->RenewIP());
765 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
766 config_->pid_ = 0; // Keep Stop from killing a real process.
mukesh agrawal1835e772013-01-15 18:35:03 -0800767 config_->Stop(__func__);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700768 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700769}
770
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800771TEST_F(DHCPConfigTest, SetProperty) {
Chris Masone43b48a12011-07-01 13:37:07 -0700772 ::DBus::Error error;
773 // Ensure that an attempt to write a R/O property returns InvalidArgs error.
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800774 EXPECT_FALSE(DBusAdaptor::SetProperty(config_->mutable_store(),
Ben Chan0295e0f2013-09-20 13:47:29 -0700775 kAddressProperty,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800776 PropertyStoreTest::kStringV,
777 &error));
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700778 ASSERT_TRUE(error.is_set()); // name() may be invalid otherwise
Chris Masone9d779932011-08-25 16:33:41 -0700779 EXPECT_EQ(invalid_args(), error.name());
Chris Masone43b48a12011-07-01 13:37:07 -0700780}
781
Darin Petkove7cb7f82011-06-03 13:21:51 -0700782} // namespace shill