150a31545d2d20d92d161c51195b653eafd164025Arman Uguray// 25b790feeeb211c42bf78ca3ae9c26aa30e516765Jakub Pawlowski// Copyright 2015 Google, Inc. 350a31545d2d20d92d161c51195b653eafd164025Arman Uguray// 450a31545d2d20d92d161c51195b653eafd164025Arman Uguray// Licensed under the Apache License, Version 2.0 (the "License"); 550a31545d2d20d92d161c51195b653eafd164025Arman Uguray// you may not use this file except in compliance with the License. 650a31545d2d20d92d161c51195b653eafd164025Arman Uguray// You may obtain a copy of the License at: 750a31545d2d20d92d161c51195b653eafd164025Arman Uguray// 850a31545d2d20d92d161c51195b653eafd164025Arman Uguray// http://www.apache.org/licenses/LICENSE-2.0 950a31545d2d20d92d161c51195b653eafd164025Arman Uguray// 1050a31545d2d20d92d161c51195b653eafd164025Arman Uguray// Unless required by applicable law or agreed to in writing, software 1150a31545d2d20d92d161c51195b653eafd164025Arman Uguray// distributed under the License is distributed on an "AS IS" BASIS, 1250a31545d2d20d92d161c51195b653eafd164025Arman Uguray// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1350a31545d2d20d92d161c51195b653eafd164025Arman Uguray// See the License for the specific language governing permissions and 1450a31545d2d20d92d161c51195b653eafd164025Arman Uguray// limitations under the License. 1550a31545d2d20d92d161c51195b653eafd164025Arman Uguray// 1650a31545d2d20d92d161c51195b653eafd164025Arman Uguray 1750a31545d2d20d92d161c51195b653eafd164025Arman Uguray#include <base/macros.h> 1850a31545d2d20d92d161c51195b653eafd164025Arman Uguray#include <gmock/gmock.h> 1950a31545d2d20d92d161c51195b653eafd164025Arman Uguray#include <gtest/gtest.h> 2050a31545d2d20d92d161c51195b653eafd164025Arman Uguray 2150a31545d2d20d92d161c51195b653eafd164025Arman Uguray#include "service/gatt_client.h" 2250a31545d2d20d92d161c51195b653eafd164025Arman Uguray#include "service/hal/fake_bluetooth_gatt_interface.h" 2350a31545d2d20d92d161c51195b653eafd164025Arman Uguray 2450a31545d2d20d92d161c51195b653eafd164025Arman Ugurayusing ::testing::_; 2550a31545d2d20d92d161c51195b653eafd164025Arman Ugurayusing ::testing::Return; 2650a31545d2d20d92d161c51195b653eafd164025Arman Uguray 2750a31545d2d20d92d161c51195b653eafd164025Arman Uguraynamespace bluetooth { 2850a31545d2d20d92d161c51195b653eafd164025Arman Uguraynamespace { 2950a31545d2d20d92d161c51195b653eafd164025Arman Uguray 3050a31545d2d20d92d161c51195b653eafd164025Arman Ugurayclass MockGattHandler 3150a31545d2d20d92d161c51195b653eafd164025Arman Uguray : public hal::FakeBluetoothGattInterface::TestClientHandler { 3250a31545d2d20d92d161c51195b653eafd164025Arman Uguray public: 3350a31545d2d20d92d161c51195b653eafd164025Arman Uguray MockGattHandler() = default; 3450a31545d2d20d92d161c51195b653eafd164025Arman Uguray ~MockGattHandler() override = default; 3550a31545d2d20d92d161c51195b653eafd164025Arman Uguray 36819e2ecb84a22d6e03ec9ed67b3260c0dd7e8abaJakub Pawlowski MOCK_METHOD1(RegisterClient, bt_status_t(const bluetooth::Uuid&)); 3750a31545d2d20d92d161c51195b653eafd164025Arman Uguray MOCK_METHOD1(UnregisterClient, bt_status_t(int)); 383f6aa07299fd9db634274fd22821b349f18b5e0fArman Uguray MOCK_METHOD1(Scan, bt_status_t(bool)); 39a484a888196ddf8bcbf1ad3226d6451bc735a94bJakub Pawlowski MOCK_METHOD4(Connect, bt_status_t(int, const RawAddress&, bool, int)); 40a484a888196ddf8bcbf1ad3226d6451bc735a94bJakub Pawlowski MOCK_METHOD3(Disconnect, bt_status_t(int, const RawAddress&, int)); 4150a31545d2d20d92d161c51195b653eafd164025Arman Uguray 4250a31545d2d20d92d161c51195b653eafd164025Arman Uguray private: 4350a31545d2d20d92d161c51195b653eafd164025Arman Uguray DISALLOW_COPY_AND_ASSIGN(MockGattHandler); 4450a31545d2d20d92d161c51195b653eafd164025Arman Uguray}; 4550a31545d2d20d92d161c51195b653eafd164025Arman Uguray 4650a31545d2d20d92d161c51195b653eafd164025Arman Ugurayclass GattClientTest : public ::testing::Test { 4750a31545d2d20d92d161c51195b653eafd164025Arman Uguray public: 4850a31545d2d20d92d161c51195b653eafd164025Arman Uguray GattClientTest() = default; 4950a31545d2d20d92d161c51195b653eafd164025Arman Uguray ~GattClientTest() override = default; 5050a31545d2d20d92d161c51195b653eafd164025Arman Uguray 5150a31545d2d20d92d161c51195b653eafd164025Arman Uguray void SetUp() override { 5250a31545d2d20d92d161c51195b653eafd164025Arman Uguray // Only set |mock_handler_| if a previous test case hasn't set it. 53911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (!mock_handler_) mock_handler_.reset(new MockGattHandler()); 5450a31545d2d20d92d161c51195b653eafd164025Arman Uguray 5550a31545d2d20d92d161c51195b653eafd164025Arman Uguray fake_hal_gatt_iface_ = new hal::FakeBluetoothGattInterface( 56911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson nullptr, nullptr, 5750a31545d2d20d92d161c51195b653eafd164025Arman Uguray std::static_pointer_cast< 5850a31545d2d20d92d161c51195b653eafd164025Arman Uguray hal::FakeBluetoothGattInterface::TestClientHandler>(mock_handler_), 5950a31545d2d20d92d161c51195b653eafd164025Arman Uguray nullptr); 6050a31545d2d20d92d161c51195b653eafd164025Arman Uguray hal::BluetoothGattInterface::InitializeForTesting(fake_hal_gatt_iface_); 6150a31545d2d20d92d161c51195b653eafd164025Arman Uguray 6250a31545d2d20d92d161c51195b653eafd164025Arman Uguray factory_.reset(new GattClientFactory()); 6350a31545d2d20d92d161c51195b653eafd164025Arman Uguray } 6450a31545d2d20d92d161c51195b653eafd164025Arman Uguray 6550a31545d2d20d92d161c51195b653eafd164025Arman Uguray void TearDown() override { 6650a31545d2d20d92d161c51195b653eafd164025Arman Uguray factory_.reset(); 6750a31545d2d20d92d161c51195b653eafd164025Arman Uguray hal::BluetoothGattInterface::CleanUp(); 6850a31545d2d20d92d161c51195b653eafd164025Arman Uguray } 6950a31545d2d20d92d161c51195b653eafd164025Arman Uguray 7050a31545d2d20d92d161c51195b653eafd164025Arman Uguray protected: 7150a31545d2d20d92d161c51195b653eafd164025Arman Uguray hal::FakeBluetoothGattInterface* fake_hal_gatt_iface_; 7250a31545d2d20d92d161c51195b653eafd164025Arman Uguray std::shared_ptr<MockGattHandler> mock_handler_; 7350a31545d2d20d92d161c51195b653eafd164025Arman Uguray std::unique_ptr<GattClientFactory> factory_; 7450a31545d2d20d92d161c51195b653eafd164025Arman Uguray 7550a31545d2d20d92d161c51195b653eafd164025Arman Uguray private: 7650a31545d2d20d92d161c51195b653eafd164025Arman Uguray DISALLOW_COPY_AND_ASSIGN(GattClientTest); 7750a31545d2d20d92d161c51195b653eafd164025Arman Uguray}; 7850a31545d2d20d92d161c51195b653eafd164025Arman Uguray 79bb18c41ffa0370d4eb0c4a15904b114355606466Arman UgurayTEST_F(GattClientTest, RegisterInstance) { 8050a31545d2d20d92d161c51195b653eafd164025Arman Uguray EXPECT_CALL(*mock_handler_, RegisterClient(_)) 8150a31545d2d20d92d161c51195b653eafd164025Arman Uguray .Times(2) 8250a31545d2d20d92d161c51195b653eafd164025Arman Uguray .WillOnce(Return(BT_STATUS_FAIL)) 8350a31545d2d20d92d161c51195b653eafd164025Arman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 8450a31545d2d20d92d161c51195b653eafd164025Arman Uguray 8550a31545d2d20d92d161c51195b653eafd164025Arman Uguray // These will be asynchronously populated with a result when the callback 8650a31545d2d20d92d161c51195b653eafd164025Arman Uguray // executes. 8750a31545d2d20d92d161c51195b653eafd164025Arman Uguray BLEStatus status = BLE_STATUS_SUCCESS; 88819e2ecb84a22d6e03ec9ed67b3260c0dd7e8abaJakub Pawlowski Uuid cb_uuid; 8950a31545d2d20d92d161c51195b653eafd164025Arman Uguray std::unique_ptr<GattClient> client; 9050a31545d2d20d92d161c51195b653eafd164025Arman Uguray int callback_count = 0; 9150a31545d2d20d92d161c51195b653eafd164025Arman Uguray 92819e2ecb84a22d6e03ec9ed67b3260c0dd7e8abaJakub Pawlowski auto callback = [&](BLEStatus in_status, const Uuid& uuid, 93bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray std::unique_ptr<BluetoothInstance> in_client) { 94911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson status = in_status; 95911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson cb_uuid = uuid; 96911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson client = std::unique_ptr<GattClient>( 97911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson static_cast<GattClient*>(in_client.release())); 98911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson callback_count++; 99911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson }; 10050a31545d2d20d92d161c51195b653eafd164025Arman Uguray 101819e2ecb84a22d6e03ec9ed67b3260c0dd7e8abaJakub Pawlowski Uuid uuid0 = Uuid::GetRandom(); 10250a31545d2d20d92d161c51195b653eafd164025Arman Uguray 10350a31545d2d20d92d161c51195b653eafd164025Arman Uguray // HAL returns failure. 104bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray EXPECT_FALSE(factory_->RegisterInstance(uuid0, callback)); 10550a31545d2d20d92d161c51195b653eafd164025Arman Uguray EXPECT_EQ(0, callback_count); 10650a31545d2d20d92d161c51195b653eafd164025Arman Uguray 10750a31545d2d20d92d161c51195b653eafd164025Arman Uguray // HAL returns success. 108bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray EXPECT_TRUE(factory_->RegisterInstance(uuid0, callback)); 10950a31545d2d20d92d161c51195b653eafd164025Arman Uguray EXPECT_EQ(0, callback_count); 11050a31545d2d20d92d161c51195b653eafd164025Arman Uguray 111819e2ecb84a22d6e03ec9ed67b3260c0dd7e8abaJakub Pawlowski // Calling twice with the same Uuid should fail with no additional call into 11250a31545d2d20d92d161c51195b653eafd164025Arman Uguray // the stack. 113bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray EXPECT_FALSE(factory_->RegisterInstance(uuid0, callback)); 11450a31545d2d20d92d161c51195b653eafd164025Arman Uguray 11550a31545d2d20d92d161c51195b653eafd164025Arman Uguray testing::Mock::VerifyAndClearExpectations(mock_handler_.get()); 11650a31545d2d20d92d161c51195b653eafd164025Arman Uguray 117819e2ecb84a22d6e03ec9ed67b3260c0dd7e8abaJakub Pawlowski // Call with a different Uuid while one is pending. 118819e2ecb84a22d6e03ec9ed67b3260c0dd7e8abaJakub Pawlowski Uuid uuid1 = Uuid::GetRandom(); 11950a31545d2d20d92d161c51195b653eafd164025Arman Uguray EXPECT_CALL(*mock_handler_, RegisterClient(_)) 12050a31545d2d20d92d161c51195b653eafd164025Arman Uguray .Times(1) 12150a31545d2d20d92d161c51195b653eafd164025Arman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 122bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray EXPECT_TRUE(factory_->RegisterInstance(uuid1, callback)); 12350a31545d2d20d92d161c51195b653eafd164025Arman Uguray 124819e2ecb84a22d6e03ec9ed67b3260c0dd7e8abaJakub Pawlowski // Trigger callback with an unknown Uuid. This should get ignored. 125819e2ecb84a22d6e03ec9ed67b3260c0dd7e8abaJakub Pawlowski Uuid uuid2 = Uuid::GetRandom(); 126819e2ecb84a22d6e03ec9ed67b3260c0dd7e8abaJakub Pawlowski fake_hal_gatt_iface_->NotifyRegisterClientCallback(0, 0, uuid2); 12750a31545d2d20d92d161c51195b653eafd164025Arman Uguray EXPECT_EQ(0, callback_count); 12850a31545d2d20d92d161c51195b653eafd164025Arman Uguray 12950a31545d2d20d92d161c51195b653eafd164025Arman Uguray // |uuid0| succeeds. 13050a31545d2d20d92d161c51195b653eafd164025Arman Uguray int client_id0 = 2; // Pick something that's not 0. 131911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson fake_hal_gatt_iface_->NotifyRegisterClientCallback(BT_STATUS_SUCCESS, 132819e2ecb84a22d6e03ec9ed67b3260c0dd7e8abaJakub Pawlowski client_id0, uuid0); 13350a31545d2d20d92d161c51195b653eafd164025Arman Uguray 13450a31545d2d20d92d161c51195b653eafd164025Arman Uguray EXPECT_EQ(1, callback_count); 13550a31545d2d20d92d161c51195b653eafd164025Arman Uguray ASSERT_TRUE(client.get() != nullptr); // Assert to terminate in case of error 13650a31545d2d20d92d161c51195b653eafd164025Arman Uguray EXPECT_EQ(BLE_STATUS_SUCCESS, status); 137bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray EXPECT_EQ(client_id0, client->GetInstanceId()); 13850a31545d2d20d92d161c51195b653eafd164025Arman Uguray EXPECT_EQ(uuid0, client->GetAppIdentifier()); 13950a31545d2d20d92d161c51195b653eafd164025Arman Uguray EXPECT_EQ(uuid0, cb_uuid); 14050a31545d2d20d92d161c51195b653eafd164025Arman Uguray 14150a31545d2d20d92d161c51195b653eafd164025Arman Uguray // The client should unregister itself when deleted. 14250a31545d2d20d92d161c51195b653eafd164025Arman Uguray EXPECT_CALL(*mock_handler_, UnregisterClient(client_id0)) 14350a31545d2d20d92d161c51195b653eafd164025Arman Uguray .Times(1) 14450a31545d2d20d92d161c51195b653eafd164025Arman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 14550a31545d2d20d92d161c51195b653eafd164025Arman Uguray client.reset(); 14650a31545d2d20d92d161c51195b653eafd164025Arman Uguray testing::Mock::VerifyAndClearExpectations(mock_handler_.get()); 14750a31545d2d20d92d161c51195b653eafd164025Arman Uguray 14850a31545d2d20d92d161c51195b653eafd164025Arman Uguray // |uuid1| fails. 14950a31545d2d20d92d161c51195b653eafd164025Arman Uguray int client_id1 = 3; 150911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson fake_hal_gatt_iface_->NotifyRegisterClientCallback(BT_STATUS_FAIL, client_id1, 151819e2ecb84a22d6e03ec9ed67b3260c0dd7e8abaJakub Pawlowski uuid1); 15250a31545d2d20d92d161c51195b653eafd164025Arman Uguray 15350a31545d2d20d92d161c51195b653eafd164025Arman Uguray EXPECT_EQ(2, callback_count); 15450a31545d2d20d92d161c51195b653eafd164025Arman Uguray ASSERT_TRUE(client.get() == nullptr); // Assert to terminate in case of error 15550a31545d2d20d92d161c51195b653eafd164025Arman Uguray EXPECT_EQ(BLE_STATUS_FAILURE, status); 15650a31545d2d20d92d161c51195b653eafd164025Arman Uguray EXPECT_EQ(uuid1, cb_uuid); 15750a31545d2d20d92d161c51195b653eafd164025Arman Uguray} 15850a31545d2d20d92d161c51195b653eafd164025Arman Uguray 15950a31545d2d20d92d161c51195b653eafd164025Arman Uguray} // namespace 16050a31545d2d20d92d161c51195b653eafd164025Arman Uguray} // namespace bluetooth 161