1 /*
2 * Copyright 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "module.h"
18
19 #include <unistd.h>
20
21 #include <functional>
22 #include <sstream>
23 #include <string>
24
25 #include "dumpsys_data_generated.h"
26 #include "gtest/gtest.h"
27 #include "module_dumper.h"
28 #include "module_unittest_generated.h"
29 #include "os/handler.h"
30 #include "os/thread.h"
31
32 using ::bluetooth::os::Thread;
33
34 namespace bluetooth {
35 namespace {
36
37 class ModuleTest : public ::testing::Test {
38 protected:
SetUp()39 void SetUp() override {
40 thread_ = new Thread("test_thread", Thread::Priority::NORMAL);
41 registry_ = new ModuleRegistry();
42 }
43
TearDown()44 void TearDown() override {
45 delete registry_;
46 delete thread_;
47 }
48
49 ModuleRegistry* registry_;
50 Thread* thread_;
51 };
52
53 os::Handler* test_module_no_dependency_handler = nullptr;
54
55 class TestModuleNoDependency : public Module {
56 public:
57 static const ModuleFactory Factory;
58
59 protected:
ListDependencies(ModuleList *) const60 void ListDependencies(ModuleList* /* list */) const {}
61
Start()62 void Start() override {
63 // A module is not considered started until Start() finishes
64 EXPECT_FALSE(GetModuleRegistry()->IsStarted<TestModuleNoDependency>());
65 test_module_no_dependency_handler = GetHandler();
66 }
67
Stop()68 void Stop() override {
69 // A module is not considered stopped until after Stop() finishes
70 EXPECT_TRUE(GetModuleRegistry()->IsStarted<TestModuleNoDependency>());
71 }
72
ToString() const73 std::string ToString() const override {
74 return std::string("TestModuleNoDependency");
75 }
76 };
77
__anon2d4c33810202() 78 const ModuleFactory TestModuleNoDependency::Factory = ModuleFactory([]() {
79 return new TestModuleNoDependency();
80 });
81
82 os::Handler* test_module_one_dependency_handler = nullptr;
83
84 class TestModuleOneDependency : public Module {
85 public:
86 static const ModuleFactory Factory;
87
88 protected:
ListDependencies(ModuleList * list) const89 void ListDependencies(ModuleList* list) const {
90 list->add<TestModuleNoDependency>();
91 }
92
Start()93 void Start() override {
94 EXPECT_TRUE(GetModuleRegistry()->IsStarted<TestModuleNoDependency>());
95
96 // A module is not considered started until Start() finishes
97 EXPECT_FALSE(GetModuleRegistry()->IsStarted<TestModuleOneDependency>());
98 test_module_one_dependency_handler = GetHandler();
99 }
100
Stop()101 void Stop() override {
102 EXPECT_TRUE(GetModuleRegistry()->IsStarted<TestModuleNoDependency>());
103
104 // A module is not considered stopped until after Stop() finishes
105 EXPECT_TRUE(GetModuleRegistry()->IsStarted<TestModuleOneDependency>());
106 }
107
ToString() const108 std::string ToString() const override {
109 return std::string("TestModuleOneDependency");
110 }
111 };
112
__anon2d4c33810302() 113 const ModuleFactory TestModuleOneDependency::Factory = ModuleFactory([]() {
114 return new TestModuleOneDependency();
115 });
116
117
118 class TestModuleNoDependencyTwo : public Module {
119 public:
120 static const ModuleFactory Factory;
121
122 protected:
ListDependencies(ModuleList *) const123 void ListDependencies(ModuleList* /* list */) const {}
124
Start()125 void Start() override {
126 // A module is not considered started until Start() finishes
127 EXPECT_FALSE(GetModuleRegistry()->IsStarted<TestModuleNoDependencyTwo>());
128 }
129
Stop()130 void Stop() override {
131 // A module is not considered stopped until after Stop() finishes
132 EXPECT_TRUE(GetModuleRegistry()->IsStarted<TestModuleNoDependencyTwo>());
133 }
134
ToString() const135 std::string ToString() const override {
136 return std::string("TestModuleNoDependencyTwo");
137 }
138 };
139
__anon2d4c33810402() 140 const ModuleFactory TestModuleNoDependencyTwo::Factory = ModuleFactory([]() {
141 return new TestModuleNoDependencyTwo();
142 });
143
144 class TestModuleTwoDependencies : public Module {
145 public:
146 static const ModuleFactory Factory;
147
148 protected:
ListDependencies(ModuleList * list) const149 void ListDependencies(ModuleList* list) const {
150 list->add<TestModuleOneDependency>();
151 list->add<TestModuleNoDependencyTwo>();
152 }
153
Start()154 void Start() override {
155 EXPECT_TRUE(GetModuleRegistry()->IsStarted<TestModuleOneDependency>());
156 EXPECT_TRUE(GetModuleRegistry()->IsStarted<TestModuleNoDependencyTwo>());
157
158 // A module is not considered started until Start() finishes
159 EXPECT_FALSE(GetModuleRegistry()->IsStarted<TestModuleTwoDependencies>());
160 }
161
Stop()162 void Stop() override {
163 EXPECT_TRUE(GetModuleRegistry()->IsStarted<TestModuleOneDependency>());
164 EXPECT_TRUE(GetModuleRegistry()->IsStarted<TestModuleNoDependencyTwo>());
165
166 // A module is not considered stopped until after Stop() finishes
167 EXPECT_TRUE(GetModuleRegistry()->IsStarted<TestModuleTwoDependencies>());
168 }
169
ToString() const170 std::string ToString() const override {
171 return std::string("TestModuleTwoDependencies");
172 }
173 };
174
__anon2d4c33810502() 175 const ModuleFactory TestModuleTwoDependencies::Factory = ModuleFactory([]() {
176 return new TestModuleTwoDependencies();
177 });
178
179 // To generate module unittest flatbuffer headers:
180 // $ flatc --cpp module_unittest.fbs
181 class TestModuleDumpState : public Module {
182 public:
183 static const ModuleFactory Factory;
184
185 std::string test_string_{"Initial Test String"};
186
187 protected:
ListDependencies(ModuleList * list) const188 void ListDependencies(ModuleList* list) const {
189 list->add<TestModuleNoDependency>();
190 }
191
Start()192 void Start() override {
193 EXPECT_TRUE(GetModuleRegistry()->IsStarted<TestModuleNoDependency>());
194
195 // A module is not considered started until Start() finishes
196 EXPECT_FALSE(GetModuleRegistry()->IsStarted<TestModuleDumpState>());
197 test_module_one_dependency_handler = GetHandler();
198 }
199
Stop()200 void Stop() override {
201 EXPECT_TRUE(GetModuleRegistry()->IsStarted<TestModuleNoDependency>());
202
203 // A module is not considered stopped until after Stop() finishes
204 EXPECT_TRUE(GetModuleRegistry()->IsStarted<TestModuleDumpState>());
205 }
206
ToString() const207 std::string ToString() const override {
208 return std::string("TestModuleDumpState");
209 }
210
GetDumpsysData(flatbuffers::FlatBufferBuilder * fb_builder) const211 DumpsysDataFinisher GetDumpsysData(flatbuffers::FlatBufferBuilder* fb_builder) const override {
212 auto string = fb_builder->CreateString(test_string_.c_str());
213
214 auto builder = ModuleUnitTestDataBuilder(*fb_builder);
215 builder.add_title(string);
216 auto table = builder.Finish();
217
218 return [table](DumpsysDataBuilder* builder) { builder->add_module_unittest_data(table); };
219 }
220 };
221
__anon2d4c33810702() 222 const ModuleFactory TestModuleDumpState::Factory = ModuleFactory([]() { return new TestModuleDumpState(); });
223
TEST_F(ModuleTest,no_dependency)224 TEST_F(ModuleTest, no_dependency) {
225 ModuleList list;
226 list.add<TestModuleNoDependency>();
227 registry_->Start(&list, thread_);
228
229 EXPECT_TRUE(registry_->IsStarted<TestModuleNoDependency>());
230 EXPECT_FALSE(registry_->IsStarted<TestModuleOneDependency>());
231 EXPECT_FALSE(registry_->IsStarted<TestModuleNoDependencyTwo>());
232 EXPECT_FALSE(registry_->IsStarted<TestModuleTwoDependencies>());
233
234 registry_->StopAll();
235
236 EXPECT_FALSE(registry_->IsStarted<TestModuleNoDependency>());
237 EXPECT_FALSE(registry_->IsStarted<TestModuleOneDependency>());
238 EXPECT_FALSE(registry_->IsStarted<TestModuleNoDependencyTwo>());
239 EXPECT_FALSE(registry_->IsStarted<TestModuleTwoDependencies>());
240 }
241
TEST_F(ModuleTest,one_dependency)242 TEST_F(ModuleTest, one_dependency) {
243 ModuleList list;
244 list.add<TestModuleOneDependency>();
245 registry_->Start(&list, thread_);
246
247 EXPECT_TRUE(registry_->IsStarted<TestModuleNoDependency>());
248 EXPECT_TRUE(registry_->IsStarted<TestModuleOneDependency>());
249 EXPECT_FALSE(registry_->IsStarted<TestModuleNoDependencyTwo>());
250 EXPECT_FALSE(registry_->IsStarted<TestModuleTwoDependencies>());
251
252 registry_->StopAll();
253
254 EXPECT_FALSE(registry_->IsStarted<TestModuleNoDependency>());
255 EXPECT_FALSE(registry_->IsStarted<TestModuleOneDependency>());
256 EXPECT_FALSE(registry_->IsStarted<TestModuleNoDependencyTwo>());
257 EXPECT_FALSE(registry_->IsStarted<TestModuleTwoDependencies>());
258 }
259
TEST_F(ModuleTest,two_dependencies)260 TEST_F(ModuleTest, two_dependencies) {
261 ModuleList list;
262 list.add<TestModuleTwoDependencies>();
263 registry_->Start(&list, thread_);
264
265 EXPECT_TRUE(registry_->IsStarted<TestModuleNoDependency>());
266 EXPECT_TRUE(registry_->IsStarted<TestModuleOneDependency>());
267 EXPECT_TRUE(registry_->IsStarted<TestModuleNoDependencyTwo>());
268 EXPECT_TRUE(registry_->IsStarted<TestModuleTwoDependencies>());
269
270 registry_->StopAll();
271
272 EXPECT_FALSE(registry_->IsStarted<TestModuleNoDependency>());
273 EXPECT_FALSE(registry_->IsStarted<TestModuleOneDependency>());
274 EXPECT_FALSE(registry_->IsStarted<TestModuleNoDependencyTwo>());
275 EXPECT_FALSE(registry_->IsStarted<TestModuleTwoDependencies>());
276 }
277
post_to_module_one_handler()278 void post_to_module_one_handler() {
279 std::this_thread::sleep_for(std::chrono::milliseconds(100));
280 test_module_one_dependency_handler->Post(common::BindOnce([] { FAIL(); }));
281 }
282
TEST_F(ModuleTest,shutdown_with_unhandled_callback)283 TEST_F(ModuleTest, shutdown_with_unhandled_callback) {
284 ModuleList list;
285 list.add<TestModuleOneDependency>();
286 registry_->Start(&list, thread_);
287 test_module_no_dependency_handler->Post(common::BindOnce(&post_to_module_one_handler));
288 registry_->StopAll();
289 }
290
TEST_F(ModuleTest,dump_state)291 TEST_F(ModuleTest, dump_state) {
292 static const char* title = "Test Dump Title";
293 ModuleList list;
294 list.add<TestModuleDumpState>();
295 registry_->Start(&list, thread_);
296
297 ModuleDumper dumper(STDOUT_FILENO, *registry_, title);
298
299 std::string output;
300 std::ostringstream oss;
301 dumper.DumpState(&output, oss);
302
303 auto data = flatbuffers::GetRoot<DumpsysData>(output.data());
304 EXPECT_STREQ(title, data->title()->c_str());
305
306 auto test_data = data->module_unittest_data();
307 EXPECT_STREQ("Initial Test String", test_data->title()->c_str());
308
309 TestModuleDumpState* test_module =
310 static_cast<TestModuleDumpState*>(registry_->Start(&TestModuleDumpState::Factory, nullptr));
311 test_module->test_string_ = "A Second Test String";
312
313 oss.clear();
314 output.clear();
315 dumper.DumpState(&output, oss);
316
317 data = flatbuffers::GetRoot<DumpsysData>(output.data());
318 test_data = data->module_unittest_data();
319 EXPECT_STREQ("A Second Test String", test_data->title()->c_str());
320
321 registry_->StopAll();
322 }
323
324 } // namespace
325 } // namespace bluetooth
326