blob: fe221f3d0eb43b5d09d844df68407e616a5f8292 [file] [log] [blame]
Darin Petkovb451d6e2012-04-23 11:56:41 +02001// 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_driver.h"
6
7#include <base/stl_util.h>
8#include <base/string_number_conversions.h>
9#include <chromeos/dbus/service_constants.h>
10#include <gmock/gmock.h>
11#include <gtest/gtest.h>
12
Darin Petkov0e9735d2012-04-24 12:33:45 +020013#include "shill/event_dispatcher.h"
14#include "shill/glib.h"
15#include "shill/mock_connection.h"
16#include "shill/mock_device_info.h"
17#include "shill/mock_glib.h"
18#include "shill/mock_manager.h"
19#include "shill/mock_metrics.h"
20#include "shill/mock_service.h"
Darin Petkovb451d6e2012-04-23 11:56:41 +020021#include "shill/mock_store.h"
Darin Petkov0e9735d2012-04-24 12:33:45 +020022#include "shill/nice_mock_control.h"
Darin Petkovb451d6e2012-04-23 11:56:41 +020023#include "shill/property_store.h"
24
25using std::string;
26using testing::_;
27using testing::AnyNumber;
Darin Petkov0e9735d2012-04-24 12:33:45 +020028using testing::NiceMock;
Darin Petkovb451d6e2012-04-23 11:56:41 +020029using testing::Return;
30using testing::SetArgumentPointee;
Darin Petkov0e9735d2012-04-24 12:33:45 +020031using testing::StrictMock;
Darin Petkovb451d6e2012-04-23 11:56:41 +020032using testing::Test;
33
34namespace shill {
35
36namespace {
Darin Petkov602303f2012-06-06 12:15:59 +020037
Darin Petkovb451d6e2012-04-23 11:56:41 +020038const char kHostProperty[] = "VPN.Host";
39const char kOTPProperty[] = "VPN.OTP";
Darin Petkovcb715292012-04-25 13:04:37 +020040const char kPINProperty[] = "VPN.PIN";
Darin Petkov4e9066f2012-06-11 13:17:06 +020041const char kPSKProperty[] = "VPN.PSK";
Darin Petkovb451d6e2012-04-23 11:56:41 +020042const char kPasswordProperty[] = "VPN.Password";
43const char kPortProperty[] = "VPN.Port";
Darin Petkovcb715292012-04-25 13:04:37 +020044
45const char kPIN[] = "5555";
46const char kPassword[] = "random-password";
47const char kPort[] = "1234";
48const char kStorageID[] = "vpn_service_id";
49
Darin Petkovb451d6e2012-04-23 11:56:41 +020050} // namespace
51
52class VPNDriverUnderTest : public VPNDriver {
53 public:
Darin Petkov602303f2012-06-06 12:15:59 +020054 VPNDriverUnderTest(EventDispatcher *dispatcher, Manager *manager);
Darin Petkovb451d6e2012-04-23 11:56:41 +020055 virtual ~VPNDriverUnderTest() {}
56
57 // Inherited from VPNDriver.
58 MOCK_METHOD2(ClaimInterface, bool(const string &link_name,
59 int interface_index));
60 MOCK_METHOD2(Connect, void(const VPNServiceRefPtr &service, Error *error));
61 MOCK_METHOD0(Disconnect, void());
Darin Petkov5eb05422012-05-11 15:45:25 +020062 MOCK_METHOD0(OnConnectionDisconnected, void());
Darin Petkovb451d6e2012-04-23 11:56:41 +020063 MOCK_CONST_METHOD0(GetProviderType, string());
64
65 private:
66 static const Property kProperties[];
67
68 DISALLOW_COPY_AND_ASSIGN(VPNDriverUnderTest);
69};
70
71// static
72const VPNDriverUnderTest::Property VPNDriverUnderTest::kProperties[] = {
73 { kHostProperty, 0 },
Darin Petkovcb715292012-04-25 13:04:37 +020074 { kOTPProperty, Property::kEphemeral },
75 { kPINProperty, Property::kWriteOnly },
Darin Petkov4e9066f2012-06-11 13:17:06 +020076 { kPSKProperty, Property::kCredential },
Darin Petkovcb715292012-04-25 13:04:37 +020077 { kPasswordProperty, Property::kCredential },
Darin Petkovb451d6e2012-04-23 11:56:41 +020078 { kPortProperty, 0 },
79 { flimflam::kProviderNameProperty, 0 },
80};
81
Darin Petkov602303f2012-06-06 12:15:59 +020082VPNDriverUnderTest::VPNDriverUnderTest(
83 EventDispatcher *dispatcher, Manager *manager)
84 : VPNDriver(dispatcher, manager, kProperties, arraysize(kProperties)) {}
Darin Petkovb451d6e2012-04-23 11:56:41 +020085
86class VPNDriverTest : public Test {
87 public:
Darin Petkov0e9735d2012-04-24 12:33:45 +020088 VPNDriverTest()
89 : device_info_(&control_, &dispatcher_, &metrics_, &manager_),
90 manager_(&control_, &dispatcher_, &metrics_, &glib_),
Darin Petkov602303f2012-06-06 12:15:59 +020091 driver_(&dispatcher_, &manager_) {}
Darin Petkovb451d6e2012-04-23 11:56:41 +020092
93 virtual ~VPNDriverTest() {}
94
95 protected:
96 void SetArg(const string &arg, const string &value) {
97 driver_.args()->SetString(arg, value);
98 }
99
100 KeyValueStore *GetArgs() { return driver_.args(); }
101
Paul Stewart8e7e4592012-04-29 09:47:48 -0700102 bool GetProviderProperty(const PropertyStore &store,
103 const string &key,
104 string *value);
Darin Petkovb451d6e2012-04-23 11:56:41 +0200105
Darin Petkov0e9735d2012-04-24 12:33:45 +0200106 NiceMockControl control_;
107 NiceMock<MockDeviceInfo> device_info_;
108 EventDispatcher dispatcher_;
109 MockMetrics metrics_;
110 MockGLib glib_;
111 MockManager manager_;
Darin Petkovb451d6e2012-04-23 11:56:41 +0200112 VPNDriverUnderTest driver_;
113};
114
Paul Stewart8e7e4592012-04-29 09:47:48 -0700115bool VPNDriverTest::GetProviderProperty(const PropertyStore &store,
116 const string &key,
117 string *value) {
Paul Stewart8e7e4592012-04-29 09:47:48 -0700118 KeyValueStore provider_properties;
Paul Stewarte6e8e492013-01-17 11:00:50 -0800119 Error error;
120 EXPECT_TRUE(store.GetKeyValueStoreProperty(
121 flimflam::kProviderProperty, &provider_properties, &error));
Paul Stewart8e7e4592012-04-29 09:47:48 -0700122 if (!provider_properties.ContainsString(key)) {
123 return false;
Darin Petkovb451d6e2012-04-23 11:56:41 +0200124 }
Paul Stewart8e7e4592012-04-29 09:47:48 -0700125 if (value != NULL) {
126 *value = provider_properties.GetString(key);
Darin Petkovb451d6e2012-04-23 11:56:41 +0200127 }
Paul Stewart8e7e4592012-04-29 09:47:48 -0700128 return true;
Darin Petkovb451d6e2012-04-23 11:56:41 +0200129}
130
131TEST_F(VPNDriverTest, Load) {
132 MockStore storage;
Darin Petkov4e9066f2012-06-11 13:17:06 +0200133 GetArgs()->SetString(kHostProperty, "1.2.3.4");
134 GetArgs()->SetString(kPSKProperty, "1234");
Darin Petkovb451d6e2012-04-23 11:56:41 +0200135 EXPECT_CALL(storage, GetString(kStorageID, _, _))
136 .WillRepeatedly(Return(false));
Darin Petkovcb715292012-04-25 13:04:37 +0200137 EXPECT_CALL(storage, GetString(_, kOTPProperty, _)).Times(0);
138 EXPECT_CALL(storage, GetCryptedString(_, kOTPProperty, _)).Times(0);
Darin Petkovb451d6e2012-04-23 11:56:41 +0200139 EXPECT_CALL(storage, GetString(kStorageID, kPortProperty, _))
Darin Petkovcb715292012-04-25 13:04:37 +0200140 .WillOnce(DoAll(SetArgumentPointee<2>(string(kPort)), Return(true)));
141 EXPECT_CALL(storage, GetString(kStorageID, kPINProperty, _))
142 .WillOnce(DoAll(SetArgumentPointee<2>(string(kPIN)), Return(true)));
Darin Petkov4e9066f2012-06-11 13:17:06 +0200143 EXPECT_CALL(storage, GetCryptedString(kStorageID, kPSKProperty, _))
144 .WillOnce(Return(false));
Darin Petkovb451d6e2012-04-23 11:56:41 +0200145 EXPECT_CALL(storage, GetCryptedString(kStorageID, kPasswordProperty, _))
Darin Petkovcb715292012-04-25 13:04:37 +0200146 .WillOnce(DoAll(SetArgumentPointee<2>(string(kPassword)), Return(true)));
Darin Petkovb451d6e2012-04-23 11:56:41 +0200147 EXPECT_TRUE(driver_.Load(&storage, kStorageID));
148 EXPECT_EQ(kPort, GetArgs()->LookupString(kPortProperty, ""));
Darin Petkovcb715292012-04-25 13:04:37 +0200149 EXPECT_EQ(kPIN, GetArgs()->LookupString(kPINProperty, ""));
Darin Petkovb451d6e2012-04-23 11:56:41 +0200150 EXPECT_EQ(kPassword, GetArgs()->LookupString(kPasswordProperty, ""));
Darin Petkov4e9066f2012-06-11 13:17:06 +0200151
152 // Properties missing from the persistent store should be deleted.
153 EXPECT_FALSE(GetArgs()->ContainsString(kHostProperty));
154 EXPECT_FALSE(GetArgs()->ContainsString(kPSKProperty));
Darin Petkovb451d6e2012-04-23 11:56:41 +0200155}
156
Darin Petkov4e9066f2012-06-11 13:17:06 +0200157TEST_F(VPNDriverTest, Save) {
158 SetArg(flimflam::kProviderNameProperty, "");
Darin Petkovcb715292012-04-25 13:04:37 +0200159 SetArg(kPINProperty, kPIN);
Darin Petkovb451d6e2012-04-23 11:56:41 +0200160 SetArg(kPortProperty, kPort);
161 SetArg(kPasswordProperty, kPassword);
162 SetArg(kOTPProperty, "987654");
163 MockStore storage;
Darin Petkov4e9066f2012-06-11 13:17:06 +0200164 EXPECT_CALL(storage,
165 SetString(kStorageID, flimflam::kProviderNameProperty, ""))
166 .WillOnce(Return(true));
Darin Petkovb451d6e2012-04-23 11:56:41 +0200167 EXPECT_CALL(storage, SetString(kStorageID, kPortProperty, kPort))
168 .WillOnce(Return(true));
Darin Petkovcb715292012-04-25 13:04:37 +0200169 EXPECT_CALL(storage, SetString(kStorageID, kPINProperty, kPIN))
170 .WillOnce(Return(true));
Darin Petkovb451d6e2012-04-23 11:56:41 +0200171 EXPECT_CALL(storage,
172 SetCryptedString(kStorageID, kPasswordProperty, kPassword))
173 .WillOnce(Return(true));
Darin Petkovcb715292012-04-25 13:04:37 +0200174 EXPECT_CALL(storage, SetCryptedString(_, kOTPProperty, _)).Times(0);
175 EXPECT_CALL(storage, SetString(_, kOTPProperty, _)).Times(0);
Darin Petkov4e9066f2012-06-11 13:17:06 +0200176 EXPECT_CALL(storage, DeleteKey(kStorageID, flimflam::kProviderNameProperty))
177 .Times(0);
178 EXPECT_CALL(storage, DeleteKey(kStorageID, kPSKProperty)).Times(1);
Darin Petkovb451d6e2012-04-23 11:56:41 +0200179 EXPECT_CALL(storage, DeleteKey(kStorageID, kHostProperty)).Times(1);
Darin Petkovcb715292012-04-25 13:04:37 +0200180 EXPECT_TRUE(driver_.Save(&storage, kStorageID, true));
181}
182
Darin Petkov4e9066f2012-06-11 13:17:06 +0200183TEST_F(VPNDriverTest, SaveNoCredentials) {
Darin Petkovcb715292012-04-25 13:04:37 +0200184 SetArg(kPasswordProperty, kPassword);
Darin Petkov4e9066f2012-06-11 13:17:06 +0200185 SetArg(kPSKProperty, "");
Darin Petkovcb715292012-04-25 13:04:37 +0200186 MockStore storage;
187 EXPECT_CALL(storage, SetString(_, kPasswordProperty, _)).Times(0);
188 EXPECT_CALL(storage, SetCryptedString(_, kPasswordProperty, _)).Times(0);
189 EXPECT_CALL(storage, DeleteKey(kStorageID, _)).Times(AnyNumber());
190 EXPECT_CALL(storage, DeleteKey(kStorageID, kPasswordProperty)).Times(1);
Darin Petkov4e9066f2012-06-11 13:17:06 +0200191 EXPECT_CALL(storage, DeleteKey(kStorageID, kPSKProperty)).Times(1);
Darin Petkovcb715292012-04-25 13:04:37 +0200192 EXPECT_TRUE(driver_.Save(&storage, kStorageID, false));
193}
194
195TEST_F(VPNDriverTest, UnloadCredentials) {
196 SetArg(kOTPProperty, "654321");
197 SetArg(kPasswordProperty, kPassword);
198 SetArg(kPortProperty, kPort);
199 driver_.UnloadCredentials();
200 EXPECT_FALSE(GetArgs()->ContainsString(kOTPProperty));
201 EXPECT_FALSE(GetArgs()->ContainsString(kPasswordProperty));
202 EXPECT_EQ(kPort, GetArgs()->LookupString(kPortProperty, ""));
Darin Petkovb451d6e2012-04-23 11:56:41 +0200203}
204
205TEST_F(VPNDriverTest, InitPropertyStore) {
206 // Figure out if the store is actually hooked up to the driver argument
207 // KeyValueStore.
208 PropertyStore store;
209 driver_.InitPropertyStore(&store);
210
211 // An un-set property should not be readable.
Paul Stewarte6e8e492013-01-17 11:00:50 -0800212 {
213 Error error;
214 EXPECT_FALSE(store.GetStringProperty(kPortProperty, NULL, &error));
215 EXPECT_EQ(Error::kInvalidArguments, error.type());
216 }
Paul Stewart8e7e4592012-04-29 09:47:48 -0700217 EXPECT_FALSE(GetProviderProperty(store, kPortProperty, NULL));
Darin Petkovb451d6e2012-04-23 11:56:41 +0200218
Darin Petkovb451d6e2012-04-23 11:56:41 +0200219 const string kProviderName = "boo";
220 SetArg(kPortProperty, kPort);
221 SetArg(kPasswordProperty, kPassword);
222 SetArg(flimflam::kProviderNameProperty, kProviderName);
Darin Petkov4e9066f2012-06-11 13:17:06 +0200223 SetArg(kHostProperty, "");
Darin Petkovb451d6e2012-04-23 11:56:41 +0200224
225 // We should not be able to read a property out of the driver args using the
226 // key to the args directly.
Paul Stewarte6e8e492013-01-17 11:00:50 -0800227 {
228 Error error;
229 EXPECT_FALSE(store.GetStringProperty(kPortProperty, NULL, &error));
230 EXPECT_EQ(Error::kInvalidArguments, error.type());
231 }
Darin Petkovb451d6e2012-04-23 11:56:41 +0200232
233 // We should instead be able to find it within the "Provider" stringmap.
Paul Stewarte6e8e492013-01-17 11:00:50 -0800234 {
235 string value;
236 EXPECT_TRUE(GetProviderProperty(store, kPortProperty, &value));
237 EXPECT_EQ(kPort, value);
238 }
Darin Petkovb451d6e2012-04-23 11:56:41 +0200239
Darin Petkov4e9066f2012-06-11 13:17:06 +0200240 // We should be able to read empty properties from the "Provider" stringmap.
241 {
242 string value;
243 EXPECT_TRUE(GetProviderProperty(store, kHostProperty, &value));
244 EXPECT_TRUE(value.empty());
245 }
246
Darin Petkovb451d6e2012-04-23 11:56:41 +0200247 // Properties that start with the prefix "Provider." should be mapped to the
248 // name in the Properties dict with the prefix removed.
Paul Stewarte6e8e492013-01-17 11:00:50 -0800249 {
250 string value;
251 EXPECT_TRUE(GetProviderProperty(store, flimflam::kNameProperty, &value));
252 EXPECT_EQ(kProviderName, value);
253 }
Darin Petkovb451d6e2012-04-23 11:56:41 +0200254
Paul Stewart8e7e4592012-04-29 09:47:48 -0700255 // If we clear a property, we should no longer be able to find it.
Darin Petkovb451d6e2012-04-23 11:56:41 +0200256 {
257 Error error;
258 EXPECT_TRUE(store.ClearProperty(kPortProperty, &error));
259 EXPECT_TRUE(error.IsSuccess());
Paul Stewart8e7e4592012-04-29 09:47:48 -0700260 EXPECT_FALSE(GetProviderProperty(store, kPortProperty, NULL));
Darin Petkovb451d6e2012-04-23 11:56:41 +0200261 }
262
263 // A second attempt to clear this property should return an error.
264 {
265 Error error;
266 EXPECT_FALSE(store.ClearProperty(kPortProperty, &error));
267 EXPECT_EQ(Error::kNotFound, error.type());
268 }
269
Darin Petkovcb715292012-04-25 13:04:37 +0200270 // Test write only properties.
Paul Stewart8e7e4592012-04-29 09:47:48 -0700271 EXPECT_FALSE(GetProviderProperty(store, kPINProperty, NULL));
Darin Petkovb451d6e2012-04-23 11:56:41 +0200272
273 // Write properties to the driver args using the PropertyStore interface.
Darin Petkovcb715292012-04-25 13:04:37 +0200274 {
275 const string kValue = "some-value";
Darin Petkovb451d6e2012-04-23 11:56:41 +0200276 Error error;
Darin Petkovcb715292012-04-25 13:04:37 +0200277 EXPECT_TRUE(store.SetStringProperty(kPINProperty, kValue, &error));
278 EXPECT_EQ(kValue, GetArgs()->GetString(kPINProperty));
Darin Petkovb451d6e2012-04-23 11:56:41 +0200279 }
280}
281
Darin Petkov602303f2012-06-06 12:15:59 +0200282TEST_F(VPNDriverTest, ConnectTimeout) {
283 EXPECT_EQ(&dispatcher_, driver_.dispatcher_);
284 EXPECT_TRUE(driver_.connect_timeout_callback_.IsCancelled());
285 EXPECT_FALSE(driver_.IsConnectTimeoutStarted());
286 EXPECT_EQ(VPNDriver::kDefaultConnectTimeoutSeconds,
287 driver_.connect_timeout_seconds_);
288 driver_.connect_timeout_seconds_ = 0;
289 driver_.StartConnectTimeout();
290 EXPECT_FALSE(driver_.connect_timeout_callback_.IsCancelled());
291 EXPECT_TRUE(driver_.IsConnectTimeoutStarted());
292 driver_.dispatcher_ = NULL;
293 driver_.StartConnectTimeout(); // Expect no crash.
294 EXPECT_CALL(driver_, OnConnectionDisconnected());
295 dispatcher_.DispatchPendingEvents();
296 EXPECT_TRUE(driver_.connect_timeout_callback_.IsCancelled());
297 EXPECT_FALSE(driver_.IsConnectTimeoutStarted());
298}
299
Darin Petkovb451d6e2012-04-23 11:56:41 +0200300} // namespace shill