20 #include <test/unit_test/multi_runner.h>
22 #include <beast/unit_test/amount.hpp>
24 #include <boost/lexical_cast.hpp>
40 fmtdur(
typename clock_type::duration
const& d)
43 auto const ms = duration_cast<milliseconds>(d);
45 return boost::lexical_cast<std::string>(ms.count()) +
"ms";
77 [](
run_time const& t1,
typename clock_type::duration
const& t2) {
78 return t1.second > t2;
81 if (iter !=
top.end())
93 top.resize(
top.size() - 1);
118 boost::container::static_vector<run_time, 2 * max_top> top_result;
119 top_result.resize(
top.size() + r.
top.size());
127 return t1.second > t2.second;
130 if (top_result.size() >
max_top)
144 s <<
"Longest suite times:\n";
145 for (
auto const& [name, dur] :
top)
150 s <<
fmtdur(elapsed) <<
", " << amount{
suites,
"suite"} <<
", "
151 << amount{
cases,
"case"} <<
", " << amount{
total,
"test"} <<
" total, "
157 template <
bool IsParent>
164 template <
bool IsParent>
168 return test_index_++;
171 template <
bool IsParent>
178 template <
bool IsParent>
182 any_failed_ = any_failed_ || v;
185 template <
bool IsParent>
192 template <
bool IsParent>
199 template <
bool IsParent>
207 template <
bool IsParent>
216 template <
bool IsParent>
224 boost::interprocess::shared_memory_object::remove(shared_mem_name_);
225 boost::interprocess::message_queue::remove(message_queue_name_);
228 shared_mem_ = boost::interprocess::shared_memory_object{
231 boost::interprocess::create_only_t,
232 boost::interprocess::open_only_t>{},
234 boost::interprocess::read_write};
238 shared_mem_.truncate(
sizeof(inner));
240 std::make_unique<boost::interprocess::message_queue>(
241 boost::interprocess::create_only,
249 std::make_unique<boost::interprocess::message_queue>(
250 boost::interprocess::open_only, message_queue_name_);
253 region_ = boost::interprocess::mapped_region{
254 shared_mem_, boost::interprocess::read_write};
256 inner_ =
new (region_.get_address()) inner{};
258 inner_ =
reinterpret_cast<inner*
>(region_.get_address());
264 boost::interprocess::shared_memory_object::remove(shared_mem_name_);
265 boost::interprocess::message_queue::remove(message_queue_name_);
271 template <
bool IsParent>
277 boost::interprocess::shared_memory_object::remove(shared_mem_name_);
278 boost::interprocess::message_queue::remove(message_queue_name_);
282 template <
bool IsParent>
286 return inner_->checkout_test_index();
289 template <
bool IsParent>
293 return inner_->checkout_job_index();
296 template <
bool IsParent>
300 return inner_->any_failed();
303 template <
bool IsParent>
307 return inner_->any_failed(v);
310 template <
bool IsParent>
317 template <
bool IsParent>
321 inner_->inc_keep_alive_count();
324 template <
bool IsParent>
328 return inner_->get_keep_alive_count();
331 template <
bool IsParent>
336 inner_->print_results(s);
339 template <
bool IsParent>
347 message_queue_->send(&mt,
sizeof(mt), 0);
348 message_queue_->send(s.
c_str(), s.
size(), 0);
351 template <
bool IsParent>
353 template <
bool IsParent>
381 unsigned int priority = 0;
383 buf.
data(), buf.
size(), recvd_size, priority);
386 assert(recvd_size == 1);
390 buf.
data(), buf.
size(), recvd_size, priority);
396 case MessageType::log:
400 case MessageType::test_start:
403 case MessageType::test_end:
414 <<
" reading unit test message queue.\n";
419 std::cerr <<
"Unknown error reading unit test message queue.\n";
437 os_ <<
"\nSuite: " << s
438 <<
" failed to complete. The child process may have crashed.\n";
455 , num_jobs_{num_jobs}
457 , print_log_{!quiet || print_log}
467 while (this->continue_keep_alive_)
473 auto cur_count = this->get_keep_alive_count();
474 if (cur_count == last_count)
478 cur_count = this->get_keep_alive_count();
479 if (cur_count == last_count)
482 std::cerr <<
"multi_runner_child " << job_index_
483 <<
": Assuming parent died, exiting.\n";
487 last_count = cur_count;
573 template class multi_runner_base<true>;
574 template class multi_runner_base<false>;