1c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
2c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Copyright (C) 2011 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//
16e02b3ca77f62f38bb5c72c826dffa185a7b71d82Darin Petkov
1719e30406a1d3123892007d20438527dc4b2f92c3Chris Masone#include "shill/ipconfig.h"
1819e30406a1d3123892007d20438527dc4b2f92c3Chris Masone
19815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan#include <sys/time.h>
20815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan
213e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbrood#include <base/bind.h>
22289a5a5e18bb1a676b3dfce111af4c2c00c7776eSamuel Tan#if defined(__ANDROID__)
23289a5a5e18bb1a676b3dfce111af4c2c00c7776eSamuel Tan#include <dbus/service_constants.h>
24289a5a5e18bb1a676b3dfce111af4c2c00c7776eSamuel Tan#else
257aed61cab2dc17f3c7f8c4a2a6d8d72ae1b7629dmukesh agrawal#include <chromeos/dbus/service_constants.h>
26289a5a5e18bb1a676b3dfce111af4c2c00c7776eSamuel Tan#endif  // __ANDROID__
277aed61cab2dc17f3c7f8c4a2a6d8d72ae1b7629dmukesh agrawal#include <gmock/gmock.h>
28f65e928d8cd59338cec95a7daa6957f6c510fd2eDarin Petkov#include <gtest/gtest.h>
29efb09c3b167e7d3f1d78d6f2ba4d3dc6e1063bafDarin Petkov
30815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan#include "shill/logging.h"
317aed61cab2dc17f3c7f8c4a2a6d8d72ae1b7629dmukesh agrawal#include "shill/mock_adaptors.h"
3219e30406a1d3123892007d20438527dc4b2f92c3Chris Masone#include "shill/mock_control.h"
33815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan#include "shill/mock_log.h"
348a7b8be27dd4570b182fb7ea1b4c5c9f107f3f8bChris Masone#include "shill/mock_store.h"
358d6b59704591ba9fad57751858835dc332dbdd37Peter Qiu#include "shill/net/mock_time.h"
367aed61cab2dc17f3c7f8c4a2a6d8d72ae1b7629dmukesh agrawal#include "shill/static_ip_parameters.h"
37e02b3ca77f62f38bb5c72c826dffa185a7b71d82Darin Petkov
383e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbroodusing base::Bind;
393e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbroodusing base::Unretained;
408a7b8be27dd4570b182fb7ea1b4c5c9f107f3f8bChris Masoneusing std::string;
418a7b8be27dd4570b182fb7ea1b4c5c9f107f3f8bChris Masoneusing testing::_;
42815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tanusing testing::EndsWith;
43815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tanusing testing::DoAll;
447aed61cab2dc17f3c7f8c4a2a6d8d72ae1b7629dmukesh agrawalusing testing::Mock;
458a7b8be27dd4570b182fb7ea1b4c5c9f107f3f8bChris Masoneusing testing::Return;
468a7b8be27dd4570b182fb7ea1b4c5c9f107f3f8bChris Masoneusing testing::SaveArg;
47815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tanusing testing::SetArgPointee;
488a7b8be27dd4570b182fb7ea1b4c5c9f107f3f8bChris Masoneusing testing::SetArgumentPointee;
498a7b8be27dd4570b182fb7ea1b4c5c9f107f3f8bChris Masoneusing testing::StrictMock;
50efb09c3b167e7d3f1d78d6f2ba4d3dc6e1063bafDarin Petkovusing testing::Test;
51efb09c3b167e7d3f1d78d6f2ba4d3dc6e1063bafDarin Petkov
52e02b3ca77f62f38bb5c72c826dffa185a7b71d82Darin Petkovnamespace shill {
53e02b3ca77f62f38bb5c72c826dffa185a7b71d82Darin Petkov
54f65e928d8cd59338cec95a7daa6957f6c510fd2eDarin Petkovnamespace {
55f65e928d8cd59338cec95a7daa6957f6c510fd2eDarin Petkovconst char kDeviceName[] = "testdevice";
56815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tanconst uint32_t kTimeNow = 10;
578a5322984f2d81bcbfd8d44c59747a11bd9b904bAlex Vakulenko}  // namespace
58f65e928d8cd59338cec95a7daa6957f6c510fd2eDarin Petkov
59e02b3ca77f62f38bb5c72c826dffa185a7b71d82Darin Petkovclass IPConfigTest : public Test {
60e02b3ca77f62f38bb5c72c826dffa185a7b71d82Darin Petkov public:
61815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  IPConfigTest() : ipconfig_(new IPConfig(&control_, kDeviceName)) {
62815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan    ipconfig_->time_ = &time_;
63815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  }
6435ed908a15b7e1df603e7ba847b45b0a54e5712cPaul Stewart
6535ed908a15b7e1df603e7ba847b45b0a54e5712cPaul Stewart  virtual void SetUp() {
6635ed908a15b7e1df603e7ba847b45b0a54e5712cPaul Stewart    ScopeLogger::GetInstance()->EnableScopesByName("inet");
6735ed908a15b7e1df603e7ba847b45b0a54e5712cPaul Stewart    ScopeLogger::GetInstance()->set_verbose_level(3);
6835ed908a15b7e1df603e7ba847b45b0a54e5712cPaul Stewart  }
6935ed908a15b7e1df603e7ba847b45b0a54e5712cPaul Stewart
7035ed908a15b7e1df603e7ba847b45b0a54e5712cPaul Stewart  virtual void TearDown() {
7135ed908a15b7e1df603e7ba847b45b0a54e5712cPaul Stewart    ScopeLogger::GetInstance()->EnableScopesByName("-inet");
7235ed908a15b7e1df603e7ba847b45b0a54e5712cPaul Stewart    ScopeLogger::GetInstance()->set_verbose_level(0);
7335ed908a15b7e1df603e7ba847b45b0a54e5712cPaul Stewart  }
7435ed908a15b7e1df603e7ba847b45b0a54e5712cPaul Stewart
753c3c36a37a885d0a2e180998587af8390744f757Samuel Tan  void DropRef(const IPConfigRefPtr & /*ipconfig*/,
763c3c36a37a885d0a2e180998587af8390744f757Samuel Tan               bool /*new_lease_acquired*/) {
77cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan    ipconfig_ = nullptr;
781c1dd351729e4d60ab24fdbfaf4fc439f14876c2mukesh agrawal  }
79e02b3ca77f62f38bb5c72c826dffa185a7b71d82Darin Petkov
803c3c36a37a885d0a2e180998587af8390744f757Samuel Tan  MOCK_METHOD2(OnIPConfigUpdated,
813b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart               void(const IPConfigRefPtr& ipconfig, bool new_lease_acquired));
823b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  MOCK_METHOD1(OnIPConfigFailed, void(const IPConfigRefPtr& ipconfig));
833b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  MOCK_METHOD1(OnIPConfigRefreshed, void(const IPConfigRefPtr& ipconfig));
843b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  MOCK_METHOD1(OnIPConfigExpired, void(const IPConfigRefPtr& ipconfig));
85c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart
86e02b3ca77f62f38bb5c72c826dffa185a7b71d82Darin Petkov protected:
873b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  IPConfigMockAdaptor* GetAdaptor() {
88fa1eb722d0742d89c26b9c5c81d02ef2a138cbf2Alex Vakulenko    return static_cast<IPConfigMockAdaptor*>(ipconfig_->adaptor_.get());
897aed61cab2dc17f3c7f8c4a2a6d8d72ae1b7629dmukesh agrawal  }
907aed61cab2dc17f3c7f8c4a2a6d8d72ae1b7629dmukesh agrawal
913b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  void UpdateProperties(const IPConfig::Properties& properties) {
923c3c36a37a885d0a2e180998587af8390744f757Samuel Tan    ipconfig_->UpdateProperties(properties, true);
93c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  }
94c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart
95c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  void NotifyFailure() {
96c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart    ipconfig_->NotifyFailure();
97c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  }
98c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart
991f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart  void NotifyExpiry() {
1001f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart    ipconfig_->NotifyExpiry();
1011f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart  }
1021f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart
1033b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  void ExpectPropertiesEqual(const IPConfig::Properties& properties) {
104c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart    EXPECT_EQ(properties.address, ipconfig_->properties().address);
105c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart    EXPECT_EQ(properties.subnet_prefix, ipconfig_->properties().subnet_prefix);
106c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart    EXPECT_EQ(properties.broadcast_address,
107c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart              ipconfig_->properties().broadcast_address);
108c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart    EXPECT_EQ(properties.dns_servers.size(),
109c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart              ipconfig_->properties().dns_servers.size());
110c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart    if (properties.dns_servers.size() ==
111c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart        ipconfig_->properties().dns_servers.size()) {
112c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart      for (size_t i = 0; i < properties.dns_servers.size(); ++i) {
113c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart        EXPECT_EQ(properties.dns_servers[i],
114c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart                  ipconfig_->properties().dns_servers[i]);
115c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart      }
116c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart    }
117c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart    EXPECT_EQ(properties.domain_search.size(),
118c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart              ipconfig_->properties().domain_search.size());
119c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart    if (properties.domain_search.size() ==
120c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart        ipconfig_->properties().domain_search.size()) {
121c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart      for (size_t i = 0; i < properties.domain_search.size(); ++i) {
122c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart        EXPECT_EQ(properties.domain_search[i],
123c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart                  ipconfig_->properties().domain_search[i]);
124c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart      }
125c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart    }
126c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart    EXPECT_EQ(properties.gateway, ipconfig_->properties().gateway);
127c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart    EXPECT_EQ(properties.blackhole_ipv6,
128c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart              ipconfig_->properties().blackhole_ipv6);
129c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart    EXPECT_EQ(properties.mtu, ipconfig_->properties().mtu);
1307aed61cab2dc17f3c7f8c4a2a6d8d72ae1b7629dmukesh agrawal  }
1317aed61cab2dc17f3c7f8c4a2a6d8d72ae1b7629dmukesh agrawal
13219e30406a1d3123892007d20438527dc4b2f92c3Chris Masone  MockControl control_;
133815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  MockTime time_;
134efb09c3b167e7d3f1d78d6f2ba4d3dc6e1063bafDarin Petkov  IPConfigRefPtr ipconfig_;
135efb09c3b167e7d3f1d78d6f2ba4d3dc6e1063bafDarin Petkov};
136efb09c3b167e7d3f1d78d6f2ba4d3dc6e1063bafDarin Petkov
137f65e928d8cd59338cec95a7daa6957f6c510fd2eDarin PetkovTEST_F(IPConfigTest, DeviceName) {
138f65e928d8cd59338cec95a7daa6957f6c510fd2eDarin Petkov  EXPECT_EQ(kDeviceName, ipconfig_->device_name());
139efb09c3b167e7d3f1d78d6f2ba4d3dc6e1063bafDarin Petkov}
140efb09c3b167e7d3f1d78d6f2ba4d3dc6e1063bafDarin Petkov
14192c4390285270320f6145c8295de0abdcc315380Darin PetkovTEST_F(IPConfigTest, RequestIP) {
14292c4390285270320f6145c8295de0abdcc315380Darin Petkov  EXPECT_FALSE(ipconfig_->RequestIP());
143efb09c3b167e7d3f1d78d6f2ba4d3dc6e1063bafDarin Petkov}
144efb09c3b167e7d3f1d78d6f2ba4d3dc6e1063bafDarin Petkov
14592c4390285270320f6145c8295de0abdcc315380Darin PetkovTEST_F(IPConfigTest, RenewIP) {
14692c4390285270320f6145c8295de0abdcc315380Darin Petkov  EXPECT_FALSE(ipconfig_->RenewIP());
14792c4390285270320f6145c8295de0abdcc315380Darin Petkov}
14892c4390285270320f6145c8295de0abdcc315380Darin Petkov
14992c4390285270320f6145c8295de0abdcc315380Darin PetkovTEST_F(IPConfigTest, ReleaseIP) {
150217c61dfafa2ddc800daa227d032d84daf668382Paul Stewart  EXPECT_FALSE(ipconfig_->ReleaseIP(IPConfig::kReleaseReasonDisconnect));
151efb09c3b167e7d3f1d78d6f2ba4d3dc6e1063bafDarin Petkov}
152efb09c3b167e7d3f1d78d6f2ba4d3dc6e1063bafDarin Petkov
153efb09c3b167e7d3f1d78d6f2ba4d3dc6e1063bafDarin PetkovTEST_F(IPConfigTest, UpdateProperties) {
154efb09c3b167e7d3f1d78d6f2ba4d3dc6e1063bafDarin Petkov  IPConfig::Properties properties;
155efb09c3b167e7d3f1d78d6f2ba4d3dc6e1063bafDarin Petkov  properties.address = "1.2.3.4";
15648100b0f484fb59d5f34eb4565375759202295e1Paul Stewart  properties.subnet_prefix = 24;
157efb09c3b167e7d3f1d78d6f2ba4d3dc6e1063bafDarin Petkov  properties.broadcast_address = "11.22.33.44";
158efb09c3b167e7d3f1d78d6f2ba4d3dc6e1063bafDarin Petkov  properties.dns_servers.push_back("10.20.30.40");
159efb09c3b167e7d3f1d78d6f2ba4d3dc6e1063bafDarin Petkov  properties.dns_servers.push_back("20.30.40.50");
160efb09c3b167e7d3f1d78d6f2ba4d3dc6e1063bafDarin Petkov  properties.domain_name = "foo.org";
161efb09c3b167e7d3f1d78d6f2ba4d3dc6e1063bafDarin Petkov  properties.domain_search.push_back("zoo.org");
162efb09c3b167e7d3f1d78d6f2ba4d3dc6e1063bafDarin Petkov  properties.domain_search.push_back("zoo.com");
163c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  properties.gateway = "5.6.7.8";
164a016312b7470e124774aec197e3b43bc795637c3Ben Chan  properties.blackhole_ipv6 = true;
165efb09c3b167e7d3f1d78d6f2ba4d3dc6e1063bafDarin Petkov  properties.mtu = 700;
166c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  UpdateProperties(properties);
167c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  ExpectPropertiesEqual(properties);
168e02b3ca77f62f38bb5c72c826dffa185a7b71d82Darin Petkov
169c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  // We should not reset on NotifyFailure.
170c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  NotifyFailure();
171c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  ExpectPropertiesEqual(properties);
172f9b0ca8ba854fe017f6315b5d037aa7b6dfd7827Darin Petkov
1731f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart  // We should not reset on NotifyExpiry.
1741f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart  NotifyExpiry();
1751f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart  ExpectPropertiesEqual(properties);
1761f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart
177c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  // We should reset if ResetProperties is called.
178c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  ipconfig_->ResetProperties();
179c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  ExpectPropertiesEqual(IPConfig::Properties());
180e02b3ca77f62f38bb5c72c826dffa185a7b71d82Darin Petkov}
181e02b3ca77f62f38bb5c72c826dffa185a7b71d82Darin Petkov
182c5099532b82fe201fe2510c43b529944a0930d2ePaul StewartTEST_F(IPConfigTest, Callbacks) {
183c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  ipconfig_->RegisterUpdateCallback(
184c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart      Bind(&IPConfigTest::OnIPConfigUpdated, Unretained(this)));
185c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  ipconfig_->RegisterFailureCallback(
186c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart      Bind(&IPConfigTest::OnIPConfigFailed, Unretained(this)));
1878223653e57318b02c40d018b47ea32f062734abdPaul Stewart  ipconfig_->RegisterRefreshCallback(
188c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart      Bind(&IPConfigTest::OnIPConfigRefreshed, Unretained(this)));
1891f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart  ipconfig_->RegisterExpireCallback(
1901f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart      Bind(&IPConfigTest::OnIPConfigExpired, Unretained(this)));
191c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart
1923c3c36a37a885d0a2e180998587af8390744f757Samuel Tan  EXPECT_CALL(*this, OnIPConfigUpdated(ipconfig_, true));
193c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  EXPECT_CALL(*this, OnIPConfigFailed(ipconfig_)).Times(0);
194c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  EXPECT_CALL(*this, OnIPConfigRefreshed(ipconfig_)).Times(0);
1951f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart  EXPECT_CALL(*this, OnIPConfigExpired(ipconfig_)).Times(0);
196c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  UpdateProperties(IPConfig::Properties());
197c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  Mock::VerifyAndClearExpectations(this);
198c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart
1993c3c36a37a885d0a2e180998587af8390744f757Samuel Tan  EXPECT_CALL(*this, OnIPConfigUpdated(ipconfig_, true)).Times(0);
200c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  EXPECT_CALL(*this, OnIPConfigFailed(ipconfig_));
201c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  EXPECT_CALL(*this, OnIPConfigRefreshed(ipconfig_)).Times(0);
2021f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart  EXPECT_CALL(*this, OnIPConfigExpired(ipconfig_)).Times(0);
203c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  NotifyFailure();
204c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  Mock::VerifyAndClearExpectations(this);
205c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart
2063c3c36a37a885d0a2e180998587af8390744f757Samuel Tan  EXPECT_CALL(*this, OnIPConfigUpdated(ipconfig_, true)).Times(0);
207c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  EXPECT_CALL(*this, OnIPConfigFailed(ipconfig_)).Times(0);
208c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  EXPECT_CALL(*this, OnIPConfigRefreshed(ipconfig_));
2091f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart  EXPECT_CALL(*this, OnIPConfigExpired(ipconfig_)).Times(0);
210cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan  ipconfig_->Refresh(nullptr);
211c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  Mock::VerifyAndClearExpectations(this);
2121f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart
2133c3c36a37a885d0a2e180998587af8390744f757Samuel Tan  EXPECT_CALL(*this, OnIPConfigUpdated(ipconfig_, true)).Times(0);
2141f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart  EXPECT_CALL(*this, OnIPConfigFailed(ipconfig_)).Times(0);
2151f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart  EXPECT_CALL(*this, OnIPConfigRefreshed(ipconfig_)).Times(0);
2161f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart  EXPECT_CALL(*this, OnIPConfigExpired(ipconfig_));
2171f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart  NotifyExpiry();
2181f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart  Mock::VerifyAndClearExpectations(this);
2198223653e57318b02c40d018b47ea32f062734abdPaul Stewart}
2208223653e57318b02c40d018b47ea32f062734abdPaul Stewart
2211c1dd351729e4d60ab24fdbfaf4fc439f14876c2mukesh agrawalTEST_F(IPConfigTest, UpdatePropertiesWithDropRef) {
2221c1dd351729e4d60ab24fdbfaf4fc439f14876c2mukesh agrawal  // The UpdateCallback should be able to drop a reference to the
2231c1dd351729e4d60ab24fdbfaf4fc439f14876c2mukesh agrawal  // IPConfig object without crashing.
2241c1dd351729e4d60ab24fdbfaf4fc439f14876c2mukesh agrawal  ipconfig_->RegisterUpdateCallback(
2251c1dd351729e4d60ab24fdbfaf4fc439f14876c2mukesh agrawal      Bind(&IPConfigTest::DropRef, Unretained(this)));
226c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  UpdateProperties(IPConfig::Properties());
2271c1dd351729e4d60ab24fdbfaf4fc439f14876c2mukesh agrawal}
2281c1dd351729e4d60ab24fdbfaf4fc439f14876c2mukesh agrawal
2297aed61cab2dc17f3c7f8c4a2a6d8d72ae1b7629dmukesh agrawalTEST_F(IPConfigTest, PropertyChanges) {
2303b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  IPConfigMockAdaptor* adaptor = GetAdaptor();
2317aed61cab2dc17f3c7f8c4a2a6d8d72ae1b7629dmukesh agrawal
2327aed61cab2dc17f3c7f8c4a2a6d8d72ae1b7629dmukesh agrawal  StaticIPParameters static_ip_params;
2330295e0f1437aa1f1488f4ae6d0f2fdde1f315397Ben Chan  EXPECT_CALL(*adaptor, EmitStringChanged(kAddressProperty, _));
2340295e0f1437aa1f1488f4ae6d0f2fdde1f315397Ben Chan  EXPECT_CALL(*adaptor, EmitStringsChanged(kNameServersProperty, _));
2357aed61cab2dc17f3c7f8c4a2a6d8d72ae1b7629dmukesh agrawal  ipconfig_->ApplyStaticIPParameters(&static_ip_params);
2367aed61cab2dc17f3c7f8c4a2a6d8d72ae1b7629dmukesh agrawal  Mock::VerifyAndClearExpectations(adaptor);
2377aed61cab2dc17f3c7f8c4a2a6d8d72ae1b7629dmukesh agrawal
2388223653e57318b02c40d018b47ea32f062734abdPaul Stewart  EXPECT_CALL(*adaptor, EmitStringChanged(kAddressProperty, _));
2398223653e57318b02c40d018b47ea32f062734abdPaul Stewart  EXPECT_CALL(*adaptor, EmitStringsChanged(kNameServersProperty, _));
2408223653e57318b02c40d018b47ea32f062734abdPaul Stewart  ipconfig_->RestoreSavedIPParameters(&static_ip_params);
2418223653e57318b02c40d018b47ea32f062734abdPaul Stewart  Mock::VerifyAndClearExpectations(adaptor);
2428223653e57318b02c40d018b47ea32f062734abdPaul Stewart
2437aed61cab2dc17f3c7f8c4a2a6d8d72ae1b7629dmukesh agrawal  IPConfig::Properties ip_properties;
2440295e0f1437aa1f1488f4ae6d0f2fdde1f315397Ben Chan  EXPECT_CALL(*adaptor, EmitStringChanged(kAddressProperty, _));
2450295e0f1437aa1f1488f4ae6d0f2fdde1f315397Ben Chan  EXPECT_CALL(*adaptor, EmitStringsChanged(kNameServersProperty, _));
246c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  UpdateProperties(ip_properties);
247c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  Mock::VerifyAndClearExpectations(adaptor);
248c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart
249c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  // It is the callback's responsibility for resetting the IPConfig
250c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  // properties (via IPConfig::ResetProperties()).  Since NotifyFailure
251c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  // by itself doesn't change any properties, it should not emit any
252c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  // property change events either.
253c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  EXPECT_CALL(*adaptor, EmitStringChanged(_, _)).Times(0);
254c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  EXPECT_CALL(*adaptor, EmitStringsChanged(_, _)).Times(0);
255c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  NotifyFailure();
2567aed61cab2dc17f3c7f8c4a2a6d8d72ae1b7629dmukesh agrawal  Mock::VerifyAndClearExpectations(adaptor);
2577aed61cab2dc17f3c7f8c4a2a6d8d72ae1b7629dmukesh agrawal
2581f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart  // Similarly, NotifyExpiry() should have no property change side effects.
2591f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart  EXPECT_CALL(*adaptor, EmitStringChanged(_, _)).Times(0);
2601f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart  EXPECT_CALL(*adaptor, EmitStringsChanged(_, _)).Times(0);
2611f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart  NotifyExpiry();
2621f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart  Mock::VerifyAndClearExpectations(adaptor);
2631f916e4adae8f937b9023e74307bde8ef8743282Paul Stewart
2640295e0f1437aa1f1488f4ae6d0f2fdde1f315397Ben Chan  EXPECT_CALL(*adaptor, EmitStringChanged(kAddressProperty, _));
2650295e0f1437aa1f1488f4ae6d0f2fdde1f315397Ben Chan  EXPECT_CALL(*adaptor, EmitStringsChanged(kNameServersProperty, _));
266c5099532b82fe201fe2510c43b529944a0930d2ePaul Stewart  ipconfig_->ResetProperties();
2677aed61cab2dc17f3c7f8c4a2a6d8d72ae1b7629dmukesh agrawal  Mock::VerifyAndClearExpectations(adaptor);
2687aed61cab2dc17f3c7f8c4a2a6d8d72ae1b7629dmukesh agrawal}
2697aed61cab2dc17f3c7f8c4a2a6d8d72ae1b7629dmukesh agrawal
270815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel TanTEST_F(IPConfigTest, UpdateLeaseExpirationTime) {
271815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  const struct timeval expected_time_now = {kTimeNow , 0};
272815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  uint32_t lease_duration = 1;
273815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  EXPECT_CALL(time_, GetTimeBoottime(_))
274815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan      .WillOnce(DoAll(SetArgPointee<0>(expected_time_now), Return(0)));
275815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  ipconfig_->UpdateLeaseExpirationTime(lease_duration);
276815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  EXPECT_EQ(kTimeNow + lease_duration,
277815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan            ipconfig_->current_lease_expiration_time_.tv_sec);
278815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan}
279815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan
280815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel TanTEST_F(IPConfigTest, TimeToLeaseExpiry_NoDHCPLease) {
281815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  ScopedMockLog log;
282815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  uint32_t time_left = 0;
283815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  // |current_lease_expiration_time_| has not been set, so expect an error.
28435ed908a15b7e1df603e7ba847b45b0a54e5712cPaul Stewart  EXPECT_CALL(log, Log(_, _,
285815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan                       EndsWith("No current DHCP lease")));
286815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  EXPECT_FALSE(ipconfig_->TimeToLeaseExpiry(&time_left));
287815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  EXPECT_EQ(0, time_left);
288815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan}
289815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan
290815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel TanTEST_F(IPConfigTest, TimeToLeaseExpiry_CurrentLeaseExpired) {
291815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  ScopedMockLog log;
292815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  const struct timeval time_now = {kTimeNow, 0};
293815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  uint32_t time_left = 0;
294815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  // Set |current_lease_expiration_time_| so it is expired (i.e. earlier than
295815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  // current time).
296815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  ipconfig_->current_lease_expiration_time_ = {kTimeNow - 1, 0};
297815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  EXPECT_CALL(time_, GetTimeBoottime(_))
298815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan      .WillOnce(DoAll(SetArgPointee<0>(time_now), Return(0)));
29935ed908a15b7e1df603e7ba847b45b0a54e5712cPaul Stewart  EXPECT_CALL(log, Log(_, _,
300815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan                       EndsWith("Current DHCP lease has already expired")));
301815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  EXPECT_FALSE(ipconfig_->TimeToLeaseExpiry(&time_left));
302815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  EXPECT_EQ(0, time_left);
303815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan}
304815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan
305815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel TanTEST_F(IPConfigTest, TimeToLeaseExpiry_Success) {
306815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  const uint32_t expected_time_to_expiry = 10;
307815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  const struct timeval time_now = {kTimeNow, 0};
308815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  uint32_t time_left;
309815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  // Set |current_lease_expiration_time_| so it appears like we already
310815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  // have obtained a DHCP lease before.
311815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  ipconfig_->current_lease_expiration_time_ = {
312815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan      kTimeNow + expected_time_to_expiry, 0};
313815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  EXPECT_CALL(time_, GetTimeBoottime(_))
314815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan      .WillOnce(DoAll(SetArgPointee<0>(time_now), Return(0)));
315815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  EXPECT_TRUE(ipconfig_->TimeToLeaseExpiry(&time_left));
316815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan  EXPECT_EQ(expected_time_to_expiry, time_left);
317815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan}
318815a6fb99abf0e4921e43784dd1d6f3fcf6415baSamuel Tan
319e02b3ca77f62f38bb5c72c826dffa185a7b71d82Darin Petkov}  // namespace shill
320