blob: 61777be28de804f74cb8b99c76ef449468e2ea8e [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()
Paul Stewartca6abd42012-03-01 15:45:29 -080033 : manager_(&control_, NULL, &metrics_, NULL),
Darin Petkov79d74c92012-03-07 17:20:32 +010034 device_info_(&control_, NULL, &metrics_, &manager_),
Paul Stewartca6abd42012-03-01 15:45:29 -080035 provider_(&control_, NULL, &metrics_, &manager_) {}
Darin Petkov33af05c2012-02-28 10:10:30 +010036
37 virtual ~VPNProviderTest() {}
38
39 protected:
Darin Petkov02867712012-03-12 14:25:05 +010040 static const char kHost[];
41 static const char kName[];
42
Darin Petkov457728b2013-01-09 09:49:08 +010043 string GetServiceFriendlyName(const ServiceRefPtr &service) {
44 return service->friendly_name();
45 }
46
Darin Petkov4cbff5b2013-01-29 16:29:05 +010047 void SetConnectState(const ServiceRefPtr &service,
48 Service::ConnectState state) {
49 service->state_ = state;
50 }
51
52 void AddService(const VPNServiceRefPtr &service) {
53 provider_.services_.push_back(service);
54 }
55
Darin Petkov33af05c2012-02-28 10:10:30 +010056 NiceMockControl control_;
57 MockMetrics metrics_;
Paul Stewartca6abd42012-03-01 15:45:29 -080058 MockManager manager_;
Darin Petkov79d74c92012-03-07 17:20:32 +010059 MockDeviceInfo device_info_;
Darin Petkov33af05c2012-02-28 10:10:30 +010060 VPNProvider provider_;
61};
62
Darin Petkov02867712012-03-12 14:25:05 +010063const char VPNProviderTest::kHost[] = "10.8.0.1";
64const char VPNProviderTest::kName[] = "vpn-name";
65
66TEST_F(VPNProviderTest, GetServiceNoType) {
Darin Petkov33af05c2012-02-28 10:10:30 +010067 KeyValueStore args;
68 Error e;
69 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
70 VPNServiceRefPtr service = provider_.GetService(args, &e);
71 EXPECT_EQ(Error::kNotSupported, e.type());
72 EXPECT_FALSE(service);
73}
74
Darin Petkov02867712012-03-12 14:25:05 +010075TEST_F(VPNProviderTest, GetServiceUnsupportedType) {
Darin Petkov33af05c2012-02-28 10:10:30 +010076 KeyValueStore args;
77 Error e;
78 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
79 args.SetString(flimflam::kProviderTypeProperty, "unknown-vpn-type");
Darin Petkov02867712012-03-12 14:25:05 +010080 args.SetString(flimflam::kProviderHostProperty, kHost);
81 args.SetString(flimflam::kProviderNameProperty, kName);
Darin Petkov33af05c2012-02-28 10:10:30 +010082 VPNServiceRefPtr service = provider_.GetService(args, &e);
83 EXPECT_EQ(Error::kNotSupported, e.type());
84 EXPECT_FALSE(service);
85}
86
Darin Petkov02867712012-03-12 14:25:05 +010087TEST_F(VPNProviderTest, GetService) {
Darin Petkov33af05c2012-02-28 10:10:30 +010088 KeyValueStore args;
89 Error e;
90 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
91 args.SetString(flimflam::kProviderTypeProperty, flimflam::kProviderOpenVpn);
Darin Petkov02867712012-03-12 14:25:05 +010092 args.SetString(flimflam::kProviderHostProperty, kHost);
93 args.SetString(flimflam::kProviderNameProperty, kName);
Darin Petkov79d74c92012-03-07 17:20:32 +010094 EXPECT_CALL(manager_, device_info()).WillOnce(Return(&device_info_));
95 EXPECT_CALL(manager_, RegisterService(_));
Paul Stewart39964fa2012-04-04 09:50:25 -070096 VPNServiceRefPtr service0 = provider_.GetService(args, &e);
Darin Petkov33af05c2012-02-28 10:10:30 +010097 EXPECT_TRUE(e.IsSuccess());
Paul Stewart39964fa2012-04-04 09:50:25 -070098 ASSERT_TRUE(service0);
99 EXPECT_EQ("vpn_10_8_0_1_vpn_name", service0->GetStorageIdentifier());
Darin Petkov457728b2013-01-09 09:49:08 +0100100 EXPECT_EQ(kName, GetServiceFriendlyName(service0));
Paul Stewart39964fa2012-04-04 09:50:25 -0700101
102 // A second call should return the same service.
103 VPNServiceRefPtr service1 = provider_.GetService(args, &e);
104 EXPECT_TRUE(e.IsSuccess());
105 ASSERT_EQ(service0.get(), service1.get());
Darin Petkov33af05c2012-02-28 10:10:30 +0100106}
107
Paul Stewartca6abd42012-03-01 15:45:29 -0800108TEST_F(VPNProviderTest, OnDeviceInfoAvailable) {
109 const string kInterfaceName("tun0");
110 const int kInterfaceIndex = 1;
111
112 scoped_ptr<MockVPNDriver> bad_driver(new MockVPNDriver());
113 EXPECT_CALL(*bad_driver.get(), ClaimInterface(_, _))
114 .Times(2)
115 .WillRepeatedly(Return(false));
116 provider_.services_.push_back(
117 new VPNService(&control_, NULL, &metrics_, NULL, bad_driver.release()));
118
119 EXPECT_FALSE(provider_.OnDeviceInfoAvailable(kInterfaceName,
120 kInterfaceIndex));
121
122 scoped_ptr<MockVPNDriver> good_driver(new MockVPNDriver());
123 EXPECT_CALL(*good_driver.get(), ClaimInterface(_, _))
124 .WillOnce(Return(true));
125 provider_.services_.push_back(
126 new VPNService(&control_, NULL, &metrics_, NULL, good_driver.release()));
127
128 scoped_ptr<MockVPNDriver> dup_driver(new MockVPNDriver());
129 EXPECT_CALL(*dup_driver.get(), ClaimInterface(_, _))
130 .Times(0);
131 provider_.services_.push_back(
132 new VPNService(&control_, NULL, &metrics_, NULL, dup_driver.release()));
133
134 EXPECT_TRUE(provider_.OnDeviceInfoAvailable(kInterfaceName, kInterfaceIndex));
135 provider_.services_.clear();
136}
137
Paul Stewart65512e12012-03-26 18:01:08 -0700138TEST_F(VPNProviderTest, RemoveService) {
139 scoped_refptr<MockVPNService> service0(
140 new MockVPNService(&control_, NULL, &metrics_, NULL, NULL));
141 scoped_refptr<MockVPNService> service1(
142 new MockVPNService(&control_, NULL, &metrics_, NULL, NULL));
143 scoped_refptr<MockVPNService> service2(
144 new MockVPNService(&control_, NULL, &metrics_, NULL, NULL));
145
146 provider_.services_.push_back(service0.get());
147 provider_.services_.push_back(service1.get());
148 provider_.services_.push_back(service2.get());
149
150 ASSERT_EQ(3, provider_.services_.size());
151
152 provider_.RemoveService(service1);
153
154 EXPECT_EQ(2, provider_.services_.size());
155 EXPECT_EQ(service0, provider_.services_[0]);
156 EXPECT_EQ(service2, provider_.services_[1]);
157
158 provider_.RemoveService(service2);
159
160 EXPECT_EQ(1, provider_.services_.size());
161 EXPECT_EQ(service0, provider_.services_[0]);
162
163 provider_.RemoveService(service0);
164 EXPECT_EQ(0, provider_.services_.size());
165}
166
Paul Stewart66815332012-04-09 18:09:36 -0700167MATCHER_P(ServiceWithStorageId, storage_id, "") {
168 return arg->GetStorageIdentifier() == storage_id;
169}
170
171TEST_F(VPNProviderTest, CreateServicesFromProfile) {
172 scoped_refptr<MockProfile> profile(
173 new NiceMock<MockProfile>(&control_, &manager_, ""));
174 NiceMock<MockStore> storage;
175 EXPECT_CALL(*profile, GetConstStorage())
176 .WillRepeatedly(Return(&storage));
177 EXPECT_CALL(storage, GetString(_, _, _))
178 .WillRepeatedly(Return(false));
179
180 std::set<string> groups;
181 const string kNonVPNIdentifier("foo_123_456");
182 groups.insert(kNonVPNIdentifier);
183 const string kVPNIdentifier0("vpn_123_456");
184 const string kVPNIdentifier1("vpn_789_012");
185 groups.insert(kVPNIdentifier0);
186 groups.insert(kVPNIdentifier1);
187 EXPECT_CALL(storage, GetGroupsWithKey(flimflam::kProviderTypeProperty))
188 .WillRepeatedly(Return(groups));
189
190 EXPECT_CALL(*profile, ConfigureService(ServiceWithStorageId(kVPNIdentifier1)))
191 .WillOnce(Return(true));
192
Paul Stewart451aa7f2012-04-11 19:07:58 -0700193 const string kName("name");
194 EXPECT_CALL(storage, GetString(_, flimflam::kNameProperty, _))
195 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kName), Return(true)));
196
Paul Stewart66815332012-04-09 18:09:36 -0700197 const string kProviderTypeUnknown("unknown");
198 EXPECT_CALL(storage, GetString(kVPNIdentifier0,
199 flimflam::kProviderTypeProperty,
200 _))
201 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kProviderTypeUnknown),
202 Return(true)));
Paul Stewart451aa7f2012-04-11 19:07:58 -0700203
Paul Stewart66815332012-04-09 18:09:36 -0700204 const string kProviderTypeOpenVPN(flimflam::kProviderOpenVpn);
205 EXPECT_CALL(storage, GetString(kVPNIdentifier1,
206 flimflam::kProviderTypeProperty,
207 _))
208 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kProviderTypeOpenVPN),
209 Return(true)));
210
211 EXPECT_CALL(manager_, device_info())
212 .WillRepeatedly(Return(reinterpret_cast<DeviceInfo *>(NULL)));
213
214 EXPECT_CALL(manager_, RegisterService(ServiceWithStorageId(kVPNIdentifier1)))
215 .Times(1);
216
217 provider_.CreateServicesFromProfile(profile);
218
219 // Calling this again should not create any more services (checked by the
220 // Times(1) above).
221 provider_.CreateServicesFromProfile(profile);
222}
223
Darin Petkov9d1bbe72012-04-25 10:58:59 +0200224TEST_F(VPNProviderTest, CreateService) {
225 static const char kName[] = "test-vpn-service";
226 static const char kStorageID[] = "test_vpn_storage_id";
227 static const char *kTypes[] = {
228 flimflam::kProviderOpenVpn,
229 flimflam::kProviderL2tpIpsec,
230 };
231 const size_t kTypesCount = arraysize(kTypes);
232 EXPECT_CALL(manager_, device_info())
233 .Times(kTypesCount)
234 .WillRepeatedly(Return(&device_info_));
235 EXPECT_CALL(manager_, RegisterService(_)).Times(kTypesCount);
236 for (size_t i = 0; i < kTypesCount; i++) {
237 Error error;
238 VPNServiceRefPtr service =
239 provider_.CreateService(kTypes[i], kName, kStorageID, &error);
240 ASSERT_TRUE(service) << kTypes[i];
241 ASSERT_TRUE(service->driver()) << kTypes[i];
242 EXPECT_EQ(kTypes[i], service->driver()->GetProviderType());
Darin Petkov457728b2013-01-09 09:49:08 +0100243 EXPECT_EQ(kName, GetServiceFriendlyName(service)) << kTypes[i];
Darin Petkov9d1bbe72012-04-25 10:58:59 +0200244 EXPECT_EQ(kStorageID, service->GetStorageIdentifier()) << kTypes[i];
245 EXPECT_TRUE(error.IsSuccess()) << kTypes[i];
246 }
247 Error error;
248 VPNServiceRefPtr unknown_service =
249 provider_.CreateService("unknown-vpn-type", kName, kStorageID, &error);
250 EXPECT_FALSE(unknown_service);
251 EXPECT_EQ(Error::kNotSupported, error.type());
252}
253
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100254TEST_F(VPNProviderTest, HasActiveService) {
255 EXPECT_FALSE(provider_.HasActiveService());
256
257 scoped_refptr<MockVPNService> service0(
258 new MockVPNService(&control_, NULL, &metrics_, NULL, NULL));
259 scoped_refptr<MockVPNService> service1(
260 new MockVPNService(&control_, NULL, &metrics_, NULL, NULL));
261 scoped_refptr<MockVPNService> service2(
262 new MockVPNService(&control_, NULL, &metrics_, NULL, NULL));
263
264 AddService(service0);
265 AddService(service1);
266 AddService(service2);
267 EXPECT_FALSE(provider_.HasActiveService());
268
269 SetConnectState(service1, Service::kStateAssociating);
270 EXPECT_TRUE(provider_.HasActiveService());
271
272 SetConnectState(service1, Service::kStateOnline);
273 EXPECT_TRUE(provider_.HasActiveService());
274}
275
Darin Petkov33af05c2012-02-28 10:10:30 +0100276} // namespace shill