blob: c449ae3b2cfce4fe52a62685d4ce45ad87f61ecd [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 Stewart21f7b342013-11-19 10:15:58 -080034using testing::Mock;
Darin Petkovf7897bc2011-06-08 17:13:36 -070035using testing::Return;
36using testing::SetArgumentPointee;
Darin Petkove7cb7f82011-06-03 13:21:51 -070037using testing::Test;
38
39namespace shill {
40
Darin Petkov92c43902011-06-09 20:46:06 -070041namespace {
Darin Petkova7b89492011-07-27 12:48:17 -070042const char kDeviceName[] = "eth0";
Paul Stewartd32f4842012-01-11 16:08:13 -080043const char kHostName[] = "hostname";
Paul Stewartd408fdf2012-05-07 17:15:57 -070044const char kLeaseFileSuffix[] = "leasefilesuffix";
45const bool kArpGateway = true;
Paul Stewart75a68b92013-10-24 10:50:27 -070046const bool kHasHostname = true;
47const bool kHasLeaseSuffix = true;
48const bool kMinimalConfig = true;
Darin Petkov92c43902011-06-09 20:46:06 -070049} // namespace {}
50
Chris Masone43b48a12011-07-01 13:37:07 -070051class DHCPConfigTest : public PropertyStoreTest {
Darin Petkove7cb7f82011-06-03 13:21:51 -070052 public:
Darin Petkovf7897bc2011-06-08 17:13:36 -070053 DHCPConfigTest()
Darin Petkovf65e9282011-06-21 14:29:56 -070054 : proxy_(new MockDHCPProxy()),
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070055 minijail_(new MockMinijail()),
Chris Masone19e30402011-07-19 15:48:47 -070056 config_(new DHCPConfig(&control_,
Chris Masone2176a882011-09-14 22:29:15 -070057 dispatcher(),
Chris Masone19e30402011-07-19 15:48:47 -070058 DHCPProvider::GetInstance(),
Darin Petkov92c43902011-06-09 20:46:06 -070059 kDeviceName,
Paul Stewartd32f4842012-01-11 16:08:13 -080060 kHostName,
Paul Stewartd408fdf2012-05-07 17:15:57 -070061 kLeaseFileSuffix,
62 kArpGateway,
Paul Stewart75a68b92013-10-24 10:50:27 -070063 !kMinimalConfig,
Chris Masone2176a882011-09-14 22:29:15 -070064 glib())) {}
Darin Petkova7b89492011-07-27 12:48:17 -070065
66 virtual void SetUp() {
Darin Petkovab565bb2011-10-06 02:55:51 -070067 config_->proxy_factory_ = &proxy_factory_;
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070068 config_->minijail_ = minijail_.get();
Darin Petkova7b89492011-07-27 12:48:17 -070069 }
70
71 virtual void TearDown() {
Darin Petkovab565bb2011-10-06 02:55:51 -070072 config_->proxy_factory_ = NULL;
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070073 config_->minijail_ = NULL;
Darin Petkov98dd6a02011-06-10 15:12:57 -070074 }
Darin Petkove7cb7f82011-06-03 13:21:51 -070075
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070076 DHCPConfigRefPtr CreateMockMinijailConfig(const string &hostname,
Paul Stewart75a68b92013-10-24 10:50:27 -070077 const string &lease_suffix,
78 bool arp_gateway,
79 bool minimal_config);
Paul Stewartd408fdf2012-05-07 17:15:57 -070080 DHCPConfigRefPtr CreateRunningConfig(const string &hostname,
81 const string &lease_suffix,
Paul Stewart75a68b92013-10-24 10:50:27 -070082 bool arp_gateway,
83 bool minimal_config);
Paul Stewartd408fdf2012-05-07 17:15:57 -070084 void StopRunningConfigAndExpect(DHCPConfigRefPtr config,
85 bool lease_file_exists);
86
Darin Petkove7cb7f82011-06-03 13:21:51 -070087 protected:
Paul Stewartd408fdf2012-05-07 17:15:57 -070088 static const int kPID;
89 static const unsigned int kTag;
90
91 FilePath lease_file_;
92 FilePath pid_file_;
93 ScopedTempDir temp_dir_;
Darin Petkova7b89492011-07-27 12:48:17 -070094 scoped_ptr<MockDHCPProxy> proxy_;
Ben Chana55469d2014-01-27 16:35:29 -080095 MockProxyFactory proxy_factory_;
Chris Masone19e30402011-07-19 15:48:47 -070096 MockControl control_;
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070097 scoped_ptr<MockMinijail> minijail_;
Darin Petkovf7897bc2011-06-08 17:13:36 -070098 DHCPConfigRefPtr config_;
Darin Petkove7cb7f82011-06-03 13:21:51 -070099};
100
Paul Stewartd408fdf2012-05-07 17:15:57 -0700101const int DHCPConfigTest::kPID = 123456;
102const unsigned int DHCPConfigTest::kTag = 77;
103
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700104DHCPConfigRefPtr DHCPConfigTest::CreateMockMinijailConfig(
Paul Stewart75a68b92013-10-24 10:50:27 -0700105 const string &hostname,
106 const string &lease_suffix,
107 bool arp_gateway,
108 bool minimal_config) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700109 DHCPConfigRefPtr config(new DHCPConfig(&control_,
110 dispatcher(),
111 DHCPProvider::GetInstance(),
112 kDeviceName,
113 hostname,
114 lease_suffix,
115 arp_gateway,
Paul Stewart75a68b92013-10-24 10:50:27 -0700116 minimal_config,
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700117 glib()));
118 config->minijail_ = minijail_.get();
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700119
120 return config;
121}
122
Paul Stewart75a68b92013-10-24 10:50:27 -0700123DHCPConfigRefPtr DHCPConfigTest::CreateRunningConfig(
124 const string &hostname,
125 const string &lease_suffix,
126 bool arp_gateway,
127 bool minimal_config) {
Paul Stewartd408fdf2012-05-07 17:15:57 -0700128 DHCPConfigRefPtr config(new DHCPConfig(&control_,
129 dispatcher(),
130 DHCPProvider::GetInstance(),
131 kDeviceName,
132 hostname,
133 lease_suffix,
134 arp_gateway,
Paul Stewart75a68b92013-10-24 10:50:27 -0700135 minimal_config,
Paul Stewartd408fdf2012-05-07 17:15:57 -0700136 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");
Ben Chana0ddf462014-02-06 11:32:42 -0800149 EXPECT_TRUE(base::CreateDirectory(varrun));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700150 pid_file_ = varrun.Append(base::StringPrintf("dhcpcd-%s.pid", kDeviceName));
151 FilePath varlib = temp_dir_.path().Append("var/lib/dhcpcd");
Ben Chana0ddf462014-02-06 11:32:42 -0800152 EXPECT_TRUE(base::CreateDirectory(varlib));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700153 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));
Ben Chana0ddf462014-02-06 11:32:42 -0800157 EXPECT_TRUE(base::PathExists(pid_file_));
158 EXPECT_TRUE(base::PathExists(lease_file_));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700159
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
Ben Chana0ddf462014-02-06 11:32:42 -0800171 EXPECT_FALSE(base::PathExists(pid_file_));
172 EXPECT_EQ(lease_file_exists, base::PathExists(lease_file_));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700173}
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());
Ben Chana55469d2014-01-27 16:35:29 -0800185 EXPECT_CALL(proxy_factory_, CreateDHCPProxy(kService))
186 .WillOnce(ReturnAndReleasePointee(&proxy_));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500187 config_->InitProxy(kService);
Darin Petkova7b89492011-07-27 12:48:17 -0700188 EXPECT_FALSE(proxy_.get());
189 EXPECT_TRUE(config_->proxy_.get());
190
191 config_->InitProxy(kService);
Darin Petkova7b89492011-07-27 12:48:17 -0700192}
193
Paul Stewart65bcd082012-11-16 09:37:14 -0800194TEST_F(DHCPConfigTest, ParseClasslessStaticRoutes) {
195 const string kDefaultAddress = "0.0.0.0";
196 const string kDefaultDestination = kDefaultAddress + "/0";
197 const string kRouter0 = "10.0.0.254";
198 const string kAddress1 = "192.168.1.0";
199 const string kDestination1 = kAddress1 + "/24";
200 // Last gateway missing, leaving an odd number of parameters.
201 const string kBrokenClasslessRoutes0 = kDefaultDestination + " " + kRouter0 +
202 " " + kDestination1;
203 IPConfig::Properties properties;
204 EXPECT_FALSE(DHCPConfig::ParseClasslessStaticRoutes(kBrokenClasslessRoutes0,
205 &properties));
206 EXPECT_TRUE(properties.routes.empty());
207 EXPECT_TRUE(properties.gateway.empty());
208
209 // Gateway argument for the second route is malformed, but we were able
210 // to salvage a default gateway.
211 const string kBrokenRouter1 = "10.0.0";
212 const string kBrokenClasslessRoutes1 = kBrokenClasslessRoutes0 + " " +
213 kBrokenRouter1;
214 EXPECT_FALSE(DHCPConfig::ParseClasslessStaticRoutes(kBrokenClasslessRoutes1,
215 &properties));
216 EXPECT_TRUE(properties.routes.empty());
217 EXPECT_EQ(kRouter0, properties.gateway);
218
219 const string kRouter1 = "10.0.0.253";
220 const string kRouter2 = "10.0.0.252";
221 const string kClasslessRoutes0 = kDefaultDestination + " " + kRouter2 + " " +
222 kDestination1 + " " + kRouter1;
223 EXPECT_TRUE(DHCPConfig::ParseClasslessStaticRoutes(kClasslessRoutes0,
224 &properties));
225 // The old default route is preserved.
226 EXPECT_EQ(kRouter0, properties.gateway);
227
228 // The two routes (including the one which would have otherwise been
229 // classified as a default route) are added to the routing table.
230 EXPECT_EQ(2, properties.routes.size());
231 const IPConfig::Route &route0 = properties.routes[0];
232 EXPECT_EQ(kDefaultAddress, route0.host);
233 EXPECT_EQ("0.0.0.0", route0.netmask);
234 EXPECT_EQ(kRouter2, route0.gateway);
235
236 const IPConfig::Route &route1 = properties.routes[1];
237 EXPECT_EQ(kAddress1, route1.host);
238 EXPECT_EQ("255.255.255.0", route1.netmask);
239 EXPECT_EQ(kRouter1, route1.gateway);
240
241 // A malformed routing table should not affect the current table.
242 EXPECT_FALSE(DHCPConfig::ParseClasslessStaticRoutes(kBrokenClasslessRoutes1,
243 &properties));
244 EXPECT_EQ(2, properties.routes.size());
245 EXPECT_EQ(kRouter0, properties.gateway);
246}
247
Darin Petkove7cb7f82011-06-03 13:21:51 -0700248TEST_F(DHCPConfigTest, ParseConfiguration) {
249 DHCPConfig::Configuration conf;
250 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
251 0x01020304);
252 conf[DHCPConfig::kConfigurationKeySubnetCIDR].writer().append_byte(
253 16);
254 conf[DHCPConfig::kConfigurationKeyBroadcastAddress].writer().append_uint32(
255 0x10203040);
256 {
Darin Petkove7cb7f82011-06-03 13:21:51 -0700257 vector<unsigned int> routers;
258 routers.push_back(0x02040608);
259 routers.push_back(0x03050709);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700260 DBus::MessageIter writer =
261 conf[DHCPConfig::kConfigurationKeyRouters].writer();
Darin Petkove7cb7f82011-06-03 13:21:51 -0700262 writer << routers;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700263 }
264 {
Darin Petkove7cb7f82011-06-03 13:21:51 -0700265 vector<unsigned int> dns;
266 dns.push_back(0x09070503);
267 dns.push_back(0x08060402);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700268 DBus::MessageIter writer = conf[DHCPConfig::kConfigurationKeyDNS].writer();
Darin Petkove7cb7f82011-06-03 13:21:51 -0700269 writer << dns;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700270 }
271 conf[DHCPConfig::kConfigurationKeyDomainName].writer().append_string(
272 "domain-name");
273 {
Darin Petkove7cb7f82011-06-03 13:21:51 -0700274 vector<string> search;
275 search.push_back("foo.com");
276 search.push_back("bar.com");
Darin Petkovf7897bc2011-06-08 17:13:36 -0700277 DBus::MessageIter writer =
278 conf[DHCPConfig::kConfigurationKeyDomainSearch].writer();
Darin Petkove7cb7f82011-06-03 13:21:51 -0700279 writer << search;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700280 }
281 conf[DHCPConfig::kConfigurationKeyMTU].writer().append_uint16(600);
282 conf["UnknownKey"] = DBus::Variant();
283
Darin Petkove7cb7f82011-06-03 13:21:51 -0700284 IPConfig::Properties properties;
Darin Petkovf7897bc2011-06-08 17:13:36 -0700285 ASSERT_TRUE(config_->ParseConfiguration(conf, &properties));
Darin Petkove7cb7f82011-06-03 13:21:51 -0700286 EXPECT_EQ("4.3.2.1", properties.address);
Paul Stewart48100b02012-03-19 07:53:52 -0700287 EXPECT_EQ(16, properties.subnet_prefix);
Darin Petkove7cb7f82011-06-03 13:21:51 -0700288 EXPECT_EQ("64.48.32.16", properties.broadcast_address);
289 EXPECT_EQ("8.6.4.2", properties.gateway);
290 ASSERT_EQ(2, properties.dns_servers.size());
291 EXPECT_EQ("3.5.7.9", properties.dns_servers[0]);
292 EXPECT_EQ("2.4.6.8", properties.dns_servers[1]);
293 EXPECT_EQ("domain-name", properties.domain_name);
294 ASSERT_EQ(2, properties.domain_search.size());
295 EXPECT_EQ("foo.com", properties.domain_search[0]);
296 EXPECT_EQ("bar.com", properties.domain_search[1]);
297 EXPECT_EQ(600, properties.mtu);
298}
299
Darin Petkov92c43902011-06-09 20:46:06 -0700300TEST_F(DHCPConfigTest, StartFail) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700301 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(false));
Chris Masone2176a882011-09-14 22:29:15 -0700302 EXPECT_CALL(*glib(), ChildWatchAdd(_, _, _)).Times(0);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700303 EXPECT_FALSE(config_->Start());
304 EXPECT_EQ(0, config_->pid_);
Darin Petkov92c43902011-06-09 20:46:06 -0700305}
Darin Petkovf7897bc2011-06-08 17:13:36 -0700306
Paul Stewart75a68b92013-10-24 10:50:27 -0700307MATCHER_P4(IsDHCPCDArgs, has_hostname, has_arp_gateway, has_lease_suffix,
308 has_minimal_config, "") {
Paul Stewartd32f4842012-01-11 16:08:13 -0800309 if (string(arg[0]) != "/sbin/dhcpcd" ||
Paul Stewart75a68b92013-10-24 10:50:27 -0700310 string(arg[1]) != "-B" ||
311 string(arg[2]) != "-q") {
Paul Stewartd32f4842012-01-11 16:08:13 -0800312 return false;
313 }
314
Paul Stewart75a68b92013-10-24 10:50:27 -0700315 int end_offset = 3;
Paul Stewartd32f4842012-01-11 16:08:13 -0800316 if (has_hostname) {
Paul Stewartd408fdf2012-05-07 17:15:57 -0700317 if (string(arg[end_offset]) != "-h" ||
318 string(arg[end_offset + 1]) != kHostName) {
Paul Stewartd32f4842012-01-11 16:08:13 -0800319 return false;
320 }
Paul Stewartd408fdf2012-05-07 17:15:57 -0700321 end_offset += 2;
Paul Stewartd32f4842012-01-11 16:08:13 -0800322 }
323
Paul Stewartd408fdf2012-05-07 17:15:57 -0700324 if (has_arp_gateway) {
Paul Stewart75a68b92013-10-24 10:50:27 -0700325 if (string(arg[end_offset]) != "-R" ||
326 string(arg[end_offset + 1]) != "-U") {
Paul Stewartd408fdf2012-05-07 17:15:57 -0700327 return false;
Paul Stewart75a68b92013-10-24 10:50:27 -0700328 }
329 end_offset += 2;
330 }
331
332 if (has_minimal_config) {
333 if (string(arg[end_offset]) != "-f" ||
334 string(arg[end_offset + 1]) != "/etc/dhcpcd-minimal.conf") {
335 return false;
336 }
337 end_offset += 2;
Paul Stewartd408fdf2012-05-07 17:15:57 -0700338 }
339
340 string device_arg = has_lease_suffix ?
341 string(kDeviceName) + "=" + string(kLeaseFileSuffix) : kDeviceName;
342 return string(arg[end_offset]) == device_arg && arg[end_offset + 1] == NULL;
Paul Stewartd32f4842012-01-11 16:08:13 -0800343}
344
345TEST_F(DHCPConfigTest, StartWithHostname) {
Paul Stewart75a68b92013-10-24 10:50:27 -0700346 EXPECT_CALL(*minijail_, RunAndDestroy(_, IsDHCPCDArgs(kHasHostname,
347 kArpGateway,
348 kHasLeaseSuffix,
349 !kMinimalConfig), _))
350 .WillOnce(Return(false));
Paul Stewartd32f4842012-01-11 16:08:13 -0800351 EXPECT_FALSE(config_->Start());
352}
353
354TEST_F(DHCPConfigTest, StartWithoutHostname) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700355 DHCPConfigRefPtr config = CreateMockMinijailConfig("",
356 kLeaseFileSuffix,
Paul Stewart75a68b92013-10-24 10:50:27 -0700357 kArpGateway,
358 !kMinimalConfig);
359 EXPECT_CALL(*minijail_, RunAndDestroy(_, IsDHCPCDArgs(!kHasHostname,
360 kArpGateway,
361 kHasLeaseSuffix,
362 !kMinimalConfig), _))
363 .WillOnce(Return(false));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700364 EXPECT_FALSE(config->Start());
365}
366
367TEST_F(DHCPConfigTest, StartWithoutArpGateway) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700368 DHCPConfigRefPtr config = CreateMockMinijailConfig(kHostName,
369 kLeaseFileSuffix,
Paul Stewart75a68b92013-10-24 10:50:27 -0700370 !kArpGateway,
371 !kMinimalConfig);
372 EXPECT_CALL(*minijail_, RunAndDestroy(_, IsDHCPCDArgs(kHasHostname,
373 !kArpGateway,
374 kHasLeaseSuffix,
375 !kMinimalConfig), _))
376 .WillOnce(Return(false));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700377 EXPECT_FALSE(config->Start());
378}
379
380TEST_F(DHCPConfigTest, StartWithoutLeaseSuffix) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700381 DHCPConfigRefPtr config = CreateMockMinijailConfig(kHostName,
382 kDeviceName,
Paul Stewart75a68b92013-10-24 10:50:27 -0700383 kArpGateway,
384 !kMinimalConfig);
385 EXPECT_CALL(*minijail_, RunAndDestroy(_, IsDHCPCDArgs(kHasHostname,
386 kArpGateway,
387 !kHasLeaseSuffix,
388 !kMinimalConfig), _))
389 .WillOnce(Return(false));
390 EXPECT_FALSE(config->Start());
391}
392
393TEST_F(DHCPConfigTest, StartWithMinimalConfig) {
394 DHCPConfigRefPtr config = CreateMockMinijailConfig(kHostName,
395 kLeaseFileSuffix,
396 kArpGateway,
397 kMinimalConfig);
398 EXPECT_CALL(*minijail_, RunAndDestroy(_, IsDHCPCDArgs(kHasHostname,
399 kArpGateway,
400 kHasLeaseSuffix,
401 kMinimalConfig), _))
402 .WillOnce(Return(false));
Paul Stewartd32f4842012-01-11 16:08:13 -0800403 EXPECT_FALSE(config->Start());
404}
405
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700406namespace {
407
Paul Stewartc5099532013-12-12 07:53:15 -0800408class DHCPConfigCallbackTest : public DHCPConfigTest {
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700409 public:
Paul Stewartc5099532013-12-12 07:53:15 -0800410 virtual void SetUp() {
411 DHCPConfigTest::SetUp();
412 config_->RegisterUpdateCallback(
413 Bind(&DHCPConfigCallbackTest::SuccessCallback, Unretained(this)));
414 config_->RegisterFailureCallback(
415 Bind(&DHCPConfigCallbackTest::FailureCallback, Unretained(this)));
416 ip_config_ = config_;
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700417 }
418
Paul Stewartc5099532013-12-12 07:53:15 -0800419 MOCK_METHOD1(SuccessCallback, void(const IPConfigRefPtr &ipconfig));
420 MOCK_METHOD1(FailureCallback, void(const IPConfigRefPtr &ipconfig));
421
422 // The mock methods above take IPConfigRefPtr because this is the type
423 // that the registered callbacks take. This conversion of the DHCP
424 // config ref pointer eases our work in setting up expectations.
425 const IPConfigRefPtr &ConfigRef() { return ip_config_; }
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700426
427 private:
Paul Stewartc5099532013-12-12 07:53:15 -0800428 IPConfigRefPtr ip_config_;
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700429};
430
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700431void DoNothing() {}
432
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700433} // namespace {}
434
Paul Stewartc5099532013-12-12 07:53:15 -0800435TEST_F(DHCPConfigCallbackTest, ProcessEventSignalFail) {
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700436 DHCPConfig::Configuration conf;
437 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
438 0x01020304);
Paul Stewartc5099532013-12-12 07:53:15 -0800439 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
440 EXPECT_CALL(*this, FailureCallback(ConfigRef()));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700441 config_->lease_acquisition_timeout_callback_.Reset(base::Bind(&DoNothing));
Paul Stewart1f916e42013-12-23 09:52:54 -0800442 config_->lease_expiration_callback_.Reset(base::Bind(&DoNothing));
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700443 config_->ProcessEventSignal(DHCPConfig::kReasonFail, conf);
Paul Stewartc5099532013-12-12 07:53:15 -0800444 Mock::VerifyAndClearExpectations(this);
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700445 EXPECT_TRUE(config_->properties().address.empty());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700446 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Paul Stewart1f916e42013-12-23 09:52:54 -0800447 EXPECT_TRUE(config_->lease_expiration_callback_.IsCancelled());
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700448}
449
Paul Stewartc5099532013-12-12 07:53:15 -0800450TEST_F(DHCPConfigCallbackTest, ProcessEventSignalSuccess) {
Paul Stewart1f916e42013-12-23 09:52:54 -0800451 for (const auto &reason : { DHCPConfig::kReasonBound,
452 DHCPConfig::kReasonRebind,
453 DHCPConfig::kReasonReboot,
454 DHCPConfig::kReasonRenew }) {
455 int address_octet = 0;
456 for (const auto lease_time_given : { false, true }) {
457 DHCPConfig::Configuration conf;
458 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
459 ++address_octet);
460 if (lease_time_given) {
461 const uint32 kLeaseTime = 1;
462 conf[DHCPConfig::kConfigurationKeyLeaseTime].writer().append_uint32(
463 kLeaseTime);
464 config_->lease_expiration_callback_.Cancel();
465 } else {
466 config_->lease_expiration_callback_.Reset(base::Bind(&DoNothing));
467 }
468 config_->lease_acquisition_timeout_callback_.Reset(
469 base::Bind(&DoNothing));
470 EXPECT_CALL(*this, SuccessCallback(ConfigRef()));
471 EXPECT_CALL(*this, FailureCallback(_)).Times(0);
472 config_->ProcessEventSignal(reason, conf);
473 string failure_message = string(reason) + " failed with lease time " +
474 (lease_time_given ? "given" : "not given");
475 EXPECT_TRUE(Mock::VerifyAndClearExpectations(this)) << failure_message;
476 EXPECT_EQ(base::StringPrintf("%d.0.0.0", address_octet),
477 config_->properties().address) << failure_message;
478 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled())
479 << failure_message;
480 // With no lease time given, the expiration callback will be cancelled.
481 // With a lease time given, the expiration callback should be started.
482 EXPECT_EQ(!lease_time_given,
483 config_->lease_expiration_callback_.IsCancelled())
484 << failure_message;
485 }
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700486 }
487}
488
Paul Stewartc5099532013-12-12 07:53:15 -0800489TEST_F(DHCPConfigCallbackTest, ProcessEventSignalUnknown) {
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700490 DHCPConfig::Configuration conf;
491 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
492 0x01020304);
493 static const char kReasonUnknown[] = "UNKNOWN_REASON";
Paul Stewartc5099532013-12-12 07:53:15 -0800494 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
495 EXPECT_CALL(*this, FailureCallback(_)).Times(0);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700496 config_->lease_acquisition_timeout_callback_.Reset(base::Bind(&DoNothing));
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700497 config_->ProcessEventSignal(kReasonUnknown, conf);
Paul Stewartc5099532013-12-12 07:53:15 -0800498 Mock::VerifyAndClearExpectations(this);
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700499 EXPECT_TRUE(config_->properties().address.empty());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700500 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700501}
502
Paul Stewartc5099532013-12-12 07:53:15 -0800503TEST_F(DHCPConfigCallbackTest, ProcessEventSignalGatewayArp) {
Paul Stewart94571f12013-09-10 17:26:07 -0700504 DHCPConfig::Configuration conf;
505 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
506 0x01020304);
Paul Stewartc5099532013-12-12 07:53:15 -0800507 EXPECT_CALL(*this, SuccessCallback(ConfigRef()));
508 EXPECT_CALL(*this, FailureCallback(_)).Times(0);
Paul Stewart94571f12013-09-10 17:26:07 -0700509 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(true));
510 config_->Start();
511 config_->ProcessEventSignal(DHCPConfig::kReasonGatewayArp, conf);
Paul Stewartc5099532013-12-12 07:53:15 -0800512 Mock::VerifyAndClearExpectations(this);
Paul Stewart94571f12013-09-10 17:26:07 -0700513 EXPECT_EQ("4.3.2.1", config_->properties().address);
514 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
515 EXPECT_TRUE(config_->is_gateway_arp_active_);
516
517 // If the timeout gets called, we shouldn't lose the lease since GatewayArp
518 // is active.
519 ScopedMockLog log;
520 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
521 EXPECT_CALL(log, Log(_, _, ::testing::EndsWith(
522 "Continuing to use our previous lease, due to gateway-ARP.")));
Paul Stewartc5099532013-12-12 07:53:15 -0800523 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
524 EXPECT_CALL(*this, FailureCallback(_)).Times(0);
Paul Stewart94571f12013-09-10 17:26:07 -0700525 config_->lease_acquisition_timeout_callback_.callback().Run();
Paul Stewartc5099532013-12-12 07:53:15 -0800526 Mock::VerifyAndClearExpectations(this);
Paul Stewart94571f12013-09-10 17:26:07 -0700527 EXPECT_TRUE(config_->is_gateway_arp_active_);
528
529 // An official reply from a DHCP server should reset our GatewayArp state.
Paul Stewartc5099532013-12-12 07:53:15 -0800530 EXPECT_CALL(*this, SuccessCallback(ConfigRef()));
531 EXPECT_CALL(*this, FailureCallback(_)).Times(0);
Paul Stewart94571f12013-09-10 17:26:07 -0700532 config_->ProcessEventSignal(DHCPConfig::kReasonRenew, conf);
Paul Stewartc5099532013-12-12 07:53:15 -0800533 Mock::VerifyAndClearExpectations(this);
Paul Stewart94571f12013-09-10 17:26:07 -0700534 EXPECT_FALSE(config_->is_gateway_arp_active_);
535}
536
Paul Stewartc5099532013-12-12 07:53:15 -0800537TEST_F(DHCPConfigCallbackTest, ProcessEventSignalGatewayArpNak) {
Paul Stewart94571f12013-09-10 17:26:07 -0700538 DHCPConfig::Configuration conf;
539 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
540 0x01020304);
Paul Stewart94571f12013-09-10 17:26:07 -0700541 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(true));
542 config_->Start();
543 config_->ProcessEventSignal(DHCPConfig::kReasonGatewayArp, conf);
544 EXPECT_TRUE(config_->is_gateway_arp_active_);
545
546 // Sending a NAK should clear is_gateway_arp_active_.
547 config_->ProcessEventSignal(DHCPConfig::kReasonNak, conf);
548 EXPECT_FALSE(config_->is_gateway_arp_active_);
Paul Stewartc5099532013-12-12 07:53:15 -0800549 Mock::VerifyAndClearExpectations(this);
Paul Stewart94571f12013-09-10 17:26:07 -0700550
551 // If the timeout gets called, we should lose the lease since GatewayArp
552 // is not active any more.
Paul Stewartc5099532013-12-12 07:53:15 -0800553 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
554 EXPECT_CALL(*this, FailureCallback(ConfigRef()));
Paul Stewart94571f12013-09-10 17:26:07 -0700555 config_->lease_acquisition_timeout_callback_.callback().Run();
Paul Stewartc5099532013-12-12 07:53:15 -0800556 Mock::VerifyAndClearExpectations(this);
Paul Stewart94571f12013-09-10 17:26:07 -0700557}
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700558
Darin Petkov98dd6a02011-06-10 15:12:57 -0700559TEST_F(DHCPConfigTest, ReleaseIP) {
560 config_->pid_ = 1 << 18; // Ensure unknown positive PID.
Paul Stewarta02ee492012-05-16 10:04:53 -0700561 config_->arp_gateway_ = false;
Darin Petkovaceede32011-07-18 15:32:38 -0700562 EXPECT_CALL(*proxy_, Release(kDeviceName)).Times(1);
Darin Petkova7b89492011-07-27 12:48:17 -0700563 config_->proxy_.reset(proxy_.release());
Paul Stewart217c61d2013-06-13 15:12:02 -0700564 EXPECT_TRUE(config_->ReleaseIP(IPConfig::kReleaseReasonDisconnect));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700565 config_->pid_ = 0;
566}
567
Paul Stewarta02ee492012-05-16 10:04:53 -0700568TEST_F(DHCPConfigTest, ReleaseIPArpGW) {
569 config_->pid_ = 1 << 18; // Ensure unknown positive PID.
570 config_->arp_gateway_ = true;
571 EXPECT_CALL(*proxy_, Release(kDeviceName)).Times(0);
572 config_->proxy_.reset(proxy_.release());
Paul Stewart217c61d2013-06-13 15:12:02 -0700573 EXPECT_TRUE(config_->ReleaseIP(IPConfig::kReleaseReasonDisconnect));
574 config_->pid_ = 0;
575}
576
577TEST_F(DHCPConfigTest, ReleaseIPStaticIPWithLease) {
578 config_->pid_ = 1 << 18; // Ensure unknown positive PID.
579 config_->arp_gateway_ = true;
580 config_->is_lease_active_ = true;
581 EXPECT_CALL(*proxy_, Release(kDeviceName));
582 config_->proxy_.reset(proxy_.release());
583 EXPECT_TRUE(config_->ReleaseIP(IPConfig::kReleaseReasonStaticIP));
584 EXPECT_EQ(NULL, config_->proxy_.get());
585 config_->pid_ = 0;
586}
587
588TEST_F(DHCPConfigTest, ReleaseIPStaticIPWithoutLease) {
589 config_->pid_ = 1 << 18; // Ensure unknown positive PID.
590 config_->arp_gateway_ = true;
591 config_->is_lease_active_ = false;
592 EXPECT_CALL(*proxy_, Release(kDeviceName)).Times(0);
593 MockDHCPProxy *proxy_pointer = proxy_.get();
594 config_->proxy_.reset(proxy_.release());
595 EXPECT_TRUE(config_->ReleaseIP(IPConfig::kReleaseReasonStaticIP));
596 // Expect that proxy has not been released.
597 EXPECT_EQ(proxy_pointer, config_->proxy_.get());
Paul Stewarta02ee492012-05-16 10:04:53 -0700598 config_->pid_ = 0;
599}
600
Darin Petkov98dd6a02011-06-10 15:12:57 -0700601TEST_F(DHCPConfigTest, RenewIP) {
Paul Stewart21f7b342013-11-19 10:15:58 -0800602 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(false));
603 config_->pid_ = 0;
604 EXPECT_FALSE(config_->RenewIP()); // Expect a call to Start() if pid_ is 0.
605 Mock::VerifyAndClearExpectations(minijail_.get());
606 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).Times(0);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700607 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Paul Stewart1f916e42013-12-23 09:52:54 -0800608 config_->lease_expiration_callback_.Reset(base::Bind(&DoNothing));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700609 config_->pid_ = 456;
Paul Stewartc02344a2012-08-17 16:57:37 -0700610 EXPECT_FALSE(config_->RenewIP()); // Expect no crash with NULL proxy.
Darin Petkovaceede32011-07-18 15:32:38 -0700611 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
Darin Petkova7b89492011-07-27 12:48:17 -0700612 config_->proxy_.reset(proxy_.release());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700613 EXPECT_TRUE(config_->RenewIP());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700614 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Paul Stewart1f916e42013-12-23 09:52:54 -0800615 EXPECT_TRUE(config_->lease_expiration_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700616 config_->pid_ = 0;
617}
618
619TEST_F(DHCPConfigTest, RequestIP) {
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700620 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700621 config_->pid_ = 567;
Darin Petkovaceede32011-07-18 15:32:38 -0700622 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
Darin Petkova7b89492011-07-27 12:48:17 -0700623 config_->proxy_.reset(proxy_.release());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700624 EXPECT_TRUE(config_->RenewIP());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700625 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
626 config_->pid_ = 0;
627}
628
Paul Stewartc5099532013-12-12 07:53:15 -0800629TEST_F(DHCPConfigCallbackTest, RequestIPTimeout) {
630 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
631 EXPECT_CALL(*this, FailureCallback(ConfigRef()));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700632 config_->lease_acquisition_timeout_seconds_ = 0;
633 config_->pid_ = 567;
634 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
635 config_->proxy_.reset(proxy_.release());
636 config_->RenewIP();
637 config_->dispatcher_->DispatchPendingEvents();
Paul Stewartc5099532013-12-12 07:53:15 -0800638 Mock::VerifyAndClearExpectations(this);
Darin Petkov98dd6a02011-06-10 15:12:57 -0700639 config_->pid_ = 0;
640}
641
642TEST_F(DHCPConfigTest, Restart) {
643 const int kPID1 = 1 << 17; // Ensure unknown positive PID.
644 const int kPID2 = 987;
645 const unsigned int kTag1 = 11;
646 const unsigned int kTag2 = 22;
647 config_->pid_ = kPID1;
648 config_->child_watch_tag_ = kTag1;
649 DHCPProvider::GetInstance()->BindPID(kPID1, config_);
Chris Masone2176a882011-09-14 22:29:15 -0700650 EXPECT_CALL(*glib(), SourceRemove(kTag1)).WillOnce(Return(true));
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700651 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(
652 DoAll(SetArgumentPointee<2>(kPID2), Return(true)));
Chris Masone2176a882011-09-14 22:29:15 -0700653 EXPECT_CALL(*glib(), ChildWatchAdd(kPID2, _, _)).WillOnce(Return(kTag2));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700654 EXPECT_TRUE(config_->Restart());
655 EXPECT_EQ(kPID2, config_->pid_);
656 EXPECT_EQ(config_.get(), DHCPProvider::GetInstance()->GetConfig(kPID2).get());
657 EXPECT_EQ(kTag2, config_->child_watch_tag_);
658 DHCPProvider::GetInstance()->UnbindPID(kPID2);
659 config_->pid_ = 0;
660 config_->child_watch_tag_ = 0;
661}
662
663TEST_F(DHCPConfigTest, RestartNoClient) {
664 const int kPID = 777;
665 const unsigned int kTag = 66;
Chris Masone2176a882011-09-14 22:29:15 -0700666 EXPECT_CALL(*glib(), SourceRemove(_)).Times(0);
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700667 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(
668 DoAll(SetArgumentPointee<2>(kPID), Return(true)));
Chris Masone2176a882011-09-14 22:29:15 -0700669 EXPECT_CALL(*glib(), ChildWatchAdd(kPID, _, _)).WillOnce(Return(kTag));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700670 EXPECT_TRUE(config_->Restart());
671 EXPECT_EQ(kPID, config_->pid_);
672 EXPECT_EQ(config_.get(), DHCPProvider::GetInstance()->GetConfig(kPID).get());
673 EXPECT_EQ(kTag, config_->child_watch_tag_);
674 DHCPProvider::GetInstance()->UnbindPID(kPID);
675 config_->pid_ = 0;
676 config_->child_watch_tag_ = 0;
677}
678
Paul Stewartd408fdf2012-05-07 17:15:57 -0700679TEST_F(DHCPConfigTest, StartSuccessEphemeral) {
680 DHCPConfigRefPtr config =
Paul Stewart75a68b92013-10-24 10:50:27 -0700681 CreateRunningConfig(kHostName, kDeviceName, kArpGateway, !kMinimalConfig);
Paul Stewartd408fdf2012-05-07 17:15:57 -0700682 StopRunningConfigAndExpect(config, false);
683}
Darin Petkov92c43902011-06-09 20:46:06 -0700684
Paul Stewartd408fdf2012-05-07 17:15:57 -0700685TEST_F(DHCPConfigTest, StartSuccessPersistent) {
686 DHCPConfigRefPtr config =
Paul Stewart75a68b92013-10-24 10:50:27 -0700687 CreateRunningConfig(kHostName, kLeaseFileSuffix, kArpGateway,
688 !kMinimalConfig);
Paul Stewartd408fdf2012-05-07 17:15:57 -0700689 StopRunningConfigAndExpect(config, true);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700690}
691
Paul Stewartc5099532013-12-12 07:53:15 -0800692TEST_F(DHCPConfigCallbackTest, StartTimeout) {
693 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
694 EXPECT_CALL(*this, FailureCallback(ConfigRef()));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700695 config_->lease_acquisition_timeout_seconds_ = 0;
696 config_->proxy_.reset(proxy_.release());
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700697 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(true));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700698 config_->Start();
699 config_->dispatcher_->DispatchPendingEvents();
Paul Stewartc5099532013-12-12 07:53:15 -0800700 Mock::VerifyAndClearExpectations(this);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700701}
702
Darin Petkov98dd6a02011-06-10 15:12:57 -0700703TEST_F(DHCPConfigTest, Stop) {
Darin Petkov98dd6a02011-06-10 15:12:57 -0700704 const int kPID = 1 << 17; // Ensure unknown positive PID.
mukesh agrawal1835e772013-01-15 18:35:03 -0800705 ScopedMockLog log;
706 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
707 EXPECT_CALL(log, Log(_, _, ContainsRegex(
Darin Petkov3fe17662013-02-04 14:19:08 +0100708 base::StringPrintf("Stopping.+%s", __func__))));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700709 config_->pid_ = kPID;
Darin Petkov3fe17662013-02-04 14:19:08 +0100710 DHCPProvider::GetInstance()->BindPID(kPID, config_);
Paul Stewart1f916e42013-12-23 09:52:54 -0800711 config_->lease_acquisition_timeout_callback_.Reset(base::Bind(&DoNothing));
712 config_->lease_expiration_callback_.Reset(base::Bind(&DoNothing));
mukesh agrawal1835e772013-01-15 18:35:03 -0800713 config_->Stop(__func__);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700714 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Paul Stewart1f916e42013-12-23 09:52:54 -0800715 EXPECT_TRUE(config_->lease_expiration_callback_.IsCancelled());
Darin Petkov3fe17662013-02-04 14:19:08 +0100716 EXPECT_FALSE(DHCPProvider::GetInstance()->GetConfig(kPID));
717 EXPECT_FALSE(config_->pid_);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700718}
719
720TEST_F(DHCPConfigTest, StopDuringRequestIP) {
721 config_->pid_ = 567;
722 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
723 config_->proxy_.reset(proxy_.release());
724 EXPECT_TRUE(config_->RenewIP());
725 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
726 config_->pid_ = 0; // Keep Stop from killing a real process.
mukesh agrawal1835e772013-01-15 18:35:03 -0800727 config_->Stop(__func__);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700728 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700729}
730
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800731TEST_F(DHCPConfigTest, SetProperty) {
Chris Masone43b48a12011-07-01 13:37:07 -0700732 ::DBus::Error error;
733 // Ensure that an attempt to write a R/O property returns InvalidArgs error.
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800734 EXPECT_FALSE(DBusAdaptor::SetProperty(config_->mutable_store(),
Ben Chan0295e0f2013-09-20 13:47:29 -0700735 kAddressProperty,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800736 PropertyStoreTest::kStringV,
737 &error));
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700738 ASSERT_TRUE(error.is_set()); // name() may be invalid otherwise
Chris Masone9d779932011-08-25 16:33:41 -0700739 EXPECT_EQ(invalid_args(), error.name());
Chris Masone43b48a12011-07-01 13:37:07 -0700740}
741
Darin Petkove7cb7f82011-06-03 13:21:51 -0700742} // namespace shill