Home | History | Annotate | Download | only in vpn
      1 //
      2 // Copyright (C) 2012 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/vpn/vpn_service.h"
     18 
     19 #include <string>
     20 
     21 #if defined(__ANDROID__)
     22 #include <dbus/service_constants.h>
     23 #else
     24 #include <chromeos/dbus/service_constants.h>
     25 #endif  // __ANDROID__
     26 #include <gtest/gtest.h>
     27 
     28 #include "shill/error.h"
     29 #include "shill/mock_adaptors.h"
     30 #include "shill/mock_connection.h"
     31 #include "shill/mock_device_info.h"
     32 #include "shill/mock_manager.h"
     33 #include "shill/mock_metrics.h"
     34 #include "shill/mock_profile.h"
     35 #include "shill/mock_store.h"
     36 #include "shill/net/mock_sockets.h"
     37 #include "shill/nice_mock_control.h"
     38 #include "shill/service_property_change_test.h"
     39 #include "shill/vpn/mock_vpn_driver.h"
     40 #include "shill/vpn/mock_vpn_provider.h"
     41 
     42 using std::string;
     43 using testing::_;
     44 using testing::Mock;
     45 using testing::NiceMock;
     46 using testing::Return;
     47 using testing::ReturnRef;
     48 using testing::ReturnRefOfCopy;
     49 
     50 namespace shill {
     51 
     52 class VPNServiceTest : public testing::Test {
     53  public:
     54   VPNServiceTest()
     55       : interface_name_("test-interface"),
     56         driver_(new MockVPNDriver()),
     57         manager_(&control_, nullptr, nullptr),
     58         metrics_(nullptr),
     59         device_info_(&control_, nullptr, nullptr, nullptr),
     60         connection_(new NiceMock<MockConnection>(&device_info_)),
     61         sockets_(new MockSockets()),
     62         service_(new VPNService(&control_, nullptr, &metrics_, &manager_,
     63                                 driver_)) {
     64     service_->sockets_.reset(sockets_);  // Passes ownership.
     65   }
     66 
     67   virtual ~VPNServiceTest() {}
     68 
     69  protected:
     70   virtual void SetUp() {
     71     ON_CALL(*connection_, interface_name())
     72         .WillByDefault(ReturnRef(interface_name_));
     73     ON_CALL(*connection_, ipconfig_rpc_identifier())
     74         .WillByDefault(ReturnRef(ipconfig_rpc_identifier_));
     75   }
     76 
     77   virtual void TearDown() {
     78     EXPECT_CALL(device_info_, FlushAddresses(0));
     79   }
     80 
     81   void SetServiceState(Service::ConnectState state) {
     82     service_->state_ = state;
     83   }
     84 
     85   void SetHasEverConnected(bool connected) {
     86     service_->has_ever_connected_ = connected;
     87   }
     88 
     89   void SetConnectable(bool connectable) {
     90     service_->connectable_ = connectable;
     91   }
     92 
     93   const char* GetAutoConnOffline() {
     94     return Service::kAutoConnOffline;
     95   }
     96 
     97   const char* GetAutoConnNeverConnected() {
     98     return VPNService::kAutoConnNeverConnected;
     99   }
    100 
    101   const char* GetAutoConnVPNAlreadyActive() {
    102     return VPNService::kAutoConnVPNAlreadyActive;
    103   }
    104 
    105   bool IsAutoConnectable(const char** reason) const {
    106     return service_->IsAutoConnectable(reason);
    107   }
    108 
    109   // Takes ownership of |provider|.
    110   void SetVPNProvider(VPNProvider* provider) {
    111     manager_.vpn_provider_.reset(provider);
    112     manager_.UpdateProviderMapping();
    113   }
    114 
    115   ServiceMockAdaptor* GetAdaptor() {
    116     return static_cast<ServiceMockAdaptor*>(service_->adaptor());
    117   }
    118 
    119   std::string interface_name_;
    120   std::string ipconfig_rpc_identifier_;
    121   MockVPNDriver* driver_;  // Owned by |service_|.
    122   NiceMockControl control_;
    123   MockManager manager_;
    124   MockMetrics metrics_;
    125   MockDeviceInfo device_info_;
    126   scoped_refptr<NiceMock<MockConnection>> connection_;
    127   MockSockets* sockets_;  // Owned by |service_|.
    128   VPNServiceRefPtr service_;
    129 };
    130 
    131 TEST_F(VPNServiceTest, Connect) {
    132   EXPECT_TRUE(service_->connectable());
    133   Error error;
    134   EXPECT_CALL(*driver_, Connect(_, &error));
    135   service_->Connect(&error, "in test");
    136   EXPECT_TRUE(error.IsSuccess());
    137 }
    138 
    139 TEST_F(VPNServiceTest, ConnectAlreadyConnected) {
    140   Error error;
    141   EXPECT_CALL(*driver_, Connect(_, _)).Times(0);
    142   SetServiceState(Service::kStateOnline);
    143   service_->Connect(&error, "in test");
    144   EXPECT_EQ(Error::kAlreadyConnected, error.type());
    145   error.Reset();
    146   SetServiceState(Service::kStateConfiguring);
    147   service_->Connect(&error, "in test");
    148   EXPECT_EQ(Error::kInProgress, error.type());
    149 }
    150 
    151 TEST_F(VPNServiceTest, Disconnect) {
    152   Error error;
    153   EXPECT_CALL(*driver_, Disconnect());
    154   service_->Disconnect(&error, "in test");
    155   EXPECT_TRUE(error.IsSuccess());
    156 }
    157 
    158 TEST_F(VPNServiceTest, CreateStorageIdentifierNoHost) {
    159   KeyValueStore args;
    160   Error error;
    161   args.SetString(kNameProperty, "vpn-name");
    162   EXPECT_EQ("", VPNService::CreateStorageIdentifier(args, &error));
    163   EXPECT_EQ(Error::kInvalidProperty, error.type());
    164 }
    165 
    166 TEST_F(VPNServiceTest, CreateStorageIdentifierNoName) {
    167   KeyValueStore args;
    168   Error error;
    169   args.SetString(kProviderHostProperty, "10.8.0.1");
    170   EXPECT_EQ("", VPNService::CreateStorageIdentifier(args, &error));
    171   EXPECT_EQ(Error::kNotSupported, error.type());
    172 }
    173 
    174 TEST_F(VPNServiceTest, CreateStorageIdentifier) {
    175   KeyValueStore args;
    176   Error error;
    177   args.SetString(kNameProperty, "vpn-name");
    178   args.SetString(kProviderHostProperty, "10.8.0.1");
    179   EXPECT_EQ("vpn_10_8_0_1_vpn_name",
    180             VPNService::CreateStorageIdentifier(args, &error));
    181   EXPECT_TRUE(error.IsSuccess());
    182 }
    183 
    184 TEST_F(VPNServiceTest, GetStorageIdentifier) {
    185   EXPECT_EQ("", service_->GetStorageIdentifier());
    186   service_->set_storage_id("foo");
    187   EXPECT_EQ("foo", service_->GetStorageIdentifier());
    188 }
    189 
    190 TEST_F(VPNServiceTest, GetDeviceRpcId) {
    191   Error error;
    192   EXPECT_EQ("/", service_->GetDeviceRpcId(&error));
    193   EXPECT_EQ(Error::kNotSupported, error.type());
    194 }
    195 
    196 TEST_F(VPNServiceTest, Load) {
    197   NiceMock<MockStore> storage;
    198   static const char kStorageID[] = "storage-id";
    199   service_->set_storage_id(kStorageID);
    200   EXPECT_CALL(storage, ContainsGroup(kStorageID)).WillOnce(Return(true));
    201   EXPECT_CALL(*driver_, Load(&storage, kStorageID))
    202       .WillOnce(Return(true));
    203   EXPECT_TRUE(service_->Load(&storage));
    204 }
    205 
    206 TEST_F(VPNServiceTest, Save) {
    207   NiceMock<MockStore> storage;
    208   static const char kStorageID[] = "storage-id";
    209   service_->set_storage_id(kStorageID);
    210   EXPECT_CALL(*driver_, Save(&storage, kStorageID, false))
    211       .WillOnce(Return(true));
    212   EXPECT_TRUE(service_->Save(&storage));
    213 }
    214 
    215 TEST_F(VPNServiceTest, SaveCredentials) {
    216   NiceMock<MockStore> storage;
    217   static const char kStorageID[] = "storage-id";
    218   service_->set_storage_id(kStorageID);
    219   service_->set_save_credentials(true);
    220   EXPECT_CALL(*driver_, Save(&storage, kStorageID, true))
    221       .WillOnce(Return(true));
    222   EXPECT_TRUE(service_->Save(&storage));
    223 }
    224 
    225 TEST_F(VPNServiceTest, Unload) {
    226   service_->SetAutoConnect(true);
    227   service_->set_save_credentials(true);
    228   EXPECT_CALL(*driver_, Disconnect());
    229   EXPECT_CALL(*driver_, UnloadCredentials());
    230   MockVPNProvider* provider = new MockVPNProvider;
    231   SetVPNProvider(provider);
    232   provider->services_.push_back(service_);
    233   service_->Unload();
    234   EXPECT_FALSE(service_->auto_connect());
    235   EXPECT_FALSE(service_->save_credentials());
    236   EXPECT_TRUE(provider->services_.empty());
    237 }
    238 
    239 TEST_F(VPNServiceTest, InitPropertyStore) {
    240   EXPECT_CALL(*driver_, InitPropertyStore(service_->mutable_store()));
    241   service_->InitDriverPropertyStore();
    242 }
    243 
    244 TEST_F(VPNServiceTest, EnableAndRetainAutoConnect) {
    245   EXPECT_FALSE(service_->retain_auto_connect());
    246   EXPECT_FALSE(service_->auto_connect());
    247   service_->EnableAndRetainAutoConnect();
    248   EXPECT_TRUE(service_->retain_auto_connect());
    249   EXPECT_FALSE(service_->auto_connect());
    250 }
    251 
    252 TEST_F(VPNServiceTest, SetConnection) {
    253   EXPECT_FALSE(service_->connection_binder_.get());
    254   EXPECT_FALSE(service_->connection());
    255   EXPECT_CALL(*sockets_, Socket(_, _, _)).WillOnce(Return(-1));
    256   service_->SetConnection(connection_);
    257   ASSERT_TRUE(service_->connection_binder_.get());
    258   EXPECT_EQ(connection_.get(),
    259             service_->connection_binder_->connection().get());
    260   EXPECT_EQ(connection_.get(), service_->connection().get());
    261   EXPECT_CALL(*driver_, OnConnectionDisconnected()).Times(0);
    262 }
    263 
    264 TEST_F(VPNServiceTest, OnConnectionDisconnected) {
    265   EXPECT_CALL(*sockets_, Socket(_, _, _)).WillOnce(Return(-1));
    266   service_->SetConnection(connection_);
    267   EXPECT_CALL(*driver_, OnConnectionDisconnected()).Times(1);
    268   connection_->OnLowerDisconnect();
    269 }
    270 
    271 TEST_F(VPNServiceTest, IsAutoConnectableOffline) {
    272   EXPECT_TRUE(service_->connectable());
    273   const char* reason = nullptr;
    274   EXPECT_CALL(manager_, IsConnected()).WillOnce(Return(false));
    275   EXPECT_FALSE(IsAutoConnectable(&reason));
    276   EXPECT_STREQ(GetAutoConnOffline(), reason);
    277 }
    278 
    279 TEST_F(VPNServiceTest, IsAutoConnectableNeverConnected) {
    280   EXPECT_TRUE(service_->connectable());
    281   EXPECT_FALSE(service_->has_ever_connected());
    282   const char* reason = nullptr;
    283   EXPECT_CALL(manager_, IsConnected()).WillOnce(Return(true));
    284   EXPECT_FALSE(IsAutoConnectable(&reason));
    285   EXPECT_STREQ(GetAutoConnNeverConnected(), reason);
    286 }
    287 
    288 TEST_F(VPNServiceTest, IsAutoConnectableVPNAlreadyActive) {
    289   EXPECT_TRUE(service_->connectable());
    290   SetHasEverConnected(true);
    291   EXPECT_CALL(manager_, IsConnected()).WillOnce(Return(true));
    292   MockVPNProvider* provider = new MockVPNProvider;
    293   SetVPNProvider(provider);
    294   EXPECT_CALL(*provider, HasActiveService()).WillOnce(Return(true));
    295   const char* reason = nullptr;
    296   EXPECT_FALSE(IsAutoConnectable(&reason));
    297   EXPECT_STREQ(GetAutoConnVPNAlreadyActive(), reason);
    298 }
    299 
    300 TEST_F(VPNServiceTest, IsAutoConnectableNotConnectable) {
    301   const char* reason = nullptr;
    302   SetConnectable(false);
    303   EXPECT_FALSE(IsAutoConnectable(&reason));
    304 }
    305 
    306 TEST_F(VPNServiceTest, IsAutoConnectable) {
    307   EXPECT_TRUE(service_->connectable());
    308   SetHasEverConnected(true);
    309   EXPECT_CALL(manager_, IsConnected()).WillOnce(Return(true));
    310   MockVPNProvider* provider = new MockVPNProvider;
    311   SetVPNProvider(provider);
    312   EXPECT_CALL(*provider, HasActiveService()).WillOnce(Return(false));
    313   const char* reason = nullptr;
    314   EXPECT_TRUE(IsAutoConnectable(&reason));
    315   EXPECT_FALSE(reason);
    316 }
    317 
    318 TEST_F(VPNServiceTest, SetNamePropertyTrivial) {
    319   Error error;
    320   // A null change returns false, but with error set to success.
    321   EXPECT_FALSE(service_->mutable_store()->SetAnyProperty(
    322       kNameProperty, brillo::Any(service_->friendly_name()), &error));
    323   EXPECT_FALSE(error.IsFailure());
    324 }
    325 
    326 TEST_F(VPNServiceTest, SetNameProperty) {
    327   const string kHost = "1.2.3.4";
    328   driver_->args()->SetString(kProviderHostProperty, kHost);
    329   string kOldId = service_->GetStorageIdentifier();
    330   Error error;
    331   const string kName = "New Name";
    332   scoped_refptr<MockProfile> profile(
    333       new MockProfile(&control_, &metrics_, &manager_));
    334   EXPECT_CALL(*profile, DeleteEntry(kOldId, _));
    335   EXPECT_CALL(*profile, UpdateService(_));
    336   service_->set_profile(profile);
    337   EXPECT_TRUE(service_->mutable_store()->SetAnyProperty(
    338       kNameProperty, brillo::Any(kName), &error));
    339   EXPECT_NE(service_->GetStorageIdentifier(), kOldId);
    340   EXPECT_EQ(kName, service_->friendly_name());
    341 }
    342 
    343 TEST_F(VPNServiceTest, PropertyChanges) {
    344   TestCommonPropertyChanges(service_, GetAdaptor());
    345   TestAutoConnectPropertyChange(service_, GetAdaptor());
    346 
    347   const string kHost = "1.2.3.4";
    348   scoped_refptr<MockProfile> profile(
    349       new NiceMock<MockProfile>(&control_, &metrics_, &manager_));
    350   service_->set_profile(profile);
    351   driver_->args()->SetString(kProviderHostProperty, kHost);
    352   TestNamePropertyChange(service_, GetAdaptor());
    353 }
    354 
    355 // Custom property setters should return false, and make no changes, if
    356 // the new value is the same as the old value.
    357 TEST_F(VPNServiceTest, CustomSetterNoopChange) {
    358   TestCustomSetterNoopChange(service_, &manager_);
    359 }
    360 
    361 TEST_F(VPNServiceTest, GetPhysicalTechnologyPropertyFailsIfNoCarrier) {
    362   scoped_refptr<Connection> null_connection;
    363 
    364   EXPECT_CALL(*sockets_, Socket(_, _, _)).WillOnce(Return(-1));
    365   service_->SetConnection(connection_);
    366   EXPECT_EQ(connection_.get(), service_->connection().get());
    367 
    368   // Simulate an error in the GetCarrierConnection() returning a NULL reference.
    369   EXPECT_CALL(*connection_, GetCarrierConnection())
    370       .WillOnce(Return(null_connection));
    371 
    372   Error error;
    373   EXPECT_EQ("", service_->GetPhysicalTechnologyProperty(&error));
    374   EXPECT_EQ(Error::kOperationFailed, error.type());
    375 }
    376 
    377 TEST_F(VPNServiceTest, GetPhysicalTechnologyPropertyOverWifi) {
    378   scoped_refptr<NiceMock<MockConnection>> lower_connection_ =
    379       new NiceMock<MockConnection>(&device_info_);
    380 
    381   EXPECT_CALL(*connection_, technology())
    382       .Times(0);
    383   EXPECT_CALL(*connection_, GetCarrierConnection())
    384       .WillOnce(Return(lower_connection_));
    385 
    386   EXPECT_CALL(*sockets_, Socket(_, _, _)).WillOnce(Return(-1));
    387   service_->SetConnection(connection_);
    388   EXPECT_EQ(connection_.get(), service_->connection().get());
    389 
    390   // Set the type of the lower connection to "wifi" and expect that type to be
    391   // returned by GetPhysicalTechnologyProperty().
    392   EXPECT_CALL(*lower_connection_, technology())
    393       .WillOnce(Return(Technology::kWifi));
    394 
    395   Error error;
    396   EXPECT_EQ(kTypeWifi, service_->GetPhysicalTechnologyProperty(&error));
    397   EXPECT_TRUE(error.IsSuccess());
    398 
    399   // Clear expectations now, so the Return(lower_connection_) action releases
    400   // the reference to |lower_connection_| allowing it to be destroyed now.
    401   Mock::VerifyAndClearExpectations(connection_.get());
    402   // Destroying the |lower_connection_| at function exit will also call an extra
    403   // FlushAddresses on the |device_info_| object.
    404   EXPECT_CALL(device_info_, FlushAddresses(0));
    405 }
    406 
    407 TEST_F(VPNServiceTest, GetTethering) {
    408   scoped_refptr<Connection> null_connection;
    409 
    410   EXPECT_CALL(*sockets_, Socket(_, _, _)).WillOnce(Return(-1));
    411   service_->SetConnection(connection_);
    412   EXPECT_EQ(connection_.get(), service_->connection().get());
    413 
    414   // Simulate an error in the GetCarrierConnection() returning a NULL reference.
    415   EXPECT_CALL(*connection_, GetCarrierConnection())
    416       .WillOnce(Return(null_connection));
    417 
    418   {
    419     Error error;
    420     EXPECT_EQ("", service_->GetTethering(&error));
    421     EXPECT_EQ(Error::kOperationFailed, error.type());
    422   }
    423 
    424   scoped_refptr<NiceMock<MockConnection>> lower_connection_ =
    425       new NiceMock<MockConnection>(&device_info_);
    426 
    427   EXPECT_CALL(*connection_, tethering()).Times(0);
    428   EXPECT_CALL(*connection_, GetCarrierConnection())
    429       .WillRepeatedly(Return(lower_connection_));
    430 
    431   const char kTethering[] = "moon unit";
    432   EXPECT_CALL(*lower_connection_, tethering())
    433       .WillOnce(ReturnRefOfCopy(string(kTethering)))
    434       .WillOnce(ReturnRefOfCopy(string()));
    435 
    436   {
    437     Error error;
    438     EXPECT_EQ(kTethering, service_->GetTethering(&error));
    439     EXPECT_TRUE(error.IsSuccess());
    440   }
    441   {
    442     Error error;
    443     EXPECT_EQ("", service_->GetTethering(&error));
    444     EXPECT_EQ(Error::kNotSupported, error.type());
    445   }
    446 
    447   // Clear expectations now, so the Return(lower_connection_) action releases
    448   // the reference to |lower_connection_| allowing it to be destroyed now.
    449   Mock::VerifyAndClearExpectations(connection_.get());
    450   // Destroying the |lower_connection_| at function exit will also call an extra
    451   // FlushAddresses on the |device_info_| object.
    452   EXPECT_CALL(device_info_, FlushAddresses(0));
    453 }
    454 
    455 }  // namespace shill
    456