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