• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
VPNServiceTest()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 
~VPNServiceTest()67   virtual ~VPNServiceTest() {}
68 
69  protected:
SetUp()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 
TearDown()77   virtual void TearDown() {
78     EXPECT_CALL(device_info_, FlushAddresses(0));
79   }
80 
SetServiceState(Service::ConnectState state)81   void SetServiceState(Service::ConnectState state) {
82     service_->state_ = state;
83   }
84 
SetHasEverConnected(bool connected)85   void SetHasEverConnected(bool connected) {
86     service_->has_ever_connected_ = connected;
87   }
88 
SetConnectable(bool connectable)89   void SetConnectable(bool connectable) {
90     service_->connectable_ = connectable;
91   }
92 
GetAutoConnOffline()93   const char* GetAutoConnOffline() {
94     return Service::kAutoConnOffline;
95   }
96 
GetAutoConnNeverConnected()97   const char* GetAutoConnNeverConnected() {
98     return VPNService::kAutoConnNeverConnected;
99   }
100 
GetAutoConnVPNAlreadyActive()101   const char* GetAutoConnVPNAlreadyActive() {
102     return VPNService::kAutoConnVPNAlreadyActive;
103   }
104 
IsAutoConnectable(const char ** reason) const105   bool IsAutoConnectable(const char** reason) const {
106     return service_->IsAutoConnectable(reason);
107   }
108 
109   // Takes ownership of |provider|.
SetVPNProvider(VPNProvider * provider)110   void SetVPNProvider(VPNProvider* provider) {
111     manager_.vpn_provider_.reset(provider);
112     manager_.UpdateProviderMapping();
113   }
114 
GetAdaptor()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 
TEST_F(VPNServiceTest,Connect)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 
TEST_F(VPNServiceTest,ConnectAlreadyConnected)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 
TEST_F(VPNServiceTest,Disconnect)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 
TEST_F(VPNServiceTest,CreateStorageIdentifierNoHost)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 
TEST_F(VPNServiceTest,CreateStorageIdentifierNoName)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 
TEST_F(VPNServiceTest,CreateStorageIdentifier)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 
TEST_F(VPNServiceTest,GetStorageIdentifier)184 TEST_F(VPNServiceTest, GetStorageIdentifier) {
185   EXPECT_EQ("", service_->GetStorageIdentifier());
186   service_->set_storage_id("foo");
187   EXPECT_EQ("foo", service_->GetStorageIdentifier());
188 }
189 
TEST_F(VPNServiceTest,GetDeviceRpcId)190 TEST_F(VPNServiceTest, GetDeviceRpcId) {
191   Error error;
192   EXPECT_EQ("/", service_->GetDeviceRpcId(&error));
193   EXPECT_EQ(Error::kNotSupported, error.type());
194 }
195 
TEST_F(VPNServiceTest,Load)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 
TEST_F(VPNServiceTest,Save)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 
TEST_F(VPNServiceTest,SaveCredentials)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 
TEST_F(VPNServiceTest,Unload)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 
TEST_F(VPNServiceTest,InitPropertyStore)239 TEST_F(VPNServiceTest, InitPropertyStore) {
240   EXPECT_CALL(*driver_, InitPropertyStore(service_->mutable_store()));
241   service_->InitDriverPropertyStore();
242 }
243 
TEST_F(VPNServiceTest,EnableAndRetainAutoConnect)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 
TEST_F(VPNServiceTest,SetConnection)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 
TEST_F(VPNServiceTest,OnConnectionDisconnected)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 
TEST_F(VPNServiceTest,IsAutoConnectableOffline)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 
TEST_F(VPNServiceTest,IsAutoConnectableNeverConnected)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 
TEST_F(VPNServiceTest,IsAutoConnectableVPNAlreadyActive)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 
TEST_F(VPNServiceTest,IsAutoConnectableNotConnectable)300 TEST_F(VPNServiceTest, IsAutoConnectableNotConnectable) {
301   const char* reason = nullptr;
302   SetConnectable(false);
303   EXPECT_FALSE(IsAutoConnectable(&reason));
304 }
305 
TEST_F(VPNServiceTest,IsAutoConnectable)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 
TEST_F(VPNServiceTest,SetNamePropertyTrivial)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 
TEST_F(VPNServiceTest,SetNameProperty)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 
TEST_F(VPNServiceTest,PropertyChanges)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.
TEST_F(VPNServiceTest,CustomSetterNoopChange)357 TEST_F(VPNServiceTest, CustomSetterNoopChange) {
358   TestCustomSetterNoopChange(service_, &manager_);
359 }
360 
TEST_F(VPNServiceTest,GetPhysicalTechnologyPropertyFailsIfNoCarrier)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 
TEST_F(VPNServiceTest,GetPhysicalTechnologyPropertyOverWifi)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 
TEST_F(VPNServiceTest,GetTethering)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