blob: 5a66c76e404d2f805ae0bf0e834acff408a7b1a1 [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 Petkov33af05c2012-02-28 10:10:30 +010047 NiceMockControl control_;
48 MockMetrics metrics_;
Paul Stewartca6abd42012-03-01 15:45:29 -080049 MockManager manager_;
Darin Petkov79d74c92012-03-07 17:20:32 +010050 MockDeviceInfo device_info_;
Darin Petkov33af05c2012-02-28 10:10:30 +010051 VPNProvider provider_;
52};
53
Darin Petkov02867712012-03-12 14:25:05 +010054const char VPNProviderTest::kHost[] = "10.8.0.1";
55const char VPNProviderTest::kName[] = "vpn-name";
56
57TEST_F(VPNProviderTest, GetServiceNoType) {
Darin Petkov33af05c2012-02-28 10:10:30 +010058 KeyValueStore args;
59 Error e;
60 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
61 VPNServiceRefPtr service = provider_.GetService(args, &e);
62 EXPECT_EQ(Error::kNotSupported, e.type());
63 EXPECT_FALSE(service);
64}
65
Darin Petkov02867712012-03-12 14:25:05 +010066TEST_F(VPNProviderTest, GetServiceUnsupportedType) {
Darin Petkov33af05c2012-02-28 10:10:30 +010067 KeyValueStore args;
68 Error e;
69 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
70 args.SetString(flimflam::kProviderTypeProperty, "unknown-vpn-type");
Darin Petkov02867712012-03-12 14:25:05 +010071 args.SetString(flimflam::kProviderHostProperty, kHost);
72 args.SetString(flimflam::kProviderNameProperty, kName);
Darin Petkov33af05c2012-02-28 10:10:30 +010073 VPNServiceRefPtr service = provider_.GetService(args, &e);
74 EXPECT_EQ(Error::kNotSupported, e.type());
75 EXPECT_FALSE(service);
76}
77
Darin Petkov02867712012-03-12 14:25:05 +010078TEST_F(VPNProviderTest, GetService) {
Darin Petkov33af05c2012-02-28 10:10:30 +010079 KeyValueStore args;
80 Error e;
81 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
82 args.SetString(flimflam::kProviderTypeProperty, flimflam::kProviderOpenVpn);
Darin Petkov02867712012-03-12 14:25:05 +010083 args.SetString(flimflam::kProviderHostProperty, kHost);
84 args.SetString(flimflam::kProviderNameProperty, kName);
Darin Petkov79d74c92012-03-07 17:20:32 +010085 EXPECT_CALL(manager_, device_info()).WillOnce(Return(&device_info_));
86 EXPECT_CALL(manager_, RegisterService(_));
Paul Stewart39964fa2012-04-04 09:50:25 -070087 VPNServiceRefPtr service0 = provider_.GetService(args, &e);
Darin Petkov33af05c2012-02-28 10:10:30 +010088 EXPECT_TRUE(e.IsSuccess());
Paul Stewart39964fa2012-04-04 09:50:25 -070089 ASSERT_TRUE(service0);
90 EXPECT_EQ("vpn_10_8_0_1_vpn_name", service0->GetStorageIdentifier());
Darin Petkov457728b2013-01-09 09:49:08 +010091 EXPECT_EQ(kName, GetServiceFriendlyName(service0));
Paul Stewart39964fa2012-04-04 09:50:25 -070092
93 // A second call should return the same service.
94 VPNServiceRefPtr service1 = provider_.GetService(args, &e);
95 EXPECT_TRUE(e.IsSuccess());
96 ASSERT_EQ(service0.get(), service1.get());
Darin Petkov33af05c2012-02-28 10:10:30 +010097}
98
Paul Stewartca6abd42012-03-01 15:45:29 -080099TEST_F(VPNProviderTest, OnDeviceInfoAvailable) {
100 const string kInterfaceName("tun0");
101 const int kInterfaceIndex = 1;
102
103 scoped_ptr<MockVPNDriver> bad_driver(new MockVPNDriver());
104 EXPECT_CALL(*bad_driver.get(), ClaimInterface(_, _))
105 .Times(2)
106 .WillRepeatedly(Return(false));
107 provider_.services_.push_back(
108 new VPNService(&control_, NULL, &metrics_, NULL, bad_driver.release()));
109
110 EXPECT_FALSE(provider_.OnDeviceInfoAvailable(kInterfaceName,
111 kInterfaceIndex));
112
113 scoped_ptr<MockVPNDriver> good_driver(new MockVPNDriver());
114 EXPECT_CALL(*good_driver.get(), ClaimInterface(_, _))
115 .WillOnce(Return(true));
116 provider_.services_.push_back(
117 new VPNService(&control_, NULL, &metrics_, NULL, good_driver.release()));
118
119 scoped_ptr<MockVPNDriver> dup_driver(new MockVPNDriver());
120 EXPECT_CALL(*dup_driver.get(), ClaimInterface(_, _))
121 .Times(0);
122 provider_.services_.push_back(
123 new VPNService(&control_, NULL, &metrics_, NULL, dup_driver.release()));
124
125 EXPECT_TRUE(provider_.OnDeviceInfoAvailable(kInterfaceName, kInterfaceIndex));
126 provider_.services_.clear();
127}
128
Paul Stewart65512e12012-03-26 18:01:08 -0700129TEST_F(VPNProviderTest, RemoveService) {
130 scoped_refptr<MockVPNService> service0(
131 new MockVPNService(&control_, NULL, &metrics_, NULL, NULL));
132 scoped_refptr<MockVPNService> service1(
133 new MockVPNService(&control_, NULL, &metrics_, NULL, NULL));
134 scoped_refptr<MockVPNService> service2(
135 new MockVPNService(&control_, NULL, &metrics_, NULL, NULL));
136
137 provider_.services_.push_back(service0.get());
138 provider_.services_.push_back(service1.get());
139 provider_.services_.push_back(service2.get());
140
141 ASSERT_EQ(3, provider_.services_.size());
142
143 provider_.RemoveService(service1);
144
145 EXPECT_EQ(2, provider_.services_.size());
146 EXPECT_EQ(service0, provider_.services_[0]);
147 EXPECT_EQ(service2, provider_.services_[1]);
148
149 provider_.RemoveService(service2);
150
151 EXPECT_EQ(1, provider_.services_.size());
152 EXPECT_EQ(service0, provider_.services_[0]);
153
154 provider_.RemoveService(service0);
155 EXPECT_EQ(0, provider_.services_.size());
156}
157
Paul Stewart66815332012-04-09 18:09:36 -0700158MATCHER_P(ServiceWithStorageId, storage_id, "") {
159 return arg->GetStorageIdentifier() == storage_id;
160}
161
162TEST_F(VPNProviderTest, CreateServicesFromProfile) {
163 scoped_refptr<MockProfile> profile(
164 new NiceMock<MockProfile>(&control_, &manager_, ""));
165 NiceMock<MockStore> storage;
166 EXPECT_CALL(*profile, GetConstStorage())
167 .WillRepeatedly(Return(&storage));
168 EXPECT_CALL(storage, GetString(_, _, _))
169 .WillRepeatedly(Return(false));
170
171 std::set<string> groups;
172 const string kNonVPNIdentifier("foo_123_456");
173 groups.insert(kNonVPNIdentifier);
174 const string kVPNIdentifier0("vpn_123_456");
175 const string kVPNIdentifier1("vpn_789_012");
176 groups.insert(kVPNIdentifier0);
177 groups.insert(kVPNIdentifier1);
178 EXPECT_CALL(storage, GetGroupsWithKey(flimflam::kProviderTypeProperty))
179 .WillRepeatedly(Return(groups));
180
181 EXPECT_CALL(*profile, ConfigureService(ServiceWithStorageId(kVPNIdentifier1)))
182 .WillOnce(Return(true));
183
Paul Stewart451aa7f2012-04-11 19:07:58 -0700184 const string kName("name");
185 EXPECT_CALL(storage, GetString(_, flimflam::kNameProperty, _))
186 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kName), Return(true)));
187
Paul Stewart66815332012-04-09 18:09:36 -0700188 const string kProviderTypeUnknown("unknown");
189 EXPECT_CALL(storage, GetString(kVPNIdentifier0,
190 flimflam::kProviderTypeProperty,
191 _))
192 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kProviderTypeUnknown),
193 Return(true)));
Paul Stewart451aa7f2012-04-11 19:07:58 -0700194
Paul Stewart66815332012-04-09 18:09:36 -0700195 const string kProviderTypeOpenVPN(flimflam::kProviderOpenVpn);
196 EXPECT_CALL(storage, GetString(kVPNIdentifier1,
197 flimflam::kProviderTypeProperty,
198 _))
199 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kProviderTypeOpenVPN),
200 Return(true)));
201
202 EXPECT_CALL(manager_, device_info())
203 .WillRepeatedly(Return(reinterpret_cast<DeviceInfo *>(NULL)));
204
205 EXPECT_CALL(manager_, RegisterService(ServiceWithStorageId(kVPNIdentifier1)))
206 .Times(1);
207
208 provider_.CreateServicesFromProfile(profile);
209
210 // Calling this again should not create any more services (checked by the
211 // Times(1) above).
212 provider_.CreateServicesFromProfile(profile);
213}
214
Darin Petkov9d1bbe72012-04-25 10:58:59 +0200215TEST_F(VPNProviderTest, CreateService) {
216 static const char kName[] = "test-vpn-service";
217 static const char kStorageID[] = "test_vpn_storage_id";
218 static const char *kTypes[] = {
219 flimflam::kProviderOpenVpn,
220 flimflam::kProviderL2tpIpsec,
221 };
222 const size_t kTypesCount = arraysize(kTypes);
223 EXPECT_CALL(manager_, device_info())
224 .Times(kTypesCount)
225 .WillRepeatedly(Return(&device_info_));
226 EXPECT_CALL(manager_, RegisterService(_)).Times(kTypesCount);
227 for (size_t i = 0; i < kTypesCount; i++) {
228 Error error;
229 VPNServiceRefPtr service =
230 provider_.CreateService(kTypes[i], kName, kStorageID, &error);
231 ASSERT_TRUE(service) << kTypes[i];
232 ASSERT_TRUE(service->driver()) << kTypes[i];
233 EXPECT_EQ(kTypes[i], service->driver()->GetProviderType());
Darin Petkov457728b2013-01-09 09:49:08 +0100234 EXPECT_EQ(kName, GetServiceFriendlyName(service)) << kTypes[i];
Darin Petkov9d1bbe72012-04-25 10:58:59 +0200235 EXPECT_EQ(kStorageID, service->GetStorageIdentifier()) << kTypes[i];
236 EXPECT_TRUE(error.IsSuccess()) << kTypes[i];
237 }
238 Error error;
239 VPNServiceRefPtr unknown_service =
240 provider_.CreateService("unknown-vpn-type", kName, kStorageID, &error);
241 EXPECT_FALSE(unknown_service);
242 EXPECT_EQ(Error::kNotSupported, error.type());
243}
244
Darin Petkov33af05c2012-02-28 10:10:30 +0100245} // namespace shill