blob: 17e91fba0a57b4d65d4aaa3d37ac0e25d9da2fbf [file] [log] [blame]
Darin Petkov33af05c2012-02-28 10:10:30 +01001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "shill/vpn_service.h"
6
Darin Petkov02867712012-03-12 14:25:05 +01007#include <chromeos/dbus/service_constants.h>
Darin Petkov33af05c2012-02-28 10:10:30 +01008#include <gtest/gtest.h>
9
Darin Petkov9c6e9812013-03-26 13:49:07 +010010#include "shill/dbus_adaptor.h"
Darin Petkov33af05c2012-02-28 10:10:30 +010011#include "shill/error.h"
12#include "shill/nice_mock_control.h"
13#include "shill/mock_adaptors.h"
Darin Petkov5eb05422012-05-11 15:45:25 +020014#include "shill/mock_connection.h"
15#include "shill/mock_device_info.h"
Darin Petkova0e645e2012-04-25 11:38:59 +020016#include "shill/mock_manager.h"
Darin Petkov33af05c2012-02-28 10:10:30 +010017#include "shill/mock_metrics.h"
Darin Petkov9c6e9812013-03-26 13:49:07 +010018#include "shill/mock_profile.h"
Darin Petkov5eb05422012-05-11 15:45:25 +020019#include "shill/mock_sockets.h"
Darin Petkovf3c71d72012-03-21 12:32:15 +010020#include "shill/mock_store.h"
Darin Petkov33af05c2012-02-28 10:10:30 +010021#include "shill/mock_vpn_driver.h"
Paul Stewart8c116a92012-05-02 18:30:03 -070022#include "shill/mock_vpn_provider.h"
mukesh agrawalcbfb34e2013-04-17 19:33:25 -070023#include "shill/service_property_change_test.h"
Darin Petkov33af05c2012-02-28 10:10:30 +010024
Darin Petkov5eb05422012-05-11 15:45:25 +020025using std::string;
Darin Petkov79d74c92012-03-07 17:20:32 +010026using testing::_;
Darin Petkovf3c71d72012-03-21 12:32:15 +010027using testing::NiceMock;
28using testing::Return;
Darin Petkov5eb05422012-05-11 15:45:25 +020029using testing::ReturnRef;
Darin Petkov79d74c92012-03-07 17:20:32 +010030
Darin Petkov33af05c2012-02-28 10:10:30 +010031namespace shill {
32
33class VPNServiceTest : public testing::Test {
34 public:
35 VPNServiceTest()
Darin Petkov5eb05422012-05-11 15:45:25 +020036 : interface_name_("test-interface"),
37 driver_(new MockVPNDriver()),
Darin Petkova0e645e2012-04-25 11:38:59 +020038 manager_(&control_, NULL, NULL, NULL),
Thieu Le6c1e3bb2013-02-06 15:20:35 -080039 metrics_(NULL),
Darin Petkov5eb05422012-05-11 15:45:25 +020040 device_info_(&control_, NULL, NULL, NULL),
41 connection_(new NiceMock<MockConnection>(&device_info_)),
42 sockets_(new MockSockets()),
Darin Petkova0e645e2012-04-25 11:38:59 +020043 service_(new VPNService(&control_, NULL, &metrics_, &manager_,
Darin Petkov5eb05422012-05-11 15:45:25 +020044 driver_)) {
45 service_->sockets_.reset(sockets_); // Passes ownership.
46 }
Darin Petkov33af05c2012-02-28 10:10:30 +010047
48 virtual ~VPNServiceTest() {}
49
50 protected:
Darin Petkov5eb05422012-05-11 15:45:25 +020051 virtual void SetUp() {
52 ON_CALL(*connection_, interface_name())
53 .WillByDefault(ReturnRef(interface_name_));
Paul Stewart1e3bc4962012-09-14 12:20:22 -070054 ON_CALL(*connection_, ipconfig_rpc_identifier())
55 .WillByDefault(ReturnRef(ipconfig_rpc_identifier_));
Darin Petkov5eb05422012-05-11 15:45:25 +020056 }
57
58 virtual void TearDown() {
59 EXPECT_CALL(device_info_, FlushAddresses(0));
60 }
61
62 void SetServiceState(Service::ConnectState state) {
63 service_->state_ = state;
64 }
65
Darin Petkov79349f02013-01-24 16:18:26 +010066 void SetHasEverConnected(bool connected) {
67 service_->has_ever_connected_ = connected;
68 }
69
70 void SetConnectable(bool connectable) {
71 service_->connectable_ = connectable;
72 }
73
Darin Petkov4cbff5b2013-01-29 16:29:05 +010074 const char *GetAutoConnOffline() {
75 return Service::kAutoConnOffline;
76 }
77
78 const char *GetAutoConnNeverConnected() {
79 return VPNService::kAutoConnNeverConnected;
80 }
81
82 const char *GetAutoConnVPNAlreadyActive() {
83 return VPNService::kAutoConnVPNAlreadyActive;
84 }
85
86 bool IsAutoConnectable(const char **reason) const {
87 return service_->IsAutoConnectable(reason);
88 }
89
Darin Petkovc3505a52013-03-18 15:13:29 +010090 // Takes ownership of |provider|.
91 void SetVPNProvider(VPNProvider *provider) {
92 manager_.vpn_provider_.reset(provider);
93 }
94
mukesh agrawalcbfb34e2013-04-17 19:33:25 -070095 ServiceMockAdaptor *GetAdaptor() {
96 return dynamic_cast<ServiceMockAdaptor *>(service_->adaptor());
97 }
98
Darin Petkov5eb05422012-05-11 15:45:25 +020099 std::string interface_name_;
Paul Stewart1e3bc4962012-09-14 12:20:22 -0700100 std::string ipconfig_rpc_identifier_;
Darin Petkov33af05c2012-02-28 10:10:30 +0100101 MockVPNDriver *driver_; // Owned by |service_|.
102 NiceMockControl control_;
Darin Petkova0e645e2012-04-25 11:38:59 +0200103 MockManager manager_;
Darin Petkov33af05c2012-02-28 10:10:30 +0100104 MockMetrics metrics_;
Darin Petkov5eb05422012-05-11 15:45:25 +0200105 MockDeviceInfo device_info_;
106 scoped_refptr<NiceMock<MockConnection> > connection_;
107 MockSockets *sockets_; // Owned by |service_|.
Darin Petkov33af05c2012-02-28 10:10:30 +0100108 VPNServiceRefPtr service_;
109};
110
111TEST_F(VPNServiceTest, Connect) {
Darin Petkov2f903b32012-04-18 12:56:43 +0200112 EXPECT_TRUE(service_->connectable());
Darin Petkov33af05c2012-02-28 10:10:30 +0100113 Error error;
Darin Petkov79d74c92012-03-07 17:20:32 +0100114 EXPECT_CALL(*driver_, Connect(_, &error));
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700115 service_->Connect(&error, "in test");
Darin Petkov79d74c92012-03-07 17:20:32 +0100116 EXPECT_TRUE(error.IsSuccess());
Darin Petkov33af05c2012-02-28 10:10:30 +0100117}
118
Darin Petkov2f903b32012-04-18 12:56:43 +0200119TEST_F(VPNServiceTest, ConnectAlreadyConnected) {
120 Error error;
121 EXPECT_CALL(*driver_, Connect(_, _)).Times(0);
Darin Petkov5eb05422012-05-11 15:45:25 +0200122 SetServiceState(Service::kStateOnline);
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700123 service_->Connect(&error, "in test");
Darin Petkov2f903b32012-04-18 12:56:43 +0200124 EXPECT_EQ(Error::kAlreadyConnected, error.type());
125 error.Reset();
Darin Petkov5eb05422012-05-11 15:45:25 +0200126 SetServiceState(Service::kStateConfiguring);
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700127 service_->Connect(&error, "in test");
Darin Petkov2f903b32012-04-18 12:56:43 +0200128 EXPECT_EQ(Error::kAlreadyConnected, error.type());
129}
130
Darin Petkov6aa21872012-03-09 16:10:19 +0100131TEST_F(VPNServiceTest, Disconnect) {
132 Error error;
133 EXPECT_CALL(*driver_, Disconnect());
134 service_->Disconnect(&error);
135 EXPECT_TRUE(error.IsSuccess());
136}
137
Darin Petkov02867712012-03-12 14:25:05 +0100138TEST_F(VPNServiceTest, CreateStorageIdentifierNoHost) {
139 KeyValueStore args;
140 Error error;
Darin Petkov4e02ba22013-04-02 13:44:08 +0200141 args.SetString(flimflam::kNameProperty, "vpn-name");
Darin Petkov02867712012-03-12 14:25:05 +0100142 EXPECT_EQ("", VPNService::CreateStorageIdentifier(args, &error));
143 EXPECT_EQ(Error::kInvalidProperty, error.type());
144}
145
146TEST_F(VPNServiceTest, CreateStorageIdentifierNoName) {
147 KeyValueStore args;
148 Error error;
149 args.SetString(flimflam::kProviderHostProperty, "10.8.0.1");
150 EXPECT_EQ("", VPNService::CreateStorageIdentifier(args, &error));
151 EXPECT_EQ(Error::kNotSupported, error.type());
152}
153
154TEST_F(VPNServiceTest, CreateStorageIdentifier) {
155 KeyValueStore args;
156 Error error;
Darin Petkov4e02ba22013-04-02 13:44:08 +0200157 args.SetString(flimflam::kNameProperty, "vpn-name");
Darin Petkov02867712012-03-12 14:25:05 +0100158 args.SetString(flimflam::kProviderHostProperty, "10.8.0.1");
159 EXPECT_EQ("vpn_10_8_0_1_vpn_name",
160 VPNService::CreateStorageIdentifier(args, &error));
161 EXPECT_TRUE(error.IsSuccess());
162}
163
Darin Petkov33af05c2012-02-28 10:10:30 +0100164TEST_F(VPNServiceTest, GetStorageIdentifier) {
165 EXPECT_EQ("", service_->GetStorageIdentifier());
Darin Petkov02867712012-03-12 14:25:05 +0100166 service_->set_storage_id("foo");
167 EXPECT_EQ("foo", service_->GetStorageIdentifier());
Darin Petkov33af05c2012-02-28 10:10:30 +0100168}
169
170TEST_F(VPNServiceTest, GetDeviceRpcId) {
171 Error error;
172 EXPECT_EQ("/", service_->GetDeviceRpcId(&error));
173 EXPECT_EQ(Error::kNotSupported, error.type());
174}
175
Darin Petkovf3c71d72012-03-21 12:32:15 +0100176TEST_F(VPNServiceTest, Load) {
177 NiceMock<MockStore> storage;
178 static const char kStorageID[] = "storage-id";
179 service_->set_storage_id(kStorageID);
180 EXPECT_CALL(storage, ContainsGroup(kStorageID)).WillOnce(Return(true));
Darin Petkovcb715292012-04-25 13:04:37 +0200181 EXPECT_CALL(*driver_, Load(&storage, kStorageID))
182 .WillOnce(Return(true));
Darin Petkovf3c71d72012-03-21 12:32:15 +0100183 EXPECT_TRUE(service_->Load(&storage));
184}
185
186TEST_F(VPNServiceTest, Save) {
187 NiceMock<MockStore> storage;
188 static const char kStorageID[] = "storage-id";
189 service_->set_storage_id(kStorageID);
Darin Petkovcb715292012-04-25 13:04:37 +0200190 EXPECT_CALL(*driver_, Save(&storage, kStorageID, false))
191 .WillOnce(Return(true));
Darin Petkovf3c71d72012-03-21 12:32:15 +0100192 EXPECT_TRUE(service_->Save(&storage));
193}
194
Darin Petkovcb715292012-04-25 13:04:37 +0200195TEST_F(VPNServiceTest, SaveCredentials) {
196 NiceMock<MockStore> storage;
197 static const char kStorageID[] = "storage-id";
198 service_->set_storage_id(kStorageID);
199 service_->set_save_credentials(true);
200 EXPECT_CALL(*driver_, Save(&storage, kStorageID, true))
201 .WillOnce(Return(true));
202 EXPECT_TRUE(service_->Save(&storage));
203}
204
205TEST_F(VPNServiceTest, Unload) {
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700206 service_->SetAutoConnect(true);
Darin Petkovcb715292012-04-25 13:04:37 +0200207 service_->set_save_credentials(true);
208 EXPECT_CALL(*driver_, Disconnect());
209 EXPECT_CALL(*driver_, UnloadCredentials());
Darin Petkovc3505a52013-03-18 15:13:29 +0100210 MockVPNProvider *provider = new MockVPNProvider;
211 SetVPNProvider(provider);
212 provider->services_.push_back(service_);
Darin Petkovcb715292012-04-25 13:04:37 +0200213 service_->Unload();
214 EXPECT_FALSE(service_->auto_connect());
215 EXPECT_FALSE(service_->save_credentials());
Darin Petkovc3505a52013-03-18 15:13:29 +0100216 EXPECT_TRUE(provider->services_.empty());
Darin Petkovcb715292012-04-25 13:04:37 +0200217}
218
Paul Stewartebd38562012-03-23 13:06:40 -0700219TEST_F(VPNServiceTest, InitPropertyStore) {
220 EXPECT_CALL(*driver_, InitPropertyStore(service_->mutable_store()));
221 service_->InitDriverPropertyStore();
222}
223
Darin Petkov1d0080a2012-04-30 17:10:36 +0200224TEST_F(VPNServiceTest, MakeFavorite) {
225 EXPECT_FALSE(service_->favorite());
226 EXPECT_FALSE(service_->auto_connect());
227 service_->MakeFavorite();
228 EXPECT_TRUE(service_->favorite());
229 EXPECT_FALSE(service_->auto_connect());
230}
231
Darin Petkov5eb05422012-05-11 15:45:25 +0200232TEST_F(VPNServiceTest, SetConnection) {
233 EXPECT_FALSE(service_->connection_binder_.get());
234 EXPECT_FALSE(service_->connection());
235 EXPECT_CALL(*sockets_, Socket(_, _, _)).WillOnce(Return(-1));
236 service_->SetConnection(connection_);
237 ASSERT_TRUE(service_->connection_binder_.get());
238 EXPECT_EQ(connection_.get(),
239 service_->connection_binder_->connection().get());
240 EXPECT_EQ(connection_.get(), service_->connection().get());
241 EXPECT_CALL(*driver_, OnConnectionDisconnected()).Times(0);
242}
243
244TEST_F(VPNServiceTest, OnConnectionDisconnected) {
245 EXPECT_CALL(*sockets_, Socket(_, _, _)).WillOnce(Return(-1));
246 service_->SetConnection(connection_);
247 EXPECT_CALL(*driver_, OnConnectionDisconnected()).Times(1);
248 connection_->OnLowerDisconnect();
249}
250
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100251TEST_F(VPNServiceTest, IsAutoConnectableOffline) {
252 EXPECT_TRUE(service_->connectable());
253 const char *reason = NULL;
254 EXPECT_CALL(manager_, IsOnline()).WillOnce(Return(false));
255 EXPECT_FALSE(IsAutoConnectable(&reason));
256 EXPECT_STREQ(GetAutoConnOffline(), reason);
257}
258
259TEST_F(VPNServiceTest, IsAutoConnectableNeverConnected) {
Darin Petkov79349f02013-01-24 16:18:26 +0100260 EXPECT_TRUE(service_->connectable());
261 EXPECT_FALSE(service_->has_ever_connected());
Darin Petkov79349f02013-01-24 16:18:26 +0100262 const char *reason = NULL;
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100263 EXPECT_CALL(manager_, IsOnline()).WillOnce(Return(true));
264 EXPECT_FALSE(IsAutoConnectable(&reason));
265 EXPECT_STREQ(GetAutoConnNeverConnected(), reason);
266}
Darin Petkov79349f02013-01-24 16:18:26 +0100267
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100268TEST_F(VPNServiceTest, IsAutoConnectableVPNAlreadyActive) {
269 EXPECT_TRUE(service_->connectable());
Darin Petkov79349f02013-01-24 16:18:26 +0100270 SetHasEverConnected(true);
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100271 EXPECT_CALL(manager_, IsOnline()).WillOnce(Return(true));
Darin Petkovc3505a52013-03-18 15:13:29 +0100272 MockVPNProvider *provider = new MockVPNProvider;
273 SetVPNProvider(provider);
274 EXPECT_CALL(*provider, HasActiveService()).WillOnce(Return(true));
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100275 const char *reason = NULL;
276 EXPECT_FALSE(IsAutoConnectable(&reason));
277 EXPECT_STREQ(GetAutoConnVPNAlreadyActive(), reason);
278}
Darin Petkov79349f02013-01-24 16:18:26 +0100279
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100280TEST_F(VPNServiceTest, IsAutoConnectableNotConnectable) {
281 const char *reason = NULL;
Darin Petkov79349f02013-01-24 16:18:26 +0100282 SetConnectable(false);
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100283 EXPECT_FALSE(IsAutoConnectable(&reason));
284}
285
286TEST_F(VPNServiceTest, IsAutoConnectable) {
287 EXPECT_TRUE(service_->connectable());
288 SetHasEverConnected(true);
289 EXPECT_CALL(manager_, IsOnline()).WillOnce(Return(true));
Darin Petkovc3505a52013-03-18 15:13:29 +0100290 MockVPNProvider *provider = new MockVPNProvider;
291 SetVPNProvider(provider);
292 EXPECT_CALL(*provider, HasActiveService()).WillOnce(Return(false));
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100293 const char *reason = NULL;
294 EXPECT_TRUE(IsAutoConnectable(&reason));
295 EXPECT_FALSE(reason);
Darin Petkov79349f02013-01-24 16:18:26 +0100296}
297
Darin Petkov9c6e9812013-03-26 13:49:07 +0100298TEST_F(VPNServiceTest, SetNamePropertyTrivial) {
299 DBus::Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700300 // A null change returns false, but with error set to success.
301 EXPECT_FALSE(DBusAdaptor::SetProperty(service_->mutable_store(),
302 flimflam::kNameProperty,
303 DBusAdaptor::StringToVariant(
304 service_->friendly_name()),
305 &error));
306 EXPECT_FALSE(error.is_set());
Darin Petkov9c6e9812013-03-26 13:49:07 +0100307}
308
309TEST_F(VPNServiceTest, SetNameProperty) {
310 const string kHost = "1.2.3.4";
311 driver_->args()->SetString(flimflam::kProviderHostProperty, kHost);
312 string kOldId = service_->GetStorageIdentifier();
313 DBus::Error error;
314 const string kName = "New Name";
315 scoped_refptr<MockProfile> profile(
316 new MockProfile(&control_, &metrics_, &manager_));
317 EXPECT_CALL(*profile, DeleteEntry(kOldId, _));
318 EXPECT_CALL(*profile, UpdateService(_));
319 service_->set_profile(profile);
320 EXPECT_TRUE(DBusAdaptor::SetProperty(service_->mutable_store(),
321 flimflam::kNameProperty,
322 DBusAdaptor::StringToVariant(kName),
323 &error));
324 EXPECT_NE(service_->GetStorageIdentifier(), kOldId);
325 EXPECT_EQ(kName, service_->friendly_name());
326}
327
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700328TEST_F(VPNServiceTest, PropertyChanges) {
329 TestCommonPropertyChanges(service_, GetAdaptor());
330 TestAutoConnectPropertyChange(service_, GetAdaptor());
331
332 const string kHost = "1.2.3.4";
333 scoped_refptr<MockProfile> profile(
334 new NiceMock<MockProfile>(&control_, &metrics_, &manager_));
335 service_->set_profile(profile);
336 driver_->args()->SetString(flimflam::kProviderHostProperty, kHost);
337 TestNamePropertyChange(service_, GetAdaptor());
338}
339
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700340// Custom property setters should return false, and make no changes, if
341// the new value is the same as the old value.
342TEST_F(VPNServiceTest, CustomSetterNoopChange) {
343 TestCustomSetterNoopChange(service_, &manager_);
344}
345
Darin Petkov33af05c2012-02-28 10:10:30 +0100346} // namespace shill