1c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
2c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Copyright (C) 2015 The Android Open Source Project
3c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
4c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Licensed under the Apache License, Version 2.0 (the "License");
5c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// you may not use this file except in compliance with the License.
6c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// You may obtain a copy of the License at
7c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
8c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//      http://www.apache.org/licenses/LICENSE-2.0
9c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
10c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Unless required by applicable law or agreed to in writing, software
11c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// distributed under the License is distributed on an "AS IS" BASIS,
12c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// See the License for the specific language governing permissions and
14c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// limitations under the License.
15c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
16b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
17b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu#include "shill/dhcp/dhcpv6_config.h"
18b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
19b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu#include <memory>
20b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu#include <string>
21b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu#include <vector>
22b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
23b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu#include <base/bind.h>
24b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu#include <base/files/file_util.h>
25b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu#include <base/files/scoped_temp_dir.h>
26b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu#include <base/strings/stringprintf.h>
27289a5a5e18bb1a676b3dfce111af4c2c00c7776eSamuel Tan#if defined(__ANDROID__)
28289a5a5e18bb1a676b3dfce111af4c2c00c7776eSamuel Tan#include <dbus/service_constants.h>
29289a5a5e18bb1a676b3dfce111af4c2c00c7776eSamuel Tan#else
30b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu#include <chromeos/dbus/service_constants.h>
31289a5a5e18bb1a676b3dfce111af4c2c00c7776eSamuel Tan#endif  // __ANDROID__
32b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
33445883dc5780b026aa37644e15468993d768c3f7Peter Qiu#include "shill/dhcp/mock_dhcp_provider.h"
34b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu#include "shill/dhcp/mock_dhcp_proxy.h"
35b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu#include "shill/event_dispatcher.h"
36b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu#include "shill/mock_control.h"
37b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu#include "shill/mock_log.h"
38b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu#include "shill/mock_metrics.h"
398ee1c83abf0050cb808fe154babe934546e77821Peter Qiu#include "shill/mock_process_manager.h"
40b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu#include "shill/property_store_unittest.h"
41b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu#include "shill/testing.h"
42b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
43b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiuusing base::Bind;
44b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiuusing base::FilePath;
45b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiuusing base::ScopedTempDir;
46b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiuusing base::Unretained;
47b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiuusing std::string;
48b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiuusing std::unique_ptr;
49b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiuusing std::vector;
50b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiuusing testing::_;
51b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiuusing testing::AnyNumber;
52b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiuusing testing::ContainsRegex;
53b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiuusing testing::InvokeWithoutArgs;
54b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiuusing testing::Mock;
55b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiuusing testing::Return;
56b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiuusing testing::SetArgumentPointee;
57b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiuusing testing::Test;
58b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
59b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiunamespace shill {
60b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
61b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiunamespace {
62b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiuconst char kDeviceName[] = "eth0";
63b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiuconst char kLeaseFileSuffix[] = "leasefilesuffix";
64b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiuconst bool kHasLeaseSuffix = true;
65b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiuconst char kIPAddress[] = "2001:db8:0:1::1";
66b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiuconst char kDelegatedPrefix[] = "2001:db8:0:100::";
67b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu}  // namespace
68b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
69b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiutypedef scoped_refptr<DHCPv6Config> DHCPv6ConfigRefPtr;
70b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
71b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiuclass DHCPv6ConfigTest : public PropertyStoreTest {
72b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu public:
73b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  DHCPv6ConfigTest()
74b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu      : proxy_(new MockDHCPProxy()),
75b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu        config_(new DHCPv6Config(&control_,
76b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu                                 dispatcher(),
77445883dc5780b026aa37644e15468993d768c3f7Peter Qiu                                 &provider_,
78b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu                                 kDeviceName,
798ee1c83abf0050cb808fe154babe934546e77821Peter Qiu                                 kLeaseFileSuffix)) {}
80b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
81b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  virtual void SetUp() {
828ee1c83abf0050cb808fe154babe934546e77821Peter Qiu    config_->process_manager_ = &process_manager_;
83b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  }
84b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
85b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  bool StartInstance(DHCPv6ConfigRefPtr config) {
86b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu    return config->Start();
87b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  }
88b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
89b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  void StopInstance() {
90b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu    config_->Stop("In test");
91b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  }
92b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
930bfabaae654ba3bf597a303b7517a0e14fd65089Paul Stewart  DHCPv6ConfigRefPtr CreateMockMinijailConfig(const string& lease_suffix);
940bfabaae654ba3bf597a303b7517a0e14fd65089Paul Stewart  DHCPv6ConfigRefPtr CreateRunningConfig(const string& lease_suffix);
95b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  void StopRunningConfigAndExpect(DHCPv6ConfigRefPtr config,
96b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu                                  bool lease_file_exists);
97b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
98b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu protected:
99b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  static const int kPID;
100b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  static const unsigned int kTag;
101b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
102b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  FilePath lease_file_;
103b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  FilePath pid_file_;
104b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  ScopedTempDir temp_dir_;
105b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  unique_ptr<MockDHCPProxy> proxy_;
106b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  MockControl control_;
1078ee1c83abf0050cb808fe154babe934546e77821Peter Qiu  MockProcessManager process_manager_;
108445883dc5780b026aa37644e15468993d768c3f7Peter Qiu  MockDHCPProvider provider_;
109b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  DHCPv6ConfigRefPtr config_;
110b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu};
111b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
112b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiuconst int DHCPv6ConfigTest::kPID = 123456;
113b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiuconst unsigned int DHCPv6ConfigTest::kTag = 77;
114b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
115b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter QiuDHCPv6ConfigRefPtr DHCPv6ConfigTest::CreateMockMinijailConfig(
1160bfabaae654ba3bf597a303b7517a0e14fd65089Paul Stewart    const string& lease_suffix) {
117b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  DHCPv6ConfigRefPtr config(new DHCPv6Config(&control_,
118b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu                                             dispatcher(),
119445883dc5780b026aa37644e15468993d768c3f7Peter Qiu                                             &provider_,
120b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu                                             kDeviceName,
1218ee1c83abf0050cb808fe154babe934546e77821Peter Qiu                                             lease_suffix));
1228ee1c83abf0050cb808fe154babe934546e77821Peter Qiu  config->process_manager_ = &process_manager_;
123b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
124b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  return config;
125b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu}
126b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
127b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter QiuDHCPv6ConfigRefPtr DHCPv6ConfigTest::CreateRunningConfig(
1280bfabaae654ba3bf597a303b7517a0e14fd65089Paul Stewart    const string& lease_suffix) {
129b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  DHCPv6ConfigRefPtr config(new DHCPv6Config(&control_,
130b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu                                             dispatcher(),
131445883dc5780b026aa37644e15468993d768c3f7Peter Qiu                                             &provider_,
132b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu                                             kDeviceName,
1338ee1c83abf0050cb808fe154babe934546e77821Peter Qiu                                             lease_suffix));
1348ee1c83abf0050cb808fe154babe934546e77821Peter Qiu  config->process_manager_ = &process_manager_;
1358ee1c83abf0050cb808fe154babe934546e77821Peter Qiu  EXPECT_CALL(process_manager_, StartProcessInMinijail(_, _, _, _, _, _, _))
1368ee1c83abf0050cb808fe154babe934546e77821Peter Qiu      .WillOnce(Return(kPID));
137445883dc5780b026aa37644e15468993d768c3f7Peter Qiu  EXPECT_CALL(provider_, BindPID(kPID, IsRefPtrTo(config)));
138b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  EXPECT_TRUE(config->Start());
139b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  EXPECT_EQ(kPID, config->pid_);
140b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
141b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
142b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  config->root_ = temp_dir_.path();
143b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  FilePath varrun = temp_dir_.path().Append("var/run/dhcpcd");
144b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  EXPECT_TRUE(base::CreateDirectory(varrun));
145b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  pid_file_ = varrun.Append(base::StringPrintf("dhcpcd-%s-6.pid", kDeviceName));
146b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  FilePath varlib = temp_dir_.path().Append("var/lib/dhcpcd");
147b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  EXPECT_TRUE(base::CreateDirectory(varlib));
148b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  lease_file_ =
149b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu      varlib.Append(base::StringPrintf("dhcpcd-%s.lease6", kDeviceName));
150b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  EXPECT_EQ(0, base::WriteFile(pid_file_, "", 0));
151b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  EXPECT_EQ(0, base::WriteFile(lease_file_, "", 0));
152b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  EXPECT_TRUE(base::PathExists(pid_file_));
153b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  EXPECT_TRUE(base::PathExists(lease_file_));
154b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
155b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  return config;
156b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu}
157b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
158b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiuvoid DHCPv6ConfigTest::StopRunningConfigAndExpect(DHCPv6ConfigRefPtr config,
159b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu                                                  bool lease_file_exists) {
160b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  ScopedMockLog log;
161b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  // We use a non-zero exit status so that we get the log message.
162b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  EXPECT_CALL(log, Log(_, _, ::testing::EndsWith("status 10")));
163445883dc5780b026aa37644e15468993d768c3f7Peter Qiu  EXPECT_CALL(provider_, UnbindPID(kPID));
1648ee1c83abf0050cb808fe154babe934546e77821Peter Qiu  config->OnProcessExited(10);
165b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
166b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  EXPECT_FALSE(base::PathExists(pid_file_));
167b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  EXPECT_EQ(lease_file_exists, base::PathExists(lease_file_));
168b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu}
169b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
170b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter QiuTEST_F(DHCPv6ConfigTest, ParseConfiguration) {
171b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  const char kConfigIPAddress[] = "2001:db8:0:1::129";
172b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  const char kConfigDelegatedPrefix[] = "2001:db8:1:100::";
173b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  const char kConfigNameServer[] = "fec8:0::1";
174b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  const char kConfigDomainSearch[] = "example.domain";
175b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  const uint32_t kConfigDelegatedPrefixLength = 56;
176b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  const uint32_t kConfigIPAddressLeaseTime = 5;
177b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  const uint32_t kConfigDelegatedPrefixLeaseTime = 10;
178b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
1797adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu  KeyValueStore conf;
1807adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu  conf.SetString(DHCPv6Config::kConfigurationKeyIPAddress, kConfigIPAddress);
1817adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu  conf.SetUint(DHCPv6Config::kConfigurationKeyIPAddressLeaseTime,
1827adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu               kConfigIPAddressLeaseTime);
1837adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu  conf.SetString(DHCPv6Config::kConfigurationKeyDelegatedPrefix,
1847adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu                 kConfigDelegatedPrefix);
1857adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu  conf.SetUint(DHCPv6Config::kConfigurationKeyDelegatedPrefixLength,
1867adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu               kConfigDelegatedPrefixLength);
1877adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu  conf.SetUint(DHCPv6Config::kConfigurationKeyDelegatedPrefixLeaseTime,
1887adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu               kConfigDelegatedPrefixLeaseTime);
189b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  {
190b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu    vector<string> dns;
191b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu    dns.push_back(kConfigNameServer);
1927adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu    conf.SetStrings(DHCPv6Config::kConfigurationKeyDNS, dns);
193b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  }
194b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  {
195b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu    vector<string> domain_search;
196b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu    domain_search.push_back(kConfigDomainSearch);
1977adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu    conf.SetStrings(DHCPv6Config::kConfigurationKeyDomainSearch, domain_search);
198b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  }
1997adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu  conf.SetString("UnknownKey", "UnknownValue");
200b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
201b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  ASSERT_TRUE(config_->ParseConfiguration(conf));
202b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  EXPECT_EQ(kConfigIPAddress, config_->properties_.address);
203b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  EXPECT_EQ(kConfigDelegatedPrefix, config_->properties_.delegated_prefix);
204b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  EXPECT_EQ(kConfigDelegatedPrefixLength,
205b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu            config_->properties_.delegated_prefix_length);
206b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  ASSERT_EQ(1, config_->properties_.dns_servers.size());
207b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  EXPECT_EQ(kConfigNameServer, config_->properties_.dns_servers[0]);
208b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  ASSERT_EQ(1, config_->properties_.domain_search.size());
209b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  EXPECT_EQ(kConfigDomainSearch, config_->properties_.domain_search[0]);
210b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  // Use IP address lease time since it is shorter.
211b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  EXPECT_EQ(kConfigIPAddressLeaseTime,
212b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu            config_->properties_.lease_duration_seconds);
213b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu}
214b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
215b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter QiuMATCHER_P(IsDHCPCDv6Args, has_lease_suffix, "") {
2168ee1c83abf0050cb808fe154babe934546e77821Peter Qiu  if (arg[0] != "-B" ||
2178ee1c83abf0050cb808fe154babe934546e77821Peter Qiu      arg[1] != "-q" ||
2188ee1c83abf0050cb808fe154babe934546e77821Peter Qiu      arg[2] != "-6" ||
219722af37a847fd5f1c51800a7f588dec685ec78e6Timothy Jennison      arg[3] != "-a") {
220b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu    return false;
221b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  }
222b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
223722af37a847fd5f1c51800a7f588dec685ec78e6Timothy Jennison  int end_offset = 4;
224b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
225b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  string device_arg = has_lease_suffix ?
226b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu      string(kDeviceName) + "=" + string(kLeaseFileSuffix) : kDeviceName;
2278ee1c83abf0050cb808fe154babe934546e77821Peter Qiu  return arg[end_offset] == device_arg;
228b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu}
229b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
230b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter QiuTEST_F(DHCPv6ConfigTest, StartDhcpcd) {
2318ee1c83abf0050cb808fe154babe934546e77821Peter Qiu  EXPECT_CALL(process_manager_,
2328ee1c83abf0050cb808fe154babe934546e77821Peter Qiu              StartProcessInMinijail(_, _, IsDHCPCDv6Args(kHasLeaseSuffix),
2338ee1c83abf0050cb808fe154babe934546e77821Peter Qiu                                     _, _, _, _))
2348ee1c83abf0050cb808fe154babe934546e77821Peter Qiu      .WillOnce(Return(-1));
235b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  EXPECT_FALSE(StartInstance(config_));
236b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu}
237b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
238b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
239b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiunamespace {
240b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
241b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiuclass DHCPv6ConfigCallbackTest : public DHCPv6ConfigTest {
242b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu public:
243b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  virtual void SetUp() {
244b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu    DHCPv6ConfigTest::SetUp();
245b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu    config_->RegisterUpdateCallback(
246b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu        Bind(&DHCPv6ConfigCallbackTest::SuccessCallback, Unretained(this)));
247b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu    config_->RegisterFailureCallback(
248b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu        Bind(&DHCPv6ConfigCallbackTest::FailureCallback, Unretained(this)));
249b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu    ip_config_ = config_;
250b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  }
251b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
252b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  MOCK_METHOD2(SuccessCallback,
2530bfabaae654ba3bf597a303b7517a0e14fd65089Paul Stewart               void(const IPConfigRefPtr& ipconfig, bool new_lease_acquired));
2540bfabaae654ba3bf597a303b7517a0e14fd65089Paul Stewart  MOCK_METHOD1(FailureCallback, void(const IPConfigRefPtr& ipconfig));
255b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
256b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  // The mock methods above take IPConfigRefPtr because this is the type
257b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  // that the registered callbacks take.  This conversion of the DHCP
258b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  // config ref pointer eases our work in setting up expectations.
2590bfabaae654ba3bf597a303b7517a0e14fd65089Paul Stewart  const IPConfigRefPtr& ConfigRef() { return ip_config_; }
260b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
261b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu private:
262b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  IPConfigRefPtr ip_config_;
263b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu};
264b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
265b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu}  // namespace
266b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
267b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter QiuTEST_F(DHCPv6ConfigCallbackTest, ProcessEventSignalFail) {
2687adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu  KeyValueStore conf;
2697adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu  conf.SetString(DHCPv6Config::kConfigurationKeyIPAddress, kIPAddress);
2707adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu  conf.SetString(DHCPv6Config::kConfigurationKeyDelegatedPrefix,
2717adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu                 kDelegatedPrefix);
272b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  EXPECT_CALL(*this, SuccessCallback(_, _)).Times(0);
273b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  EXPECT_CALL(*this, FailureCallback(ConfigRef()));
274b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  config_->ProcessEventSignal(DHCPv6Config::kReasonFail, conf);
275b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  Mock::VerifyAndClearExpectations(this);
276b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  EXPECT_TRUE(config_->properties().address.empty());
277b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu}
278b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
279b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter QiuTEST_F(DHCPv6ConfigCallbackTest, ProcessEventSignalSuccess) {
2800bfabaae654ba3bf597a303b7517a0e14fd65089Paul Stewart  for (const auto& reason : { DHCPv6Config::kReasonBound,
281b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu                              DHCPv6Config::kReasonRebind,
282b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu                              DHCPv6Config::kReasonReboot,
283b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu                              DHCPv6Config::kReasonRenew }) {
284b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu    for (const auto lease_time_given : { false, true }) {
2857adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu      KeyValueStore conf;
2867adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu      conf.SetString(DHCPv6Config::kConfigurationKeyIPAddress, kIPAddress);
2877adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu      conf.SetString(DHCPv6Config::kConfigurationKeyDelegatedPrefix,
2887adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu                     kDelegatedPrefix);
289b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu      if (lease_time_given) {
290b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu        const uint32_t kLeaseTime = 1;
2917adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu        conf.SetUint(DHCPv6Config::kConfigurationKeyIPAddressLeaseTime,
2927adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu                     kLeaseTime);
293b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu      }
294b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu      EXPECT_CALL(*this, SuccessCallback(ConfigRef(), true));
295b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu      EXPECT_CALL(*this, FailureCallback(_)).Times(0);
296b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu      config_->ProcessEventSignal(reason, conf);
297b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu      string failure_message = string(reason) + " failed with lease time " +
298b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu          (lease_time_given ? "given" : "not given");
299b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu      EXPECT_TRUE(Mock::VerifyAndClearExpectations(this)) << failure_message;
300b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu      EXPECT_EQ("2001:db8:0:1::1", config_->properties().address)
301b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu          << failure_message;
302b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu    }
303b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  }
304b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu}
305b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
306b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter QiuTEST_F(DHCPv6ConfigCallbackTest, StoppedDuringFailureCallback) {
3077adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu  KeyValueStore conf;
3087adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu  conf.SetString(DHCPv6Config::kConfigurationKeyIPAddress, kIPAddress);
3097adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu  conf.SetString(DHCPv6Config::kConfigurationKeyDelegatedPrefix,
3107adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu                 kDelegatedPrefix);
311b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  // Stop the DHCP config while it is calling the failure callback.  We
312b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  // need to ensure that no callbacks are left running inadvertently as
313b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  // a result.
314b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  EXPECT_CALL(*this, FailureCallback(ConfigRef()))
315b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu      .WillOnce(InvokeWithoutArgs(this, &DHCPv6ConfigTest::StopInstance));
316b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  config_->ProcessEventSignal(DHCPv6Config::kReasonFail, conf);
317b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  EXPECT_TRUE(Mock::VerifyAndClearExpectations(this));
318b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu}
319b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
320b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter QiuTEST_F(DHCPv6ConfigCallbackTest, StoppedDuringSuccessCallback) {
3217adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu  KeyValueStore conf;
3227adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu  conf.SetString(DHCPv6Config::kConfigurationKeyIPAddress, kIPAddress);
3237adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu  conf.SetString(DHCPv6Config::kConfigurationKeyDelegatedPrefix,
3247adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu                 kDelegatedPrefix);
325b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  const uint32_t kLeaseTime = 1;
3267adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu  conf.SetUint(DHCPv6Config::kConfigurationKeyIPAddressLeaseTime, kLeaseTime);
327b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  // Stop the DHCP config while it is calling the success callback.  This
328b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  // can happen if the device has a static IP configuration and releases
329b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  // the lease after accepting other network parameters from the DHCP
330b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  // IPConfig properties.  We need to ensure that no callbacks are left
331b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  // running inadvertently as a result.
332b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  EXPECT_CALL(*this, SuccessCallback(ConfigRef(), true))
333b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu      .WillOnce(InvokeWithoutArgs(this, &DHCPv6ConfigTest::StopInstance));
334b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  config_->ProcessEventSignal(DHCPv6Config::kReasonBound, conf);
335b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  EXPECT_TRUE(Mock::VerifyAndClearExpectations(this));
336b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu}
337b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
338b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter QiuTEST_F(DHCPv6ConfigCallbackTest, ProcessEventSignalUnknown) {
3397adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu  KeyValueStore conf;
3407adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu  conf.SetString(DHCPv6Config::kConfigurationKeyIPAddress, kIPAddress);
3417adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu  conf.SetString(DHCPv6Config::kConfigurationKeyDelegatedPrefix,
3427adad988e41954c134cbb4e5ab8a1a152e1e3c78Peter Qiu                 kDelegatedPrefix);
343b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  static const char kReasonUnknown[] = "UNKNOWN_REASON";
344b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  EXPECT_CALL(*this, SuccessCallback(_, _)).Times(0);
345b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  EXPECT_CALL(*this, FailureCallback(_)).Times(0);
346b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  config_->ProcessEventSignal(kReasonUnknown, conf);
347b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  Mock::VerifyAndClearExpectations(this);
348b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  EXPECT_TRUE(config_->properties().address.empty());
349b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu}
350b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
351b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter QiuTEST_F(DHCPv6ConfigTest, StartSuccessEphemeral) {
352b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  DHCPv6ConfigRefPtr config =
353b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu      CreateRunningConfig(kDeviceName);
354b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  StopRunningConfigAndExpect(config, false);
355b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu}
356b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
357b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter QiuTEST_F(DHCPv6ConfigTest, StartSuccessPersistent) {
358b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  DHCPv6ConfigRefPtr config =
359b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu      CreateRunningConfig(kLeaseFileSuffix);
360b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu  StopRunningConfigAndExpect(config, true);
361b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu}
362b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu
363b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu}  // namespace shill
364