Unverified Commit cc7f3496 authored by Dominik Charousset's avatar Dominik Charousset Committed by GitHub

Merge pull request #1514

Move legacy tests to proper subfolder
parents 10f1f01f f901e643
...@@ -109,16 +109,16 @@ elseif(MSVC) ...@@ -109,16 +109,16 @@ elseif(MSVC)
target_compile_options(caf_internal INTERFACE /EHsc) target_compile_options(caf_internal INTERFACE /EHsc)
endif() endif()
# -- unit testing setup / caf_add_test_suites function ------------------------ # -- unit testing setup / caf_add_legacy_test_suites function ------------------------
if(CAF_ENABLE_TESTING) if(CAF_ENABLE_TESTING)
enable_testing() enable_testing()
function(caf_add_test_suites target) function(caf_add_legacy_test_suites target)
foreach(suiteName ${ARGN}) foreach(suiteName ${ARGN})
if(NOT ${suiteName} IN_LIST CAF_EXCLUDE_TESTS) if(NOT ${suiteName} IN_LIST CAF_EXCLUDE_TESTS)
string(REPLACE "." "/" suitePath ${suiteName}) string(REPLACE "." "/" suitePath ${suiteName})
target_sources(${target} PRIVATE target_sources(${target} PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/test/${suitePath}.cpp") "${CMAKE_CURRENT_SOURCE_DIR}/tests/legacy/${suitePath}.cpp")
add_test(NAME ${suiteName} add_test(NAME ${suiteName}
COMMAND ${target} -r300 -n -v5 -s "^${suiteName}$") COMMAND ${target} -r300 -n -v5 -s "^${suiteName}$")
endif() endif()
...@@ -313,14 +313,14 @@ endfunction() ...@@ -313,14 +313,14 @@ endfunction()
# ... # ...
# SOURCES # SOURCES
# ... # ...
# TEST_SOURCES # LEGACY_TEST_SOURCES
# ... # ...
# TEST_SUITES # LEGACY_TEST_SUITES
# ... # ...
# ) # )
function(caf_add_component name) function(caf_add_component name)
set(varargs DEPENDENCIES HEADERS SOURCES TEST_SOURCES TEST_SUITES ENUM_TYPES set(varargs DEPENDENCIES HEADERS SOURCES ENUM_TYPES LEGACY_TEST_SOURCES
LEGACY_TEST_SOURCES LEGACY_TEST_SUITES) LEGACY_TEST_SUITES)
cmake_parse_arguments(CAF_ADD_COMPONENT "" "" "${varargs}" ${ARGN}) cmake_parse_arguments(CAF_ADD_COMPONENT "" "" "${varargs}" ${ARGN})
if(NOT CAF_ADD_COMPONENT_HEADERS) if(NOT CAF_ADD_COMPONENT_HEADERS)
message(FATAL_ERROR "Cannot add CAF component without at least one header.") message(FATAL_ERROR "Cannot add CAF component without at least one header.")
...@@ -369,20 +369,6 @@ function(caf_add_component name) ...@@ -369,20 +369,6 @@ function(caf_add_component name)
"${PROJECT_SOURCE_DIR}/cmake/dummy.cpp" "${PROJECT_SOURCE_DIR}/cmake/dummy.cpp"
$<TARGET_OBJECTS:${obj_lib_target}>) $<TARGET_OBJECTS:${obj_lib_target}>)
endif() endif()
if(CAF_ENABLE_TESTING AND CAF_ADD_COMPONENT_TEST_SOURCES)
set(tst_bin_target "caf-${name}-test")
list(APPEND targets ${tst_bin_target})
add_executable(${tst_bin_target}
${CAF_ADD_COMPONENT_TEST_SOURCES}
$<TARGET_OBJECTS:${obj_lib_target}>)
target_link_libraries(${tst_bin_target} PRIVATE libcaf_test
${CAF_ADD_COMPONENT_DEPENDENCIES})
target_include_directories(${tst_bin_target} PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/test")
if(CAF_ADD_COMPONENT_TEST_SUITES)
caf_add_test_suites(${tst_bin_target} ${CAF_ADD_COMPONENT_TEST_SUITES})
endif()
endif()
if(CAF_ENABLE_TESTING AND CAF_ADD_COMPONENT_LEGACY_TEST_SOURCES) if(CAF_ENABLE_TESTING AND CAF_ADD_COMPONENT_LEGACY_TEST_SOURCES)
set(tst_bin_target "caf-${name}-legacy-test") set(tst_bin_target "caf-${name}-legacy-test")
list(APPEND targets ${tst_bin_target}) list(APPEND targets ${tst_bin_target})
...@@ -392,9 +378,9 @@ function(caf_add_component name) ...@@ -392,9 +378,9 @@ function(caf_add_component name)
target_link_libraries(${tst_bin_target} PRIVATE libcaf_test target_link_libraries(${tst_bin_target} PRIVATE libcaf_test
${CAF_ADD_COMPONENT_DEPENDENCIES}) ${CAF_ADD_COMPONENT_DEPENDENCIES})
target_include_directories(${tst_bin_target} PRIVATE target_include_directories(${tst_bin_target} PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/test") "${CMAKE_CURRENT_SOURCE_DIR}/tests/legacy")
if(CAF_ADD_COMPONENT_LEGACY_TEST_SUITES) if(CAF_ADD_COMPONENT_LEGACY_TEST_SUITES)
caf_add_test_suites(${tst_bin_target} ${CAF_ADD_COMPONENT_LEGACY_TEST_SUITES}) caf_add_legacy_test_suites(${tst_bin_target} ${CAF_ADD_COMPONENT_LEGACY_TEST_SUITES})
endif() endif()
endif() endif()
target_link_libraries(${pub_lib_target} ${CAF_ADD_COMPONENT_DEPENDENCIES}) target_link_libraries(${pub_lib_target} ${CAF_ADD_COMPONENT_DEPENDENCIES})
......
...@@ -224,8 +224,8 @@ caf_add_component( ...@@ -224,8 +224,8 @@ caf_add_component(
caf/uri_builder.cpp caf/uri_builder.cpp
caf/uuid.cpp caf/uuid.cpp
LEGACY_TEST_SOURCES LEGACY_TEST_SOURCES
test/core-test.cpp tests/legacy/core-test.cpp
test/nasty.cpp tests/legacy/nasty.cpp
LEGACY_TEST_SUITES LEGACY_TEST_SUITES
action action
actor_clock actor_clock
...@@ -386,5 +386,5 @@ if(NOT CAF_USE_STD_FORMAT) ...@@ -386,5 +386,5 @@ if(NOT CAF_USE_STD_FORMAT)
endif() endif()
if(CAF_ENABLE_TESTING AND CAF_ENABLE_EXCEPTIONS) if(CAF_ENABLE_TESTING AND CAF_ENABLE_EXCEPTIONS)
caf_add_test_suites(caf-core-legacy-test custom_exception_handler) caf_add_legacy_test_suites(caf-core-legacy-test custom_exception_handler)
endif() endif()
// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
#define CAF_SUITE intrusive.drr_cached_queue
#include "caf/intrusive/drr_cached_queue.hpp"
#include "caf/intrusive/singly_linked.hpp"
#include "core-test.hpp"
#include <memory>
using namespace caf;
using namespace caf::intrusive;
namespace {
struct inode : singly_linked<inode> {
int value;
inode(int x = 0) : value(x) {
// nop
}
};
std::string to_string(const inode& x) {
return std::to_string(x.value);
}
struct inode_policy {
using mapped_type = inode;
using task_size_type = int;
using deficit_type = int;
using deleter_type = std::default_delete<mapped_type>;
using unique_pointer = std::unique_ptr<mapped_type, deleter_type>;
static inline task_size_type task_size(const mapped_type&) noexcept {
return 1;
}
};
using queue_type = drr_cached_queue<inode_policy>;
struct fixture {
inode_policy policy;
queue_type queue{policy};
template <class Queue>
void fill(Queue&) {
// nop
}
template <class Queue, class T, class... Ts>
void fill(Queue& q, T x, Ts... xs) {
q.emplace_back(x);
fill(q, xs...);
}
};
auto make_new_round_result(size_t consumed_items, bool stop_all) {
return new_round_result{consumed_items, stop_all};
}
} // namespace
BEGIN_FIXTURE_SCOPE(fixture)
CAF_TEST(default_constructed) {
CAF_REQUIRE_EQUAL(queue.empty(), true);
CAF_REQUIRE_EQUAL(queue.deficit(), 0);
CAF_REQUIRE_EQUAL(queue.total_task_size(), 0);
CAF_REQUIRE_EQUAL(queue.peek(), nullptr);
}
CAF_TEST(new_round) {
// Define a function object for consuming even numbers.
std::string fseq;
auto f = [&](inode& x) -> task_result {
if ((x.value & 0x01) == 1)
return task_result::skip;
fseq += to_string(x);
return task_result::resume;
};
// Define a function object for consuming odd numbers.
std::string gseq;
auto g = [&](inode& x) -> task_result {
if ((x.value & 0x01) == 0)
return task_result::skip;
gseq += to_string(x);
return task_result::resume;
};
fill(queue, 1, 2, 3, 4, 5, 6, 7, 8, 9);
// Allow f to consume 2, 4, and 6.
auto round_result = queue.new_round(3, f);
CHECK_EQ(round_result, make_new_round_result(3, false));
CHECK_EQ(fseq, "246");
CHECK_EQ(queue.deficit(), 0);
// Allow g to consume 1, 3, 5, and 7.
round_result = queue.new_round(4, g);
CHECK_EQ(round_result, make_new_round_result(4, false));
CHECK_EQ(gseq, "1357");
CHECK_EQ(queue.deficit(), 0);
}
CAF_TEST(skipping) {
// Define a function object for consuming even numbers.
std::string seq;
auto f = [&](inode& x) -> task_result {
if ((x.value & 0x01) == 1)
return task_result::skip;
seq += to_string(x);
return task_result::resume;
};
MESSAGE("make a round on an empty queue");
CHECK_EQ(queue.new_round(10, f), make_new_round_result(0, false));
MESSAGE("make a round on a queue with only odd numbers (skip all)");
fill(queue, 1, 3, 5);
CHECK_EQ(queue.new_round(10, f), make_new_round_result(0, false));
MESSAGE("make a round on a queue with an even number at the front");
fill(queue, 2);
CHECK_EQ(queue.new_round(10, f), make_new_round_result(1, false));
CHECK_EQ(seq, "2");
MESSAGE("make a round on a queue with an even number in between");
fill(queue, 7, 9, 4, 11, 13);
CHECK_EQ(queue.new_round(10, f), make_new_round_result(1, false));
CHECK_EQ(seq, "24");
MESSAGE("make a round on a queue with an even number at the back");
fill(queue, 15, 17, 6);
CHECK_EQ(queue.new_round(10, f), make_new_round_result(1, false));
CHECK_EQ(seq, "246");
}
CAF_TEST(take_front) {
std::string seq;
fill(queue, 1, 2, 3, 4, 5, 6);
auto f = [&](inode& x) {
seq += to_string(x);
return task_result::resume;
};
CHECK_EQ(queue.deficit(), 0);
while (!queue.empty()) {
auto ptr = queue.take_front();
f(*ptr);
}
CHECK_EQ(seq, "123456");
fill(queue, 5, 4, 3, 2, 1);
while (!queue.empty()) {
auto ptr = queue.take_front();
f(*ptr);
}
CHECK_EQ(seq, "12345654321");
CHECK_EQ(queue.deficit(), 0);
}
CAF_TEST(alternating_consumer) {
using fun_type = std::function<task_result(inode&)>;
fun_type f;
fun_type g;
fun_type* selected = &f;
// Define a function object for consuming even numbers.
std::string seq;
f = [&](inode& x) -> task_result {
if ((x.value & 0x01) == 1)
return task_result::skip;
seq += to_string(x);
selected = &g;
return task_result::resume;
};
// Define a function object for consuming odd numbers.
g = [&](inode& x) -> task_result {
if ((x.value & 0x01) == 0)
return task_result::skip;
seq += to_string(x);
selected = &f;
return task_result::resume;
};
/// Define a function object that alternates between f and g.
auto h = [&](inode& x) { return (*selected)(x); };
// Fill and consume queue, h leaves 9 in the cache since it reads (odd, even)
// sequences and no odd value to read after 7 is available.
fill(queue, 1, 2, 3, 4, 5, 6, 7, 8, 9);
auto round_result = queue.new_round(1000, h);
CHECK_EQ(round_result, make_new_round_result(8, false));
CHECK_EQ(seq, "21436587");
CHECK_EQ(queue.deficit(), 0);
CHECK_EQ(deep_to_string(queue.cache()), "[9]");
}
CAF_TEST(peek_all) {
auto queue_to_string = [&] {
std::string str;
auto peek_fun = [&](const inode& x) {
if (!str.empty())
str += ", ";
str += std::to_string(x.value);
};
queue.peek_all(peek_fun);
return str;
};
CHECK_EQ(queue_to_string(), "");
queue.emplace_back(2);
CHECK_EQ(queue_to_string(), "2");
queue.cache().emplace_back(1);
CHECK_EQ(queue_to_string(), "2");
queue.emplace_back(3);
CHECK_EQ(queue_to_string(), "2, 3");
queue.flush_cache();
CHECK_EQ(queue_to_string(), "1, 2, 3");
}
CAF_TEST(to_string) {
CHECK_EQ(deep_to_string(queue.items()), "[]");
fill(queue, 3, 4);
CHECK_EQ(deep_to_string(queue.items()), "[3, 4]");
fill(queue.cache(), 1, 2);
CHECK_EQ(deep_to_string(queue.items()), "[3, 4]");
queue.flush_cache();
CHECK_EQ(deep_to_string(queue.items()), "[1, 2, 3, 4]");
}
END_FIXTURE_SCOPE()
// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
#define CAF_SUITE intrusive.drr_queue
#include "caf/intrusive/drr_queue.hpp"
#include "caf/intrusive/singly_linked.hpp"
#include "core-test.hpp"
#include <memory>
using namespace caf;
using namespace caf::intrusive;
namespace {
struct inode : singly_linked<inode> {
int value;
inode(int x = 0) : value(x) {
// nop
}
};
std::string to_string(const inode& x) {
return std::to_string(x.value);
}
struct inode_policy {
using mapped_type = inode;
using task_size_type = int;
using deficit_type = int;
using deleter_type = std::default_delete<mapped_type>;
using unique_pointer = std::unique_ptr<mapped_type, deleter_type>;
static inline task_size_type task_size(const mapped_type& x) {
return x.value;
}
};
using queue_type = drr_queue<inode_policy>;
struct fixture {
inode_policy policy;
queue_type queue{policy};
void fill(queue_type&) {
// nop
}
template <class T, class... Ts>
void fill(queue_type& q, T x, Ts... xs) {
q.emplace_back(x);
fill(q, xs...);
}
};
auto make_new_round_result(size_t consumed_items, bool stop_all) {
return new_round_result{consumed_items, stop_all};
}
} // namespace
BEGIN_FIXTURE_SCOPE(fixture)
CAF_TEST(default_constructed) {
CAF_REQUIRE_EQUAL(queue.empty(), true);
CAF_REQUIRE_EQUAL(queue.deficit(), 0);
CAF_REQUIRE_EQUAL(queue.total_task_size(), 0);
CAF_REQUIRE_EQUAL(queue.peek(), nullptr);
CAF_REQUIRE_EQUAL(queue.next(), nullptr);
CAF_REQUIRE_EQUAL(queue.begin(), queue.end());
}
CAF_TEST(inc_deficit) {
// Increasing the deficit does nothing as long as the queue is empty.
queue.inc_deficit(100);
CAF_REQUIRE_EQUAL(queue.deficit(), 0);
// Increasing the deficit must work on non-empty queues.
fill(queue, 1);
queue.inc_deficit(100);
CAF_REQUIRE_EQUAL(queue.deficit(), 100);
// Deficit must drop back down to 0 once the queue becomes empty.
queue.next();
CAF_REQUIRE_EQUAL(queue.deficit(), 0);
}
CAF_TEST(new_round) {
std::string seq;
fill(queue, 1, 2, 3, 4, 5, 6);
auto f = [&](inode& x) {
seq += to_string(x);
return task_result::resume;
};
// Allow f to consume 1, 2, and 3 with a leftover deficit of 1.
auto round_result = queue.new_round(7, f);
CHECK_EQ(round_result, make_new_round_result(3, false));
CHECK_EQ(seq, "123");
CHECK_EQ(queue.deficit(), 1);
// Allow f to consume 4 and 5 with a leftover deficit of 0.
round_result = queue.new_round(8, f);
CHECK_EQ(round_result, make_new_round_result(2, false));
CHECK_EQ(seq, "12345");
CHECK_EQ(queue.deficit(), 0);
// Allow f to consume 6 with a leftover deficit of 0 (queue is empty).
round_result = queue.new_round(1000, f);
CHECK_EQ(round_result, make_new_round_result(1, false));
CHECK_EQ(seq, "123456");
CHECK_EQ(queue.deficit(), 0);
// new_round on an empty queue does nothing.
round_result = queue.new_round(1000, f);
CHECK_EQ(round_result, make_new_round_result(0, false));
CHECK_EQ(seq, "123456");
CHECK_EQ(queue.deficit(), 0);
}
CAF_TEST(next) {
std::string seq;
fill(queue, 1, 2, 3, 4, 5, 6);
auto f = [&](inode& x) {
seq += to_string(x);
return task_result::resume;
};
auto take = [&] {
queue.flush_cache();
queue.inc_deficit(queue.peek()->value);
return queue.next();
};
while (!queue.empty()) {
auto ptr = take();
f(*ptr);
}
CHECK_EQ(seq, "123456");
fill(queue, 5, 4, 3, 2, 1);
while (!queue.empty()) {
auto ptr = take();
f(*ptr);
}
CHECK_EQ(seq, "12345654321");
CHECK_EQ(queue.deficit(), 0);
}
CAF_TEST(peek_all) {
auto queue_to_string = [&] {
std::string str;
auto peek_fun = [&](const inode& x) {
if (!str.empty())
str += ", ";
str += std::to_string(x.value);
};
queue.peek_all(peek_fun);
return str;
};
CHECK_EQ(queue_to_string(), "");
queue.emplace_back(1);
CHECK_EQ(queue_to_string(), "1");
queue.emplace_back(2);
CHECK_EQ(queue_to_string(), "1, 2");
queue.emplace_back(3);
CHECK_EQ(queue_to_string(), "1, 2, 3");
queue.emplace_back(4);
CHECK_EQ(queue_to_string(), "1, 2, 3, 4");
}
CAF_TEST(to_string) {
CHECK_EQ(deep_to_string(queue), "[]");
fill(queue, 1, 2, 3, 4);
CHECK_EQ(deep_to_string(queue), "[1, 2, 3, 4]");
}
END_FIXTURE_SCOPE()
// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
#define CAF_SUITE intrusive.fifo_inbox
#include "caf/intrusive/fifo_inbox.hpp"
#include "caf/intrusive/drr_queue.hpp"
#include "caf/intrusive/singly_linked.hpp"
#include "core-test.hpp"
#include <memory>
using namespace caf;
using namespace caf::intrusive;
namespace {
struct inode : singly_linked<inode> {
int value;
inode(int x = 0) : value(x) {
// nop
}
};
std::string to_string(const inode& x) {
return std::to_string(x.value);
}
struct inode_policy {
using mapped_type = inode;
using task_size_type = int;
using deficit_type = int;
using deleter_type = std::default_delete<mapped_type>;
using unique_pointer = std::unique_ptr<mapped_type, deleter_type>;
using queue_type = drr_queue<inode_policy>;
static constexpr task_size_type task_size(const inode&) noexcept {
return 1;
}
};
using inbox_type = fifo_inbox<inode_policy>;
struct fixture {
inode_policy policy;
inbox_type inbox{policy};
void fill(inbox_type&) {
// nop
}
template <class T, class... Ts>
void fill(inbox_type& i, T x, Ts... xs) {
i.emplace_back(x);
fill(i, xs...);
}
std::string fetch() {
std::string result;
auto f = [&](inode& x) {
result += to_string(x);
return task_result::resume;
};
inbox.new_round(1000, f);
return result;
}
std::string close_and_fetch() {
std::string result;
auto f = [&](inode& x) {
result += to_string(x);
return task_result::resume;
};
inbox.close();
inbox.queue().new_round(1000, f);
return result;
}
};
} // namespace
BEGIN_FIXTURE_SCOPE(fixture)
CAF_TEST(default_constructed) {
CAF_REQUIRE_EQUAL(inbox.empty(), true);
}
CAF_TEST(push_front) {
fill(inbox, 1, 2, 3);
CAF_REQUIRE_EQUAL(close_and_fetch(), "123");
CAF_REQUIRE_EQUAL(inbox.closed(), true);
}
CAF_TEST(push_after_close) {
inbox.close();
auto res = inbox.push_back(new inode(0));
CAF_REQUIRE_EQUAL(res, inbox_result::queue_closed);
}
CAF_TEST(unblock) {
CAF_REQUIRE_EQUAL(inbox.try_block(), true);
auto res = inbox.push_back(new inode(0));
CAF_REQUIRE_EQUAL(res, inbox_result::unblocked_reader);
res = inbox.push_back(new inode(1));
CAF_REQUIRE_EQUAL(res, inbox_result::success);
CAF_REQUIRE_EQUAL(close_and_fetch(), "01");
}
CAF_TEST(await) {
std::mutex mx;
std::condition_variable cv;
std::thread t{[&] { inbox.synchronized_emplace_back(mx, cv, 1); }};
inbox.synchronized_await(mx, cv);
CAF_REQUIRE_EQUAL(close_and_fetch(), "1");
t.join();
}
CAF_TEST(timed_await) {
std::mutex mx;
std::condition_variable cv;
auto tout = std::chrono::system_clock::now();
tout += std::chrono::microseconds(1);
auto res = inbox.synchronized_await(mx, cv, tout);
CAF_REQUIRE_EQUAL(res, false);
fill(inbox, 1);
res = inbox.synchronized_await(mx, cv, tout);
CAF_REQUIRE_EQUAL(res, true);
CHECK_EQ(fetch(), "1");
tout += std::chrono::hours(1000);
std::thread t{[&] { inbox.synchronized_emplace_back(mx, cv, 2); }};
res = inbox.synchronized_await(mx, cv, tout);
CAF_REQUIRE_EQUAL(res, true);
CAF_REQUIRE_EQUAL(close_and_fetch(), "2");
t.join();
}
END_FIXTURE_SCOPE()
// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
#define CAF_SUITE intrusive.lifo_inbox
#include "caf/intrusive/lifo_inbox.hpp"
#include "caf/intrusive/singly_linked.hpp"
#include "core-test.hpp"
#include <memory>
using namespace caf;
using namespace caf::intrusive;
namespace {
struct inode : singly_linked<inode> {
int value;
inode(int x = 0) : value(x) {
// nop
}
};
std::string to_string(const inode& x) {
return std::to_string(x.value);
}
struct inode_policy {
using mapped_type = inode;
using task_size_type = int;
using deficit_type = int;
using deleter_type = std::default_delete<mapped_type>;
using unique_pointer = std::unique_ptr<mapped_type, deleter_type>;
};
using inbox_type = lifo_inbox<inode_policy>;
struct fixture {
inode_policy policy;
inbox_type inbox;
void fill(inbox_type&) {
// nop
}
template <class T, class... Ts>
void fill(inbox_type& i, T x, Ts... xs) {
i.emplace_front(x);
fill(i, xs...);
}
std::string fetch() {
std::string result;
inode_policy::unique_pointer ptr{inbox.take_head()};
while (ptr != nullptr) {
auto next = ptr->next;
result += to_string(*ptr);
ptr.reset(inbox_type::promote(next));
}
return result;
}
std::string close_and_fetch() {
std::string result;
auto f = [&](inode* x) {
result += to_string(*x);
delete x;
};
inbox.close(f);
return result;
}
};
} // namespace
BEGIN_FIXTURE_SCOPE(fixture)
CAF_TEST(default_constructed) {
CAF_REQUIRE_EQUAL(inbox.empty(), true);
}
CAF_TEST(push_front) {
fill(inbox, 1, 2, 3);
CAF_REQUIRE_EQUAL(close_and_fetch(), "321");
CAF_REQUIRE_EQUAL(inbox.closed(), true);
}
CAF_TEST(push_after_close) {
inbox.close();
auto res = inbox.push_front(new inode(0));
CAF_REQUIRE_EQUAL(res, inbox_result::queue_closed);
}
CAF_TEST(unblock) {
CAF_REQUIRE_EQUAL(inbox.try_block(), true);
auto res = inbox.push_front(new inode(1));
CAF_REQUIRE_EQUAL(res, inbox_result::unblocked_reader);
res = inbox.push_front(new inode(2));
CAF_REQUIRE_EQUAL(res, inbox_result::success);
CAF_REQUIRE_EQUAL(close_and_fetch(), "21");
}
CAF_TEST(await) {
std::mutex mx;
std::condition_variable cv;
std::thread t{[&] { inbox.synchronized_emplace_front(mx, cv, 1); }};
inbox.synchronized_await(mx, cv);
CAF_REQUIRE_EQUAL(close_and_fetch(), "1");
t.join();
}
CAF_TEST(timed_await) {
std::mutex mx;
std::condition_variable cv;
auto tout = std::chrono::system_clock::now();
tout += std::chrono::microseconds(1);
auto res = inbox.synchronized_await(mx, cv, tout);
CAF_REQUIRE_EQUAL(res, false);
fill(inbox, 1);
res = inbox.synchronized_await(mx, cv, tout);
CAF_REQUIRE_EQUAL(res, true);
CHECK_EQ(fetch(), "1");
tout += std::chrono::hours(1000);
std::thread t{[&] { inbox.synchronized_emplace_front(mx, cv, 2); }};
res = inbox.synchronized_await(mx, cv, tout);
CAF_REQUIRE_EQUAL(res, true);
CAF_REQUIRE_EQUAL(close_and_fetch(), "2");
t.join();
}
END_FIXTURE_SCOPE()
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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