blob: dab06feb7e18ed1d66bdf5da1e33f59db017d504 [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
10#include "shill/error.h"
11#include "shill/nice_mock_control.h"
12#include "shill/mock_adaptors.h"
Darin Petkov5eb05422012-05-11 15:45:25 +020013#include "shill/mock_connection.h"
14#include "shill/mock_device_info.h"
Darin Petkova0e645e2012-04-25 11:38:59 +020015#include "shill/mock_manager.h"
Darin Petkov33af05c2012-02-28 10:10:30 +010016#include "shill/mock_metrics.h"
Darin Petkov5eb05422012-05-11 15:45:25 +020017#include "shill/mock_sockets.h"
Darin Petkovf3c71d72012-03-21 12:32:15 +010018#include "shill/mock_store.h"
Darin Petkov33af05c2012-02-28 10:10:30 +010019#include "shill/mock_vpn_driver.h"
Paul Stewart8c116a92012-05-02 18:30:03 -070020#include "shill/mock_vpn_provider.h"
Darin Petkov33af05c2012-02-28 10:10:30 +010021
Darin Petkov5eb05422012-05-11 15:45:25 +020022using std::string;
Darin Petkov79d74c92012-03-07 17:20:32 +010023using testing::_;
Darin Petkovf3c71d72012-03-21 12:32:15 +010024using testing::NiceMock;
25using testing::Return;
Darin Petkov5eb05422012-05-11 15:45:25 +020026using testing::ReturnRef;
Darin Petkov79d74c92012-03-07 17:20:32 +010027
Darin Petkov33af05c2012-02-28 10:10:30 +010028namespace shill {
29
30class VPNServiceTest : public testing::Test {
31 public:
32 VPNServiceTest()
Darin Petkov5eb05422012-05-11 15:45:25 +020033 : interface_name_("test-interface"),
34 driver_(new MockVPNDriver()),
Darin Petkova0e645e2012-04-25 11:38:59 +020035 manager_(&control_, NULL, NULL, NULL),
Thieu Le6c1e3bb2013-02-06 15:20:35 -080036 metrics_(NULL),
Darin Petkov5eb05422012-05-11 15:45:25 +020037 device_info_(&control_, NULL, NULL, NULL),
38 connection_(new NiceMock<MockConnection>(&device_info_)),
39 sockets_(new MockSockets()),
Darin Petkova0e645e2012-04-25 11:38:59 +020040 service_(new VPNService(&control_, NULL, &metrics_, &manager_,
Darin Petkov5eb05422012-05-11 15:45:25 +020041 driver_)) {
42 service_->sockets_.reset(sockets_); // Passes ownership.
43 }
Darin Petkov33af05c2012-02-28 10:10:30 +010044
45 virtual ~VPNServiceTest() {}
46
47 protected:
Darin Petkov5eb05422012-05-11 15:45:25 +020048 virtual void SetUp() {
49 ON_CALL(*connection_, interface_name())
50 .WillByDefault(ReturnRef(interface_name_));
Paul Stewart1e3bc4962012-09-14 12:20:22 -070051 ON_CALL(*connection_, ipconfig_rpc_identifier())
52 .WillByDefault(ReturnRef(ipconfig_rpc_identifier_));
Darin Petkov5eb05422012-05-11 15:45:25 +020053 }
54
55 virtual void TearDown() {
56 EXPECT_CALL(device_info_, FlushAddresses(0));
57 }
58
59 void SetServiceState(Service::ConnectState state) {
60 service_->state_ = state;
61 }
62
Darin Petkov79349f02013-01-24 16:18:26 +010063 void SetHasEverConnected(bool connected) {
64 service_->has_ever_connected_ = connected;
65 }
66
67 void SetConnectable(bool connectable) {
68 service_->connectable_ = connectable;
69 }
70
Darin Petkov4cbff5b2013-01-29 16:29:05 +010071 const char *GetAutoConnOffline() {
72 return Service::kAutoConnOffline;
73 }
74
75 const char *GetAutoConnNeverConnected() {
76 return VPNService::kAutoConnNeverConnected;
77 }
78
79 const char *GetAutoConnVPNAlreadyActive() {
80 return VPNService::kAutoConnVPNAlreadyActive;
81 }
82
83 bool IsAutoConnectable(const char **reason) const {
84 return service_->IsAutoConnectable(reason);
85 }
86
Darin Petkov5eb05422012-05-11 15:45:25 +020087 std::string interface_name_;
Paul Stewart1e3bc4962012-09-14 12:20:22 -070088 std::string ipconfig_rpc_identifier_;
Darin Petkov33af05c2012-02-28 10:10:30 +010089 MockVPNDriver *driver_; // Owned by |service_|.
90 NiceMockControl control_;
Darin Petkova0e645e2012-04-25 11:38:59 +020091 MockManager manager_;
Darin Petkov33af05c2012-02-28 10:10:30 +010092 MockMetrics metrics_;
Darin Petkov5eb05422012-05-11 15:45:25 +020093 MockDeviceInfo device_info_;
94 scoped_refptr<NiceMock<MockConnection> > connection_;
95 MockSockets *sockets_; // Owned by |service_|.
Darin Petkov33af05c2012-02-28 10:10:30 +010096 VPNServiceRefPtr service_;
97};
98
99TEST_F(VPNServiceTest, Connect) {
Darin Petkov2f903b32012-04-18 12:56:43 +0200100 EXPECT_TRUE(service_->connectable());
Darin Petkov33af05c2012-02-28 10:10:30 +0100101 Error error;
Darin Petkov79d74c92012-03-07 17:20:32 +0100102 EXPECT_CALL(*driver_, Connect(_, &error));
Darin Petkov33af05c2012-02-28 10:10:30 +0100103 service_->Connect(&error);
Darin Petkov79d74c92012-03-07 17:20:32 +0100104 EXPECT_TRUE(error.IsSuccess());
Darin Petkov33af05c2012-02-28 10:10:30 +0100105}
106
Darin Petkov2f903b32012-04-18 12:56:43 +0200107TEST_F(VPNServiceTest, ConnectAlreadyConnected) {
108 Error error;
109 EXPECT_CALL(*driver_, Connect(_, _)).Times(0);
Darin Petkov5eb05422012-05-11 15:45:25 +0200110 SetServiceState(Service::kStateOnline);
Darin Petkov2f903b32012-04-18 12:56:43 +0200111 service_->Connect(&error);
112 EXPECT_EQ(Error::kAlreadyConnected, error.type());
113 error.Reset();
Darin Petkov5eb05422012-05-11 15:45:25 +0200114 SetServiceState(Service::kStateConfiguring);
Darin Petkov2f903b32012-04-18 12:56:43 +0200115 service_->Connect(&error);
116 EXPECT_EQ(Error::kAlreadyConnected, error.type());
117}
118
Darin Petkov6aa21872012-03-09 16:10:19 +0100119TEST_F(VPNServiceTest, Disconnect) {
120 Error error;
121 EXPECT_CALL(*driver_, Disconnect());
122 service_->Disconnect(&error);
123 EXPECT_TRUE(error.IsSuccess());
124}
125
Darin Petkov02867712012-03-12 14:25:05 +0100126TEST_F(VPNServiceTest, CreateStorageIdentifierNoHost) {
127 KeyValueStore args;
128 Error error;
129 args.SetString(flimflam::kProviderNameProperty, "vpn-name");
130 EXPECT_EQ("", VPNService::CreateStorageIdentifier(args, &error));
131 EXPECT_EQ(Error::kInvalidProperty, error.type());
132}
133
134TEST_F(VPNServiceTest, CreateStorageIdentifierNoName) {
135 KeyValueStore args;
136 Error error;
137 args.SetString(flimflam::kProviderHostProperty, "10.8.0.1");
138 EXPECT_EQ("", VPNService::CreateStorageIdentifier(args, &error));
139 EXPECT_EQ(Error::kNotSupported, error.type());
140}
141
142TEST_F(VPNServiceTest, CreateStorageIdentifier) {
143 KeyValueStore args;
144 Error error;
145 args.SetString(flimflam::kProviderNameProperty, "vpn-name");
146 args.SetString(flimflam::kProviderHostProperty, "10.8.0.1");
147 EXPECT_EQ("vpn_10_8_0_1_vpn_name",
148 VPNService::CreateStorageIdentifier(args, &error));
149 EXPECT_TRUE(error.IsSuccess());
150}
151
Darin Petkov33af05c2012-02-28 10:10:30 +0100152TEST_F(VPNServiceTest, GetStorageIdentifier) {
153 EXPECT_EQ("", service_->GetStorageIdentifier());
Darin Petkov02867712012-03-12 14:25:05 +0100154 service_->set_storage_id("foo");
155 EXPECT_EQ("foo", service_->GetStorageIdentifier());
Darin Petkov33af05c2012-02-28 10:10:30 +0100156}
157
158TEST_F(VPNServiceTest, GetDeviceRpcId) {
159 Error error;
160 EXPECT_EQ("/", service_->GetDeviceRpcId(&error));
161 EXPECT_EQ(Error::kNotSupported, error.type());
162}
163
Darin Petkovf3c71d72012-03-21 12:32:15 +0100164TEST_F(VPNServiceTest, Load) {
165 NiceMock<MockStore> storage;
166 static const char kStorageID[] = "storage-id";
167 service_->set_storage_id(kStorageID);
168 EXPECT_CALL(storage, ContainsGroup(kStorageID)).WillOnce(Return(true));
Darin Petkovcb715292012-04-25 13:04:37 +0200169 EXPECT_CALL(*driver_, Load(&storage, kStorageID))
170 .WillOnce(Return(true));
Darin Petkovf3c71d72012-03-21 12:32:15 +0100171 EXPECT_TRUE(service_->Load(&storage));
172}
173
174TEST_F(VPNServiceTest, Save) {
175 NiceMock<MockStore> storage;
176 static const char kStorageID[] = "storage-id";
177 service_->set_storage_id(kStorageID);
Darin Petkovcb715292012-04-25 13:04:37 +0200178 EXPECT_CALL(*driver_, Save(&storage, kStorageID, false))
179 .WillOnce(Return(true));
Darin Petkovf3c71d72012-03-21 12:32:15 +0100180 EXPECT_TRUE(service_->Save(&storage));
181}
182
Darin Petkovcb715292012-04-25 13:04:37 +0200183TEST_F(VPNServiceTest, SaveCredentials) {
184 NiceMock<MockStore> storage;
185 static const char kStorageID[] = "storage-id";
186 service_->set_storage_id(kStorageID);
187 service_->set_save_credentials(true);
188 EXPECT_CALL(*driver_, Save(&storage, kStorageID, true))
189 .WillOnce(Return(true));
190 EXPECT_TRUE(service_->Save(&storage));
191}
192
193TEST_F(VPNServiceTest, Unload) {
194 service_->set_auto_connect(true);
195 service_->set_save_credentials(true);
196 EXPECT_CALL(*driver_, Disconnect());
197 EXPECT_CALL(*driver_, UnloadCredentials());
Paul Stewart8c116a92012-05-02 18:30:03 -0700198 MockVPNProvider provider;
199 EXPECT_CALL(manager_, vpn_provider()).WillRepeatedly(Return(&provider));
200 provider.services_.push_back(service_);
Darin Petkovcb715292012-04-25 13:04:37 +0200201 service_->Unload();
202 EXPECT_FALSE(service_->auto_connect());
203 EXPECT_FALSE(service_->save_credentials());
Paul Stewart8c116a92012-05-02 18:30:03 -0700204 EXPECT_TRUE(provider.services_.empty());
Darin Petkovcb715292012-04-25 13:04:37 +0200205}
206
Paul Stewartebd38562012-03-23 13:06:40 -0700207TEST_F(VPNServiceTest, InitPropertyStore) {
208 EXPECT_CALL(*driver_, InitPropertyStore(service_->mutable_store()));
209 service_->InitDriverPropertyStore();
210}
211
Darin Petkov1d0080a2012-04-30 17:10:36 +0200212TEST_F(VPNServiceTest, MakeFavorite) {
213 EXPECT_FALSE(service_->favorite());
214 EXPECT_FALSE(service_->auto_connect());
215 service_->MakeFavorite();
216 EXPECT_TRUE(service_->favorite());
217 EXPECT_FALSE(service_->auto_connect());
218}
219
Darin Petkov5eb05422012-05-11 15:45:25 +0200220TEST_F(VPNServiceTest, SetConnection) {
221 EXPECT_FALSE(service_->connection_binder_.get());
222 EXPECT_FALSE(service_->connection());
223 EXPECT_CALL(*sockets_, Socket(_, _, _)).WillOnce(Return(-1));
224 service_->SetConnection(connection_);
225 ASSERT_TRUE(service_->connection_binder_.get());
226 EXPECT_EQ(connection_.get(),
227 service_->connection_binder_->connection().get());
228 EXPECT_EQ(connection_.get(), service_->connection().get());
229 EXPECT_CALL(*driver_, OnConnectionDisconnected()).Times(0);
230}
231
232TEST_F(VPNServiceTest, OnConnectionDisconnected) {
233 EXPECT_CALL(*sockets_, Socket(_, _, _)).WillOnce(Return(-1));
234 service_->SetConnection(connection_);
235 EXPECT_CALL(*driver_, OnConnectionDisconnected()).Times(1);
236 connection_->OnLowerDisconnect();
237}
238
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100239TEST_F(VPNServiceTest, IsAutoConnectableOffline) {
240 EXPECT_TRUE(service_->connectable());
241 const char *reason = NULL;
242 EXPECT_CALL(manager_, IsOnline()).WillOnce(Return(false));
243 EXPECT_FALSE(IsAutoConnectable(&reason));
244 EXPECT_STREQ(GetAutoConnOffline(), reason);
245}
246
247TEST_F(VPNServiceTest, IsAutoConnectableNeverConnected) {
Darin Petkov79349f02013-01-24 16:18:26 +0100248 EXPECT_TRUE(service_->connectable());
249 EXPECT_FALSE(service_->has_ever_connected());
Darin Petkov79349f02013-01-24 16:18:26 +0100250 const char *reason = NULL;
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100251 EXPECT_CALL(manager_, IsOnline()).WillOnce(Return(true));
252 EXPECT_FALSE(IsAutoConnectable(&reason));
253 EXPECT_STREQ(GetAutoConnNeverConnected(), reason);
254}
Darin Petkov79349f02013-01-24 16:18:26 +0100255
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100256TEST_F(VPNServiceTest, IsAutoConnectableVPNAlreadyActive) {
257 EXPECT_TRUE(service_->connectable());
Darin Petkov79349f02013-01-24 16:18:26 +0100258 SetHasEverConnected(true);
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100259 EXPECT_CALL(manager_, IsOnline()).WillOnce(Return(true));
260 MockVPNProvider provider;
261 EXPECT_CALL(manager_, vpn_provider()).WillOnce(Return(&provider));
262 EXPECT_CALL(provider, HasActiveService()).WillOnce(Return(true));
263 const char *reason = NULL;
264 EXPECT_FALSE(IsAutoConnectable(&reason));
265 EXPECT_STREQ(GetAutoConnVPNAlreadyActive(), reason);
266}
Darin Petkov79349f02013-01-24 16:18:26 +0100267
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100268TEST_F(VPNServiceTest, IsAutoConnectableNotConnectable) {
269 const char *reason = NULL;
Darin Petkov79349f02013-01-24 16:18:26 +0100270 SetConnectable(false);
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100271 EXPECT_FALSE(IsAutoConnectable(&reason));
272}
273
274TEST_F(VPNServiceTest, IsAutoConnectable) {
275 EXPECT_TRUE(service_->connectable());
276 SetHasEverConnected(true);
277 EXPECT_CALL(manager_, IsOnline()).WillOnce(Return(true));
278 MockVPNProvider provider;
279 EXPECT_CALL(manager_, vpn_provider()).WillOnce(Return(&provider));
280 EXPECT_CALL(provider, HasActiveService()).WillOnce(Return(false));
281 const char *reason = NULL;
282 EXPECT_TRUE(IsAutoConnectable(&reason));
283 EXPECT_FALSE(reason);
Darin Petkov79349f02013-01-24 16:18:26 +0100284}
285
Darin Petkov33af05c2012-02-28 10:10:30 +0100286} // namespace shill