blob: eb20e7d8a2e46566a50276808773ca7c366f9151 [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/openvpn_driver.h"
6
Darin Petkova9b1fed2012-02-29 11:49:05 +01007#include <algorithm>
8
Paul Stewart291a4732012-03-14 19:19:02 -07009#include <base/file_path.h>
10#include <base/file_util.h>
11#include <base/string_util.h>
Darin Petkovfe6a9372012-02-28 16:25:06 +010012#include <chromeos/dbus/service_constants.h>
Darin Petkov33af05c2012-02-28 10:10:30 +010013#include <gtest/gtest.h>
14
Paul Stewartebd38562012-03-23 13:06:40 -070015#include "shill/dbus_adaptor.h"
Darin Petkov33af05c2012-02-28 10:10:30 +010016#include "shill/error.h"
Darin Petkov14c29ec2012-03-02 11:34:19 +010017#include "shill/ipconfig.h"
Christopher Wileyb691efd2012-08-09 13:51:51 -070018#include "shill/logging.h"
Darin Petkova9b1fed2012-02-29 11:49:05 +010019#include "shill/mock_adaptors.h"
Paul Stewartca6abd42012-03-01 15:45:29 -080020#include "shill/mock_device_info.h"
Darin Petkovf20994f2012-03-05 16:12:19 +010021#include "shill/mock_glib.h"
22#include "shill/mock_manager.h"
23#include "shill/mock_metrics.h"
Darin Petkov3c5e4dc2012-04-02 14:44:27 +020024#include "shill/mock_nss.h"
Darin Petkov46463022012-03-29 14:57:32 +020025#include "shill/mock_openvpn_management_server.h"
Darin Petkov5a850472012-06-06 15:44:24 +020026#include "shill/mock_process_killer.h"
Darin Petkova5e07ef2012-07-09 14:27:57 +020027#include "shill/mock_service.h"
Darin Petkovf3c71d72012-03-21 12:32:15 +010028#include "shill/mock_store.h"
Darin Petkov36a3ace2012-03-06 17:22:14 +010029#include "shill/mock_vpn.h"
Darin Petkov79d74c92012-03-07 17:20:32 +010030#include "shill/mock_vpn_service.h"
Darin Petkova9b1fed2012-02-29 11:49:05 +010031#include "shill/nice_mock_control.h"
Paul Stewart8e7e4592012-04-29 09:47:48 -070032#include "shill/property_store_inspector.h"
Darin Petkova9b1fed2012-02-29 11:49:05 +010033#include "shill/rpc_task.h"
Darin Petkovf20994f2012-03-05 16:12:19 +010034#include "shill/vpn.h"
Darin Petkov79d74c92012-03-07 17:20:32 +010035#include "shill/vpn_service.h"
Darin Petkov33af05c2012-02-28 10:10:30 +010036
Darin Petkov5a850472012-06-06 15:44:24 +020037using base::WeakPtr;
Darin Petkova9b1fed2012-02-29 11:49:05 +010038using std::map;
Darin Petkovfe6a9372012-02-28 16:25:06 +010039using std::string;
40using std::vector;
Paul Stewartca6abd42012-03-01 15:45:29 -080041using testing::_;
Darin Petkovf3c71d72012-03-21 12:32:15 +010042using testing::AnyNumber;
Paul Stewartca6abd42012-03-01 15:45:29 -080043using testing::DoAll;
Darin Petkov3c5e4dc2012-04-02 14:44:27 +020044using testing::ElementsAreArray;
Darin Petkove8587e32012-07-02 13:56:07 +020045using testing::Field;
Darin Petkovf3c71d72012-03-21 12:32:15 +010046using testing::Ne;
Paul Stewartce4ec192012-03-14 12:53:46 -070047using testing::NiceMock;
Paul Stewartca6abd42012-03-01 15:45:29 -080048using testing::Return;
49using testing::SetArgumentPointee;
Paul Stewartce4ec192012-03-14 12:53:46 -070050using testing::StrictMock;
Darin Petkovfe6a9372012-02-28 16:25:06 +010051
Darin Petkov33af05c2012-02-28 10:10:30 +010052namespace shill {
53
Darin Petkova9b1fed2012-02-29 11:49:05 +010054class OpenVPNDriverTest : public testing::Test,
55 public RPCTaskDelegate {
Darin Petkov33af05c2012-02-28 10:10:30 +010056 public:
Darin Petkovfe6a9372012-02-28 16:25:06 +010057 OpenVPNDriverTest()
Darin Petkov0e9735d2012-04-24 12:33:45 +020058 : device_info_(&control_, &dispatcher_, &metrics_, &manager_),
Darin Petkovf20994f2012-03-05 16:12:19 +010059 manager_(&control_, &dispatcher_, &metrics_, &glib_),
Darin Petkov79d74c92012-03-07 17:20:32 +010060 driver_(new OpenVPNDriver(&control_, &dispatcher_, &metrics_, &manager_,
Paul Stewart451aa7f2012-04-11 19:07:58 -070061 &device_info_, &glib_)),
Darin Petkov79d74c92012-03-07 17:20:32 +010062 service_(new MockVPNService(&control_, &dispatcher_, &metrics_,
63 &manager_, driver_)),
64 device_(new MockVPN(&control_, &dispatcher_, &metrics_, &manager_,
Darin Petkov46463022012-03-29 14:57:32 +020065 kInterfaceName, kInterfaceIndex)),
66 management_server_(new NiceMock<MockOpenVPNManagementServer>()) {
67 driver_->management_server_.reset(management_server_);
Darin Petkov3c5e4dc2012-04-02 14:44:27 +020068 driver_->nss_ = &nss_;
Darin Petkov5a850472012-06-06 15:44:24 +020069 driver_->process_killer_ = &process_killer_;
Darin Petkov46463022012-03-29 14:57:32 +020070 }
Darin Petkovfe6a9372012-02-28 16:25:06 +010071
Darin Petkov33af05c2012-02-28 10:10:30 +010072 virtual ~OpenVPNDriverTest() {}
73
Darin Petkov36a3ace2012-03-06 17:22:14 +010074 virtual void TearDown() {
Darin Petkova5e07ef2012-07-09 14:27:57 +020075 driver_->default_service_callback_tag_ = 0;
Darin Petkov79d74c92012-03-07 17:20:32 +010076 driver_->child_watch_tag_ = 0;
77 driver_->pid_ = 0;
78 driver_->device_ = NULL;
79 driver_->service_ = NULL;
Darin Petkov1a462de2012-05-02 11:10:48 +020080 if (!lsb_release_file_.empty()) {
81 EXPECT_TRUE(file_util::Delete(lsb_release_file_, false));
82 lsb_release_file_.clear();
83 }
Darin Petkov36a3ace2012-03-06 17:22:14 +010084 }
Darin Petkova9b1fed2012-02-29 11:49:05 +010085
Darin Petkov33af05c2012-02-28 10:10:30 +010086 protected:
Darin Petkovfe6a9372012-02-28 16:25:06 +010087 static const char kOption[];
88 static const char kProperty[];
89 static const char kValue[];
90 static const char kOption2[];
91 static const char kProperty2[];
92 static const char kValue2[];
Darin Petkov60596742012-03-05 12:17:17 +010093 static const char kGateway1[];
94 static const char kNetmask1[];
95 static const char kNetwork1[];
96 static const char kGateway2[];
97 static const char kNetmask2[];
98 static const char kNetwork2[];
Darin Petkov79d74c92012-03-07 17:20:32 +010099 static const char kInterfaceName[];
100 static const int kInterfaceIndex;
Darin Petkovfe6a9372012-02-28 16:25:06 +0100101
Darin Petkovb451d6e2012-04-23 11:56:41 +0200102 void SetArg(const string &arg, const string &value) {
103 driver_->args()->SetString(arg, value);
Darin Petkovfe6a9372012-02-28 16:25:06 +0100104 }
105
Darin Petkovf3c71d72012-03-21 12:32:15 +0100106 KeyValueStore *GetArgs() {
Darin Petkovb451d6e2012-04-23 11:56:41 +0200107 return driver_->args();
Darin Petkovf3c71d72012-03-21 12:32:15 +0100108 }
109
Paul Stewartca6abd42012-03-01 15:45:29 -0800110 // Used to assert that a flag appears in the options.
111 void ExpectInFlags(const vector<string> &options, const string &flag,
112 const string &value);
113
Darin Petkov1a462de2012-05-02 11:10:48 +0200114 void SetupLSBRelease();
115
Darin Petkov36a3ace2012-03-06 17:22:14 +0100116 // Inherited from RPCTaskDelegate.
Darin Petkov209e6292012-04-20 11:33:32 +0200117 virtual void GetLogin(string *user, string *password);
Darin Petkov36a3ace2012-03-06 17:22:14 +0100118 virtual void Notify(const string &reason, const map<string, string> &dict);
Paul Stewartca6abd42012-03-01 15:45:29 -0800119
Darin Petkova9b1fed2012-02-29 11:49:05 +0100120 NiceMockControl control_;
Darin Petkov0e9735d2012-04-24 12:33:45 +0200121 NiceMock<MockDeviceInfo> device_info_;
Darin Petkovf20994f2012-03-05 16:12:19 +0100122 EventDispatcher dispatcher_;
123 MockMetrics metrics_;
124 MockGLib glib_;
125 MockManager manager_;
Darin Petkov46463022012-03-29 14:57:32 +0200126 OpenVPNDriver *driver_; // Owned by |service_|.
Darin Petkov79d74c92012-03-07 17:20:32 +0100127 scoped_refptr<MockVPNService> service_;
128 scoped_refptr<MockVPN> device_;
Darin Petkov3c5e4dc2012-04-02 14:44:27 +0200129 MockNSS nss_;
Darin Petkov5a850472012-06-06 15:44:24 +0200130 MockProcessKiller process_killer_;
Darin Petkov46463022012-03-29 14:57:32 +0200131
132 // Owned by |driver_|.
133 NiceMock<MockOpenVPNManagementServer> *management_server_;
Darin Petkov1a462de2012-05-02 11:10:48 +0200134
135 FilePath lsb_release_file_;
Darin Petkov33af05c2012-02-28 10:10:30 +0100136};
137
Darin Petkovfe6a9372012-02-28 16:25:06 +0100138const char OpenVPNDriverTest::kOption[] = "--openvpn-option";
139const char OpenVPNDriverTest::kProperty[] = "OpenVPN.SomeProperty";
140const char OpenVPNDriverTest::kValue[] = "some-property-value";
141const char OpenVPNDriverTest::kOption2[] = "--openvpn-option2";
142const char OpenVPNDriverTest::kProperty2[] = "OpenVPN.SomeProperty2";
143const char OpenVPNDriverTest::kValue2[] = "some-property-value2";
Darin Petkov60596742012-03-05 12:17:17 +0100144const char OpenVPNDriverTest::kGateway1[] = "10.242.2.13";
145const char OpenVPNDriverTest::kNetmask1[] = "255.255.255.255";
146const char OpenVPNDriverTest::kNetwork1[] = "10.242.2.1";
147const char OpenVPNDriverTest::kGateway2[] = "10.242.2.14";
148const char OpenVPNDriverTest::kNetmask2[] = "255.255.0.0";
149const char OpenVPNDriverTest::kNetwork2[] = "192.168.0.0";
Darin Petkov79d74c92012-03-07 17:20:32 +0100150const char OpenVPNDriverTest::kInterfaceName[] = "tun0";
151const int OpenVPNDriverTest::kInterfaceIndex = 123;
Darin Petkovfe6a9372012-02-28 16:25:06 +0100152
Darin Petkov209e6292012-04-20 11:33:32 +0200153void OpenVPNDriverTest::GetLogin(string */*user*/, string */*password*/) {}
154
Darin Petkova9b1fed2012-02-29 11:49:05 +0100155void OpenVPNDriverTest::Notify(const string &/*reason*/,
156 const map<string, string> &/*dict*/) {}
157
Paul Stewartca6abd42012-03-01 15:45:29 -0800158void OpenVPNDriverTest::ExpectInFlags(const vector<string> &options,
159 const string &flag,
160 const string &value) {
161 vector<string>::const_iterator it =
162 std::find(options.begin(), options.end(), flag);
163
164 EXPECT_TRUE(it != options.end());
165 if (it != options.end())
Darin Petkov36a3ace2012-03-06 17:22:14 +0100166 return; // Don't crash below.
Paul Stewartca6abd42012-03-01 15:45:29 -0800167 it++;
168 EXPECT_TRUE(it != options.end());
169 if (it != options.end())
Darin Petkov36a3ace2012-03-06 17:22:14 +0100170 return; // Don't crash below.
Paul Stewartca6abd42012-03-01 15:45:29 -0800171 EXPECT_EQ(value, *it);
172}
173
Darin Petkov1a462de2012-05-02 11:10:48 +0200174void OpenVPNDriverTest::SetupLSBRelease() {
175 static const char kLSBReleaseContents[] =
176 "\n"
177 "=\n"
178 "foo=\n"
179 "=bar\n"
180 "zoo==\n"
181 "CHROMEOS_RELEASE_BOARD=x86-alex\n"
182 "CHROMEOS_RELEASE_NAME=Chromium OS\n"
183 "CHROMEOS_RELEASE_VERSION=2202.0\n";
184 EXPECT_TRUE(file_util::CreateTemporaryFile(&lsb_release_file_));
185 EXPECT_EQ(arraysize(kLSBReleaseContents),
186 file_util::WriteFile(lsb_release_file_,
187 kLSBReleaseContents,
188 arraysize(kLSBReleaseContents)));
189 EXPECT_EQ(OpenVPNDriver::kLSBReleaseFile, driver_->lsb_release_file_.value());
190 driver_->lsb_release_file_ = lsb_release_file_;
191}
192
Darin Petkov33af05c2012-02-28 10:10:30 +0100193TEST_F(OpenVPNDriverTest, Connect) {
Darin Petkov79d74c92012-03-07 17:20:32 +0100194 EXPECT_CALL(*service_, SetState(Service::kStateConfiguring));
195 const string interface = kInterfaceName;
Darin Petkovf20994f2012-03-05 16:12:19 +0100196 EXPECT_CALL(device_info_, CreateTunnelInterface(_))
Darin Petkov79d74c92012-03-07 17:20:32 +0100197 .WillOnce(DoAll(SetArgumentPointee<0>(interface), Return(true)));
198 Error error;
199 driver_->Connect(service_, &error);
200 EXPECT_TRUE(error.IsSuccess());
201 EXPECT_EQ(kInterfaceName, driver_->tunnel_interface_);
Darin Petkov602303f2012-06-06 12:15:59 +0200202 EXPECT_TRUE(driver_->IsConnectTimeoutStarted());
Darin Petkov79d74c92012-03-07 17:20:32 +0100203}
204
205TEST_F(OpenVPNDriverTest, ConnectTunnelFailure) {
206 EXPECT_CALL(*service_, SetState(Service::kStateConfiguring));
Darin Petkov0e9735d2012-04-24 12:33:45 +0200207 EXPECT_CALL(device_info_, CreateTunnelInterface(_)).WillOnce(Return(false));
Darin Petkov79d74c92012-03-07 17:20:32 +0100208 EXPECT_CALL(*service_, SetState(Service::kStateFailure));
209 Error error;
210 driver_->Connect(service_, &error);
211 EXPECT_EQ(Error::kInternalError, error.type());
212 EXPECT_TRUE(driver_->tunnel_interface_.empty());
Darin Petkov602303f2012-06-06 12:15:59 +0200213 EXPECT_FALSE(driver_->IsConnectTimeoutStarted());
Darin Petkov33af05c2012-02-28 10:10:30 +0100214}
215
Darin Petkov0e9735d2012-04-24 12:33:45 +0200216namespace {
217MATCHER_P(IsIPAddress, address, "") {
218 IPAddress ip_address(IPAddress::kFamilyIPv4);
219 EXPECT_TRUE(ip_address.SetAddressFromString(address));
220 return ip_address.Equals(arg);
221}
222} // namespace
223
Darin Petkov14c29ec2012-03-02 11:34:19 +0100224TEST_F(OpenVPNDriverTest, Notify) {
Darin Petkov0e9735d2012-04-24 12:33:45 +0200225 map<string, string> config;
Darin Petkov79d74c92012-03-07 17:20:32 +0100226 driver_->device_ = device_;
Darin Petkov602303f2012-06-06 12:15:59 +0200227 driver_->StartConnectTimeout();
Darin Petkove8587e32012-07-02 13:56:07 +0200228 EXPECT_CALL(*device_,
229 UpdateIPConfig(Field(&IPConfig::Properties::address, "")));
Darin Petkov0e9735d2012-04-24 12:33:45 +0200230 driver_->Notify("up", config);
Darin Petkov602303f2012-06-06 12:15:59 +0200231 EXPECT_FALSE(driver_->IsConnectTimeoutStarted());
Darin Petkove8587e32012-07-02 13:56:07 +0200232
233 // Tests that existing properties are reused if no new ones provided.
234 IPConfigRefPtr ipconfig(new IPConfig(&control_, device_->link_name()));
235 IPConfig::Properties props;
236 props.address = "1.2.3.4";
237 ipconfig->set_properties(props);
238 device_->set_ipconfig(ipconfig);
239 EXPECT_CALL(*device_,
240 UpdateIPConfig(Field(&IPConfig::Properties::address, "1.2.3.4")));
241 driver_->Notify("up", config);
Darin Petkov79d74c92012-03-07 17:20:32 +0100242}
243
244TEST_F(OpenVPNDriverTest, NotifyFail) {
245 map<string, string> dict;
246 driver_->device_ = device_;
Darin Petkov602303f2012-06-06 12:15:59 +0200247 driver_->StartConnectTimeout();
Darin Petkov79d74c92012-03-07 17:20:32 +0100248 EXPECT_CALL(*device_, OnDisconnected());
249 driver_->Notify("fail", dict);
Darin Petkov602303f2012-06-06 12:15:59 +0200250 EXPECT_TRUE(driver_->IsConnectTimeoutStarted());
Darin Petkov14c29ec2012-03-02 11:34:19 +0100251}
252
Darin Petkov60596742012-03-05 12:17:17 +0100253TEST_F(OpenVPNDriverTest, GetRouteOptionEntry) {
254 OpenVPNDriver::RouteOptions routes;
255 EXPECT_EQ(NULL, OpenVPNDriver::GetRouteOptionEntry("foo", "bar", &routes));
256 EXPECT_TRUE(routes.empty());
257 EXPECT_EQ(NULL, OpenVPNDriver::GetRouteOptionEntry("foo", "foo", &routes));
258 EXPECT_TRUE(routes.empty());
259 EXPECT_EQ(NULL, OpenVPNDriver::GetRouteOptionEntry("foo", "fooZ", &routes));
260 EXPECT_TRUE(routes.empty());
261 IPConfig::Route *route =
262 OpenVPNDriver::GetRouteOptionEntry("foo", "foo12", &routes);
263 EXPECT_EQ(1, routes.size());
264 EXPECT_EQ(route, &routes[12]);
265 route = OpenVPNDriver::GetRouteOptionEntry("foo", "foo13", &routes);
266 EXPECT_EQ(2, routes.size());
267 EXPECT_EQ(route, &routes[13]);
268}
269
270TEST_F(OpenVPNDriverTest, ParseRouteOption) {
271 OpenVPNDriver::RouteOptions routes;
272 OpenVPNDriver::ParseRouteOption("foo", "bar", &routes);
273 EXPECT_TRUE(routes.empty());
274 OpenVPNDriver::ParseRouteOption("gateway_2", kGateway2, &routes);
275 OpenVPNDriver::ParseRouteOption("netmask_2", kNetmask2, &routes);
276 OpenVPNDriver::ParseRouteOption("network_2", kNetwork2, &routes);
277 EXPECT_EQ(1, routes.size());
278 OpenVPNDriver::ParseRouteOption("gateway_1", kGateway1, &routes);
279 OpenVPNDriver::ParseRouteOption("netmask_1", kNetmask1, &routes);
280 OpenVPNDriver::ParseRouteOption("network_1", kNetwork1, &routes);
281 EXPECT_EQ(2, routes.size());
282 EXPECT_EQ(kGateway1, routes[1].gateway);
283 EXPECT_EQ(kNetmask1, routes[1].netmask);
284 EXPECT_EQ(kNetwork1, routes[1].host);
285 EXPECT_EQ(kGateway2, routes[2].gateway);
286 EXPECT_EQ(kNetmask2, routes[2].netmask);
287 EXPECT_EQ(kNetwork2, routes[2].host);
288}
289
290TEST_F(OpenVPNDriverTest, SetRoutes) {
291 OpenVPNDriver::RouteOptions routes;
292 routes[1].gateway = "1.2.3.4";
293 routes[1].host= "1.2.3.4";
294 routes[2].host = "2.3.4.5";
295 routes[2].netmask = "255.0.0.0";
296 routes[3].netmask = "255.0.0.0";
297 routes[3].gateway = "1.2.3.5";
298 routes[5].host = kNetwork2;
299 routes[5].netmask = kNetmask2;
300 routes[5].gateway = kGateway2;
301 routes[4].host = kNetwork1;
302 routes[4].netmask = kNetmask1;
303 routes[4].gateway = kGateway1;
304 IPConfig::Properties props;
305 OpenVPNDriver::SetRoutes(routes, &props);
306 ASSERT_EQ(2, props.routes.size());
307 EXPECT_EQ(kGateway1, props.routes[0].gateway);
308 EXPECT_EQ(kNetmask1, props.routes[0].netmask);
309 EXPECT_EQ(kNetwork1, props.routes[0].host);
310 EXPECT_EQ(kGateway2, props.routes[1].gateway);
311 EXPECT_EQ(kNetmask2, props.routes[1].netmask);
312 EXPECT_EQ(kNetwork2, props.routes[1].host);
Darin Petkove8587e32012-07-02 13:56:07 +0200313
314 // Tests that the routes are not reset if no new routes are supplied.
315 OpenVPNDriver::SetRoutes(OpenVPNDriver::RouteOptions(), &props);
316 EXPECT_EQ(2, props.routes.size());
Darin Petkov60596742012-03-05 12:17:17 +0100317}
318
Darin Petkov14c29ec2012-03-02 11:34:19 +0100319TEST_F(OpenVPNDriverTest, ParseForeignOption) {
Darin Petkove8587e32012-07-02 13:56:07 +0200320 vector<string> domain_search;
321 vector<string> dns_servers;
Darin Petkov14c29ec2012-03-02 11:34:19 +0100322 IPConfig::Properties props;
Darin Petkove8587e32012-07-02 13:56:07 +0200323 OpenVPNDriver::ParseForeignOption("", &domain_search, &dns_servers);
324 OpenVPNDriver::ParseForeignOption(
325 "dhcp-option DOMAIN", &domain_search, &dns_servers);
326 OpenVPNDriver::ParseForeignOption(
327 "dhcp-option DOMAIN zzz.com foo", &domain_search, &dns_servers);
328 OpenVPNDriver::ParseForeignOption(
329 "dhcp-Option DOmAIN xyz.com", &domain_search, &dns_servers);
330 ASSERT_EQ(1, domain_search.size());
331 EXPECT_EQ("xyz.com", domain_search[0]);
332 OpenVPNDriver::ParseForeignOption(
333 "dhcp-option DnS 1.2.3.4", &domain_search, &dns_servers);
334 ASSERT_EQ(1, dns_servers.size());
335 EXPECT_EQ("1.2.3.4", dns_servers[0]);
Darin Petkov14c29ec2012-03-02 11:34:19 +0100336}
337
338TEST_F(OpenVPNDriverTest, ParseForeignOptions) {
Darin Petkove8587e32012-07-02 13:56:07 +0200339 // This also tests that std::map is a sorted container.
Darin Petkov14c29ec2012-03-02 11:34:19 +0100340 map<int, string> options;
341 options[5] = "dhcp-option DOMAIN five.com";
342 options[2] = "dhcp-option DOMAIN two.com";
343 options[8] = "dhcp-option DOMAIN eight.com";
344 options[7] = "dhcp-option DOMAIN seven.com";
345 options[4] = "dhcp-option DOMAIN four.com";
Darin Petkove8587e32012-07-02 13:56:07 +0200346 options[10] = "dhcp-option dns 1.2.3.4";
Darin Petkov14c29ec2012-03-02 11:34:19 +0100347 IPConfig::Properties props;
348 OpenVPNDriver::ParseForeignOptions(options, &props);
349 ASSERT_EQ(5, props.domain_search.size());
350 EXPECT_EQ("two.com", props.domain_search[0]);
351 EXPECT_EQ("four.com", props.domain_search[1]);
352 EXPECT_EQ("five.com", props.domain_search[2]);
353 EXPECT_EQ("seven.com", props.domain_search[3]);
354 EXPECT_EQ("eight.com", props.domain_search[4]);
Darin Petkove8587e32012-07-02 13:56:07 +0200355 ASSERT_EQ(1, props.dns_servers.size());
356 EXPECT_EQ("1.2.3.4", props.dns_servers[0]);
357
358 // Test that the DNS properties are not updated if no new DNS properties are
359 // supplied.
360 OpenVPNDriver::ParseForeignOptions(map<int, string>(), &props);
361 EXPECT_EQ(5, props.domain_search.size());
362 ASSERT_EQ(1, props.dns_servers.size());
Darin Petkov14c29ec2012-03-02 11:34:19 +0100363}
364
365TEST_F(OpenVPNDriverTest, ParseIPConfiguration) {
366 map<string, string> config;
Darin Petkove8587e32012-07-02 13:56:07 +0200367 IPConfig::Properties props;
368
369 OpenVPNDriver::ParseIPConfiguration(config, &props);
370 EXPECT_EQ(IPAddress::kFamilyIPv4, props.address_family);
371 EXPECT_EQ(32, props.subnet_prefix);
372
373 props.subnet_prefix = 18;
374 OpenVPNDriver::ParseIPConfiguration(config, &props);
375 EXPECT_EQ(18, props.subnet_prefix);
376
Darin Petkov14c29ec2012-03-02 11:34:19 +0100377 config["ifconfig_loCal"] = "4.5.6.7";
378 config["ifconfiG_broadcast"] = "1.2.255.255";
379 config["ifconFig_netmAsk"] = "255.255.255.0";
380 config["ifconfig_remotE"] = "33.44.55.66";
381 config["route_vpN_gateway"] = "192.168.1.1";
Paul Stewartce4ec192012-03-14 12:53:46 -0700382 config["trusted_ip"] = "99.88.77.66";
Darin Petkov14c29ec2012-03-02 11:34:19 +0100383 config["tun_mtu"] = "1000";
384 config["foreign_option_2"] = "dhcp-option DNS 4.4.4.4";
385 config["foreign_option_1"] = "dhcp-option DNS 1.1.1.1";
386 config["foreign_option_3"] = "dhcp-option DNS 2.2.2.2";
Darin Petkov60596742012-03-05 12:17:17 +0100387 config["route_network_2"] = kNetwork2;
388 config["route_network_1"] = kNetwork1;
389 config["route_netmask_2"] = kNetmask2;
390 config["route_netmask_1"] = kNetmask1;
391 config["route_gateway_2"] = kGateway2;
392 config["route_gateway_1"] = kGateway1;
Darin Petkov14c29ec2012-03-02 11:34:19 +0100393 config["foo"] = "bar";
Darin Petkov14c29ec2012-03-02 11:34:19 +0100394 OpenVPNDriver::ParseIPConfiguration(config, &props);
395 EXPECT_EQ(IPAddress::kFamilyIPv4, props.address_family);
396 EXPECT_EQ("4.5.6.7", props.address);
397 EXPECT_EQ("1.2.255.255", props.broadcast_address);
Paul Stewart48100b02012-03-19 07:53:52 -0700398 EXPECT_EQ(24, props.subnet_prefix);
Darin Petkov14c29ec2012-03-02 11:34:19 +0100399 EXPECT_EQ("33.44.55.66", props.peer_address);
400 EXPECT_EQ("192.168.1.1", props.gateway);
Paul Stewartce4ec192012-03-14 12:53:46 -0700401 EXPECT_EQ("99.88.77.66", props.trusted_ip);
Darin Petkov14c29ec2012-03-02 11:34:19 +0100402 EXPECT_EQ(1000, props.mtu);
403 ASSERT_EQ(3, props.dns_servers.size());
404 EXPECT_EQ("1.1.1.1", props.dns_servers[0]);
405 EXPECT_EQ("4.4.4.4", props.dns_servers[1]);
406 EXPECT_EQ("2.2.2.2", props.dns_servers[2]);
Darin Petkov60596742012-03-05 12:17:17 +0100407 ASSERT_EQ(2, props.routes.size());
408 EXPECT_EQ(kGateway1, props.routes[0].gateway);
409 EXPECT_EQ(kNetmask1, props.routes[0].netmask);
410 EXPECT_EQ(kNetwork1, props.routes[0].host);
411 EXPECT_EQ(kGateway2, props.routes[1].gateway);
412 EXPECT_EQ(kNetmask2, props.routes[1].netmask);
413 EXPECT_EQ(kNetwork2, props.routes[1].host);
Darin Petkov14c29ec2012-03-02 11:34:19 +0100414}
415
Darin Petkovfe6a9372012-02-28 16:25:06 +0100416TEST_F(OpenVPNDriverTest, InitOptionsNoHost) {
417 Error error;
418 vector<string> options;
Darin Petkov79d74c92012-03-07 17:20:32 +0100419 driver_->InitOptions(&options, &error);
Darin Petkovfe6a9372012-02-28 16:25:06 +0100420 EXPECT_EQ(Error::kInvalidArguments, error.type());
421 EXPECT_TRUE(options.empty());
422}
423
424TEST_F(OpenVPNDriverTest, InitOptions) {
425 static const char kHost[] = "192.168.2.254";
Darin Petkov1fa81942012-04-02 11:38:08 +0200426 static const char kTLSAuthContents[] = "SOME-RANDOM-CONTENTS\n";
Darin Petkov3c5e4dc2012-04-02 14:44:27 +0200427 static const char kCaCertNSS[] = "{1234}";
Darin Petkove0d5dd12012-04-04 16:10:48 +0200428 static const char kID[] = "TestPKCS11ID";
429 FilePath empty_cert;
430 SetArg(flimflam::kProviderHostProperty, kHost);
431 SetArg(flimflam::kOpenVPNTLSAuthContentsProperty, kTLSAuthContents);
432 SetArg(flimflam::kOpenVPNCaCertNSSProperty, kCaCertNSS);
433 SetArg(flimflam::kOpenVPNClientCertIdProperty, kID);
Darin Petkov79d74c92012-03-07 17:20:32 +0100434 driver_->rpc_task_.reset(new RPCTask(&control_, this));
Darin Petkov79d74c92012-03-07 17:20:32 +0100435 driver_->tunnel_interface_ = kInterfaceName;
Darin Petkove0d5dd12012-04-04 16:10:48 +0200436 EXPECT_CALL(*management_server_, Start(_, _, _)).WillOnce(Return(true));
437 EXPECT_CALL(nss_, GetPEMCertfile(kCaCertNSS, _)).WillOnce(Return(empty_cert));
Darin Petkova5e07ef2012-07-09 14:27:57 +0200438 ServiceRefPtr null_service;
439 EXPECT_CALL(manager_, GetDefaultService()).WillOnce(Return(null_service));
Darin Petkove0d5dd12012-04-04 16:10:48 +0200440
441 Error error;
442 vector<string> options;
443 driver_->InitOptions(&options, &error);
444 EXPECT_TRUE(error.IsSuccess());
445 EXPECT_EQ("--client", options[0]);
446 ExpectInFlags(options, "--remote", kHost);
447 ExpectInFlags(options, "CONNMAN_PATH", RPCTaskMockAdaptor::kRpcId);
448 ExpectInFlags(options, "--dev", kInterfaceName);
449 ExpectInFlags(options, "--group", "openvpn");
450 EXPECT_EQ(kInterfaceName, driver_->tunnel_interface_);
451 ASSERT_FALSE(driver_->tls_auth_file_.empty());
452 ExpectInFlags(options, "--tls-auth", driver_->tls_auth_file_.value());
453 string contents;
454 EXPECT_TRUE(
455 file_util::ReadFileToString(driver_->tls_auth_file_, &contents));
456 EXPECT_EQ(kTLSAuthContents, contents);
457 ExpectInFlags(options, "--pkcs11-id", kID);
Darin Petkov55771b72012-04-25 09:25:19 +0200458 EXPECT_TRUE(std::find(options.begin(), options.end(), "--syslog") !=
459 options.end());
Darin Petkove0d5dd12012-04-04 16:10:48 +0200460}
461
462TEST_F(OpenVPNDriverTest, InitNSSOptions) {
463 static const char kHost[] = "192.168.2.254";
464 static const char kCaCertNSS[] = "{1234}";
465 static const char kNSSCertfile[] = "/tmp/nss-cert";
466 FilePath empty_cert;
467 FilePath nss_cert(kNSSCertfile);
468 SetArg(flimflam::kProviderHostProperty, kHost);
469 SetArg(flimflam::kOpenVPNCaCertNSSProperty, kCaCertNSS);
Darin Petkov3c5e4dc2012-04-02 14:44:27 +0200470 EXPECT_CALL(nss_,
471 GetPEMCertfile(kCaCertNSS,
472 ElementsAreArray(kHost, arraysize(kHost) - 1)))
Darin Petkove0d5dd12012-04-04 16:10:48 +0200473 .WillOnce(Return(empty_cert))
474 .WillOnce(Return(nss_cert));
475
476 Error error;
477 vector<string> options;
478 EXPECT_TRUE(driver_->InitNSSOptions(&options, &error));
479 EXPECT_TRUE(error.IsSuccess());
480 EXPECT_TRUE(options.empty());
481 EXPECT_TRUE(driver_->InitNSSOptions(&options, &error));
482 ExpectInFlags(options, "--ca", kNSSCertfile);
483 EXPECT_TRUE(error.IsSuccess());
484
485 SetArg(flimflam::kOpenVPNCaCertProperty, "foo");
486 options.clear();
487 EXPECT_FALSE(driver_->InitNSSOptions(&options, &error));
488 EXPECT_EQ(Error::kInvalidArguments, error.type());
489 EXPECT_EQ("Can't specify both CACert and CACertNSS.", error.message());
490}
491
492TEST_F(OpenVPNDriverTest, InitPKCS11Options) {
493 vector<string> options;
494 driver_->InitPKCS11Options(&options);
495 EXPECT_TRUE(options.empty());
496
497 static const char kID[] = "TestPKCS11ID";
498 SetArg(flimflam::kOpenVPNClientCertIdProperty, kID);
499 driver_->InitPKCS11Options(&options);
500 ExpectInFlags(options, "--pkcs11-id", kID);
501 ExpectInFlags(options, "--pkcs11-providers", "libchaps.so");
502
503 static const char kProvider[] = "libpkcs11.so";
504 SetArg(flimflam::kOpenVPNProviderProperty, kProvider);
505 options.clear();
506 driver_->InitPKCS11Options(&options);
507 ExpectInFlags(options, "--pkcs11-id", kID);
508 ExpectInFlags(options, "--pkcs11-providers", kProvider);
509}
510
511TEST_F(OpenVPNDriverTest, InitManagementChannelOptions) {
512 vector<string> options;
Darin Petkova5e07ef2012-07-09 14:27:57 +0200513 Error error;
514
Darin Petkove0d5dd12012-04-04 16:10:48 +0200515 EXPECT_CALL(*management_server_,
516 Start(&dispatcher_, &driver_->sockets_, &options))
Darin Petkova5e07ef2012-07-09 14:27:57 +0200517 .Times(4)
Darin Petkove0d5dd12012-04-04 16:10:48 +0200518 .WillOnce(Return(false))
Darin Petkova5e07ef2012-07-09 14:27:57 +0200519 .WillRepeatedly(Return(true));
Darin Petkove0d5dd12012-04-04 16:10:48 +0200520
Darin Petkova5e07ef2012-07-09 14:27:57 +0200521 // Management server fails to start.
Darin Petkove0d5dd12012-04-04 16:10:48 +0200522 EXPECT_FALSE(driver_->InitManagementChannelOptions(&options, &error));
523 EXPECT_EQ(Error::kInternalError, error.type());
524 EXPECT_EQ("Unable to setup management channel.", error.message());
525
Darin Petkova5e07ef2012-07-09 14:27:57 +0200526 // Start with a connected default service.
527 scoped_refptr<MockService> mock_service(
528 new MockService(&control_, &dispatcher_, &metrics_, &manager_));
529 EXPECT_CALL(manager_, GetDefaultService()).WillOnce(Return(mock_service));
530 EXPECT_CALL(*mock_service, IsConnected()).WillOnce(Return(true));
531 EXPECT_CALL(*management_server_, ReleaseHold());
Darin Petkove0d5dd12012-04-04 16:10:48 +0200532 error.Reset();
533 EXPECT_TRUE(driver_->InitManagementChannelOptions(&options, &error));
534 EXPECT_TRUE(error.IsSuccess());
Darin Petkova5e07ef2012-07-09 14:27:57 +0200535
536 // Start with a disconnected default service.
537 EXPECT_CALL(manager_, GetDefaultService()).WillOnce(Return(mock_service));
538 EXPECT_CALL(*mock_service, IsConnected()).WillOnce(Return(false));
539 EXPECT_CALL(*management_server_, ReleaseHold()).Times(0);
540 EXPECT_TRUE(driver_->InitManagementChannelOptions(&options, &error));
541 EXPECT_TRUE(error.IsSuccess());
542
543 // Start with no default service.
544 ServiceRefPtr null_service;
545 EXPECT_CALL(manager_, GetDefaultService()).WillOnce(Return(null_service));
546 EXPECT_CALL(*management_server_, ReleaseHold()).Times(0);
547 EXPECT_TRUE(driver_->InitManagementChannelOptions(&options, &error));
548 EXPECT_TRUE(error.IsSuccess());
Darin Petkovfe6a9372012-02-28 16:25:06 +0100549}
550
Darin Petkov55771b72012-04-25 09:25:19 +0200551TEST_F(OpenVPNDriverTest, InitLoggingOptions) {
552 vector<string> options;
553 bool vpn_logging = SLOG_IS_ON(VPN, 0);
554 ScopeLogger::GetInstance()->EnableScopesByName("-vpn");
555 driver_->InitLoggingOptions(&options);
556 ASSERT_EQ(1, options.size());
557 EXPECT_EQ("--syslog", options[0]);
558 ScopeLogger::GetInstance()->EnableScopesByName("+vpn");
559 options.clear();
560 driver_->InitLoggingOptions(&options);
561 ExpectInFlags(options, "--verb", "3");
562 ScopeLogger::GetInstance()->EnableScopesByName("-vpn");
563 SetArg("OpenVPN.Verb", "2");
564 options.clear();
565 driver_->InitLoggingOptions(&options);
566 ExpectInFlags(options, "--verb", "2");
567 ScopeLogger::GetInstance()->EnableScopesByName("+vpn");
568 SetArg("OpenVPN.Verb", "1");
569 options.clear();
570 driver_->InitLoggingOptions(&options);
571 ExpectInFlags(options, "--verb", "1");
572 if (!vpn_logging) {
573 ScopeLogger::GetInstance()->EnableScopesByName("-vpn");
574 }
575}
576
Darin Petkovfe6a9372012-02-28 16:25:06 +0100577TEST_F(OpenVPNDriverTest, AppendValueOption) {
578 vector<string> options;
Darin Petkov46463022012-03-29 14:57:32 +0200579 EXPECT_FALSE(
580 driver_->AppendValueOption("OpenVPN.UnknownProperty", kOption, &options));
Darin Petkovfe6a9372012-02-28 16:25:06 +0100581 EXPECT_TRUE(options.empty());
582
Darin Petkove0d5dd12012-04-04 16:10:48 +0200583 SetArg(kProperty, "");
Darin Petkov46463022012-03-29 14:57:32 +0200584 EXPECT_FALSE(driver_->AppendValueOption(kProperty, kOption, &options));
Darin Petkovfe6a9372012-02-28 16:25:06 +0100585 EXPECT_TRUE(options.empty());
586
Darin Petkove0d5dd12012-04-04 16:10:48 +0200587 SetArg(kProperty, kValue);
588 SetArg(kProperty2, kValue2);
Darin Petkov46463022012-03-29 14:57:32 +0200589 EXPECT_TRUE(driver_->AppendValueOption(kProperty, kOption, &options));
590 EXPECT_TRUE(driver_->AppendValueOption(kProperty2, kOption2, &options));
Darin Petkovfe6a9372012-02-28 16:25:06 +0100591 EXPECT_EQ(4, options.size());
592 EXPECT_EQ(kOption, options[0]);
593 EXPECT_EQ(kValue, options[1]);
594 EXPECT_EQ(kOption2, options[2]);
595 EXPECT_EQ(kValue2, options[3]);
596}
597
598TEST_F(OpenVPNDriverTest, AppendFlag) {
599 vector<string> options;
Darin Petkov46463022012-03-29 14:57:32 +0200600 EXPECT_FALSE(
601 driver_->AppendFlag("OpenVPN.UnknownProperty", kOption, &options));
Darin Petkovfe6a9372012-02-28 16:25:06 +0100602 EXPECT_TRUE(options.empty());
603
Darin Petkove0d5dd12012-04-04 16:10:48 +0200604 SetArg(kProperty, "");
605 SetArg(kProperty2, kValue2);
Darin Petkov46463022012-03-29 14:57:32 +0200606 EXPECT_TRUE(driver_->AppendFlag(kProperty, kOption, &options));
607 EXPECT_TRUE(driver_->AppendFlag(kProperty2, kOption2, &options));
Darin Petkovfe6a9372012-02-28 16:25:06 +0100608 EXPECT_EQ(2, options.size());
609 EXPECT_EQ(kOption, options[0]);
610 EXPECT_EQ(kOption2, options[1]);
611}
612
Paul Stewartca6abd42012-03-01 15:45:29 -0800613TEST_F(OpenVPNDriverTest, ClaimInterface) {
Darin Petkov79d74c92012-03-07 17:20:32 +0100614 driver_->tunnel_interface_ = kInterfaceName;
615 EXPECT_FALSE(driver_->ClaimInterface(string(kInterfaceName) + "XXX",
616 kInterfaceIndex));
617 EXPECT_FALSE(driver_->device_);
Paul Stewartca6abd42012-03-01 15:45:29 -0800618
Darin Petkov36a3ace2012-03-06 17:22:14 +0100619 static const char kHost[] = "192.168.2.254";
Darin Petkove0d5dd12012-04-04 16:10:48 +0200620 SetArg(flimflam::kProviderHostProperty, kHost);
Darin Petkov46463022012-03-29 14:57:32 +0200621 EXPECT_CALL(*management_server_, Start(_, _, _)).WillOnce(Return(true));
Darin Petkova5e07ef2012-07-09 14:27:57 +0200622 ServiceRefPtr null_service;
623 EXPECT_CALL(manager_, GetDefaultService()).WillOnce(Return(null_service));
Darin Petkov36a3ace2012-03-06 17:22:14 +0100624 EXPECT_CALL(glib_, SpawnAsyncWithPipesCWD(_, _, _, _, _, _, _, _, _, _))
625 .WillOnce(Return(true));
626 EXPECT_CALL(glib_, ChildWatchAdd(_, _, _)).WillOnce(Return(1));
Darin Petkova5e07ef2012-07-09 14:27:57 +0200627 const int kServiceCallbackTag = 1;
628 EXPECT_EQ(0, driver_->default_service_callback_tag_);
629 EXPECT_CALL(manager_, RegisterDefaultServiceCallback(_))
630 .WillOnce(Return(kServiceCallbackTag));
Darin Petkov79d74c92012-03-07 17:20:32 +0100631 EXPECT_TRUE(driver_->ClaimInterface(kInterfaceName, kInterfaceIndex));
632 ASSERT_TRUE(driver_->device_);
633 EXPECT_EQ(kInterfaceIndex, driver_->device_->interface_index());
Darin Petkova5e07ef2012-07-09 14:27:57 +0200634 EXPECT_EQ(kServiceCallbackTag, driver_->default_service_callback_tag_);
Paul Stewartca6abd42012-03-01 15:45:29 -0800635}
636
Darin Petkov36a3ace2012-03-06 17:22:14 +0100637TEST_F(OpenVPNDriverTest, Cleanup) {
Darin Petkov1fa81942012-04-02 11:38:08 +0200638 driver_->Cleanup(Service::kStateIdle); // Ensure no crash.
639
Darin Petkova5e07ef2012-07-09 14:27:57 +0200640 const unsigned int kChildTag = 123;
Darin Petkov36a3ace2012-03-06 17:22:14 +0100641 const int kPID = 123456;
Darin Petkova5e07ef2012-07-09 14:27:57 +0200642 const int kServiceCallbackTag = 5;
643 driver_->default_service_callback_tag_ = kServiceCallbackTag;
644 driver_->child_watch_tag_ = kChildTag;
Darin Petkov79d74c92012-03-07 17:20:32 +0100645 driver_->pid_ = kPID;
646 driver_->rpc_task_.reset(new RPCTask(&control_, this));
647 driver_->tunnel_interface_ = kInterfaceName;
648 driver_->device_ = device_;
649 driver_->service_ = service_;
Darin Petkov602303f2012-06-06 12:15:59 +0200650 driver_->StartConnectTimeout();
Darin Petkov1fa81942012-04-02 11:38:08 +0200651 FilePath tls_auth_file;
652 EXPECT_TRUE(file_util::CreateTemporaryFile(&tls_auth_file));
653 EXPECT_FALSE(tls_auth_file.empty());
654 EXPECT_TRUE(file_util::PathExists(tls_auth_file));
655 driver_->tls_auth_file_ = tls_auth_file;
Darin Petkov46463022012-03-29 14:57:32 +0200656 // Stop will be called twice -- once by Cleanup and once by the destructor.
657 EXPECT_CALL(*management_server_, Stop()).Times(2);
Darin Petkova5e07ef2012-07-09 14:27:57 +0200658 EXPECT_CALL(glib_, SourceRemove(kChildTag));
659 EXPECT_CALL(manager_, DeregisterDefaultServiceCallback(kServiceCallbackTag));
Darin Petkov5a850472012-06-06 15:44:24 +0200660 EXPECT_CALL(process_killer_, Kill(kPID, _));
661 EXPECT_CALL(device_info_, DeleteInterface(_)).Times(0);
Darin Petkov029d3532012-04-18 14:38:04 +0200662 EXPECT_CALL(*device_, OnDisconnected());
Eric Shienbrood9a245532012-03-07 14:20:39 -0500663 EXPECT_CALL(*device_, SetEnabled(false));
Darin Petkov79d74c92012-03-07 17:20:32 +0100664 EXPECT_CALL(*service_, SetState(Service::kStateFailure));
Darin Petkov3f9131c2012-03-20 11:37:32 +0100665 driver_->Cleanup(Service::kStateFailure);
Darin Petkov79d74c92012-03-07 17:20:32 +0100666 EXPECT_EQ(0, driver_->child_watch_tag_);
Darin Petkova5e07ef2012-07-09 14:27:57 +0200667 EXPECT_EQ(0, driver_->default_service_callback_tag_);
Darin Petkov79d74c92012-03-07 17:20:32 +0100668 EXPECT_EQ(0, driver_->pid_);
669 EXPECT_FALSE(driver_->rpc_task_.get());
670 EXPECT_TRUE(driver_->tunnel_interface_.empty());
671 EXPECT_FALSE(driver_->device_);
672 EXPECT_FALSE(driver_->service_);
Darin Petkov1fa81942012-04-02 11:38:08 +0200673 EXPECT_FALSE(file_util::PathExists(tls_auth_file));
674 EXPECT_TRUE(driver_->tls_auth_file_.empty());
Darin Petkov602303f2012-06-06 12:15:59 +0200675 EXPECT_FALSE(driver_->IsConnectTimeoutStarted());
Darin Petkov36a3ace2012-03-06 17:22:14 +0100676}
677
Darin Petkov1a462de2012-05-02 11:10:48 +0200678namespace {
679MATCHER(CheckEnv, "") {
680 if (!arg || !arg[0] || !arg[1] || arg[2]) {
681 return false;
682 }
683 return (string(arg[0]) == "IV_PLAT=Chromium OS" &&
684 string(arg[1]) == "IV_PLAT_REL=2202.0");
685}
686} // namespace
687
Darin Petkov36a3ace2012-03-06 17:22:14 +0100688TEST_F(OpenVPNDriverTest, SpawnOpenVPN) {
Darin Petkov1a462de2012-05-02 11:10:48 +0200689 SetupLSBRelease();
690
Darin Petkov79d74c92012-03-07 17:20:32 +0100691 EXPECT_FALSE(driver_->SpawnOpenVPN());
Darin Petkov36a3ace2012-03-06 17:22:14 +0100692
693 static const char kHost[] = "192.168.2.254";
Darin Petkove0d5dd12012-04-04 16:10:48 +0200694 SetArg(flimflam::kProviderHostProperty, kHost);
Darin Petkov79d74c92012-03-07 17:20:32 +0100695 driver_->tunnel_interface_ = "tun0";
696 driver_->rpc_task_.reset(new RPCTask(&control_, this));
Darin Petkov46463022012-03-29 14:57:32 +0200697 EXPECT_CALL(*management_server_, Start(_, _, _))
698 .Times(2)
699 .WillRepeatedly(Return(true));
Darin Petkova5e07ef2012-07-09 14:27:57 +0200700 ServiceRefPtr null_service;
701 EXPECT_CALL(manager_, GetDefaultService())
702 .Times(2)
703 .WillRepeatedly(Return(null_service));
Darin Petkov36a3ace2012-03-06 17:22:14 +0100704
705 const int kPID = 234678;
Darin Petkov1a462de2012-05-02 11:10:48 +0200706 EXPECT_CALL(glib_,
707 SpawnAsyncWithPipesCWD(_, CheckEnv(), _, _, _, _, _, _, _, _))
Darin Petkov36a3ace2012-03-06 17:22:14 +0100708 .WillOnce(Return(false))
709 .WillOnce(DoAll(SetArgumentPointee<5>(kPID), Return(true)));
710 const int kTag = 6;
Darin Petkov79d74c92012-03-07 17:20:32 +0100711 EXPECT_CALL(glib_, ChildWatchAdd(kPID, &driver_->OnOpenVPNDied, driver_))
Darin Petkov36a3ace2012-03-06 17:22:14 +0100712 .WillOnce(Return(kTag));
Darin Petkov79d74c92012-03-07 17:20:32 +0100713 EXPECT_FALSE(driver_->SpawnOpenVPN());
714 EXPECT_TRUE(driver_->SpawnOpenVPN());
715 EXPECT_EQ(kPID, driver_->pid_);
716 EXPECT_EQ(kTag, driver_->child_watch_tag_);
Darin Petkov36a3ace2012-03-06 17:22:14 +0100717}
718
719TEST_F(OpenVPNDriverTest, OnOpenVPNDied) {
720 const int kPID = 99999;
Darin Petkov5a850472012-06-06 15:44:24 +0200721 driver_->device_ = device_;
Darin Petkov79d74c92012-03-07 17:20:32 +0100722 driver_->child_watch_tag_ = 333;
723 driver_->pid_ = kPID;
Darin Petkov5a850472012-06-06 15:44:24 +0200724 EXPECT_CALL(*device_, OnDisconnected());
725 EXPECT_CALL(*device_, SetEnabled(false));
726 EXPECT_CALL(process_killer_, Kill(_, _)).Times(0);
727 EXPECT_CALL(device_info_, DeleteInterface(kInterfaceIndex));
Darin Petkov79d74c92012-03-07 17:20:32 +0100728 OpenVPNDriver::OnOpenVPNDied(kPID, 2, driver_);
729 EXPECT_EQ(0, driver_->child_watch_tag_);
730 EXPECT_EQ(0, driver_->pid_);
Darin Petkov36a3ace2012-03-06 17:22:14 +0100731}
732
Darin Petkov6aa21872012-03-09 16:10:19 +0100733TEST_F(OpenVPNDriverTest, Disconnect) {
734 driver_->device_ = device_;
735 driver_->service_ = service_;
Darin Petkov029d3532012-04-18 14:38:04 +0200736 EXPECT_CALL(*device_, OnDisconnected());
Eric Shienbrood9a245532012-03-07 14:20:39 -0500737 EXPECT_CALL(*device_, SetEnabled(false));
Darin Petkov6aa21872012-03-09 16:10:19 +0100738 EXPECT_CALL(device_info_, DeleteInterface(kInterfaceIndex));
739 EXPECT_CALL(*service_, SetState(Service::kStateIdle));
740 driver_->Disconnect();
Darin Petkova0e645e2012-04-25 11:38:59 +0200741 EXPECT_FALSE(driver_->device_);
Darin Petkov6aa21872012-03-09 16:10:19 +0100742 EXPECT_FALSE(driver_->service_);
743}
744
Darin Petkov5eb05422012-05-11 15:45:25 +0200745TEST_F(OpenVPNDriverTest, OnConnectionDisconnected) {
746 driver_->service_ = service_;
747 EXPECT_CALL(*service_, SetState(Service::kStateFailure));
748 driver_->OnConnectionDisconnected();
749 EXPECT_FALSE(driver_->service_);
750}
751
Darin Petkov271fe522012-03-27 13:47:29 +0200752TEST_F(OpenVPNDriverTest, OnReconnecting) {
753 driver_->OnReconnecting(); // Expect no crash.
754 driver_->device_ = device_;
755 driver_->service_ = service_;
756 EXPECT_CALL(*device_, OnDisconnected());
757 EXPECT_CALL(*service_, SetState(Service::kStateAssociating));
758 driver_->OnReconnecting();
Darin Petkov602303f2012-06-06 12:15:59 +0200759 EXPECT_TRUE(driver_->IsConnectTimeoutStarted());
Darin Petkov271fe522012-03-27 13:47:29 +0200760}
761
Paul Stewart291a4732012-03-14 19:19:02 -0700762TEST_F(OpenVPNDriverTest, VerifyPaths) {
763 // Ensure that the various path constants that the OpenVPN driver uses
Darin Petkova0e645e2012-04-25 11:38:59 +0200764 // actually exists in the build image. Due to build dependencies, they should
765 // already exist by the time we run unit tests.
Paul Stewart291a4732012-03-14 19:19:02 -0700766
Darin Petkova0e645e2012-04-25 11:38:59 +0200767 // The OpenVPNDriver path constants are absolute. FilePath::Append asserts
768 // that its argument is not an absolute path, so we need to strip the leading
769 // separators. There's nothing built into FilePath to do so.
770 static const char *kPaths[] = {
771 OpenVPNDriver::kOpenVPNPath,
772 OpenVPNDriver::kOpenVPNScript,
773 };
774 for (size_t i = 0; i < arraysize(kPaths); i++) {
775 string path(kPaths[i]);
776 TrimString(path, FilePath::kSeparators, &path);
777 EXPECT_TRUE(file_util::PathExists(FilePath(SYSROOT).Append(path)))
778 << kPaths[i];
779 }
Paul Stewart291a4732012-03-14 19:19:02 -0700780}
781
Darin Petkovd4325392012-04-23 15:48:22 +0200782TEST_F(OpenVPNDriverTest, InitPropertyStore) {
783 // Sanity test property store initialization.
784 PropertyStore store;
785 driver_->InitPropertyStore(&store);
786 const string kUser = "joe";
787 Error error;
788 EXPECT_TRUE(
789 store.SetStringProperty(flimflam::kOpenVPNUserProperty, kUser, &error));
790 EXPECT_TRUE(error.IsSuccess());
Darin Petkovb536a742012-04-26 11:31:28 +0200791 EXPECT_EQ(kUser, GetArgs()->LookupString(flimflam::kOpenVPNUserProperty, ""));
792}
793
794TEST_F(OpenVPNDriverTest, GetProvider) {
795 PropertyStore store;
796 driver_->InitPropertyStore(&store);
Paul Stewart8e7e4592012-04-29 09:47:48 -0700797 PropertyStoreInspector inspector(&store);
Darin Petkovb536a742012-04-26 11:31:28 +0200798 {
Darin Petkovb536a742012-04-26 11:31:28 +0200799 KeyValueStore props;
800 EXPECT_TRUE(
Paul Stewart8e7e4592012-04-29 09:47:48 -0700801 inspector.GetKeyValueStoreProperty(
Darin Petkov4682aa82012-05-31 16:24:11 +0200802 flimflam::kProviderProperty, &props));
Darin Petkovb536a742012-04-26 11:31:28 +0200803 EXPECT_TRUE(props.LookupBool(flimflam::kPassphraseRequiredProperty, false));
804 }
805 {
Darin Petkovb536a742012-04-26 11:31:28 +0200806 KeyValueStore props;
807 SetArg(flimflam::kOpenVPNPasswordProperty, "random-password");
808 EXPECT_TRUE(
Paul Stewart8e7e4592012-04-29 09:47:48 -0700809 inspector.GetKeyValueStoreProperty(
Darin Petkov4682aa82012-05-31 16:24:11 +0200810 flimflam::kProviderProperty, &props));
Darin Petkovb536a742012-04-26 11:31:28 +0200811 EXPECT_FALSE(props.LookupBool(flimflam::kPassphraseRequiredProperty, true));
Darin Petkov02236552012-06-11 13:15:19 +0200812 EXPECT_FALSE(props.ContainsString(flimflam::kOpenVPNPasswordProperty));
Darin Petkovb536a742012-04-26 11:31:28 +0200813 }
Darin Petkovd4325392012-04-23 15:48:22 +0200814}
815
Darin Petkov1a462de2012-05-02 11:10:48 +0200816TEST_F(OpenVPNDriverTest, ParseLSBRelease) {
817 SetupLSBRelease();
818 map<string, string> lsb_release;
819 EXPECT_TRUE(driver_->ParseLSBRelease(&lsb_release));
820 EXPECT_TRUE(ContainsKey(lsb_release, "foo") && lsb_release["foo"] == "");
821 EXPECT_EQ("=", lsb_release["zoo"]);
822 EXPECT_EQ("Chromium OS", lsb_release[OpenVPNDriver::kChromeOSReleaseName]);
823 EXPECT_EQ("2202.0", lsb_release[OpenVPNDriver::kChromeOSReleaseVersion]);
824 driver_->lsb_release_file_ = FilePath("/non/existent/file");
825 EXPECT_FALSE(driver_->ParseLSBRelease(NULL));
826}
827
828TEST_F(OpenVPNDriverTest, InitEnvironment) {
829 vector<string> env;
830 SetupLSBRelease();
831 driver_->InitEnvironment(&env);
832 ASSERT_EQ(2, env.size());
833 EXPECT_EQ("IV_PLAT=Chromium OS", env[0]);
834 EXPECT_EQ("IV_PLAT_REL=2202.0", env[1]);
835 env.clear();
836 EXPECT_EQ(0, file_util::WriteFile(lsb_release_file_, "", 0));
837 driver_->InitEnvironment(&env);
838 EXPECT_EQ(0, env.size());
839}
840
Darin Petkov5a850472012-06-06 15:44:24 +0200841TEST_F(OpenVPNDriverTest, DeleteInterface) {
842 scoped_ptr<MockDeviceInfo> device_info(
843 new MockDeviceInfo(&control_, &dispatcher_, &metrics_, &manager_));
844 EXPECT_CALL(*device_info, DeleteInterface(kInterfaceIndex))
845 .WillOnce(Return(true));
846 WeakPtr<DeviceInfo> weak = device_info->AsWeakPtr();
847 EXPECT_TRUE(weak);
848 OpenVPNDriver::DeleteInterface(weak, kInterfaceIndex);
849 device_info.reset();
850 EXPECT_FALSE(weak);
851 // Expect no crash.
852 OpenVPNDriver::DeleteInterface(weak, kInterfaceIndex);
853}
854
Darin Petkova5e07ef2012-07-09 14:27:57 +0200855TEST_F(OpenVPNDriverTest, OnDefaultServiceChanged) {
856 driver_->service_ = service_;
857
858 ServiceRefPtr null_service;
859 EXPECT_CALL(*management_server_, Hold());
860 driver_->OnDefaultServiceChanged(null_service);
861
862 EXPECT_CALL(*management_server_, Hold());
863 driver_->OnDefaultServiceChanged(service_);
864
865 scoped_refptr<MockService> mock_service(
866 new MockService(&control_, &dispatcher_, &metrics_, &manager_));
867
868 EXPECT_CALL(*mock_service, IsConnected()).WillOnce(Return(false));
869 EXPECT_CALL(*management_server_, Hold());
870 driver_->OnDefaultServiceChanged(mock_service);
871
872 EXPECT_CALL(*mock_service, IsConnected()).WillOnce(Return(true));
873 EXPECT_CALL(*management_server_, ReleaseHold());
874 driver_->OnDefaultServiceChanged(mock_service);
875}
876
Darin Petkov33af05c2012-02-28 10:10:30 +0100877} // namespace shill