1 //
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 //
16
17 #include "shill/ethernet/ethernet.h"
18
19 #include <netinet/ether.h>
20 #include <linux/if.h> // NOLINT - Needs definitions from netinet/ether.h
21 #include <linux/sockios.h>
22
23 #include <memory>
24 #include <utility>
25 #include <vector>
26
27 #include <base/memory/ref_counted.h>
28
29 #include "shill/dhcp/mock_dhcp_config.h"
30 #include "shill/dhcp/mock_dhcp_provider.h"
31 #include "shill/ethernet/mock_ethernet_service.h"
32 #include "shill/mock_device_info.h"
33 #include "shill/mock_event_dispatcher.h"
34 #include "shill/mock_log.h"
35 #include "shill/mock_manager.h"
36 #include "shill/mock_metrics.h"
37 #include "shill/mock_service.h"
38 #include "shill/net/mock_rtnl_handler.h"
39 #include "shill/net/mock_sockets.h"
40 #include "shill/nice_mock_control.h"
41 #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"
47 #include "shill/supplicant/mock_supplicant_interface_proxy.h"
48 #include "shill/supplicant/mock_supplicant_process_proxy.h"
49 #include "shill/supplicant/wpa_supplicant.h"
50 #endif // DISABLE_WIRED_8021X
51
52 using std::pair;
53 using std::string;
54 using std::vector;
55 using testing::_;
56 using testing::AnyNumber;
57 using testing::EndsWith;
58 using testing::Eq;
59 using testing::InSequence;
60 using testing::Mock;
61 using testing::NiceMock;
62 using testing::Return;
63 using testing::ReturnRef;
64 using testing::SetArgumentPointee;
65 using testing::StrEq;
66 using testing::StrictMock;
67
68 namespace shill {
69
70 class EthernetTest : public testing::Test {
71 public:
EthernetTest()72 EthernetTest()
73 : metrics_(nullptr),
74 manager_(&control_interface_, nullptr, &metrics_),
75 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)),
85 #if !defined(DISABLE_WIRED_8021X)
86 eap_listener_(new MockEapListener()),
87 mock_eap_service_(new MockService(&control_interface_,
88 &dispatcher_,
89 &metrics_,
90 &manager_)),
91 supplicant_interface_proxy_(
92 new NiceMock<MockSupplicantInterfaceProxy>()),
93 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())) {}
~EthernetTest()99 ~EthernetTest() override {}
100
SetUp()101 void SetUp() override {
102 ethernet_->rtnl_handler_ = &rtnl_handler_;
103 ethernet_->sockets_.reset(mock_sockets_); // Transfers ownership.
104
105 ethernet_->set_dhcp_provider(&dhcp_provider_);
106 ON_CALL(manager_, device_info()).WillByDefault(Return(&device_info_));
107 EXPECT_CALL(manager_, UpdateEnabledTechnologies()).Times(AnyNumber());
108
109 #if !defined(DISABLE_WIRED_8021X)
110 ethernet_->eap_listener_.reset(eap_listener_); // Transfers ownership.
111 EXPECT_CALL(manager_, ethernet_eap_provider())
112 .WillRepeatedly(Return(ðernet_eap_provider_));
113 ethernet_eap_provider_.set_service(mock_eap_service_);
114 // Transfers ownership.
115 ethernet_->supplicant_process_proxy_.reset(supplicant_process_proxy_);
116 #endif // DISABLE_WIRED_8021X
117
118 ON_CALL(*mock_service_, technology())
119 .WillByDefault(Return(Technology::kEthernet));
120 }
121
TearDown()122 void TearDown() override {
123 #if !defined(DISABLE_WIRED_8021X)
124 ethernet_eap_provider_.set_service(nullptr);
125 ethernet_->eap_listener_.reset();
126 #endif // DISABLE_WIRED_8021X
127 ethernet_->set_dhcp_provider(nullptr);
128 ethernet_->sockets_.reset();
129 Mock::VerifyAndClearExpectations(&manager_);
130 ethernet_->Stop(nullptr, EnabledStateChangedCallback());
131 }
132
133 protected:
134 static const char kDeviceName[];
135 static const char kDeviceAddress[];
136 static const char kInterfacePath[];
137 static const int kInterfaceIndex;
138
GetLinkUp()139 bool GetLinkUp() { return ethernet_->link_up_; }
SetLinkUp(bool link_up)140 void SetLinkUp(bool link_up) { ethernet_->link_up_ = link_up; }
GetSelectedService()141 const ServiceRefPtr& GetSelectedService() {
142 return ethernet_->selected_service();
143 }
GetService()144 ServiceRefPtr GetService() { return ethernet_->service_; }
SetService(const EthernetServiceRefPtr & service)145 void SetService(const EthernetServiceRefPtr& service) {
146 ethernet_->service_ = service;
147 }
GetStore()148 const PropertyStore& GetStore() { return ethernet_->store(); }
StartEthernet()149 void StartEthernet() {
150 EXPECT_CALL(rtnl_handler_,
151 SetInterfaceFlags(kInterfaceIndex, IFF_UP, IFF_UP));
152 ethernet_->Start(nullptr, EnabledStateChangedCallback());
153 }
154
155 #if !defined(DISABLE_WIRED_8021X)
GetIsEapAuthenticated()156 bool GetIsEapAuthenticated() { return ethernet_->is_eap_authenticated_; }
SetIsEapAuthenticated(bool is_eap_authenticated)157 void SetIsEapAuthenticated(bool is_eap_authenticated) {
158 ethernet_->is_eap_authenticated_ = is_eap_authenticated;
159 }
GetIsEapDetected()160 bool GetIsEapDetected() { return ethernet_->is_eap_detected_; }
SetIsEapDetected(bool is_eap_detected)161 void SetIsEapDetected(bool is_eap_detected) {
162 ethernet_->is_eap_detected_ = is_eap_detected;
163 }
GetSupplicantInterfaceProxy()164 const SupplicantInterfaceProxyInterface* GetSupplicantInterfaceProxy() {
165 return ethernet_->supplicant_interface_proxy_.get();
166 }
GetSupplicantInterfacePath()167 const string& GetSupplicantInterfacePath() {
168 return ethernet_->supplicant_interface_path_;
169 }
GetSupplicantNetworkPath()170 const string& GetSupplicantNetworkPath() {
171 return ethernet_->supplicant_network_path_;
172 }
SetSupplicantNetworkPath(const string & network_path)173 void SetSupplicantNetworkPath(const string& network_path) {
174 ethernet_->supplicant_network_path_ = network_path;
175 }
InvokeStartSupplicant()176 bool InvokeStartSupplicant() {
177 return ethernet_->StartSupplicant();
178 }
InvokeStopSupplicant()179 void InvokeStopSupplicant() {
180 return ethernet_->StopSupplicant();
181 }
InvokeStartEapAuthentication()182 bool InvokeStartEapAuthentication() {
183 return ethernet_->StartEapAuthentication();
184 }
StartSupplicant()185 void StartSupplicant() {
186 MockSupplicantInterfaceProxy* interface_proxy =
187 ExpectCreateSupplicantInterfaceProxy();
188 EXPECT_CALL(*supplicant_process_proxy_, CreateInterface(_, _))
189 .WillOnce(DoAll(SetArgumentPointee<1>(string(kInterfacePath)),
190 Return(true)));
191 EXPECT_TRUE(InvokeStartSupplicant());
192 EXPECT_EQ(interface_proxy, GetSupplicantInterfaceProxy());
193 EXPECT_EQ(kInterfacePath, GetSupplicantInterfacePath());
194 }
TriggerOnEapDetected()195 void TriggerOnEapDetected() { ethernet_->OnEapDetected(); }
TriggerCertification(const string & subject,uint32_t depth)196 void TriggerCertification(const string& subject, uint32_t depth) {
197 ethernet_->CertificationTask(subject, depth);
198 }
TriggerTryEapAuthentication()199 void TriggerTryEapAuthentication() {
200 ethernet_->TryEapAuthenticationTask();
201 }
202
ExpectCreateSupplicantInterfaceProxy()203 MockSupplicantInterfaceProxy* ExpectCreateSupplicantInterfaceProxy() {
204 EXPECT_CALL(control_interface_,
205 CreateSupplicantInterfaceProxy(_, kInterfacePath))
206 .WillOnce(ReturnAndReleasePointee(&supplicant_interface_proxy_));
207 return supplicant_interface_proxy_.get();
208 }
209 #endif // DISABLE_WIRED_8021X
210
211 StrictMock<MockEventDispatcher> dispatcher_;
212 NiceMockControl control_interface_;
213 NiceMock<MockMetrics> metrics_;
214 MockManager manager_;
215 MockDeviceInfo device_info_;
216 EthernetRefPtr ethernet_;
217 MockDHCPProvider dhcp_provider_;
218 scoped_refptr<MockDHCPConfig> dhcp_config_;
219
220 #if !defined(DISABLE_WIRED_8021X)
221 MockEthernetEapProvider ethernet_eap_provider_;
222
223 // Owned by Ethernet instance, but tracked here for expectations.
224 MockEapListener* eap_listener_;
225
226 scoped_refptr<MockService> mock_eap_service_;
227 std::unique_ptr<MockSupplicantInterfaceProxy> supplicant_interface_proxy_;
228 MockSupplicantProcessProxy* supplicant_process_proxy_;
229 #endif // DISABLE_WIRED_8021X
230
231 // Owned by Ethernet instance, but tracked here for expectations.
232 MockSockets* mock_sockets_;
233
234 MockRTNLHandler rtnl_handler_;
235 scoped_refptr<MockEthernetService> mock_service_;
236 };
237
238 // static
239 const char EthernetTest::kDeviceName[] = "eth0";
240 const char EthernetTest::kDeviceAddress[] = "000102030405";
241 const char EthernetTest::kInterfacePath[] = "/interface/path";
242 const int EthernetTest::kInterfaceIndex = 123;
243
TEST_F(EthernetTest,Construct)244 TEST_F(EthernetTest, Construct) {
245 EXPECT_FALSE(GetLinkUp());
246 #if !defined(DISABLE_WIRED_8021X)
247 EXPECT_FALSE(GetIsEapAuthenticated());
248 EXPECT_FALSE(GetIsEapDetected());
249 EXPECT_TRUE(GetStore().Contains(kEapAuthenticationCompletedProperty));
250 EXPECT_TRUE(GetStore().Contains(kEapAuthenticatorDetectedProperty));
251 #endif // DISABLE_WIRED_8021X
252 EXPECT_NE(nullptr, GetService().get());
253 }
254
TEST_F(EthernetTest,StartStop)255 TEST_F(EthernetTest, StartStop) {
256 Service* service = GetService().get();
257 EXPECT_CALL(manager_, RegisterService(Eq(service)));
258 StartEthernet();
259
260 EXPECT_CALL(manager_, DeregisterService(Eq(service)));
261 ethernet_->Stop(nullptr, EnabledStateChangedCallback());
262
263 // Ethernet device retains its service.
264 EXPECT_NE(nullptr, GetService());
265 }
266
TEST_F(EthernetTest,LinkEvent)267 TEST_F(EthernetTest, LinkEvent) {
268 StartEthernet();
269 SetService(mock_service_);
270
271 // Link-down event while already down.
272 EXPECT_CALL(manager_, DeregisterService(_)).Times(0);
273 #if !defined(DISABLE_WIRED_8021X)
274 EXPECT_CALL(*eap_listener_, Start()).Times(0);
275 #endif // DISABLE_WIRED_8021X
276 ethernet_->LinkEvent(0, IFF_LOWER_UP);
277 EXPECT_FALSE(GetLinkUp());
278 #if !defined(DISABLE_WIRED_8021X)
279 EXPECT_FALSE(GetIsEapDetected());
280 #endif // DISABLE_WIRED_8021X
281 Mock::VerifyAndClearExpectations(&manager_);
282
283 // Link-up event while down.
284 int kFakeFd = 789;
285 EXPECT_CALL(manager_, UpdateService(IsRefPtrTo(mock_service_)));
286 EXPECT_CALL(*mock_service_, OnVisibilityChanged());
287 #if !defined(DISABLE_WIRED_8021X)
288 EXPECT_CALL(*eap_listener_, Start());
289 #endif // DISABLE_WIRED_8021X
290 EXPECT_CALL(*mock_sockets_, Socket(_, _, _)).WillOnce(Return(kFakeFd));
291 EXPECT_CALL(*mock_sockets_, Ioctl(kFakeFd, SIOCETHTOOL, _));
292 EXPECT_CALL(*mock_sockets_, Close(kFakeFd));
293 ethernet_->LinkEvent(IFF_LOWER_UP, 0);
294 EXPECT_TRUE(GetLinkUp());
295 #if !defined(DISABLE_WIRED_8021X)
296 EXPECT_FALSE(GetIsEapDetected());
297 #endif // DISABLE_WIRED_8021X
298 Mock::VerifyAndClearExpectations(&manager_);
299 Mock::VerifyAndClearExpectations(mock_service_.get());
300
301 // Link-up event while already up.
302 EXPECT_CALL(manager_, UpdateService(_)).Times(0);
303 EXPECT_CALL(*mock_service_, OnVisibilityChanged()).Times(0);
304 #if !defined(DISABLE_WIRED_8021X)
305 EXPECT_CALL(*eap_listener_, Start()).Times(0);
306 #endif // DISABLE_WIRED_8021X
307 ethernet_->LinkEvent(IFF_LOWER_UP, 0);
308 EXPECT_TRUE(GetLinkUp());
309 #if !defined(DISABLE_WIRED_8021X)
310 EXPECT_FALSE(GetIsEapDetected());
311 #endif // DISABLE_WIRED_8021X
312 Mock::VerifyAndClearExpectations(&manager_);
313 Mock::VerifyAndClearExpectations(mock_service_.get());
314
315 // Link-down event while up.
316 #if !defined(DISABLE_WIRED_8021X)
317 SetIsEapDetected(true);
318 // 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(ðernet_eap_provider_));
322 EXPECT_CALL(ethernet_eap_provider_,
323 ClearCredentialChangeCallback(ethernet_.get()));
324 EXPECT_CALL(*eap_listener_, Stop());
325 #endif // DISABLE_WIRED_8021X
326 EXPECT_CALL(manager_, UpdateService(IsRefPtrTo(GetService().get())));
327 EXPECT_CALL(*mock_service_, OnVisibilityChanged());
328 ethernet_->LinkEvent(0, IFF_LOWER_UP);
329 EXPECT_FALSE(GetLinkUp());
330 #if !defined(DISABLE_WIRED_8021X)
331 EXPECT_FALSE(GetIsEapDetected());
332 #endif // DISABLE_WIRED_8021X
333
334 // Restore this expectation during shutdown.
335 EXPECT_CALL(manager_, UpdateEnabledTechnologies()).Times(AnyNumber());
336 }
337
TEST_F(EthernetTest,ConnectToLinkDown)338 TEST_F(EthernetTest, ConnectToLinkDown) {
339 StartEthernet();
340 SetService(mock_service_);
341 SetLinkUp(false);
342 EXPECT_EQ(nullptr, GetSelectedService().get());
343 EXPECT_CALL(dhcp_provider_, CreateIPv4Config(_, _, _, _)).Times(0);
344 EXPECT_CALL(*dhcp_config_.get(), RequestIP()).Times(0);
345 EXPECT_CALL(dispatcher_, PostTask(_)).Times(0);
346 EXPECT_CALL(*mock_service_, SetState(_)).Times(0);
347 ethernet_->ConnectTo(mock_service_.get());
348 EXPECT_EQ(nullptr, GetSelectedService().get());
349 }
350
TEST_F(EthernetTest,ConnectToFailure)351 TEST_F(EthernetTest, ConnectToFailure) {
352 StartEthernet();
353 SetService(mock_service_);
354 SetLinkUp(true);
355 EXPECT_EQ(nullptr, GetSelectedService().get());
356 EXPECT_CALL(dhcp_provider_, CreateIPv4Config(_, _, _, _)).
357 WillOnce(Return(dhcp_config_));
358 EXPECT_CALL(*dhcp_config_.get(), RequestIP()).WillOnce(Return(false));
359 EXPECT_CALL(dispatcher_, PostTask(_)); // Posts ConfigureStaticIPTask.
360 EXPECT_CALL(*mock_service_, SetState(Service::kStateFailure));
361 ethernet_->ConnectTo(mock_service_.get());
362 EXPECT_EQ(mock_service_, GetSelectedService().get());
363 }
364
TEST_F(EthernetTest,ConnectToSuccess)365 TEST_F(EthernetTest, ConnectToSuccess) {
366 StartEthernet();
367 SetService(mock_service_);
368 SetLinkUp(true);
369 EXPECT_EQ(nullptr, GetSelectedService().get());
370 EXPECT_CALL(dhcp_provider_, CreateIPv4Config(_, _, _, _)).
371 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());
377 Mock::VerifyAndClearExpectations(mock_service_.get());
378
379 EXPECT_CALL(*mock_service_, SetState(Service::kStateIdle));
380 ethernet_->DisconnectFrom(mock_service_.get());
381 EXPECT_EQ(nullptr, GetSelectedService().get());
382 }
383
384 #if !defined(DISABLE_WIRED_8021X)
TEST_F(EthernetTest,OnEapDetected)385 TEST_F(EthernetTest, OnEapDetected) {
386 EXPECT_FALSE(GetIsEapDetected());
387 EXPECT_CALL(*eap_listener_, Stop());
388 EXPECT_CALL(ethernet_eap_provider_,
389 SetCredentialChangeCallback(ethernet_.get(), _));
390 EXPECT_CALL(dispatcher_, PostTask(_)); // Posts TryEapAuthenticationTask.
391 TriggerOnEapDetected();
392 EXPECT_TRUE(GetIsEapDetected());
393 }
394
TEST_F(EthernetTest,TryEapAuthenticationNotConnectableNotAuthenticated)395 TEST_F(EthernetTest, TryEapAuthenticationNotConnectableNotAuthenticated) {
396 SetService(mock_service_);
397 EXPECT_CALL(*mock_eap_service_, Is8021xConnectable()).WillOnce(Return(false));
398 NiceScopedMockLog log;
399 EXPECT_CALL(log, Log(logging::LOG_INFO, _,
400 EndsWith("EAP Service lacks 802.1X credentials; "
401 "not doing EAP authentication.")));
402 TriggerTryEapAuthentication();
403 SetService(nullptr);
404 }
405
TEST_F(EthernetTest,TryEapAuthenticationNotConnectableAuthenticated)406 TEST_F(EthernetTest, TryEapAuthenticationNotConnectableAuthenticated) {
407 SetService(mock_service_);
408 SetIsEapAuthenticated(true);
409 EXPECT_CALL(*mock_eap_service_, Is8021xConnectable()).WillOnce(Return(false));
410 NiceScopedMockLog log;
411 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
412 EXPECT_CALL(log, Log(logging::LOG_INFO, _,
413 EndsWith("EAP Service lost 802.1X credentials; "
414 "terminating EAP authentication.")));
415 TriggerTryEapAuthentication();
416 EXPECT_FALSE(GetIsEapAuthenticated());
417 }
418
TEST_F(EthernetTest,TryEapAuthenticationEapNotDetected)419 TEST_F(EthernetTest, TryEapAuthenticationEapNotDetected) {
420 SetService(mock_service_);
421 EXPECT_CALL(*mock_eap_service_, Is8021xConnectable()).WillOnce(Return(true));
422 NiceScopedMockLog log;
423 EXPECT_CALL(log, Log(logging::LOG_WARNING, _,
424 EndsWith("EAP authenticator not detected; "
425 "not doing EAP authentication.")));
426 TriggerTryEapAuthentication();
427 }
428
TEST_F(EthernetTest,StartSupplicant)429 TEST_F(EthernetTest, StartSupplicant) {
430 // Save the mock proxy pointers before the Ethernet instance accepts it.
431 MockSupplicantInterfaceProxy* interface_proxy =
432 supplicant_interface_proxy_.get();
433 MockSupplicantProcessProxy* process_proxy = supplicant_process_proxy_;
434
435 StartSupplicant();
436
437 // Starting it again should not invoke another call to create an interface.
438 Mock::VerifyAndClearExpectations(process_proxy);
439 EXPECT_CALL(*process_proxy, CreateInterface(_, _)).Times(0);
440 EXPECT_TRUE(InvokeStartSupplicant());
441
442 // Also, the mock pointers should remain; if the MockProxyFactory was
443 // invoked again, they would be nullptr.
444 EXPECT_EQ(interface_proxy, GetSupplicantInterfaceProxy());
445 EXPECT_EQ(kInterfacePath, GetSupplicantInterfacePath());
446 }
447
TEST_F(EthernetTest,StartSupplicantWithInterfaceExistsException)448 TEST_F(EthernetTest, StartSupplicantWithInterfaceExistsException) {
449 MockSupplicantProcessProxy* process_proxy = supplicant_process_proxy_;
450 MockSupplicantInterfaceProxy* interface_proxy =
451 ExpectCreateSupplicantInterfaceProxy();
452 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)));
456 EXPECT_TRUE(InvokeStartSupplicant());
457 EXPECT_EQ(interface_proxy, GetSupplicantInterfaceProxy());
458 EXPECT_EQ(kInterfacePath, GetSupplicantInterfacePath());
459 }
460
TEST_F(EthernetTest,StartSupplicantWithUnknownException)461 TEST_F(EthernetTest, StartSupplicantWithUnknownException) {
462 MockSupplicantProcessProxy* process_proxy = supplicant_process_proxy_;
463 EXPECT_CALL(*process_proxy, CreateInterface(_, _)).WillOnce(Return(false));
464 EXPECT_CALL(*process_proxy, GetInterface(kDeviceName, _))
465 .WillOnce(Return(false));
466 EXPECT_FALSE(InvokeStartSupplicant());
467 EXPECT_EQ(nullptr, GetSupplicantInterfaceProxy());
468 EXPECT_EQ("", GetSupplicantInterfacePath());
469 }
470
TEST_F(EthernetTest,StartEapAuthentication)471 TEST_F(EthernetTest, StartEapAuthentication) {
472 MockSupplicantInterfaceProxy* interface_proxy =
473 supplicant_interface_proxy_.get();
474
475 StartSupplicant();
476 SetService(mock_service_);
477
478 EXPECT_CALL(*mock_service_, ClearEAPCertification());
479 MockEapCredentials mock_eap_credentials;
480 EXPECT_CALL(*mock_eap_service_, eap())
481 .WillOnce(Return(&mock_eap_credentials));
482 EXPECT_CALL(mock_eap_credentials, PopulateSupplicantProperties(_, _));
483 EXPECT_CALL(*interface_proxy, RemoveNetwork(_)).Times(0);
484 EXPECT_CALL(*interface_proxy, AddNetwork(_, _))
485 .WillOnce(Return(false));
486 EXPECT_CALL(*interface_proxy, SelectNetwork(_)).Times(0);
487 EXPECT_CALL(*interface_proxy, EAPLogon()).Times(0);
488 EXPECT_FALSE(InvokeStartEapAuthentication());
489 Mock::VerifyAndClearExpectations(mock_service_.get());
490 Mock::VerifyAndClearExpectations(mock_eap_service_.get());
491 Mock::VerifyAndClearExpectations(interface_proxy);
492 EXPECT_EQ("", GetSupplicantNetworkPath());
493
494 EXPECT_CALL(*mock_service_, ClearEAPCertification());
495 EXPECT_CALL(*interface_proxy, RemoveNetwork(_)).Times(0);
496 EXPECT_CALL(*mock_eap_service_, eap())
497 .WillOnce(Return(&mock_eap_credentials));
498 EXPECT_CALL(mock_eap_credentials, PopulateSupplicantProperties(_, _));
499 const char kFirstNetworkPath[] = "/network/first-path";
500 EXPECT_CALL(*interface_proxy, AddNetwork(_, _))
501 .WillOnce(
502 DoAll(SetArgumentPointee<1>(string(kFirstNetworkPath)),
503 Return(true)));
504 EXPECT_CALL(*interface_proxy, SelectNetwork(StrEq(kFirstNetworkPath)));
505 EXPECT_CALL(*interface_proxy, EAPLogon());
506 EXPECT_TRUE(InvokeStartEapAuthentication());
507 Mock::VerifyAndClearExpectations(mock_service_.get());
508 Mock::VerifyAndClearExpectations(mock_eap_service_.get());
509 Mock::VerifyAndClearExpectations(&mock_eap_credentials);
510 Mock::VerifyAndClearExpectations(interface_proxy);
511 EXPECT_EQ(kFirstNetworkPath, GetSupplicantNetworkPath());
512
513 EXPECT_CALL(*mock_service_, ClearEAPCertification());
514 EXPECT_CALL(*interface_proxy, RemoveNetwork(StrEq(kFirstNetworkPath)))
515 .WillOnce(Return(true));
516 EXPECT_CALL(*mock_eap_service_, eap())
517 .WillOnce(Return(&mock_eap_credentials));
518 EXPECT_CALL(mock_eap_credentials, PopulateSupplicantProperties(_, _));
519 const char kSecondNetworkPath[] = "/network/second-path";
520 EXPECT_CALL(*interface_proxy, AddNetwork(_, _))
521 .WillOnce(
522 DoAll(SetArgumentPointee<1>(string(kSecondNetworkPath)),
523 Return(true)));
524 EXPECT_CALL(*interface_proxy, SelectNetwork(StrEq(kSecondNetworkPath)));
525 EXPECT_CALL(*interface_proxy, EAPLogon());
526 EXPECT_TRUE(InvokeStartEapAuthentication());
527 EXPECT_EQ(kSecondNetworkPath, GetSupplicantNetworkPath());
528 }
529
TEST_F(EthernetTest,StopSupplicant)530 TEST_F(EthernetTest, StopSupplicant) {
531 MockSupplicantProcessProxy* process_proxy = supplicant_process_proxy_;
532 MockSupplicantInterfaceProxy* interface_proxy =
533 supplicant_interface_proxy_.get();
534 StartSupplicant();
535 SetIsEapAuthenticated(true);
536 SetSupplicantNetworkPath("/network/1");
537 EXPECT_CALL(*interface_proxy, EAPLogoff()).WillOnce(Return(true));
538 EXPECT_CALL(*process_proxy, RemoveInterface(StrEq(kInterfacePath)))
539 .WillOnce(Return(true));
540 InvokeStopSupplicant();
541 EXPECT_EQ(nullptr, GetSupplicantInterfaceProxy());
542 EXPECT_EQ("", GetSupplicantInterfacePath());
543 EXPECT_EQ("", GetSupplicantNetworkPath());
544 EXPECT_FALSE(GetIsEapAuthenticated());
545 }
546
TEST_F(EthernetTest,Certification)547 TEST_F(EthernetTest, Certification) {
548 const string kSubjectName("subject-name");
549 const uint32_t kDepth = 123;
550 // 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 }
556 #endif // DISABLE_WIRED_8021X
557
558 #if !defined(DISABLE_PPPOE)
559
560 MATCHER_P(TechnologyEq, technology, "") {
561 return arg->technology() == technology;
562 }
563
TEST_F(EthernetTest,TogglePPPoE)564 TEST_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
TEST_F(EthernetTest,PPPoEDisabled)593 TEST_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
601 } // namespace shill
602