1# GTest Unit Tests 2 3[TOC] 4 5## GTest Unit Tests 6 7[GTest](https://github.com/google/googletest) is a Google developed open source 8unit testing framework for C++ and C code. As the majority of GD code is writeen 9in C++, GTest provide the first layer of defence against bugs from the 10implementation level. Used in combination with 11[GMock](https://github.com/google/googlemock) developers can easily isolate 12classes and functions from their code to conduct unit testing. 13 14* [GTest Primer](https://github.com/google/googletest/blob/master/googletest/docs/primer.md) 15* [GMock for Dummies](https://github.com/google/googletest/blob/master/googlemock/docs/for_dummies.md) 16 17### Test Binary 18 19All Gd unit test classes are compiled into a single binary 20[bluetooth_test_gd](https://android.googlesource.com/platform/packages/modules/Bluetooth/system/+/master/gd/Android.bp). 21 22### Test Sources Definitions 23 24* Tests should live in the same directory as the source code 25* Mocks should live in the same directory as the source header so that it can 26 be shared among multiple tests 27* Tests should not modify global states that would affect other tests, so that 28 all tests could be executed using the same binary 29* Each module can define a filegroup() that includes all test sources. This 30 filegroup is then included in a single cc_test() target that produce a 31 single test binary 32 [bluetooth_test_gd](https://android.googlesource.com/platform/packages/modules/Bluetooth/system/+/master/gd/Android.bp). 33 A single test binary simplifies the configuration effort needed for 34 compilation, presubmit and postsubmit execution, and so on. 35 36### How to run tests 37 38#### Use `atest` 39 40[ATest](https://source.android.com/compatibility/tests/development/atest) is an 41Android tool that allows a developers to run multiple modes of tests from the 42same `atest` command, including Java Instrumentation Tests, C/C++ GTests, 43CTS/GTS tests, etc. To use `atest` with GD, simplying sync your Android tree, 44run `source build/envsetup.sh` and `lunch` to a desired target. Then 45 46* To run tests on device, the following command will automatically build, 47 push, and execute tests on a connected Android device 48 49 ```shell 50 atest bluetooth_test_gd 51 ``` 52 53* To run tests on host, the following command will automatically build and run 54 tests on your host machine 55 56 ```shell 57 atest --host bluetooth_test_gd 58 ``` 59 60* To run a single test case, use `<test_binary>:<test_class>#<test_method>` 61 format, such as 62 63 ```shell 64 atest --host bluetooth_test_gd:AclManagerTest#invoke_registered_callback_connection_complete_success 65 ``` 66 67 See `atest --help` for more documentation on how to use atest to run various 68 tests 69 70#### Run it yourself (Not receommended unless really needed) 71 72Sometimes, you may want to execute the test binary directly because you want to 73attach a debugger or you want to avoid the test boostrap delay in `atest`. You 74can do it with the following steps 75 761. Sync Android tree, run `build/envsetup` and `lunch` desired target, `cd` 77 into Android checkout root directory 78 791. Make bluetooth_test_gd binary 80 81 ```shell 82 m -j40 bluetooth_test_gd 83 ``` 84 851. Run the test on host {value=3} 86 87 ```shell 88 $ANDROID_HOST_OUT/nativetest64/bluetooth_test_gd/bluetooth_test_gd 89 ``` 90 911. Run the test on device {value=4} 92 93 Push test to device 94 95 ```shell 96 adb push $ANDROID_PRODUCT_OUT/testcases/bluetooth_test_gd/arm64/bluetooth_test_gd /data/nativetest64/bluetooth_test_gd 97 ``` 98 99 Run test using ADB 100 101 ```shell 102 adb shell /data/nativetest64/bluetooth_test_gd 103 ``` 104 1051. Run test with filter (Works the same way for device based test) {value=5} 106 107 ```shell 108 $ANDROID_HOST_OUT/nativetest64/bluetooth_test_gd/bluetooth_test_gd --gtest_filter=AclManagerTest.invoke_registered_callback_connection_complete_success* 109 ``` 110 111 Note: the '*' wildcard is very important 112 1131. Get command line help {value=6} 114 115 ```shell 116 $ANDROID_HOST_OUT/nativetest64/bluetooth_test_gd/bluetooth_test_gd --help 117 ``` 118 119### Example: L2capClassicFixedChannelImplTest 120 121Note: All paths are relative to 122[packages/modules/Bluetooth/system/gd](https://android.googlesource.com/platform/packages/modules/Bluetooth/system/+/master/gd) 123 124#### Source code: 125 126* [l2cap/classic/internal/fixed_channel_impl.h](https://android.googlesource.com/platform/packages/modules/Bluetooth/system/+/master/gd/l2cap/classic/internal/fixed_channel_impl.h) 127 128```c++ 129#pragma once 130 131#include "common/bidi_queue.h" 132#include "l2cap/cid.h" 133#include "l2cap/classic/fixed_channel.h" 134#include "l2cap/internal/channel_impl.h" 135#include "l2cap/l2cap_packets.h" 136#include "os/handler.h" 137 138namespace bluetooth { 139namespace l2cap { 140namespace classic { 141namespace internal { 142 143class Link; 144 145class FixedChannelImpl : public l2cap::internal::ChannelImpl { 146 public: 147 FixedChannelImpl(Cid cid, Link* link, os::Handler* l2cap_handler); 148 virtual ~FixedChannelImpl() = default; 149 hci::Address GetDevice() const; 150 virtual void RegisterOnCloseCallback(os::Handler* user_handler, FixedChannel::OnCloseCallback on_close_callback); 151 virtual void Acquire(); 152 virtual void Release(); 153 virtual bool IsAcquired() const; 154 virtual void OnClosed(hci::ErrorCode status); 155 virtual std::string ToString(); 156 common::BidiQueueEnd<packet::BasePacketBuilder, packet::PacketView<packet::kLittleEndian>>* GetQueueUpEnd(); 157 common::BidiQueueEnd<packet::PacketView<packet::kLittleEndian>, packet::BasePacketBuilder>* GetQueueDownEnd(); 158 Cid GetCid() const; 159 Cid GetRemoteCid() const; 160 private: 161 // private fields omitted in doc ... 162}; 163 164} // namespace internal 165} // namespace classic 166} // namespace l2cap 167} // namespace bluetooth 168``` 169 170* [packages/modules/Bluetooth/system/gd/l2cap/classic/internal/fixed_channel_impl.cc](https://android.googlesource.com/platform/packages/modules/Bluetooth/system/+/master/gd/l2cap/classic/internal/fixed_channel_impl.cc) 171 172#### Mocks for dependencies' unit tests 173 174* [l2cap/classic/internal/fixed_channel_impl_mock.h](https://android.googlesource.com/platform/packages/modules/Bluetooth/system/+/master/gd/l2cap/classic/internal/fixed_channel_impl_mock.h) 175 176```c++ 177#pragma once 178 179#include "l2cap/classic/internal/fixed_channel_impl.h" 180 181#include <gmock/gmock.h> 182 183// Unit test interfaces 184namespace bluetooth { 185namespace l2cap { 186namespace classic { 187namespace internal { 188namespace testing { 189 190class MockFixedChannelImpl : public FixedChannelImpl { 191 public: 192 MockFixedChannelImpl(Cid cid, Link* link, os::Handler* l2cap_handler) : FixedChannelImpl(cid, link, l2cap_handler) {} 193 MOCK_METHOD(void, RegisterOnCloseCallback, 194 (os::Handler * user_handler, FixedChannel::OnCloseCallback on_close_callback), (override)); 195 MOCK_METHOD(void, Acquire, (), (override)); 196 MOCK_METHOD(void, Release, (), (override)); 197 MOCK_METHOD(bool, IsAcquired, (), (override, const)); 198 MOCK_METHOD(void, OnClosed, (hci::ErrorCode status), (override)); 199}; 200 201} // namespace testing 202} // namespace internal 203} // namespace classic 204} // namespace l2cap 205} // namespace bluetooth 206``` 207 208#### Tests 209 210* [l2cap/classic/internal/fixed_channel_impl_test.cc](https://android.googlesource.com/platform/packages/modules/Bluetooth/system/+/master/gd/l2cap/classic/internal/fixed_channel_impl_test.cc) 211 212```c++ 213#include "l2cap/classic/internal/fixed_channel_impl.h" 214 215#include "common/testing/bind_test_util.h" 216#include "l2cap/cid.h" 217#include "l2cap/classic/internal/link_mock.h" 218#include "l2cap/internal/parameter_provider_mock.h" 219#include "os/handler.h" 220 221#include <gmock/gmock.h> 222#include <gtest/gtest.h> 223 224namespace bluetooth { 225namespace l2cap { 226namespace classic { 227namespace internal { 228 229using l2cap::internal::testing::MockParameterProvider; 230using ::testing::_; 231using testing::MockLink; 232using ::testing::Return; 233 234class L2capClassicFixedChannelImplTest : public ::testing::Test { 235 public: 236 static void SyncHandler(os::Handler* handler) { 237 std::promise<void> promise; 238 auto future = promise.get_future(); 239 handler->Post(common::BindOnce(&std::promise<void>::set_value, common::Unretained(&promise))); 240 future.wait_for(std::chrono::seconds(1)); 241 } 242 243 protected: 244 void SetUp() override { 245 thread_ = new os::Thread("test_thread", os::Thread::Priority::NORMAL); 246 l2cap_handler_ = new os::Handler(thread_); 247 } 248 249 void TearDown() override { 250 l2cap_handler_->Clear(); 251 delete l2cap_handler_; 252 delete thread_; 253 } 254 255 os::Thread* thread_ = nullptr; 256 os::Handler* l2cap_handler_ = nullptr; 257}; 258 259TEST_F(L2capClassicFixedChannelImplTest, get_device) { 260 MockParameterProvider mock_parameter_provider; 261 EXPECT_CALL(mock_parameter_provider, GetClassicLinkIdleDisconnectTimeout()) 262 .WillRepeatedly(Return(std::chrono::seconds(5))); 263 testing::MockClassicAclConnection* mock_acl_connection = new testing::MockClassicAclConnection(); 264 EXPECT_CALL(*mock_acl_connection, GetAddress()).Times(1); 265 EXPECT_CALL(*mock_acl_connection, RegisterCallbacks(_, l2cap_handler_)).Times(1); 266 EXPECT_CALL(*mock_acl_connection, UnregisterCallbacks(_)).Times(1); 267 MockLink mock_classic_link(l2cap_handler_, &mock_parameter_provider, 268 std::unique_ptr<testing::MockClassicAclConnection>(mock_acl_connection)); 269 hci::AddressWithType device{hci::Address{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}}, 270 hci::AddressType::PUBLIC_IDENTITY_ADDRESS}; 271 EXPECT_CALL(mock_classic_link, GetDevice()).WillRepeatedly(Return(device)); 272 FixedChannelImpl fixed_channel_impl(kSmpBrCid, &mock_classic_link, l2cap_handler_); 273 EXPECT_EQ(device.GetAddress(), fixed_channel_impl.GetDevice()); 274} 275 276// Other test cases omitted in doc ... 277 278} // namespace internal 279} // namespace classic 280} // namespace l2cap 281} // namespace bluetooth 282``` 283