Commit a376b31a authored by Dominik Charousset's avatar Dominik Charousset

Make sure unit test output is not messed up

parent 6aea8222
...@@ -9,6 +9,11 @@ using namespace caf; ...@@ -9,6 +9,11 @@ using namespace caf;
namespace { namespace {
atomic<size_t> s_error_count{0}; atomic<size_t> s_error_count{0};
std::mutex s_stdout_mtx;
}
std::mutex& caf_stdout_mtx() {
return s_stdout_mtx;
} }
size_t caf_error_count() { size_t caf_error_count() {
......
#ifndef TEST_HPP #ifndef TEST_HPP
#define TEST_HPP #define TEST_HPP
#include <mutex>
#include <vector> #include <vector>
#include <string> #include <string>
#include <thread> #include <thread>
...@@ -27,6 +28,7 @@ constexpr char to_dev_null[] = ""; ...@@ -27,6 +28,7 @@ constexpr char to_dev_null[] = "";
void set_default_test_settings(); void set_default_test_settings();
std::mutex& caf_stdout_mtx();
size_t caf_error_count(); size_t caf_error_count();
void caf_inc_error_count(); void caf_inc_error_count();
std::string caf_fill4(size_t value); std::string caf_fill4(size_t value);
...@@ -34,37 +36,50 @@ const char* caf_strip_path(const char* file); ...@@ -34,37 +36,50 @@ const char* caf_strip_path(const char* file);
void caf_unexpected_message(const char* file, size_t line, caf::message t); void caf_unexpected_message(const char* file, size_t line, caf::message t);
void caf_unexpected_timeout(const char* file, size_t line); void caf_unexpected_timeout(const char* file, size_t line);
#define CAF_STREAMIFY(fname, line, message) \ #define CAF_STREAMIFY(fname, line, message) \
caf_strip_path(fname) << ":" << caf_fill4(line) << " " << message caf_strip_path(fname) << ":" << caf_fill4(line) << " " << message
#define CAF_PRINTC(filename, linenum, message) \ #define CAF_PRINTC(filename, line, message) \
CAF_LOGF_INFO(CAF_STREAMIFY(filename, linenum, message)); \ CAF_LOGF_INFO(CAF_STREAMIFY(filename, line, message)); \
std::cout << CAF_STREAMIFY(filename, linenum, message) << std::endl { \
std::lock_guard<std::mutex> guard{caf_stdout_mtx()}; \
std::cout << CAF_STREAMIFY(filename, line, message) << std::endl; \
} \
static_cast<void>(0)
#define CAF_PRINT(message) CAF_PRINTC(__FILE__, __LINE__, message) #define CAF_PRINT(message) CAF_PRINTC(__FILE__, __LINE__, message)
#if defined(CAF_LOG_LEVEL) && CAF_LOG_LEVEL > 1 #if defined(CAF_LOG_LEVEL) && CAF_LOG_LEVEL > 1
#define CAF_PRINTERRC(fname, linenum, msg) \ # define CAF_PRINTERRC(fname, line, msg) \
CAF_LOGF_ERROR(CAF_STREAMIFY(fname, linenum, msg)); \ CAF_LOGF_ERROR(CAF_STREAMIFY(fname, line, msg)); \
std::cerr << "ERROR: " << CAF_STREAMIFY(fname, linenum, msg) << std::endl { \
std::lock_guard<std::mutex> guard{caf_stdout_mtx()}; \
std::cerr << "ERROR: " << CAF_STREAMIFY(fname, line, msg) << std::endl; \
} \
static_cast<void>(0)
#else #else
#define CAF_PRINTERRC(fname, linenum, msg) \ # define CAF_PRINTERRC(fname, line, msg) \
std::cerr << "ERROR: " << CAF_STREAMIFY(fname, linenum, msg) << std::endl { \
std::lock_guard<std::mutex> guard{caf_stdout_mtx()}; \
std::cerr << "ERROR: " << CAF_STREAMIFY(fname, line, msg) << std::endl; \
} \
static_cast<void>(0)
#endif #endif
#define CAF_PRINTERR(message) CAF_PRINTERRC(__FILE__, __LINE__, message) #define CAF_PRINTERR(message) CAF_PRINTERRC(__FILE__, __LINE__, message)
template <class T1, typename T2> template <class T1, typename T2>
struct both_integral { struct both_integral {
static constexpr bool value = static constexpr bool value = std::is_integral<T1>::value
std::is_integral<T1>::value && std::is_integral<T2>::value; && std::is_integral<T2>::value;
}; };
template <bool V, typename T1, typename T2> template <bool V, typename T1, typename T2>
struct enable_integral : std::enable_if<both_integral<T1, T2>::value == struct enable_integral
V&& not std::is_pointer<T1>::value&& not : std::enable_if<
std::is_pointer<T2>::value> {}; both_integral<T1, T2>::value == V
&& not std::is_pointer<T1>::value
&& not std::is_pointer<T2>::value> { };
template <class T> template <class T>
const T& caf_stream_arg(const T& value) { const T& caf_stream_arg(const T& value) {
...@@ -99,10 +114,11 @@ inline void caf_failed(const V1& v1, const V2& v2, const char* fname, ...@@ -99,10 +114,11 @@ inline void caf_failed(const V1& v1, const V2& v2, const char* fname,
inline void caf_check_value(const std::string& v1, const std::string& v2, inline void caf_check_value(const std::string& v1, const std::string& v2,
const char* fname, size_t line, const char* fname, size_t line,
bool expected = true) { bool expected = true) {
if ((v1 == v2) == expected) if ((v1 == v2) == expected) {
caf_passed(fname, line); caf_passed(fname, line);
else } else {
caf_failed(v1, v2, fname, line); caf_failed(v1, v2, fname, line);
}
} }
template <class V1, typename V2> template <class V1, typename V2>
...@@ -110,10 +126,11 @@ inline void caf_check_value(const V1& v1, const V2& v2, const char* fname, ...@@ -110,10 +126,11 @@ inline void caf_check_value(const V1& v1, const V2& v2, const char* fname,
size_t line, bool expected = true, size_t line, bool expected = true,
typename enable_integral<false, V1, V2>::type* = typename enable_integral<false, V1, V2>::type* =
0) { 0) {
if (caf::detail::safe_equal(v1, v2) == expected) if (caf::detail::safe_equal(v1, v2) == expected) {
caf_passed(fname, line); caf_passed(fname, line);
else } else {
caf_failed(v1, v2, fname, line); caf_failed(v1, v2, fname, line);
}
} }
template <class V1, typename V2> template <class V1, typename V2>
...@@ -121,13 +138,14 @@ inline void caf_check_value(V1 v1, V2 v2, const char* fname, size_t line, ...@@ -121,13 +138,14 @@ inline void caf_check_value(V1 v1, V2 v2, const char* fname, size_t line,
bool expected = true, bool expected = true,
typename enable_integral<true, V1, V2>::type* = typename enable_integral<true, V1, V2>::type* =
0) { 0) {
if ((v1 == static_cast<V1>(v2)) == expected) if ((v1 == static_cast<V1>(v2)) == expected) {
caf_passed(fname, line); caf_passed(fname, line);
else } else {
caf_failed(v1, v2, fname, line); caf_failed(v1, v2, fname, line);
}
} }
#define CAF_VERBOSE_EVAL(LineOfCode) \ #define CAF_VERBOSE_EVAL(LineOfCode) \
CAF_PRINT(#LineOfCode << " = " << (LineOfCode)); CAF_PRINT(#LineOfCode << " = " << (LineOfCode));
#define CAF_TEST(testname) \ #define CAF_TEST(testname) \
...@@ -144,54 +162,58 @@ inline void caf_check_value(V1 v1, V2 v2, const char* fname, size_t line, ...@@ -144,54 +162,58 @@ inline void caf_check_value(V1 v1, V2 v2, const char* fname, size_t line,
#define CAF_TEST_RESULT() ((caf_error_count() == 0) ? 0 : -1) #define CAF_TEST_RESULT() ((caf_error_count() == 0) ? 0 : -1)
#define CAF_CHECK_VERBOSE(line_of_code, err_stream) \ #define CAF_CHECK_VERBOSE(line_of_code, err_stream) \
if (!(line_of_code)) { \ if (!(line_of_code)) { \
std::cerr << err_stream << std::endl; \ std::cerr << err_stream << std::endl; \
caf_inc_error_count(); \ caf_inc_error_count(); \
} else { \ } else { \
CAF_PRINT("passed"); \ CAF_PRINT("passed"); \
} \ } \
((void)0) ((void)0)
#define CAF_CHECK(line_of_code) \ #define CAF_CHECK(line_of_code) \
if (!(line_of_code)) { \ if (!(line_of_code)) { \
CAF_PRINTERR(#line_of_code); \ CAF_PRINTERR(#line_of_code); \
caf_inc_error_count(); \ caf_inc_error_count(); \
} else { \ } else { \
CAF_PRINT("passed"); \ CAF_PRINT("passed"); \
} \ } \
CAF_VOID_STMT static_cast<void>(0)
#define CAF_CHECK_EQUAL(lhs_loc, rhs_loc) \ #define CAF_CHECK_EQUAL(lhs_loc, rhs_loc) \
caf_check_value((lhs_loc), (rhs_loc), __FILE__, __LINE__) caf_check_value((lhs_loc), (rhs_loc), __FILE__, __LINE__)
#define CAF_CHECK_NOT_EQUAL(rhs_loc, lhs_loc) \ #define CAF_CHECK_NOT_EQUAL(rhs_loc, lhs_loc) \
caf_check_value((lhs_loc), (rhs_loc), __FILE__, __LINE__, false) caf_check_value((lhs_loc), (rhs_loc), __FILE__, __LINE__, false)
#define CAF_FAILURE(err_msg) \ #define CAF_FAILURE(err_msg) \
{ \ { \
CAF_PRINTERR("ERROR: " << err_msg); \ CAF_PRINTERR("ERROR: " << err_msg); \
caf_inc_error_count(); \ caf_inc_error_count(); \
} \ } \
((void)0) static_cast<void>(0)
#define CAF_CHECKPOINT() CAF_PRINT("passed") #define CAF_CHECKPOINT() CAF_PRINT("passed")
#define CAF_UNEXPECTED_TOUT() caf_unexpected_timeout(__FILE__, __LINE__) #define CAF_UNEXPECTED_TOUT() caf_unexpected_timeout(__FILE__, __LINE__)
#define CAF_UNEXPECTED_MSG(selfptr) \ #define CAF_UNEXPECTED_MSG(selfptr) \
caf_unexpected_message(__FILE__, __LINE__, selfptr->last_dequeued()) caf_unexpected_message(__FILE__, __LINE__, selfptr->last_dequeued())
// some convenience macros for defining callbacks // some convenience macros for defining callbacks
#define CAF_CHECKPOINT_CB() \ #define CAF_CHECKPOINT_CB() \
[] { CAF_CHECKPOINT(); } [] { CAF_CHECKPOINT(); }
#define CAF_FAILURE_CB(err_msg) \
#define CAF_FAILURE_CB(err_msg) \
[] { CAF_FAILURE(err_msg); } [] { CAF_FAILURE(err_msg); }
#define CAF_UNEXPECTED_MSG_CB(selfptr) \
#define CAF_UNEXPECTED_MSG_CB(selfptr) \
[=] { CAF_UNEXPECTED_MSG(selfptr); } [=] { CAF_UNEXPECTED_MSG(selfptr); }
#define CAF_UNEXPECTED_MSG_CB_REF(selfref) \
#define CAF_UNEXPECTED_MSG_CB_REF(selfref) \
[&] { CAF_UNEXPECTED_MSG(selfref); } [&] { CAF_UNEXPECTED_MSG(selfref); }
#define CAF_UNEXPECTED_TOUT_CB() \
#define CAF_UNEXPECTED_TOUT_CB() \
[] { CAF_UNEXPECTED_TOUT(); } [] { CAF_UNEXPECTED_TOUT(); }
// string projection // string projection
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment