blob: 9202c071a896aa79b6456b49508cfb5f6f110d5e [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>
Utkarsh Sanghi83bd64b2014-07-29 16:01:43 -070015#include <chromeos/minijail/mock_minijail.h>
Darin Petkov92c43902011-06-09 20:46:06 -070016
Chris Masone43b48a12011-07-01 13:37:07 -070017#include "shill/dbus_adaptor.h"
Darin Petkovf7897bc2011-06-08 17:13:36 -070018#include "shill/dhcp_provider.h"
Paul Stewart26b327e2011-10-19 11:38:09 -070019#include "shill/event_dispatcher.h"
Chris Masone19e30402011-07-19 15:48:47 -070020#include "shill/mock_control.h"
Darin Petkov98dd6a02011-06-10 15:12:57 -070021#include "shill/mock_dhcp_proxy.h"
Darin Petkovf7897bc2011-06-08 17:13:36 -070022#include "shill/mock_glib.h"
mukesh agrawal6c6655d2012-12-06 14:49:50 -080023#include "shill/mock_log.h"
Paul Stewart3bdf1ab2014-07-17 19:22:26 -070024#include "shill/mock_metrics.h"
Ben Chana55469d2014-01-27 16:35:29 -080025#include "shill/mock_proxy_factory.h"
Chris Masone43b48a12011-07-01 13:37:07 -070026#include "shill/property_store_unittest.h"
Ben Chana55469d2014-01-27 16:35:29 -080027#include "shill/testing.h"
Darin Petkove7cb7f82011-06-03 13:21:51 -070028
Eric Shienbrood3e20a232012-02-16 11:35:56 -050029using base::Bind;
Albert Chaulk0e1cdea2013-02-27 15:32:55 -080030using base::FilePath;
Paul Stewart5ad16062013-02-21 18:10:48 -080031using base::ScopedTempDir;
Eric Shienbrood3e20a232012-02-16 11:35:56 -050032using base::Unretained;
Utkarsh Sanghi83bd64b2014-07-29 16:01:43 -070033using chromeos::MockMinijail;
Darin Petkove7cb7f82011-06-03 13:21:51 -070034using std::string;
35using std::vector;
Darin Petkovf7897bc2011-06-08 17:13:36 -070036using testing::_;
mukesh agrawal1835e772013-01-15 18:35:03 -080037using testing::AnyNumber;
38using testing::ContainsRegex;
Paul Stewart475c0722014-04-18 08:52:00 -070039using testing::InvokeWithoutArgs;
Paul Stewart21f7b342013-11-19 10:15:58 -080040using testing::Mock;
Darin Petkovf7897bc2011-06-08 17:13:36 -070041using testing::Return;
42using testing::SetArgumentPointee;
Darin Petkove7cb7f82011-06-03 13:21:51 -070043using testing::Test;
44
45namespace shill {
46
Darin Petkov92c43902011-06-09 20:46:06 -070047namespace {
Darin Petkova7b89492011-07-27 12:48:17 -070048const char kDeviceName[] = "eth0";
Paul Stewartd32f4842012-01-11 16:08:13 -080049const char kHostName[] = "hostname";
Paul Stewartd408fdf2012-05-07 17:15:57 -070050const char kLeaseFileSuffix[] = "leasefilesuffix";
51const bool kArpGateway = true;
Paul Stewart75a68b92013-10-24 10:50:27 -070052const bool kHasHostname = true;
53const bool kHasLeaseSuffix = true;
Alex Vakulenko8a532292014-06-16 17:18:44 -070054} // namespace
Darin Petkov92c43902011-06-09 20:46:06 -070055
Chris Masone43b48a12011-07-01 13:37:07 -070056class DHCPConfigTest : public PropertyStoreTest {
Darin Petkove7cb7f82011-06-03 13:21:51 -070057 public:
Darin Petkovf7897bc2011-06-08 17:13:36 -070058 DHCPConfigTest()
Darin Petkovf65e9282011-06-21 14:29:56 -070059 : proxy_(new MockDHCPProxy()),
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070060 minijail_(new MockMinijail()),
Paul Stewart3bdf1ab2014-07-17 19:22:26 -070061 metrics_(dispatcher()),
Chris Masone19e30402011-07-19 15:48:47 -070062 config_(new DHCPConfig(&control_,
Chris Masone2176a882011-09-14 22:29:15 -070063 dispatcher(),
Chris Masone19e30402011-07-19 15:48:47 -070064 DHCPProvider::GetInstance(),
Darin Petkov92c43902011-06-09 20:46:06 -070065 kDeviceName,
Paul Stewartd32f4842012-01-11 16:08:13 -080066 kHostName,
Paul Stewartd408fdf2012-05-07 17:15:57 -070067 kLeaseFileSuffix,
68 kArpGateway,
Paul Stewart3bdf1ab2014-07-17 19:22:26 -070069 glib(),
70 &metrics_)) {}
Darin Petkova7b89492011-07-27 12:48:17 -070071
72 virtual void SetUp() {
Darin Petkovab565bb2011-10-06 02:55:51 -070073 config_->proxy_factory_ = &proxy_factory_;
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070074 config_->minijail_ = minijail_.get();
Darin Petkova7b89492011-07-27 12:48:17 -070075 }
76
77 virtual void TearDown() {
Darin Petkovab565bb2011-10-06 02:55:51 -070078 config_->proxy_factory_ = NULL;
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070079 config_->minijail_ = NULL;
Darin Petkov98dd6a02011-06-10 15:12:57 -070080 }
Darin Petkove7cb7f82011-06-03 13:21:51 -070081
Paul Stewart475c0722014-04-18 08:52:00 -070082 void StopInstance() {
83 config_->Stop("In test");
84 }
85
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070086 DHCPConfigRefPtr CreateMockMinijailConfig(const string &hostname,
Paul Stewart75a68b92013-10-24 10:50:27 -070087 const string &lease_suffix,
Paul Stewartb1083182014-06-25 03:04:53 -070088 bool arp_gateway);
Paul Stewartd408fdf2012-05-07 17:15:57 -070089 DHCPConfigRefPtr CreateRunningConfig(const string &hostname,
90 const string &lease_suffix,
Paul Stewartb1083182014-06-25 03:04:53 -070091 bool arp_gateway);
Paul Stewartd408fdf2012-05-07 17:15:57 -070092 void StopRunningConfigAndExpect(DHCPConfigRefPtr config,
93 bool lease_file_exists);
94
Darin Petkove7cb7f82011-06-03 13:21:51 -070095 protected:
Paul Stewartd408fdf2012-05-07 17:15:57 -070096 static const int kPID;
97 static const unsigned int kTag;
98
99 FilePath lease_file_;
100 FilePath pid_file_;
101 ScopedTempDir temp_dir_;
Darin Petkova7b89492011-07-27 12:48:17 -0700102 scoped_ptr<MockDHCPProxy> proxy_;
Ben Chana55469d2014-01-27 16:35:29 -0800103 MockProxyFactory proxy_factory_;
Chris Masone19e30402011-07-19 15:48:47 -0700104 MockControl control_;
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700105 scoped_ptr<MockMinijail> minijail_;
Paul Stewart3bdf1ab2014-07-17 19:22:26 -0700106 MockMetrics metrics_;
Darin Petkovf7897bc2011-06-08 17:13:36 -0700107 DHCPConfigRefPtr config_;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700108};
109
Paul Stewartd408fdf2012-05-07 17:15:57 -0700110const int DHCPConfigTest::kPID = 123456;
111const unsigned int DHCPConfigTest::kTag = 77;
112
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700113DHCPConfigRefPtr DHCPConfigTest::CreateMockMinijailConfig(
Paul Stewart75a68b92013-10-24 10:50:27 -0700114 const string &hostname,
115 const string &lease_suffix,
Paul Stewartb1083182014-06-25 03:04:53 -0700116 bool arp_gateway) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700117 DHCPConfigRefPtr config(new DHCPConfig(&control_,
118 dispatcher(),
119 DHCPProvider::GetInstance(),
120 kDeviceName,
121 hostname,
122 lease_suffix,
123 arp_gateway,
Paul Stewart3bdf1ab2014-07-17 19:22:26 -0700124 glib(),
125 &metrics_));
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700126 config->minijail_ = minijail_.get();
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700127
128 return config;
129}
130
Paul Stewartb1083182014-06-25 03:04:53 -0700131DHCPConfigRefPtr DHCPConfigTest::CreateRunningConfig(const string &hostname,
132 const string &lease_suffix,
133 bool arp_gateway) {
Paul Stewartd408fdf2012-05-07 17:15:57 -0700134 DHCPConfigRefPtr config(new DHCPConfig(&control_,
135 dispatcher(),
136 DHCPProvider::GetInstance(),
137 kDeviceName,
138 hostname,
139 lease_suffix,
140 arp_gateway,
Paul Stewart3bdf1ab2014-07-17 19:22:26 -0700141 glib(),
142 &metrics_));
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700143 config->minijail_ = minijail_.get();
144 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _))
145 .WillOnce(DoAll(SetArgumentPointee<2>(kPID), Return(true)));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700146 EXPECT_CALL(*glib(), ChildWatchAdd(kPID, _, _)).WillOnce(Return(kTag));
147 EXPECT_TRUE(config->Start());
148 EXPECT_EQ(kPID, config->pid_);
149 EXPECT_EQ(config.get(), DHCPProvider::GetInstance()->GetConfig(kPID).get());
150 EXPECT_EQ(kTag, config->child_watch_tag_);
151
152 EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
153 config->root_ = temp_dir_.path();
Jorge Lucangeli Obes2f3169d2012-04-25 11:38:25 -0700154 FilePath varrun = temp_dir_.path().Append("var/run/dhcpcd");
Ben Chana0ddf462014-02-06 11:32:42 -0800155 EXPECT_TRUE(base::CreateDirectory(varrun));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700156 pid_file_ = varrun.Append(base::StringPrintf("dhcpcd-%s.pid", kDeviceName));
157 FilePath varlib = temp_dir_.path().Append("var/lib/dhcpcd");
Ben Chana0ddf462014-02-06 11:32:42 -0800158 EXPECT_TRUE(base::CreateDirectory(varlib));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700159 lease_file_ =
160 varlib.Append(base::StringPrintf("dhcpcd-%s.lease", kDeviceName));
Ben Chan6fbf64f2014-05-21 18:07:01 -0700161 EXPECT_EQ(0, base::WriteFile(pid_file_, "", 0));
162 EXPECT_EQ(0, base::WriteFile(lease_file_, "", 0));
Ben Chana0ddf462014-02-06 11:32:42 -0800163 EXPECT_TRUE(base::PathExists(pid_file_));
164 EXPECT_TRUE(base::PathExists(lease_file_));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700165
166 return config;
167}
168
169void DHCPConfigTest::StopRunningConfigAndExpect(DHCPConfigRefPtr config,
170 bool lease_file_exists) {
mukesh agrawal6c6655d2012-12-06 14:49:50 -0800171 ScopedMockLog log;
172 // We use a non-zero exit status so that we get the log message.
173 EXPECT_CALL(log, Log(_, _, ::testing::EndsWith("status 10")));
174 DHCPConfig::ChildWatchCallback(kPID, 10, config.get());
Paul Stewartd408fdf2012-05-07 17:15:57 -0700175 EXPECT_EQ(NULL, DHCPProvider::GetInstance()->GetConfig(kPID).get());
176
Ben Chana0ddf462014-02-06 11:32:42 -0800177 EXPECT_FALSE(base::PathExists(pid_file_));
178 EXPECT_EQ(lease_file_exists, base::PathExists(lease_file_));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700179}
180
Darin Petkove7cb7f82011-06-03 13:21:51 -0700181TEST_F(DHCPConfigTest, GetIPv4AddressString) {
Darin Petkovf7897bc2011-06-08 17:13:36 -0700182 EXPECT_EQ("255.255.255.255", config_->GetIPv4AddressString(0xffffffff));
183 EXPECT_EQ("0.0.0.0", config_->GetIPv4AddressString(0));
184 EXPECT_EQ("1.2.3.4", config_->GetIPv4AddressString(0x04030201));
Darin Petkove7cb7f82011-06-03 13:21:51 -0700185}
186
Darin Petkova7b89492011-07-27 12:48:17 -0700187TEST_F(DHCPConfigTest, InitProxy) {
188 static const char kService[] = ":1.200";
Darin Petkova7b89492011-07-27 12:48:17 -0700189 EXPECT_TRUE(proxy_.get());
190 EXPECT_FALSE(config_->proxy_.get());
Ben Chana55469d2014-01-27 16:35:29 -0800191 EXPECT_CALL(proxy_factory_, CreateDHCPProxy(kService))
192 .WillOnce(ReturnAndReleasePointee(&proxy_));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500193 config_->InitProxy(kService);
Darin Petkova7b89492011-07-27 12:48:17 -0700194 EXPECT_FALSE(proxy_.get());
195 EXPECT_TRUE(config_->proxy_.get());
196
197 config_->InitProxy(kService);
Darin Petkova7b89492011-07-27 12:48:17 -0700198}
199
Paul Stewart65bcd082012-11-16 09:37:14 -0800200TEST_F(DHCPConfigTest, ParseClasslessStaticRoutes) {
201 const string kDefaultAddress = "0.0.0.0";
202 const string kDefaultDestination = kDefaultAddress + "/0";
203 const string kRouter0 = "10.0.0.254";
204 const string kAddress1 = "192.168.1.0";
205 const string kDestination1 = kAddress1 + "/24";
206 // Last gateway missing, leaving an odd number of parameters.
207 const string kBrokenClasslessRoutes0 = kDefaultDestination + " " + kRouter0 +
208 " " + kDestination1;
209 IPConfig::Properties properties;
210 EXPECT_FALSE(DHCPConfig::ParseClasslessStaticRoutes(kBrokenClasslessRoutes0,
211 &properties));
212 EXPECT_TRUE(properties.routes.empty());
213 EXPECT_TRUE(properties.gateway.empty());
214
215 // Gateway argument for the second route is malformed, but we were able
216 // to salvage a default gateway.
217 const string kBrokenRouter1 = "10.0.0";
218 const string kBrokenClasslessRoutes1 = kBrokenClasslessRoutes0 + " " +
219 kBrokenRouter1;
220 EXPECT_FALSE(DHCPConfig::ParseClasslessStaticRoutes(kBrokenClasslessRoutes1,
221 &properties));
222 EXPECT_TRUE(properties.routes.empty());
223 EXPECT_EQ(kRouter0, properties.gateway);
224
225 const string kRouter1 = "10.0.0.253";
226 const string kRouter2 = "10.0.0.252";
227 const string kClasslessRoutes0 = kDefaultDestination + " " + kRouter2 + " " +
228 kDestination1 + " " + kRouter1;
229 EXPECT_TRUE(DHCPConfig::ParseClasslessStaticRoutes(kClasslessRoutes0,
230 &properties));
231 // The old default route is preserved.
232 EXPECT_EQ(kRouter0, properties.gateway);
233
234 // The two routes (including the one which would have otherwise been
235 // classified as a default route) are added to the routing table.
236 EXPECT_EQ(2, properties.routes.size());
237 const IPConfig::Route &route0 = properties.routes[0];
238 EXPECT_EQ(kDefaultAddress, route0.host);
239 EXPECT_EQ("0.0.0.0", route0.netmask);
240 EXPECT_EQ(kRouter2, route0.gateway);
241
242 const IPConfig::Route &route1 = properties.routes[1];
243 EXPECT_EQ(kAddress1, route1.host);
244 EXPECT_EQ("255.255.255.0", route1.netmask);
245 EXPECT_EQ(kRouter1, route1.gateway);
246
247 // A malformed routing table should not affect the current table.
248 EXPECT_FALSE(DHCPConfig::ParseClasslessStaticRoutes(kBrokenClasslessRoutes1,
249 &properties));
250 EXPECT_EQ(2, properties.routes.size());
251 EXPECT_EQ(kRouter0, properties.gateway);
252}
253
Darin Petkove7cb7f82011-06-03 13:21:51 -0700254TEST_F(DHCPConfigTest, ParseConfiguration) {
255 DHCPConfig::Configuration conf;
256 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
257 0x01020304);
258 conf[DHCPConfig::kConfigurationKeySubnetCIDR].writer().append_byte(
259 16);
260 conf[DHCPConfig::kConfigurationKeyBroadcastAddress].writer().append_uint32(
261 0x10203040);
262 {
Darin Petkove7cb7f82011-06-03 13:21:51 -0700263 vector<unsigned int> routers;
264 routers.push_back(0x02040608);
265 routers.push_back(0x03050709);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700266 DBus::MessageIter writer =
267 conf[DHCPConfig::kConfigurationKeyRouters].writer();
Darin Petkove7cb7f82011-06-03 13:21:51 -0700268 writer << routers;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700269 }
270 {
Darin Petkove7cb7f82011-06-03 13:21:51 -0700271 vector<unsigned int> dns;
272 dns.push_back(0x09070503);
273 dns.push_back(0x08060402);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700274 DBus::MessageIter writer = conf[DHCPConfig::kConfigurationKeyDNS].writer();
Darin Petkove7cb7f82011-06-03 13:21:51 -0700275 writer << dns;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700276 }
277 conf[DHCPConfig::kConfigurationKeyDomainName].writer().append_string(
278 "domain-name");
279 {
Darin Petkove7cb7f82011-06-03 13:21:51 -0700280 vector<string> search;
281 search.push_back("foo.com");
282 search.push_back("bar.com");
Darin Petkovf7897bc2011-06-08 17:13:36 -0700283 DBus::MessageIter writer =
284 conf[DHCPConfig::kConfigurationKeyDomainSearch].writer();
Darin Petkove7cb7f82011-06-03 13:21:51 -0700285 writer << search;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700286 }
287 conf[DHCPConfig::kConfigurationKeyMTU].writer().append_uint16(600);
288 conf["UnknownKey"] = DBus::Variant();
289
Darin Petkove7cb7f82011-06-03 13:21:51 -0700290 IPConfig::Properties properties;
Darin Petkovf7897bc2011-06-08 17:13:36 -0700291 ASSERT_TRUE(config_->ParseConfiguration(conf, &properties));
Darin Petkove7cb7f82011-06-03 13:21:51 -0700292 EXPECT_EQ("4.3.2.1", properties.address);
Paul Stewart48100b02012-03-19 07:53:52 -0700293 EXPECT_EQ(16, properties.subnet_prefix);
Darin Petkove7cb7f82011-06-03 13:21:51 -0700294 EXPECT_EQ("64.48.32.16", properties.broadcast_address);
295 EXPECT_EQ("8.6.4.2", properties.gateway);
296 ASSERT_EQ(2, properties.dns_servers.size());
297 EXPECT_EQ("3.5.7.9", properties.dns_servers[0]);
298 EXPECT_EQ("2.4.6.8", properties.dns_servers[1]);
299 EXPECT_EQ("domain-name", properties.domain_name);
300 ASSERT_EQ(2, properties.domain_search.size());
301 EXPECT_EQ("foo.com", properties.domain_search[0]);
302 EXPECT_EQ("bar.com", properties.domain_search[1]);
303 EXPECT_EQ(600, properties.mtu);
304}
305
Darin Petkov92c43902011-06-09 20:46:06 -0700306TEST_F(DHCPConfigTest, StartFail) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700307 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(false));
Chris Masone2176a882011-09-14 22:29:15 -0700308 EXPECT_CALL(*glib(), ChildWatchAdd(_, _, _)).Times(0);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700309 EXPECT_FALSE(config_->Start());
310 EXPECT_EQ(0, config_->pid_);
Darin Petkov92c43902011-06-09 20:46:06 -0700311}
Darin Petkovf7897bc2011-06-08 17:13:36 -0700312
Paul Stewartb1083182014-06-25 03:04:53 -0700313MATCHER_P3(IsDHCPCDArgs, has_hostname, has_arp_gateway, has_lease_suffix, "") {
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
Paul Stewartd408fdf2012-05-07 17:15:57 -0700337 string device_arg = has_lease_suffix ?
338 string(kDeviceName) + "=" + string(kLeaseFileSuffix) : kDeviceName;
339 return string(arg[end_offset]) == device_arg && arg[end_offset + 1] == NULL;
Paul Stewartd32f4842012-01-11 16:08:13 -0800340}
341
342TEST_F(DHCPConfigTest, StartWithHostname) {
Paul Stewart75a68b92013-10-24 10:50:27 -0700343 EXPECT_CALL(*minijail_, RunAndDestroy(_, IsDHCPCDArgs(kHasHostname,
344 kArpGateway,
Paul Stewartb1083182014-06-25 03:04:53 -0700345 kHasLeaseSuffix), _))
Paul Stewart75a68b92013-10-24 10:50:27 -0700346 .WillOnce(Return(false));
Paul Stewartd32f4842012-01-11 16:08:13 -0800347 EXPECT_FALSE(config_->Start());
348}
349
350TEST_F(DHCPConfigTest, StartWithoutHostname) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700351 DHCPConfigRefPtr config = CreateMockMinijailConfig("",
352 kLeaseFileSuffix,
Paul Stewartb1083182014-06-25 03:04:53 -0700353 kArpGateway);
Paul Stewart75a68b92013-10-24 10:50:27 -0700354 EXPECT_CALL(*minijail_, RunAndDestroy(_, IsDHCPCDArgs(!kHasHostname,
355 kArpGateway,
Paul Stewartb1083182014-06-25 03:04:53 -0700356 kHasLeaseSuffix), _))
Paul Stewart75a68b92013-10-24 10:50:27 -0700357 .WillOnce(Return(false));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700358 EXPECT_FALSE(config->Start());
359}
360
361TEST_F(DHCPConfigTest, StartWithoutArpGateway) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700362 DHCPConfigRefPtr config = CreateMockMinijailConfig(kHostName,
363 kLeaseFileSuffix,
Paul Stewartb1083182014-06-25 03:04:53 -0700364 !kArpGateway);
Paul Stewart75a68b92013-10-24 10:50:27 -0700365 EXPECT_CALL(*minijail_, RunAndDestroy(_, IsDHCPCDArgs(kHasHostname,
366 !kArpGateway,
Paul Stewartb1083182014-06-25 03:04:53 -0700367 kHasLeaseSuffix), _))
Paul Stewart75a68b92013-10-24 10:50:27 -0700368 .WillOnce(Return(false));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700369 EXPECT_FALSE(config->Start());
370}
371
372TEST_F(DHCPConfigTest, StartWithoutLeaseSuffix) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700373 DHCPConfigRefPtr config = CreateMockMinijailConfig(kHostName,
374 kDeviceName,
Paul Stewartb1083182014-06-25 03:04:53 -0700375 kArpGateway);
Paul Stewart75a68b92013-10-24 10:50:27 -0700376 EXPECT_CALL(*minijail_, RunAndDestroy(_, IsDHCPCDArgs(kHasHostname,
377 kArpGateway,
Paul Stewartb1083182014-06-25 03:04:53 -0700378 !kHasLeaseSuffix), _))
Paul Stewart75a68b92013-10-24 10:50:27 -0700379 .WillOnce(Return(false));
Paul Stewartd32f4842012-01-11 16:08:13 -0800380 EXPECT_FALSE(config->Start());
381}
382
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700383namespace {
384
Paul Stewartc5099532013-12-12 07:53:15 -0800385class DHCPConfigCallbackTest : public DHCPConfigTest {
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700386 public:
Paul Stewartc5099532013-12-12 07:53:15 -0800387 virtual void SetUp() {
388 DHCPConfigTest::SetUp();
389 config_->RegisterUpdateCallback(
390 Bind(&DHCPConfigCallbackTest::SuccessCallback, Unretained(this)));
391 config_->RegisterFailureCallback(
392 Bind(&DHCPConfigCallbackTest::FailureCallback, Unretained(this)));
393 ip_config_ = config_;
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700394 }
395
Paul Stewartc5099532013-12-12 07:53:15 -0800396 MOCK_METHOD1(SuccessCallback, void(const IPConfigRefPtr &ipconfig));
397 MOCK_METHOD1(FailureCallback, void(const IPConfigRefPtr &ipconfig));
398
399 // The mock methods above take IPConfigRefPtr because this is the type
400 // that the registered callbacks take. This conversion of the DHCP
401 // config ref pointer eases our work in setting up expectations.
402 const IPConfigRefPtr &ConfigRef() { return ip_config_; }
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700403
404 private:
Paul Stewartc5099532013-12-12 07:53:15 -0800405 IPConfigRefPtr ip_config_;
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700406};
407
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700408void DoNothing() {}
409
Alex Vakulenko8a532292014-06-16 17:18:44 -0700410} // namespace
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700411
Paul Stewartc5099532013-12-12 07:53:15 -0800412TEST_F(DHCPConfigCallbackTest, ProcessEventSignalFail) {
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700413 DHCPConfig::Configuration conf;
414 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
415 0x01020304);
Paul Stewartc5099532013-12-12 07:53:15 -0800416 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
417 EXPECT_CALL(*this, FailureCallback(ConfigRef()));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700418 config_->lease_acquisition_timeout_callback_.Reset(base::Bind(&DoNothing));
Paul Stewart1f916e42013-12-23 09:52:54 -0800419 config_->lease_expiration_callback_.Reset(base::Bind(&DoNothing));
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700420 config_->ProcessEventSignal(DHCPConfig::kReasonFail, conf);
Paul Stewartc5099532013-12-12 07:53:15 -0800421 Mock::VerifyAndClearExpectations(this);
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700422 EXPECT_TRUE(config_->properties().address.empty());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700423 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Paul Stewart1f916e42013-12-23 09:52:54 -0800424 EXPECT_TRUE(config_->lease_expiration_callback_.IsCancelled());
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700425}
426
Paul Stewartc5099532013-12-12 07:53:15 -0800427TEST_F(DHCPConfigCallbackTest, ProcessEventSignalSuccess) {
Paul Stewart1f916e42013-12-23 09:52:54 -0800428 for (const auto &reason : { DHCPConfig::kReasonBound,
429 DHCPConfig::kReasonRebind,
430 DHCPConfig::kReasonReboot,
431 DHCPConfig::kReasonRenew }) {
432 int address_octet = 0;
433 for (const auto lease_time_given : { false, true }) {
434 DHCPConfig::Configuration conf;
435 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
436 ++address_octet);
437 if (lease_time_given) {
Ben Chan7fab8972014-08-10 17:14:46 -0700438 const uint32_t kLeaseTime = 1;
Paul Stewart1f916e42013-12-23 09:52:54 -0800439 conf[DHCPConfig::kConfigurationKeyLeaseTime].writer().append_uint32(
440 kLeaseTime);
441 config_->lease_expiration_callback_.Cancel();
442 } else {
443 config_->lease_expiration_callback_.Reset(base::Bind(&DoNothing));
444 }
445 config_->lease_acquisition_timeout_callback_.Reset(
446 base::Bind(&DoNothing));
447 EXPECT_CALL(*this, SuccessCallback(ConfigRef()));
448 EXPECT_CALL(*this, FailureCallback(_)).Times(0);
449 config_->ProcessEventSignal(reason, conf);
450 string failure_message = string(reason) + " failed with lease time " +
451 (lease_time_given ? "given" : "not given");
452 EXPECT_TRUE(Mock::VerifyAndClearExpectations(this)) << failure_message;
453 EXPECT_EQ(base::StringPrintf("%d.0.0.0", address_octet),
454 config_->properties().address) << failure_message;
455 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled())
456 << failure_message;
457 // With no lease time given, the expiration callback will be cancelled.
458 // With a lease time given, the expiration callback should be started.
459 EXPECT_EQ(!lease_time_given,
460 config_->lease_expiration_callback_.IsCancelled())
461 << failure_message;
462 }
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700463 }
464}
465
Paul Stewart475c0722014-04-18 08:52:00 -0700466TEST_F(DHCPConfigCallbackTest, StoppedDuringFailureCallback) {
467 DHCPConfig::Configuration conf;
468 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
469 0x01020304);
470 // Stop the DHCP config while it is calling the failure callback. We
471 // need to ensure that no callbacks are left running inadvertently as
472 // a result.
473 EXPECT_CALL(*this, FailureCallback(ConfigRef()))
474 .WillOnce(InvokeWithoutArgs(this, &DHCPConfigTest::StopInstance));
475 config_->ProcessEventSignal(DHCPConfig::kReasonFail, conf);
476 EXPECT_TRUE(Mock::VerifyAndClearExpectations(this));
477 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
478 EXPECT_TRUE(config_->lease_expiration_callback_.IsCancelled());
479}
480
481TEST_F(DHCPConfigCallbackTest, StoppedDuringSuccessCallback) {
482 DHCPConfig::Configuration conf;
483 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
484 0x01020304);
Ben Chan7fab8972014-08-10 17:14:46 -0700485 const uint32_t kLeaseTime = 1;
Paul Stewart475c0722014-04-18 08:52:00 -0700486 conf[DHCPConfig::kConfigurationKeyLeaseTime].writer().append_uint32(
487 kLeaseTime);
488 // Stop the DHCP config while it is calling the success callback. This
489 // can happen if the device has a static IP configuration and releases
490 // the lease after accepting other network parameters from the DHCP
491 // IPConfig properties. We need to ensure that no callbacks are left
492 // running inadvertently as a result.
493 EXPECT_CALL(*this, SuccessCallback(ConfigRef()))
494 .WillOnce(InvokeWithoutArgs(this, &DHCPConfigTest::StopInstance));
495 config_->ProcessEventSignal(DHCPConfig::kReasonBound, conf);
496 EXPECT_TRUE(Mock::VerifyAndClearExpectations(this));
497 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
498 EXPECT_TRUE(config_->lease_expiration_callback_.IsCancelled());
499}
500
Paul Stewartc5099532013-12-12 07:53:15 -0800501TEST_F(DHCPConfigCallbackTest, ProcessEventSignalUnknown) {
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700502 DHCPConfig::Configuration conf;
503 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
504 0x01020304);
505 static const char kReasonUnknown[] = "UNKNOWN_REASON";
Paul Stewartc5099532013-12-12 07:53:15 -0800506 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
507 EXPECT_CALL(*this, FailureCallback(_)).Times(0);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700508 config_->lease_acquisition_timeout_callback_.Reset(base::Bind(&DoNothing));
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700509 config_->ProcessEventSignal(kReasonUnknown, conf);
Paul Stewartc5099532013-12-12 07:53:15 -0800510 Mock::VerifyAndClearExpectations(this);
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700511 EXPECT_TRUE(config_->properties().address.empty());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700512 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700513}
514
Paul Stewartc5099532013-12-12 07:53:15 -0800515TEST_F(DHCPConfigCallbackTest, ProcessEventSignalGatewayArp) {
Paul Stewart94571f12013-09-10 17:26:07 -0700516 DHCPConfig::Configuration conf;
517 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
518 0x01020304);
Paul Stewartc5099532013-12-12 07:53:15 -0800519 EXPECT_CALL(*this, SuccessCallback(ConfigRef()));
520 EXPECT_CALL(*this, FailureCallback(_)).Times(0);
Paul Stewart94571f12013-09-10 17:26:07 -0700521 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(true));
522 config_->Start();
523 config_->ProcessEventSignal(DHCPConfig::kReasonGatewayArp, conf);
Paul Stewartc5099532013-12-12 07:53:15 -0800524 Mock::VerifyAndClearExpectations(this);
Paul Stewart94571f12013-09-10 17:26:07 -0700525 EXPECT_EQ("4.3.2.1", config_->properties().address);
526 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
527 EXPECT_TRUE(config_->is_gateway_arp_active_);
528
529 // If the timeout gets called, we shouldn't lose the lease since GatewayArp
530 // is active.
531 ScopedMockLog log;
532 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
533 EXPECT_CALL(log, Log(_, _, ::testing::EndsWith(
534 "Continuing to use our previous lease, due to gateway-ARP.")));
Paul Stewartc5099532013-12-12 07:53:15 -0800535 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
536 EXPECT_CALL(*this, FailureCallback(_)).Times(0);
Paul Stewart94571f12013-09-10 17:26:07 -0700537 config_->lease_acquisition_timeout_callback_.callback().Run();
Paul Stewartc5099532013-12-12 07:53:15 -0800538 Mock::VerifyAndClearExpectations(this);
Paul Stewart94571f12013-09-10 17:26:07 -0700539 EXPECT_TRUE(config_->is_gateway_arp_active_);
540
541 // An official reply from a DHCP server should reset our GatewayArp state.
Paul Stewartc5099532013-12-12 07:53:15 -0800542 EXPECT_CALL(*this, SuccessCallback(ConfigRef()));
543 EXPECT_CALL(*this, FailureCallback(_)).Times(0);
Paul Stewart94571f12013-09-10 17:26:07 -0700544 config_->ProcessEventSignal(DHCPConfig::kReasonRenew, conf);
Paul Stewartc5099532013-12-12 07:53:15 -0800545 Mock::VerifyAndClearExpectations(this);
Paul Stewart94571f12013-09-10 17:26:07 -0700546 EXPECT_FALSE(config_->is_gateway_arp_active_);
547}
548
Paul Stewartc5099532013-12-12 07:53:15 -0800549TEST_F(DHCPConfigCallbackTest, ProcessEventSignalGatewayArpNak) {
Paul Stewart94571f12013-09-10 17:26:07 -0700550 DHCPConfig::Configuration conf;
551 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
552 0x01020304);
Paul Stewart94571f12013-09-10 17:26:07 -0700553 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(true));
554 config_->Start();
555 config_->ProcessEventSignal(DHCPConfig::kReasonGatewayArp, conf);
556 EXPECT_TRUE(config_->is_gateway_arp_active_);
557
558 // Sending a NAK should clear is_gateway_arp_active_.
559 config_->ProcessEventSignal(DHCPConfig::kReasonNak, conf);
560 EXPECT_FALSE(config_->is_gateway_arp_active_);
Paul Stewartc5099532013-12-12 07:53:15 -0800561 Mock::VerifyAndClearExpectations(this);
Paul Stewart94571f12013-09-10 17:26:07 -0700562
563 // If the timeout gets called, we should lose the lease since GatewayArp
564 // is not active any more.
Paul Stewartc5099532013-12-12 07:53:15 -0800565 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
566 EXPECT_CALL(*this, FailureCallback(ConfigRef()));
Paul Stewart94571f12013-09-10 17:26:07 -0700567 config_->lease_acquisition_timeout_callback_.callback().Run();
Paul Stewartc5099532013-12-12 07:53:15 -0800568 Mock::VerifyAndClearExpectations(this);
Paul Stewart94571f12013-09-10 17:26:07 -0700569}
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700570
Darin Petkov98dd6a02011-06-10 15:12:57 -0700571TEST_F(DHCPConfigTest, ReleaseIP) {
572 config_->pid_ = 1 << 18; // Ensure unknown positive PID.
Paul Stewarta02ee492012-05-16 10:04:53 -0700573 config_->arp_gateway_ = false;
Darin Petkovaceede32011-07-18 15:32:38 -0700574 EXPECT_CALL(*proxy_, Release(kDeviceName)).Times(1);
Darin Petkova7b89492011-07-27 12:48:17 -0700575 config_->proxy_.reset(proxy_.release());
Paul Stewart217c61d2013-06-13 15:12:02 -0700576 EXPECT_TRUE(config_->ReleaseIP(IPConfig::kReleaseReasonDisconnect));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700577 config_->pid_ = 0;
578}
579
Paul Stewarta02ee492012-05-16 10:04:53 -0700580TEST_F(DHCPConfigTest, ReleaseIPArpGW) {
581 config_->pid_ = 1 << 18; // Ensure unknown positive PID.
582 config_->arp_gateway_ = true;
583 EXPECT_CALL(*proxy_, Release(kDeviceName)).Times(0);
584 config_->proxy_.reset(proxy_.release());
Paul Stewart217c61d2013-06-13 15:12:02 -0700585 EXPECT_TRUE(config_->ReleaseIP(IPConfig::kReleaseReasonDisconnect));
586 config_->pid_ = 0;
587}
588
589TEST_F(DHCPConfigTest, ReleaseIPStaticIPWithLease) {
590 config_->pid_ = 1 << 18; // Ensure unknown positive PID.
591 config_->arp_gateway_ = true;
592 config_->is_lease_active_ = true;
593 EXPECT_CALL(*proxy_, Release(kDeviceName));
594 config_->proxy_.reset(proxy_.release());
595 EXPECT_TRUE(config_->ReleaseIP(IPConfig::kReleaseReasonStaticIP));
596 EXPECT_EQ(NULL, config_->proxy_.get());
597 config_->pid_ = 0;
598}
599
600TEST_F(DHCPConfigTest, ReleaseIPStaticIPWithoutLease) {
601 config_->pid_ = 1 << 18; // Ensure unknown positive PID.
602 config_->arp_gateway_ = true;
603 config_->is_lease_active_ = false;
604 EXPECT_CALL(*proxy_, Release(kDeviceName)).Times(0);
605 MockDHCPProxy *proxy_pointer = proxy_.get();
606 config_->proxy_.reset(proxy_.release());
607 EXPECT_TRUE(config_->ReleaseIP(IPConfig::kReleaseReasonStaticIP));
608 // Expect that proxy has not been released.
609 EXPECT_EQ(proxy_pointer, config_->proxy_.get());
Paul Stewarta02ee492012-05-16 10:04:53 -0700610 config_->pid_ = 0;
611}
612
Darin Petkov98dd6a02011-06-10 15:12:57 -0700613TEST_F(DHCPConfigTest, RenewIP) {
Paul Stewart21f7b342013-11-19 10:15:58 -0800614 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(false));
615 config_->pid_ = 0;
616 EXPECT_FALSE(config_->RenewIP()); // Expect a call to Start() if pid_ is 0.
617 Mock::VerifyAndClearExpectations(minijail_.get());
618 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).Times(0);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700619 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Paul Stewart1f916e42013-12-23 09:52:54 -0800620 config_->lease_expiration_callback_.Reset(base::Bind(&DoNothing));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700621 config_->pid_ = 456;
Paul Stewartc02344a2012-08-17 16:57:37 -0700622 EXPECT_FALSE(config_->RenewIP()); // Expect no crash with NULL proxy.
Darin Petkovaceede32011-07-18 15:32:38 -0700623 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
Darin Petkova7b89492011-07-27 12:48:17 -0700624 config_->proxy_.reset(proxy_.release());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700625 EXPECT_TRUE(config_->RenewIP());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700626 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Paul Stewart1f916e42013-12-23 09:52:54 -0800627 EXPECT_TRUE(config_->lease_expiration_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700628 config_->pid_ = 0;
629}
630
631TEST_F(DHCPConfigTest, RequestIP) {
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700632 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700633 config_->pid_ = 567;
Darin Petkovaceede32011-07-18 15:32:38 -0700634 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
Darin Petkova7b89492011-07-27 12:48:17 -0700635 config_->proxy_.reset(proxy_.release());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700636 EXPECT_TRUE(config_->RenewIP());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700637 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
638 config_->pid_ = 0;
639}
640
Paul Stewartc5099532013-12-12 07:53:15 -0800641TEST_F(DHCPConfigCallbackTest, RequestIPTimeout) {
642 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
643 EXPECT_CALL(*this, FailureCallback(ConfigRef()));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700644 config_->lease_acquisition_timeout_seconds_ = 0;
645 config_->pid_ = 567;
646 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
647 config_->proxy_.reset(proxy_.release());
648 config_->RenewIP();
649 config_->dispatcher_->DispatchPendingEvents();
Paul Stewartc5099532013-12-12 07:53:15 -0800650 Mock::VerifyAndClearExpectations(this);
Darin Petkov98dd6a02011-06-10 15:12:57 -0700651 config_->pid_ = 0;
652}
653
654TEST_F(DHCPConfigTest, Restart) {
655 const int kPID1 = 1 << 17; // Ensure unknown positive PID.
656 const int kPID2 = 987;
657 const unsigned int kTag1 = 11;
658 const unsigned int kTag2 = 22;
659 config_->pid_ = kPID1;
660 config_->child_watch_tag_ = kTag1;
661 DHCPProvider::GetInstance()->BindPID(kPID1, config_);
Chris Masone2176a882011-09-14 22:29:15 -0700662 EXPECT_CALL(*glib(), SourceRemove(kTag1)).WillOnce(Return(true));
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700663 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(
664 DoAll(SetArgumentPointee<2>(kPID2), Return(true)));
Chris Masone2176a882011-09-14 22:29:15 -0700665 EXPECT_CALL(*glib(), ChildWatchAdd(kPID2, _, _)).WillOnce(Return(kTag2));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700666 EXPECT_TRUE(config_->Restart());
667 EXPECT_EQ(kPID2, config_->pid_);
668 EXPECT_EQ(config_.get(), DHCPProvider::GetInstance()->GetConfig(kPID2).get());
669 EXPECT_EQ(kTag2, config_->child_watch_tag_);
670 DHCPProvider::GetInstance()->UnbindPID(kPID2);
671 config_->pid_ = 0;
672 config_->child_watch_tag_ = 0;
673}
674
675TEST_F(DHCPConfigTest, RestartNoClient) {
676 const int kPID = 777;
677 const unsigned int kTag = 66;
Chris Masone2176a882011-09-14 22:29:15 -0700678 EXPECT_CALL(*glib(), SourceRemove(_)).Times(0);
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700679 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(
680 DoAll(SetArgumentPointee<2>(kPID), Return(true)));
Chris Masone2176a882011-09-14 22:29:15 -0700681 EXPECT_CALL(*glib(), ChildWatchAdd(kPID, _, _)).WillOnce(Return(kTag));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700682 EXPECT_TRUE(config_->Restart());
683 EXPECT_EQ(kPID, config_->pid_);
684 EXPECT_EQ(config_.get(), DHCPProvider::GetInstance()->GetConfig(kPID).get());
685 EXPECT_EQ(kTag, config_->child_watch_tag_);
686 DHCPProvider::GetInstance()->UnbindPID(kPID);
687 config_->pid_ = 0;
688 config_->child_watch_tag_ = 0;
689}
690
Paul Stewartd408fdf2012-05-07 17:15:57 -0700691TEST_F(DHCPConfigTest, StartSuccessEphemeral) {
692 DHCPConfigRefPtr config =
Paul Stewartb1083182014-06-25 03:04:53 -0700693 CreateRunningConfig(kHostName, kDeviceName, kArpGateway);
Paul Stewartd408fdf2012-05-07 17:15:57 -0700694 StopRunningConfigAndExpect(config, false);
695}
Darin Petkov92c43902011-06-09 20:46:06 -0700696
Paul Stewartd408fdf2012-05-07 17:15:57 -0700697TEST_F(DHCPConfigTest, StartSuccessPersistent) {
698 DHCPConfigRefPtr config =
Paul Stewartb1083182014-06-25 03:04:53 -0700699 CreateRunningConfig(kHostName, kLeaseFileSuffix, kArpGateway);
Paul Stewartd408fdf2012-05-07 17:15:57 -0700700 StopRunningConfigAndExpect(config, true);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700701}
702
Paul Stewartc5099532013-12-12 07:53:15 -0800703TEST_F(DHCPConfigCallbackTest, StartTimeout) {
704 EXPECT_CALL(*this, SuccessCallback(_)).Times(0);
705 EXPECT_CALL(*this, FailureCallback(ConfigRef()));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700706 config_->lease_acquisition_timeout_seconds_ = 0;
707 config_->proxy_.reset(proxy_.release());
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700708 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(true));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700709 config_->Start();
710 config_->dispatcher_->DispatchPendingEvents();
Paul Stewartc5099532013-12-12 07:53:15 -0800711 Mock::VerifyAndClearExpectations(this);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700712}
713
Darin Petkov98dd6a02011-06-10 15:12:57 -0700714TEST_F(DHCPConfigTest, Stop) {
Darin Petkov98dd6a02011-06-10 15:12:57 -0700715 const int kPID = 1 << 17; // Ensure unknown positive PID.
mukesh agrawal1835e772013-01-15 18:35:03 -0800716 ScopedMockLog log;
717 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
718 EXPECT_CALL(log, Log(_, _, ContainsRegex(
Darin Petkov3fe17662013-02-04 14:19:08 +0100719 base::StringPrintf("Stopping.+%s", __func__))));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700720 config_->pid_ = kPID;
Darin Petkov3fe17662013-02-04 14:19:08 +0100721 DHCPProvider::GetInstance()->BindPID(kPID, config_);
Paul Stewart1f916e42013-12-23 09:52:54 -0800722 config_->lease_acquisition_timeout_callback_.Reset(base::Bind(&DoNothing));
723 config_->lease_expiration_callback_.Reset(base::Bind(&DoNothing));
mukesh agrawal1835e772013-01-15 18:35:03 -0800724 config_->Stop(__func__);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700725 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Paul Stewart1f916e42013-12-23 09:52:54 -0800726 EXPECT_TRUE(config_->lease_expiration_callback_.IsCancelled());
Darin Petkov3fe17662013-02-04 14:19:08 +0100727 EXPECT_FALSE(DHCPProvider::GetInstance()->GetConfig(kPID));
728 EXPECT_FALSE(config_->pid_);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700729}
730
731TEST_F(DHCPConfigTest, StopDuringRequestIP) {
732 config_->pid_ = 567;
733 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
734 config_->proxy_.reset(proxy_.release());
735 EXPECT_TRUE(config_->RenewIP());
736 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
737 config_->pid_ = 0; // Keep Stop from killing a real process.
mukesh agrawal1835e772013-01-15 18:35:03 -0800738 config_->Stop(__func__);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700739 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700740}
741
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800742TEST_F(DHCPConfigTest, SetProperty) {
Chris Masone43b48a12011-07-01 13:37:07 -0700743 ::DBus::Error error;
744 // Ensure that an attempt to write a R/O property returns InvalidArgs error.
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800745 EXPECT_FALSE(DBusAdaptor::SetProperty(config_->mutable_store(),
Ben Chan0295e0f2013-09-20 13:47:29 -0700746 kAddressProperty,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800747 PropertyStoreTest::kStringV,
748 &error));
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700749 ASSERT_TRUE(error.is_set()); // name() may be invalid otherwise
Chris Masone9d779932011-08-25 16:33:41 -0700750 EXPECT_EQ(invalid_args(), error.name());
Chris Masone43b48a12011-07-01 13:37:07 -0700751}
752
Paul Stewart3bdf1ab2014-07-17 19:22:26 -0700753TEST_F(DHCPConfigTest, ProcessStatusChangeSingal) {
754 EXPECT_CALL(metrics_, NotifyDhcpClientStatus(
755 Metrics::kDhcpClientStatusBound));
756 config_->ProcessStatusChangeSignal(DHCPConfig::kStatusBound);
757}
758
Darin Petkove7cb7f82011-06-03 13:21:51 -0700759} // namespace shill