blob: dad123a79eb70b2c8c3c5058ed1a62421bc7bd37 [file] [log] [blame]
Paul Stewartced3ad72013-04-03 13:39:25 -07001// Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "shill/ethernet.h"
6
7#include <netinet/ether.h>
8#include <linux/if.h> // Needs definitions from netinet/ether.h
9
10#include <base/memory/ref_counted.h>
11#include <base/memory/scoped_ptr.h>
12#include <gmock/gmock.h>
13#include <gtest/gtest.h>
14
15#include "shill/mock_device_info.h"
16#include "shill/mock_dhcp_config.h"
17#include "shill/mock_dhcp_provider.h"
18#include "shill/mock_eap_listener.h"
19#include "shill/mock_event_dispatcher.h"
20#include "shill/mock_glib.h"
21#include "shill/mock_manager.h"
22#include "shill/mock_metrics.h"
23#include "shill/mock_rtnl_handler.h"
24#include "shill/nice_mock_control.h"
25
26using testing::_;
27using testing::AnyNumber;
Gaurav Shah25ee2502013-04-08 17:55:01 -070028using testing::Eq;
Paul Stewartced3ad72013-04-03 13:39:25 -070029using testing::Mock;
30using testing::Return;
31using testing::StrictMock;
32
33namespace shill {
34
35class EthernetTest : public testing::Test {
36 public:
37 EthernetTest()
38 : metrics_(NULL),
39 manager_(&control_interface_, NULL, &metrics_, &glib_),
40 device_info_(&control_interface_, &dispatcher_, &metrics_, &manager_),
41 ethernet_(new Ethernet(&control_interface_,
42 &dispatcher_,
43 &metrics_,
44 &manager_,
45 kDeviceName,
46 kDeviceAddress,
47 kInterfaceIndex)),
48 dhcp_config_(new MockDHCPConfig(&control_interface_,
49 kDeviceName)),
50 eap_listener_(new MockEapListener()) {
51 ON_CALL(dhcp_provider_, CreateConfig(_, _, _, _)).
52 WillByDefault(Return(dhcp_config_));
53 ON_CALL(*dhcp_config_.get(), RequestIP()).
54 WillByDefault(Return(true));
55 }
56
57 virtual void SetUp() {
58 ethernet_->rtnl_handler_ = &rtnl_handler_;
59 // Transfers ownership.
60 ethernet_->eap_listener_.reset(eap_listener_);
61
62 ethernet_->set_dhcp_provider(&dhcp_provider_);
63 ON_CALL(manager_, device_info()).WillByDefault(Return(&device_info_));
64 EXPECT_CALL(manager_, UpdateEnabledTechnologies()).Times(AnyNumber());
65 }
66
67 virtual void TearDown() {
68 ethernet_->set_dhcp_provider(NULL);
69 ethernet_->eap_listener_.reset();
70 }
71
72 protected:
73 static const char kDeviceName[];
74 static const char kDeviceAddress[];
75 static const int kInterfaceIndex;
76
77 void StartEthernet() {
78 EXPECT_CALL(rtnl_handler_,
79 SetInterfaceFlags(kInterfaceIndex, IFF_UP, IFF_UP));
80 ethernet_->Start(NULL, EnabledStateChangedCallback());
81 }
82 bool GetLinkUp() { return ethernet_->link_up_; }
83 bool GetIsEapDetected() { return ethernet_->is_eap_detected_; }
84 void SetIsEapDetected(bool is_eap_detected) {
85 ethernet_->is_eap_detected_ = is_eap_detected;
86 }
87 const PropertyStore &GetStore() { return ethernet_->store(); }
88 const ServiceRefPtr &GetService() { return ethernet_->service_; }
89 void TriggerOnEapDetected() { ethernet_->OnEapDetected(); }
90
91 StrictMock<MockEventDispatcher> dispatcher_;
92 MockGLib glib_;
93 NiceMockControl control_interface_;
94 MockMetrics metrics_;
95 MockManager manager_;
96 MockDeviceInfo device_info_;
97 EthernetRefPtr ethernet_;
98 MockDHCPProvider dhcp_provider_;
99 scoped_refptr<MockDHCPConfig> dhcp_config_;
100 MockRTNLHandler rtnl_handler_;
101 // Owned by Ethernet instance, but tracked here for expectations.
102 MockEapListener *eap_listener_;
103};
104
105// static
106const char EthernetTest::kDeviceName[] = "eth0";
107const char EthernetTest::kDeviceAddress[] = "000102030405";
108const int EthernetTest::kInterfaceIndex = 123;
109
110TEST_F(EthernetTest, Construct) {
111 EXPECT_FALSE(GetLinkUp());
112 EXPECT_FALSE(GetIsEapDetected());
113 EXPECT_TRUE(GetStore().Contains(kEapAuthenticatorDetectedProperty));
114 EXPECT_EQ(NULL, GetService().get());
115}
116
117TEST_F(EthernetTest, StartStop) {
Gaurav Shah25ee2502013-04-08 17:55:01 -0700118 StartEthernet();
119
Paul Stewartced3ad72013-04-03 13:39:25 -0700120 EXPECT_FALSE(GetService().get() == NULL);
121
Gaurav Shah25ee2502013-04-08 17:55:01 -0700122 Service* service = GetService().get();
123 EXPECT_CALL(manager_, DeregisterService(Eq(service)));
Paul Stewartced3ad72013-04-03 13:39:25 -0700124 ethernet_->Stop(NULL, EnabledStateChangedCallback());
125 EXPECT_EQ(NULL, GetService().get());
126}
127
128TEST_F(EthernetTest, LinkEvent) {
129 StartEthernet();
130
131 // Link-down event while already down.
132 EXPECT_CALL(manager_, DeregisterService(_)).Times(0);
133 EXPECT_CALL(*eap_listener_, Start()).Times(0);
134 ethernet_->LinkEvent(0, IFF_LOWER_UP);
135 EXPECT_FALSE(GetLinkUp());
136 EXPECT_FALSE(GetIsEapDetected());
137 Mock::VerifyAndClearExpectations(&manager_);
138
139 // Link-up event while down.
140 EXPECT_CALL(manager_, RegisterService(GetService()));
141 EXPECT_CALL(*eap_listener_, Start());
142 ethernet_->LinkEvent(IFF_LOWER_UP, 0);
143 EXPECT_TRUE(GetLinkUp());
144 EXPECT_FALSE(GetIsEapDetected());
145 Mock::VerifyAndClearExpectations(&manager_);
146
147 // Link-up event while already up.
148 EXPECT_CALL(manager_, RegisterService(GetService())).Times(0);
149 EXPECT_CALL(*eap_listener_, Start()).Times(0);
150 ethernet_->LinkEvent(IFF_LOWER_UP, 0);
151 EXPECT_TRUE(GetLinkUp());
152 EXPECT_FALSE(GetIsEapDetected());
153 Mock::VerifyAndClearExpectations(&manager_);
154
155 // Link-down event while up.
156 SetIsEapDetected(true);
157 EXPECT_CALL(manager_, DeregisterService(GetService()));
158 EXPECT_CALL(*eap_listener_, Stop());
159 ethernet_->LinkEvent(0, IFF_LOWER_UP);
160 EXPECT_FALSE(GetLinkUp());
161 EXPECT_FALSE(GetIsEapDetected());
162
163 // Restore this expectation during shutdown.
164 EXPECT_CALL(manager_, UpdateEnabledTechnologies()).Times(AnyNumber());
165}
166
167TEST_F(EthernetTest, OnEapDetected) {
168 EXPECT_FALSE(GetIsEapDetected());
169 EXPECT_CALL(*eap_listener_, Stop());
170 TriggerOnEapDetected();
171 EXPECT_TRUE(GetIsEapDetected());
172}
173
174} // namespace shill