• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&ethernet_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(&ethernet_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