1c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
2c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Copyright (C) 2012 The Android Open Source Project
3c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
4c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Licensed under the Apache License, Version 2.0 (the "License");
5c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// you may not use this file except in compliance with the License.
6c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// You may obtain a copy of the License at
7c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
8c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//      http://www.apache.org/licenses/LICENSE-2.0
9c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
10c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Unless required by applicable law or agreed to in writing, software
11c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// distributed under the License is distributed on an "AS IS" BASIS,
12c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// See the License for the specific language governing permissions and
14c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// limitations under the License.
15c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
1633af05c849e0888b15222da38b55515784b821c7Darin Petkov
172240e8c03451c6b6f21eb8944d8a1c0747ac10b3Ben Chan#include "shill/vpn/vpn_service.h"
1833af05c849e0888b15222da38b55515784b821c7Darin Petkov
19cddd2d09878704128d35ddfeec862109b7d7fdc9Alex Deymo#include <string>
20cddd2d09878704128d35ddfeec862109b7d7fdc9Alex Deymo
21289a5a5e18bb1a676b3dfce111af4c2c00c7776eSamuel Tan#if defined(__ANDROID__)
22289a5a5e18bb1a676b3dfce111af4c2c00c7776eSamuel Tan#include <dbus/service_constants.h>
23289a5a5e18bb1a676b3dfce111af4c2c00c7776eSamuel Tan#else
2402867717f4e1e72ae3ed337ed854736c7b00130eDarin Petkov#include <chromeos/dbus/service_constants.h>
25289a5a5e18bb1a676b3dfce111af4c2c00c7776eSamuel Tan#endif  // __ANDROID__
2633af05c849e0888b15222da38b55515784b821c7Darin Petkov#include <gtest/gtest.h>
2733af05c849e0888b15222da38b55515784b821c7Darin Petkov
2833af05c849e0888b15222da38b55515784b821c7Darin Petkov#include "shill/error.h"
2933af05c849e0888b15222da38b55515784b821c7Darin Petkov#include "shill/mock_adaptors.h"
305eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov#include "shill/mock_connection.h"
315eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov#include "shill/mock_device_info.h"
32a0e645ef4df5ed16fef367ec97c3d9cded7980eeDarin Petkov#include "shill/mock_manager.h"
3333af05c849e0888b15222da38b55515784b821c7Darin Petkov#include "shill/mock_metrics.h"
349c6e9818cd1337ee06a218db83ee577ac977c7d9Darin Petkov#include "shill/mock_profile.h"
35f3c71d70885fdddff8d71db75878c1310af28f9dDarin Petkov#include "shill/mock_store.h"
368d6b59704591ba9fad57751858835dc332dbdd37Peter Qiu#include "shill/net/mock_sockets.h"
37a41ab517725d036b63420f8445550246f8f50b99Alex Vakulenko#include "shill/nice_mock_control.h"
38cbfb34e699532f62eb5b381d0ea3a15d39e00b7cmukesh agrawal#include "shill/service_property_change_test.h"
392240e8c03451c6b6f21eb8944d8a1c0747ac10b3Ben Chan#include "shill/vpn/mock_vpn_driver.h"
402240e8c03451c6b6f21eb8944d8a1c0747ac10b3Ben Chan#include "shill/vpn/mock_vpn_provider.h"
4133af05c849e0888b15222da38b55515784b821c7Darin Petkov
425eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkovusing std::string;
4379d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkovusing testing::_;
44fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymousing testing::Mock;
45f3c71d70885fdddff8d71db75878c1310af28f9dDarin Petkovusing testing::NiceMock;
46f3c71d70885fdddff8d71db75878c1310af28f9dDarin Petkovusing testing::Return;
475eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkovusing testing::ReturnRef;
487f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewartusing testing::ReturnRefOfCopy;
4979d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov
5033af05c849e0888b15222da38b55515784b821c7Darin Petkovnamespace shill {
5133af05c849e0888b15222da38b55515784b821c7Darin Petkov
5233af05c849e0888b15222da38b55515784b821c7Darin Petkovclass VPNServiceTest : public testing::Test {
5333af05c849e0888b15222da38b55515784b821c7Darin Petkov public:
5433af05c849e0888b15222da38b55515784b821c7Darin Petkov  VPNServiceTest()
555eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov      : interface_name_("test-interface"),
565eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov        driver_(new MockVPNDriver()),
57bad1c10ffd2d4ac14f7bd9f4ef6a8982e711f566mukesh agrawal        manager_(&control_, nullptr, nullptr),
584168b2c8d57755ea6b16763745379e0529541a3fBen Chan        metrics_(nullptr),
594168b2c8d57755ea6b16763745379e0529541a3fBen Chan        device_info_(&control_, nullptr, nullptr, nullptr),
605eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov        connection_(new NiceMock<MockConnection>(&device_info_)),
615eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov        sockets_(new MockSockets()),
624168b2c8d57755ea6b16763745379e0529541a3fBen Chan        service_(new VPNService(&control_, nullptr, &metrics_, &manager_,
635eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov                                driver_)) {
645eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov    service_->sockets_.reset(sockets_);  // Passes ownership.
655eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov  }
6633af05c849e0888b15222da38b55515784b821c7Darin Petkov
6733af05c849e0888b15222da38b55515784b821c7Darin Petkov  virtual ~VPNServiceTest() {}
6833af05c849e0888b15222da38b55515784b821c7Darin Petkov
6933af05c849e0888b15222da38b55515784b821c7Darin Petkov protected:
705eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov  virtual void SetUp() {
715eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov    ON_CALL(*connection_, interface_name())
725eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov        .WillByDefault(ReturnRef(interface_name_));
731e3bc4967760686fd475f899951db4414d6c822bPaul Stewart    ON_CALL(*connection_, ipconfig_rpc_identifier())
741e3bc4967760686fd475f899951db4414d6c822bPaul Stewart        .WillByDefault(ReturnRef(ipconfig_rpc_identifier_));
755eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov  }
765eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov
775eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov  virtual void TearDown() {
785eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov    EXPECT_CALL(device_info_, FlushAddresses(0));
795eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov  }
805eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov
815eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov  void SetServiceState(Service::ConnectState state) {
825eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov    service_->state_ = state;
835eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov  }
845eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov
8579349f031df30747ae7a1271f80724036ba3e961Darin Petkov  void SetHasEverConnected(bool connected) {
8679349f031df30747ae7a1271f80724036ba3e961Darin Petkov    service_->has_ever_connected_ = connected;
8779349f031df30747ae7a1271f80724036ba3e961Darin Petkov  }
8879349f031df30747ae7a1271f80724036ba3e961Darin Petkov
8979349f031df30747ae7a1271f80724036ba3e961Darin Petkov  void SetConnectable(bool connectable) {
9079349f031df30747ae7a1271f80724036ba3e961Darin Petkov    service_->connectable_ = connectable;
9179349f031df30747ae7a1271f80724036ba3e961Darin Petkov  }
9279349f031df30747ae7a1271f80724036ba3e961Darin Petkov
93e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  const char* GetAutoConnOffline() {
944cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov    return Service::kAutoConnOffline;
954cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov  }
964cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov
97e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  const char* GetAutoConnNeverConnected() {
984cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov    return VPNService::kAutoConnNeverConnected;
994cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov  }
1004cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov
101e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  const char* GetAutoConnVPNAlreadyActive() {
1024cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov    return VPNService::kAutoConnVPNAlreadyActive;
1034cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov  }
1044cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov
105e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  bool IsAutoConnectable(const char** reason) const {
1064cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov    return service_->IsAutoConnectable(reason);
1074cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov  }
1084cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov
109c3505a569e3f98ce56e4017300a3ce46bc714e4cDarin Petkov  // Takes ownership of |provider|.
110e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  void SetVPNProvider(VPNProvider* provider) {
111c3505a569e3f98ce56e4017300a3ce46bc714e4cDarin Petkov    manager_.vpn_provider_.reset(provider);
112b87d22b774fe15b6580d13638d5f0514bde031fdPaul Stewart    manager_.UpdateProviderMapping();
113c3505a569e3f98ce56e4017300a3ce46bc714e4cDarin Petkov  }
114c3505a569e3f98ce56e4017300a3ce46bc714e4cDarin Petkov
115e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  ServiceMockAdaptor* GetAdaptor() {
116fa1eb722d0742d89c26b9c5c81d02ef2a138cbf2Alex Vakulenko    return static_cast<ServiceMockAdaptor*>(service_->adaptor());
117cbfb34e699532f62eb5b381d0ea3a15d39e00b7cmukesh agrawal  }
118cbfb34e699532f62eb5b381d0ea3a15d39e00b7cmukesh agrawal
1195eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov  std::string interface_name_;
1201e3bc4967760686fd475f899951db4414d6c822bPaul Stewart  std::string ipconfig_rpc_identifier_;
121e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  MockVPNDriver* driver_;  // Owned by |service_|.
12233af05c849e0888b15222da38b55515784b821c7Darin Petkov  NiceMockControl control_;
123a0e645ef4df5ed16fef367ec97c3d9cded7980eeDarin Petkov  MockManager manager_;
12433af05c849e0888b15222da38b55515784b821c7Darin Petkov  MockMetrics metrics_;
1255eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov  MockDeviceInfo device_info_;
126e2ee5e009081a392fb31596c1d0cfb30bc7bad6eBen Chan  scoped_refptr<NiceMock<MockConnection>> connection_;
127e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  MockSockets* sockets_;  // Owned by |service_|.
12833af05c849e0888b15222da38b55515784b821c7Darin Petkov  VPNServiceRefPtr service_;
12933af05c849e0888b15222da38b55515784b821c7Darin Petkov};
13033af05c849e0888b15222da38b55515784b821c7Darin Petkov
13133af05c849e0888b15222da38b55515784b821c7Darin PetkovTEST_F(VPNServiceTest, Connect) {
1322f903b3842af547e062fbf7b21a04e103211dec3Darin Petkov  EXPECT_TRUE(service_->connectable());
13333af05c849e0888b15222da38b55515784b821c7Darin Petkov  Error error;
13479d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  EXPECT_CALL(*driver_, Connect(_, &error));
135dc7b8447aa220fae51b73fd8610cbfed14ed57fcmukesh agrawal  service_->Connect(&error, "in test");
13679d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  EXPECT_TRUE(error.IsSuccess());
13733af05c849e0888b15222da38b55515784b821c7Darin Petkov}
13833af05c849e0888b15222da38b55515784b821c7Darin Petkov
1392f903b3842af547e062fbf7b21a04e103211dec3Darin PetkovTEST_F(VPNServiceTest, ConnectAlreadyConnected) {
1402f903b3842af547e062fbf7b21a04e103211dec3Darin Petkov  Error error;
1412f903b3842af547e062fbf7b21a04e103211dec3Darin Petkov  EXPECT_CALL(*driver_, Connect(_, _)).Times(0);
1425eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov  SetServiceState(Service::kStateOnline);
143dc7b8447aa220fae51b73fd8610cbfed14ed57fcmukesh agrawal  service_->Connect(&error, "in test");
1442f903b3842af547e062fbf7b21a04e103211dec3Darin Petkov  EXPECT_EQ(Error::kAlreadyConnected, error.type());
1452f903b3842af547e062fbf7b21a04e103211dec3Darin Petkov  error.Reset();
1465eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov  SetServiceState(Service::kStateConfiguring);
147dc7b8447aa220fae51b73fd8610cbfed14ed57fcmukesh agrawal  service_->Connect(&error, "in test");
148dba10462000f10426bd9b7e6b54a661a1da71f85mukesh agrawal  EXPECT_EQ(Error::kInProgress, error.type());
1492f903b3842af547e062fbf7b21a04e103211dec3Darin Petkov}
1502f903b3842af547e062fbf7b21a04e103211dec3Darin Petkov
1516aa2187f18e5a9ba3d6d475669cd27dfee4d92bdDarin PetkovTEST_F(VPNServiceTest, Disconnect) {
1526aa2187f18e5a9ba3d6d475669cd27dfee4d92bdDarin Petkov  Error error;
1536aa2187f18e5a9ba3d6d475669cd27dfee4d92bdDarin Petkov  EXPECT_CALL(*driver_, Disconnect());
1540d06119be3224788ba1aa65ed24bc8e46b56b949Samuel Tan  service_->Disconnect(&error, "in test");
1556aa2187f18e5a9ba3d6d475669cd27dfee4d92bdDarin Petkov  EXPECT_TRUE(error.IsSuccess());
1566aa2187f18e5a9ba3d6d475669cd27dfee4d92bdDarin Petkov}
1576aa2187f18e5a9ba3d6d475669cd27dfee4d92bdDarin Petkov
15802867717f4e1e72ae3ed337ed854736c7b00130eDarin PetkovTEST_F(VPNServiceTest, CreateStorageIdentifierNoHost) {
15902867717f4e1e72ae3ed337ed854736c7b00130eDarin Petkov  KeyValueStore args;
16002867717f4e1e72ae3ed337ed854736c7b00130eDarin Petkov  Error error;
1617372878af066cc079ad88a7b004ca3f769952de2Ben Chan  args.SetString(kNameProperty, "vpn-name");
16202867717f4e1e72ae3ed337ed854736c7b00130eDarin Petkov  EXPECT_EQ("", VPNService::CreateStorageIdentifier(args, &error));
16302867717f4e1e72ae3ed337ed854736c7b00130eDarin Petkov  EXPECT_EQ(Error::kInvalidProperty, error.type());
16402867717f4e1e72ae3ed337ed854736c7b00130eDarin Petkov}
16502867717f4e1e72ae3ed337ed854736c7b00130eDarin Petkov
16602867717f4e1e72ae3ed337ed854736c7b00130eDarin PetkovTEST_F(VPNServiceTest, CreateStorageIdentifierNoName) {
16702867717f4e1e72ae3ed337ed854736c7b00130eDarin Petkov  KeyValueStore args;
16802867717f4e1e72ae3ed337ed854736c7b00130eDarin Petkov  Error error;
1697372878af066cc079ad88a7b004ca3f769952de2Ben Chan  args.SetString(kProviderHostProperty, "10.8.0.1");
17002867717f4e1e72ae3ed337ed854736c7b00130eDarin Petkov  EXPECT_EQ("", VPNService::CreateStorageIdentifier(args, &error));
17102867717f4e1e72ae3ed337ed854736c7b00130eDarin Petkov  EXPECT_EQ(Error::kNotSupported, error.type());
17202867717f4e1e72ae3ed337ed854736c7b00130eDarin Petkov}
17302867717f4e1e72ae3ed337ed854736c7b00130eDarin Petkov
17402867717f4e1e72ae3ed337ed854736c7b00130eDarin PetkovTEST_F(VPNServiceTest, CreateStorageIdentifier) {
17502867717f4e1e72ae3ed337ed854736c7b00130eDarin Petkov  KeyValueStore args;
17602867717f4e1e72ae3ed337ed854736c7b00130eDarin Petkov  Error error;
1777372878af066cc079ad88a7b004ca3f769952de2Ben Chan  args.SetString(kNameProperty, "vpn-name");
1787372878af066cc079ad88a7b004ca3f769952de2Ben Chan  args.SetString(kProviderHostProperty, "10.8.0.1");
17902867717f4e1e72ae3ed337ed854736c7b00130eDarin Petkov  EXPECT_EQ("vpn_10_8_0_1_vpn_name",
18002867717f4e1e72ae3ed337ed854736c7b00130eDarin Petkov            VPNService::CreateStorageIdentifier(args, &error));
18102867717f4e1e72ae3ed337ed854736c7b00130eDarin Petkov  EXPECT_TRUE(error.IsSuccess());
18202867717f4e1e72ae3ed337ed854736c7b00130eDarin Petkov}
18302867717f4e1e72ae3ed337ed854736c7b00130eDarin Petkov
18433af05c849e0888b15222da38b55515784b821c7Darin PetkovTEST_F(VPNServiceTest, GetStorageIdentifier) {
18533af05c849e0888b15222da38b55515784b821c7Darin Petkov  EXPECT_EQ("", service_->GetStorageIdentifier());
18602867717f4e1e72ae3ed337ed854736c7b00130eDarin Petkov  service_->set_storage_id("foo");
18702867717f4e1e72ae3ed337ed854736c7b00130eDarin Petkov  EXPECT_EQ("foo", service_->GetStorageIdentifier());
18833af05c849e0888b15222da38b55515784b821c7Darin Petkov}
18933af05c849e0888b15222da38b55515784b821c7Darin Petkov
19033af05c849e0888b15222da38b55515784b821c7Darin PetkovTEST_F(VPNServiceTest, GetDeviceRpcId) {
19133af05c849e0888b15222da38b55515784b821c7Darin Petkov  Error error;
19233af05c849e0888b15222da38b55515784b821c7Darin Petkov  EXPECT_EQ("/", service_->GetDeviceRpcId(&error));
19333af05c849e0888b15222da38b55515784b821c7Darin Petkov  EXPECT_EQ(Error::kNotSupported, error.type());
19433af05c849e0888b15222da38b55515784b821c7Darin Petkov}
19533af05c849e0888b15222da38b55515784b821c7Darin Petkov
196f3c71d70885fdddff8d71db75878c1310af28f9dDarin PetkovTEST_F(VPNServiceTest, Load) {
197f3c71d70885fdddff8d71db75878c1310af28f9dDarin Petkov  NiceMock<MockStore> storage;
198f3c71d70885fdddff8d71db75878c1310af28f9dDarin Petkov  static const char kStorageID[] = "storage-id";
199f3c71d70885fdddff8d71db75878c1310af28f9dDarin Petkov  service_->set_storage_id(kStorageID);
200f3c71d70885fdddff8d71db75878c1310af28f9dDarin Petkov  EXPECT_CALL(storage, ContainsGroup(kStorageID)).WillOnce(Return(true));
201cb71529cc0432935aff005726c81df109d1dc710Darin Petkov  EXPECT_CALL(*driver_, Load(&storage, kStorageID))
202cb71529cc0432935aff005726c81df109d1dc710Darin Petkov      .WillOnce(Return(true));
203f3c71d70885fdddff8d71db75878c1310af28f9dDarin Petkov  EXPECT_TRUE(service_->Load(&storage));
204f3c71d70885fdddff8d71db75878c1310af28f9dDarin Petkov}
205f3c71d70885fdddff8d71db75878c1310af28f9dDarin Petkov
206f3c71d70885fdddff8d71db75878c1310af28f9dDarin PetkovTEST_F(VPNServiceTest, Save) {
207f3c71d70885fdddff8d71db75878c1310af28f9dDarin Petkov  NiceMock<MockStore> storage;
208f3c71d70885fdddff8d71db75878c1310af28f9dDarin Petkov  static const char kStorageID[] = "storage-id";
209f3c71d70885fdddff8d71db75878c1310af28f9dDarin Petkov  service_->set_storage_id(kStorageID);
210cb71529cc0432935aff005726c81df109d1dc710Darin Petkov  EXPECT_CALL(*driver_, Save(&storage, kStorageID, false))
211cb71529cc0432935aff005726c81df109d1dc710Darin Petkov      .WillOnce(Return(true));
212f3c71d70885fdddff8d71db75878c1310af28f9dDarin Petkov  EXPECT_TRUE(service_->Save(&storage));
213f3c71d70885fdddff8d71db75878c1310af28f9dDarin Petkov}
214f3c71d70885fdddff8d71db75878c1310af28f9dDarin Petkov
215cb71529cc0432935aff005726c81df109d1dc710Darin PetkovTEST_F(VPNServiceTest, SaveCredentials) {
216cb71529cc0432935aff005726c81df109d1dc710Darin Petkov  NiceMock<MockStore> storage;
217cb71529cc0432935aff005726c81df109d1dc710Darin Petkov  static const char kStorageID[] = "storage-id";
218cb71529cc0432935aff005726c81df109d1dc710Darin Petkov  service_->set_storage_id(kStorageID);
219cb71529cc0432935aff005726c81df109d1dc710Darin Petkov  service_->set_save_credentials(true);
220cb71529cc0432935aff005726c81df109d1dc710Darin Petkov  EXPECT_CALL(*driver_, Save(&storage, kStorageID, true))
221cb71529cc0432935aff005726c81df109d1dc710Darin Petkov      .WillOnce(Return(true));
222cb71529cc0432935aff005726c81df109d1dc710Darin Petkov  EXPECT_TRUE(service_->Save(&storage));
223ebd3856da9d213154f3c85a71e4ec8e8fce3b9eaPaul Stewart}
224ebd3856da9d213154f3c85a71e4ec8e8fce3b9eaPaul Stewart
225a0e645ef4df5ed16fef367ec97c3d9cded7980eeDarin PetkovTEST_F(VPNServiceTest, Unload) {
226cbfb34e699532f62eb5b381d0ea3a15d39e00b7cmukesh agrawal  service_->SetAutoConnect(true);
227cb71529cc0432935aff005726c81df109d1dc710Darin Petkov  service_->set_save_credentials(true);
228a0e645ef4df5ed16fef367ec97c3d9cded7980eeDarin Petkov  EXPECT_CALL(*driver_, Disconnect());
229cb71529cc0432935aff005726c81df109d1dc710Darin Petkov  EXPECT_CALL(*driver_, UnloadCredentials());
230e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  MockVPNProvider* provider = new MockVPNProvider;
231c3505a569e3f98ce56e4017300a3ce46bc714e4cDarin Petkov  SetVPNProvider(provider);
232c3505a569e3f98ce56e4017300a3ce46bc714e4cDarin Petkov  provider->services_.push_back(service_);
233a0e645ef4df5ed16fef367ec97c3d9cded7980eeDarin Petkov  service_->Unload();
234cb71529cc0432935aff005726c81df109d1dc710Darin Petkov  EXPECT_FALSE(service_->auto_connect());
235cb71529cc0432935aff005726c81df109d1dc710Darin Petkov  EXPECT_FALSE(service_->save_credentials());
236c3505a569e3f98ce56e4017300a3ce46bc714e4cDarin Petkov  EXPECT_TRUE(provider->services_.empty());
237a0e645ef4df5ed16fef367ec97c3d9cded7980eeDarin Petkov}
238a0e645ef4df5ed16fef367ec97c3d9cded7980eeDarin Petkov
239cb71529cc0432935aff005726c81df109d1dc710Darin PetkovTEST_F(VPNServiceTest, InitPropertyStore) {
240cb71529cc0432935aff005726c81df109d1dc710Darin Petkov  EXPECT_CALL(*driver_, InitPropertyStore(service_->mutable_store()));
241cb71529cc0432935aff005726c81df109d1dc710Darin Petkov  service_->InitDriverPropertyStore();
242cb71529cc0432935aff005726c81df109d1dc710Darin Petkov}
243cb71529cc0432935aff005726c81df109d1dc710Darin Petkov
2442da34c038933eeac36a85550ff54e09611a1d828Paul StewartTEST_F(VPNServiceTest, EnableAndRetainAutoConnect) {
2452da34c038933eeac36a85550ff54e09611a1d828Paul Stewart  EXPECT_FALSE(service_->retain_auto_connect());
2461d0080a0f39f03402cde853d832af976eb32852bDarin Petkov  EXPECT_FALSE(service_->auto_connect());
2472da34c038933eeac36a85550ff54e09611a1d828Paul Stewart  service_->EnableAndRetainAutoConnect();
2482da34c038933eeac36a85550ff54e09611a1d828Paul Stewart  EXPECT_TRUE(service_->retain_auto_connect());
2491d0080a0f39f03402cde853d832af976eb32852bDarin Petkov  EXPECT_FALSE(service_->auto_connect());
2501d0080a0f39f03402cde853d832af976eb32852bDarin Petkov}
2511d0080a0f39f03402cde853d832af976eb32852bDarin Petkov
2525eb0542cb67358d9030367498a4ad741fc42af4fDarin PetkovTEST_F(VPNServiceTest, SetConnection) {
2535eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov  EXPECT_FALSE(service_->connection_binder_.get());
2545eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov  EXPECT_FALSE(service_->connection());
2555eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov  EXPECT_CALL(*sockets_, Socket(_, _, _)).WillOnce(Return(-1));
2565eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov  service_->SetConnection(connection_);
2575eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov  ASSERT_TRUE(service_->connection_binder_.get());
2585eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov  EXPECT_EQ(connection_.get(),
2595eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov            service_->connection_binder_->connection().get());
2605eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov  EXPECT_EQ(connection_.get(), service_->connection().get());
2615eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov  EXPECT_CALL(*driver_, OnConnectionDisconnected()).Times(0);
2625eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov}
2635eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov
2645eb0542cb67358d9030367498a4ad741fc42af4fDarin PetkovTEST_F(VPNServiceTest, OnConnectionDisconnected) {
2655eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov  EXPECT_CALL(*sockets_, Socket(_, _, _)).WillOnce(Return(-1));
2665eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov  service_->SetConnection(connection_);
2675eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov  EXPECT_CALL(*driver_, OnConnectionDisconnected()).Times(1);
2685eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov  connection_->OnLowerDisconnect();
2695eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov}
2705eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov
2714cbff5b5897593f7a2e6de48a98abe72356075afDarin PetkovTEST_F(VPNServiceTest, IsAutoConnectableOffline) {
27279349f031df30747ae7a1271f80724036ba3e961Darin Petkov  EXPECT_TRUE(service_->connectable());
273e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  const char* reason = nullptr;
274700de6400c18f8cba77821f8cd2a1935b96999a6Peter Qiu  EXPECT_CALL(manager_, IsConnected()).WillOnce(Return(false));
2754cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov  EXPECT_FALSE(IsAutoConnectable(&reason));
2764cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov  EXPECT_STREQ(GetAutoConnOffline(), reason);
2774cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov}
27879349f031df30747ae7a1271f80724036ba3e961Darin Petkov
2794cbff5b5897593f7a2e6de48a98abe72356075afDarin PetkovTEST_F(VPNServiceTest, IsAutoConnectableNeverConnected) {
2804cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov  EXPECT_TRUE(service_->connectable());
2814cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov  EXPECT_FALSE(service_->has_ever_connected());
282e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  const char* reason = nullptr;
283700de6400c18f8cba77821f8cd2a1935b96999a6Peter Qiu  EXPECT_CALL(manager_, IsConnected()).WillOnce(Return(true));
2844cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov  EXPECT_FALSE(IsAutoConnectable(&reason));
2854cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov  EXPECT_STREQ(GetAutoConnNeverConnected(), reason);
2864cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov}
28779349f031df30747ae7a1271f80724036ba3e961Darin Petkov
2884cbff5b5897593f7a2e6de48a98abe72356075afDarin PetkovTEST_F(VPNServiceTest, IsAutoConnectableVPNAlreadyActive) {
2894cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov  EXPECT_TRUE(service_->connectable());
29079349f031df30747ae7a1271f80724036ba3e961Darin Petkov  SetHasEverConnected(true);
291700de6400c18f8cba77821f8cd2a1935b96999a6Peter Qiu  EXPECT_CALL(manager_, IsConnected()).WillOnce(Return(true));
292e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  MockVPNProvider* provider = new MockVPNProvider;
293c3505a569e3f98ce56e4017300a3ce46bc714e4cDarin Petkov  SetVPNProvider(provider);
294c3505a569e3f98ce56e4017300a3ce46bc714e4cDarin Petkov  EXPECT_CALL(*provider, HasActiveService()).WillOnce(Return(true));
295e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  const char* reason = nullptr;
2964cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov  EXPECT_FALSE(IsAutoConnectable(&reason));
2974cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov  EXPECT_STREQ(GetAutoConnVPNAlreadyActive(), reason);
2984cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov}
29979349f031df30747ae7a1271f80724036ba3e961Darin Petkov
3004cbff5b5897593f7a2e6de48a98abe72356075afDarin PetkovTEST_F(VPNServiceTest, IsAutoConnectableNotConnectable) {
301e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  const char* reason = nullptr;
30279349f031df30747ae7a1271f80724036ba3e961Darin Petkov  SetConnectable(false);
3034cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov  EXPECT_FALSE(IsAutoConnectable(&reason));
3044cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov}
3054cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov
3064cbff5b5897593f7a2e6de48a98abe72356075afDarin PetkovTEST_F(VPNServiceTest, IsAutoConnectable) {
3074cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov  EXPECT_TRUE(service_->connectable());
3084cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov  SetHasEverConnected(true);
309700de6400c18f8cba77821f8cd2a1935b96999a6Peter Qiu  EXPECT_CALL(manager_, IsConnected()).WillOnce(Return(true));
310e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  MockVPNProvider* provider = new MockVPNProvider;
311c3505a569e3f98ce56e4017300a3ce46bc714e4cDarin Petkov  SetVPNProvider(provider);
312c3505a569e3f98ce56e4017300a3ce46bc714e4cDarin Petkov  EXPECT_CALL(*provider, HasActiveService()).WillOnce(Return(false));
313e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  const char* reason = nullptr;
3144cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov  EXPECT_TRUE(IsAutoConnectable(&reason));
3154cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov  EXPECT_FALSE(reason);
31679349f031df30747ae7a1271f80724036ba3e961Darin Petkov}
31779349f031df30747ae7a1271f80724036ba3e961Darin Petkov
3189c6e9818cd1337ee06a218db83ee577ac977c7d9Darin PetkovTEST_F(VPNServiceTest, SetNamePropertyTrivial) {
319b8172ec75bbc9faac13a33e162ddedd53a97d1c8Peter Qiu  Error error;
320bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal  // A null change returns false, but with error set to success.
321b8172ec75bbc9faac13a33e162ddedd53a97d1c8Peter Qiu  EXPECT_FALSE(service_->mutable_store()->SetAnyProperty(
32203e6719bae1e0903d94853b896673a033196bcf5Alex Vakulenko      kNameProperty, brillo::Any(service_->friendly_name()), &error));
323b8172ec75bbc9faac13a33e162ddedd53a97d1c8Peter Qiu  EXPECT_FALSE(error.IsFailure());
3249c6e9818cd1337ee06a218db83ee577ac977c7d9Darin Petkov}
3259c6e9818cd1337ee06a218db83ee577ac977c7d9Darin Petkov
3269c6e9818cd1337ee06a218db83ee577ac977c7d9Darin PetkovTEST_F(VPNServiceTest, SetNameProperty) {
3279c6e9818cd1337ee06a218db83ee577ac977c7d9Darin Petkov  const string kHost = "1.2.3.4";
3287372878af066cc079ad88a7b004ca3f769952de2Ben Chan  driver_->args()->SetString(kProviderHostProperty, kHost);
3299c6e9818cd1337ee06a218db83ee577ac977c7d9Darin Petkov  string kOldId = service_->GetStorageIdentifier();
330b8172ec75bbc9faac13a33e162ddedd53a97d1c8Peter Qiu  Error error;
3319c6e9818cd1337ee06a218db83ee577ac977c7d9Darin Petkov  const string kName = "New Name";
3329c6e9818cd1337ee06a218db83ee577ac977c7d9Darin Petkov  scoped_refptr<MockProfile> profile(
3339c6e9818cd1337ee06a218db83ee577ac977c7d9Darin Petkov      new MockProfile(&control_, &metrics_, &manager_));
3349c6e9818cd1337ee06a218db83ee577ac977c7d9Darin Petkov  EXPECT_CALL(*profile, DeleteEntry(kOldId, _));
3359c6e9818cd1337ee06a218db83ee577ac977c7d9Darin Petkov  EXPECT_CALL(*profile, UpdateService(_));
3369c6e9818cd1337ee06a218db83ee577ac977c7d9Darin Petkov  service_->set_profile(profile);
337b8172ec75bbc9faac13a33e162ddedd53a97d1c8Peter Qiu  EXPECT_TRUE(service_->mutable_store()->SetAnyProperty(
33803e6719bae1e0903d94853b896673a033196bcf5Alex Vakulenko      kNameProperty, brillo::Any(kName), &error));
3399c6e9818cd1337ee06a218db83ee577ac977c7d9Darin Petkov  EXPECT_NE(service_->GetStorageIdentifier(), kOldId);
3409c6e9818cd1337ee06a218db83ee577ac977c7d9Darin Petkov  EXPECT_EQ(kName, service_->friendly_name());
3419c6e9818cd1337ee06a218db83ee577ac977c7d9Darin Petkov}
3429c6e9818cd1337ee06a218db83ee577ac977c7d9Darin Petkov
343cbfb34e699532f62eb5b381d0ea3a15d39e00b7cmukesh agrawalTEST_F(VPNServiceTest, PropertyChanges) {
344cbfb34e699532f62eb5b381d0ea3a15d39e00b7cmukesh agrawal  TestCommonPropertyChanges(service_, GetAdaptor());
345cbfb34e699532f62eb5b381d0ea3a15d39e00b7cmukesh agrawal  TestAutoConnectPropertyChange(service_, GetAdaptor());
346cbfb34e699532f62eb5b381d0ea3a15d39e00b7cmukesh agrawal
347cbfb34e699532f62eb5b381d0ea3a15d39e00b7cmukesh agrawal  const string kHost = "1.2.3.4";
348cbfb34e699532f62eb5b381d0ea3a15d39e00b7cmukesh agrawal  scoped_refptr<MockProfile> profile(
349cbfb34e699532f62eb5b381d0ea3a15d39e00b7cmukesh agrawal      new NiceMock<MockProfile>(&control_, &metrics_, &manager_));
350cbfb34e699532f62eb5b381d0ea3a15d39e00b7cmukesh agrawal  service_->set_profile(profile);
3517372878af066cc079ad88a7b004ca3f769952de2Ben Chan  driver_->args()->SetString(kProviderHostProperty, kHost);
352cbfb34e699532f62eb5b381d0ea3a15d39e00b7cmukesh agrawal  TestNamePropertyChange(service_, GetAdaptor());
353cbfb34e699532f62eb5b381d0ea3a15d39e00b7cmukesh agrawal}
354cbfb34e699532f62eb5b381d0ea3a15d39e00b7cmukesh agrawal
355bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal// Custom property setters should return false, and make no changes, if
356bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal// the new value is the same as the old value.
357bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawalTEST_F(VPNServiceTest, CustomSetterNoopChange) {
358bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal  TestCustomSetterNoopChange(service_, &manager_);
359bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal}
360bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal
36117ef7c010180936b40d8106c9061bc0099f95734Garret KellyTEST_F(VPNServiceTest, GetPhysicalTechnologyPropertyFailsIfNoCarrier) {
362fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo  scoped_refptr<Connection> null_connection;
363fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo
364fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo  EXPECT_CALL(*sockets_, Socket(_, _, _)).WillOnce(Return(-1));
365fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo  service_->SetConnection(connection_);
366fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo  EXPECT_EQ(connection_.get(), service_->connection().get());
367fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo
368fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo  // Simulate an error in the GetCarrierConnection() returning a NULL reference.
369fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo  EXPECT_CALL(*connection_, GetCarrierConnection())
370fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo      .WillOnce(Return(null_connection));
371fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo
372fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo  Error error;
37317ef7c010180936b40d8106c9061bc0099f95734Garret Kelly  EXPECT_EQ("", service_->GetPhysicalTechnologyProperty(&error));
374fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo  EXPECT_EQ(Error::kOperationFailed, error.type());
375fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo}
376fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo
37717ef7c010180936b40d8106c9061bc0099f95734Garret KellyTEST_F(VPNServiceTest, GetPhysicalTechnologyPropertyOverWifi) {
378fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo  scoped_refptr<NiceMock<MockConnection>> lower_connection_ =
379fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo      new NiceMock<MockConnection>(&device_info_);
380fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo
381fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo  EXPECT_CALL(*connection_, technology())
382fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo      .Times(0);
383fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo  EXPECT_CALL(*connection_, GetCarrierConnection())
384fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo      .WillOnce(Return(lower_connection_));
385fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo
386fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo  EXPECT_CALL(*sockets_, Socket(_, _, _)).WillOnce(Return(-1));
387fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo  service_->SetConnection(connection_);
388fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo  EXPECT_EQ(connection_.get(), service_->connection().get());
389fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo
390fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo  // Set the type of the lower connection to "wifi" and expect that type to be
39117ef7c010180936b40d8106c9061bc0099f95734Garret Kelly  // returned by GetPhysicalTechnologyProperty().
392fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo  EXPECT_CALL(*lower_connection_, technology())
393fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo      .WillOnce(Return(Technology::kWifi));
394fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo
395fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo  Error error;
39617ef7c010180936b40d8106c9061bc0099f95734Garret Kelly  EXPECT_EQ(kTypeWifi, service_->GetPhysicalTechnologyProperty(&error));
397fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo  EXPECT_TRUE(error.IsSuccess());
398fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo
399fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo  // Clear expectations now, so the Return(lower_connection_) action releases
400fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo  // the reference to |lower_connection_| allowing it to be destroyed now.
4010951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko  Mock::VerifyAndClearExpectations(connection_.get());
402fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo  // Destroying the |lower_connection_| at function exit will also call an extra
403fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo  // FlushAddresses on the |device_info_| object.
404fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo  EXPECT_CALL(device_info_, FlushAddresses(0));
405fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo}
406fddc09ac26ba77cabb59810f01b705fca2efd10bAlex Deymo
4077f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul StewartTEST_F(VPNServiceTest, GetTethering) {
4087f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart  scoped_refptr<Connection> null_connection;
4097f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart
4107f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart  EXPECT_CALL(*sockets_, Socket(_, _, _)).WillOnce(Return(-1));
4117f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart  service_->SetConnection(connection_);
4127f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart  EXPECT_EQ(connection_.get(), service_->connection().get());
4137f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart
4147f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart  // Simulate an error in the GetCarrierConnection() returning a NULL reference.
4157f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart  EXPECT_CALL(*connection_, GetCarrierConnection())
4167f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart      .WillOnce(Return(null_connection));
4177f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart
4187f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart  {
4197f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart    Error error;
4207f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart    EXPECT_EQ("", service_->GetTethering(&error));
4217f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart    EXPECT_EQ(Error::kOperationFailed, error.type());
4227f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart  }
4237f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart
4247f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart  scoped_refptr<NiceMock<MockConnection>> lower_connection_ =
4257f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart      new NiceMock<MockConnection>(&device_info_);
4267f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart
4277f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart  EXPECT_CALL(*connection_, tethering()).Times(0);
4287f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart  EXPECT_CALL(*connection_, GetCarrierConnection())
4297f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart      .WillRepeatedly(Return(lower_connection_));
4307f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart
4317f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart  const char kTethering[] = "moon unit";
4327f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart  EXPECT_CALL(*lower_connection_, tethering())
4337f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart      .WillOnce(ReturnRefOfCopy(string(kTethering)))
4347f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart      .WillOnce(ReturnRefOfCopy(string()));
4357f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart
4367f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart  {
4377f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart    Error error;
4387f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart    EXPECT_EQ(kTethering, service_->GetTethering(&error));
4397f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart    EXPECT_TRUE(error.IsSuccess());
4407f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart  }
4417f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart  {
4427f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart    Error error;
4437f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart    EXPECT_EQ("", service_->GetTethering(&error));
4447f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart    EXPECT_EQ(Error::kNotSupported, error.type());
4457f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart  }
4467f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart
4477f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart  // Clear expectations now, so the Return(lower_connection_) action releases
4487f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart  // the reference to |lower_connection_| allowing it to be destroyed now.
4490951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko  Mock::VerifyAndClearExpectations(connection_.get());
4507f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart  // Destroying the |lower_connection_| at function exit will also call an extra
4517f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart  // FlushAddresses on the |device_info_| object.
4527f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart  EXPECT_CALL(device_info_, FlushAddresses(0));
4537f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart}
4547f5d9c0847d08ff4cd1fc7c0c8ae4117421e75c8Paul Stewart
45533af05c849e0888b15222da38b55515784b821c7Darin Petkov}  // namespace shill
456