Bridge++  Ver. 1.1.x
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
testManager.cpp
Go to the documentation of this file.
1 
14 #include "testManager.h"
15 
16 // prototype definition
17 std::vector<std::string> string_tokenize(const std::string& src, const char delim = '.');
18 
19 
20 //====================================================================
21 int DoNothing()
22 {
23  return int();
24 }
25 
26 
27 //====================================================================
29 {
30  vout.general(m_vl, "\n");
31  vout.general(m_vl, "-------------------------------------------------\n");
32  vout.general(m_vl, "------------ <Bridge++ 1.1> Test Menu -----------\n");
33  vout.general(m_vl, "-------------------------------------------------\n");
34  vout.general(m_vl, "Please select test category name \n");
35 }
36 
37 
38 //====================================================================
40 {
41  if (!s_instance) {
42  //
43  // acquire lock here
44  //
45  if (!s_instance) {
47  }
48  //
49  // release lock here
50  //
51  }
52 
53  return *s_instance;
54 }
55 
56 
57 //====================================================================
59 {
60  static TestManager instance_;
61 
62  s_instance = &instance_;
63 }
64 
65 
66 //====================================================================
68  : m_vl(CommonParameters::Vlevel()),
69  m_root_node("<top_level>"),
70  m_precision(Test::default_precision)
71 {
72 }
73 
74 
75 //====================================================================
77 {
78  s_instance = 0;
79 }
80 
81 
82 //====================================================================
84 {
87  } else {
89  }
90 }
91 
92 
93 //====================================================================
95 {
96  menu(&m_root_node, true);
97 
98  std::string jobname = "<terminate>";
99  Communicator::broadcast(1, jobname, 0);
100 
101  vout.detailed(m_vl, "TestManager::interactive_master: rank=%d, exit.\n", Communicator::self());
102 }
103 
104 
105 //====================================================================
107 {
108  for ( ; ; ) {
109  std::string jobname;
110  Communicator::broadcast(1, jobname, 0);
111 
112  vout.detailed(m_vl, "TestManager::interactive_slave: rank=%d, job=%s\n", Communicator::self(), jobname.c_str());
113 
114  if (jobname == "<terminate>") break;
115 
116  batch(jobname);
117  }
118 
119  vout.detailed(m_vl, "TestManager::interactive_slave: rank=%d, exit.\n", Communicator::self());
120 }
121 
122 
123 //====================================================================
124 void TestManager::batch(const std::string& arg)
125 {
127 
128  if (p && (p->m_function != DoNothing)) {
129  int result = p->m_function();
130  } else {
131  vout.general(m_vl, "Test not found: %s.\n", arg.c_str());
132  }
133 }
134 
135 
136 //====================================================================
137 bool TestManager::registerTest(const std::string& key, const Test_function func)
138 {
140  return true;
141 }
142 
143 
144 //====================================================================
145 void TestManager::run(const Node *p)
146 {
147  if (!p) return;
148 
149  if (p->m_function == DoNothing) return;
150 
151  std::string testname = find_fullpath(p);
152  vout.general(m_vl, "run test \"%s\"\n", testname.c_str());
153 
154  if (Communicator::is_primary()) {
155  Communicator::broadcast(1, testname, 0);
156  }
157 
158  int result = p->m_function();
159 
160  // increment stat counter
161  if (result == 0) {
162  m_stat.success(testname);
163  } else {
164  m_stat.failure(testname);
165  }
166 
167  // check result
168  //check_result(testname, result);
169 }
170 
171 
172 //====================================================================
174 {
175  if (!p) return;
176 
177  if (p->m_next.size() == 0) {
178  run(p);
179  } else {
180  for (size_t i = 0; i < p->m_next.size(); ++i) {
181  run_traversal(p->m_next[i]);
182  }
183  }
184 }
185 
186 
187 //====================================================================
188 bool TestManager::menu(const Node *p, bool is_top)
189 {
190  if (!p) return false;
191 
192  if (is_top && (p->m_next.size() > 0)) banner();
193 
194 
195  if (p->m_next.size() == 0) { // leaf node
196  vout.general(m_vl, "run %s\n", p->m_name.c_str());
197  run(p);
198  return true;
199  }
200 
201  bool do_continue = true;
202 
203  while (do_continue) // loop forever
204 
205  { // show item list
206  for (unsigned int i = 0; i < p->m_next.size(); ++i) {
207  vout.general(m_vl, "%u : %s\n", i + 1, p->m_next[i]->m_name.c_str());
208  }
209 
210  vout.general(m_vl, "a : Test All \n");
211  vout.general(m_vl, "p : Setup test check precision (current precision: %d)\n", m_precision);
212  if (!is_top) {
213  vout.general(m_vl, "u : Go back \n");
214  }
215  vout.general(m_vl, "q : Quit \n");
216 
217  char buf[1024];
218  buf[0] = '\0';
219 
220  int choice = 0;
221 
222  bool do_alltest = false;
223  bool do_setprecision = false;
224 
225  while (true) // loop until get valid answer.
226  {
227  vout.general(m_vl, "choice> ");
228  // scanf("%1023s", buf);
229  std::cin >> buf;
230 
231  if (buf[0] == 0) return false; // ctrl-D to escape
232 
233  if (buf[0] == 'a') {
234  do_alltest = true;
235  break;
236  }
237 
238  if (buf[0] == 'p') {
239  do_setprecision = true;
240  break;
241  }
242 
243  if (!is_top) {
244  if (buf[0] == 'u') return true; // go up.
245  }
246  if (buf[0] == 'q') return false; // quit.
247 
248 
249  choice = atoi(buf);
250  buf[0] = '\0';
251 
252  if ((choice >= 1) && (choice <= int(p->m_next.size()))) break;
253  }
254 
255  if (do_alltest) {
256  m_stat.reset();
257 
258  run_traversal(p);
259 
260  stat_report();
261  } else if (do_setprecision) {
262  set_precision();
263  } else {
264  do_continue = menu(p->m_next[choice - 1]);
265  }
266 
267  if (!do_continue) break;
268  }
269 
270  return do_continue;
271 }
272 
273 
274 //====================================================================
276 {
277  vout.general(m_vl, "Please input test check precision \n");
278  vout.general(m_vl, "input number from 1 to 14 (default: 12)\n");
279 
280  char buf[1024];
281  buf[0] = '\0';
282 
283  vout.general(m_vl, "precision = ");
284  // scanf("%1023s", buf);
285  std::cin >> buf;
286 
287  int prec = atoi(buf);
288  if ((prec >= 1) && (prec <= 14)) {
289  m_precision = prec;
290 
291  vout.general(m_vl, "precision set to %d\n", m_precision);
292  } else {
293  vout.general(m_vl, "invalid value.\n");
294  }
295 }
296 
297 
298 //====================================================================
299 TestManager::Node *TestManager::find_node(TestManager::Node *p, const std::vector<std::string>& v)
300 {
301  if (!p) return 0;
302 
303  if (v.size() == 0) return p;
304 
305  for (std::vector<std::string>::const_iterator r = v.begin(); r != v.end(); ++r) {
306  bool is_found = false;
307  size_t i = 0;
308  for (i = 0; i < p->m_next.size(); ++i) {
309  if (p->m_next[i]->m_name == (*r)) {
310  is_found = true;
311  break;
312  }
313  }
314 
315  if (!is_found) return 0;
316 
317  p = p->m_next[i];
318  }
319 
320  return p;
321 }
322 
323 
324 //====================================================================
325 TestManager::Node *TestManager::append_key(TestManager::Node *p, const std::vector<std::string>& v)
326 {
327  if (!p) return 0;
328 
329  if (v.size() == 0) return p;
330 
331  for (std::vector<std::string>::const_iterator r = v.begin(); r != v.end(); ++r) {
332  bool is_found = false;
333  size_t i = 0;
334  for (i = 0; i < p->m_next.size(); ++i) {
335  if (p->m_next[i]->m_name == (*r)) {
336  is_found = true;
337  break;
338  }
339  }
340 
341  if (is_found) {
342  p = p->m_next[i];
343  } else {
344  Node *q = new Node(*r, p);
345  p->m_next.push_back(q);
346  p = q;
347  }
348  }
349 
350  return p;
351 }
352 
353 
354 //====================================================================
356 {
357  if (!p) return 0;
358 
359  if (argc == 0) return p;
360 
361  vout.general(m_vl, "%s: p=%p, argc=%d, argv={ ", __func__, p, argc);
362  for (int i = 0; i < argc; ++i) {
363  vout.general(m_vl, "%s, ", argv[i]);
364  }
365  vout.general(m_vl, "}\n");
366 
367  for (size_t i = 0; i < p->m_next.size(); ++i) {
368  if (p->m_next[i]->m_name == argv[0]) {
369  return append_key(p->m_next[i], argc - 1, argv + 1);
370  }
371  }
372 
373  Node *q = new Node(argv[0], p);
374  p->m_next.push_back(q);
375 
376  return append_key(q, argc - 1, argv + 1);
377 }
378 
379 
380 //====================================================================
381 std::string TestManager::find_fullpath(const TestManager::Node *p, const std::string& path)
382 {
383  if (!p) return path;
384 
385  if (!p->m_prev) return path; // omit "<top_level>"
386 
387  if (path.length() > 0) {
388  return find_fullpath(p->m_prev, p->m_name + '.' + path);
389  } else {
390  return find_fullpath(p->m_prev, p->m_name);
391  }
392 }
393 
394 
395 //====================================================================
397 {
398  m_num_tests = 0;
399  m_num_failure = 0;
400  m_list_failure.resize(0);
401 }
402 
403 
404 //====================================================================
405 void TestManager::Stat::success(const std::string& test_name)
406 {
407  ++m_num_tests;
408 }
409 
410 
411 //====================================================================
412 void TestManager::Stat::failure(const std::string& test_name)
413 {
414  ++m_num_tests;
415  ++m_num_failure;
416  m_list_failure.push_back(test_name);
417 }
418 
419 
420 //====================================================================
422 {
423  vout.general(m_vl, "Test report:\n");
424  vout.general(m_vl, " Total number of tests = %3d\n", m_stat.m_num_tests);
425  vout.general(m_vl, " Number of successes = %3d\n", m_stat.m_num_tests - m_stat.m_num_failure);
426  vout.general(m_vl, " Number of failures = %3d\n", m_stat.m_num_failure);
427 
428  if (m_stat.m_num_failure > 0) {
429  vout.general(m_vl, " Failed tests:\n");
430  for (std::vector<std::string>::const_iterator p = m_stat.m_list_failure.begin(); p != m_stat.m_list_failure.end(); ++p) {
431  vout.general(m_vl, " %s\n", p->c_str());
432  }
433  }
434 
435  if (m_stat.m_num_failure == 0) {
436  vout.general(m_vl, " All tests are done successfully.\n");
437  }
438 
439  vout.general(m_vl, "\n");
440 }
441 
442 
443 //====================================================================
444 void TestManager::traverse(const Node *p, const std::string& indent)
445 {
446  if (!p) return;
447 
448  if (p->m_next.size() == 0) {
449  vout.general(m_vl, "%sleaf \"%s\"\n", indent.c_str(), p->m_name.c_str());
450  return;
451  }
452 
453  vout.general(m_vl, "%snode \"%s\"\n", indent.c_str(), p->m_name.c_str());
454 
455  for (size_t i = 0; i < p->m_next.size(); ++i) {
456  traverse(p->m_next[i], indent + " ");
457  }
458 }
459 
460 
461 //====================================================================
462 std::vector<std::string> string_tokenize(const std::string& src, const char delim)
463 {
464  std::vector<std::string> retv;
465 
466  size_t npos = src.length();
467  size_t p = 0;
468 
469  while (true)
470  {
471  size_t q = src.find(delim, p);
472 
473  if (q >= npos) { // not found
474  retv.push_back(src.substr(p)); // append rest
475  break;
476  }
477 
478  retv.push_back(src.substr(p, q - p));
479  p = q + 1; // skip delimiter.
480  }
481 
482  return retv;
483 }
484 
485 
486 //====================================================================
488 
489 //====================================================================
490 //==============================================================END===