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#include "os/log.h" 138 139namespace bluetooth { 140namespace l2cap { 141namespace classic { 142namespace internal { 143 144class Link; 145 146class FixedChannelImpl : public l2cap::internal::ChannelImpl { 147 public: 148 FixedChannelImpl(Cid cid, Link* link, os::Handler* l2cap_handler); 149 virtual ~FixedChannelImpl() = default; 150 hci::Address GetDevice() const; 151 virtual void RegisterOnCloseCallback(os::Handler* user_handler, FixedChannel::OnCloseCallback on_close_callback); 152 virtual void Acquire(); 153 virtual void Release(); 154 virtual bool IsAcquired() const; 155 virtual void OnClosed(hci::ErrorCode status); 156 virtual std::string ToString(); 157 common::BidiQueueEnd<packet::BasePacketBuilder, packet::PacketView<packet::kLittleEndian>>* GetQueueUpEnd(); 158 common::BidiQueueEnd<packet::PacketView<packet::kLittleEndian>, packet::BasePacketBuilder>* GetQueueDownEnd(); 159 Cid GetCid() const; 160 Cid GetRemoteCid() const; 161 private: 162 // private fields omitted in doc ... 163}; 164 165} // namespace internal 166} // namespace classic 167} // namespace l2cap 168} // namespace bluetooth 169``` 170 171* [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) 172 173#### Mocks for dependencies' unit tests 174 175* [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) 176 177```c++ 178#pragma once 179 180#include "l2cap/classic/internal/fixed_channel_impl.h" 181 182#include <gmock/gmock.h> 183 184// Unit test interfaces 185namespace bluetooth { 186namespace l2cap { 187namespace classic { 188namespace internal { 189namespace testing { 190 191class MockFixedChannelImpl : public FixedChannelImpl { 192 public: 193 MockFixedChannelImpl(Cid cid, Link* link, os::Handler* l2cap_handler) : FixedChannelImpl(cid, link, l2cap_handler) {} 194 MOCK_METHOD(void, RegisterOnCloseCallback, 195 (os::Handler * user_handler, FixedChannel::OnCloseCallback on_close_callback), (override)); 196 MOCK_METHOD(void, Acquire, (), (override)); 197 MOCK_METHOD(void, Release, (), (override)); 198 MOCK_METHOD(bool, IsAcquired, (), (override, const)); 199 MOCK_METHOD(void, OnClosed, (hci::ErrorCode status), (override)); 200}; 201 202} // namespace testing 203} // namespace internal 204} // namespace classic 205} // namespace l2cap 206} // namespace bluetooth 207``` 208 209#### Tests 210 211* [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) 212 213```c++ 214#include "l2cap/classic/internal/fixed_channel_impl.h" 215 216#include "common/testing/bind_test_util.h" 217#include "l2cap/cid.h" 218#include "l2cap/classic/internal/link_mock.h" 219#include "l2cap/internal/parameter_provider_mock.h" 220#include "os/handler.h" 221 222#include <gmock/gmock.h> 223#include <gtest/gtest.h> 224 225namespace bluetooth { 226namespace l2cap { 227namespace classic { 228namespace internal { 229 230using l2cap::internal::testing::MockParameterProvider; 231using ::testing::_; 232using testing::MockLink; 233using ::testing::Return; 234 235class L2capClassicFixedChannelImplTest : public ::testing::Test { 236 public: 237 static void SyncHandler(os::Handler* handler) { 238 std::promise<void> promise; 239 auto future = promise.get_future(); 240 handler->Post(common::BindOnce(&std::promise<void>::set_value, common::Unretained(&promise))); 241 future.wait_for(std::chrono::seconds(1)); 242 } 243 244 protected: 245 void SetUp() override { 246 thread_ = new os::Thread("test_thread", os::Thread::Priority::NORMAL); 247 l2cap_handler_ = new os::Handler(thread_); 248 } 249 250 void TearDown() override { 251 l2cap_handler_->Clear(); 252 delete l2cap_handler_; 253 delete thread_; 254 } 255 256 os::Thread* thread_ = nullptr; 257 os::Handler* l2cap_handler_ = nullptr; 258}; 259 260TEST_F(L2capClassicFixedChannelImplTest, get_device) { 261 MockParameterProvider mock_parameter_provider; 262 EXPECT_CALL(mock_parameter_provider, GetClassicLinkIdleDisconnectTimeout()) 263 .WillRepeatedly(Return(std::chrono::seconds(5))); 264 testing::MockClassicAclConnection* mock_acl_connection = new testing::MockClassicAclConnection(); 265 EXPECT_CALL(*mock_acl_connection, GetAddress()).Times(1); 266 EXPECT_CALL(*mock_acl_connection, RegisterCallbacks(_, l2cap_handler_)).Times(1); 267 EXPECT_CALL(*mock_acl_connection, UnregisterCallbacks(_)).Times(1); 268 MockLink mock_classic_link(l2cap_handler_, &mock_parameter_provider, 269 std::unique_ptr<testing::MockClassicAclConnection>(mock_acl_connection)); 270 hci::AddressWithType device{hci::Address{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}}, 271 hci::AddressType::PUBLIC_IDENTITY_ADDRESS}; 272 EXPECT_CALL(mock_classic_link, GetDevice()).WillRepeatedly(Return(device)); 273 FixedChannelImpl fixed_channel_impl(kSmpBrCid, &mock_classic_link, l2cap_handler_); 274 EXPECT_EQ(device.GetAddress(), fixed_channel_impl.GetDevice()); 275} 276 277// Other test cases omitted in doc ... 278 279} // namespace internal 280} // namespace classic 281} // namespace l2cap 282} // namespace bluetooth 283``` 284