1 /* 2 * Copyright 2020 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 #pragma once 18 19 #include <bluetooth/log.h> 20 #include <unistd.h> 21 22 #include <unordered_map> 23 24 #include "include/hardware/bluetooth.h" 25 #include "test/headless/bt_stack_info.h" 26 #include "test/headless/get_options.h" 27 #include "test/headless/log.h" 28 29 extern bt_interface_t bluetoothInterface; 30 31 namespace bluetooth { 32 namespace test { 33 namespace headless { 34 35 template <typename T> 36 using ExecutionUnit = std::function<T()>; 37 38 constexpr char kHeadlessInitialSentinel[] = 39 " INITIAL HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS"; 40 constexpr char kHeadlessStartSentinel[] = 41 " START HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS"; 42 constexpr char kHeadlessStopSentinel[] = 43 " STOP HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS"; 44 constexpr char kHeadlessFinalSentinel[] = 45 " FINAL HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS"; 46 47 class HeadlessStack { 48 protected: HeadlessStack()49 HeadlessStack() {} 50 virtual ~HeadlessStack() = default; 51 52 void SetUp(); 53 void TearDown(); 54 55 private: 56 std::unique_ptr<BtStackInfo> bt_stack_info_; 57 }; 58 59 class HeadlessRun : public HeadlessStack { 60 protected: 61 const bluetooth::test::headless::GetOpt& options_; 62 uint64_t loop_{0}; 63 HeadlessRun(const bluetooth::test::headless::GetOpt & options)64 HeadlessRun(const bluetooth::test::headless::GetOpt& options) : options_(options) {} 65 66 template <typename T> RunOnHeadlessStack(ExecutionUnit<T> func)67 T RunOnHeadlessStack(ExecutionUnit<T> func) { 68 log::info("{}", kHeadlessInitialSentinel); 69 SetUp(); 70 log::info("{}", kHeadlessStartSentinel); 71 72 T rc; 73 for (loop_ = 0; loop_ < options_.loop_; loop_++) { 74 LOG_CONSOLE("Loop started: %lu", loop_); 75 rc = func(); 76 if (options_.msec_ != 0) { 77 usleep(options_.msec_ * 1000); 78 } 79 if (rc) { 80 break; 81 } 82 LOG_CONSOLE("Loop completed: %lu", loop_); 83 } 84 if (rc) { 85 log::error("FAIL:{} loop/loops:{}/{}", rc, loop_, options_.loop_); 86 } else { 87 log::info("PASS:{} loop/loops:{}/{}", rc, loop_, options_.loop_); 88 } 89 90 log::info("{}", kHeadlessStopSentinel); 91 TearDown(); 92 log::info("{}", kHeadlessFinalSentinel); 93 return rc; 94 } 95 virtual ~HeadlessRun() = default; 96 }; 97 98 template <typename T> 99 class HeadlessTest : public HeadlessRun { 100 public: Run()101 virtual T Run() { 102 if (options_.non_options_.size() == 0) { 103 fprintf(stdout, "Must supply at least one subtest name\n"); 104 return -1; 105 } 106 107 std::string subtest = options_.GetNextSubTest(); 108 if (test_nodes_.find(subtest) == test_nodes_.end()) { 109 fprintf(stdout, "Unknown subtest module:%s\n", subtest.c_str()); 110 return -1; 111 } 112 return test_nodes_.at(subtest)->Run(); 113 } 114 115 virtual ~HeadlessTest() = default; 116 117 protected: HeadlessTest(const bluetooth::test::headless::GetOpt & options)118 HeadlessTest(const bluetooth::test::headless::GetOpt& options) : HeadlessRun(options) {} 119 120 std::unordered_map<std::string, std::unique_ptr<HeadlessTest<T>>> test_nodes_; 121 }; 122 123 } // namespace headless 124 } // namespace test 125 } // namespace bluetooth 126