blob: f7322d4bc57d17f836bc9f2d2025bc2d218f1300 [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>
Darin Petkov92c43902011-06-09 20:46:06 -070010#include <base/stringprintf.h>
Chris Masone43b48a12011-07-01 13:37:07 -070011#include <chromeos/dbus/service_constants.h>
Chris Masone8a7b8be2011-07-22 12:43:37 -070012#include <gtest/gtest.h>
Darin Petkov92c43902011-06-09 20:46:06 -070013
Chris Masone43b48a12011-07-01 13:37:07 -070014#include "shill/dbus_adaptor.h"
Darin Petkovf7897bc2011-06-08 17:13:36 -070015#include "shill/dhcp_provider.h"
Paul Stewart26b327e2011-10-19 11:38:09 -070016#include "shill/event_dispatcher.h"
Chris Masone19e30402011-07-19 15:48:47 -070017#include "shill/mock_control.h"
Darin Petkov98dd6a02011-06-10 15:12:57 -070018#include "shill/mock_dhcp_proxy.h"
Darin Petkovf7897bc2011-06-08 17:13:36 -070019#include "shill/mock_glib.h"
mukesh agrawal6c6655d2012-12-06 14:49:50 -080020#include "shill/mock_log.h"
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070021#include "shill/mock_minijail.h"
Chris Masone43b48a12011-07-01 13:37:07 -070022#include "shill/property_store_unittest.h"
Darin Petkova7b89492011-07-27 12:48:17 -070023#include "shill/proxy_factory.h"
Darin Petkove7cb7f82011-06-03 13:21:51 -070024
Eric Shienbrood3e20a232012-02-16 11:35:56 -050025using base::Bind;
Paul Stewart5ad16062013-02-21 18:10:48 -080026using base::ScopedTempDir;
Eric Shienbrood3e20a232012-02-16 11:35:56 -050027using base::Unretained;
Darin Petkove7cb7f82011-06-03 13:21:51 -070028using std::string;
29using std::vector;
Darin Petkovf7897bc2011-06-08 17:13:36 -070030using testing::_;
mukesh agrawal1835e772013-01-15 18:35:03 -080031using testing::AnyNumber;
32using testing::ContainsRegex;
Darin Petkovf7897bc2011-06-08 17:13:36 -070033using testing::Return;
34using testing::SetArgumentPointee;
Darin Petkove7cb7f82011-06-03 13:21:51 -070035using testing::Test;
36
37namespace shill {
38
Darin Petkov92c43902011-06-09 20:46:06 -070039namespace {
Darin Petkova7b89492011-07-27 12:48:17 -070040const char kDeviceName[] = "eth0";
Paul Stewartd32f4842012-01-11 16:08:13 -080041const char kHostName[] = "hostname";
Paul Stewartd408fdf2012-05-07 17:15:57 -070042const char kLeaseFileSuffix[] = "leasefilesuffix";
43const bool kArpGateway = true;
Darin Petkov92c43902011-06-09 20:46:06 -070044} // namespace {}
45
Chris Masone43b48a12011-07-01 13:37:07 -070046class DHCPConfigTest : public PropertyStoreTest {
Darin Petkove7cb7f82011-06-03 13:21:51 -070047 public:
Darin Petkovf7897bc2011-06-08 17:13:36 -070048 DHCPConfigTest()
Darin Petkovf65e9282011-06-21 14:29:56 -070049 : proxy_(new MockDHCPProxy()),
Darin Petkova7b89492011-07-27 12:48:17 -070050 proxy_factory_(this),
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070051 minijail_(new MockMinijail()),
Chris Masone19e30402011-07-19 15:48:47 -070052 config_(new DHCPConfig(&control_,
Chris Masone2176a882011-09-14 22:29:15 -070053 dispatcher(),
Chris Masone19e30402011-07-19 15:48:47 -070054 DHCPProvider::GetInstance(),
Darin Petkov92c43902011-06-09 20:46:06 -070055 kDeviceName,
Paul Stewartd32f4842012-01-11 16:08:13 -080056 kHostName,
Paul Stewartd408fdf2012-05-07 17:15:57 -070057 kLeaseFileSuffix,
58 kArpGateway,
Chris Masone2176a882011-09-14 22:29:15 -070059 glib())) {}
Darin Petkova7b89492011-07-27 12:48:17 -070060
61 virtual void SetUp() {
Darin Petkovab565bb2011-10-06 02:55:51 -070062 config_->proxy_factory_ = &proxy_factory_;
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070063 config_->minijail_ = minijail_.get();
Darin Petkova7b89492011-07-27 12:48:17 -070064 }
65
66 virtual void TearDown() {
Darin Petkovab565bb2011-10-06 02:55:51 -070067 config_->proxy_factory_ = NULL;
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070068 config_->minijail_ = NULL;
Darin Petkov98dd6a02011-06-10 15:12:57 -070069 }
Darin Petkove7cb7f82011-06-03 13:21:51 -070070
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070071 DHCPConfigRefPtr CreateMockMinijailConfig(const string &hostname,
72 const string &lease_suffix,
73 bool arp_gateway);
Paul Stewartd408fdf2012-05-07 17:15:57 -070074 DHCPConfigRefPtr CreateRunningConfig(const string &hostname,
75 const string &lease_suffix,
76 bool arp_gateway);
77 void StopRunningConfigAndExpect(DHCPConfigRefPtr config,
78 bool lease_file_exists);
79
Darin Petkove7cb7f82011-06-03 13:21:51 -070080 protected:
Darin Petkova7b89492011-07-27 12:48:17 -070081 class TestProxyFactory : public ProxyFactory {
82 public:
Paul Stewart7355ce12011-09-02 10:47:01 -070083 explicit TestProxyFactory(DHCPConfigTest *test) : test_(test) {}
Darin Petkova7b89492011-07-27 12:48:17 -070084
mukesh agrawal1830fa12011-09-26 14:31:40 -070085 virtual DHCPProxyInterface *CreateDHCPProxy(const string &/*service*/) {
Darin Petkova7b89492011-07-27 12:48:17 -070086 return test_->proxy_.release();
87 }
88
89 private:
90 DHCPConfigTest *test_;
91 };
92
Paul Stewartd408fdf2012-05-07 17:15:57 -070093 static const int kPID;
94 static const unsigned int kTag;
95
96 FilePath lease_file_;
97 FilePath pid_file_;
98 ScopedTempDir temp_dir_;
Darin Petkova7b89492011-07-27 12:48:17 -070099 scoped_ptr<MockDHCPProxy> proxy_;
100 TestProxyFactory proxy_factory_;
Chris Masone19e30402011-07-19 15:48:47 -0700101 MockControl control_;
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700102 scoped_ptr<MockMinijail> minijail_;
Darin Petkovf7897bc2011-06-08 17:13:36 -0700103 DHCPConfigRefPtr config_;
Darin Petkove7cb7f82011-06-03 13:21:51 -0700104};
105
Paul Stewartd408fdf2012-05-07 17:15:57 -0700106const int DHCPConfigTest::kPID = 123456;
107const unsigned int DHCPConfigTest::kTag = 77;
108
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700109DHCPConfigRefPtr DHCPConfigTest::CreateMockMinijailConfig(
110 const string &hostname,
111 const string &lease_suffix,
112 bool arp_gateway) {
113 DHCPConfigRefPtr config(new DHCPConfig(&control_,
114 dispatcher(),
115 DHCPProvider::GetInstance(),
116 kDeviceName,
117 hostname,
118 lease_suffix,
119 arp_gateway,
120 glib()));
121 config->minijail_ = minijail_.get();
122 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(false));
123
124 return config;
125}
126
Paul Stewartd408fdf2012-05-07 17:15:57 -0700127DHCPConfigRefPtr DHCPConfigTest::CreateRunningConfig(const string &hostname,
128 const string &lease_suffix,
129 bool arp_gateway) {
130 DHCPConfigRefPtr config(new DHCPConfig(&control_,
131 dispatcher(),
132 DHCPProvider::GetInstance(),
133 kDeviceName,
134 hostname,
135 lease_suffix,
136 arp_gateway,
137 glib()));
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700138 config->minijail_ = minijail_.get();
139 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _))
140 .WillOnce(DoAll(SetArgumentPointee<2>(kPID), Return(true)));
Paul Stewartd408fdf2012-05-07 17:15:57 -0700141 EXPECT_CALL(*glib(), ChildWatchAdd(kPID, _, _)).WillOnce(Return(kTag));
142 EXPECT_TRUE(config->Start());
143 EXPECT_EQ(kPID, config->pid_);
144 EXPECT_EQ(config.get(), DHCPProvider::GetInstance()->GetConfig(kPID).get());
145 EXPECT_EQ(kTag, config->child_watch_tag_);
146
147 EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
148 config->root_ = temp_dir_.path();
Jorge Lucangeli Obes2f3169d2012-04-25 11:38:25 -0700149 FilePath varrun = temp_dir_.path().Append("var/run/dhcpcd");
Paul Stewartd408fdf2012-05-07 17:15:57 -0700150 EXPECT_TRUE(file_util::CreateDirectory(varrun));
151 pid_file_ = varrun.Append(base::StringPrintf("dhcpcd-%s.pid", kDeviceName));
152 FilePath varlib = temp_dir_.path().Append("var/lib/dhcpcd");
153 EXPECT_TRUE(file_util::CreateDirectory(varlib));
154 lease_file_ =
155 varlib.Append(base::StringPrintf("dhcpcd-%s.lease", kDeviceName));
156 EXPECT_EQ(0, file_util::WriteFile(pid_file_, "", 0));
157 EXPECT_EQ(0, file_util::WriteFile(lease_file_, "", 0));
158 EXPECT_TRUE(file_util::PathExists(pid_file_));
159 EXPECT_TRUE(file_util::PathExists(lease_file_));
160
161 return config;
162}
163
164void DHCPConfigTest::StopRunningConfigAndExpect(DHCPConfigRefPtr config,
165 bool lease_file_exists) {
mukesh agrawal6c6655d2012-12-06 14:49:50 -0800166 ScopedMockLog log;
167 // We use a non-zero exit status so that we get the log message.
168 EXPECT_CALL(log, Log(_, _, ::testing::EndsWith("status 10")));
169 DHCPConfig::ChildWatchCallback(kPID, 10, config.get());
Paul Stewartd408fdf2012-05-07 17:15:57 -0700170 EXPECT_EQ(NULL, DHCPProvider::GetInstance()->GetConfig(kPID).get());
171
172 EXPECT_FALSE(file_util::PathExists(pid_file_));
173 EXPECT_EQ(lease_file_exists, file_util::PathExists(lease_file_));
174}
175
Darin Petkove7cb7f82011-06-03 13:21:51 -0700176TEST_F(DHCPConfigTest, GetIPv4AddressString) {
Darin Petkovf7897bc2011-06-08 17:13:36 -0700177 EXPECT_EQ("255.255.255.255", config_->GetIPv4AddressString(0xffffffff));
178 EXPECT_EQ("0.0.0.0", config_->GetIPv4AddressString(0));
179 EXPECT_EQ("1.2.3.4", config_->GetIPv4AddressString(0x04030201));
Darin Petkove7cb7f82011-06-03 13:21:51 -0700180}
181
Darin Petkova7b89492011-07-27 12:48:17 -0700182TEST_F(DHCPConfigTest, InitProxy) {
183 static const char kService[] = ":1.200";
Darin Petkova7b89492011-07-27 12:48:17 -0700184 EXPECT_TRUE(proxy_.get());
185 EXPECT_FALSE(config_->proxy_.get());
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 Stewartd408fdf2012-05-07 17:15:57 -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 Stewartd408fdf2012-05-07 17:15:57 -0700308 string(arg[1]) != "-B") {
Paul Stewartd32f4842012-01-11 16:08:13 -0800309 return false;
310 }
311
Paul Stewartd408fdf2012-05-07 17:15:57 -0700312 int end_offset = 2;
Paul Stewartd32f4842012-01-11 16:08:13 -0800313 if (has_hostname) {
Paul Stewartd408fdf2012-05-07 17:15:57 -0700314 if (string(arg[end_offset]) != "-h" ||
315 string(arg[end_offset + 1]) != kHostName) {
Paul Stewartd32f4842012-01-11 16:08:13 -0800316 return false;
317 }
Paul Stewartd408fdf2012-05-07 17:15:57 -0700318 end_offset += 2;
Paul Stewartd32f4842012-01-11 16:08:13 -0800319 }
320
Paul Stewartd408fdf2012-05-07 17:15:57 -0700321 if (has_arp_gateway) {
322 if (string(arg[end_offset]) != "-R")
323 return false;
324 ++end_offset;
325 }
326
327 string device_arg = has_lease_suffix ?
328 string(kDeviceName) + "=" + string(kLeaseFileSuffix) : kDeviceName;
329 return string(arg[end_offset]) == device_arg && arg[end_offset + 1] == NULL;
Paul Stewartd32f4842012-01-11 16:08:13 -0800330}
331
332TEST_F(DHCPConfigTest, StartWithHostname) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700333 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(false));
Paul Stewartd32f4842012-01-11 16:08:13 -0800334 EXPECT_FALSE(config_->Start());
335}
336
337TEST_F(DHCPConfigTest, StartWithoutHostname) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700338 DHCPConfigRefPtr config = CreateMockMinijailConfig("",
339 kLeaseFileSuffix,
340 kArpGateway);
Paul Stewartd408fdf2012-05-07 17:15:57 -0700341 EXPECT_FALSE(config->Start());
342}
343
344TEST_F(DHCPConfigTest, StartWithoutArpGateway) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700345 DHCPConfigRefPtr config = CreateMockMinijailConfig(kHostName,
346 kLeaseFileSuffix,
347 false);
Paul Stewartd408fdf2012-05-07 17:15:57 -0700348 EXPECT_FALSE(config->Start());
349}
350
351TEST_F(DHCPConfigTest, StartWithoutLeaseSuffix) {
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700352 DHCPConfigRefPtr config = CreateMockMinijailConfig(kHostName,
353 kDeviceName,
354 kArpGateway);
Paul Stewartd32f4842012-01-11 16:08:13 -0800355 EXPECT_FALSE(config->Start());
356}
357
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700358namespace {
359
360class UpdateCallbackTest {
361 public:
362 UpdateCallbackTest(const string &message,
Chris Masone2b105542011-06-22 10:58:09 -0700363 const IPConfigRefPtr &ipconfig,
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700364 bool success)
365 : message_(message),
366 ipconfig_(ipconfig),
367 success_(success),
368 called_(false) {}
369
Chris Masone2b105542011-06-22 10:58:09 -0700370 void Callback(const IPConfigRefPtr &ipconfig, bool success) {
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700371 called_ = true;
372 EXPECT_EQ(ipconfig_.get(), ipconfig.get()) << message_;
373 EXPECT_EQ(success_, success) << message_;
374 }
375
376 bool called() const { return called_; }
377
378 private:
379 const string message_;
380 IPConfigRefPtr ipconfig_;
381 bool success_;
382 bool called_;
383};
384
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700385void DoNothing() {}
386
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700387} // namespace {}
388
389TEST_F(DHCPConfigTest, ProcessEventSignalFail) {
390 DHCPConfig::Configuration conf;
391 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
392 0x01020304);
393 UpdateCallbackTest callback_test(DHCPConfig::kReasonFail, config_, false);
394 config_->RegisterUpdateCallback(
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500395 Bind(&UpdateCallbackTest::Callback, Unretained(&callback_test)));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700396 config_->lease_acquisition_timeout_callback_.Reset(base::Bind(&DoNothing));
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700397 config_->ProcessEventSignal(DHCPConfig::kReasonFail, conf);
398 EXPECT_TRUE(callback_test.called());
399 EXPECT_TRUE(config_->properties().address.empty());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700400 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700401}
402
403TEST_F(DHCPConfigTest, ProcessEventSignalSuccess) {
404 static const char * const kReasons[] = {
405 DHCPConfig::kReasonBound,
406 DHCPConfig::kReasonRebind,
407 DHCPConfig::kReasonReboot,
408 DHCPConfig::kReasonRenew
409 };
410 for (size_t r = 0; r < arraysize(kReasons); r++) {
411 DHCPConfig::Configuration conf;
412 string message = string(kReasons[r]) + " failed";
413 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(r);
414 UpdateCallbackTest callback_test(message, config_, true);
415 config_->RegisterUpdateCallback(
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500416 Bind(&UpdateCallbackTest::Callback, Unretained(&callback_test)));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700417 config_->lease_acquisition_timeout_callback_.Reset(base::Bind(&DoNothing));
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700418 config_->ProcessEventSignal(kReasons[r], conf);
419 EXPECT_TRUE(callback_test.called()) << message;
Paul Stewart83224402011-11-30 14:52:30 -0800420 EXPECT_EQ(base::StringPrintf("%zu.0.0.0", r), config_->properties().address)
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700421 << message;
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700422 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700423 }
424}
425
426TEST_F(DHCPConfigTest, ProcessEventSignalUnknown) {
427 DHCPConfig::Configuration conf;
428 conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
429 0x01020304);
430 static const char kReasonUnknown[] = "UNKNOWN_REASON";
431 UpdateCallbackTest callback_test(kReasonUnknown, config_, false);
432 config_->RegisterUpdateCallback(
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500433 Bind(&UpdateCallbackTest::Callback, Unretained(&callback_test)));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700434 config_->lease_acquisition_timeout_callback_.Reset(base::Bind(&DoNothing));
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700435 config_->ProcessEventSignal(kReasonUnknown, conf);
436 EXPECT_FALSE(callback_test.called());
437 EXPECT_TRUE(config_->properties().address.empty());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700438 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700439}
440
441
Darin Petkov98dd6a02011-06-10 15:12:57 -0700442TEST_F(DHCPConfigTest, ReleaseIP) {
443 config_->pid_ = 1 << 18; // Ensure unknown positive PID.
Paul Stewarta02ee492012-05-16 10:04:53 -0700444 config_->arp_gateway_ = false;
Darin Petkovaceede32011-07-18 15:32:38 -0700445 EXPECT_CALL(*proxy_, Release(kDeviceName)).Times(1);
Darin Petkova7b89492011-07-27 12:48:17 -0700446 config_->proxy_.reset(proxy_.release());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700447 EXPECT_TRUE(config_->ReleaseIP());
448 config_->pid_ = 0;
449}
450
Paul Stewarta02ee492012-05-16 10:04:53 -0700451TEST_F(DHCPConfigTest, ReleaseIPArpGW) {
452 config_->pid_ = 1 << 18; // Ensure unknown positive PID.
453 config_->arp_gateway_ = true;
454 EXPECT_CALL(*proxy_, Release(kDeviceName)).Times(0);
455 config_->proxy_.reset(proxy_.release());
456 EXPECT_TRUE(config_->ReleaseIP());
457 config_->pid_ = 0;
458}
459
Darin Petkov98dd6a02011-06-10 15:12:57 -0700460TEST_F(DHCPConfigTest, RenewIP) {
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700461 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700462 config_->pid_ = 456;
Paul Stewartc02344a2012-08-17 16:57:37 -0700463 EXPECT_FALSE(config_->RenewIP()); // Expect no crash with NULL proxy.
Darin Petkovaceede32011-07-18 15:32:38 -0700464 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
Darin Petkova7b89492011-07-27 12:48:17 -0700465 config_->proxy_.reset(proxy_.release());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700466 EXPECT_TRUE(config_->RenewIP());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700467 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700468 config_->pid_ = 0;
469}
470
471TEST_F(DHCPConfigTest, RequestIP) {
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700472 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700473 config_->pid_ = 567;
Darin Petkovaceede32011-07-18 15:32:38 -0700474 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
Darin Petkova7b89492011-07-27 12:48:17 -0700475 config_->proxy_.reset(proxy_.release());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700476 EXPECT_TRUE(config_->RenewIP());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700477 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
478 config_->pid_ = 0;
479}
480
481TEST_F(DHCPConfigTest, RequestIPTimeout) {
482 UpdateCallbackTest callback_test(DHCPConfig::kReasonFail, config_, false);
483 config_->RegisterUpdateCallback(
484 Bind(&UpdateCallbackTest::Callback, Unretained(&callback_test)));
485 config_->lease_acquisition_timeout_seconds_ = 0;
486 config_->pid_ = 567;
487 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
488 config_->proxy_.reset(proxy_.release());
489 config_->RenewIP();
490 config_->dispatcher_->DispatchPendingEvents();
491 EXPECT_TRUE(callback_test.called());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700492 config_->pid_ = 0;
493}
494
495TEST_F(DHCPConfigTest, Restart) {
496 const int kPID1 = 1 << 17; // Ensure unknown positive PID.
497 const int kPID2 = 987;
498 const unsigned int kTag1 = 11;
499 const unsigned int kTag2 = 22;
500 config_->pid_ = kPID1;
501 config_->child_watch_tag_ = kTag1;
502 DHCPProvider::GetInstance()->BindPID(kPID1, config_);
Chris Masone2176a882011-09-14 22:29:15 -0700503 EXPECT_CALL(*glib(), SourceRemove(kTag1)).WillOnce(Return(true));
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700504 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(
505 DoAll(SetArgumentPointee<2>(kPID2), Return(true)));
Chris Masone2176a882011-09-14 22:29:15 -0700506 EXPECT_CALL(*glib(), ChildWatchAdd(kPID2, _, _)).WillOnce(Return(kTag2));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700507 EXPECT_TRUE(config_->Restart());
508 EXPECT_EQ(kPID2, config_->pid_);
509 EXPECT_EQ(config_.get(), DHCPProvider::GetInstance()->GetConfig(kPID2).get());
510 EXPECT_EQ(kTag2, config_->child_watch_tag_);
511 DHCPProvider::GetInstance()->UnbindPID(kPID2);
512 config_->pid_ = 0;
513 config_->child_watch_tag_ = 0;
514}
515
516TEST_F(DHCPConfigTest, RestartNoClient) {
517 const int kPID = 777;
518 const unsigned int kTag = 66;
Chris Masone2176a882011-09-14 22:29:15 -0700519 EXPECT_CALL(*glib(), SourceRemove(_)).Times(0);
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700520 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(
521 DoAll(SetArgumentPointee<2>(kPID), Return(true)));
Chris Masone2176a882011-09-14 22:29:15 -0700522 EXPECT_CALL(*glib(), ChildWatchAdd(kPID, _, _)).WillOnce(Return(kTag));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700523 EXPECT_TRUE(config_->Restart());
524 EXPECT_EQ(kPID, config_->pid_);
525 EXPECT_EQ(config_.get(), DHCPProvider::GetInstance()->GetConfig(kPID).get());
526 EXPECT_EQ(kTag, config_->child_watch_tag_);
527 DHCPProvider::GetInstance()->UnbindPID(kPID);
528 config_->pid_ = 0;
529 config_->child_watch_tag_ = 0;
530}
531
Paul Stewartd408fdf2012-05-07 17:15:57 -0700532TEST_F(DHCPConfigTest, StartSuccessEphemeral) {
533 DHCPConfigRefPtr config =
534 CreateRunningConfig(kHostName, kDeviceName, kArpGateway);
535 StopRunningConfigAndExpect(config, false);
536}
Darin Petkov92c43902011-06-09 20:46:06 -0700537
Paul Stewartd408fdf2012-05-07 17:15:57 -0700538TEST_F(DHCPConfigTest, StartSuccessPersistent) {
539 DHCPConfigRefPtr config =
540 CreateRunningConfig(kHostName, kLeaseFileSuffix, kArpGateway);
541 StopRunningConfigAndExpect(config, true);
Darin Petkovf7897bc2011-06-08 17:13:36 -0700542}
543
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700544TEST_F(DHCPConfigTest, StartTimeout) {
545 UpdateCallbackTest callback_test(DHCPConfig::kReasonFail, config_, false);
546 config_->RegisterUpdateCallback(
547 Bind(&UpdateCallbackTest::Callback, Unretained(&callback_test)));
548 config_->lease_acquisition_timeout_seconds_ = 0;
549 config_->proxy_.reset(proxy_.release());
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700550 EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(true));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700551 config_->Start();
552 config_->dispatcher_->DispatchPendingEvents();
553 EXPECT_TRUE(callback_test.called());
554}
555
Darin Petkov98dd6a02011-06-10 15:12:57 -0700556TEST_F(DHCPConfigTest, Stop) {
Darin Petkov98dd6a02011-06-10 15:12:57 -0700557 const int kPID = 1 << 17; // Ensure unknown positive PID.
mukesh agrawal1835e772013-01-15 18:35:03 -0800558 ScopedMockLog log;
559 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
560 EXPECT_CALL(log, Log(_, _, ContainsRegex(
Darin Petkov3fe17662013-02-04 14:19:08 +0100561 base::StringPrintf("Stopping.+%s", __func__))));
Darin Petkov98dd6a02011-06-10 15:12:57 -0700562 config_->pid_ = kPID;
Darin Petkov3fe17662013-02-04 14:19:08 +0100563 DHCPProvider::GetInstance()->BindPID(kPID, config_);
mukesh agrawal1835e772013-01-15 18:35:03 -0800564 config_->Stop(__func__);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700565 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkov3fe17662013-02-04 14:19:08 +0100566 EXPECT_FALSE(DHCPProvider::GetInstance()->GetConfig(kPID));
567 EXPECT_FALSE(config_->pid_);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700568}
569
570TEST_F(DHCPConfigTest, StopDuringRequestIP) {
571 config_->pid_ = 567;
572 EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
573 config_->proxy_.reset(proxy_.release());
574 EXPECT_TRUE(config_->RenewIP());
575 EXPECT_FALSE(config_->lease_acquisition_timeout_callback_.IsCancelled());
576 config_->pid_ = 0; // Keep Stop from killing a real process.
mukesh agrawal1835e772013-01-15 18:35:03 -0800577 config_->Stop(__func__);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700578 EXPECT_TRUE(config_->lease_acquisition_timeout_callback_.IsCancelled());
Darin Petkov98dd6a02011-06-10 15:12:57 -0700579}
580
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800581TEST_F(DHCPConfigTest, SetProperty) {
Chris Masone43b48a12011-07-01 13:37:07 -0700582 ::DBus::Error error;
583 // Ensure that an attempt to write a R/O property returns InvalidArgs error.
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800584 EXPECT_FALSE(DBusAdaptor::SetProperty(config_->mutable_store(),
585 flimflam::kAddressProperty,
586 PropertyStoreTest::kStringV,
587 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700588 EXPECT_EQ(invalid_args(), error.name());
Chris Masone43b48a12011-07-01 13:37:07 -0700589}
590
Darin Petkove7cb7f82011-06-03 13:21:51 -0700591} // namespace shill