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

Commit b76e9326 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Refactor of headless test to allow additional tests"

parents 1d4def95 89c3340a
Loading
Loading
Loading
Loading
+7 −1
Original line number Original line Diff line number Diff line
@@ -5,7 +5,13 @@ cc_test {
    srcs: [
    srcs: [
        "get_options.cc",
        "get_options.cc",
        "headless.cc",
        "headless.cc",
        "sdp/main.cc",
        "main.cc",
        "pairing/pairing.cc",
        "sdp/sdp.cc",
        "sdp/sdp_db.cc",
        "nop/nop.cc",
        "read/read.cc",
        "read/name.cc",
    ],
    ],
    include_dirs: [
    include_dirs: [
        "packages/modules/Bluetooth/system",
        "packages/modules/Bluetooth/system",
+30 −18
Original line number Original line Diff line number Diff line
@@ -24,19 +24,34 @@
#include <string>
#include <string>


namespace {
namespace {
constexpr struct option long_options[] = {{"device", required_argument, 0, 0},
constexpr struct option long_options[] = {
                                          {"loop", required_argument, 0, 0},
    {"device", required_argument, 0, 0}, {"loop", required_argument, 0, 0},
                                          {"uuid", required_argument, 0, 0},
    {"uuid", required_argument, 0, 0},   {"msleep", required_argument, 0, 0},
                                          {0, 0, 0, 0}};
    {"stderr", no_argument, 0, 0},       {0, 0, 0, 0}};


enum OptionType {
enum OptionType {
  kOptionDevice = 0,
  kOptionDevice = 0,
  kOptionLoop = 1,
  kOptionLoop = 1,
  kOptionUuid = 2,
  kOptionUuid = 2,
  kOptionMsleep = 3,
  kOptionStdErr = 4,
};
};


}  // namespace
}  // namespace


void bluetooth::test::headless::GetOpt::Usage() const {
  fprintf(stdout, "%s: Usage:\n", name_);
  fprintf(stdout,
          "%s  --device=<device,>  Comma separated list of remote devices\n",
          name_);
  fprintf(stdout, "%s  --uuid=<uuid,>      Comma separated list of uuids\n",
          name_);
  fprintf(stdout, "%s  --loop=<loop>       Number of loops\n", name_);
  fprintf(stdout, "%s  --msleep=<msecs>    Sleep msec between loops\n", name_);
  fprintf(stdout, "%s  --stderr            Dump stderr to stdout\n", name_);
  fflush(nullptr);
}

void bluetooth::test::headless::GetOpt::ParseValue(
void bluetooth::test::headless::GetOpt::ParseValue(
    char* optarg, std::list<std::string>& string_list) {
    char* optarg, std::list<std::string>& string_list) {
  CHECK(optarg != nullptr);
  CHECK(optarg != nullptr);
@@ -58,9 +73,9 @@ void bluetooth::test::headless::GetOpt::ProcessOption(int option_index,
  std::list<std::string> string_list;
  std::list<std::string> string_list;
  OptionType option_type = static_cast<OptionType>(option_index);
  OptionType option_type = static_cast<OptionType>(option_index);


  if (!optarg) return;
  switch (option_type) {
  switch (option_type) {
    case kOptionDevice:
    case kOptionDevice:
      if (!optarg) return;
      ParseValue(optarg, string_list);
      ParseValue(optarg, string_list);
      for (auto& entry : string_list) {
      for (auto& entry : string_list) {
        if (RawAddress::IsValidAddress(entry)) {
        if (RawAddress::IsValidAddress(entry)) {
@@ -74,12 +89,20 @@ void bluetooth::test::headless::GetOpt::ProcessOption(int option_index,
      loop_ = std::stoul(optarg, nullptr, 0);
      loop_ = std::stoul(optarg, nullptr, 0);
      break;
      break;
    case kOptionUuid:
    case kOptionUuid:
      if (!optarg) return;
      ParseValue(optarg, string_list);
      ParseValue(optarg, string_list);
      for (auto& entry : string_list) {
      for (auto& entry : string_list) {
        uuid_.push_back(
        uuid_.push_back(
            bluetooth::Uuid::From16Bit(std::stoul(entry.c_str(), nullptr, 0)));
            bluetooth::Uuid::From16Bit(std::stoul(entry.c_str(), nullptr, 0)));
      }
      }
      break;
      break;
    case kOptionMsleep:
      if (!optarg) return;
      msec_ = std::stoul(optarg, nullptr, 0);
      break;
    case kOptionStdErr:
      close_stderr_ = false;
      break;
    default:
    default:
      fflush(nullptr);
      fflush(nullptr);
      valid_ = false;
      valid_ = false;
@@ -108,20 +131,9 @@ bluetooth::test::headless::GetOpt::GetOpt(int argc, char** argv)
    }
    }
  }
  }


  if (optind < argc) {
  while (optind < argc) {
    printf("non-option ARGV-elements: ");
    non_options_.push_back(argv[optind++]);
    while (optind < argc) printf("%s ", argv[optind++]);
    printf("\n");
    valid_ = false;
  }
  }
  fflush(nullptr);
  fflush(nullptr);
}
}
void bluetooth::test::headless::GetOpt::Usage() const {
  printf("%s: Usage:\n", name_);
  printf("%s  --device=<device,>  Comma separated list of remote devices\n",
         name_);
  printf("%s  --uuid=<uuid,>      Comma separated list of uuids\n", name_);
  printf("%s  --loop=<loop>       Number of loops\n", name_);
  fflush(nullptr);
}
+12 −1
Original line number Original line Diff line number Diff line
@@ -33,9 +33,20 @@ class GetOpt {
  virtual void Usage() const;
  virtual void Usage() const;
  virtual bool IsValid() const { return valid_; };
  virtual bool IsValid() const { return valid_; };


  std::string GetNextSubTest() const {
    std::string test = non_options_.front();
    non_options_.pop_front();
    return test;
  }

  std::list<RawAddress> device_;
  std::list<RawAddress> device_;
  std::list<bluetooth::Uuid> uuid_;
  std::list<bluetooth::Uuid> uuid_;
  int loop_;
  unsigned long loop_{1};
  unsigned long msec_{0};

  bool close_stderr_{true};

  mutable std::list<std::string> non_options_;


 private:
 private:
  void ParseValue(char* optarg, std::list<std::string>& my_list);
  void ParseValue(char* optarg, std::list<std::string>& my_list);
+6 −5
Original line number Original line Diff line number Diff line
@@ -21,6 +21,7 @@
#include "base/logging.h"  // LOG() stdout and android log
#include "base/logging.h"  // LOG() stdout and android log
#include "include/hardware/bluetooth.h"
#include "include/hardware/bluetooth.h"
#include "osi/include/log.h"  // android log only
#include "osi/include/log.h"  // android log only
#include "test/headless/get_options.h"
#include "test/headless/headless.h"
#include "test/headless/headless.h"


extern bt_interface_t bluetoothInterface;
extern bt_interface_t bluetoothInterface;
@@ -137,7 +138,7 @@ bt_os_callouts_t bt_os_callouts{
};
};
}  // namespace
}  // namespace


void Headless::SetUp() {
void HeadlessStack::SetUp() {
  LOG(INFO) << __func__ << " Entry";
  LOG(INFO) << __func__ << " Entry";


  int status = bluetoothInterface.init(&bt_callbacks, false, false);
  int status = bluetoothInterface.init(&bt_callbacks, false, false);
@@ -151,14 +152,14 @@ void Headless::SetUp() {
      : LOG(ERROR) << "Failed to set up Bluetooth OS callouts";
      : LOG(ERROR) << "Failed to set up Bluetooth OS callouts";


  bluetoothInterface.enable();
  bluetoothInterface.enable();
  LOG_INFO(LOG_TAG, "%s Headless stack has enabled", __func__);
  LOG_INFO(LOG_TAG, "%s HeadlessStack stack has enabled", __func__);


  std::unique_lock<std::mutex> lck(adapter_state_mutex_);
  std::unique_lock<std::mutex> lck(adapter_state_mutex_);
  while (bt_state_ != BT_STATE_ON) adapter_state_cv_.wait(lck);
  while (bt_state_ != BT_STATE_ON) adapter_state_cv_.wait(lck);
  LOG_INFO(LOG_TAG, "%s Headless stack is operational", __func__);
  LOG_INFO(LOG_TAG, "%s HeadlessStack stack is operational", __func__);
}
}


void Headless::TearDown() {
void HeadlessStack::TearDown() {
  LOG_INFO(LOG_TAG, "Stack has disabled");
  LOG_INFO(LOG_TAG, "Stack has disabled");
  int status = bluetoothInterface.disable();
  int status = bluetoothInterface.disable();


@@ -169,5 +170,5 @@ void Headless::TearDown() {


  std::unique_lock<std::mutex> lck(adapter_state_mutex_);
  std::unique_lock<std::mutex> lck(adapter_state_mutex_);
  while (bt_state_ != BT_STATE_OFF) adapter_state_cv_.wait(lck);
  while (bt_state_ != BT_STATE_OFF) adapter_state_cv_.wait(lck);
  LOG_INFO(LOG_TAG, "%s Headless stack has exited", __func__);
  LOG_INFO(LOG_TAG, "%s HeadlessStack stack has exited", __func__);
}
}
+82 −10
Original line number Original line Diff line number Diff line
@@ -14,32 +14,104 @@
 * limitations under the License.
 * limitations under the License.
 */
 */


#pragma once

#include <unordered_map>

#include <unistd.h>

#include "base/logging.h"  // LOG() stdout and android log
#include "test/headless/get_options.h"

namespace bluetooth {
namespace bluetooth {
namespace test {
namespace test {
namespace headless {
namespace headless {


namespace {

template <typename T>
template <typename T>
using ExecutionUnit = std::function<T()>;
using ExecutionUnit = std::function<T()>;


class Headless {
constexpr char kHeadlessStartSentinel[] =
 public:
    " START HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS "
  Headless() = default;
    "HEADLESS";
  virtual ~Headless() = default;
constexpr char kHeadlessStopSentinel[] =
    " STOP HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS "
    "HEADLESS";


}  // namespace

class HeadlessStack {
 protected:
 protected:
  virtual void SetUp();
  HeadlessStack() = default;
  virtual void TearDown();
  virtual ~HeadlessStack() = default;

  void SetUp();
  void TearDown();
};
};


class Test : public Headless {
class HeadlessRun : public HeadlessStack {
 public:
 protected:
  const bluetooth::test::headless::GetOpt& options_;
  unsigned long loop_{0};

  HeadlessRun(const bluetooth::test::headless::GetOpt& options)
      : options_(options) {}

  template <typename T>
  template <typename T>
  T Run(ExecutionUnit<T> func) {
  T RunOnHeadlessStack(ExecutionUnit<T> func) {
    SetUp();
    SetUp();
    T rc = func();
    LOG(INFO) << kHeadlessStartSentinel;

    T rc;
    for (loop_ = 0; loop_ < options_.loop_; loop_++) {
      rc = func();
      if (options_.msec_ != 0) {
        usleep(options_.msec_ * 1000);
      }
      if (rc) {
        break;
      }
    }
    if (rc) {
      LOG(ERROR) << "FAIL:" << rc << " loop/loops:" << loop_ << "/"
                 << options_.loop_;
    } else {
      LOG(INFO) << "PASS:" << rc << " loop/loops:" << loop_ << "/"
                << options_.loop_;
    }

    LOG(INFO) << kHeadlessStopSentinel;
    TearDown();
    TearDown();
    return rc;
    return rc;
  }
  }
  virtual ~HeadlessRun() = default;
};

template <typename T>
class HeadlessTest : public HeadlessRun {
 public:
  virtual T Run() {
    if (options_.non_options_.size() == 0) {
      fprintf(stdout, "Must supply at least one subtest name\n");
      return -1;
    }

    std::string subtest = options_.GetNextSubTest();
    if (test_nodes_.find(subtest) == test_nodes_.end()) {
      fprintf(stdout, "Unknown subtest module:%s\n", subtest.c_str());
      return -1;
    }
    return test_nodes_.at(subtest)->Run();
  }

  virtual ~HeadlessTest() = default;

 protected:
  HeadlessTest(const bluetooth::test::headless::GetOpt& options)
      : HeadlessRun(options) {}

  std::unordered_map<std::string, std::unique_ptr<HeadlessTest<T>>> test_nodes_;
};
};


}  // namespace headless
}  // namespace headless
Loading