blob: e0ad631b8ec6b465666e898feb8a46a3feedb47f [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"
Paul Stewart8e7e4592012-04-29 09:47:48 -070024#include "shill/property_store_inspector.h"
Darin Petkovb451d6e2012-04-23 11:56:41 +020025
26using std::string;
27using testing::_;
28using testing::AnyNumber;
Darin Petkov0e9735d2012-04-24 12:33:45 +020029using testing::NiceMock;
Darin Petkovb451d6e2012-04-23 11:56:41 +020030using testing::Return;
31using testing::SetArgumentPointee;
Darin Petkov0e9735d2012-04-24 12:33:45 +020032using testing::StrictMock;
Darin Petkovb451d6e2012-04-23 11:56:41 +020033using testing::Test;
34
35namespace shill {
36
37namespace {
38const char kHostProperty[] = "VPN.Host";
39const char kOTPProperty[] = "VPN.OTP";
Darin Petkovcb715292012-04-25 13:04:37 +020040const char kPINProperty[] = "VPN.PIN";
Darin Petkovb451d6e2012-04-23 11:56:41 +020041const char kPasswordProperty[] = "VPN.Password";
42const char kPortProperty[] = "VPN.Port";
Darin Petkovcb715292012-04-25 13:04:37 +020043
44const char kPIN[] = "5555";
45const char kPassword[] = "random-password";
46const char kPort[] = "1234";
47const char kStorageID[] = "vpn_service_id";
48
Darin Petkovb451d6e2012-04-23 11:56:41 +020049} // namespace
50
51class VPNDriverUnderTest : public VPNDriver {
52 public:
Darin Petkov0e9735d2012-04-24 12:33:45 +020053 VPNDriverUnderTest(Manager *manager);
Darin Petkovb451d6e2012-04-23 11:56:41 +020054 virtual ~VPNDriverUnderTest() {}
55
56 // Inherited from VPNDriver.
57 MOCK_METHOD2(ClaimInterface, bool(const string &link_name,
58 int interface_index));
59 MOCK_METHOD2(Connect, void(const VPNServiceRefPtr &service, Error *error));
60 MOCK_METHOD0(Disconnect, void());
Darin Petkov5eb05422012-05-11 15:45:25 +020061 MOCK_METHOD0(OnConnectionDisconnected, void());
Darin Petkovb451d6e2012-04-23 11:56:41 +020062 MOCK_CONST_METHOD0(GetProviderType, string());
63
64 private:
65 static const Property kProperties[];
66
67 DISALLOW_COPY_AND_ASSIGN(VPNDriverUnderTest);
68};
69
70// static
71const VPNDriverUnderTest::Property VPNDriverUnderTest::kProperties[] = {
72 { kHostProperty, 0 },
Darin Petkovcb715292012-04-25 13:04:37 +020073 { kOTPProperty, Property::kEphemeral },
74 { kPINProperty, Property::kWriteOnly },
75 { kPasswordProperty, Property::kCredential },
Darin Petkovb451d6e2012-04-23 11:56:41 +020076 { kPortProperty, 0 },
77 { flimflam::kProviderNameProperty, 0 },
78};
79
Darin Petkov0e9735d2012-04-24 12:33:45 +020080VPNDriverUnderTest::VPNDriverUnderTest(Manager *manager)
81 : VPNDriver(manager, kProperties, arraysize(kProperties)) {}
Darin Petkovb451d6e2012-04-23 11:56:41 +020082
83class VPNDriverTest : public Test {
84 public:
Darin Petkov0e9735d2012-04-24 12:33:45 +020085 VPNDriverTest()
86 : device_info_(&control_, &dispatcher_, &metrics_, &manager_),
87 manager_(&control_, &dispatcher_, &metrics_, &glib_),
88 driver_(&manager_) {}
Darin Petkovb451d6e2012-04-23 11:56:41 +020089
90 virtual ~VPNDriverTest() {}
91
92 protected:
93 void SetArg(const string &arg, const string &value) {
94 driver_.args()->SetString(arg, value);
95 }
96
97 KeyValueStore *GetArgs() { return driver_.args(); }
98
Paul Stewart8e7e4592012-04-29 09:47:48 -070099 bool GetProviderProperty(const PropertyStore &store,
100 const string &key,
101 string *value);
Darin Petkovb451d6e2012-04-23 11:56:41 +0200102
Darin Petkov0e9735d2012-04-24 12:33:45 +0200103 NiceMockControl control_;
104 NiceMock<MockDeviceInfo> device_info_;
105 EventDispatcher dispatcher_;
106 MockMetrics metrics_;
107 MockGLib glib_;
108 MockManager manager_;
Darin Petkovb451d6e2012-04-23 11:56:41 +0200109 VPNDriverUnderTest driver_;
110};
111
Paul Stewart8e7e4592012-04-29 09:47:48 -0700112bool VPNDriverTest::GetProviderProperty(const PropertyStore &store,
113 const string &key,
114 string *value) {
115 Error error;
116 PropertyStoreInspector inspector(&store);
117 KeyValueStore provider_properties;
118 EXPECT_TRUE(inspector.GetKeyValueStoreProperty(
119 flimflam::kProviderProperty, &provider_properties, &error));
120 if (!provider_properties.ContainsString(key)) {
121 return false;
Darin Petkovb451d6e2012-04-23 11:56:41 +0200122 }
Paul Stewart8e7e4592012-04-29 09:47:48 -0700123 if (value != NULL) {
124 *value = provider_properties.GetString(key);
Darin Petkovb451d6e2012-04-23 11:56:41 +0200125 }
Paul Stewart8e7e4592012-04-29 09:47:48 -0700126 return true;
Darin Petkovb451d6e2012-04-23 11:56:41 +0200127}
128
129TEST_F(VPNDriverTest, Load) {
130 MockStore storage;
Darin Petkovb451d6e2012-04-23 11:56:41 +0200131 EXPECT_CALL(storage, GetString(kStorageID, _, _))
132 .WillRepeatedly(Return(false));
Darin Petkovcb715292012-04-25 13:04:37 +0200133 EXPECT_CALL(storage, GetString(_, kOTPProperty, _)).Times(0);
134 EXPECT_CALL(storage, GetCryptedString(_, kOTPProperty, _)).Times(0);
Darin Petkovb451d6e2012-04-23 11:56:41 +0200135 EXPECT_CALL(storage, GetString(kStorageID, kPortProperty, _))
Darin Petkovcb715292012-04-25 13:04:37 +0200136 .WillOnce(DoAll(SetArgumentPointee<2>(string(kPort)), Return(true)));
137 EXPECT_CALL(storage, GetString(kStorageID, kPINProperty, _))
138 .WillOnce(DoAll(SetArgumentPointee<2>(string(kPIN)), Return(true)));
Darin Petkovb451d6e2012-04-23 11:56:41 +0200139 EXPECT_CALL(storage, GetCryptedString(kStorageID, kPasswordProperty, _))
Darin Petkovcb715292012-04-25 13:04:37 +0200140 .WillOnce(DoAll(SetArgumentPointee<2>(string(kPassword)), Return(true)));
Darin Petkovb451d6e2012-04-23 11:56:41 +0200141 EXPECT_TRUE(driver_.Load(&storage, kStorageID));
142 EXPECT_EQ(kPort, GetArgs()->LookupString(kPortProperty, ""));
Darin Petkovcb715292012-04-25 13:04:37 +0200143 EXPECT_EQ(kPIN, GetArgs()->LookupString(kPINProperty, ""));
Darin Petkovb451d6e2012-04-23 11:56:41 +0200144 EXPECT_EQ(kPassword, GetArgs()->LookupString(kPasswordProperty, ""));
145}
146
147TEST_F(VPNDriverTest, Store) {
Darin Petkovcb715292012-04-25 13:04:37 +0200148 SetArg(kPINProperty, kPIN);
Darin Petkovb451d6e2012-04-23 11:56:41 +0200149 SetArg(kPortProperty, kPort);
150 SetArg(kPasswordProperty, kPassword);
151 SetArg(kOTPProperty, "987654");
152 MockStore storage;
Darin Petkovb451d6e2012-04-23 11:56:41 +0200153 EXPECT_CALL(storage, SetString(kStorageID, kPortProperty, kPort))
154 .WillOnce(Return(true));
Darin Petkovcb715292012-04-25 13:04:37 +0200155 EXPECT_CALL(storage, SetString(kStorageID, kPINProperty, kPIN))
156 .WillOnce(Return(true));
Darin Petkovb451d6e2012-04-23 11:56:41 +0200157 EXPECT_CALL(storage,
158 SetCryptedString(kStorageID, kPasswordProperty, kPassword))
159 .WillOnce(Return(true));
Darin Petkovcb715292012-04-25 13:04:37 +0200160 EXPECT_CALL(storage, SetCryptedString(_, kOTPProperty, _)).Times(0);
161 EXPECT_CALL(storage, SetString(_, kOTPProperty, _)).Times(0);
Darin Petkovb451d6e2012-04-23 11:56:41 +0200162 EXPECT_CALL(storage, DeleteKey(kStorageID, _)).Times(AnyNumber());
163 EXPECT_CALL(storage, DeleteKey(kStorageID, kHostProperty)).Times(1);
Darin Petkovcb715292012-04-25 13:04:37 +0200164 EXPECT_TRUE(driver_.Save(&storage, kStorageID, true));
165}
166
167TEST_F(VPNDriverTest, StoreNoCredentials) {
168 SetArg(kPasswordProperty, kPassword);
169 MockStore storage;
170 EXPECT_CALL(storage, SetString(_, kPasswordProperty, _)).Times(0);
171 EXPECT_CALL(storage, SetCryptedString(_, kPasswordProperty, _)).Times(0);
172 EXPECT_CALL(storage, DeleteKey(kStorageID, _)).Times(AnyNumber());
173 EXPECT_CALL(storage, DeleteKey(kStorageID, kPasswordProperty)).Times(1);
174 EXPECT_TRUE(driver_.Save(&storage, kStorageID, false));
175}
176
177TEST_F(VPNDriverTest, UnloadCredentials) {
178 SetArg(kOTPProperty, "654321");
179 SetArg(kPasswordProperty, kPassword);
180 SetArg(kPortProperty, kPort);
181 driver_.UnloadCredentials();
182 EXPECT_FALSE(GetArgs()->ContainsString(kOTPProperty));
183 EXPECT_FALSE(GetArgs()->ContainsString(kPasswordProperty));
184 EXPECT_EQ(kPort, GetArgs()->LookupString(kPortProperty, ""));
Darin Petkovb451d6e2012-04-23 11:56:41 +0200185}
186
187TEST_F(VPNDriverTest, InitPropertyStore) {
188 // Figure out if the store is actually hooked up to the driver argument
189 // KeyValueStore.
190 PropertyStore store;
191 driver_.InitPropertyStore(&store);
Paul Stewart8e7e4592012-04-29 09:47:48 -0700192 PropertyStoreInspector inspector(&store);
Darin Petkovb451d6e2012-04-23 11:56:41 +0200193
194 // An un-set property should not be readable.
Paul Stewart8e7e4592012-04-29 09:47:48 -0700195 EXPECT_FALSE(inspector.ContainsStringProperty(kPortProperty));
196 EXPECT_FALSE(GetProviderProperty(store, kPortProperty, NULL));
Darin Petkovb451d6e2012-04-23 11:56:41 +0200197
Darin Petkovb451d6e2012-04-23 11:56:41 +0200198 const string kProviderName = "boo";
199 SetArg(kPortProperty, kPort);
200 SetArg(kPasswordProperty, kPassword);
201 SetArg(flimflam::kProviderNameProperty, kProviderName);
202
203 // We should not be able to read a property out of the driver args using the
204 // key to the args directly.
Paul Stewart8e7e4592012-04-29 09:47:48 -0700205 EXPECT_FALSE(inspector.ContainsStringProperty(kPortProperty));
Darin Petkovb451d6e2012-04-23 11:56:41 +0200206
207 // We should instead be able to find it within the "Provider" stringmap.
Paul Stewart8e7e4592012-04-29 09:47:48 -0700208 string value;
209 EXPECT_TRUE(GetProviderProperty(store, kPortProperty, &value));
210 EXPECT_EQ(kPort, value);
Darin Petkovb451d6e2012-04-23 11:56:41 +0200211
212 // Properties that start with the prefix "Provider." should be mapped to the
213 // name in the Properties dict with the prefix removed.
Paul Stewart8e7e4592012-04-29 09:47:48 -0700214 EXPECT_TRUE(GetProviderProperty(store, flimflam::kNameProperty, &value));
215 EXPECT_EQ(kProviderName, value);
Darin Petkovb451d6e2012-04-23 11:56:41 +0200216
Paul Stewart8e7e4592012-04-29 09:47:48 -0700217 // If we clear a property, we should no longer be able to find it.
Darin Petkovb451d6e2012-04-23 11:56:41 +0200218 {
219 Error error;
220 EXPECT_TRUE(store.ClearProperty(kPortProperty, &error));
221 EXPECT_TRUE(error.IsSuccess());
Paul Stewart8e7e4592012-04-29 09:47:48 -0700222 EXPECT_FALSE(GetProviderProperty(store, kPortProperty, NULL));
Darin Petkovb451d6e2012-04-23 11:56:41 +0200223 }
224
225 // A second attempt to clear this property should return an error.
226 {
227 Error error;
228 EXPECT_FALSE(store.ClearProperty(kPortProperty, &error));
229 EXPECT_EQ(Error::kNotFound, error.type());
230 }
231
Darin Petkovcb715292012-04-25 13:04:37 +0200232 // Test write only properties.
Paul Stewart8e7e4592012-04-29 09:47:48 -0700233 EXPECT_FALSE(GetProviderProperty(store, kPINProperty, NULL));
Darin Petkovb451d6e2012-04-23 11:56:41 +0200234
235 // Write properties to the driver args using the PropertyStore interface.
Darin Petkovcb715292012-04-25 13:04:37 +0200236 {
237 const string kValue = "some-value";
Darin Petkovb451d6e2012-04-23 11:56:41 +0200238 Error error;
Darin Petkovcb715292012-04-25 13:04:37 +0200239 EXPECT_TRUE(store.SetStringProperty(kPINProperty, kValue, &error));
240 EXPECT_EQ(kValue, GetArgs()->GetString(kPINProperty));
Darin Petkovb451d6e2012-04-23 11:56:41 +0200241 }
242}
243
Darin Petkovb451d6e2012-04-23 11:56:41 +0200244} // namespace shill