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