blob: 3b4d35314d98df24dda76c0b65bdad79ddc09e2b [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;
Alex Vakulenko8a532292014-06-16 17:18:44 -070052} // namespace
Darin Petkov92c43902011-06-09 20:46:06 -070053
Chris Masone43b48a12011-07-01 13:37:07 -070054class DHCPConfigTest : public PropertyStoreTest {
Darin Petkove7cb7f82011-06-03 13:21:51 -070055 public:
Darin Petkovf7897bc2011-06-08 17:13:36 -070056 DHCPConfigTest()
Darin Petkovf65e9282011-06-21 14:29:56 -070057 : proxy_(new MockDHCPProxy()),
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070058 minijail_(new MockMinijail()),
Chris Masone19e30402011-07-19 15:48:47 -070059 config_(new DHCPConfig(&control_,
Chris Masone2176a882011-09-14 22:29:15 -070060 dispatcher(),
Chris Masone19e30402011-07-19 15:48:47 -070061 DHCPProvider::GetInstance(),
Darin Petkov92c43902011-06-09 20:46:06 -070062 kDeviceName,
Paul Stewartd32f4842012-01-11 16:08:13 -080063 kHostName,
Paul Stewartd408fdf2012-05-07 17:15:57 -070064 kLeaseFileSuffix,
65 kArpGateway,
Chris Masone2176a882011-09-14 22:29:15 -070066 glib())) {}
Darin Petkova7b89492011-07-27 12:48:17 -070067
68 virtual void SetUp() {
Darin Petkovab565bb2011-10-06 02:55:51 -070069 config_->proxy_factory_ = &proxy_factory_;
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070070 config_->minijail_ = minijail_.get();
Darin Petkova7b89492011-07-27 12:48:17 -070071 }
72
73 virtual void TearDown() {
Darin Petkovab565bb2011-10-06 02:55:51 -070074 config_->proxy_factory_ = NULL;
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070075 config_->minijail_ = NULL;
Darin Petkov98dd6a02011-06-10 15:12:57 -070076 }
Darin Petkove7cb7f82011-06-03 13:21:51 -070077
Paul Stewart475c0722014-04-18 08:52:00 -070078 void StopInstance() {
79 config_->Stop("In test");
80 }
81
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070082 DHCPConfigRefPtr CreateMockMinijailConfig(const string &hostname,
Paul Stewart75a68b92013-10-24 10:50:27 -070083 const string &lease_suffix,
Paul Stewartb1083182014-06-25 03:04:53 -070084 bool arp_gateway);
Paul Stewartd408fdf2012-05-07 17:15:57 -070085 DHCPConfigRefPtr CreateRunningConfig(const string &hostname,
86 const string &lease_suffix,
Paul Stewartb1083182014-06-25 03:04:53 -070087 bool arp_gateway);
Paul Stewartd408fdf2012-05-07 17:15:57 -070088 void StopRunningConfigAndExpect(DHCPConfigRefPtr config,
89 bool lease_file_exists);
90
Darin Petkove7cb7f82011-06-03 13:21:51 -070091 protected:
Paul Stewartd408fdf2012-05-07 17:15:57 -070092 static const int kPID;
93 static const unsigned int kTag;
94
95 FilePath lease_file_;
96 FilePath pid_file_;
97 ScopedTempDir temp_dir_;
Darin Petkova7b89492011-07-27 12:48:17 -070098 scoped_ptr<MockDHCPProxy> proxy_;
Ben Chana55469d2014-01-27 16:35:29 -080099 MockProxyFactory proxy_factory_;
Chris Masone19e30402011-07-19 15:48:47 -0700100 MockControl control_;
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700101 scoped_ptr<MockMinijail> minijail_;
Darin Petkovf7897bc2011-06-08 17:13:36 -0700102 DHCPConfigRefPtr config_;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700103};
104
Paul Stewartd408fdf2012-05-07 17:15:57 -0700105const int DHCPConfigTest::kPID = 123456;
106const unsigned int DHCPConfigTest::kTag = 77;
107
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700108DHCPConfigRefPtr DHCPConfigTest::CreateMockMinijailConfig(
Paul Stewart75a68b92013-10-24 10:50:27 -0700109 const string &hostname,
110 const string &lease_suffix,
Paul Stewartb1083182014-06-25 03:04:53 -0700111 bool arp_gateway) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700112 DHCPConfigRefPtr config(new DHCPConfig(&control_,
113 dispatcher(),
114 DHCPProvider::GetInstance(),
115 kDeviceName,
116 hostname,
117 lease_suffix,
118 arp_gateway,
119 glib()));
120 config->minijail_ = minijail_.get();
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700121
122 return config;
123}
124
Paul Stewartb1083182014-06-25 03:04:53 -0700125DHCPConfigRefPtr DHCPConfigTest::CreateRunningConfig(const string &hostname,
126 const string &lease_suffix,
127 bool arp_gateway) {
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,
135 glib()));
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700136 config->minijail_ = minijail_.get();
137 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _))
138 .WillOnce(DoAll(SetArgumentPointee<2>(kPID), Return(true)));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700139 EXPECT_CALL(*glib(), ChildWatchAdd(kPID, _, _)).WillOnce(Return(kTag));
140 EXPECT_TRUE(config->Start());
141 EXPECT_EQ(kPID, config->pid_);
142 EXPECT_EQ(config.get(), DHCPProvider::GetInstance()->GetConfig(kPID).get());
143 EXPECT_EQ(kTag, config->child_watch_tag_);
144
145 EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
146 config->root_ = temp_dir_.path();
Jorge Lucangeli Obes2f3169d2012-04-25 11:38:25 -0700147 FilePath varrun = temp_dir_.path().Append("var/run/dhcpcd");
Ben Chana0ddf462014-02-06 11:32:42 -0800148 EXPECT_TRUE(base::CreateDirectory(varrun));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700149 pid_file_ = varrun.Append(base::StringPrintf("dhcpcd-%s.pid", kDeviceName));
150 FilePath varlib = temp_dir_.path().Append("var/lib/dhcpcd");
Ben Chana0ddf462014-02-06 11:32:42 -0800151 EXPECT_TRUE(base::CreateDirectory(varlib));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700152 lease_file_ =
153 varlib.Append(base::StringPrintf("dhcpcd-%s.lease", kDeviceName));
Ben Chan6fbf64f2014-05-21 18:07:01 -0700154 EXPECT_EQ(0, base::WriteFile(pid_file_, "", 0));
155 EXPECT_EQ(0, base::WriteFile(lease_file_, "", 0));
Ben Chana0ddf462014-02-06 11:32:42 -0800156 EXPECT_TRUE(base::PathExists(pid_file_));
157 EXPECT_TRUE(base::PathExists(lease_file_));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700158
159 return config;
160}
161
162void DHCPConfigTest::StopRunningConfigAndExpect(DHCPConfigRefPtr config,
163 bool lease_file_exists) {
mukesh agrawal6c6655d2012-12-06 14:49:50 -0800164 ScopedMockLog log;
165 // We use a non-zero exit status so that we get the log message.
166 EXPECT_CALL(log, Log(_, _, ::testing::EndsWith("status 10")));
167 DHCPConfig::ChildWatchCallback(kPID, 10, config.get());
Paul Stewartd408fdf2012-05-07 17:15:57 -0700168 EXPECT_EQ(NULL, DHCPProvider::GetInstance()->GetConfig(kPID).get());
169
Ben Chana0ddf462014-02-06 11:32:42 -0800170 EXPECT_FALSE(base::PathExists(pid_file_));
171 EXPECT_EQ(lease_file_exists, base::PathExists(lease_file_));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700172}
173
Darin Petkove7cb7f82011-06-03 13:21:51 -0700174TEST_F(DHCPConfigTest, GetIPv4AddressString) {
Darin Petkovf7897bc2011-06-08 17:13:36 -0700175 EXPECT_EQ("255.255.255.255", config_->GetIPv4AddressString(0xffffffff));
176 EXPECT_EQ("0.0.0.0", config_->GetIPv4AddressString(0));
177 EXPECT_EQ("1.2.3.4", config_->GetIPv4AddressString(0x04030201));
Darin Petkove7cb7f82011-06-03 13:21:51 -0700178}
179
Darin Petkova7b89492011-07-27 12:48:17 -0700180TEST_F(DHCPConfigTest, InitProxy) {
181 static const char kService[] = ":1.200";
Darin Petkova7b89492011-07-27 12:48:17 -0700182 EXPECT_TRUE(proxy_.get());
183 EXPECT_FALSE(config_->proxy_.get());
Ben Chana55469d2014-01-27 16:35:29 -0800184 EXPECT_CALL(proxy_factory_, CreateDHCPProxy(kService))
185 .WillOnce(ReturnAndReleasePointee(&proxy_));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500186 config_->InitProxy(kService);
Darin Petkova7b89492011-07-27 12:48:17 -0700187 EXPECT_FALSE(proxy_.get());
188 EXPECT_TRUE(config_->proxy_.get());
189
190 config_->InitProxy(kService);
Darin Petkova7b89492011-07-27 12:48:17 -0700191}
192
Paul Stewart65bcd082012-11-16 09:37:14 -0800193TEST_F(DHCPConfigTest, ParseClasslessStaticRoutes) {
194 const string kDefaultAddress = "0.0.0.0";
195 const string kDefaultDestination = kDefaultAddress + "/0";
196 const string kRouter0 = "10.0.0.254";
197 const string kAddress1 = "192.168.1.0";
198 const string kDestination1 = kAddress1 + "/24";
199 // Last gateway missing, leaving an odd number of parameters.
200 const string kBrokenClasslessRoutes0 = kDefaultDestination + " " + kRouter0 +
201 " " + kDestination1;
202 IPConfig::Properties properties;
203 EXPECT_FALSE(DHCPConfig::ParseClasslessStaticRoutes(kBrokenClasslessRoutes0,
204 &properties));
205 EXPECT_TRUE(properties.routes.empty());
206 EXPECT_TRUE(properties.gateway.empty());
207
208 // Gateway argument for the second route is malformed, but we were able
209 // to salvage a default gateway.
210 const string kBrokenRouter1 = "10.0.0";
211 const string kBrokenClasslessRoutes1 = kBrokenClasslessRoutes0 + " " +
212 kBrokenRouter1;
213 EXPECT_FALSE(DHCPConfig::ParseClasslessStaticRoutes(kBrokenClasslessRoutes1,
214 &properties));
215 EXPECT_TRUE(properties.routes.empty());
216 EXPECT_EQ(kRouter0, properties.gateway);
217
218 const string kRouter1 = "10.0.0.253";
219 const string kRouter2 = "10.0.0.252";
220 const string kClasslessRoutes0 = kDefaultDestination + " " + kRouter2 + " " +
221 kDestination1 + " " + kRouter1;
222 EXPECT_TRUE(DHCPConfig::ParseClasslessStaticRoutes(kClasslessRoutes0,
223 &properties));
224 // The old default route is preserved.
225 EXPECT_EQ(kRouter0, properties.gateway);
226
227 // The two routes (including the one which would have otherwise been
228 // classified as a default route) are added to the routing table.
229 EXPECT_EQ(2, properties.routes.size());
230 const IPConfig::Route &route0 = properties.routes[0];
231 EXPECT_EQ(kDefaultAddress, route0.host);
232 EXPECT_EQ("0.0.0.0", route0.netmask);
233 EXPECT_EQ(kRouter2, route0.gateway);
234
235 const IPConfig::Route &route1 = properties.routes[1];
236 EXPECT_EQ(kAddress1, route1.host);
237 EXPECT_EQ("255.255.255.0", route1.netmask);
238 EXPECT_EQ(kRouter1, route1.gateway);
239
240 // A malformed routing table should not affect the current table.
241 EXPECT_FALSE(DHCPConfig::ParseClasslessStaticRoutes(kBrokenClasslessRoutes1,
242 &properties));
243 EXPECT_EQ(2, properties.routes.size());
244 EXPECT_EQ(kRouter0, properties.gateway);
245}
246
Darin Petkove7cb7f82011-06-03 13:21:51 -0700247TEST_F(DHCPConfigTest, ParseConfiguration) {
248 DHCPConfig::Configuration conf;
249 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
250 0x01020304);
251 conf[DHCPConfig::kConfigurationKeySubnetCIDR].writer().append_byte(
252 16);
253 conf[DHCPConfig::kConfigurationKeyBroadcastAddress].writer().append_uint32(
254 0x10203040);
255 {
Darin Petkove7cb7f82011-06-03 13:21:51 -0700256 vector<unsigned int> routers;
257 routers.push_back(0x02040608);
258 routers.push_back(0x03050709);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700259 DBus::MessageIter writer =
260 conf[DHCPConfig::kConfigurationKeyRouters].writer();
Darin Petkove7cb7f82011-06-03 13:21:51 -0700261 writer << routers;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700262 }
263 {
Darin Petkove7cb7f82011-06-03 13:21:51 -0700264 vector<unsigned int> dns;
265 dns.push_back(0x09070503);
266 dns.push_back(0x08060402);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700267 DBus::MessageIter writer = conf[DHCPConfig::kConfigurationKeyDNS].writer();
Darin Petkove7cb7f82011-06-03 13:21:51 -0700268 writer << dns;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700269 }
270 conf[DHCPConfig::kConfigurationKeyDomainName].writer().append_string(
271 "domain-name");
272 {
Darin Petkove7cb7f82011-06-03 13:21:51 -0700273 vector<string> search;
274 search.push_back("foo.com");
275 search.push_back("bar.com");
Darin Petkovf7897bc2011-06-08 17:13:36 -0700276 DBus::MessageIter writer =
277 conf[DHCPConfig::kConfigurationKeyDomainSearch].writer();
Darin Petkove7cb7f82011-06-03 13:21:51 -0700278 writer << search;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700279 }
280 conf[DHCPConfig::kConfigurationKeyMTU].writer().append_uint16(600);
281 conf["UnknownKey"] = DBus::Variant();
282
Darin Petkove7cb7f82011-06-03 13:21:51 -0700283 IPConfig::Properties properties;
Darin Petkovf7897bc2011-06-08 17:13:36 -0700284 ASSERT_TRUE(config_->ParseConfiguration(conf, &properties));
Darin Petkove7cb7f82011-06-03 13:21:51 -0700285 EXPECT_EQ("4.3.2.1", properties.address);
Paul Stewart48100b02012-03-19 07:53:52 -0700286 EXPECT_EQ(16, properties.subnet_prefix);
Darin Petkove7cb7f82011-06-03 13:21:51 -0700287 EXPECT_EQ("64.48.32.16", properties.broadcast_address);
288 EXPECT_EQ("8.6.4.2", properties.gateway);
289 ASSERT_EQ(2, properties.dns_servers.size());
290 EXPECT_EQ("3.5.7.9", properties.dns_servers[0]);
291 EXPECT_EQ("2.4.6.8", properties.dns_servers[1]);
292 EXPECT_EQ("domain-name", properties.domain_name);
293 ASSERT_EQ(2, properties.domain_search.size());
294 EXPECT_EQ("foo.com", properties.domain_search[0]);
295 EXPECT_EQ("bar.com", properties.domain_search[1]);
296 EXPECT_EQ(600, properties.mtu);
297}
298
Darin Petkov92c43902011-06-09 20:46:06 -0700299TEST_F(DHCPConfigTest, StartFail) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700300 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(false));
Chris Masone2176a882011-09-14 22:29:15 -0700301 EXPECT_CALL(*glib(), ChildWatchAdd(_, _, _)).Times(0);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700302 EXPECT_FALSE(config_->Start());
303 EXPECT_EQ(0, config_->pid_);
Darin Petkov92c43902011-06-09 20:46:06 -0700304}
Darin Petkovf7897bc2011-06-08 17:13:36 -0700305
Paul Stewartb1083182014-06-25 03:04:53 -0700306MATCHER_P3(IsDHCPCDArgs, has_hostname, has_arp_gateway, has_lease_suffix, "") {
Paul Stewartd32f4842012-01-11 16:08:13 -0800307 if (string(arg[0]) != "/sbin/dhcpcd" ||
Paul Stewart75a68b92013-10-24 10:50:27 -0700308 string(arg[1]) != "-B" ||
309 string(arg[2]) != "-q") {
Paul Stewartd32f4842012-01-11 16:08:13 -0800310 return false;
311 }
312
Paul Stewart75a68b92013-10-24 10:50:27 -0700313 int end_offset = 3;
Paul Stewartd32f4842012-01-11 16:08:13 -0800314 if (has_hostname) {
Paul Stewartd408fdf2012-05-07 17:15:57 -0700315 if (string(arg[end_offset]) != "-h" ||
316 string(arg[end_offset + 1]) != kHostName) {
Paul Stewartd32f4842012-01-11 16:08:13 -0800317 return false;
318 }
Paul Stewartd408fdf2012-05-07 17:15:57 -0700319 end_offset += 2;
Paul Stewartd32f4842012-01-11 16:08:13 -0800320 }
321
Paul Stewartd408fdf2012-05-07 17:15:57 -0700322 if (has_arp_gateway) {
Paul Stewart75a68b92013-10-24 10:50:27 -0700323 if (string(arg[end_offset]) != "-R" ||
324 string(arg[end_offset + 1]) != "-U") {
Paul Stewartd408fdf2012-05-07 17:15:57 -0700325 return false;
Paul Stewart75a68b92013-10-24 10:50:27 -0700326 }
327 end_offset += 2;
328 }
329
Paul Stewartd408fdf2012-05-07 17:15:57 -0700330 string device_arg = has_lease_suffix ?
331 string(kDeviceName) + "=" + string(kLeaseFileSuffix) : kDeviceName;
332 return string(arg[end_offset]) == device_arg && arg[end_offset + 1] == NULL;
Paul Stewartd32f4842012-01-11 16:08:13 -0800333}
334
335TEST_F(DHCPConfigTest, StartWithHostname) {
Paul Stewart75a68b92013-10-24 10:50:27 -0700336 EXPECT_CALL(*minijail_, RunAndDestroy(_, IsDHCPCDArgs(kHasHostname,
337 kArpGateway,
Paul Stewartb1083182014-06-25 03:04:53 -0700338 kHasLeaseSuffix), _))
Paul Stewart75a68b92013-10-24 10:50:27 -0700339 .WillOnce(Return(false));
Paul Stewartd32f4842012-01-11 16:08:13 -0800340 EXPECT_FALSE(config_->Start());
341}
342
343TEST_F(DHCPConfigTest, StartWithoutHostname) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700344 DHCPConfigRefPtr config = CreateMockMinijailConfig("",
345 kLeaseFileSuffix,
Paul Stewartb1083182014-06-25 03:04:53 -0700346 kArpGateway);
Paul Stewart75a68b92013-10-24 10:50:27 -0700347 EXPECT_CALL(*minijail_, RunAndDestroy(_, IsDHCPCDArgs(!kHasHostname,
348 kArpGateway,
Paul Stewartb1083182014-06-25 03:04:53 -0700349 kHasLeaseSuffix), _))
Paul Stewart75a68b92013-10-24 10:50:27 -0700350 .WillOnce(Return(false));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700351 EXPECT_FALSE(config->Start());
352}
353
354TEST_F(DHCPConfigTest, StartWithoutArpGateway) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700355 DHCPConfigRefPtr config = CreateMockMinijailConfig(kHostName,
356 kLeaseFileSuffix,
Paul Stewartb1083182014-06-25 03:04:53 -0700357 !kArpGateway);
Paul Stewart75a68b92013-10-24 10:50:27 -0700358 EXPECT_CALL(*minijail_, RunAndDestroy(_, IsDHCPCDArgs(kHasHostname,
359 !kArpGateway,
Paul Stewartb1083182014-06-25 03:04:53 -0700360 kHasLeaseSuffix), _))
Paul Stewart75a68b92013-10-24 10:50:27 -0700361 .WillOnce(Return(false));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700362 EXPECT_FALSE(config->Start());
363}
364
365TEST_F(DHCPConfigTest, StartWithoutLeaseSuffix) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700366 DHCPConfigRefPtr config = CreateMockMinijailConfig(kHostName,
367 kDeviceName,
Paul Stewartb1083182014-06-25 03:04:53 -0700368 kArpGateway);
Paul Stewart75a68b92013-10-24 10:50:27 -0700369 EXPECT_CALL(*minijail_, RunAndDestroy(_, IsDHCPCDArgs(kHasHostname,
370 kArpGateway,
Paul Stewartb1083182014-06-25 03:04:53 -0700371 !kHasLeaseSuffix), _))
Paul Stewart75a68b92013-10-24 10:50:27 -0700372 .WillOnce(Return(false));
Paul Stewartd32f4842012-01-11 16:08:13 -0800373 EXPECT_FALSE(config->Start());
374}
375
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700376namespace {
377
Paul Stewartc5099532013-12-12 07:53:15 -0800378class DHCPConfigCallbackTest : public DHCPConfigTest {
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700379 public:
Paul Stewartc5099532013-12-12 07:53:15 -0800380 virtual void SetUp() {
381 DHCPConfigTest::SetUp();
382 config_->RegisterUpdateCallback(
383 Bind(&DHCPConfigCallbackTest::SuccessCallback, Unretained(this)));
384 config_->RegisterFailureCallback(
385 Bind(&DHCPConfigCallbackTest::FailureCallback, Unretained(this)));
386 ip_config_ = config_;
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700387 }
388
Paul Stewartc5099532013-12-12 07:53:15 -0800389 MOCK_METHOD1(SuccessCallback, void(const IPConfigRefPtr &ipconfig));
390 MOCK_METHOD1(FailureCallback, void(const IPConfigRefPtr &ipconfig));
391
392 // The mock methods above take IPConfigRefPtr because this is the type
393 // that the registered callbacks take. This conversion of the DHCP
394 // config ref pointer eases our work in setting up expectations.
395 const IPConfigRefPtr &ConfigRef() { return ip_config_; }
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700396
397 private:
Paul Stewartc5099532013-12-12 07:53:15 -0800398 IPConfigRefPtr ip_config_;
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700399};
400
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700401void DoNothing() {}
402
Alex Vakulenko8a532292014-06-16 17:18:44 -0700403} // namespace
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700404
Paul Stewartc5099532013-12-12 07:53:15 -0800405TEST_F(DHCPConfigCallbackTest, ProcessEventSignalFail) {
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700406 DHCPConfig::Configuration conf;
407 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
408 0x01020304);
Paul Stewartc5099532013-12-12 07:53:15 -0800409 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
410 EXPECT_CALL(*this, FailureCallback(ConfigRef()));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700411 config_->lease_acquisition_timeout_callback_.Reset(base::Bind(&DoNothing));
Paul Stewart1f916e42013-12-23 09:52:54 -0800412 config_->lease_expiration_callback_.Reset(base::Bind(&DoNothing));
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700413 config_->ProcessEventSignal(DHCPConfig::kReasonFail, conf);
Paul Stewartc5099532013-12-12 07:53:15 -0800414 Mock::VerifyAndClearExpectations(this);
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700415 EXPECT_TRUE(config_->properties().address.empty());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700416 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Paul Stewart1f916e42013-12-23 09:52:54 -0800417 EXPECT_TRUE(config_->lease_expiration_callback_.IsCancelled());
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700418}
419
Paul Stewartc5099532013-12-12 07:53:15 -0800420TEST_F(DHCPConfigCallbackTest, ProcessEventSignalSuccess) {
Paul Stewart1f916e42013-12-23 09:52:54 -0800421 for (const auto &reason : { DHCPConfig::kReasonBound,
422 DHCPConfig::kReasonRebind,
423 DHCPConfig::kReasonReboot,
424 DHCPConfig::kReasonRenew }) {
425 int address_octet = 0;
426 for (const auto lease_time_given : { false, true }) {
427 DHCPConfig::Configuration conf;
428 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
429 ++address_octet);
430 if (lease_time_given) {
431 const uint32 kLeaseTime = 1;
432 conf[DHCPConfig::kConfigurationKeyLeaseTime].writer().append_uint32(
433 kLeaseTime);
434 config_->lease_expiration_callback_.Cancel();
435 } else {
436 config_->lease_expiration_callback_.Reset(base::Bind(&DoNothing));
437 }
438 config_->lease_acquisition_timeout_callback_.Reset(
439 base::Bind(&DoNothing));
440 EXPECT_CALL(*this, SuccessCallback(ConfigRef()));
441 EXPECT_CALL(*this, FailureCallback(_)).Times(0);
442 config_->ProcessEventSignal(reason, conf);
443 string failure_message = string(reason) + " failed with lease time " +
444 (lease_time_given ? "given" : "not given");
445 EXPECT_TRUE(Mock::VerifyAndClearExpectations(this)) << failure_message;
446 EXPECT_EQ(base::StringPrintf("%d.0.0.0", address_octet),
447 config_->properties().address) << failure_message;
448 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled())
449 << failure_message;
450 // With no lease time given, the expiration callback will be cancelled.
451 // With a lease time given, the expiration callback should be started.
452 EXPECT_EQ(!lease_time_given,
453 config_->lease_expiration_callback_.IsCancelled())
454 << failure_message;
455 }
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700456 }
457}
458
Paul Stewart475c0722014-04-18 08:52:00 -0700459TEST_F(DHCPConfigCallbackTest, StoppedDuringFailureCallback) {
460 DHCPConfig::Configuration conf;
461 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
462 0x01020304);
463 // Stop the DHCP config while it is calling the failure callback. We
464 // need to ensure that no callbacks are left running inadvertently as
465 // a result.
466 EXPECT_CALL(*this, FailureCallback(ConfigRef()))
467 .WillOnce(InvokeWithoutArgs(this, &DHCPConfigTest::StopInstance));
468 config_->ProcessEventSignal(DHCPConfig::kReasonFail, conf);
469 EXPECT_TRUE(Mock::VerifyAndClearExpectations(this));
470 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
471 EXPECT_TRUE(config_->lease_expiration_callback_.IsCancelled());
472}
473
474TEST_F(DHCPConfigCallbackTest, StoppedDuringSuccessCallback) {
475 DHCPConfig::Configuration conf;
476 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
477 0x01020304);
478 const uint32 kLeaseTime = 1;
479 conf[DHCPConfig::kConfigurationKeyLeaseTime].writer().append_uint32(
480 kLeaseTime);
481 // Stop the DHCP config while it is calling the success callback. This
482 // can happen if the device has a static IP configuration and releases
483 // the lease after accepting other network parameters from the DHCP
484 // IPConfig properties. We need to ensure that no callbacks are left
485 // running inadvertently as a result.
486 EXPECT_CALL(*this, SuccessCallback(ConfigRef()))
487 .WillOnce(InvokeWithoutArgs(this, &DHCPConfigTest::StopInstance));
488 config_->ProcessEventSignal(DHCPConfig::kReasonBound, conf);
489 EXPECT_TRUE(Mock::VerifyAndClearExpectations(this));
490 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
491 EXPECT_TRUE(config_->lease_expiration_callback_.IsCancelled());
492}
493
Paul Stewartc5099532013-12-12 07:53:15 -0800494TEST_F(DHCPConfigCallbackTest, ProcessEventSignalUnknown) {
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700495 DHCPConfig::Configuration conf;
496 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
497 0x01020304);
498 static const char kReasonUnknown[] = "UNKNOWN_REASON";
Paul Stewartc5099532013-12-12 07:53:15 -0800499 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
500 EXPECT_CALL(*this, FailureCallback(_)).Times(0);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700501 config_->lease_acquisition_timeout_callback_.Reset(base::Bind(&DoNothing));
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700502 config_->ProcessEventSignal(kReasonUnknown, conf);
Paul Stewartc5099532013-12-12 07:53:15 -0800503 Mock::VerifyAndClearExpectations(this);
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700504 EXPECT_TRUE(config_->properties().address.empty());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700505 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700506}
507
Paul Stewartc5099532013-12-12 07:53:15 -0800508TEST_F(DHCPConfigCallbackTest, ProcessEventSignalGatewayArp) {
Paul Stewart94571f12013-09-10 17:26:07 -0700509 DHCPConfig::Configuration conf;
510 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
511 0x01020304);
Paul Stewartc5099532013-12-12 07:53:15 -0800512 EXPECT_CALL(*this, SuccessCallback(ConfigRef()));
513 EXPECT_CALL(*this, FailureCallback(_)).Times(0);
Paul Stewart94571f12013-09-10 17:26:07 -0700514 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(true));
515 config_->Start();
516 config_->ProcessEventSignal(DHCPConfig::kReasonGatewayArp, conf);
Paul Stewartc5099532013-12-12 07:53:15 -0800517 Mock::VerifyAndClearExpectations(this);
Paul Stewart94571f12013-09-10 17:26:07 -0700518 EXPECT_EQ("4.3.2.1", config_->properties().address);
519 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
520 EXPECT_TRUE(config_->is_gateway_arp_active_);
521
522 // If the timeout gets called, we shouldn't lose the lease since GatewayArp
523 // is active.
524 ScopedMockLog log;
525 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
526 EXPECT_CALL(log, Log(_, _, ::testing::EndsWith(
527 "Continuing to use our previous lease, due to gateway-ARP.")));
Paul Stewartc5099532013-12-12 07:53:15 -0800528 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
529 EXPECT_CALL(*this, FailureCallback(_)).Times(0);
Paul Stewart94571f12013-09-10 17:26:07 -0700530 config_->lease_acquisition_timeout_callback_.callback().Run();
Paul Stewartc5099532013-12-12 07:53:15 -0800531 Mock::VerifyAndClearExpectations(this);
Paul Stewart94571f12013-09-10 17:26:07 -0700532 EXPECT_TRUE(config_->is_gateway_arp_active_);
533
534 // An official reply from a DHCP server should reset our GatewayArp state.
Paul Stewartc5099532013-12-12 07:53:15 -0800535 EXPECT_CALL(*this, SuccessCallback(ConfigRef()));
536 EXPECT_CALL(*this, FailureCallback(_)).Times(0);
Paul Stewart94571f12013-09-10 17:26:07 -0700537 config_->ProcessEventSignal(DHCPConfig::kReasonRenew, conf);
Paul Stewartc5099532013-12-12 07:53:15 -0800538 Mock::VerifyAndClearExpectations(this);
Paul Stewart94571f12013-09-10 17:26:07 -0700539 EXPECT_FALSE(config_->is_gateway_arp_active_);
540}
541
Paul Stewartc5099532013-12-12 07:53:15 -0800542TEST_F(DHCPConfigCallbackTest, ProcessEventSignalGatewayArpNak) {
Paul Stewart94571f12013-09-10 17:26:07 -0700543 DHCPConfig::Configuration conf;
544 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
545 0x01020304);
Paul Stewart94571f12013-09-10 17:26:07 -0700546 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(true));
547 config_->Start();
548 config_->ProcessEventSignal(DHCPConfig::kReasonGatewayArp, conf);
549 EXPECT_TRUE(config_->is_gateway_arp_active_);
550
551 // Sending a NAK should clear is_gateway_arp_active_.
552 config_->ProcessEventSignal(DHCPConfig::kReasonNak, conf);
553 EXPECT_FALSE(config_->is_gateway_arp_active_);
Paul Stewartc5099532013-12-12 07:53:15 -0800554 Mock::VerifyAndClearExpectations(this);
Paul Stewart94571f12013-09-10 17:26:07 -0700555
556 // If the timeout gets called, we should lose the lease since GatewayArp
557 // is not active any more.
Paul Stewartc5099532013-12-12 07:53:15 -0800558 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
559 EXPECT_CALL(*this, FailureCallback(ConfigRef()));
Paul Stewart94571f12013-09-10 17:26:07 -0700560 config_->lease_acquisition_timeout_callback_.callback().Run();
Paul Stewartc5099532013-12-12 07:53:15 -0800561 Mock::VerifyAndClearExpectations(this);
Paul Stewart94571f12013-09-10 17:26:07 -0700562}
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700563
Darin Petkov98dd6a02011-06-10 15:12:57 -0700564TEST_F(DHCPConfigTest, ReleaseIP) {
565 config_->pid_ = 1 << 18; // Ensure unknown positive PID.
Paul Stewarta02ee492012-05-16 10:04:53 -0700566 config_->arp_gateway_ = false;
Darin Petkovaceede32011-07-18 15:32:38 -0700567 EXPECT_CALL(*proxy_, Release(kDeviceName)).Times(1);
Darin Petkova7b89492011-07-27 12:48:17 -0700568 config_->proxy_.reset(proxy_.release());
Paul Stewart217c61d2013-06-13 15:12:02 -0700569 EXPECT_TRUE(config_->ReleaseIP(IPConfig::kReleaseReasonDisconnect));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700570 config_->pid_ = 0;
571}
572
Paul Stewarta02ee492012-05-16 10:04:53 -0700573TEST_F(DHCPConfigTest, ReleaseIPArpGW) {
574 config_->pid_ = 1 << 18; // Ensure unknown positive PID.
575 config_->arp_gateway_ = true;
576 EXPECT_CALL(*proxy_, Release(kDeviceName)).Times(0);
577 config_->proxy_.reset(proxy_.release());
Paul Stewart217c61d2013-06-13 15:12:02 -0700578 EXPECT_TRUE(config_->ReleaseIP(IPConfig::kReleaseReasonDisconnect));
579 config_->pid_ = 0;
580}
581
582TEST_F(DHCPConfigTest, ReleaseIPStaticIPWithLease) {
583 config_->pid_ = 1 << 18; // Ensure unknown positive PID.
584 config_->arp_gateway_ = true;
585 config_->is_lease_active_ = true;
586 EXPECT_CALL(*proxy_, Release(kDeviceName));
587 config_->proxy_.reset(proxy_.release());
588 EXPECT_TRUE(config_->ReleaseIP(IPConfig::kReleaseReasonStaticIP));
589 EXPECT_EQ(NULL, config_->proxy_.get());
590 config_->pid_ = 0;
591}
592
593TEST_F(DHCPConfigTest, ReleaseIPStaticIPWithoutLease) {
594 config_->pid_ = 1 << 18; // Ensure unknown positive PID.
595 config_->arp_gateway_ = true;
596 config_->is_lease_active_ = false;
597 EXPECT_CALL(*proxy_, Release(kDeviceName)).Times(0);
598 MockDHCPProxy *proxy_pointer = proxy_.get();
599 config_->proxy_.reset(proxy_.release());
600 EXPECT_TRUE(config_->ReleaseIP(IPConfig::kReleaseReasonStaticIP));
601 // Expect that proxy has not been released.
602 EXPECT_EQ(proxy_pointer, config_->proxy_.get());
Paul Stewarta02ee492012-05-16 10:04:53 -0700603 config_->pid_ = 0;
604}
605
Darin Petkov98dd6a02011-06-10 15:12:57 -0700606TEST_F(DHCPConfigTest, RenewIP) {
Paul Stewart21f7b342013-11-19 10:15:58 -0800607 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(false));
608 config_->pid_ = 0;
609 EXPECT_FALSE(config_->RenewIP()); // Expect a call to Start() if pid_ is 0.
610 Mock::VerifyAndClearExpectations(minijail_.get());
611 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).Times(0);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700612 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Paul Stewart1f916e42013-12-23 09:52:54 -0800613 config_->lease_expiration_callback_.Reset(base::Bind(&DoNothing));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700614 config_->pid_ = 456;
Paul Stewartc02344a2012-08-17 16:57:37 -0700615 EXPECT_FALSE(config_->RenewIP()); // Expect no crash with NULL proxy.
Darin Petkovaceede32011-07-18 15:32:38 -0700616 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
Darin Petkova7b89492011-07-27 12:48:17 -0700617 config_->proxy_.reset(proxy_.release());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700618 EXPECT_TRUE(config_->RenewIP());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700619 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Paul Stewart1f916e42013-12-23 09:52:54 -0800620 EXPECT_TRUE(config_->lease_expiration_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700621 config_->pid_ = 0;
622}
623
624TEST_F(DHCPConfigTest, RequestIP) {
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700625 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700626 config_->pid_ = 567;
Darin Petkovaceede32011-07-18 15:32:38 -0700627 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
Darin Petkova7b89492011-07-27 12:48:17 -0700628 config_->proxy_.reset(proxy_.release());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700629 EXPECT_TRUE(config_->RenewIP());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700630 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
631 config_->pid_ = 0;
632}
633
Paul Stewartc5099532013-12-12 07:53:15 -0800634TEST_F(DHCPConfigCallbackTest, RequestIPTimeout) {
635 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
636 EXPECT_CALL(*this, FailureCallback(ConfigRef()));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700637 config_->lease_acquisition_timeout_seconds_ = 0;
638 config_->pid_ = 567;
639 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
640 config_->proxy_.reset(proxy_.release());
641 config_->RenewIP();
642 config_->dispatcher_->DispatchPendingEvents();
Paul Stewartc5099532013-12-12 07:53:15 -0800643 Mock::VerifyAndClearExpectations(this);
Darin Petkov98dd6a02011-06-10 15:12:57 -0700644 config_->pid_ = 0;
645}
646
647TEST_F(DHCPConfigTest, Restart) {
648 const int kPID1 = 1 << 17; // Ensure unknown positive PID.
649 const int kPID2 = 987;
650 const unsigned int kTag1 = 11;
651 const unsigned int kTag2 = 22;
652 config_->pid_ = kPID1;
653 config_->child_watch_tag_ = kTag1;
654 DHCPProvider::GetInstance()->BindPID(kPID1, config_);
Chris Masone2176a882011-09-14 22:29:15 -0700655 EXPECT_CALL(*glib(), SourceRemove(kTag1)).WillOnce(Return(true));
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700656 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(
657 DoAll(SetArgumentPointee<2>(kPID2), Return(true)));
Chris Masone2176a882011-09-14 22:29:15 -0700658 EXPECT_CALL(*glib(), ChildWatchAdd(kPID2, _, _)).WillOnce(Return(kTag2));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700659 EXPECT_TRUE(config_->Restart());
660 EXPECT_EQ(kPID2, config_->pid_);
661 EXPECT_EQ(config_.get(), DHCPProvider::GetInstance()->GetConfig(kPID2).get());
662 EXPECT_EQ(kTag2, config_->child_watch_tag_);
663 DHCPProvider::GetInstance()->UnbindPID(kPID2);
664 config_->pid_ = 0;
665 config_->child_watch_tag_ = 0;
666}
667
668TEST_F(DHCPConfigTest, RestartNoClient) {
669 const int kPID = 777;
670 const unsigned int kTag = 66;
Chris Masone2176a882011-09-14 22:29:15 -0700671 EXPECT_CALL(*glib(), SourceRemove(_)).Times(0);
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700672 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(
673 DoAll(SetArgumentPointee<2>(kPID), Return(true)));
Chris Masone2176a882011-09-14 22:29:15 -0700674 EXPECT_CALL(*glib(), ChildWatchAdd(kPID, _, _)).WillOnce(Return(kTag));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700675 EXPECT_TRUE(config_->Restart());
676 EXPECT_EQ(kPID, config_->pid_);
677 EXPECT_EQ(config_.get(), DHCPProvider::GetInstance()->GetConfig(kPID).get());
678 EXPECT_EQ(kTag, config_->child_watch_tag_);
679 DHCPProvider::GetInstance()->UnbindPID(kPID);
680 config_->pid_ = 0;
681 config_->child_watch_tag_ = 0;
682}
683
Paul Stewartd408fdf2012-05-07 17:15:57 -0700684TEST_F(DHCPConfigTest, StartSuccessEphemeral) {
685 DHCPConfigRefPtr config =
Paul Stewartb1083182014-06-25 03:04:53 -0700686 CreateRunningConfig(kHostName, kDeviceName, kArpGateway);
Paul Stewartd408fdf2012-05-07 17:15:57 -0700687 StopRunningConfigAndExpect(config, false);
688}
Darin Petkov92c43902011-06-09 20:46:06 -0700689
Paul Stewartd408fdf2012-05-07 17:15:57 -0700690TEST_F(DHCPConfigTest, StartSuccessPersistent) {
691 DHCPConfigRefPtr config =
Paul Stewartb1083182014-06-25 03:04:53 -0700692 CreateRunningConfig(kHostName, kLeaseFileSuffix, kArpGateway);
Paul Stewartd408fdf2012-05-07 17:15:57 -0700693 StopRunningConfigAndExpect(config, true);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700694}
695
Paul Stewartc5099532013-12-12 07:53:15 -0800696TEST_F(DHCPConfigCallbackTest, StartTimeout) {
697 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
698 EXPECT_CALL(*this, FailureCallback(ConfigRef()));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700699 config_->lease_acquisition_timeout_seconds_ = 0;
700 config_->proxy_.reset(proxy_.release());
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700701 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(true));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700702 config_->Start();
703 config_->dispatcher_->DispatchPendingEvents();
Paul Stewartc5099532013-12-12 07:53:15 -0800704 Mock::VerifyAndClearExpectations(this);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700705}
706
Darin Petkov98dd6a02011-06-10 15:12:57 -0700707TEST_F(DHCPConfigTest, Stop) {
Darin Petkov98dd6a02011-06-10 15:12:57 -0700708 const int kPID = 1 << 17; // Ensure unknown positive PID.
mukesh agrawal1835e772013-01-15 18:35:03 -0800709 ScopedMockLog log;
710 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
711 EXPECT_CALL(log, Log(_, _, ContainsRegex(
Darin Petkov3fe17662013-02-04 14:19:08 +0100712 base::StringPrintf("Stopping.+%s", __func__))));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700713 config_->pid_ = kPID;
Darin Petkov3fe17662013-02-04 14:19:08 +0100714 DHCPProvider::GetInstance()->BindPID(kPID, config_);
Paul Stewart1f916e42013-12-23 09:52:54 -0800715 config_->lease_acquisition_timeout_callback_.Reset(base::Bind(&DoNothing));
716 config_->lease_expiration_callback_.Reset(base::Bind(&DoNothing));
mukesh agrawal1835e772013-01-15 18:35:03 -0800717 config_->Stop(__func__);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700718 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Paul Stewart1f916e42013-12-23 09:52:54 -0800719 EXPECT_TRUE(config_->lease_expiration_callback_.IsCancelled());
Darin Petkov3fe17662013-02-04 14:19:08 +0100720 EXPECT_FALSE(DHCPProvider::GetInstance()->GetConfig(kPID));
721 EXPECT_FALSE(config_->pid_);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700722}
723
724TEST_F(DHCPConfigTest, StopDuringRequestIP) {
725 config_->pid_ = 567;
726 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
727 config_->proxy_.reset(proxy_.release());
728 EXPECT_TRUE(config_->RenewIP());
729 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
730 config_->pid_ = 0; // Keep Stop from killing a real process.
mukesh agrawal1835e772013-01-15 18:35:03 -0800731 config_->Stop(__func__);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700732 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700733}
734
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800735TEST_F(DHCPConfigTest, SetProperty) {
Chris Masone43b48a12011-07-01 13:37:07 -0700736 ::DBus::Error error;
737 // Ensure that an attempt to write a R/O property returns InvalidArgs error.
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800738 EXPECT_FALSE(DBusAdaptor::SetProperty(config_->mutable_store(),
Ben Chan0295e0f2013-09-20 13:47:29 -0700739 kAddressProperty,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800740 PropertyStoreTest::kStringV,
741 &error));
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700742 ASSERT_TRUE(error.is_set()); // name() may be invalid otherwise
Chris Masone9d779932011-08-25 16:33:41 -0700743 EXPECT_EQ(invalid_args(), error.name());
Chris Masone43b48a12011-07-01 13:37:07 -0700744}
745
Darin Petkove7cb7f82011-06-03 13:21:51 -0700746} // namespace shill