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