1 // 2 // Copyright (C) 2015 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/pppoe/pppoe_service.h" 18 19 #include <map> 20 #include <string> 21 22 #include <gmock/gmock.h> 23 #include <gtest/gtest.h> 24 25 #include <base/memory/ref_counted.h> 26 27 #include "shill/ethernet/mock_ethernet.h" 28 #include "shill/mock_control.h" 29 #include "shill/mock_device_info.h" 30 #include "shill/mock_external_task.h" 31 #include "shill/mock_manager.h" 32 #include "shill/mock_metrics.h" 33 #include "shill/mock_ppp_device.h" 34 #include "shill/mock_ppp_device_factory.h" 35 #include "shill/mock_process_manager.h" 36 #include "shill/service.h" 37 #include "shill/test_event_dispatcher.h" 38 #include "shill/testing.h" 39 40 using std::map; 41 using std::string; 42 using testing::Mock; 43 using testing::NiceMock; 44 using testing::Return; 45 using testing::StrEq; 46 using testing::_; 47 48 namespace shill { 49 50 class PPPoEServiceTest : public testing::Test { 51 public: 52 PPPoEServiceTest() 53 : metrics_(&dispatcher_), 54 manager_(&control_interface_, &dispatcher_, &metrics_), 55 ethernet_(new MockEthernet(&control_interface_, 56 &dispatcher_, 57 &metrics_, 58 &manager_, 59 "ethernet", 60 "aabbccddeeff", 61 0)), 62 device_info_(&control_interface_, 63 &dispatcher_, 64 &metrics_, 65 &manager_), 66 service_(new PPPoEService(&control_interface_, 67 &dispatcher_, 68 &metrics_, 69 &manager_, 70 ethernet_->weak_ptr_factory_.GetWeakPtr())) { 71 manager_.set_mock_device_info(&device_info_); 72 service_->process_manager_ = &process_manager_; 73 } 74 75 ~PPPoEServiceTest() override { 76 Error error; 77 service_->Disconnect(&error, __func__); 78 dispatcher_.DispatchPendingEvents(); 79 } 80 81 protected: 82 void FakeConnectionSuccess() { 83 EXPECT_CALL(*ethernet_, link_up()) 84 .WillRepeatedly(Return(true)); 85 EXPECT_CALL(process_manager_, StartProcess(_, _, _, _, _, _)) 86 .WillOnce(Return(0)); 87 Error error; 88 service_->Connect(&error, "in test"); 89 EXPECT_TRUE(error.IsSuccess()); 90 } 91 92 EventDispatcherForTest dispatcher_; 93 MockMetrics metrics_; 94 MockControl control_interface_; 95 MockProcessManager process_manager_; 96 MockManager manager_; 97 scoped_refptr<MockEthernet> ethernet_; 98 MockDeviceInfo device_info_; 99 100 scoped_refptr<PPPoEService> service_; 101 102 private: 103 DISALLOW_COPY_AND_ASSIGN(PPPoEServiceTest); 104 }; 105 106 MATCHER_P(LinkNamed, name, "") { 107 return arg->link_name() == name; 108 } 109 110 TEST_F(PPPoEServiceTest, AuthenticationFailure) { 111 EXPECT_CALL(*ethernet_, link_up()).WillRepeatedly(Return(true)); 112 FakeConnectionSuccess(); 113 map<string, string> empty_dict; 114 service_->Notify(kPPPReasonAuthenticating, empty_dict); 115 service_->Notify(kPPPReasonDisconnect, empty_dict); 116 EXPECT_EQ(service_->state(), Service::kStateFailure); 117 EXPECT_EQ(service_->failure(), Service::kFailurePPPAuth); 118 } 119 120 TEST_F(PPPoEServiceTest, DisconnectBeforeConnect) { 121 EXPECT_CALL(*ethernet_, link_up()).WillRepeatedly(Return(true)); 122 FakeConnectionSuccess(); 123 map<string, string> empty_dict; 124 service_->Notify(kPPPReasonAuthenticating, empty_dict); 125 service_->Notify(kPPPReasonAuthenticated, empty_dict); 126 service_->Notify(kPPPReasonDisconnect, empty_dict); 127 EXPECT_EQ(service_->state(), Service::kStateFailure); 128 EXPECT_EQ(service_->failure(), Service::kFailureUnknown); 129 } 130 131 TEST_F(PPPoEServiceTest, ConnectFailsWhenEthernetLinkDown) { 132 EXPECT_CALL(*ethernet_, link_up()).WillRepeatedly(Return(false)); 133 134 Error error; 135 service_->Connect(&error, "in test"); 136 EXPECT_FALSE(error.IsSuccess()); 137 } 138 139 TEST_F(PPPoEServiceTest, OnPPPConnected) { 140 // Setup device factory. 141 MockPPPDeviceFactory* factory = MockPPPDeviceFactory::GetInstance(); 142 service_->ppp_device_factory_ = factory; 143 144 static const char kLinkName[] = "ppp0"; 145 map<string, string> params = { {kPPPInterfaceName, kLinkName} }; 146 MockPPPDevice* device = new MockPPPDevice( 147 &control_interface_, &dispatcher_, &metrics_, &manager_, kLinkName, 0); 148 149 EXPECT_CALL(device_info_, GetIndex(StrEq(kLinkName))).WillOnce(Return(0)); 150 EXPECT_CALL(*factory, CreatePPPDevice(_, _, _, _, _, _)) 151 .WillOnce(Return(device)); 152 EXPECT_CALL(device_info_, RegisterDevice(IsRefPtrTo(device))); 153 EXPECT_CALL(*device, SetEnabled(true)); 154 EXPECT_CALL(*device, SelectService(_)); 155 EXPECT_CALL(*device, UpdateIPConfigFromPPP(params, false)); 156 #ifndef DISABLE_DHCPV6 157 EXPECT_CALL(manager_, IsDHCPv6EnabledForDevice(StrEq(kLinkName))) 158 .WillOnce(Return(true)); 159 EXPECT_CALL(*device, AcquireIPv6Config()); 160 #endif // DISABLE_DHCPV6 161 EXPECT_CALL(manager_, OnInnerDevicesChanged()); 162 service_->OnPPPConnected(params); 163 Mock::VerifyAndClearExpectations(&manager_); 164 } 165 166 TEST_F(PPPoEServiceTest, Connect) { 167 static const char kLinkName[] = "ppp0"; 168 169 EXPECT_CALL(*ethernet_, link_up()).WillRepeatedly(Return(true)); 170 EXPECT_CALL(device_info_, GetIndex(StrEq(kLinkName))).WillOnce(Return(0)); 171 EXPECT_CALL(device_info_, RegisterDevice(LinkNamed(kLinkName))); 172 173 FakeConnectionSuccess(); 174 map<string, string> empty_dict; 175 service_->Notify(kPPPReasonAuthenticating, empty_dict); 176 service_->Notify(kPPPReasonAuthenticated, empty_dict); 177 178 map<string, string> connect_dict = { 179 {kPPPInterfaceName, kLinkName}, 180 }; 181 service_->Notify(kPPPReasonConnect, connect_dict); 182 EXPECT_EQ(service_->state(), Service::kStateOnline); 183 } 184 185 TEST_F(PPPoEServiceTest, Disconnect) { 186 FakeConnectionSuccess(); 187 188 auto weak_ptr = service_->weak_ptr_factory_.GetWeakPtr(); 189 MockExternalTask* pppd = new MockExternalTask( 190 &control_interface_, &process_manager_, weak_ptr, 191 base::Bind(&PPPoEService::OnPPPDied, weak_ptr)); 192 service_->pppd_.reset(pppd); 193 194 MockPPPDevice* ppp_device = new MockPPPDevice( 195 &control_interface_, &dispatcher_, &metrics_, &manager_, "ppp0", 0); 196 service_->ppp_device_ = ppp_device; 197 198 EXPECT_CALL(*ppp_device, DropConnection()); 199 EXPECT_CALL(*pppd, OnDelete()); 200 201 { 202 Error error; 203 service_->Disconnect(&error, "in test"); 204 EXPECT_TRUE(error.IsSuccess()); 205 } 206 } 207 208 TEST_F(PPPoEServiceTest, DisconnectDuringAssociation) { 209 FakeConnectionSuccess(); 210 211 Error error; 212 service_->Disconnect(&error, "in test"); 213 EXPECT_TRUE(error.IsSuccess()); 214 215 EXPECT_EQ(service_->state(), Service::kStateIdle); 216 } 217 218 } // namespace shill 219