libcopp  1.1.0
test_manager.cpp
Go to the documentation of this file.
1 /*
2  * test_manager.cpp
3  *
4  * Created on: 2014年3月11日
5  * Author: owent
6  *
7  * Released under the MIT license
8  */
9 
10 #include <cstring>
11 #include <iostream>
12 #include <sstream>
13 #include <string>
14 #include <vector>
15 
16 #include "cli/cmd_option.h"
17 #include "cli/cmd_option_phoenix.h"
18 #include "cli/shell_font.h"
19 
20 #include "test_manager.h"
21 
22 
24 test_manager::pick_param_str_t::pick_param_str_t(const std::string &in) : str_(in.c_str()) {}
25 
26 bool test_manager::pick_param_str_t::operator==(const pick_param_str_t &other) const { return strcmp(str_, other.str_) == 0; }
27 bool test_manager::pick_param_str_t::operator!=(const pick_param_str_t &other) const { return strcmp(str_, other.str_) != 0; }
28 bool test_manager::pick_param_str_t::operator>=(const pick_param_str_t &other) const { return strcmp(str_, other.str_) >= 0; }
29 bool test_manager::pick_param_str_t::operator>(const pick_param_str_t &other) const { return strcmp(str_, other.str_) > 0; }
30 bool test_manager::pick_param_str_t::operator<=(const pick_param_str_t &other) const { return strcmp(str_, other.str_) <= 0; }
31 bool test_manager::pick_param_str_t::operator<(const pick_param_str_t &other) const { return strcmp(str_, other.str_) < 0; }
32 
35  success_ = 0;
36  failed_ = 0;
37 }
38 
40 
41 void test_manager::append(const std::string &test_name, const std::string &case_name, case_ptr_type ptr) {
42  tests_[test_name].push_back(std::make_pair(case_name, ptr));
43 }
44 
45 #ifdef UTILS_TEST_MACRO_TEST_ENABLE_BOOST_TEST
46 
47 boost::unit_test::test_suite *&test_manager::test_suit() {
48  static boost::unit_test::test_suite *ret = NULL;
49  return ret;
50 }
51 
52 int test_manager::run() {
53  using namespace boost::unit_test;
54 
55  for (test_data_type::iterator iter = tests_.begin(); iter != tests_.end(); ++iter) {
56  test_suit() = BOOST_TEST_SUITE(iter->first.c_str());
57 
58  for (test_type::iterator iter2 = iter->second.begin(); iter2 != iter->second.end(); ++iter2) {
59  test_suit()->add(make_test_case(callback0<>(iter2->second->func_), iter2->first.c_str()));
60  iter2->second->run();
61  }
62 
63  framework::master_test_suite().add(test_suit());
64  }
65 
66  return 0;
67 }
68 
69 #else
70 
72  success_ = 0;
73  failed_ = 0;
74 
75  clock_t all_begin_time = clock();
76  util::cli::shell_stream ss(std::cout);
78  << util::cli::shell_font_style::SHELL_FONT_SPEC_NULL << "Running " << tests_.size() << " test(s)" << std::endl;
79 
80  for (test_data_type::iterator iter = tests_.begin(); iter != tests_.end(); ++iter) {
81  bool check_test_group_passed = run_cases_.empty();
82  bool check_test_group_has_cases = false;
83 
84  if (!check_test_group_passed) {
85  check_test_group_passed = run_cases_.end() != run_cases_.find(iter->first);
86  }
87 
88  if (!check_test_group_passed) {
89  check_test_group_has_cases = run_groups_.end() != run_groups_.find(iter->first);
90  }
91 
92  // skip unknown groups
93  if (!check_test_group_passed && !check_test_group_has_cases) {
94  continue;
95  }
96 
97  size_t run_group_count = 0;
98 
99  ss() << std::endl
101  << util::cli::shell_font_style::SHELL_FONT_SPEC_NULL << iter->second.size() << " test case(s) from " << iter->first
102  << std::endl;
103 
104  clock_t test_begin_time = clock();
105  for (test_type::iterator iter2 = iter->second.begin(); iter2 != iter->second.end(); ++iter2) {
106  bool check_test_case_passed = run_cases_.empty() || check_test_group_passed;
107  if (!check_test_case_passed) {
108  check_test_case_passed = run_cases_.end() != run_cases_.find(iter2->first);
109 
110  if (!check_test_case_passed) {
111  std::string full_name;
112  full_name.reserve(iter->first.size() + 1 + iter2->first.size());
113  full_name = iter->first + "." + iter2->first;
114  check_test_case_passed = run_cases_.end() != run_cases_.find(full_name);
115  }
116  }
117 
118  // skip unknown cases
119  if (!check_test_case_passed) {
120  continue;
121  }
122 
124  << util::cli::shell_font_style::SHELL_FONT_SPEC_NULL << iter->first << "." << iter2->first << std::endl;
125 
126  clock_t case_begin_time = clock();
127  iter2->second->run();
128  clock_t case_end_time = clock();
129 
130  if (0 == iter2->second->failed_) {
131  ++success_;
133  << util::cli::shell_font_style::SHELL_FONT_SPEC_NULL << iter->first << "." << iter2->first << " ("
134  << get_expire_time(case_begin_time, case_end_time) << ")" << std::endl;
135  } else {
136  ++failed_;
138  << util::cli::shell_font_style::SHELL_FONT_SPEC_NULL << iter->first << "." << iter2->first << " ("
139  << get_expire_time(case_begin_time, case_end_time) << ")" << std::endl;
140  }
141 
142  ++run_group_count;
143  }
144 
145  clock_t test_end_time = clock();
147  << util::cli::shell_font_style::SHELL_FONT_SPEC_NULL << run_group_count << " test case(s) from " << iter->first << " ("
148  << get_expire_time(test_begin_time, test_end_time) << " total)" << std::endl;
149  }
150 
151  clock_t all_end_time = clock();
154  << " (" << get_expire_time(all_begin_time, all_end_time) << " total)" << std::endl;
155 
157  << success_ << " test case(s)." << std::endl;
158 
159  if (failed_ > 0) {
161  << failed_ << " test case(s), listed below:" << std::endl;
162 
163  for (test_data_type::iterator iter = tests_.begin(); iter != tests_.end(); ++iter) {
164  for (test_type::iterator iter2 = iter->second.begin(); iter2 != iter->second.end(); ++iter2) {
165  if (iter2->second->failed_ > 0) {
167  << util::cli::shell_font_style::SHELL_FONT_SPEC_NULL << iter->first << "." << iter2->first << std::endl;
168  }
169  }
170  }
171  }
172 
173  return (0 == failed_) ? 0 : -failed_;
174 }
175 
176 #endif
177 
178 void test_manager::set_cases(const std::vector<std::string> &case_names) {
179  run_cases_.clear();
180  run_groups_.clear();
181 
182  for (size_t i = 0; i < case_names.size(); ++i) {
183  run_cases_.insert(case_names[i]);
184  std::string::size_type split_idx = case_names[i].find('.');
185  if (split_idx != std::string::npos) {
186  run_groups_.insert(case_names[i].substr(0, split_idx));
187  }
188  }
189 }
190 
192  static test_manager ret;
193  return ret;
194 }
195 
196 std::string test_manager::get_expire_time(clock_t begin, clock_t end) {
197  std::stringstream ss;
198  double ms = 1000.0 * (end - begin) / CLOCKS_PER_SEC;
199 
200  ss << ms << " ms";
201 
202  return ss.str();
203 }
204 
205 int run_tests(int argc, char *argv[]) {
206  std::vector<std::string> run_cases;
207  const char * version = "1.0.0";
208  bool is_help = false;
209  bool is_show_version = false;
210 
212  cmd_opts->bind_cmd("-h, --help, help", util::cli::phoenix::set_const(is_help, true))
213  ->set_help_msg(" show help message and exit.");
214  cmd_opts->bind_cmd("-v, --version, version", util::cli::phoenix::set_const(is_show_version, true))
215  ->set_help_msg(" show version and exit.");
216  cmd_opts->bind_cmd("-r, --run, run", util::cli::phoenix::push_back(run_cases))
217  ->set_help_msg("[case names...] only run specify cases.");
218 
219  cmd_opts->start(argc, argv);
220  if (is_help) {
221  std::cout << *cmd_opts << std::endl;
222  return 0;
223  }
224 
225  if (is_show_version) {
226  std::cout << version << std::endl;
227  return 0;
228  }
229 
230  test_manager::me().set_cases(run_cases);
231  return test_manager::me().run();
232 }
bool operator>(const pick_param_str_t &other) const
static test_manager & me()
bool operator!=(const pick_param_str_t &other) const
bool operator<(const pick_param_str_t &other) const
bool operator==(const pick_param_str_t &other) const
void append(const std::string &test_name, const std::string &case_name, case_ptr_type)
bool operator<=(const pick_param_str_t &other) const
test_data_type tests_
Definition: test_manager.h:280
std::shared_ptr< cmd_option_bind > ptr_type
Definition: cmd_option.h:328
int * failed_counter_ptr
Definition: test_manager.h:66
void set_cases(const std::vector< std::string > &case_names)
bool operator>=(const pick_param_str_t &other) const
push_back_t< T > push_back(T &t)
set_const_t< T > set_const(T &t, const T &v)
int run_tests(int argc, char *argv[])
static ptr_type create()
Definition: cmd_option.h:329
static std::string get_expire_time(clock_t begin, clock_t end)
virtual ~test_manager()
int * success_counter_ptr
Definition: test_manager.h:65