blob: aa23a2fa32a123498b0d1461cf857e5a6e7b0092 [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_provider.h"
6
7#include <chromeos/dbus/service_constants.h>
8#include <gtest/gtest.h>
9
10#include "shill/error.h"
11#include "shill/nice_mock_control.h"
12#include "shill/mock_adaptors.h"
Darin Petkov79d74c92012-03-07 17:20:32 +010013#include "shill/mock_device_info.h"
Paul Stewartca6abd42012-03-01 15:45:29 -080014#include "shill/mock_manager.h"
Darin Petkov33af05c2012-02-28 10:10:30 +010015#include "shill/mock_metrics.h"
Paul Stewart66815332012-04-09 18:09:36 -070016#include "shill/mock_profile.h"
17#include "shill/mock_store.h"
Paul Stewartca6abd42012-03-01 15:45:29 -080018#include "shill/mock_vpn_driver.h"
Paul Stewart65512e12012-03-26 18:01:08 -070019#include "shill/mock_vpn_service.h"
Darin Petkov33af05c2012-02-28 10:10:30 +010020
Paul Stewartca6abd42012-03-01 15:45:29 -080021using std::string;
22using testing::_;
Paul Stewart66815332012-04-09 18:09:36 -070023using testing::DoAll;
24using testing::NiceMock;
Paul Stewartca6abd42012-03-01 15:45:29 -080025using testing::Return;
Paul Stewart66815332012-04-09 18:09:36 -070026using testing::SetArgumentPointee;
Paul Stewartca6abd42012-03-01 15:45:29 -080027
Darin Petkov33af05c2012-02-28 10:10:30 +010028namespace shill {
29
30class VPNProviderTest : public testing::Test {
31 public:
32 VPNProviderTest()
Thieu Le6c1e3bb2013-02-06 15:20:35 -080033 : metrics_(NULL),
34 manager_(&control_, NULL, &metrics_, NULL),
Darin Petkov79d74c92012-03-07 17:20:32 +010035 device_info_(&control_, NULL, &metrics_, &manager_),
Paul Stewartca6abd42012-03-01 15:45:29 -080036 provider_(&control_, NULL, &metrics_, &manager_) {}
Darin Petkov33af05c2012-02-28 10:10:30 +010037
38 virtual ~VPNProviderTest() {}
39
40 protected:
Darin Petkov02867712012-03-12 14:25:05 +010041 static const char kHost[];
42 static const char kName[];
43
Darin Petkov457728b2013-01-09 09:49:08 +010044 string GetServiceFriendlyName(const ServiceRefPtr &service) {
45 return service->friendly_name();
46 }
47
Darin Petkov4cbff5b2013-01-29 16:29:05 +010048 void SetConnectState(const ServiceRefPtr &service,
49 Service::ConnectState state) {
50 service->state_ = state;
51 }
52
53 void AddService(const VPNServiceRefPtr &service) {
54 provider_.services_.push_back(service);
55 }
56
Darin Petkov9c6e9812013-03-26 13:49:07 +010057 VPNServiceRefPtr GetServiceAt(int idx) {
58 return provider_.services_[idx];
59 }
60
Darin Petkov33af05c2012-02-28 10:10:30 +010061 NiceMockControl control_;
62 MockMetrics metrics_;
Paul Stewartca6abd42012-03-01 15:45:29 -080063 MockManager manager_;
Darin Petkov79d74c92012-03-07 17:20:32 +010064 MockDeviceInfo device_info_;
Darin Petkov33af05c2012-02-28 10:10:30 +010065 VPNProvider provider_;
66};
67
Darin Petkov02867712012-03-12 14:25:05 +010068const char VPNProviderTest::kHost[] = "10.8.0.1";
69const char VPNProviderTest::kName[] = "vpn-name";
70
71TEST_F(VPNProviderTest, GetServiceNoType) {
Darin Petkov33af05c2012-02-28 10:10:30 +010072 KeyValueStore args;
73 Error e;
74 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
75 VPNServiceRefPtr service = provider_.GetService(args, &e);
76 EXPECT_EQ(Error::kNotSupported, e.type());
77 EXPECT_FALSE(service);
78}
79
Darin Petkov02867712012-03-12 14:25:05 +010080TEST_F(VPNProviderTest, GetServiceUnsupportedType) {
Darin Petkov33af05c2012-02-28 10:10:30 +010081 KeyValueStore args;
82 Error e;
83 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
84 args.SetString(flimflam::kProviderTypeProperty, "unknown-vpn-type");
Darin Petkov02867712012-03-12 14:25:05 +010085 args.SetString(flimflam::kProviderHostProperty, kHost);
Darin Petkov4e02ba22013-04-02 13:44:08 +020086 args.SetString(flimflam::kNameProperty, kName);
Darin Petkov33af05c2012-02-28 10:10:30 +010087 VPNServiceRefPtr service = provider_.GetService(args, &e);
88 EXPECT_EQ(Error::kNotSupported, e.type());
89 EXPECT_FALSE(service);
90}
91
Darin Petkov02867712012-03-12 14:25:05 +010092TEST_F(VPNProviderTest, GetService) {
Darin Petkov33af05c2012-02-28 10:10:30 +010093 KeyValueStore args;
94 Error e;
95 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
96 args.SetString(flimflam::kProviderTypeProperty, flimflam::kProviderOpenVpn);
Darin Petkov02867712012-03-12 14:25:05 +010097 args.SetString(flimflam::kProviderHostProperty, kHost);
Darin Petkov4e02ba22013-04-02 13:44:08 +020098 args.SetString(flimflam::kNameProperty, kName);
Darin Petkov79d74c92012-03-07 17:20:32 +010099 EXPECT_CALL(manager_, device_info()).WillOnce(Return(&device_info_));
100 EXPECT_CALL(manager_, RegisterService(_));
Paul Stewart39964fa2012-04-04 09:50:25 -0700101 VPNServiceRefPtr service0 = provider_.GetService(args, &e);
Darin Petkov33af05c2012-02-28 10:10:30 +0100102 EXPECT_TRUE(e.IsSuccess());
Paul Stewart39964fa2012-04-04 09:50:25 -0700103 ASSERT_TRUE(service0);
104 EXPECT_EQ("vpn_10_8_0_1_vpn_name", service0->GetStorageIdentifier());
Darin Petkov457728b2013-01-09 09:49:08 +0100105 EXPECT_EQ(kName, GetServiceFriendlyName(service0));
Paul Stewart39964fa2012-04-04 09:50:25 -0700106
Darin Petkov9c6e9812013-03-26 13:49:07 +0100107 // Configure the service to set its properties (including Provider.Host).
108 service0->Configure(args, &e);
109 EXPECT_TRUE(e.IsSuccess());
110
Paul Stewart39964fa2012-04-04 09:50:25 -0700111 // A second call should return the same service.
112 VPNServiceRefPtr service1 = provider_.GetService(args, &e);
113 EXPECT_TRUE(e.IsSuccess());
114 ASSERT_EQ(service0.get(), service1.get());
Darin Petkov33af05c2012-02-28 10:10:30 +0100115}
116
Paul Stewartca6abd42012-03-01 15:45:29 -0800117TEST_F(VPNProviderTest, OnDeviceInfoAvailable) {
118 const string kInterfaceName("tun0");
119 const int kInterfaceIndex = 1;
120
121 scoped_ptr<MockVPNDriver> bad_driver(new MockVPNDriver());
122 EXPECT_CALL(*bad_driver.get(), ClaimInterface(_, _))
123 .Times(2)
124 .WillRepeatedly(Return(false));
125 provider_.services_.push_back(
126 new VPNService(&control_, NULL, &metrics_, NULL, bad_driver.release()));
127
128 EXPECT_FALSE(provider_.OnDeviceInfoAvailable(kInterfaceName,
129 kInterfaceIndex));
130
131 scoped_ptr<MockVPNDriver> good_driver(new MockVPNDriver());
132 EXPECT_CALL(*good_driver.get(), ClaimInterface(_, _))
133 .WillOnce(Return(true));
134 provider_.services_.push_back(
135 new VPNService(&control_, NULL, &metrics_, NULL, good_driver.release()));
136
137 scoped_ptr<MockVPNDriver> dup_driver(new MockVPNDriver());
138 EXPECT_CALL(*dup_driver.get(), ClaimInterface(_, _))
139 .Times(0);
140 provider_.services_.push_back(
141 new VPNService(&control_, NULL, &metrics_, NULL, dup_driver.release()));
142
143 EXPECT_TRUE(provider_.OnDeviceInfoAvailable(kInterfaceName, kInterfaceIndex));
144 provider_.services_.clear();
145}
146
Paul Stewart65512e12012-03-26 18:01:08 -0700147TEST_F(VPNProviderTest, RemoveService) {
148 scoped_refptr<MockVPNService> service0(
149 new MockVPNService(&control_, NULL, &metrics_, NULL, NULL));
150 scoped_refptr<MockVPNService> service1(
151 new MockVPNService(&control_, NULL, &metrics_, NULL, NULL));
152 scoped_refptr<MockVPNService> service2(
153 new MockVPNService(&control_, NULL, &metrics_, NULL, NULL));
154
155 provider_.services_.push_back(service0.get());
156 provider_.services_.push_back(service1.get());
157 provider_.services_.push_back(service2.get());
158
159 ASSERT_EQ(3, provider_.services_.size());
160
161 provider_.RemoveService(service1);
162
163 EXPECT_EQ(2, provider_.services_.size());
164 EXPECT_EQ(service0, provider_.services_[0]);
165 EXPECT_EQ(service2, provider_.services_[1]);
166
167 provider_.RemoveService(service2);
168
169 EXPECT_EQ(1, provider_.services_.size());
170 EXPECT_EQ(service0, provider_.services_[0]);
171
172 provider_.RemoveService(service0);
173 EXPECT_EQ(0, provider_.services_.size());
174}
175
Paul Stewart66815332012-04-09 18:09:36 -0700176MATCHER_P(ServiceWithStorageId, storage_id, "") {
177 return arg->GetStorageIdentifier() == storage_id;
178}
179
180TEST_F(VPNProviderTest, CreateServicesFromProfile) {
181 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -0800182 new NiceMock<MockProfile>(&control_, &metrics_, &manager_, ""));
Paul Stewart66815332012-04-09 18:09:36 -0700183 NiceMock<MockStore> storage;
Darin Petkov9c6e9812013-03-26 13:49:07 +0100184 EXPECT_CALL(*profile, GetConstStorage()).WillRepeatedly(Return(&storage));
185 EXPECT_CALL(storage, GetString(_, _, _)).WillRepeatedly(Return(false));
Paul Stewart66815332012-04-09 18:09:36 -0700186
187 std::set<string> groups;
Darin Petkov9c6e9812013-03-26 13:49:07 +0100188
189 const string kNonVPNIdentifier("foo_1");
Paul Stewart66815332012-04-09 18:09:36 -0700190 groups.insert(kNonVPNIdentifier);
Darin Petkov9c6e9812013-03-26 13:49:07 +0100191
192 const string kVPNIdentifierNoProvider("vpn_no_provider");
193 groups.insert(kVPNIdentifierNoProvider);
194
195 const string kVPNIdentifierNoName("vpn_no_name");
196 groups.insert(kVPNIdentifierNoName);
197 const string kOpenVPNProvider(flimflam::kProviderOpenVpn);
198 EXPECT_CALL(storage, GetString(kVPNIdentifierNoName,
199 flimflam::kProviderTypeProperty,
200 _))
201 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kOpenVPNProvider),
202 Return(true)));
203
204 const string kVPNIdentifierNoHost("vpn_no_host");
205 groups.insert(kVPNIdentifierNoHost);
206 EXPECT_CALL(storage, GetString(kVPNIdentifierNoHost,
207 flimflam::kProviderTypeProperty,
208 _))
209 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kOpenVPNProvider),
210 Return(true)));
211 const string kName("name");
212 EXPECT_CALL(storage, GetString(kVPNIdentifierNoHost,
213 flimflam::kNameProperty, _))
214 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kName), Return(true)));
215
216 const string kVPNIdentifierValid("vpn_valid");
217 groups.insert(kVPNIdentifierValid);
218 EXPECT_CALL(storage, GetString(kVPNIdentifierValid,
219 flimflam::kProviderTypeProperty,
220 _))
221 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kOpenVPNProvider),
222 Return(true)));
223 EXPECT_CALL(storage, GetString(kVPNIdentifierValid,
224 flimflam::kNameProperty, _))
225 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kName), Return(true)));
226 const string kHost("1.2.3.4");
227 EXPECT_CALL(storage, GetString(kVPNIdentifierValid,
228 flimflam::kProviderHostProperty, _))
229 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kHost), Return(true)));
230
Paul Stewart66815332012-04-09 18:09:36 -0700231 EXPECT_CALL(storage, GetGroupsWithKey(flimflam::kProviderTypeProperty))
232 .WillRepeatedly(Return(groups));
233
Paul Stewart66815332012-04-09 18:09:36 -0700234 EXPECT_CALL(manager_, device_info())
235 .WillRepeatedly(Return(reinterpret_cast<DeviceInfo *>(NULL)));
Darin Petkov9c6e9812013-03-26 13:49:07 +0100236 EXPECT_CALL(manager_,
237 RegisterService(ServiceWithStorageId(kVPNIdentifierValid)));
238 EXPECT_CALL(*profile,
239 ConfigureService(ServiceWithStorageId(kVPNIdentifierValid)))
240 .WillOnce(Return(true));
Paul Stewart66815332012-04-09 18:09:36 -0700241 provider_.CreateServicesFromProfile(profile);
242
Darin Petkov9c6e9812013-03-26 13:49:07 +0100243 GetServiceAt(0)->driver()->args()->SetString(flimflam::kProviderHostProperty,
244 kHost);
Paul Stewart66815332012-04-09 18:09:36 -0700245 // Calling this again should not create any more services (checked by the
246 // Times(1) above).
247 provider_.CreateServicesFromProfile(profile);
248}
249
Darin Petkov9d1bbe72012-04-25 10:58:59 +0200250TEST_F(VPNProviderTest, CreateService) {
251 static const char kName[] = "test-vpn-service";
252 static const char kStorageID[] = "test_vpn_storage_id";
253 static const char *kTypes[] = {
254 flimflam::kProviderOpenVpn,
255 flimflam::kProviderL2tpIpsec,
256 };
257 const size_t kTypesCount = arraysize(kTypes);
258 EXPECT_CALL(manager_, device_info())
259 .Times(kTypesCount)
260 .WillRepeatedly(Return(&device_info_));
261 EXPECT_CALL(manager_, RegisterService(_)).Times(kTypesCount);
262 for (size_t i = 0; i < kTypesCount; i++) {
263 Error error;
264 VPNServiceRefPtr service =
265 provider_.CreateService(kTypes[i], kName, kStorageID, &error);
266 ASSERT_TRUE(service) << kTypes[i];
267 ASSERT_TRUE(service->driver()) << kTypes[i];
268 EXPECT_EQ(kTypes[i], service->driver()->GetProviderType());
Darin Petkov457728b2013-01-09 09:49:08 +0100269 EXPECT_EQ(kName, GetServiceFriendlyName(service)) << kTypes[i];
Darin Petkov9d1bbe72012-04-25 10:58:59 +0200270 EXPECT_EQ(kStorageID, service->GetStorageIdentifier()) << kTypes[i];
271 EXPECT_TRUE(error.IsSuccess()) << kTypes[i];
272 }
273 Error error;
274 VPNServiceRefPtr unknown_service =
275 provider_.CreateService("unknown-vpn-type", kName, kStorageID, &error);
276 EXPECT_FALSE(unknown_service);
277 EXPECT_EQ(Error::kNotSupported, error.type());
278}
279
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100280TEST_F(VPNProviderTest, HasActiveService) {
281 EXPECT_FALSE(provider_.HasActiveService());
282
283 scoped_refptr<MockVPNService> service0(
284 new MockVPNService(&control_, NULL, &metrics_, NULL, NULL));
285 scoped_refptr<MockVPNService> service1(
286 new MockVPNService(&control_, NULL, &metrics_, NULL, NULL));
287 scoped_refptr<MockVPNService> service2(
288 new MockVPNService(&control_, NULL, &metrics_, NULL, NULL));
289
290 AddService(service0);
291 AddService(service1);
292 AddService(service2);
293 EXPECT_FALSE(provider_.HasActiveService());
294
295 SetConnectState(service1, Service::kStateAssociating);
296 EXPECT_TRUE(provider_.HasActiveService());
297
298 SetConnectState(service1, Service::kStateOnline);
299 EXPECT_TRUE(provider_.HasActiveService());
300}
301
Darin Petkov33af05c2012-02-28 10:10:30 +0100302} // namespace shill