shill: vpn: Support L2TP/IPSec services in VPNProvider.

Also, add a unit test for VPNProvider::CreateService.

BUG=chromium-os:29366
TEST=unit tests

Change-Id: I196748870003d303adb13f3f333305099af80b63
Reviewed-on: https://gerrit.chromium.org/gerrit/21038
Tested-by: Darin Petkov <petkov@chromium.org>
Reviewed-by: Paul Stewart <pstew@chromium.org>
Commit-Ready: Darin Petkov <petkov@chromium.org>
diff --git a/vpn_provider.cc b/vpn_provider.cc
index baa9d6b..0f4c525 100644
--- a/vpn_provider.cc
+++ b/vpn_provider.cc
@@ -11,6 +11,7 @@
 #include <chromeos/dbus/service_constants.h>
 
 #include "shill/error.h"
+#include "shill/l2tp_ipsec_driver.h"
 #include "shill/manager.h"
 #include "shill/openvpn_driver.h"
 #include "shill/profile.h"
@@ -154,6 +155,10 @@
     driver.reset(new OpenVPNDriver(
         control_interface_, dispatcher_, metrics_, manager_,
         manager_->device_info(), manager_->glib()));
+  } else if (type == flimflam::kProviderL2tpIpsec) {
+    driver.reset(new L2TPIPSecDriver(
+        control_interface_, dispatcher_, metrics_, manager_,
+        manager_->device_info(), manager_->glib()));
   } else {
     Error::PopulateAndLog(
         error, Error::kNotSupported, "Unsupported VPN type: " + type);
diff --git a/vpn_provider.h b/vpn_provider.h
index 158107c..1de0b15 100644
--- a/vpn_provider.h
+++ b/vpn_provider.h
@@ -47,6 +47,7 @@
   void CreateServicesFromProfile(ProfileRefPtr profile);
 
  private:
+  FRIEND_TEST(VPNProviderTest, CreateService);
   FRIEND_TEST(VPNProviderTest, OnDeviceInfoAvailable);
   FRIEND_TEST(VPNProviderTest, RemoveService);
 
diff --git a/vpn_provider_unittest.cc b/vpn_provider_unittest.cc
index 62c7f95..07bbdfb 100644
--- a/vpn_provider_unittest.cc
+++ b/vpn_provider_unittest.cc
@@ -208,4 +208,34 @@
   provider_.CreateServicesFromProfile(profile);
 }
 
+TEST_F(VPNProviderTest, CreateService) {
+  static const char kName[] = "test-vpn-service";
+  static const char kStorageID[] = "test_vpn_storage_id";
+  static const char *kTypes[] = {
+    flimflam::kProviderOpenVpn,
+    flimflam::kProviderL2tpIpsec,
+  };
+  const size_t kTypesCount = arraysize(kTypes);
+  EXPECT_CALL(manager_, device_info())
+      .Times(kTypesCount)
+      .WillRepeatedly(Return(&device_info_));
+  EXPECT_CALL(manager_, RegisterService(_)).Times(kTypesCount);
+  for (size_t i = 0; i < kTypesCount; i++) {
+    Error error;
+    VPNServiceRefPtr service =
+        provider_.CreateService(kTypes[i], kName, kStorageID, &error);
+    ASSERT_TRUE(service) << kTypes[i];
+    ASSERT_TRUE(service->driver()) << kTypes[i];
+    EXPECT_EQ(kTypes[i], service->driver()->GetProviderType());
+    EXPECT_EQ(kName, service->friendly_name()) << kTypes[i];
+    EXPECT_EQ(kStorageID, service->GetStorageIdentifier()) << kTypes[i];
+    EXPECT_TRUE(error.IsSuccess()) << kTypes[i];
+  }
+  Error error;
+  VPNServiceRefPtr unknown_service =
+      provider_.CreateService("unknown-vpn-type", kName, kStorageID, &error);
+  EXPECT_FALSE(unknown_service);
+  EXPECT_EQ(Error::kNotSupported, error.type());
+}
+
 }  // namespace shill