1 // 2 // Copyright (C) 2012 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #include "shill/vpn/vpn_provider.h" 18 19 #include <memory> 20 #include <set> 21 22 #if defined(__ANDROID__) 23 #include <dbus/service_constants.h> 24 #else 25 #include <chromeos/dbus/service_constants.h> 26 #endif // __ANDROID__ 27 #include <gtest/gtest.h> 28 29 #include "shill/error.h" 30 #include "shill/fake_store.h" 31 #include "shill/mock_adaptors.h" 32 #include "shill/mock_device_info.h" 33 #include "shill/mock_manager.h" 34 #include "shill/mock_metrics.h" 35 #include "shill/mock_profile.h" 36 #include "shill/mock_store.h" 37 #include "shill/nice_mock_control.h" 38 #include "shill/vpn/mock_vpn_driver.h" 39 #include "shill/vpn/mock_vpn_service.h" 40 41 using std::string; 42 using std::unique_ptr; 43 using testing::_; 44 using testing::DoAll; 45 using testing::NiceMock; 46 using testing::Return; 47 using testing::SetArgumentPointee; 48 using testing::StartsWith; 49 50 namespace shill { 51 52 class VPNProviderTest : public testing::Test { 53 public: 54 VPNProviderTest() 55 : metrics_(nullptr), 56 manager_(&control_, nullptr, &metrics_), 57 device_info_(&control_, nullptr, &metrics_, &manager_), 58 provider_(&control_, nullptr, &metrics_, &manager_) {} 59 60 virtual ~VPNProviderTest() {} 61 62 protected: 63 static const char kHost[]; 64 static const char kName[]; 65 66 string GetServiceFriendlyName(const ServiceRefPtr& service) { 67 return service->friendly_name(); 68 } 69 70 void SetConnectState(const ServiceRefPtr& service, 71 Service::ConnectState state) { 72 service->state_ = state; 73 } 74 75 void AddService(const VPNServiceRefPtr& service) { 76 provider_.services_.push_back(service); 77 } 78 79 VPNServiceRefPtr GetServiceAt(int idx) { 80 return provider_.services_[idx]; 81 } 82 83 size_t GetServiceCount() const { 84 return provider_.services_.size(); 85 } 86 87 NiceMockControl control_; 88 MockMetrics metrics_; 89 MockManager manager_; 90 MockDeviceInfo device_info_; 91 VPNProvider provider_; 92 }; 93 94 const char VPNProviderTest::kHost[] = "10.8.0.1"; 95 const char VPNProviderTest::kName[] = "vpn-name"; 96 97 TEST_F(VPNProviderTest, GetServiceNoType) { 98 KeyValueStore args; 99 Error e; 100 args.SetString(kTypeProperty, kTypeVPN); 101 ServiceRefPtr service = provider_.GetService(args, &e); 102 EXPECT_EQ(Error::kNotSupported, e.type()); 103 EXPECT_FALSE(service); 104 } 105 106 TEST_F(VPNProviderTest, GetServiceUnsupportedType) { 107 KeyValueStore args; 108 Error e; 109 args.SetString(kTypeProperty, kTypeVPN); 110 args.SetString(kProviderTypeProperty, "unknown-vpn-type"); 111 args.SetString(kProviderHostProperty, kHost); 112 args.SetString(kNameProperty, kName); 113 ServiceRefPtr service = provider_.GetService(args, &e); 114 EXPECT_EQ(Error::kNotSupported, e.type()); 115 EXPECT_FALSE(service); 116 } 117 118 TEST_F(VPNProviderTest, GetService) { 119 KeyValueStore args; 120 args.SetString(kTypeProperty, kTypeVPN); 121 args.SetString(kProviderTypeProperty, kProviderOpenVpn); 122 args.SetString(kProviderHostProperty, kHost); 123 args.SetString(kNameProperty, kName); 124 125 { 126 Error error; 127 ServiceRefPtr service = provider_.FindSimilarService(args, &error); 128 EXPECT_EQ(Error::kNotFound, error.type()); 129 EXPECT_EQ(nullptr, service.get()); 130 } 131 132 EXPECT_EQ(0, GetServiceCount()); 133 134 ServiceRefPtr service; 135 { 136 Error error; 137 EXPECT_CALL(manager_, device_info()).WillOnce(Return(&device_info_)); 138 EXPECT_CALL(manager_, RegisterService(_)); 139 service = provider_.GetService(args, &error); 140 EXPECT_TRUE(error.IsSuccess()); 141 ASSERT_TRUE(service); 142 testing::Mock::VerifyAndClearExpectations(&manager_); 143 } 144 145 EXPECT_EQ("vpn_10_8_0_1_vpn_name", service->GetStorageIdentifier()); 146 EXPECT_EQ(kName, GetServiceFriendlyName(service)); 147 148 EXPECT_EQ(1, GetServiceCount()); 149 150 // Configure the service to set its properties (including Provider.Host). 151 { 152 Error error; 153 service->Configure(args, &error); 154 EXPECT_TRUE(error.IsSuccess()); 155 } 156 157 // None of the calls below should cause a new service to be registered. 158 EXPECT_CALL(manager_, RegisterService(_)).Times(0); 159 160 // A second call should return the same service. 161 { 162 Error error; 163 ServiceRefPtr get_service = provider_.GetService(args, &error); 164 EXPECT_TRUE(error.IsSuccess()); 165 ASSERT_EQ(service, get_service); 166 } 167 168 EXPECT_EQ(1, GetServiceCount()); 169 170 // FindSimilarService should also return this service. 171 { 172 Error error; 173 ServiceRefPtr similar_service = provider_.FindSimilarService(args, &error); 174 EXPECT_TRUE(error.IsSuccess()); 175 EXPECT_EQ(service, similar_service); 176 } 177 178 EXPECT_EQ(1, GetServiceCount()); 179 180 // However, CreateTemporaryService should create a different service. 181 { 182 Error error; 183 ServiceRefPtr temporary_service = 184 provider_.CreateTemporaryService(args, &error); 185 EXPECT_TRUE(error.IsSuccess()); 186 EXPECT_NE(service, temporary_service); 187 188 // However this service will not be part of the provider. 189 EXPECT_EQ(1, GetServiceCount()); 190 } 191 } 192 193 TEST_F(VPNProviderTest, OnDeviceInfoAvailable) { 194 const string kInterfaceName("tun0"); 195 const int kInterfaceIndex = 1; 196 197 unique_ptr<MockVPNDriver> bad_driver(new MockVPNDriver()); 198 EXPECT_CALL(*bad_driver.get(), ClaimInterface(_, _)) 199 .Times(2) 200 .WillRepeatedly(Return(false)); 201 provider_.services_.push_back(new VPNService(&control_, nullptr, &metrics_, 202 nullptr, bad_driver.release())); 203 204 EXPECT_FALSE(provider_.OnDeviceInfoAvailable(kInterfaceName, 205 kInterfaceIndex)); 206 207 unique_ptr<MockVPNDriver> good_driver(new MockVPNDriver()); 208 EXPECT_CALL(*good_driver.get(), ClaimInterface(_, _)) 209 .WillOnce(Return(true)); 210 provider_.services_.push_back(new VPNService(&control_, nullptr, &metrics_, 211 nullptr, good_driver.release())); 212 213 unique_ptr<MockVPNDriver> dup_driver(new MockVPNDriver()); 214 EXPECT_CALL(*dup_driver.get(), ClaimInterface(_, _)) 215 .Times(0); 216 provider_.services_.push_back(new VPNService(&control_, nullptr, &metrics_, 217 nullptr, dup_driver.release())); 218 219 EXPECT_TRUE(provider_.OnDeviceInfoAvailable(kInterfaceName, kInterfaceIndex)); 220 provider_.services_.clear(); 221 } 222 223 TEST_F(VPNProviderTest, RemoveService) { 224 scoped_refptr<MockVPNService> service0( 225 new MockVPNService(&control_, nullptr, &metrics_, nullptr, nullptr)); 226 scoped_refptr<MockVPNService> service1( 227 new MockVPNService(&control_, nullptr, &metrics_, nullptr, nullptr)); 228 scoped_refptr<MockVPNService> service2( 229 new MockVPNService(&control_, nullptr, &metrics_, nullptr, nullptr)); 230 231 provider_.services_.push_back(service0.get()); 232 provider_.services_.push_back(service1.get()); 233 provider_.services_.push_back(service2.get()); 234 235 ASSERT_EQ(3, provider_.services_.size()); 236 237 provider_.RemoveService(service1); 238 239 EXPECT_EQ(2, provider_.services_.size()); 240 EXPECT_EQ(service0, provider_.services_[0]); 241 EXPECT_EQ(service2, provider_.services_[1]); 242 243 provider_.RemoveService(service2); 244 245 EXPECT_EQ(1, provider_.services_.size()); 246 EXPECT_EQ(service0, provider_.services_[0]); 247 248 provider_.RemoveService(service0); 249 EXPECT_EQ(0, provider_.services_.size()); 250 } 251 252 MATCHER_P(ServiceWithStorageId, storage_id, "") { 253 return arg->GetStorageIdentifier() == storage_id; 254 } 255 256 TEST_F(VPNProviderTest, CreateServicesFromProfile) { 257 FakeStore storage; 258 storage.SetString("no_type", "Name", "No Type Entry"); 259 storage.SetString("no_vpn", "Type", "wimax"); 260 storage.SetString("vpn_no_provider_type", "Type", "vpn"); 261 storage.SetString("vpn_no_name", "Type", "vpn"); 262 storage.SetString("vpn_no_name", "Provider.Type", "openvpn"); 263 storage.SetString("vpn_no_host", "Type", "vpn"); 264 storage.SetString("vpn_no_host", "Provider.Type", "openvpn"); 265 storage.SetString("vpn_ho_host", "Name", "name"); 266 storage.SetString("vpn_complete", "Type", "vpn"); 267 storage.SetString("vpn_complete", "Provider.Type", "openvpn"); 268 storage.SetString("vpn_complete", "Name", "name"); 269 storage.SetString("vpn_complete", "Provider.Host", "1.2.3.4"); 270 271 scoped_refptr<MockProfile> profile( 272 new NiceMock<MockProfile>(&control_, &metrics_, &manager_, "")); 273 EXPECT_CALL(*profile, GetConstStorage()).WillRepeatedly(Return(&storage)); 274 275 EXPECT_CALL(manager_, device_info()).WillRepeatedly(Return(nullptr)); 276 EXPECT_CALL(manager_, 277 RegisterService(ServiceWithStorageId("vpn_complete"))); 278 EXPECT_CALL(*profile, 279 ConfigureService(ServiceWithStorageId("vpn_complete"))) 280 .WillOnce(Return(true)); 281 provider_.CreateServicesFromProfile(profile); 282 283 GetServiceAt(0)->driver()->args()->SetString(kProviderHostProperty, 284 "1.2.3.4"); 285 // Calling this again should not create any more services (checked by the 286 // Times(1) above). 287 provider_.CreateServicesFromProfile(profile); 288 } 289 290 TEST_F(VPNProviderTest, CreateService) { 291 static const char kName[] = "test-vpn-service"; 292 static const char kStorageID[] = "test_vpn_storage_id"; 293 static const char* kTypes[] = { 294 kProviderOpenVpn, 295 kProviderL2tpIpsec, 296 kProviderThirdPartyVpn 297 }; 298 const size_t kTypesCount = arraysize(kTypes); 299 EXPECT_CALL(manager_, device_info()) 300 .Times(kTypesCount) 301 .WillRepeatedly(Return(&device_info_)); 302 EXPECT_CALL(manager_, RegisterService(_)).Times(kTypesCount); 303 for (size_t i = 0; i < kTypesCount; i++) { 304 Error error; 305 VPNServiceRefPtr service = 306 provider_.CreateService(kTypes[i], kName, kStorageID, &error); 307 ASSERT_TRUE(service) << kTypes[i]; 308 ASSERT_TRUE(service->driver()) << kTypes[i]; 309 EXPECT_EQ(kTypes[i], service->driver()->GetProviderType()); 310 EXPECT_EQ(kName, GetServiceFriendlyName(service)) << kTypes[i]; 311 EXPECT_EQ(kStorageID, service->GetStorageIdentifier()) << kTypes[i]; 312 EXPECT_TRUE(error.IsSuccess()) << kTypes[i]; 313 } 314 Error error; 315 VPNServiceRefPtr unknown_service = 316 provider_.CreateService("unknown-vpn-type", kName, kStorageID, &error); 317 EXPECT_FALSE(unknown_service); 318 EXPECT_EQ(Error::kNotSupported, error.type()); 319 } 320 321 TEST_F(VPNProviderTest, CreateTemporaryServiceFromProfile) { 322 FakeStore storage; 323 storage.SetString("no_vpn", "Type", "wimax"); 324 storage.SetString("vpn_no_provider_type", "Type", "vpn"); 325 storage.SetString("vpn_no_name", "Type", "vpn"); 326 storage.SetString("vpn_no_name", "Provider.Type", "openvpn"); 327 storage.SetString("vpn_no_host", "Type", "vpn"); 328 storage.SetString("vpn_no_host", "Provider.Type", "openvpn"); 329 storage.SetString("vpn_no_host", "Name", "name"); 330 storage.SetString("vpn_complete", "Type", "vpn"); 331 storage.SetString("vpn_complete", "Provider.Type", "openvpn"); 332 storage.SetString("vpn_complete", "Name", "name"); 333 storage.SetString("vpn_complete", "Provider.Host", "1.2.3.4"); 334 335 scoped_refptr<MockProfile> profile( 336 new NiceMock<MockProfile>(&control_, &metrics_, &manager_, "")); 337 EXPECT_CALL(*profile, GetConstStorage()).WillRepeatedly(Return(&storage)); 338 Error error; 339 340 // Non VPN entry. 341 EXPECT_EQ(nullptr, 342 provider_.CreateTemporaryServiceFromProfile(profile, 343 "no_vpn", 344 &error)); 345 EXPECT_FALSE(error.IsSuccess()); 346 EXPECT_THAT(error.message(), 347 StartsWith("Unspecified or invalid network type")); 348 349 // VPN type not specified. 350 error.Reset(); 351 EXPECT_EQ(nullptr, 352 provider_.CreateTemporaryServiceFromProfile(profile, 353 "vpn_no_provider_type", 354 &error)); 355 EXPECT_FALSE(error.IsSuccess()); 356 EXPECT_THAT(error.message(), StartsWith("VPN type not specified")); 357 358 // Name not specified. 359 error.Reset(); 360 EXPECT_EQ(nullptr, 361 provider_.CreateTemporaryServiceFromProfile(profile, 362 "vpn_no_name", 363 &error)); 364 EXPECT_FALSE(error.IsSuccess()); 365 EXPECT_THAT(error.message(), StartsWith("Network name not specified")); 366 367 // Host not specified. 368 error.Reset(); 369 EXPECT_EQ(nullptr, 370 provider_.CreateTemporaryServiceFromProfile(profile, 371 "vpn_no_host", 372 &error)); 373 EXPECT_FALSE(error.IsSuccess()); 374 EXPECT_THAT(error.message(), StartsWith("Host not specified")); 375 376 // Valid VPN service entry. 377 error.Reset(); 378 EXPECT_NE(nullptr, 379 provider_.CreateTemporaryServiceFromProfile(profile, 380 "vpn_complete", 381 &error)); 382 EXPECT_TRUE(error.IsSuccess()); 383 } 384 385 TEST_F(VPNProviderTest, HasActiveService) { 386 EXPECT_FALSE(provider_.HasActiveService()); 387 388 scoped_refptr<MockVPNService> service0( 389 new MockVPNService(&control_, nullptr, &metrics_, nullptr, nullptr)); 390 scoped_refptr<MockVPNService> service1( 391 new MockVPNService(&control_, nullptr, &metrics_, nullptr, nullptr)); 392 scoped_refptr<MockVPNService> service2( 393 new MockVPNService(&control_, nullptr, &metrics_, nullptr, nullptr)); 394 395 AddService(service0); 396 AddService(service1); 397 AddService(service2); 398 EXPECT_FALSE(provider_.HasActiveService()); 399 400 SetConnectState(service1, Service::kStateAssociating); 401 EXPECT_TRUE(provider_.HasActiveService()); 402 403 SetConnectState(service1, Service::kStateOnline); 404 EXPECT_TRUE(provider_.HasActiveService()); 405 } 406 407 } // namespace shill 408