Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 10ae3eb6 authored by Chris Manton's avatar Chris Manton
Browse files

Collect dumpsys data from participating modules

Bug: 157647700
Test: atest --host bluetooth_test_gd
Tag: #gd-refactor
Change-Id: I8105f53e9792e5e4f0c27ae3e13091b99e21cd80
parent 1a75b090
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
// Top level module dumpsys data schema
include "module_unittest.fbs";

namespace bluetooth;

@@ -6,6 +7,7 @@ attribute "privacy";

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

root_type DumpsysData;
+23 −3
Original line number Diff line number Diff line
@@ -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;
}

@@ -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
+5 −3
Original line number Diff line number Diff line
@@ -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;

@@ -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 {
+72 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */

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

@@ -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>();
@@ -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 −0
Original line number Diff line number Diff line
// module_unittest
namespace bluetooth;

attribute "privacy";

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

root_type ModuleUnitTestData;
Loading