Home | History | Annotate | Download | only in pppoe
      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