blob: 38cacb19e08394bc0b8c1c0079b87e2d239863cf [file] [log] [blame]
Peter Qiuc0beca52015-09-03 11:25:46 -07001//
2// Copyright (C) 2013 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
Paul Stewartced3ad72013-04-03 13:39:25 -070016
Ben Chan87602512014-11-07 20:50:05 -080017#include "shill/ethernet/ethernet.h"
Paul Stewartced3ad72013-04-03 13:39:25 -070018
19#include <netinet/ether.h>
Alex Vakulenkoa41ab512014-07-23 14:24:23 -070020#include <linux/if.h> // NOLINT - Needs definitions from netinet/ether.h
mukesh agrawal8bda7962014-04-01 17:09:35 -070021#include <linux/sockios.h>
Paul Stewartced3ad72013-04-03 13:39:25 -070022
Ben Chancd477322014-10-17 14:19:30 -070023#include <memory>
Garret Kelly65a56722015-02-03 14:48:25 -050024#include <utility>
25#include <vector>
Ben Chancd477322014-10-17 14:19:30 -070026
Paul Stewartced3ad72013-04-03 13:39:25 -070027#include <base/memory/ref_counted.h>
Paul Stewartced3ad72013-04-03 13:39:25 -070028
Peter Qiu675d0b02015-06-03 13:08:09 -070029#include "shill/dhcp/mock_dhcp_config.h"
30#include "shill/dhcp/mock_dhcp_provider.h"
Ben Chan87602512014-11-07 20:50:05 -080031#include "shill/ethernet/mock_ethernet_service.h"
Paul Stewartced3ad72013-04-03 13:39:25 -070032#include "shill/mock_device_info.h"
Alex Vakulenkoa41ab512014-07-23 14:24:23 -070033#include "shill/mock_event_dispatcher.h"
Paul Stewart9413bcc2013-04-04 16:12:43 -070034#include "shill/mock_log.h"
Paul Stewartced3ad72013-04-03 13:39:25 -070035#include "shill/mock_manager.h"
36#include "shill/mock_metrics.h"
Paul Stewart35eff132013-04-12 12:08:40 -070037#include "shill/mock_service.h"
Peter Qiu8d6b5972014-10-28 15:33:34 -070038#include "shill/net/mock_rtnl_handler.h"
39#include "shill/net/mock_sockets.h"
Paul Stewartced3ad72013-04-03 13:39:25 -070040#include "shill/nice_mock_control.h"
Peter Qiu1a72f542015-04-14 16:31:36 -070041#include "shill/testing.h"
42
43#if !defined(DISABLE_WIRED_8021X)
44#include "shill/ethernet/mock_ethernet_eap_provider.h"
45#include "shill/mock_eap_credentials.h"
46#include "shill/mock_eap_listener.h"
Ben Chanda69ecf2014-11-19 07:44:42 -080047#include "shill/supplicant/mock_supplicant_interface_proxy.h"
48#include "shill/supplicant/mock_supplicant_process_proxy.h"
49#include "shill/supplicant/wpa_supplicant.h"
Peter Qiu1a72f542015-04-14 16:31:36 -070050#endif // DISABLE_WIRED_8021X
Paul Stewartced3ad72013-04-03 13:39:25 -070051
Garret Kelly65a56722015-02-03 14:48:25 -050052using std::pair;
Paul Stewart9413bcc2013-04-04 16:12:43 -070053using std::string;
Garret Kelly65a56722015-02-03 14:48:25 -050054using std::vector;
Paul Stewartced3ad72013-04-03 13:39:25 -070055using testing::_;
56using testing::AnyNumber;
Paul Stewart9413bcc2013-04-04 16:12:43 -070057using testing::EndsWith;
Gaurav Shah25ee2502013-04-08 17:55:01 -070058using testing::Eq;
Garret Kelly65a56722015-02-03 14:48:25 -050059using testing::InSequence;
Paul Stewartced3ad72013-04-03 13:39:25 -070060using testing::Mock;
Paul Stewart9413bcc2013-04-04 16:12:43 -070061using testing::NiceMock;
Paul Stewartced3ad72013-04-03 13:39:25 -070062using testing::Return;
Paul Stewart35eff132013-04-12 12:08:40 -070063using testing::ReturnRef;
Peter Qiufc523632015-07-14 14:13:41 -070064using testing::SetArgumentPointee;
Paul Stewart9413bcc2013-04-04 16:12:43 -070065using testing::StrEq;
Paul Stewartced3ad72013-04-03 13:39:25 -070066using testing::StrictMock;
67
68namespace shill {
69
70class EthernetTest : public testing::Test {
71 public:
72 EthernetTest()
mukesh agrawal8bda7962014-04-01 17:09:35 -070073 : metrics_(nullptr),
mukesh agrawalbad1c102015-09-18 16:15:08 -070074 manager_(&control_interface_, nullptr, &metrics_),
Paul Stewartced3ad72013-04-03 13:39:25 -070075 device_info_(&control_interface_, &dispatcher_, &metrics_, &manager_),
76 ethernet_(new Ethernet(&control_interface_,
77 &dispatcher_,
78 &metrics_,
79 &manager_,
80 kDeviceName,
81 kDeviceAddress,
82 kInterfaceIndex)),
83 dhcp_config_(new MockDHCPConfig(&control_interface_,
84 kDeviceName)),
Peter Qiu1a72f542015-04-14 16:31:36 -070085#if !defined(DISABLE_WIRED_8021X)
Paul Stewart9413bcc2013-04-04 16:12:43 -070086 eap_listener_(new MockEapListener()),
Paul Stewart35eff132013-04-12 12:08:40 -070087 mock_eap_service_(new MockService(&control_interface_,
88 &dispatcher_,
89 &metrics_,
90 &manager_)),
Paul Stewart9413bcc2013-04-04 16:12:43 -070091 supplicant_interface_proxy_(
92 new NiceMock<MockSupplicantInterfaceProxy>()),
Peter Qiu1a72f542015-04-14 16:31:36 -070093 supplicant_process_proxy_(new NiceMock<MockSupplicantProcessProxy>()),
94#endif // DISABLE_WIRED_8021X
95 mock_sockets_(new StrictMock<MockSockets>()),
96 mock_service_(new MockEthernetService(
97 &control_interface_, &metrics_,
98 ethernet_->weak_ptr_factory_.GetWeakPtr())) {}
Paul Stewart3de88a02014-12-05 07:55:14 -080099 ~EthernetTest() override {}
Paul Stewartced3ad72013-04-03 13:39:25 -0700100
Paul Stewart3de88a02014-12-05 07:55:14 -0800101 void SetUp() override {
Paul Stewartced3ad72013-04-03 13:39:25 -0700102 ethernet_->rtnl_handler_ = &rtnl_handler_;
mukesh agrawal8bda7962014-04-01 17:09:35 -0700103 ethernet_->sockets_.reset(mock_sockets_); // Transfers ownership.
Paul Stewartced3ad72013-04-03 13:39:25 -0700104
105 ethernet_->set_dhcp_provider(&dhcp_provider_);
106 ON_CALL(manager_, device_info()).WillByDefault(Return(&device_info_));
107 EXPECT_CALL(manager_, UpdateEnabledTechnologies()).Times(AnyNumber());
Peter Qiu1a72f542015-04-14 16:31:36 -0700108
109#if !defined(DISABLE_WIRED_8021X)
110 ethernet_->eap_listener_.reset(eap_listener_); // Transfers ownership.
Paul Stewart35eff132013-04-12 12:08:40 -0700111 EXPECT_CALL(manager_, ethernet_eap_provider())
112 .WillRepeatedly(Return(&ethernet_eap_provider_));
113 ethernet_eap_provider_.set_service(mock_eap_service_);
Peter Qiue5fe58d2015-08-12 15:21:56 -0700114 // Transfers ownership.
115 ethernet_->supplicant_process_proxy_.reset(supplicant_process_proxy_);
Peter Qiu1a72f542015-04-14 16:31:36 -0700116#endif // DISABLE_WIRED_8021X
Garret Kelly65a56722015-02-03 14:48:25 -0500117
118 ON_CALL(*mock_service_, technology())
119 .WillByDefault(Return(Technology::kEthernet));
Paul Stewartced3ad72013-04-03 13:39:25 -0700120 }
121
Paul Stewart3de88a02014-12-05 07:55:14 -0800122 void TearDown() override {
Peter Qiu1a72f542015-04-14 16:31:36 -0700123#if !defined(DISABLE_WIRED_8021X)
Ben Chanf8a2ce12014-09-30 14:42:59 -0700124 ethernet_eap_provider_.set_service(nullptr);
Paul Stewartced3ad72013-04-03 13:39:25 -0700125 ethernet_->eap_listener_.reset();
Peter Qiu1a72f542015-04-14 16:31:36 -0700126#endif // DISABLE_WIRED_8021X
127 ethernet_->set_dhcp_provider(nullptr);
mukesh agrawal8bda7962014-04-01 17:09:35 -0700128 ethernet_->sockets_.reset();
Paul Stewartb6addef2014-08-29 14:41:59 -0700129 Mock::VerifyAndClearExpectations(&manager_);
Ben Chanf8a2ce12014-09-30 14:42:59 -0700130 ethernet_->Stop(nullptr, EnabledStateChangedCallback());
Paul Stewartced3ad72013-04-03 13:39:25 -0700131 }
132
133 protected:
134 static const char kDeviceName[];
135 static const char kDeviceAddress[];
Paul Stewart9413bcc2013-04-04 16:12:43 -0700136 static const char kInterfacePath[];
Paul Stewartced3ad72013-04-03 13:39:25 -0700137 static const int kInterfaceIndex;
138
Paul Stewart9413bcc2013-04-04 16:12:43 -0700139 bool GetLinkUp() { return ethernet_->link_up_; }
Paul Stewart3de88a02014-12-05 07:55:14 -0800140 void SetLinkUp(bool link_up) { ethernet_->link_up_ = link_up; }
Paul Stewart7e779d82015-06-16 13:13:10 -0700141 const ServiceRefPtr& GetSelectedService() {
Paul Stewart9413bcc2013-04-04 16:12:43 -0700142 return ethernet_->selected_service();
143 }
144 ServiceRefPtr GetService() { return ethernet_->service_; }
Paul Stewart7e779d82015-06-16 13:13:10 -0700145 void SetService(const EthernetServiceRefPtr& service) {
Paul Stewart9413bcc2013-04-04 16:12:43 -0700146 ethernet_->service_ = service;
147 }
Paul Stewart7e779d82015-06-16 13:13:10 -0700148 const PropertyStore& GetStore() { return ethernet_->store(); }
Paul Stewartced3ad72013-04-03 13:39:25 -0700149 void StartEthernet() {
150 EXPECT_CALL(rtnl_handler_,
151 SetInterfaceFlags(kInterfaceIndex, IFF_UP, IFF_UP));
Ben Chanf8a2ce12014-09-30 14:42:59 -0700152 ethernet_->Start(nullptr, EnabledStateChangedCallback());
Paul Stewartced3ad72013-04-03 13:39:25 -0700153 }
Peter Qiu1a72f542015-04-14 16:31:36 -0700154
155#if !defined(DISABLE_WIRED_8021X)
156 bool GetIsEapAuthenticated() { return ethernet_->is_eap_authenticated_; }
157 void SetIsEapAuthenticated(bool is_eap_authenticated) {
158 ethernet_->is_eap_authenticated_ = is_eap_authenticated;
159 }
160 bool GetIsEapDetected() { return ethernet_->is_eap_detected_; }
161 void SetIsEapDetected(bool is_eap_detected) {
162 ethernet_->is_eap_detected_ = is_eap_detected;
163 }
Paul Stewart7e779d82015-06-16 13:13:10 -0700164 const SupplicantInterfaceProxyInterface* GetSupplicantInterfaceProxy() {
Paul Stewart9413bcc2013-04-04 16:12:43 -0700165 return ethernet_->supplicant_interface_proxy_.get();
Paul Stewartced3ad72013-04-03 13:39:25 -0700166 }
Paul Stewart7e779d82015-06-16 13:13:10 -0700167 const string& GetSupplicantInterfacePath() {
Paul Stewart9413bcc2013-04-04 16:12:43 -0700168 return ethernet_->supplicant_interface_path_;
169 }
Paul Stewart7e779d82015-06-16 13:13:10 -0700170 const string& GetSupplicantNetworkPath() {
Paul Stewart9413bcc2013-04-04 16:12:43 -0700171 return ethernet_->supplicant_network_path_;
172 }
Paul Stewart7e779d82015-06-16 13:13:10 -0700173 void SetSupplicantNetworkPath(const string& network_path) {
Paul Stewart9413bcc2013-04-04 16:12:43 -0700174 ethernet_->supplicant_network_path_ = network_path;
175 }
176 bool InvokeStartSupplicant() {
177 return ethernet_->StartSupplicant();
178 }
179 void InvokeStopSupplicant() {
180 return ethernet_->StopSupplicant();
181 }
182 bool InvokeStartEapAuthentication() {
183 return ethernet_->StartEapAuthentication();
184 }
185 void StartSupplicant() {
Paul Stewart7e779d82015-06-16 13:13:10 -0700186 MockSupplicantInterfaceProxy* interface_proxy =
Ben Chana55469d2014-01-27 16:35:29 -0800187 ExpectCreateSupplicantInterfaceProxy();
Peter Qiue5fe58d2015-08-12 15:21:56 -0700188 EXPECT_CALL(*supplicant_process_proxy_, CreateInterface(_, _))
Peter Qiufc523632015-07-14 14:13:41 -0700189 .WillOnce(DoAll(SetArgumentPointee<1>(string(kInterfacePath)),
190 Return(true)));
Paul Stewart9413bcc2013-04-04 16:12:43 -0700191 EXPECT_TRUE(InvokeStartSupplicant());
Ben Chana55469d2014-01-27 16:35:29 -0800192 EXPECT_EQ(interface_proxy, GetSupplicantInterfaceProxy());
Paul Stewart9413bcc2013-04-04 16:12:43 -0700193 EXPECT_EQ(kInterfacePath, GetSupplicantInterfacePath());
194 }
Paul Stewartced3ad72013-04-03 13:39:25 -0700195 void TriggerOnEapDetected() { ethernet_->OnEapDetected(); }
Paul Stewart7e779d82015-06-16 13:13:10 -0700196 void TriggerCertification(const string& subject, uint32_t depth) {
Paul Stewart9413bcc2013-04-04 16:12:43 -0700197 ethernet_->CertificationTask(subject, depth);
198 }
Paul Stewart35eff132013-04-12 12:08:40 -0700199 void TriggerTryEapAuthentication() {
200 ethernet_->TryEapAuthenticationTask();
201 }
Paul Stewartced3ad72013-04-03 13:39:25 -0700202
Paul Stewart7e779d82015-06-16 13:13:10 -0700203 MockSupplicantInterfaceProxy* ExpectCreateSupplicantInterfaceProxy() {
Peter Qiu608ec292015-07-30 15:46:16 -0700204 EXPECT_CALL(control_interface_,
Peter Qiue5fe58d2015-08-12 15:21:56 -0700205 CreateSupplicantInterfaceProxy(_, kInterfacePath))
Ben Chana55469d2014-01-27 16:35:29 -0800206 .WillOnce(ReturnAndReleasePointee(&supplicant_interface_proxy_));
207 return supplicant_interface_proxy_.get();
208 }
Peter Qiu1a72f542015-04-14 16:31:36 -0700209#endif // DISABLE_WIRED_8021X
Ben Chana55469d2014-01-27 16:35:29 -0800210
Paul Stewartced3ad72013-04-03 13:39:25 -0700211 StrictMock<MockEventDispatcher> dispatcher_;
Paul Stewartced3ad72013-04-03 13:39:25 -0700212 NiceMockControl control_interface_;
mukesh agrawal8bda7962014-04-01 17:09:35 -0700213 NiceMock<MockMetrics> metrics_;
Paul Stewartced3ad72013-04-03 13:39:25 -0700214 MockManager manager_;
215 MockDeviceInfo device_info_;
216 EthernetRefPtr ethernet_;
217 MockDHCPProvider dhcp_provider_;
218 scoped_refptr<MockDHCPConfig> dhcp_config_;
Paul Stewart9413bcc2013-04-04 16:12:43 -0700219
Peter Qiu1a72f542015-04-14 16:31:36 -0700220#if !defined(DISABLE_WIRED_8021X)
221 MockEthernetEapProvider ethernet_eap_provider_;
222
Paul Stewartced3ad72013-04-03 13:39:25 -0700223 // Owned by Ethernet instance, but tracked here for expectations.
Paul Stewart7e779d82015-06-16 13:13:10 -0700224 MockEapListener* eap_listener_;
Peter Qiu1a72f542015-04-14 16:31:36 -0700225
226 scoped_refptr<MockService> mock_eap_service_;
227 std::unique_ptr<MockSupplicantInterfaceProxy> supplicant_interface_proxy_;
Peter Qiue5fe58d2015-08-12 15:21:56 -0700228 MockSupplicantProcessProxy* supplicant_process_proxy_;
Peter Qiu1a72f542015-04-14 16:31:36 -0700229#endif // DISABLE_WIRED_8021X
230
231 // Owned by Ethernet instance, but tracked here for expectations.
Paul Stewart7e779d82015-06-16 13:13:10 -0700232 MockSockets* mock_sockets_;
Paul Stewart9413bcc2013-04-04 16:12:43 -0700233
234 MockRTNLHandler rtnl_handler_;
235 scoped_refptr<MockEthernetService> mock_service_;
Paul Stewartced3ad72013-04-03 13:39:25 -0700236};
237
238// static
239const char EthernetTest::kDeviceName[] = "eth0";
240const char EthernetTest::kDeviceAddress[] = "000102030405";
Paul Stewart9413bcc2013-04-04 16:12:43 -0700241const char EthernetTest::kInterfacePath[] = "/interface/path";
Paul Stewartced3ad72013-04-03 13:39:25 -0700242const int EthernetTest::kInterfaceIndex = 123;
243
244TEST_F(EthernetTest, Construct) {
245 EXPECT_FALSE(GetLinkUp());
Peter Qiu1a72f542015-04-14 16:31:36 -0700246#if !defined(DISABLE_WIRED_8021X)
Paul Stewart9413bcc2013-04-04 16:12:43 -0700247 EXPECT_FALSE(GetIsEapAuthenticated());
Paul Stewartced3ad72013-04-03 13:39:25 -0700248 EXPECT_FALSE(GetIsEapDetected());
Paul Stewart9413bcc2013-04-04 16:12:43 -0700249 EXPECT_TRUE(GetStore().Contains(kEapAuthenticationCompletedProperty));
Paul Stewartced3ad72013-04-03 13:39:25 -0700250 EXPECT_TRUE(GetStore().Contains(kEapAuthenticatorDetectedProperty));
Peter Qiu1a72f542015-04-14 16:31:36 -0700251#endif // DISABLE_WIRED_8021X
Paul Stewart3de88a02014-12-05 07:55:14 -0800252 EXPECT_NE(nullptr, GetService().get());
Paul Stewartced3ad72013-04-03 13:39:25 -0700253}
254
255TEST_F(EthernetTest, StartStop) {
Paul Stewart3de88a02014-12-05 07:55:14 -0800256 Service* service = GetService().get();
257 EXPECT_CALL(manager_, RegisterService(Eq(service)));
Gaurav Shah25ee2502013-04-08 17:55:01 -0700258 StartEthernet();
259
Gaurav Shah25ee2502013-04-08 17:55:01 -0700260 EXPECT_CALL(manager_, DeregisterService(Eq(service)));
Ben Chanf8a2ce12014-09-30 14:42:59 -0700261 ethernet_->Stop(nullptr, EnabledStateChangedCallback());
Paul Stewart3de88a02014-12-05 07:55:14 -0800262
263 // Ethernet device retains its service.
264 EXPECT_NE(nullptr, GetService());
Paul Stewartced3ad72013-04-03 13:39:25 -0700265}
266
267TEST_F(EthernetTest, LinkEvent) {
268 StartEthernet();
Paul Stewart3de88a02014-12-05 07:55:14 -0800269 SetService(mock_service_);
Paul Stewartced3ad72013-04-03 13:39:25 -0700270
271 // Link-down event while already down.
272 EXPECT_CALL(manager_, DeregisterService(_)).Times(0);
Peter Qiu1a72f542015-04-14 16:31:36 -0700273#if !defined(DISABLE_WIRED_8021X)
Paul Stewartced3ad72013-04-03 13:39:25 -0700274 EXPECT_CALL(*eap_listener_, Start()).Times(0);
Peter Qiu1a72f542015-04-14 16:31:36 -0700275#endif // DISABLE_WIRED_8021X
Paul Stewartced3ad72013-04-03 13:39:25 -0700276 ethernet_->LinkEvent(0, IFF_LOWER_UP);
277 EXPECT_FALSE(GetLinkUp());
Peter Qiu1a72f542015-04-14 16:31:36 -0700278#if !defined(DISABLE_WIRED_8021X)
Paul Stewartced3ad72013-04-03 13:39:25 -0700279 EXPECT_FALSE(GetIsEapDetected());
Peter Qiu1a72f542015-04-14 16:31:36 -0700280#endif // DISABLE_WIRED_8021X
Paul Stewartced3ad72013-04-03 13:39:25 -0700281 Mock::VerifyAndClearExpectations(&manager_);
282
283 // Link-up event while down.
mukesh agrawal8bda7962014-04-01 17:09:35 -0700284 int kFakeFd = 789;
Paul Stewart3de88a02014-12-05 07:55:14 -0800285 EXPECT_CALL(manager_, UpdateService(IsRefPtrTo(mock_service_)));
286 EXPECT_CALL(*mock_service_, OnVisibilityChanged());
Peter Qiu1a72f542015-04-14 16:31:36 -0700287#if !defined(DISABLE_WIRED_8021X)
Paul Stewartced3ad72013-04-03 13:39:25 -0700288 EXPECT_CALL(*eap_listener_, Start());
Peter Qiu1a72f542015-04-14 16:31:36 -0700289#endif // DISABLE_WIRED_8021X
mukesh agrawal8bda7962014-04-01 17:09:35 -0700290 EXPECT_CALL(*mock_sockets_, Socket(_, _, _)).WillOnce(Return(kFakeFd));
291 EXPECT_CALL(*mock_sockets_, Ioctl(kFakeFd, SIOCETHTOOL, _));
292 EXPECT_CALL(*mock_sockets_, Close(kFakeFd));
Paul Stewartced3ad72013-04-03 13:39:25 -0700293 ethernet_->LinkEvent(IFF_LOWER_UP, 0);
294 EXPECT_TRUE(GetLinkUp());
Peter Qiu1a72f542015-04-14 16:31:36 -0700295#if !defined(DISABLE_WIRED_8021X)
Paul Stewartced3ad72013-04-03 13:39:25 -0700296 EXPECT_FALSE(GetIsEapDetected());
Peter Qiu1a72f542015-04-14 16:31:36 -0700297#endif // DISABLE_WIRED_8021X
Paul Stewartced3ad72013-04-03 13:39:25 -0700298 Mock::VerifyAndClearExpectations(&manager_);
Alex Vakulenko0951ccb2014-12-10 12:52:31 -0800299 Mock::VerifyAndClearExpectations(mock_service_.get());
Paul Stewartced3ad72013-04-03 13:39:25 -0700300
301 // Link-up event while already up.
Paul Stewart3de88a02014-12-05 07:55:14 -0800302 EXPECT_CALL(manager_, UpdateService(_)).Times(0);
303 EXPECT_CALL(*mock_service_, OnVisibilityChanged()).Times(0);
Peter Qiu1a72f542015-04-14 16:31:36 -0700304#if !defined(DISABLE_WIRED_8021X)
Paul Stewartced3ad72013-04-03 13:39:25 -0700305 EXPECT_CALL(*eap_listener_, Start()).Times(0);
Peter Qiu1a72f542015-04-14 16:31:36 -0700306#endif // DISABLE_WIRED_8021X
Paul Stewartced3ad72013-04-03 13:39:25 -0700307 ethernet_->LinkEvent(IFF_LOWER_UP, 0);
308 EXPECT_TRUE(GetLinkUp());
Peter Qiu1a72f542015-04-14 16:31:36 -0700309#if !defined(DISABLE_WIRED_8021X)
Paul Stewartced3ad72013-04-03 13:39:25 -0700310 EXPECT_FALSE(GetIsEapDetected());
Peter Qiu1a72f542015-04-14 16:31:36 -0700311#endif // DISABLE_WIRED_8021X
Paul Stewartced3ad72013-04-03 13:39:25 -0700312 Mock::VerifyAndClearExpectations(&manager_);
Alex Vakulenko0951ccb2014-12-10 12:52:31 -0800313 Mock::VerifyAndClearExpectations(mock_service_.get());
Paul Stewartced3ad72013-04-03 13:39:25 -0700314
315 // Link-down event while up.
Peter Qiu1a72f542015-04-14 16:31:36 -0700316#if !defined(DISABLE_WIRED_8021X)
Paul Stewartced3ad72013-04-03 13:39:25 -0700317 SetIsEapDetected(true);
Paul Stewart35eff132013-04-12 12:08:40 -0700318 // This is done in SetUp, but we have to reestablish this after calling
319 // VerifyAndClearExpectations() above.
320 EXPECT_CALL(manager_, ethernet_eap_provider())
321 .WillRepeatedly(Return(&ethernet_eap_provider_));
322 EXPECT_CALL(ethernet_eap_provider_,
323 ClearCredentialChangeCallback(ethernet_.get()));
Peter Qiu1a72f542015-04-14 16:31:36 -0700324 EXPECT_CALL(*eap_listener_, Stop());
325#endif // DISABLE_WIRED_8021X
Paul Stewart3de88a02014-12-05 07:55:14 -0800326 EXPECT_CALL(manager_, UpdateService(IsRefPtrTo(GetService().get())));
327 EXPECT_CALL(*mock_service_, OnVisibilityChanged());
Paul Stewartced3ad72013-04-03 13:39:25 -0700328 ethernet_->LinkEvent(0, IFF_LOWER_UP);
329 EXPECT_FALSE(GetLinkUp());
Peter Qiu1a72f542015-04-14 16:31:36 -0700330#if !defined(DISABLE_WIRED_8021X)
Paul Stewartced3ad72013-04-03 13:39:25 -0700331 EXPECT_FALSE(GetIsEapDetected());
Peter Qiu1a72f542015-04-14 16:31:36 -0700332#endif // DISABLE_WIRED_8021X
Paul Stewartced3ad72013-04-03 13:39:25 -0700333
334 // Restore this expectation during shutdown.
335 EXPECT_CALL(manager_, UpdateEnabledTechnologies()).Times(AnyNumber());
336}
337
Paul Stewart3de88a02014-12-05 07:55:14 -0800338TEST_F(EthernetTest, ConnectToLinkDown) {
339 StartEthernet();
340 SetService(mock_service_);
341 SetLinkUp(false);
342 EXPECT_EQ(nullptr, GetSelectedService().get());
Peter Qiu8e0151e2015-06-04 09:41:47 -0700343 EXPECT_CALL(dhcp_provider_, CreateIPv4Config(_, _, _, _)).Times(0);
Paul Stewart3de88a02014-12-05 07:55:14 -0800344 EXPECT_CALL(*dhcp_config_.get(), RequestIP()).Times(0);
345 EXPECT_CALL(dispatcher_, PostTask(_)).Times(0);
346 EXPECT_CALL(*mock_service_, SetState(_)).Times(0);
Alex Vakulenko0951ccb2014-12-10 12:52:31 -0800347 ethernet_->ConnectTo(mock_service_.get());
Paul Stewart3de88a02014-12-05 07:55:14 -0800348 EXPECT_EQ(nullptr, GetSelectedService().get());
349}
350
Paul Stewart9413bcc2013-04-04 16:12:43 -0700351TEST_F(EthernetTest, ConnectToFailure) {
352 StartEthernet();
353 SetService(mock_service_);
Paul Stewart3de88a02014-12-05 07:55:14 -0800354 SetLinkUp(true);
Ben Chanf8a2ce12014-09-30 14:42:59 -0700355 EXPECT_EQ(nullptr, GetSelectedService().get());
Peter Qiu8e0151e2015-06-04 09:41:47 -0700356 EXPECT_CALL(dhcp_provider_, CreateIPv4Config(_, _, _, _)).
Paul Stewart9413bcc2013-04-04 16:12:43 -0700357 WillOnce(Return(dhcp_config_));
358 EXPECT_CALL(*dhcp_config_.get(), RequestIP()).WillOnce(Return(false));
359 EXPECT_CALL(dispatcher_, PostTask(_)); // Posts ConfigureStaticIPTask.
Paul Stewartdded0072013-10-24 12:38:54 -0700360 EXPECT_CALL(*mock_service_, SetState(Service::kStateFailure));
Alex Vakulenko0951ccb2014-12-10 12:52:31 -0800361 ethernet_->ConnectTo(mock_service_.get());
Paul Stewartdded0072013-10-24 12:38:54 -0700362 EXPECT_EQ(mock_service_, GetSelectedService().get());
Paul Stewart9413bcc2013-04-04 16:12:43 -0700363}
364
365TEST_F(EthernetTest, ConnectToSuccess) {
366 StartEthernet();
367 SetService(mock_service_);
Paul Stewart3de88a02014-12-05 07:55:14 -0800368 SetLinkUp(true);
Ben Chanf8a2ce12014-09-30 14:42:59 -0700369 EXPECT_EQ(nullptr, GetSelectedService().get());
Peter Qiu8e0151e2015-06-04 09:41:47 -0700370 EXPECT_CALL(dhcp_provider_, CreateIPv4Config(_, _, _, _)).
Paul Stewart9413bcc2013-04-04 16:12:43 -0700371 WillOnce(Return(dhcp_config_));
372 EXPECT_CALL(*dhcp_config_.get(), RequestIP()).WillOnce(Return(true));
373 EXPECT_CALL(dispatcher_, PostTask(_)); // Posts ConfigureStaticIPTask.
374 EXPECT_CALL(*mock_service_, SetState(Service::kStateConfiguring));
375 ethernet_->ConnectTo(mock_service_.get());
376 EXPECT_EQ(GetService().get(), GetSelectedService().get());
Alex Vakulenko0951ccb2014-12-10 12:52:31 -0800377 Mock::VerifyAndClearExpectations(mock_service_.get());
Paul Stewart9413bcc2013-04-04 16:12:43 -0700378
379 EXPECT_CALL(*mock_service_, SetState(Service::kStateIdle));
Alex Vakulenko0951ccb2014-12-10 12:52:31 -0800380 ethernet_->DisconnectFrom(mock_service_.get());
Ben Chanf8a2ce12014-09-30 14:42:59 -0700381 EXPECT_EQ(nullptr, GetSelectedService().get());
Paul Stewart9413bcc2013-04-04 16:12:43 -0700382}
383
Peter Qiu1a72f542015-04-14 16:31:36 -0700384#if !defined(DISABLE_WIRED_8021X)
Paul Stewartced3ad72013-04-03 13:39:25 -0700385TEST_F(EthernetTest, OnEapDetected) {
386 EXPECT_FALSE(GetIsEapDetected());
387 EXPECT_CALL(*eap_listener_, Stop());
Paul Stewart35eff132013-04-12 12:08:40 -0700388 EXPECT_CALL(ethernet_eap_provider_,
389 SetCredentialChangeCallback(ethernet_.get(), _));
390 EXPECT_CALL(dispatcher_, PostTask(_)); // Posts TryEapAuthenticationTask.
Paul Stewartced3ad72013-04-03 13:39:25 -0700391 TriggerOnEapDetected();
392 EXPECT_TRUE(GetIsEapDetected());
393}
394
Paul Stewart9413bcc2013-04-04 16:12:43 -0700395TEST_F(EthernetTest, TryEapAuthenticationNotConnectableNotAuthenticated) {
396 SetService(mock_service_);
Paul Stewart35eff132013-04-12 12:08:40 -0700397 EXPECT_CALL(*mock_eap_service_, Is8021xConnectable()).WillOnce(Return(false));
Paul Stewart9413bcc2013-04-04 16:12:43 -0700398 NiceScopedMockLog log;
399 EXPECT_CALL(log, Log(logging::LOG_INFO, _,
Paul Stewart35eff132013-04-12 12:08:40 -0700400 EndsWith("EAP Service lacks 802.1X credentials; "
Paul Stewart9413bcc2013-04-04 16:12:43 -0700401 "not doing EAP authentication.")));
Paul Stewart35eff132013-04-12 12:08:40 -0700402 TriggerTryEapAuthentication();
Ben Chanf8a2ce12014-09-30 14:42:59 -0700403 SetService(nullptr);
Paul Stewart9413bcc2013-04-04 16:12:43 -0700404}
405
406TEST_F(EthernetTest, TryEapAuthenticationNotConnectableAuthenticated) {
407 SetService(mock_service_);
408 SetIsEapAuthenticated(true);
Paul Stewart35eff132013-04-12 12:08:40 -0700409 EXPECT_CALL(*mock_eap_service_, Is8021xConnectable()).WillOnce(Return(false));
Paul Stewart9413bcc2013-04-04 16:12:43 -0700410 NiceScopedMockLog log;
Paul Stewart35eff132013-04-12 12:08:40 -0700411 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
Paul Stewart9413bcc2013-04-04 16:12:43 -0700412 EXPECT_CALL(log, Log(logging::LOG_INFO, _,
Paul Stewart35eff132013-04-12 12:08:40 -0700413 EndsWith("EAP Service lost 802.1X credentials; "
Paul Stewart9413bcc2013-04-04 16:12:43 -0700414 "terminating EAP authentication.")));
Paul Stewart35eff132013-04-12 12:08:40 -0700415 TriggerTryEapAuthentication();
Paul Stewart9413bcc2013-04-04 16:12:43 -0700416 EXPECT_FALSE(GetIsEapAuthenticated());
417}
418
419TEST_F(EthernetTest, TryEapAuthenticationEapNotDetected) {
420 SetService(mock_service_);
Paul Stewart35eff132013-04-12 12:08:40 -0700421 EXPECT_CALL(*mock_eap_service_, Is8021xConnectable()).WillOnce(Return(true));
Paul Stewart9413bcc2013-04-04 16:12:43 -0700422 NiceScopedMockLog log;
Paul Stewart35eff132013-04-12 12:08:40 -0700423 EXPECT_CALL(log, Log(logging::LOG_WARNING, _,
Paul Stewart9413bcc2013-04-04 16:12:43 -0700424 EndsWith("EAP authenticator not detected; "
425 "not doing EAP authentication.")));
Paul Stewart35eff132013-04-12 12:08:40 -0700426 TriggerTryEapAuthentication();
Paul Stewart9413bcc2013-04-04 16:12:43 -0700427}
428
429TEST_F(EthernetTest, StartSupplicant) {
430 // Save the mock proxy pointers before the Ethernet instance accepts it.
Paul Stewart7e779d82015-06-16 13:13:10 -0700431 MockSupplicantInterfaceProxy* interface_proxy =
Paul Stewart9413bcc2013-04-04 16:12:43 -0700432 supplicant_interface_proxy_.get();
Peter Qiue5fe58d2015-08-12 15:21:56 -0700433 MockSupplicantProcessProxy* process_proxy = supplicant_process_proxy_;
Paul Stewart9413bcc2013-04-04 16:12:43 -0700434
435 StartSupplicant();
436
437 // Starting it again should not invoke another call to create an interface.
438 Mock::VerifyAndClearExpectations(process_proxy);
Peter Qiufc523632015-07-14 14:13:41 -0700439 EXPECT_CALL(*process_proxy, CreateInterface(_, _)).Times(0);
Paul Stewart9413bcc2013-04-04 16:12:43 -0700440 EXPECT_TRUE(InvokeStartSupplicant());
441
Ben Chana55469d2014-01-27 16:35:29 -0800442 // Also, the mock pointers should remain; if the MockProxyFactory was
Ben Chanf8a2ce12014-09-30 14:42:59 -0700443 // invoked again, they would be nullptr.
Paul Stewart9413bcc2013-04-04 16:12:43 -0700444 EXPECT_EQ(interface_proxy, GetSupplicantInterfaceProxy());
Paul Stewart9413bcc2013-04-04 16:12:43 -0700445 EXPECT_EQ(kInterfacePath, GetSupplicantInterfacePath());
446}
447
448TEST_F(EthernetTest, StartSupplicantWithInterfaceExistsException) {
Peter Qiue5fe58d2015-08-12 15:21:56 -0700449 MockSupplicantProcessProxy* process_proxy = supplicant_process_proxy_;
Paul Stewart7e779d82015-06-16 13:13:10 -0700450 MockSupplicantInterfaceProxy* interface_proxy =
Ben Chana55469d2014-01-27 16:35:29 -0800451 ExpectCreateSupplicantInterfaceProxy();
Peter Qiufc523632015-07-14 14:13:41 -0700452 EXPECT_CALL(*process_proxy, CreateInterface(_, _)).WillOnce(Return(false));
453 EXPECT_CALL(*process_proxy, GetInterface(kDeviceName, _))
454 .WillOnce(
455 DoAll(SetArgumentPointee<1>(string(kInterfacePath)), Return(true)));
Paul Stewart9413bcc2013-04-04 16:12:43 -0700456 EXPECT_TRUE(InvokeStartSupplicant());
457 EXPECT_EQ(interface_proxy, GetSupplicantInterfaceProxy());
Paul Stewart9413bcc2013-04-04 16:12:43 -0700458 EXPECT_EQ(kInterfacePath, GetSupplicantInterfacePath());
459}
460
461TEST_F(EthernetTest, StartSupplicantWithUnknownException) {
Peter Qiue5fe58d2015-08-12 15:21:56 -0700462 MockSupplicantProcessProxy* process_proxy = supplicant_process_proxy_;
Peter Qiufc523632015-07-14 14:13:41 -0700463 EXPECT_CALL(*process_proxy, CreateInterface(_, _)).WillOnce(Return(false));
464 EXPECT_CALL(*process_proxy, GetInterface(kDeviceName, _))
465 .WillOnce(Return(false));
Paul Stewart9413bcc2013-04-04 16:12:43 -0700466 EXPECT_FALSE(InvokeStartSupplicant());
Ben Chanf8a2ce12014-09-30 14:42:59 -0700467 EXPECT_EQ(nullptr, GetSupplicantInterfaceProxy());
Paul Stewart9413bcc2013-04-04 16:12:43 -0700468 EXPECT_EQ("", GetSupplicantInterfacePath());
469}
470
471TEST_F(EthernetTest, StartEapAuthentication) {
Paul Stewart7e779d82015-06-16 13:13:10 -0700472 MockSupplicantInterfaceProxy* interface_proxy =
Paul Stewart9413bcc2013-04-04 16:12:43 -0700473 supplicant_interface_proxy_.get();
474
475 StartSupplicant();
476 SetService(mock_service_);
477
478 EXPECT_CALL(*mock_service_, ClearEAPCertification());
Paul Stewart35eff132013-04-12 12:08:40 -0700479 MockEapCredentials mock_eap_credentials;
480 EXPECT_CALL(*mock_eap_service_, eap())
481 .WillOnce(Return(&mock_eap_credentials));
Paul Stewartc350e682014-06-19 15:44:30 -0700482 EXPECT_CALL(mock_eap_credentials, PopulateSupplicantProperties(_, _));
Paul Stewart9413bcc2013-04-04 16:12:43 -0700483 EXPECT_CALL(*interface_proxy, RemoveNetwork(_)).Times(0);
Peter Qiufc523632015-07-14 14:13:41 -0700484 EXPECT_CALL(*interface_proxy, AddNetwork(_, _))
485 .WillOnce(Return(false));
Paul Stewart9413bcc2013-04-04 16:12:43 -0700486 EXPECT_CALL(*interface_proxy, SelectNetwork(_)).Times(0);
Paul Stewartbe9abfd2013-04-22 12:18:48 -0700487 EXPECT_CALL(*interface_proxy, EAPLogon()).Times(0);
Paul Stewart9413bcc2013-04-04 16:12:43 -0700488 EXPECT_FALSE(InvokeStartEapAuthentication());
Alex Vakulenko0951ccb2014-12-10 12:52:31 -0800489 Mock::VerifyAndClearExpectations(mock_service_.get());
490 Mock::VerifyAndClearExpectations(mock_eap_service_.get());
Paul Stewart9413bcc2013-04-04 16:12:43 -0700491 Mock::VerifyAndClearExpectations(interface_proxy);
492 EXPECT_EQ("", GetSupplicantNetworkPath());
493
494 EXPECT_CALL(*mock_service_, ClearEAPCertification());
495 EXPECT_CALL(*interface_proxy, RemoveNetwork(_)).Times(0);
Paul Stewart35eff132013-04-12 12:08:40 -0700496 EXPECT_CALL(*mock_eap_service_, eap())
497 .WillOnce(Return(&mock_eap_credentials));
Paul Stewartc350e682014-06-19 15:44:30 -0700498 EXPECT_CALL(mock_eap_credentials, PopulateSupplicantProperties(_, _));
Paul Stewart9413bcc2013-04-04 16:12:43 -0700499 const char kFirstNetworkPath[] = "/network/first-path";
Peter Qiufc523632015-07-14 14:13:41 -0700500 EXPECT_CALL(*interface_proxy, AddNetwork(_, _))
501 .WillOnce(
502 DoAll(SetArgumentPointee<1>(string(kFirstNetworkPath)),
503 Return(true)));
Paul Stewart9413bcc2013-04-04 16:12:43 -0700504 EXPECT_CALL(*interface_proxy, SelectNetwork(StrEq(kFirstNetworkPath)));
Paul Stewartbe9abfd2013-04-22 12:18:48 -0700505 EXPECT_CALL(*interface_proxy, EAPLogon());
Paul Stewart9413bcc2013-04-04 16:12:43 -0700506 EXPECT_TRUE(InvokeStartEapAuthentication());
Alex Vakulenko0951ccb2014-12-10 12:52:31 -0800507 Mock::VerifyAndClearExpectations(mock_service_.get());
508 Mock::VerifyAndClearExpectations(mock_eap_service_.get());
Paul Stewart35eff132013-04-12 12:08:40 -0700509 Mock::VerifyAndClearExpectations(&mock_eap_credentials);
Paul Stewart9413bcc2013-04-04 16:12:43 -0700510 Mock::VerifyAndClearExpectations(interface_proxy);
511 EXPECT_EQ(kFirstNetworkPath, GetSupplicantNetworkPath());
512
513 EXPECT_CALL(*mock_service_, ClearEAPCertification());
Peter Qiufc523632015-07-14 14:13:41 -0700514 EXPECT_CALL(*interface_proxy, RemoveNetwork(StrEq(kFirstNetworkPath)))
515 .WillOnce(Return(true));
Paul Stewart35eff132013-04-12 12:08:40 -0700516 EXPECT_CALL(*mock_eap_service_, eap())
517 .WillOnce(Return(&mock_eap_credentials));
Paul Stewartc350e682014-06-19 15:44:30 -0700518 EXPECT_CALL(mock_eap_credentials, PopulateSupplicantProperties(_, _));
Paul Stewart9413bcc2013-04-04 16:12:43 -0700519 const char kSecondNetworkPath[] = "/network/second-path";
Peter Qiufc523632015-07-14 14:13:41 -0700520 EXPECT_CALL(*interface_proxy, AddNetwork(_, _))
521 .WillOnce(
522 DoAll(SetArgumentPointee<1>(string(kSecondNetworkPath)),
523 Return(true)));
Paul Stewart9413bcc2013-04-04 16:12:43 -0700524 EXPECT_CALL(*interface_proxy, SelectNetwork(StrEq(kSecondNetworkPath)));
Paul Stewartbe9abfd2013-04-22 12:18:48 -0700525 EXPECT_CALL(*interface_proxy, EAPLogon());
Paul Stewart9413bcc2013-04-04 16:12:43 -0700526 EXPECT_TRUE(InvokeStartEapAuthentication());
527 EXPECT_EQ(kSecondNetworkPath, GetSupplicantNetworkPath());
528}
529
530TEST_F(EthernetTest, StopSupplicant) {
Peter Qiue5fe58d2015-08-12 15:21:56 -0700531 MockSupplicantProcessProxy* process_proxy = supplicant_process_proxy_;
Paul Stewart7e779d82015-06-16 13:13:10 -0700532 MockSupplicantInterfaceProxy* interface_proxy =
Paul Stewartbe9abfd2013-04-22 12:18:48 -0700533 supplicant_interface_proxy_.get();
Paul Stewart9413bcc2013-04-04 16:12:43 -0700534 StartSupplicant();
535 SetIsEapAuthenticated(true);
536 SetSupplicantNetworkPath("/network/1");
Peter Qiufc523632015-07-14 14:13:41 -0700537 EXPECT_CALL(*interface_proxy, EAPLogoff()).WillOnce(Return(true));
538 EXPECT_CALL(*process_proxy, RemoveInterface(StrEq(kInterfacePath)))
539 .WillOnce(Return(true));
Paul Stewart9413bcc2013-04-04 16:12:43 -0700540 InvokeStopSupplicant();
Ben Chanf8a2ce12014-09-30 14:42:59 -0700541 EXPECT_EQ(nullptr, GetSupplicantInterfaceProxy());
Paul Stewart9413bcc2013-04-04 16:12:43 -0700542 EXPECT_EQ("", GetSupplicantInterfacePath());
543 EXPECT_EQ("", GetSupplicantNetworkPath());
544 EXPECT_FALSE(GetIsEapAuthenticated());
545}
546
547TEST_F(EthernetTest, Certification) {
548 const string kSubjectName("subject-name");
Ben Chan7fab8972014-08-10 17:14:46 -0700549 const uint32_t kDepth = 123;
Paul Stewart9413bcc2013-04-04 16:12:43 -0700550 // Should not crash due to no service_.
551 TriggerCertification(kSubjectName, kDepth);
552 EXPECT_CALL(*mock_service_, AddEAPCertification(kSubjectName, kDepth));
553 SetService(mock_service_);
554 TriggerCertification(kSubjectName, kDepth);
555}
Peter Qiu1a72f542015-04-14 16:31:36 -0700556#endif // DISABLE_WIRED_8021X
Paul Stewart9413bcc2013-04-04 16:12:43 -0700557
Garret Kelly65a56722015-02-03 14:48:25 -0500558#if !defined(DISABLE_PPPOE)
559
560MATCHER_P(TechnologyEq, technology, "") {
561 return arg->technology() == technology;
562}
563
564TEST_F(EthernetTest, TogglePPPoE) {
565 SetService(mock_service_);
566
567 EXPECT_CALL(*mock_service_, technology())
568 .WillRepeatedly(Return(Technology::kEthernet));
569 EXPECT_CALL(*mock_service_, Disconnect(_, _));
570
571 InSequence sequence;
572 EXPECT_CALL(manager_, DeregisterService(Eq(mock_service_)));
573 EXPECT_CALL(manager_, RegisterService(TechnologyEq(Technology::kPPPoE)));
574 EXPECT_CALL(manager_, DeregisterService(TechnologyEq(Technology::kPPPoE)));
575 EXPECT_CALL(manager_, RegisterService(_));
576
577 const vector<pair<bool, Technology::Identifier>> transitions = {
578 {false, Technology::kEthernet},
579 {true, Technology::kPPPoE},
580 {false, Technology::kEthernet},
581 };
582 for (const auto transition : transitions) {
583 Error error;
584 ethernet_->mutable_store()->SetBoolProperty(
585 kPPPoEProperty, transition.first, &error);
586 EXPECT_TRUE(error.IsSuccess());
587 EXPECT_EQ(GetService()->technology(), transition.second);
588 }
589}
590
591#else
592
593TEST_F(EthernetTest, PPPoEDisabled) {
594 Error error;
595 ethernet_->mutable_store()->SetBoolProperty(kPPPoEProperty, true, &error);
596 EXPECT_FALSE(error.IsSuccess());
597}
598
599#endif // DISABLE_PPPOE
600
Paul Stewartced3ad72013-04-03 13:39:25 -0700601} // namespace shill