Skip to content

Commit

Permalink
Collect dumpsys data from participating modules
Browse files Browse the repository at this point in the history
Bug: 157647700
Test: atest --host bluetooth_test_gd
Tag: #gd-refactor
Change-Id: I8105f53e9792e5e4f0c27ae3e13091b99e21cd80
  • Loading branch information
Chris Manton committed Jun 23, 2020
1 parent a10b000 commit 57c205a
Show file tree
Hide file tree
Showing 7 changed files with 198 additions and 7 deletions.
2 changes: 2 additions & 0 deletions gd/dumpsys_data.fbs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
// Top level module dumpsys data schema
include "module_unittest.fbs";

namespace bluetooth;

attribute "privacy";

table DumpsysData {
title:string;
module_unittest_data:bluetooth.ModuleUnitTestData; // private
}

root_type DumpsysData;
26 changes: 23 additions & 3 deletions gd/module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Handler* Module::GetHandler() const {
}

DumpsysDataFinisher EmptyDumpsysDataFinisher = [](DumpsysDataBuilder* dumpsys_data_builder) {};
DumpsysDataFinisher Module::GetTable(flatbuffers::FlatBufferBuilder* builder) const {
DumpsysDataFinisher Module::GetDumpsysData(flatbuffers::FlatBufferBuilder* builder) const {
return EmptyDumpsysDataFinisher;
}

Expand Down Expand Up @@ -127,8 +127,28 @@ os::Handler* ModuleRegistry::GetModuleHandler(const ModuleFactory* module) const
}

void ModuleDumper::DumpState(std::string* output) const {
// TODO(cmanton)
*output = std::string("TBD");
ASSERT(output != nullptr);

flatbuffers::FlatBufferBuilder builder(1024);
auto title = builder.CreateString(title_);

std::queue<DumpsysDataFinisher> queue;
for (auto it = module_registry_.start_order_.rbegin(); it != module_registry_.start_order_.rend(); it++) {
auto instance = module_registry_.started_modules_.find(*it);
ASSERT(instance != module_registry_.started_modules_.end());
queue.push(instance->second->GetDumpsysData(&builder));
}

DumpsysDataBuilder data_builder(builder);
data_builder.add_title(title);

while (!queue.empty()) {
queue.front()(&data_builder);
queue.pop();
}

builder.Finish(data_builder.Finish());
*output = std::string(builder.GetBufferPointer(), builder.GetBufferPointer() + builder.GetSize());
}

} // namespace bluetooth
8 changes: 5 additions & 3 deletions gd/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class Module {
virtual void Stop() = 0;

// Get relevant state data from the module
virtual DumpsysDataFinisher GetTable(flatbuffers::FlatBufferBuilder* builder) const;
virtual DumpsysDataFinisher GetDumpsysData(flatbuffers::FlatBufferBuilder* builder) const;

virtual std::string ToString() const;

Expand Down Expand Up @@ -160,11 +160,13 @@ class ModuleRegistry {

class ModuleDumper {
public:
ModuleDumper(const ModuleRegistry& module_registry) : module_registry_(module_registry) {}
ModuleDumper(const ModuleRegistry& module_registry, const char* title)
: module_registry_(module_registry), title_(title) {}
void DumpState(std::string* output) const;

private:
[[maybe_unused]] const ModuleRegistry& module_registry_;
const ModuleRegistry& module_registry_;
const std::string title_;
};

class TestModuleRegistry : public ModuleRegistry {
Expand Down
72 changes: 72 additions & 0 deletions gd/module_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

#include "module.h"
#include "module_unittest_generated.h"
#include "os/handler.h"
#include "os/thread.h"

Expand Down Expand Up @@ -156,6 +157,47 @@ const ModuleFactory TestModuleTwoDependencies::Factory = ModuleFactory([]() {
return new TestModuleTwoDependencies();
});

// To generate module unittest flatbuffer headers:
// $ flatc --cpp module_unittest.fbs
class TestModuleDumpState : public Module {
public:
static const ModuleFactory Factory;

std::string test_string_{"Initial Test String"};

protected:
void ListDependencies(ModuleList* list) override {
list->add<TestModuleNoDependency>();
}

void Start() override {
EXPECT_TRUE(GetModuleRegistry()->IsStarted<TestModuleNoDependency>());

// A module is not considered started until Start() finishes
EXPECT_FALSE(GetModuleRegistry()->IsStarted<TestModuleDumpState>());
test_module_one_dependency_handler = GetHandler();
}

void Stop() override {
EXPECT_TRUE(GetModuleRegistry()->IsStarted<TestModuleNoDependency>());

// A module is not considered stopped until after Stop() finishes
EXPECT_TRUE(GetModuleRegistry()->IsStarted<TestModuleDumpState>());
}

DumpsysDataFinisher GetDumpsysData(flatbuffers::FlatBufferBuilder* fb_builder) const override {
auto string = fb_builder->CreateString(test_string_.c_str());

auto builder = ModuleUnitTestDataBuilder(*fb_builder);
builder.add_title(string);
auto table = builder.Finish();

return [table](DumpsysDataBuilder* builder) { builder->add_module_unittest_data(table); };
}
};

const ModuleFactory TestModuleDumpState::Factory = ModuleFactory([]() { return new TestModuleDumpState(); });

TEST_F(ModuleTest, no_dependency) {
ModuleList list;
list.add<TestModuleNoDependency>();
Expand Down Expand Up @@ -223,5 +265,35 @@ TEST_F(ModuleTest, shutdown_with_unhandled_callback) {
registry_->StopAll();
}

TEST_F(ModuleTest, dump_state) {
static const char* title = "Test Dump Title";
ModuleList list;
list.add<TestModuleDumpState>();
registry_->Start(&list, thread_);

ModuleDumper dumper(*registry_, title);

std::string output;
dumper.DumpState(&output);

auto data = flatbuffers::GetRoot<DumpsysData>(output.data());
EXPECT_STREQ(title, data->title()->c_str());

auto test_data = data->module_unittest_data();
EXPECT_STREQ("Initial Test String", test_data->title()->c_str());

TestModuleDumpState* test_module =
static_cast<TestModuleDumpState*>(registry_->Start(&TestModuleDumpState::Factory, nullptr));
test_module->test_string_ = "A Second Test String";

dumper.DumpState(&output);

data = flatbuffers::GetRoot<DumpsysData>(output.data());
test_data = data->module_unittest_data();
EXPECT_STREQ("A Second Test String", test_data->title()->c_str());

registry_->StopAll();
}

} // namespace
} // namespace bluetooth
10 changes: 10 additions & 0 deletions gd/module_unittest.fbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// module_unittest
namespace bluetooth;

attribute "privacy";

table ModuleUnitTestData {
title:string (privacy:"Any");
}

root_type ModuleUnitTestData;
84 changes: 84 additions & 0 deletions gd/module_unittest_generated.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// automatically generated by the FlatBuffers compiler, do not modify

#ifndef FLATBUFFERS_GENERATED_MODULEUNITTEST_BLUETOOTH_H_
#define FLATBUFFERS_GENERATED_MODULEUNITTEST_BLUETOOTH_H_

#include "flatbuffers/flatbuffers.h"

namespace bluetooth {

struct ModuleUnitTestData;
struct ModuleUnitTestDataBuilder;

struct ModuleUnitTestData FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
typedef ModuleUnitTestDataBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_TITLE = 4 };
const flatbuffers::String* title() const {
return GetPointer<const flatbuffers::String*>(VT_TITLE);
}
bool Verify(flatbuffers::Verifier& verifier) const {
return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_TITLE) && verifier.VerifyString(title()) &&
verifier.EndTable();
}
};

struct ModuleUnitTestDataBuilder {
typedef ModuleUnitTestData Table;
flatbuffers::FlatBufferBuilder& fbb_;
flatbuffers::uoffset_t start_;
void add_title(flatbuffers::Offset<flatbuffers::String> title) {
fbb_.AddOffset(ModuleUnitTestData::VT_TITLE, title);
}
explicit ModuleUnitTestDataBuilder(flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) {
start_ = fbb_.StartTable();
}
ModuleUnitTestDataBuilder& operator=(const ModuleUnitTestDataBuilder&);
flatbuffers::Offset<ModuleUnitTestData> Finish() {
const auto end = fbb_.EndTable(start_);
auto o = flatbuffers::Offset<ModuleUnitTestData>(end);
return o;
}
};

inline flatbuffers::Offset<ModuleUnitTestData> CreateModuleUnitTestData(
flatbuffers::FlatBufferBuilder& _fbb, flatbuffers::Offset<flatbuffers::String> title = 0) {
ModuleUnitTestDataBuilder builder_(_fbb);
builder_.add_title(title);
return builder_.Finish();
}

inline flatbuffers::Offset<ModuleUnitTestData> CreateModuleUnitTestDataDirect(
flatbuffers::FlatBufferBuilder& _fbb, const char* title = nullptr) {
auto title__ = title ? _fbb.CreateString(title) : 0;
return bluetooth::CreateModuleUnitTestData(_fbb, title__);
}

inline const bluetooth::ModuleUnitTestData* GetModuleUnitTestData(const void* buf) {
return flatbuffers::GetRoot<bluetooth::ModuleUnitTestData>(buf);
}

inline const bluetooth::ModuleUnitTestData* GetSizePrefixedModuleUnitTestData(const void* buf) {
return flatbuffers::GetSizePrefixedRoot<bluetooth::ModuleUnitTestData>(buf);
}

inline bool VerifyModuleUnitTestDataBuffer(flatbuffers::Verifier& verifier) {
return verifier.VerifyBuffer<bluetooth::ModuleUnitTestData>(nullptr);
}

inline bool VerifySizePrefixedModuleUnitTestDataBuffer(flatbuffers::Verifier& verifier) {
return verifier.VerifySizePrefixedBuffer<bluetooth::ModuleUnitTestData>(nullptr);
}

inline void FinishModuleUnitTestDataBuffer(
flatbuffers::FlatBufferBuilder& fbb, flatbuffers::Offset<bluetooth::ModuleUnitTestData> root) {
fbb.Finish(root);
}

inline void FinishSizePrefixedModuleUnitTestDataBuffer(
flatbuffers::FlatBufferBuilder& fbb, flatbuffers::Offset<bluetooth::ModuleUnitTestData> root) {
fbb.FinishSizePrefixed(root);
}

} // namespace bluetooth

#endif // FLATBUFFERS_GENERATED_MODULEUNITTEST_BLUETOOTH_H_
3 changes: 2 additions & 1 deletion gd/shim/dumpsys.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ namespace shim {

namespace {
constexpr char kModuleName[] = "shim::Dumpsys";
constexpr char kDumpsysTitle[] = "----- Gd Dumpsys ------";
} // namespace

constexpr char kArgumentDeveloper[] = "--dev";
Expand Down Expand Up @@ -116,7 +117,7 @@ void Dumpsys::impl::DumpWithArgs(int fd, const char** args, std::promise<void> p
ParsedDumpsysArgs parsed_dumpsys_args(args);
const auto registry = dumpsys_module_.GetModuleRegistry();

ModuleDumper dumper(*registry);
ModuleDumper dumper(*registry, kDumpsysTitle);
std::string output;
// Get the dumpstate into out string
dumper.DumpState(&output);
Expand Down

0 comments on commit 57c205a

Please sign in to comment.