Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
5ea3e4ac
Commit
5ea3e4ac
authored
Aug 02, 2018
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/dsl-redesign'
parents
254e30c6
d5ee300e
Changes
27
Hide whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
473 additions
and
324 deletions
+473
-324
libcaf_core/caf/config.hpp
libcaf_core/caf/config.hpp
+5
-5
libcaf_core/caf/detail/stringification_inspector.hpp
libcaf_core/caf/detail/stringification_inspector.hpp
+18
-0
libcaf_core/caf/detail/test_actor_clock.hpp
libcaf_core/caf/detail/test_actor_clock.hpp
+21
-7
libcaf_core/caf/ipv4_address.hpp
libcaf_core/caf/ipv4_address.hpp
+5
-0
libcaf_core/caf/scheduler/test_coordinator.hpp
libcaf_core/caf/scheduler/test_coordinator.hpp
+23
-21
libcaf_core/src/ipv4_address.cpp
libcaf_core/src/ipv4_address.cpp
+6
-0
libcaf_core/src/stringification_inspector.cpp
libcaf_core/src/stringification_inspector.cpp
+33
-0
libcaf_core/src/test_actor_clock.cpp
libcaf_core/src/test_actor_clock.cpp
+26
-5
libcaf_core/src/test_coordinator.cpp
libcaf_core/src/test_coordinator.cpp
+13
-41
libcaf_core/src/tick_emitter.cpp
libcaf_core/src/tick_emitter.cpp
+3
-1
libcaf_core/test/continuous_streaming.cpp
libcaf_core/test/continuous_streaming.cpp
+11
-12
libcaf_core/test/deep_to_string.cpp
libcaf_core/test/deep_to_string.cpp
+33
-0
libcaf_core/test/fused_streaming.cpp
libcaf_core/test/fused_streaming.cpp
+2
-3
libcaf_core/test/ipv4_address.cpp
libcaf_core/test/ipv4_address.cpp
+3
-8
libcaf_core/test/ipv4_subnet.cpp
libcaf_core/test/ipv4_subnet.cpp
+1
-3
libcaf_core/test/ipv6_address.cpp
libcaf_core/test/ipv6_address.cpp
+5
-4
libcaf_core/test/ipv6_subnet.cpp
libcaf_core/test/ipv6_subnet.cpp
+1
-1
libcaf_core/test/pipeline_streaming.cpp
libcaf_core/test/pipeline_streaming.cpp
+11
-12
libcaf_core/test/read_ini.cpp
libcaf_core/test/read_ini.cpp
+1
-1
libcaf_core/test/request_timeout.cpp
libcaf_core/test/request_timeout.cpp
+26
-50
libcaf_core/test/selective_streaming.cpp
libcaf_core/test/selective_streaming.cpp
+4
-5
libcaf_core/test/simple_timeout.cpp
libcaf_core/test/simple_timeout.cpp
+6
-29
libcaf_io/test/basp_udp.cpp
libcaf_io/test/basp_udp.cpp
+2
-2
libcaf_test/caf/test/dsl.hpp
libcaf_test/caf/test/dsl.hpp
+141
-58
libcaf_test/caf/test/io_dsl.hpp
libcaf_test/caf/test/io_dsl.hpp
+67
-50
libcaf_test/caf/test/unit_test.hpp
libcaf_test/caf/test/unit_test.hpp
+5
-5
libcaf_test/caf/test/unit_test_impl.hpp
libcaf_test/caf/test/unit_test_impl.hpp
+1
-1
No files found.
libcaf_core/caf/config.hpp
View file @
5ea3e4ac
...
...
@@ -116,7 +116,7 @@
# define CAF_UNLIKELY(x) __builtin_expect((x), 0)
# define CAF_DEPRECATED __attribute__((deprecated))
# define CAF_DEPRECATED_MSG(msg) __attribute__((deprecated(msg)))
# define CAF_PUSH_WARNINGS
# define CAF_PUSH_WARNINGS
\
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wshadow\"") \
_Pragma("GCC diagnostic ignored \"-Wpragmas\"") \
...
...
@@ -220,10 +220,10 @@
# define CAF_POSIX
#endif
#if defined(CAF_WINDOWS)
# if defined(__clang__)
struct
IUnknown
;
// fix for issue with static_cast<> in objbase.h (see https://github.com/philsquared/Catch/issues/690)
# endif
#if defined(CAF_WINDOWS)
&& defined(CAF_CLANG)
// Fix for issue with static_cast<> in objbase.h.
// See: https://github.com/philsquared/Catch/issues/690.
struct
IUnknown
;
#endif
#include <cstdio>
...
...
libcaf_core/caf/detail/stringification_inspector.hpp
View file @
5ea3e4ac
...
...
@@ -28,6 +28,8 @@
#include "caf/error.hpp"
#include "caf/none.hpp"
#include "caf/string_view.hpp"
#include "caf/timespan.hpp"
#include "caf/timestamp.hpp"
#include "caf/meta/type_name.hpp"
#include "caf/meta/omittable.hpp"
...
...
@@ -76,6 +78,22 @@ public:
void
consume
(
string_view
str
);
void
consume
(
timespan
&
x
);
void
consume
(
timestamp
&
x
);
template
<
class
Clock
,
class
Duration
>
void
consume
(
std
::
chrono
::
time_point
<
Clock
,
Duration
>&
x
)
{
timestamp
tmp
{
std
::
chrono
::
duration_cast
<
timespan
>
(
x
.
time_since_epoch
())};
consume
(
tmp
);
}
template
<
class
Rep
,
class
Period
>
void
consume
(
std
::
chrono
::
duration
<
Rep
,
Period
>&
x
)
{
auto
tmp
=
std
::
chrono
::
duration_cast
<
timespan
>
(
x
);
consume
(
tmp
);
}
inline
void
consume
(
bool
&
x
)
{
result_
+=
x
?
"true"
:
"false"
;
}
...
...
libcaf_core/caf/detail/test_actor_clock.hpp
View file @
5ea3e4ac
...
...
@@ -34,16 +34,30 @@ public:
duration_type
difference
(
atom_value
measurement
,
long
units
,
time_point
t0
,
time_point
t1
)
const
noexcept
override
;
/// Tries to dispatch the next timeout or delayed message regardless of its
/// timestamp. Returns `false` if `schedule().empty()`, otherwise `true`.
bool
dispatch_once
();
/// Returns whether the actor clock has at least one pending timeout.
bool
has_pending_timeout
()
const
{
return
!
schedule_
.
empty
();
}
/// Dispatches all timeouts and delayed messages regardless of their
/// timestamp. Returns the number of dispatched events.
size_t
dispatch
();
/// Triggers the next pending timeout regardless of its timestamp. Sets
/// `current_time` to the time point of the triggered timeout unless
/// `current_time` is already set to a later time.
/// @returns Whether a timeout was triggered.
bool
trigger_timeout
();
/// Triggers all pending timeouts regardless of their timestamp. Sets
/// `current_time` to the time point of the latest timeout unless
/// `current_time` is already set to a later time.
/// @returns The number of triggered timeouts.
size_t
trigger_timeouts
();
/// Triggers all timeouts with timestamp <= now.
/// @returns The number of triggered timeouts.
size_t
trigger_expired_timeouts
();
/// Advances the time by `x` and dispatches timeouts and delayed messages.
void
advance_time
(
duration_type
x
);
/// @returns The number of triggered timeouts.
size_t
advance_time
(
duration_type
x
);
/// Configures the returned value for `difference`. For example, inserting
/// `('foo', 120ns)` causes the clock to return `units * 120ns` for any call
...
...
libcaf_core/caf/ipv4_address.hpp
View file @
5ea3e4ac
...
...
@@ -108,6 +108,11 @@ private:
// -- related free functions ---------------------------------------------------
/// Convenience function for creating an IPv4 address from octets.
/// @relates ipv4_address
ipv4_address
make_ipv4_address
(
uint8_t
oct1
,
uint8_t
oct2
,
uint8_t
oct3
,
uint8_t
oct4
);
/// Returns a human-readable string representation of the address.
/// @relates ipv4_address
std
::
string
to_string
(
const
ipv4_address
&
x
);
...
...
libcaf_core/caf/scheduler/test_coordinator.hpp
View file @
5ea3e4ac
...
...
@@ -38,14 +38,14 @@ class test_coordinator : public abstract_coordinator {
public:
using
super
=
abstract_coordinator
;
/// A type-erased boolean predicate.
using
bool_predicate
=
std
::
function
<
bool
()
>
;
test_coordinator
(
actor_system
&
sys
);
/// A double-ended queue representing our current job queue.
std
::
deque
<
resumable
*>
jobs
;
/// A clock type using the highest available precision.
using
hrc
=
std
::
chrono
::
high_resolution_clock
;
/// Returns whether at least one job is in the queue.
inline
bool
has_job
()
const
{
return
!
jobs
.
empty
();
...
...
@@ -105,25 +105,25 @@ public:
/// left. Returns the number of processed events.
size_t
run
(
size_t
max_count
=
std
::
numeric_limits
<
size_t
>::
max
());
/// Tries to dispatch a single delayed message.
bool
dispatch_once
();
/// Returns whether at least one pending timeout exists.
bool
has_pending_timeout
()
const
{
return
clock_
.
has_pending_timeout
();
}
/// Dispatches all pending delayed messages. Returns the number of dispatched
/// messages.
size_t
dispatch
();
/// Tries to trigger a single timeout.
bool
trigger_timeout
()
{
return
clock_
.
trigger_timeout
();
}
/// Loops until no job or delayed message remains or `predicate` returns
/// `true`. Returns the total number of events (first) and dispatched delayed
/// messages (second). Advances time by `cycle` nanoseconds between to calls
/// to `dispatch()` or the default tick-duration when passing 0ns.
std
::
pair
<
size_t
,
size_t
>
run_dispatch_loop
(
std
::
function
<
bool
()
>
predicate
,
timespan
cycle
=
timespan
{
0
});
/// Triggers all pending timeouts.
size_t
trigger_timeouts
()
{
return
clock_
.
trigger_timeouts
();
}
/// Loops until no job or delayed message remains. Returns the total number
/// of events (first) and dispatched delayed messages (second). Advances time
/// by `cycle` nanoseconds between to calls to `dispatch()` or the default
/// tick-duration when passing 0ns.
std
::
pair
<
size_t
,
size_t
>
run_dispatch_loop
(
timespan
cycle
=
timespan
{
0
});
/// Advances simulation time and returns the number of triggered timeouts.
size_t
advance_time
(
timespan
x
)
{
return
clock_
.
advance_time
(
x
);
}
template
<
class
F
>
void
after_next_enqueue
(
F
f
)
{
...
...
@@ -142,6 +142,10 @@ public:
detail
::
test_actor_clock
&
clock
()
noexcept
override
;
std
::
pair
<
size_t
,
size_t
>
run_dispatch_loop
(
timespan
cycle_duration
=
timespan
{
1
})
CAF_DEPRECATED_MSG
(
"use the testing DSL's run() instead"
);
protected:
void
start
()
override
;
...
...
@@ -161,5 +165,3 @@ private:
}
// namespace scheduler
}
// namespace caf
libcaf_core/src/ipv4_address.cpp
View file @
5ea3e4ac
...
...
@@ -71,6 +71,12 @@ bool ipv4_address::is_multicast() const noexcept {
// -- related free functions ---------------------------------------------------
ipv4_address
make_ipv4_address
(
uint8_t
oct1
,
uint8_t
oct2
,
uint8_t
oct3
,
uint8_t
oct4
)
{
ipv4_address
::
array_type
bytes
{{
oct1
,
oct2
,
oct3
,
oct4
}};
return
ipv4_address
{
bytes
};
}
std
::
string
to_string
(
const
ipv4_address
&
x
)
{
using
std
::
to_string
;
std
::
string
result
;
...
...
libcaf_core/src/stringification_inspector.cpp
View file @
5ea3e4ac
...
...
@@ -18,6 +18,8 @@
#include "caf/detail/stringification_inspector.hpp"
#include <ctime>
namespace
caf
{
namespace
detail
{
...
...
@@ -67,5 +69,36 @@ void stringification_inspector::consume(string_view str) {
result_
+=
'"'
;
}
void
stringification_inspector
::
consume
(
timespan
&
x
)
{
auto
count
=
x
.
count
();
auto
res
=
[
&
](
const
char
*
suffix
)
{
result_
+=
std
::
to_string
(
count
);
result_
+=
suffix
;
};
// Check whether it's nano-, micro-, or milliseconds.
for
(
auto
suffix
:
{
"ns"
,
"us"
,
"ms"
})
{
if
(
count
%
1000
!=
0
)
return
res
(
suffix
);
count
/=
1000
;
}
// After the loop we only need to differentiate between seconds and minutes.
if
(
count
%
60
!=
0
)
return
res
(
"s"
);
count
/=
60
;
return
res
(
"min"
);
}
void
stringification_inspector
::
consume
(
timestamp
&
x
)
{
char
buf
[
64
];
auto
y
=
std
::
chrono
::
time_point_cast
<
timestamp
::
clock
::
duration
>
(
x
);
auto
z
=
timestamp
::
clock
::
to_time_t
(
y
);
strftime
(
buf
,
sizeof
(
buf
),
"%FT%T"
,
std
::
localtime
(
&
z
));
result_
+=
buf
;
// time_t has no milliseconds, so we need to insert them manually.
auto
ms
=
(
x
.
time_since_epoch
().
count
()
/
1000000
)
%
1000
;
result_
+=
'.'
;
result_
+=
std
::
to_string
(
ms
);
}
}
// namespace detail
}
// namespace caf
libcaf_core/src/test_actor_clock.cpp
View file @
5ea3e4ac
...
...
@@ -18,6 +18,8 @@
#include "caf/detail/test_actor_clock.hpp"
#include "caf/logger.hpp"
namespace
caf
{
namespace
detail
{
...
...
@@ -40,35 +42,54 @@ test_actor_clock::difference(atom_value measurement, long units, time_point t0,
return
t0
==
t1
?
duration_type
{
1
}
:
t1
-
t0
;
}
bool
test_actor_clock
::
dispatch_once
()
{
bool
test_actor_clock
::
trigger_timeout
()
{
CAF_LOG_TRACE
(
CAF_ARG2
(
"schedule.size"
,
schedule_
.
size
()));
if
(
schedule_
.
empty
())
return
false
;
visitor
f
{
this
};
auto
i
=
schedule_
.
begin
();
auto
tout
=
i
->
first
;
if
(
tout
>
current_time
)
current_time
=
tout
;
visit
(
f
,
i
->
second
);
schedule_
.
erase
(
i
);
return
true
;
}
size_t
test_actor_clock
::
dispatch
()
{
size_t
test_actor_clock
::
trigger_timeouts
()
{
CAF_LOG_TRACE
(
CAF_ARG2
(
"schedule.size"
,
schedule_
.
size
()));
if
(
schedule_
.
empty
())
return
0u
;
visitor
f
{
this
};
auto
result
=
schedule_
.
size
();
for
(
auto
&
kvp
:
schedule_
)
for
(
auto
&
kvp
:
schedule_
)
{
auto
tout
=
kvp
.
first
;
if
(
tout
>
current_time
)
current_time
=
tout
;
visit
(
f
,
kvp
.
second
);
}
schedule_
.
clear
();
return
result
;
}
void
test_actor_clock
::
advance_time
(
duration_type
x
)
{
size_t
test_actor_clock
::
trigger_expired_timeouts
()
{
CAF_LOG_TRACE
(
CAF_ARG2
(
"schedule.size"
,
schedule_
.
size
()));
visitor
f
{
this
};
current_time
+=
x
;
size_t
result
=
0
;
auto
i
=
schedule_
.
begin
();
while
(
i
!=
schedule_
.
end
()
&&
i
->
first
<=
current_time
)
{
++
result
;
visit
(
f
,
i
->
second
);
i
=
schedule_
.
erase
(
i
);
}
return
result
;
}
size_t
test_actor_clock
::
advance_time
(
duration_type
x
)
{
CAF_LOG_TRACE
(
CAF_ARG
(
x
)
<<
CAF_ARG2
(
"schedule.size"
,
schedule_
.
size
()));
CAF_ASSERT
(
x
.
count
()
>=
0
);
current_time
+=
x
;
return
trigger_expired_timeouts
();
}
}
// namespace detail
...
...
libcaf_core/src/test_coordinator.cpp
View file @
5ea3e4ac
...
...
@@ -87,7 +87,8 @@ void test_coordinator::start() {
}
void
test_coordinator
::
stop
()
{
run_dispatch_loop
();
while
(
run
()
>
0
)
trigger_timeouts
();
}
void
test_coordinator
::
enqueue
(
resumable
*
ptr
)
{
...
...
@@ -147,46 +148,6 @@ size_t test_coordinator::run(size_t max_count) {
return
res
;
}
bool
test_coordinator
::
dispatch_once
()
{
return
clock
().
dispatch_once
();
}
size_t
test_coordinator
::
dispatch
()
{
return
clock
().
dispatch
();
}
std
::
pair
<
size_t
,
size_t
>
test_coordinator
::
run_dispatch_loop
(
std
::
function
<
bool
()
>
predicate
,
timespan
cycle
)
{
std
::
pair
<
size_t
,
size_t
>
res
{
0
,
0
};
if
(
cycle
.
count
()
==
0
)
{
auto
x
=
system
().
config
().
streaming_tick_duration_us
();
cycle
=
std
::
chrono
::
microseconds
(
x
);
}
for
(;;)
{
size_t
progress
=
0
;
while
(
try_run_once
())
{
++
progress
;
res
.
first
+=
1
;
if
(
predicate
())
return
res
;
}
clock
().
current_time
+=
cycle
;
while
(
dispatch_once
())
{
++
progress
;
res
.
second
+=
1
;
if
(
predicate
())
return
res
;
}
if
(
progress
==
0
)
return
res
;
}
}
std
::
pair
<
size_t
,
size_t
>
test_coordinator
::
run_dispatch_loop
(
timespan
cycle
)
{
return
run_dispatch_loop
([]
{
return
false
;
},
cycle
);
}
void
test_coordinator
::
inline_next_enqueue
()
{
after_next_enqueue
([
=
]
{
run_once_lifo
();
});
}
...
...
@@ -200,6 +161,17 @@ void test_coordinator::inline_all_enqueues_helper() {
after_next_enqueue
([
=
]
{
inline_all_enqueues_helper
();
});
}
std
::
pair
<
size_t
,
size_t
>
test_coordinator
::
run_dispatch_loop
(
timespan
cycle_duration
)
{
size_t
messages
=
0
;
size_t
timeouts
=
0
;
while
(
has_job
()
||
has_pending_timeout
())
{
messages
+=
run
();
timeouts
+=
advance_time
(
cycle_duration
);
}
return
{
messages
,
timeouts
};
}
}
// namespace caf
}
// namespace scheduler
libcaf_core/src/tick_emitter.cpp
View file @
5ea3e4ac
...
...
@@ -56,7 +56,9 @@ void tick_emitter::interval(duration_type x) {
size_t
tick_emitter
::
timeouts
(
time_point
now
,
std
::
initializer_list
<
size_t
>
periods
)
{
CAF_LOG_TRACE
(
CAF_ARG
(
now
)
<<
CAF_ARG
(
periods
));
CAF_LOG_TRACE
(
CAF_ARG
(
now
)
<<
CAF_ARG
(
periods
)
<<
CAF_ARG
(
interval_
)
<<
CAF_ARG
(
start_
));
CAF_ASSERT
(
now
>=
start_
);
size_t
result
=
0
;
auto
f
=
[
&
](
size_t
tick
)
{
size_t
n
=
0
;
...
...
libcaf_core/test/continuous_streaming.cpp
View file @
5ea3e4ac
...
...
@@ -166,14 +166,14 @@ CAF_TEST(depth_3_pipeline_with_fork) {
CAF_MESSAGE
(
"connect sinks to the stage (fork)"
);
self
->
send
(
snk1
,
join_atom
::
value
,
stg
);
self
->
send
(
snk2
,
join_atom
::
value
,
stg
);
sched
.
run
();
consume_messages
();
CAF_CHECK_EQUAL
(
st
.
stage
->
out
().
num_paths
(),
2u
);
CAF_MESSAGE
(
"connect source to the stage (fork)"
);
self
->
send
(
stg
*
src
,
"numbers.txt"
);
sched
.
run
();
consume_messages
();
CAF_CHECK_EQUAL
(
st
.
stage
->
out
().
num_paths
(),
2u
);
CAF_CHECK_EQUAL
(
st
.
stage
->
inbound_paths
().
size
(),
1u
);
run
_exhaustively
();
run
();
CAF_CHECK_EQUAL
(
st
.
stage
->
out
().
num_paths
(),
2u
);
CAF_CHECK_EQUAL
(
st
.
stage
->
inbound_paths
().
size
(),
0u
);
CAF_CHECK_EQUAL
(
deref
<
sum_up_actor
>
(
snk1
).
state
.
x
,
1275
);
...
...
@@ -189,15 +189,15 @@ CAF_TEST(depth_3_pipeline_with_join) {
auto
&
st
=
deref
<
stream_multiplexer_actor
>
(
stg
).
state
;
CAF_MESSAGE
(
"connect sink to the stage"
);
self
->
send
(
snk
,
join_atom
::
value
,
stg
);
sched
.
run
();
consume_messages
();
CAF_CHECK_EQUAL
(
st
.
stage
->
out
().
num_paths
(),
1u
);
CAF_MESSAGE
(
"connect sources to the stage (join)"
);
self
->
send
(
stg
*
src1
,
"numbers.txt"
);
self
->
send
(
stg
*
src2
,
"numbers.txt"
);
sched
.
run
();
consume_messages
();
CAF_CHECK_EQUAL
(
st
.
stage
->
out
().
num_paths
(),
1u
);
CAF_CHECK_EQUAL
(
st
.
stage
->
inbound_paths
().
size
(),
2u
);
run
_exhaustively
();
run
();
CAF_CHECK_EQUAL
(
st
.
stage
->
out
().
num_paths
(),
1u
);
CAF_CHECK_EQUAL
(
st
.
stage
->
inbound_paths
().
size
(),
0u
);
CAF_CHECK_EQUAL
(
deref
<
sum_up_actor
>
(
snk
).
state
.
x
,
2550
);
...
...
@@ -213,17 +213,16 @@ CAF_TEST(closing_downstreams_before_end_of_stream) {
CAF_MESSAGE
(
"connect sinks to the stage (fork)"
);
self
->
send
(
snk1
,
join_atom
::
value
,
stg
);
self
->
send
(
snk2
,
join_atom
::
value
,
stg
);
sched
.
run
();
consume_messages
();
CAF_CHECK_EQUAL
(
st
.
stage
->
out
().
num_paths
(),
2u
);
CAF_MESSAGE
(
"connect source to the stage (fork)"
);
self
->
send
(
stg
*
src
,
"numbers.txt"
);
sched
.
run
();
consume_messages
();
CAF_CHECK_EQUAL
(
st
.
stage
->
out
().
num_paths
(),
2u
);
CAF_CHECK_EQUAL
(
st
.
stage
->
inbound_paths
().
size
(),
1u
);
CAF_MESSAGE
(
"do a single round of credit"
);
sched
.
clock
().
current_time
+=
streaming_cycle
;
sched
.
dispatch
();
sched
.
run
();
trigger_timeouts
();
consume_messages
();
CAF_MESSAGE
(
"make sure the stream isn't done yet"
);
CAF_REQUIRE
(
!
deref
<
file_reader_actor
>
(
src
).
state
.
buf
.
empty
());
CAF_CHECK_EQUAL
(
st
.
stage
->
out
().
num_paths
(),
2u
);
...
...
@@ -236,7 +235,7 @@ CAF_TEST(closing_downstreams_before_end_of_stream) {
self
->
send
(
stg
,
close_atom
::
value
,
0
);
expect
((
atom_value
,
int
),
from
(
self
).
to
(
stg
));
CAF_MESSAGE
(
"ship remaining elements"
);
run
_exhaustively
();
run
();
CAF_CHECK_EQUAL
(
st
.
stage
->
out
().
num_paths
(),
1u
);
CAF_CHECK_EQUAL
(
st
.
stage
->
inbound_paths
().
size
(),
0u
);
CAF_CHECK_LESS
(
deref
<
sum_up_actor
>
(
snk1
).
state
.
x
,
sink1_result
);
...
...
libcaf_core/test/deep_to_string.cpp
0 → 100644
View file @
5ea3e4ac
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#define CAF_SUITE deep_to_string
#include "caf/deep_to_string.hpp"
#include "caf/test/dsl.hpp"
using
namespace
caf
;
CAF_TEST
(
timespans
)
{
CAF_CHECK_EQUAL
(
deep_to_string
(
timespan
{
1
}),
"1ns"
);
CAF_CHECK_EQUAL
(
deep_to_string
(
timespan
{
1000
}),
"1us"
);
CAF_CHECK_EQUAL
(
deep_to_string
(
timespan
{
1000000
}),
"1ms"
);
CAF_CHECK_EQUAL
(
deep_to_string
(
timespan
{
1000000000
}),
"1s"
);
CAF_CHECK_EQUAL
(
deep_to_string
(
timespan
{
60000000000
}),
"1min"
);
}
libcaf_core/test/fused_streaming.cpp
View file @
5ea3e4ac
...
...
@@ -279,10 +279,9 @@ CAF_TEST(depth_3_pipeline_with_fork) {
sched
.
run
();
CAF_CHECK_EQUAL
(
st
.
stage
->
out
().
num_paths
(),
2u
);
CAF_CHECK_EQUAL
(
st
.
stage
->
inbound_paths
().
size
(),
2u
);
auto
predicate
=
[
&
]
{
run_until
(
[
&
]
{
return
st
.
stage
->
inbound_paths
().
empty
()
&&
st
.
stage
->
out
().
clean
();
};
sched
.
run_dispatch_loop
(
predicate
,
streaming_cycle
);
});
CAF_CHECK_EQUAL
(
st
.
stage
->
out
().
num_paths
(),
2u
);
CAF_CHECK_EQUAL
(
st
.
stage
->
inbound_paths
().
size
(),
0u
);
CAF_CHECK_EQUAL
(
deref
<
sum_up_actor
>
(
snk1
).
state
.
x
,
1275
);
...
...
libcaf_core/test/ipv4_address.cpp
View file @
5ea3e4ac
...
...
@@ -31,20 +31,15 @@ using namespace caf;
namespace
{
using
array_type
=
ipv4_address
::
array_type
;
ipv4_address
addr
(
uint8_t
oct1
,
uint8_t
oct2
,
uint8_t
oct3
,
uint8_t
oct4
)
{
return
ipv4_address
({
oct1
,
oct2
,
oct3
,
oct4
});
}
const
auto
addr
=
make_ipv4_address
;
}
// namespace <anonymous>
CAF_TEST
(
constructing
)
{
ipv4_address
localhost
({
127
,
0
,
0
,
1
}
);
auto
localhost
=
addr
(
127
,
0
,
0
,
1
);
CAF_CHECK_EQUAL
(
localhost
.
bits
(),
to_network_order
(
0x7F000001u
));
CAF_CHECK_EQUAL
(
localhost
.
data
(),
array_type
({
127
,
0
,
0
,
1
}));
ipv4_address
zero
;
CAF_CHECK_EQUAL
(
zero
.
data
(),
array_type
({
0
,
0
,
0
,
0
})
);
CAF_CHECK_EQUAL
(
zero
.
bits
(),
0u
);
}
CAF_TEST
(
to
and
from
string
)
{
...
...
libcaf_core/test/ipv4_subnet.cpp
View file @
5ea3e4ac
...
...
@@ -27,9 +27,7 @@ using namespace caf;
namespace
{
ipv4_address
addr
(
uint8_t
oct1
,
uint8_t
oct2
,
uint8_t
oct3
,
uint8_t
oct4
)
{
return
ipv4_address
({
oct1
,
oct2
,
oct3
,
oct4
});
}
const
auto
addr
=
make_ipv4_address
;
ipv4_subnet
operator
/
(
ipv4_address
addr
,
uint8_t
prefix
)
{
return
{
addr
,
prefix
};
...
...
libcaf_core/test/ipv6_address.cpp
View file @
5ea3e4ac
...
...
@@ -40,9 +40,10 @@ ipv6_address addr(std::initializer_list<uint16_t> prefix,
}
// namespace <anonymous>
CAF_TEST
(
constructing
)
{
ipv6_address
localhost
({
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
1
});
CAF_CHECK_EQUAL
(
localhost
.
data
(),
array_type
({
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
1
}));
ipv6_address
::
array_type
localhost_bytes
{{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
1
}};
ipv6_address
localhost
{
localhost_bytes
};
CAF_CHECK_EQUAL
(
localhost
.
data
(),
localhost_bytes
);
CAF_CHECK_EQUAL
(
localhost
,
addr
({},
{
0x01
}));
}
...
...
@@ -50,7 +51,7 @@ CAF_TEST(comparison) {
CAF_CHECK_EQUAL
(
addr
({
1
,
2
,
3
}),
addr
({
1
,
2
,
3
}));
CAF_CHECK_NOT_EQUAL
(
addr
({
3
,
2
,
1
}),
addr
({
1
,
2
,
3
}));
CAF_CHECK_EQUAL
(
addr
({},
{
0xFFFF
,
0x7F00
,
0x0001
}),
ipv4_address
({
127
,
0
,
0
,
1
}
));
make_ipv4_address
(
127
,
0
,
0
,
1
));
}
CAF_TEST
(
from
string
)
{
...
...
libcaf_core/test/ipv6_subnet.cpp
View file @
5ea3e4ac
...
...
@@ -46,7 +46,7 @@ CAF_TEST(constains) {
}
CAF_TEST
(
embedding
)
{
ipv4_subnet
v4_local
{
ipv4_address
({
127
,
0
,
0
,
1
}
),
8
};
ipv4_subnet
v4_local
{
make_ipv4_address
(
127
,
0
,
0
,
1
),
8
};
ipv6_subnet
local
{
v4_local
};
CAF_CHECK
(
local
.
embeds_v4
());
CAF_CHECK_EQUAL
(
local
.
prefix_length
(),
104u
);
...
...
libcaf_core/test/pipeline_streaming.cpp
View file @
5ea3e4ac
...
...
@@ -211,7 +211,11 @@ TESTEE(doubler) {
};
}
using
fixture
=
test_coordinator_fixture
<>
;
struct
fixture
:
test_coordinator_fixture
<>
{
void
tick
()
{
advance_time
(
cfg
.
streaming_credit_round_interval
());
}
};
}
// namespace <anonymous>
...
...
@@ -230,8 +234,7 @@ CAF_TEST(depth_2_pipeline_50_items) {
expect
((
upstream_msg
::
ack_open
),
from
(
snk
).
to
(
src
));
CAF_MESSAGE
(
"start data transmission (a single batch)"
);
expect
((
downstream_msg
::
batch
),
from
(
src
).
to
(
snk
));
sched
.
clock
().
current_time
+=
credit_round_interval
;
sched
.
dispatch
();
tick
();
expect
((
timeout_msg
),
from
(
snk
).
to
(
snk
));
expect
((
timeout_msg
),
from
(
src
).
to
(
src
));
expect
((
upstream_msg
::
ack_batch
),
from
(
snk
).
to
(
src
));
...
...
@@ -251,8 +254,7 @@ CAF_TEST(depth_2_pipeline_setup2_50_items) {
expect
((
upstream_msg
::
ack_open
),
from
(
snk
).
to
(
src
));
CAF_MESSAGE
(
"start data transmission (a single batch)"
);
expect
((
downstream_msg
::
batch
),
from
(
src
).
to
(
snk
));
sched
.
clock
().
current_time
+=
credit_round_interval
;
sched
.
dispatch
();
tick
();
expect
((
timeout_msg
),
from
(
snk
).
to
(
snk
));
expect
((
timeout_msg
),
from
(
src
).
to
(
src
));
expect
((
upstream_msg
::
ack_batch
),
from
(
snk
).
to
(
src
));
...
...
@@ -278,8 +280,7 @@ CAF_TEST(delayed_depth_2_pipeline_50_items) {
expect
((
upstream_msg
::
ack_open
),
from
(
snk
).
to
(
src
));
CAF_MESSAGE
(
"start data transmission (a single batch)"
);
expect
((
downstream_msg
::
batch
),
from
(
src
).
to
(
snk
));
sched
.
clock
().
current_time
+=
credit_round_interval
;
sched
.
dispatch
();
tick
();
expect
((
timeout_msg
),
from
(
snk
).
to
(
snk
));
expect
((
timeout_msg
),
from
(
src
).
to
(
src
));
expect
((
upstream_msg
::
ack_batch
),
from
(
snk
).
to
(
src
));
...
...
@@ -304,8 +305,7 @@ CAF_TEST(depth_2_pipeline_500_items) {
expect
((
downstream_msg
::
batch
),
from
(
src
).
to
(
snk
));
}
CAF_MESSAGE
(
"trigger timeouts"
);
sched
.
clock
().
current_time
+=
credit_round_interval
;
sched
.
dispatch
();
tick
();
allow
((
timeout_msg
),
from
(
snk
).
to
(
snk
));
allow
((
timeout_msg
),
from
(
src
).
to
(
src
));
CAF_MESSAGE
(
"process ack_batch in source"
);
...
...
@@ -368,8 +368,7 @@ CAF_TEST(depth_3_pipeline_50_items) {
auto
stg
=
sys
.
spawn
(
filter
);
auto
snk
=
sys
.
spawn
(
sum_up
);
auto
next_cycle
=
[
&
]
{
sched
.
clock
().
current_time
+=
credit_round_interval
;
sched
.
dispatch
();
tick
();
allow
((
timeout_msg
),
from
(
snk
).
to
(
snk
));
allow
((
timeout_msg
),
from
(
stg
).
to
(
stg
));
allow
((
timeout_msg
),
from
(
src
).
to
(
src
));
...
...
@@ -415,7 +414,7 @@ CAF_TEST(depth_4_pipeline_500_items) {
expect
((
upstream_msg
::
ack_open
),
from
(
stg2
).
to
(
stg1
));
expect
((
upstream_msg
::
ack_open
),
from
(
stg1
).
to
(
src
));
CAF_MESSAGE
(
"start data transmission"
);
sched
.
run_dispatch_loop
(
credit_round_interval
);
run
(
);
CAF_MESSAGE
(
"check sink result"
);
CAF_CHECK_EQUAL
(
deref
<
sum_up_actor
>
(
snk
).
state
.
x
,
125000
);
}
...
...
libcaf_core/test/read_ini.cpp
View file @
5ea3e4ac
...
...
@@ -150,7 +150,7 @@ const auto ini0_log = make_log(
"key: scheduler"
,
"{"
,
"key: timing"
,
"value (timespan): 2
000n
s"
,
"value (timespan): 2
u
s"
,
"key: impl"
,
"value (atom): 'foo'"
,
"key: x_"
,
...
...
libcaf_core/test/request_timeout.cpp
View file @
5ea3e4ac
...
...
@@ -16,12 +16,12 @@
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#include "caf/
config
.hpp"
#include "caf/
after
.hpp"
#define CAF_SUITE request_timeout
#include "caf/test/unit_test.hpp"
#include <thread>
#include "caf/test/dsl.hpp"
#include <chrono>
#include "caf/all.hpp"
...
...
@@ -70,7 +70,7 @@ behavior ping_single1(ping_actor* self, bool* had_timeout, const actor& buddy) {
self
->
delayed_send
(
self
,
std
::
chrono
::
seconds
(
1
),
timeout_atom
::
value
);
return
{
[
=
](
pong_atom
)
{
CAF_
ERROR
(
"received pong atom"
);
CAF_
FAIL
(
"received pong atom"
);
},
[
=
](
timeout_atom
)
{
*
had_timeout
=
true
;
...
...
@@ -84,7 +84,7 @@ behavior ping_single2(ping_actor* self, bool* had_timeout, const actor& buddy) {
self
->
send
(
buddy
,
ping_atom
::
value
);
return
{
[
=
](
pong_atom
)
{
CAF_
ERROR
(
"received pong atom"
);
CAF_
FAIL
(
"received pong atom"
);
},
after
(
std
::
chrono
::
seconds
(
1
))
>>
[
=
]
{
*
had_timeout
=
true
;
...
...
@@ -97,7 +97,7 @@ behavior ping_single2(ping_actor* self, bool* had_timeout, const actor& buddy) {
behavior
ping_single3
(
ping_actor
*
self
,
bool
*
had_timeout
,
const
actor
&
buddy
)
{
self
->
request
(
buddy
,
milliseconds
(
100
),
ping_atom
::
value
).
then
(
[
=
](
pong_atom
)
{
CAF_
ERROR
(
"received pong atom"
);
CAF_
FAIL
(
"received pong atom"
);
},
[
=
](
const
error
&
err
)
{
CAF_REQUIRE
(
err
==
sec
::
request_timeout
);
...
...
@@ -115,7 +115,7 @@ behavior ping_nested1(ping_actor* self, bool* had_timeout,
self
->
delayed_send
(
self
,
std
::
chrono
::
seconds
(
1
),
timeout_atom
::
value
);
return
{
[
=
](
pong_atom
)
{
CAF_
ERROR
(
"received pong atom"
);
CAF_
FAIL
(
"received pong atom"
);
},
[
=
](
timeout_atom
)
{
self
->
state
.
had_first_timeout
=
true
;
...
...
@@ -136,7 +136,7 @@ behavior ping_nested2(ping_actor* self, bool* had_timeout, const actor& buddy) {
self
->
send
(
buddy
,
ping_atom
::
value
);
return
{
[
=
](
pong_atom
)
{
CAF_
ERROR
(
"received pong atom"
);
CAF_
FAIL
(
"received pong atom"
);
},
after
(
std
::
chrono
::
seconds
(
1
))
>>
[
=
]
{
self
->
state
.
had_first_timeout
=
true
;
...
...
@@ -156,7 +156,7 @@ behavior ping_nested2(ping_actor* self, bool* had_timeout, const actor& buddy) {
behavior
ping_nested3
(
ping_actor
*
self
,
bool
*
had_timeout
,
const
actor
&
buddy
)
{
self
->
request
(
buddy
,
milliseconds
(
100
),
ping_atom
::
value
).
then
(
[
=
](
pong_atom
)
{
CAF_
ERROR
(
"received pong atom"
);
CAF_
FAIL
(
"received pong atom"
);
self
->
quit
(
sec
::
unexpected_message
);
},
[
=
](
const
error
&
err
)
{
...
...
@@ -178,7 +178,7 @@ behavior ping_multiplexed1(ping_actor* self, bool* had_timeout,
const
actor
&
pong_actor
)
{
self
->
request
(
pong_actor
,
milliseconds
(
100
),
ping_atom
::
value
).
then
(
[
=
](
pong_atom
)
{
CAF_
ERROR
(
"received pong atom"
);
CAF_
FAIL
(
"received pong atom"
);
},
[
=
](
const
error
&
err
)
{
CAF_REQUIRE_EQUAL
(
err
,
sec
::
request_timeout
);
...
...
@@ -190,7 +190,7 @@ behavior ping_multiplexed1(ping_actor* self, bool* had_timeout,
);
self
->
request
(
pong_actor
,
milliseconds
(
100
),
ping_atom
::
value
).
then
(
[
=
](
pong_atom
)
{
CAF_
ERROR
(
"received pong atom"
);
CAF_
FAIL
(
"received pong atom"
);
},
[
=
](
const
error
&
err
)
{
CAF_REQUIRE_EQUAL
(
err
,
sec
::
request_timeout
);
...
...
@@ -208,7 +208,7 @@ behavior ping_multiplexed2(ping_actor* self, bool* had_timeout,
const
actor
&
pong_actor
)
{
self
->
request
(
pong_actor
,
milliseconds
(
100
),
ping_atom
::
value
).
await
(
[
=
](
pong_atom
)
{
CAF_
ERROR
(
"received pong atom"
);
CAF_
FAIL
(
"received pong atom"
);
},
[
=
](
const
error
&
err
)
{
CAF_REQUIRE_EQUAL
(
err
,
sec
::
request_timeout
);
...
...
@@ -220,7 +220,7 @@ behavior ping_multiplexed2(ping_actor* self, bool* had_timeout,
);
self
->
request
(
pong_actor
,
milliseconds
(
100
),
ping_atom
::
value
).
await
(
[
=
](
pong_atom
)
{
CAF_
ERROR
(
"received pong atom"
);
CAF_
FAIL
(
"received pong atom"
);
},
[
=
](
const
error
&
err
)
{
CAF_REQUIRE_EQUAL
(
err
,
sec
::
request_timeout
);
...
...
@@ -238,7 +238,7 @@ behavior ping_multiplexed3(ping_actor* self, bool* had_timeout,
const
actor
&
pong_actor
)
{
self
->
request
(
pong_actor
,
milliseconds
(
100
),
ping_atom
::
value
).
then
(
[
=
](
pong_atom
)
{
CAF_
ERROR
(
"received pong atom"
);
CAF_
FAIL
(
"received pong atom"
);
},
[
=
](
const
error
&
err
)
{
CAF_REQUIRE_EQUAL
(
err
,
sec
::
request_timeout
);
...
...
@@ -250,7 +250,7 @@ behavior ping_multiplexed3(ping_actor* self, bool* had_timeout,
);
self
->
request
(
pong_actor
,
milliseconds
(
100
),
ping_atom
::
value
).
await
(
[
=
](
pong_atom
)
{
CAF_
ERROR
(
"received pong atom"
);
CAF_
FAIL
(
"received pong atom"
);
},
[
=
](
const
error
&
err
)
{
CAF_REQUIRE_EQUAL
(
err
,
sec
::
request_timeout
);
...
...
@@ -263,33 +263,9 @@ behavior ping_multiplexed3(ping_actor* self, bool* had_timeout,
return
{};
}
struct
config
:
actor_system_config
{
config
()
{
set
(
"scheduler.policy"
,
atom
(
"testing"
));
}
};
struct
fixture
{
config
cfg
;
actor_system
system
;
scoped_actor
self
;
scheduler
::
test_coordinator
&
sched
;
fixture
()
:
system
(
cfg
),
self
(
system
),
sched
(
dynamic_cast
<
scheduler
::
test_coordinator
&>
(
system
.
scheduler
()))
{
CAF_REQUIRE
(
sched
.
jobs
.
empty
());
}
~
fixture
()
{
sched
.
run_dispatch_loop
();
}
};
}
// namespace <anonymous>
CAF_TEST_FIXTURE_SCOPE
(
request_timeout_tests
,
fixture
)
CAF_TEST_FIXTURE_SCOPE
(
request_timeout_tests
,
test_coordinator_fixture
<>
)
CAF_TEST
(
single_timeout
)
{
test_vec
fs
{{
ping_single1
,
"ping_single1"
},
...
...
@@ -298,14 +274,14 @@ CAF_TEST(single_timeout) {
for
(
auto
f
:
fs
)
{
bool
had_timeout
=
false
;
CAF_MESSAGE
(
"test implemenation "
<<
f
.
second
);
auto
testee
=
sys
tem
.
spawn
(
f
.
first
,
&
had_timeout
,
system
.
spawn
<
lazy_init
>
(
pong
));
auto
testee
=
sys
.
spawn
(
f
.
first
,
&
had_timeout
,
sys
.
spawn
<
lazy_init
>
(
pong
));
CAF_REQUIRE_EQUAL
(
sched
.
jobs
.
size
(),
1u
);
CAF_REQUIRE_EQUAL
(
sched
.
next_job
<
local_actor
>
().
name
(),
string
{
"ping"
});
sched
.
run_once
();
CAF_REQUIRE_EQUAL
(
sched
.
jobs
.
size
(),
1u
);
CAF_REQUIRE_EQUAL
(
sched
.
next_job
<
local_actor
>
().
name
(),
string
{
"pong"
});
sched
.
dispatch
();
sched
.
trigger_timeout
();
CAF_REQUIRE_EQUAL
(
sched
.
jobs
.
size
(),
2u
);
// now, the timeout message is already dispatched, while pong did
// not respond to the message yet, i.e., timeout arrives before response
...
...
@@ -321,20 +297,20 @@ CAF_TEST(nested_timeout) {
for
(
auto
f
:
fs
)
{
bool
had_timeout
=
false
;
CAF_MESSAGE
(
"test implemenation "
<<
f
.
second
);
auto
testee
=
sys
tem
.
spawn
(
f
.
first
,
&
had_timeout
,
system
.
spawn
<
lazy_init
>
(
pong
));
auto
testee
=
sys
.
spawn
(
f
.
first
,
&
had_timeout
,
sys
.
spawn
<
lazy_init
>
(
pong
));
CAF_REQUIRE_EQUAL
(
sched
.
jobs
.
size
(),
1u
);
CAF_REQUIRE_EQUAL
(
sched
.
next_job
<
local_actor
>
().
name
(),
string
{
"ping"
});
sched
.
run_once
();
CAF_REQUIRE_EQUAL
(
sched
.
jobs
.
size
(),
1u
);
CAF_REQUIRE_EQUAL
(
sched
.
next_job
<
local_actor
>
().
name
(),
string
{
"pong"
});
sched
.
dispatch
();
sched
.
trigger_timeout
();
CAF_REQUIRE_EQUAL
(
sched
.
jobs
.
size
(),
2u
);
// now, the timeout message is already dispatched, while pong did
// not respond to the message yet, i.e., timeout arrives before response
sched
.
run
();
// dispatch second timeout
CAF_REQUIRE_EQUAL
(
sched
.
dispatch
(),
true
);
CAF_REQUIRE_EQUAL
(
sched
.
trigger_timeout
(),
true
);
CAF_REQUIRE_EQUAL
(
sched
.
next_job
<
local_actor
>
().
name
(),
string
{
"ping"
});
CAF_CHECK
(
!
had_timeout
);
CAF_CHECK
(
sched
.
next_job
<
ping_actor
>
().
state
.
had_first_timeout
);
...
...
@@ -350,14 +326,14 @@ CAF_TEST(multiplexed_timeout) {
for
(
auto
f
:
fs
)
{
bool
had_timeout
=
false
;
CAF_MESSAGE
(
"test implemenation "
<<
f
.
second
);
auto
testee
=
sys
tem
.
spawn
(
f
.
first
,
&
had_timeout
,
system
.
spawn
<
lazy_init
>
(
pong
));
auto
testee
=
sys
.
spawn
(
f
.
first
,
&
had_timeout
,
sys
.
spawn
<
lazy_init
>
(
pong
));
CAF_REQUIRE_EQUAL
(
sched
.
jobs
.
size
(),
1u
);
CAF_REQUIRE_EQUAL
(
sched
.
next_job
<
local_actor
>
().
name
(),
string
{
"ping"
});
sched
.
run_once
();
CAF_REQUIRE_EQUAL
(
sched
.
jobs
.
size
(),
1u
);
CAF_REQUIRE_EQUAL
(
sched
.
next_job
<
local_actor
>
().
name
(),
string
{
"pong"
});
sched
.
dispatch
();
sched
.
trigger_timeouts
();
CAF_REQUIRE_EQUAL
(
sched
.
jobs
.
size
(),
2u
);
// now, the timeout message is already dispatched, while pong did
// not respond to the message yet, i.e., timeout arrives before response
...
...
libcaf_core/test/selective_streaming.cpp
View file @
5ea3e4ac
...
...
@@ -186,7 +186,7 @@ CAF_TEST(select_all) {
CAF_MESSAGE
(
CAF_ARG
(
self
)
<<
CAF_ARG
(
src
)
<<
CAF_ARG
(
snk
));
CAF_MESSAGE
(
"initiate stream handshake"
);
self
->
send
(
snk
*
src
,
level
::
all
);
sched
.
run_dispatch_loop
(
streaming_cycle
);
run
(
);
CAF_CHECK_EQUAL
(
deref
<
log_consumer_actor
>
(
snk
).
state
.
log
,
make_log
(
level
::
all
));
}
...
...
@@ -197,7 +197,7 @@ CAF_TEST(select_trace) {
CAF_MESSAGE
(
CAF_ARG
(
self
)
<<
CAF_ARG
(
src
)
<<
CAF_ARG
(
snk
));
CAF_MESSAGE
(
"initiate stream handshake"
);
self
->
send
(
snk
*
src
,
level
::
trace
);
sched
.
run_dispatch_loop
(
streaming_cycle
);
run
(
);
CAF_CHECK_EQUAL
(
deref
<
log_consumer_actor
>
(
snk
).
state
.
log
,
make_log
(
level
::
trace
));
}
...
...
@@ -213,10 +213,9 @@ CAF_TEST(forking) {
self
->
send
(
snk2
*
stg
,
join_atom
::
value
,
level
::
error
);
sched
.
run
();
auto
&
st
=
deref
<
log_dispatcher_actor
>
(
stg
).
state
;
auto
predicate
=
[
&
]
{
run_until
(
[
&
]
{
return
st
.
stage
->
inbound_paths
().
empty
()
&&
st
.
stage
->
out
().
clean
();
};
sched
.
run_dispatch_loop
(
predicate
,
streaming_cycle
);
});
CAF_CHECK_EQUAL
(
deref
<
log_consumer_actor
>
(
snk1
).
state
.
log
,
make_log
(
level
::
trace
));
CAF_CHECK_EQUAL
(
deref
<
log_consumer_actor
>
(
snk2
).
state
.
log
,
...
...
libcaf_core/test/simple_timeout.cpp
View file @
5ea3e4ac
...
...
@@ -16,10 +16,11 @@
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#include "caf/
config
.hpp"
#include "caf/
after
.hpp"
#define CAF_SUITE simple_timeout
#include "caf/test/unit_test.hpp"
#include "caf/test/dsl.hpp"
#include <chrono>
#include <memory>
...
...
@@ -70,33 +71,9 @@ timer::behavior_type timer_impl2(timer::pointer self) {
};
}
struct
config
:
actor_system_config
{
config
()
{
set
(
"scheduler.policy"
,
atom
(
"testing"
));
}
};
struct
fixture
{
config
cfg
;
actor_system
system
;
scoped_actor
self
;
scheduler
::
test_coordinator
&
sched
;
fixture
()
:
system
(
cfg
),
self
(
system
),
sched
(
dynamic_cast
<
scheduler
::
test_coordinator
&>
(
system
.
scheduler
()))
{
CAF_REQUIRE
(
sched
.
jobs
.
empty
());
}
~
fixture
()
{
sched
.
run_dispatch_loop
();
}
};
}
// namespace <anonymous>
CAF_TEST_FIXTURE_SCOPE
(
simple_timeout_tests
,
fixture
)
CAF_TEST_FIXTURE_SCOPE
(
simple_timeout_tests
,
test_coordinator_fixture
<>
)
CAF_TEST
(
duration_conversion
)
{
duration
d1
{
time_unit
::
milliseconds
,
100
};
...
...
@@ -107,11 +84,11 @@ CAF_TEST(duration_conversion) {
}
CAF_TEST
(
single_timeout
)
{
sys
tem
.
spawn
(
timer_impl
);
sys
.
spawn
(
timer_impl
);
}
CAF_TEST
(
single_anon_timeout
)
{
sys
tem
.
spawn
(
timer_impl2
);
sys
.
spawn
(
timer_impl2
);
}
CAF_TEST_FIXTURE_SCOPE_END
()
libcaf_io/test/basp_udp.cpp
View file @
5ea3e4ac
...
...
@@ -1015,7 +1015,7 @@ CAF_TEST_DISABLED(out_of_order_delivery_udp) {
++
expected_next
;
}
);
sched
.
dispatch
();
sched
.
trigger_timeouts
();
mpx
()
->
flush_runnables
();
CAF_MESSAGE
(
"force delivery via timeout that skips messages"
);
const
basp
::
sequence_type
seq_and_payload
=
23
;
...
...
@@ -1023,7 +1023,7 @@ CAF_TEST_DISABLED(out_of_order_delivery_udp) {
.
enqueue_back
(
jupiter
().
endpoint
,
header_with_seq
(
seq_and_payload
),
std
::
vector
<
actor_id
>
{},
make_message
(
seq_and_payload
))
.
deliver
(
jupiter
().
endpoint
,
1
);
sched
.
dispatch
();
sched
.
trigger_timeouts
();
mpx
()
->
exec_runnable
();
self
()
->
receive
(
[
&
](
basp
::
sequence_type
val
)
{
...
...
libcaf_test/caf/test/dsl.hpp
View file @
5ea3e4ac
...
...
@@ -27,12 +27,14 @@
CAF_PUSH_WARNINGS
namespace
{
/// The type of `_`.
struct
wildcard
{
};
/// Allows ignoring individual messages elements in `expect` clauses, e.g.
/// `expect((int, int), from(foo).to(bar).with(1, _))`.
constexpr
wildcard
_
=
wildcard
{};
/// @relates wildcard
constexpr
bool
operator
==
(
const
wildcard
&
,
const
wildcard
&
)
{
return
true
;
}
...
...
@@ -56,8 +58,6 @@ msg_cmp_rec(const caf::message& x, const std::tuple<Ts...>& ys) {
return
cmp_one
<
I
>
(
x
,
std
::
get
<
I
>
(
ys
))
&&
msg_cmp_rec
<
I
+
1
>
(
x
,
ys
);
}
}
// namespace <anonymous>
// allow comparing arbitrary `T`s to `message` objects for the purpose of the
// testing DSL
namespace
caf
{
...
...
@@ -74,8 +74,6 @@ bool operator==(const message& x, const T& y) {
}
// namespace caf
namespace
{
// dummy function to force ADL later on
//int inspect(int, int);
...
...
@@ -189,16 +187,16 @@ public:
caf_handle
&
operator
=
(
const
caf_handle
&
)
=
default
;
inline
pointer
get
()
const
{
pointer
get
()
const
{
return
ptr_
;
}
inline
ptrdiff_t
compare
(
const
caf_handle
&
other
)
const
{
ptrdiff_t
compare
(
const
caf_handle
&
other
)
const
{
return
reinterpret_cast
<
ptrdiff_t
>
(
ptr_
)
-
reinterpret_cast
<
ptrdiff_t
>
(
other
.
ptr_
);
}
inline
ptrdiff_t
compare
(
std
::
nullptr_t
)
const
{
ptrdiff_t
compare
(
std
::
nullptr_t
)
const
{
return
reinterpret_cast
<
ptrdiff_t
>
(
ptr_
);
}
...
...
@@ -546,35 +544,14 @@ struct test_coordinator_fixture_fetch_helper<T> {
/// A fixture with a deterministic scheduler setup.
template
<
class
Config
=
caf
::
actor_system_config
>
struct
test_coordinator_fixture
{
class
test_coordinator_fixture
{
public:
// -- member types -----------------------------------------------------------
/// A deterministic scheduler type.
using
scheduler_type
=
caf
::
scheduler
::
test_coordinator
;
/// Convenience alias for std::chrono::microseconds.
using
us_t
=
std
::
chrono
::
microseconds
;
/// The user-generated system config.
Config
cfg
;
/// Host system for (scheduled) actors.
caf
::
actor_system
sys
;
/// A scoped actor for conveniently sending and receiving messages.
caf
::
scoped_actor
self
;
/// Deterministic scheduler.
scheduler_type
&
sched
;
/// Duration between two credit rounds.
caf
::
timespan
credit_round_interval
;
/// Max send delay for stream batches.
caf
::
timespan
max_batch_delay
;
/// Duration a single cycle, computed as GCD of credit-round-interval and
/// max-batch-delay. Using this duration for `sched.run_dispatch_loop()`
/// advances the clock in ideal steps.
caf
::
timespan
streaming_cycle
;
// -- constructors, destructors, and assignment operators --------------------
template
<
class
...
Ts
>
explicit
test_coordinator_fixture
(
Ts
&&
...
xs
)
...
...
@@ -584,59 +561,167 @@ struct test_coordinator_fixture {
.
set
(
"logger.inline-output"
,
true
)
.
set
(
"middleman.network-backend"
,
caf
::
atom
(
"testing"
))),
self
(
sys
,
true
),
sched
(
dynamic_cast
<
scheduler_type
&>
(
sys
.
scheduler
())),
credit_round_interval
(
cfg
.
streaming_credit_round_interval
()),
max_batch_delay
(
cfg
.
streaming_max_batch_delay
())
{
sched
(
dynamic_cast
<
scheduler_type
&>
(
sys
.
scheduler
()))
{
// Configure the clock to measure each batch item with 1us.
sched
.
clock
().
time_per_unit
.
emplace
(
caf
::
atom
(
"batch"
),
caf
::
timespan
{
1000
});
// Compute reasonable step size.
auto
cycle_us
=
cfg
.
streaming_tick_duration_us
();
streaming_cycle
=
caf
::
timespan
{
us_t
{
cycle_us
}};
// Make sure the current time isn't 0.
sched
.
clock
().
current_time
+=
streaming_cycle
;
sched
.
clock
().
current_time
+=
std
::
chrono
::
hours
(
1
);
credit_round_interval
=
cfg
.
streaming_credit_round_interval
();
}
virtual
~
test_coordinator_fixture
()
{
sched
.
clock
().
cancel_all
();
sched
.
run
();
run
();
}
/// Dispatches messages and timeouts until no activity remains.
void
run_exhaustively
()
{
sched
.
run_dispatch_loop
(
streaming_cycle
);
// -- DSL functions ----------------------------------------------------------
/// Advances the clock by a single tick duration.
size_t
advance_time
(
caf
::
timespan
interval
)
{
return
sched
.
clock
().
advance_time
(
interval
);
}
/// Allows the next actor to consume one message from its mailbox. Fails the
/// test if no message was consumed.
void
consume_message
()
{
if
(
!
sched
.
try_run_once
())
CAF_FAIL
(
"no message to consume"
);
}
/// Dispatches messages and timeouts until no activity remains.
template
<
class
Predicate
>
void
run_exhaustively_while
(
Predicate
predicate
)
{
sched
.
run_dispatch_loop
(
predicate
,
streaming_cycle
);
/// Allows each actors to consume all messages from its mailbox. Fails the
/// test if no message was consumed.
/// @returns The number of consumed messages.
size_t
consume_messages
()
{
auto
result
=
sched
.
run
();
if
(
result
==
0
)
CAF_FAIL
(
"no message to consume"
);
return
result
;
}
/// Sends a request to `from`, then calls `run_exhaustively`, and finally
/// fetches and returns the result.
/// Consume messages and trigger timeouts until no activity remains.
/// @returns The total number of events, i.e., messages consumed and
/// timeouts triggerd.
size_t
run
()
{
return
run_until
([]
{
return
false
;
});
}
/// Consume messages and trigger timeouts until `pred` becomes `true` or
/// until no activity remains.
/// @returns The total number of events, i.e., messages consumed and
/// timeouts triggered.
template
<
class
BoolPredicate
>
size_t
run_until
(
BoolPredicate
predicate
)
{
CAF_LOG_TRACE
(
""
);
// Bookkeeping.
size_t
events
=
0
;
// Loop until no activity remains.
while
(
sched
.
has_job
()
||
sched
.
has_pending_timeout
())
{
while
(
sched
.
try_run_once
())
{
++
events
;
if
(
predicate
())
{
CAF_LOG_DEBUG
(
"stop due to predicate:"
<<
CAF_ARG
(
events
));
return
events
;
}
}
if
(
trigger_timeout
())
++
events
;
}
CAF_LOG_DEBUG
(
"no activity left:"
<<
CAF_ARG
(
events
));
return
events
;
}
/// Call `run()` when the next scheduled actor becomes ready.
void
run_after_next_ready_event
()
{
sched
.
after_next_enqueue
([
=
]
{
run
();
});
}
/// Call `run_until(predicate)` when the next scheduled actor becomes ready.
template
<
class
BoolPredicate
>
void
run_until_after_next_ready_event
(
BoolPredicate
predicate
)
{
sched
.
after_next_enqueue
([
=
]
{
run_until
(
predicate
);
});
}
/// Sends a request to `hdl`, then calls `run()`, and finally fetches and
/// returns the result.
template
<
class
T
,
class
...
Ts
,
class
Handle
,
class
...
Us
>
typename
std
::
conditional
<
sizeof
...(
Ts
)
==
0
,
T
,
std
::
tuple
<
T
,
Ts
...
>>::
type
request
(
Handle
from
,
Us
...
args
)
{
auto
res_hdl
=
self
->
request
(
from
,
caf
::
infinite
,
std
::
move
(
args
)...);
run
_exhaustively
();
request
(
Handle
hdl
,
Us
...
args
)
{
auto
res_hdl
=
self
->
request
(
hdl
,
caf
::
infinite
,
std
::
move
(
args
)...);
run
();
test_coordinator_fixture_fetch_helper
<
T
,
Ts
...
>
f
;
return
f
(
res_hdl
);
}
/// Returns the next message from the next pending actor's mailbox as `T`.
template
<
class
T
>
const
T
&
peek
()
{
return
sched
.
template
peek
<
T
>();
}
/// Dereferences `hdl` and downcasts it to `T`.
template
<
class
T
=
caf
::
scheduled_actor
,
class
Handle
=
caf
::
actor
>
T
&
deref
(
const
Handle
&
hdl
)
{
auto
ptr
=
caf
::
actor_cast
<
caf
::
abstract_actor
*>
(
hdl
);
CAF_REQUIRE
(
ptr
!=
nullptr
);
return
dynamic_cast
<
T
&>
(
*
ptr
);
}
/// Triggers the next pending timeout.
virtual
bool
trigger_timeout
()
{
return
sched
.
trigger_timeout
();
}
/// Triggers all pending timeouts.
size_t
trigger_timeouts
()
{
size_t
timeouts
=
0
;
while
(
trigger_timeout
())
++
timeouts
;
return
timeouts
;
}
// -- member variables -------------------------------------------------------
/// The user-generated system config.
Config
cfg
;
/// Host system for (scheduled) actors.
caf
::
actor_system
sys
;
/// A scoped actor for conveniently sending and receiving messages.
caf
::
scoped_actor
self
;
/// Deterministic scheduler.
scheduler_type
&
sched
;
// -- deprecated functionality -----------------------------------------------
void
run_exhaustively
()
CAF_DEPRECATED_MSG
(
"use run() instead"
);
void
run_exhaustively_until
(
std
::
function
<
bool
()
>
f
)
CAF_DEPRECATED_MSG
(
"use run_until() instead"
);
void
loop_after_next_enqueue
()
CAF_DEPRECATED_MSG
(
"use run_after_next_ready_event() instead"
);
caf
::
timespan
credit_round_interval
CAF_DEPRECATED
;
};
template
<
class
Config
>
void
test_coordinator_fixture
<
Config
>::
run_exhaustively
()
{
run
();
}
template
<
class
Config
>
void
test_coordinator_fixture
<
Config
>::
run_exhaustively_until
(
std
::
function
<
bool
()
>
f
)
{
run_until
(
std
::
move
(
f
));
}
template
<
class
Config
>
void
test_coordinator_fixture
<
Config
>::
loop_after_next_enqueue
()
{
sched
.
after_next_enqueue
([
=
]
{
run
();
});
}
/// Unboxes an expected value or fails the test if it doesn't exist.
template
<
class
T
>
T
unbox
(
caf
::
expected
<
T
>
x
)
{
...
...
@@ -653,8 +738,6 @@ T unbox(caf::optional<T> x) {
return
std
::
move
(
*
x
);
}
}
// namespace <anonymous>
/// Expands to its argument.
#define CAF_EXPAND(x) x
...
...
libcaf_test/caf/test/io_dsl.hpp
View file @
5ea3e4ac
...
...
@@ -18,41 +18,55 @@
#pragma once
#include <functional>
#include "caf/io/all.hpp"
#include "caf/io/network/test_multiplexer.hpp"
#include "caf/test/dsl.hpp"
namespace
{
/// Ensures that `test_node_fixture` can override `run_exhaustively` even if
/// the base fixture does not declare these member functions virtual.
template
<
class
BaseFixture
>
class
test_node_fixture_base
{
public:
// -- constructors, destructors, and assignment operators --------------------
virtual
~
test_node_fixture_base
()
{
// nop
}
// -- interface functions ----------------------------------------------------
virtual
bool
advance
()
=
0
;
virtual
bool
trigger_timeout
()
=
0
;
};
/// A fixture containing all required state to simulate a single CAF node.
template
<
class
BaseFixture
=
test_coordinator_fixture
<
caf
::
actor_system_config
>
>
class
test_node_fixture
:
public
BaseFixture
{
class
test_node_fixture
:
public
BaseFixture
,
test_node_fixture_base
<
BaseFixture
>
{
public:
using
super
=
BaseFixture
;
// -- member types -----------------------------------------------------------
using
exec_all_nodes_fun
=
std
::
function
<
void
()
>
;
/// Base type.
using
super
=
BaseFixture
;
exec_all_nodes_fun
exec_all_nodes
;
caf
::
io
::
middleman
&
mm
;
caf
::
io
::
network
::
test_multiplexer
&
mpx
;
/// Callback function type.
using
run_all_nodes_fun
=
std
::
function
<
void
()
>
;
/// @param fun A function object for delegating to the parent's `exec_all`.
test_node_fixture
(
exec
_all_nodes_fun
fun
)
:
exec_all_nodes
(
std
::
move
(
fun
)),
m
m
(
this
->
sys
.
middleman
(
)),
mpx
(
dynamic_cast
<
caf
::
io
::
network
::
test_multiplexer
&>
(
mm
.
backend
()
))
{
test_node_fixture
(
run
_all_nodes_fun
fun
)
:
mm
(
this
->
sys
.
middleman
(
)),
m
px
(
dynamic_cast
<
caf
::
io
::
network
::
test_multiplexer
&>
(
mm
.
backend
()
)),
run_all_nodes
(
std
::
move
(
fun
))
{
// nop
}
// Convenience function for transmitting all "network" traffic and running
// all executables on this node.
void
exec_all
()
{
while
(
mpx
.
try_exec_runnable
()
||
mpx
.
read_data
()
||
mpx
.
try_accept_connection
()
||
this
->
sched
.
try_run_once
())
{
// rince and repeat
}
test_node_fixture
()
:
test_node_fixture
([
=
]
{
this
->
run
();
})
{
// nop
}
/// Convenience function for calling `mm.publish` and requiring a valid
...
...
@@ -71,17 +85,39 @@ public:
template
<
class
Handle
=
caf
::
actor
>
Handle
remote_actor
(
std
::
string
host
,
uint16_t
port
)
{
this
->
sched
.
inline_next_enqueue
();
this
->
sched
.
after_next_enqueue
(
exec
_all_nodes
);
this
->
sched
.
after_next_enqueue
(
run
_all_nodes
);
auto
res
=
mm
.
remote_actor
<
Handle
>
(
std
::
move
(
host
),
port
);
CAF_REQUIRE
(
res
);
return
*
res
;
}
private:
caf
::
io
::
basp_broker
*
get_basp_broker
()
{
auto
hdl
=
mm
.
named_broker
<
caf
::
io
::
basp_broker
>
(
caf
::
atom
(
"BASP"
));
return
dynamic_cast
<
caf
::
io
::
basp_broker
*>
(
caf
::
actor_cast
<
caf
::
abstract_actor
*>
(
hdl
));
// -- member variables -------------------------------------------------------
/// Reference to the node's middleman.
caf
::
io
::
middleman
&
mm
;
/// Reference to the middleman's event multiplexer.
caf
::
io
::
network
::
test_multiplexer
&
mpx
;
/// Callback for triggering all nodes when simulating a network of CAF nodes.
run_all_nodes_fun
run_all_nodes
;
// -- deprecated functions ---------------------------------------------------
void
exec_all
()
CAF_DEPRECATED_MSG
(
"use run() instead"
)
{
this
->
run
();
}
// -- overriding member functions --------------------------------------------
bool
advance
()
override
{
return
mpx
.
try_exec_runnable
()
||
mpx
.
read_data
()
||
mpx
.
try_accept_connection
()
||
this
->
sched
.
try_run_once
();
}
bool
trigger_timeout
()
override
{
// Same as in dsl.hpp, but we have to provide it here again.
return
this
->
sched
.
trigger_timeout
();
}
};
...
...
@@ -93,9 +129,7 @@ void exec_all_fixtures(Iterator first, Iterator last) {
||
x
->
mpx
.
try_exec_runnable
()
||
x
->
mpx
.
try_accept_connection
();
};
auto
trigger_timeouts
=
[](
fixture_ptr
x
)
{
auto
&
sched
=
x
->
sched
;
sched
.
clock
().
current_time
+=
x
->
credit_round_interval
;
sched
.
dispatch
();
x
->
sched
.
trigger_timeouts
();
};
for
(;;)
{
// Exhaust all messages in the system.
...
...
@@ -109,14 +143,9 @@ void exec_all_fixtures(Iterator first, Iterator last) {
}
}
/// Binds `test_coordinator_fixture<Config>` to `test_node_fixture`.
template
<
class
Config
=
caf
::
actor_system_config
>
using
test_node_fixture_t
=
test_node_fixture
<
test_coordinator_fixture
<
Config
>>
;
/// Base fixture for simulated network settings with any number of CAF nodes.
template
<
class
PlanetType
>
class
fake
_network_fixture_base
{
class
test
_network_fixture_base
{
public:
using
planets_vector
=
std
::
vector
<
PlanetType
*>
;
...
...
@@ -124,7 +153,7 @@ public:
using
accept_handle
=
caf
::
io
::
accept_handle
;
fake
_network_fixture_base
(
planets_vector
xs
)
:
planets_
(
std
::
move
(
xs
))
{
test
_network_fixture_base
(
planets_vector
xs
)
:
planets_
(
std
::
move
(
xs
))
{
// nop
}
...
...
@@ -199,11 +228,11 @@ private:
template
<
class
BaseFixture
=
test_coordinator_fixture
<
caf
::
actor_system_config
>
>
class
point_to_point_fixture
:
public
fake
_network_fixture_base
<
test_node_fixture
<
BaseFixture
>>
{
:
public
test
_network_fixture_base
<
test_node_fixture
<
BaseFixture
>>
{
public:
using
planet_type
=
test_node_fixture
<
BaseFixture
>
;
using
super
=
fake
_network_fixture_base
<
planet_type
>
;
using
super
=
test
_network_fixture_base
<
planet_type
>
;
planet_type
earth
;
planet_type
mars
;
...
...
@@ -217,21 +246,16 @@ public:
}
};
/// Binds `test_coordinator_fixture<Config>` to `point_to_point_fixture`.
template
<
class
Config
=
caf
::
actor_system_config
>
using
point_to_point_fixture_t
=
point_to_point_fixture
<
test_coordinator_fixture
<
Config
>>
;
/// A simple fixture that includes three nodes (`earth`, `mars`, and `jupiter`)
/// that can connect to each other.
template
<
class
BaseFixture
=
test_coordinator_fixture
<
caf
::
actor_system_config
>
>
class
belt_fixture
:
public
fake
_network_fixture_base
<
test_node_fixture
<
BaseFixture
>>
{
:
public
test
_network_fixture_base
<
test_node_fixture
<
BaseFixture
>>
{
public:
using
planet_type
=
test_node_fixture
<
BaseFixture
>
;
using
super
=
fake
_network_fixture_base
<
planet_type
>
;
using
super
=
test
_network_fixture_base
<
planet_type
>
;
planet_type
earth
;
planet_type
mars
;
...
...
@@ -246,13 +270,6 @@ public:
}
};
/// Binds `test_coordinator_fixture<Config>` to `belt_fixture`.
template
<
class
Config
=
caf
::
actor_system_config
>
using
belt_fixture_t
=
belt_fixture
<
test_coordinator_fixture
<
Config
>>
;
}
// namespace <anonymous>
#define expect_on(where, types, fields) \
CAF_MESSAGE(#where << ": expect" << #types << "." << #fields); \
expect_clause< CAF_EXPAND(CAF_DSL_LIST types) >{where . sched} . fields
...
...
libcaf_test/caf/test/unit_test.hpp
View file @
5ea3e4ac
...
...
@@ -252,7 +252,7 @@ public:
return
disabled_
;
}
virtual
void
run
()
=
0
;
virtual
void
run
_test_impl
()
=
0
;
private:
size_t
expected_failures_
;
...
...
@@ -272,9 +272,9 @@ public:
// nop
}
void
run
()
override
{
void
run
_test_impl
()
override
{
T
impl
;
impl
.
run
();
impl
.
run
_test_impl
();
}
};
...
...
@@ -603,12 +603,12 @@ using caf_test_case_auto_fixture = caf::test::dummy_fixture;
#define CAF_TEST_IMPL(name, disabled_by_default) \
namespace { \
struct CAF_UNIQUE(test) : caf_test_case_auto_fixture { \
void run
();
\
void run
_test_impl();
\
}; \
::caf::test::detail::adder<::caf::test::test_impl<CAF_UNIQUE(test)>> \
CAF_UNIQUE(a){CAF_XSTR(CAF_SUITE), CAF_XSTR(name), disabled_by_default}; \
}
/* namespace <anonymous> */
\
void CAF_UNIQUE(test)::run()
void CAF_UNIQUE(test)::run
_test_impl
()
#define CAF_TEST(name) CAF_TEST_IMPL(name, false)
...
...
libcaf_test/caf/test/unit_test_impl.hpp
View file @
5ea3e4ac
...
...
@@ -369,7 +369,7 @@ bool engine::run(bool colorize,
<<
'\n'
;
auto
start
=
std
::
chrono
::
high_resolution_clock
::
now
();
watchdog
::
start
(
max_runtime
());
t
->
run
();
t
->
run
_test_impl
();
watchdog
::
stop
();
auto
stop
=
std
::
chrono
::
high_resolution_clock
::
now
();
auto
elapsed
=
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment