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
ff54e90a
Commit
ff54e90a
authored
May 12, 2015
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use fixtures in unit tests
parent
a79b8628
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
279 additions
and
188 deletions
+279
-188
libcaf_core/test/actor_lifetime.cpp
libcaf_core/test/actor_lifetime.cpp
+29
-17
libcaf_core/test/actor_pool.cpp
libcaf_core/test/actor_pool.cpp
+135
-116
libcaf_core/test/atom.cpp
libcaf_core/test/atom.cpp
+21
-14
libcaf_core/test/message_lifetime.cpp
libcaf_core/test/message_lifetime.cpp
+29
-28
libcaf_core/test/serialization.cpp
libcaf_core/test/serialization.cpp
+4
-4
libcaf_core/test/spawn.cpp
libcaf_core/test/spawn.cpp
+30
-0
libcaf_test/caf/test/unit_test.hpp
libcaf_test/caf/test/unit_test.hpp
+14
-7
libcaf_test/caf/test/unit_test_impl.hpp
libcaf_test/caf/test/unit_test_impl.hpp
+17
-2
No files found.
libcaf_core/test/actor_lifetime.cpp
View file @
ff54e90a
...
@@ -31,9 +31,9 @@ using namespace caf;
...
@@ -31,9 +31,9 @@ using namespace caf;
using
check_atom
=
caf
::
atom_constant
<
caf
::
atom
(
"check"
)
>
;
using
check_atom
=
caf
::
atom_constant
<
caf
::
atom
(
"check"
)
>
;
namespace
{
namespace
{
std
::
atomic
<
long
>
s_testees
;
std
::
atomic
<
long
>
s_testees
;
std
::
atomic
<
long
>
s_pending_on_exits
;
std
::
atomic
<
long
>
s_pending_on_exits
;
}
// namespace <anonymous>
class
testee
:
public
event_based_actor
{
class
testee
:
public
event_based_actor
{
public:
public:
...
@@ -67,16 +67,13 @@ behavior testee::make_behavior() {
...
@@ -67,16 +67,13 @@ behavior testee::make_behavior() {
template
<
class
ExitMsgType
>
template
<
class
ExitMsgType
>
behavior
tester
(
event_based_actor
*
self
,
const
actor
&
aut
)
{
behavior
tester
(
event_based_actor
*
self
,
const
actor
&
aut
)
{
CAF_MESSAGE
(
"tester behaivor entered"
);
if
(
std
::
is_same
<
ExitMsgType
,
exit_msg
>::
value
)
{
if
(
std
::
is_same
<
ExitMsgType
,
exit_msg
>::
value
)
{
self
->
trap_exit
(
true
);
self
->
trap_exit
(
true
);
self
->
link_to
(
aut
);
self
->
link_to
(
aut
);
}
else
{
}
else
{
self
->
monitor
(
aut
);
self
->
monitor
(
aut
);
}
}
CAF_MESSAGE
(
"tester before `anon_send_exit`"
);
anon_send_exit
(
aut
,
exit_reason
::
user_shutdown
);
anon_send_exit
(
aut
,
exit_reason
::
user_shutdown
);
CAF_MESSAGE
(
"tester after `anon_send_exit`"
);
return
{
return
{
[
self
](
const
ExitMsgType
&
msg
)
{
[
self
](
const
ExitMsgType
&
msg
)
{
// must be still alive at this point
// must be still alive at this point
...
@@ -100,32 +97,47 @@ behavior tester(event_based_actor* self, const actor& aut) {
...
@@ -100,32 +97,47 @@ behavior tester(event_based_actor* self, const actor& aut) {
};
};
}
}
CAF_TEST
(
no_spawn_options
)
{
struct
fixture
{
~
fixture
()
{
await_all_actors_done
();
shutdown
();
}
};
}
// namespace <anonymous>
CAF_TEST_FIXTURE_SCOPE
(
actor_lifetime_tests
,
fixture
)
CAF_TEST
(
no_spawn_options_and_exit_msg
)
{
spawn
<
no_spawn_options
>
(
tester
<
exit_msg
>
,
spawn
<
testee
,
no_spawn_options
>
());
spawn
<
no_spawn_options
>
(
tester
<
exit_msg
>
,
spawn
<
testee
,
no_spawn_options
>
());
await_all_actors_done
();
}
CAF_TEST
(
no_spawn_options_and_down_msg
)
{
spawn
<
no_spawn_options
>
(
tester
<
down_msg
>
,
spawn
<
testee
,
no_spawn_options
>
());
spawn
<
no_spawn_options
>
(
tester
<
down_msg
>
,
spawn
<
testee
,
no_spawn_options
>
());
await_all_actors_done
();
}
}
CAF_TEST
(
mixed_spawn_options
)
{
CAF_TEST
(
mixed_spawn_options
_and_exit_msg
)
{
spawn
<
detached
>
(
tester
<
exit_msg
>
,
spawn
<
testee
,
no_spawn_options
>
());
spawn
<
detached
>
(
tester
<
exit_msg
>
,
spawn
<
testee
,
no_spawn_options
>
());
await_all_actors_done
();
}
CAF_TEST
(
mixed_spawn_options_and_down_msg
)
{
spawn
<
detached
>
(
tester
<
down_msg
>
,
spawn
<
testee
,
no_spawn_options
>
());
spawn
<
detached
>
(
tester
<
down_msg
>
,
spawn
<
testee
,
no_spawn_options
>
());
await_all_actors_done
();
}
}
CAF_TEST
(
mixed_spawn_options2
)
{
CAF_TEST
(
mixed_spawn_options2
_and_exit_msg
)
{
spawn
<
no_spawn_options
>
(
tester
<
exit_msg
>
,
spawn
<
testee
,
detached
>
());
spawn
<
no_spawn_options
>
(
tester
<
exit_msg
>
,
spawn
<
testee
,
detached
>
());
await_all_actors_done
();
}
CAF_TEST
(
mixed_spawn_options2_and_down_msg
)
{
spawn
<
no_spawn_options
>
(
tester
<
down_msg
>
,
spawn
<
testee
,
detached
>
());
spawn
<
no_spawn_options
>
(
tester
<
down_msg
>
,
spawn
<
testee
,
detached
>
());
await_all_actors_done
();
}
}
CAF_TEST
(
detached_
spawn_options
)
{
CAF_TEST
(
detached_
and_exit_msg
)
{
spawn
<
detached
>
(
tester
<
exit_msg
>
,
spawn
<
testee
,
detached
>
());
spawn
<
detached
>
(
tester
<
exit_msg
>
,
spawn
<
testee
,
detached
>
());
await_all_actors_done
();
}
CAF_TEST
(
detached_and_down_msg
)
{
spawn
<
detached
>
(
tester
<
down_msg
>
,
spawn
<
testee
,
detached
>
());
spawn
<
detached
>
(
tester
<
down_msg
>
,
spawn
<
testee
,
detached
>
());
await_all_actors_done
();
shutdown
();
}
}
CAF_TEST_FIXTURE_SCOPE_END
()
libcaf_core/test/actor_pool.cpp
View file @
ff54e90a
...
@@ -29,8 +29,6 @@ namespace {
...
@@ -29,8 +29,6 @@ namespace {
std
::
atomic
<
size_t
>
s_ctors
;
std
::
atomic
<
size_t
>
s_ctors
;
std
::
atomic
<
size_t
>
s_dtors
;
std
::
atomic
<
size_t
>
s_dtors
;
}
// namespace <anonymous>
class
worker
:
public
event_based_actor
{
class
worker
:
public
event_based_actor
{
public:
public:
worker
();
worker
();
...
@@ -58,124 +56,145 @@ actor spawn_worker() {
...
@@ -58,124 +56,145 @@ actor spawn_worker() {
return
spawn
<
worker
>
();
return
spawn
<
worker
>
();
}
}
CAF_TEST
(
test_actor_pool
)
{
struct
fixture
{
announce
<
std
::
vector
<
int
>>
(
"vector<int>"
);
fixture
()
{
scoped_actor
self
;
announce
<
std
::
vector
<
int
>>
(
"vector<int>"
);
auto
w
=
actor_pool
::
make
(
5
,
spawn_worker
,
actor_pool
::
round_robin
{});
self
->
monitor
(
w
);
self
->
send
(
w
,
sys_atom
::
value
,
put_atom
::
value
,
spawn_worker
());
std
::
vector
<
actor_addr
>
workers
;
for
(
int
i
=
0
;
i
<
6
;
++
i
)
{
self
->
sync_send
(
w
,
i
,
i
).
await
(
[
&
](
int
res
)
{
CAF_CHECK_EQUAL
(
res
,
i
+
i
);
auto
sender
=
self
->
current_sender
();
self
->
monitor
(
sender
);
workers
.
push_back
(
sender
);
}
);
}
}
CAF_CHECK
(
workers
.
size
()
==
6
);
};
CAF_CHECK
(
std
::
unique
(
workers
.
begin
(),
workers
.
end
())
==
workers
.
end
());
auto
is_invalid
=
[](
const
actor_addr
&
addr
)
{
}
// namespace <anonymous>
return
addr
==
invalid_actor_addr
;
};
CAF_TEST_FIXTURE_SCOPE
(
actor_pool_tests
,
fixture
)
CAF_CHECK
(
std
::
none_of
(
workers
.
begin
(),
workers
.
end
(),
is_invalid
));
self
->
sync_send
(
w
,
sys_atom
::
value
,
get_atom
::
value
).
await
(
CAF_TEST
(
round_robin_actor_pool
)
{
[
&
](
std
::
vector
<
actor
>&
ws
)
{
{
// lifetime scope of self
std
::
sort
(
workers
.
begin
(),
workers
.
end
());
scoped_actor
self
;
std
::
sort
(
ws
.
begin
(),
ws
.
end
());
auto
w
=
actor_pool
::
make
(
5
,
spawn_worker
,
actor_pool
::
round_robin
{});
CAF_CHECK
(
workers
.
size
()
==
ws
.
size
()
self
->
monitor
(
w
);
&&
std
::
equal
(
workers
.
begin
(),
workers
.
end
(),
ws
.
begin
()));
self
->
send
(
w
,
sys_atom
::
value
,
put_atom
::
value
,
spawn_worker
());
}
std
::
vector
<
actor_addr
>
workers
;
);
for
(
int
i
=
0
;
i
<
6
;
++
i
)
{
anon_send_exit
(
workers
.
back
(),
exit_reason
::
user_shutdown
);
self
->
sync_send
(
w
,
i
,
i
).
await
(
self
->
receive
(
[
&
](
int
res
)
{
after
(
std
::
chrono
::
milliseconds
(
25
))
>>
[]
{
CAF_CHECK_EQUAL
(
res
,
i
+
i
);
// wait some time to give the pool time to remove the failed worker
auto
sender
=
self
->
current_sender
();
}
self
->
monitor
(
sender
);
);
workers
.
push_back
(
sender
);
self
->
receive
(
[
&
](
const
down_msg
&
dm
)
{
CAF_CHECK
(
dm
.
source
==
workers
.
back
());
workers
.
pop_back
();
// check whether actor pool removed failed worker
self
->
sync_send
(
w
,
sys_atom
::
value
,
get_atom
::
value
).
await
(
[
&
](
std
::
vector
<
actor
>&
ws
)
{
std
::
sort
(
ws
.
begin
(),
ws
.
end
());
CAF_CHECK
(
workers
.
size
()
==
ws
.
size
()
&&
std
::
equal
(
workers
.
begin
(),
workers
.
end
(),
ws
.
begin
()));
}
}
);
);
},
after
(
std
::
chrono
::
milliseconds
(
250
))
>>
[]
{
CAF_TEST_ERROR
(
"didn't receive a down message"
);
}
}
);
CAF_CHECK
(
workers
.
size
()
==
6
);
CAF_MESSAGE
(
"about to send exit to workers"
);
CAF_CHECK
(
std
::
unique
(
workers
.
begin
(),
workers
.
end
())
==
workers
.
end
());
self
->
send_exit
(
w
,
exit_reason
::
user_shutdown
);
auto
is_invalid
=
[](
const
actor_addr
&
addr
)
{
for
(
int
i
=
0
;
i
<
6
;
++
i
)
{
return
addr
==
invalid_actor_addr
;
};
CAF_CHECK
(
std
::
none_of
(
workers
.
begin
(),
workers
.
end
(),
is_invalid
));
self
->
sync_send
(
w
,
sys_atom
::
value
,
get_atom
::
value
).
await
(
[
&
](
std
::
vector
<
actor
>&
ws
)
{
std
::
sort
(
workers
.
begin
(),
workers
.
end
());
std
::
sort
(
ws
.
begin
(),
ws
.
end
());
CAF_CHECK
(
workers
.
size
()
==
ws
.
size
()
&&
std
::
equal
(
workers
.
begin
(),
workers
.
end
(),
ws
.
begin
()));
}
);
anon_send_exit
(
workers
.
back
(),
exit_reason
::
user_shutdown
);
self
->
receive
(
after
(
std
::
chrono
::
milliseconds
(
25
))
>>
[]
{
// wait some time to give the pool time to remove the failed worker
}
);
self
->
receive
(
self
->
receive
(
[
&
](
const
down_msg
&
dm
)
{
[
&
](
const
down_msg
&
dm
)
{
auto
last
=
workers
.
end
();
CAF_CHECK
(
dm
.
source
==
workers
.
back
());
auto
src
=
dm
.
source
;
workers
.
pop_back
();
CAF_CHECK
(
src
!=
invalid_actor_addr
);
// check whether actor pool removed failed worker
auto
pos
=
std
::
find
(
workers
.
begin
(),
last
,
src
);
self
->
sync_send
(
w
,
sys_atom
::
value
,
get_atom
::
value
).
await
(
//CAF_CHECK(pos != last || src == w); fail?
[
&
](
std
::
vector
<
actor
>&
ws
)
{
if
(
pos
!=
last
)
{
std
::
sort
(
ws
.
begin
(),
ws
.
end
());
workers
.
erase
(
pos
);
CAF_CHECK
(
workers
.
size
()
==
ws
.
size
()
}
&&
std
::
equal
(
workers
.
begin
(),
workers
.
end
(),
ws
.
begin
()));
}
);
},
},
after
(
std
::
chrono
::
milliseconds
(
250
))
>>
[]
{
after
(
std
::
chrono
::
milliseconds
(
250
))
>>
[]
{
CAF_TEST_ERROR
(
"didn't receive a down message"
);
CAF_TEST_ERROR
(
"didn't receive a down message"
);
}
}
);
);
}
CAF_MESSAGE
(
"about to send exit to workers"
);
}
self
->
send_exit
(
w
,
exit_reason
::
user_shutdown
);
for
(
int
i
=
0
;
i
<
6
;
++
i
)
{
CAF_TEST
(
test_broadcast_actor_pool
)
{
self
->
receive
(
scoped_actor
self
;
[
&
](
const
down_msg
&
dm
)
{
auto
spawn5
=
[]()
{
auto
last
=
workers
.
end
();
return
actor_pool
::
make
(
5
,
spawn_worker
,
actor_pool
::
broadcast
{})
;
auto
src
=
dm
.
source
;
}
;
CAF_CHECK
(
src
!=
invalid_actor_addr
)
;
auto
w
=
actor_pool
::
make
(
5
,
spawn5
,
actor_pool
::
broadcast
{}
);
auto
pos
=
std
::
find
(
workers
.
begin
(),
last
,
src
);
self
->
send
(
w
,
1
,
2
);
//CAF_CHECK(pos != last || src == w); fail?
std
::
vector
<
int
>
results
;
if
(
pos
!=
last
)
{
int
i
=
0
;
workers
.
erase
(
pos
)
;
self
->
receive_for
(
i
,
25
)(
}
[
&
](
int
res
)
{
},
results
.
push_back
(
res
);
after
(
std
::
chrono
::
milliseconds
(
250
))
>>
[]
{
},
CAF_TEST_ERROR
(
"didn't receive a down message"
);
after
(
std
::
chrono
::
milliseconds
(
250
))
>>
[]
{
}
CAF_TEST_ERROR
(
"didn't receive a result"
);
);
}
}
);
}
CAF_CHECK_EQUAL
(
results
.
size
(),
25
);
await_all_actors_done
();
CAF_CHECK
(
std
::
all_of
(
results
.
begin
(),
results
.
end
(),
shutdown
();
[](
int
res
)
{
return
res
==
3
;
}));
CAF_CHECK_EQUAL
(
s_dtors
.
load
(),
s_ctors
.
load
());
self
->
send_exit
(
w
,
exit_reason
::
user_shutdown
);
self
->
await_all_other_actors_done
();
}
}
CAF_TEST
(
test_random_actor_pool
)
{
CAF_TEST
(
broadcast_actor_pool
)
{
scoped_actor
self
;
{
// lifetime scope of self
auto
w
=
actor_pool
::
make
(
5
,
spawn_worker
,
actor_pool
::
random
{});
scoped_actor
self
;
for
(
int
i
=
0
;
i
<
5
;
++
i
)
{
auto
spawn5
=
[]()
{
self
->
sync_send
(
w
,
1
,
2
).
await
(
return
actor_pool
::
make
(
5
,
spawn_worker
,
actor_pool
::
broadcast
{});
};
auto
w
=
actor_pool
::
make
(
5
,
spawn5
,
actor_pool
::
broadcast
{});
self
->
send
(
w
,
1
,
2
);
std
::
vector
<
int
>
results
;
int
i
=
0
;
self
->
receive_for
(
i
,
25
)(
[
&
](
int
res
)
{
[
&
](
int
res
)
{
CAF_CHECK_EQUAL
(
res
,
3
);
results
.
push_back
(
res
);
},
},
after
(
std
::
chrono
::
milliseconds
(
250
))
>>
[]
{
after
(
std
::
chrono
::
milliseconds
(
250
))
>>
[]
{
CAF_TEST_ERROR
(
"didn't receive a
down message
"
);
CAF_TEST_ERROR
(
"didn't receive a
result
"
);
}
}
);
);
CAF_CHECK_EQUAL
(
results
.
size
(),
25
);
CAF_CHECK
(
std
::
all_of
(
results
.
begin
(),
results
.
end
(),
[](
int
res
)
{
return
res
==
3
;
}));
self
->
send_exit
(
w
,
exit_reason
::
user_shutdown
);
}
}
self
->
send_exit
(
w
,
exit_reason
::
user_shutdown
);
await_all_actors_done
();
self
->
await_all_other_actors_done
();
shutdown
();
CAF_CHECK_EQUAL
(
s_dtors
.
load
(),
s_ctors
.
load
());
}
CAF_TEST
(
random_actor_pool
)
{
{
// lifetime scope of self
scoped_actor
self
;
auto
w
=
actor_pool
::
make
(
5
,
spawn_worker
,
actor_pool
::
random
{});
for
(
int
i
=
0
;
i
<
5
;
++
i
)
{
self
->
sync_send
(
w
,
1
,
2
).
await
(
[
&
](
int
res
)
{
CAF_CHECK_EQUAL
(
res
,
3
);
},
after
(
std
::
chrono
::
milliseconds
(
250
))
>>
[]
{
CAF_TEST_ERROR
(
"didn't receive a down message"
);
}
);
}
self
->
send_exit
(
w
,
exit_reason
::
user_shutdown
);
}
await_all_actors_done
();
shutdown
();
CAF_CHECK_EQUAL
(
s_dtors
.
load
(),
s_ctors
.
load
());
}
}
CAF_TEST
(
test_split_join_actor_pool
)
{
CAF_TEST
(
split_join_actor_pool
)
{
announce
<
std
::
vector
<
int
>>
(
"vector<int>"
);
auto
spawn_split_worker
=
[]
{
auto
spawn_split_worker
=
[]
{
return
spawn
<
lazy_init
>
([]()
->
behavior
{
return
spawn
<
lazy_init
>
([]()
->
behavior
{
return
{
return
{
...
@@ -195,25 +214,25 @@ CAF_TEST(test_split_join_actor_pool) {
...
@@ -195,25 +214,25 @@ CAF_TEST(test_split_join_actor_pool) {
res
+=
x
;
res
+=
x
;
});
});
};
};
scoped_actor
self
;
{
// lifetime scope of self
auto
w
=
actor_pool
::
make
(
5
,
spawn_split_worker
,
scoped_actor
self
;
actor_pool
::
split_join
<
int
>
(
join_fun
,
split_fun
));
auto
w
=
actor_pool
::
make
(
5
,
spawn_split_worker
,
self
->
sync_send
(
w
,
std
::
vector
<
int
>
{
1
,
2
,
3
,
4
,
5
}).
await
(
actor_pool
::
split_join
<
int
>
(
join_fun
,
split_fun
));
[
&
](
int
res
)
{
self
->
sync_send
(
w
,
std
::
vector
<
int
>
{
1
,
2
,
3
,
4
,
5
}).
await
(
CAF_CHECK_EQUAL
(
res
,
15
);
[
&
](
int
res
)
{
}
CAF_CHECK_EQUAL
(
res
,
15
);
);
}
self
->
sync_send
(
w
,
std
::
vector
<
int
>
{
6
,
7
,
8
,
9
,
10
}).
await
(
);
[
&
](
int
res
)
{
self
->
sync_send
(
w
,
std
::
vector
<
int
>
{
6
,
7
,
8
,
9
,
10
}).
await
(
CAF_CHECK_EQUAL
(
res
,
40
);
[
&
](
int
res
)
{
}
CAF_CHECK_EQUAL
(
res
,
40
);
);
}
self
->
send_exit
(
w
,
exit_reason
::
user_shutdown
);
);
self
->
await_all_other_actors_done
();
self
->
send_exit
(
w
,
exit_reason
::
user_shutdown
);
}
}
CAF_TEST
(
test_dtors
)
{
await_all_actors_done
();
await_all_actors_done
();
shutdown
();
shutdown
();
CAF_CHECK_EQUAL
(
s_dtors
.
load
(),
s_ctors
.
load
());
CAF_CHECK_EQUAL
(
s_dtors
.
load
(),
s_ctors
.
load
());
}
}
CAF_TEST_FIXTURE_SCOPE_END
()
libcaf_core/test/atom.cpp
View file @
ff54e90a
...
@@ -30,18 +30,28 @@ using namespace caf;
...
@@ -30,18 +30,28 @@ using namespace caf;
namespace
{
namespace
{
constexpr
auto
s_foo
=
atom
(
"FooBar"
);
constexpr
auto
s_foo
=
atom
(
"FooBar"
);
using
abc_atom
=
atom_constant
<
atom
(
"abc"
)
>
;
using
abc_atom
=
atom_constant
<
atom
(
"abc"
)
>
;
struct
fixture
{
~
fixture
()
{
await_all_actors_done
();
shutdown
();
}
};
}
// namespace <anonymous>
}
// namespace <anonymous>
CAF_TEST_FIXTURE_SCOPE
(
atom_tests
,
fixture
)
CAF_TEST
(
basics
)
{
CAF_TEST
(
basics
)
{
// check if there are leading bits that distinguish "zzz" and "000 "
// check if there are leading bits that distinguish "zzz" and "000 "
CAF_CHECK
(
atom
(
"zzz"
)
!=
atom
(
"000 "
));
CAF_CHECK
(
atom
(
"zzz"
)
!=
atom
(
"000 "
));
// check if there are leading bits that distinguish "abc" and " abc"
// check if there are leading bits that distinguish "abc" and " abc"
CAF_CHECK
(
atom
(
"abc"
)
!=
atom
(
" abc"
));
CAF_CHECK
(
atom
(
"abc"
)
!=
atom
(
" abc"
));
// 'illegal' characters are mapped to whitespaces
// 'illegal' characters are mapped to whitespaces
CAF_CHECK
_EQUAL
(
atom
(
" "
),
atom
(
"@!?"
));
CAF_CHECK
(
atom
(
" "
)
==
atom
(
"@!?"
));
// check to_string impl
.
// check to_string impl
CAF_CHECK_EQUAL
(
to_string
(
s_foo
),
"FooBar"
);
CAF_CHECK_EQUAL
(
to_string
(
s_foo
),
"FooBar"
);
}
}
...
@@ -111,7 +121,6 @@ using testee = typed_actor<replies_to<abc_atom>::with<int>>;
...
@@ -111,7 +121,6 @@ using testee = typed_actor<replies_to<abc_atom>::with<int>>;
testee
::
behavior_type
testee_impl
(
testee
::
pointer
self
)
{
testee
::
behavior_type
testee_impl
(
testee
::
pointer
self
)
{
return
{
return
{
[
=
](
abc_atom
)
{
[
=
](
abc_atom
)
{
CAF_MESSAGE
(
"received abc_atom"
);
self
->
quit
();
self
->
quit
();
return
42
;
return
42
;
}
}
...
@@ -119,15 +128,13 @@ testee::behavior_type testee_impl(testee::pointer self) {
...
@@ -119,15 +128,13 @@ testee::behavior_type testee_impl(testee::pointer self) {
}
}
CAF_TEST
(
sync_send_atom_constants
)
{
CAF_TEST
(
sync_send_atom_constants
)
{
{
scoped_actor
self
;
scoped_actor
self
;
auto
tst
=
spawn_typed
(
testee_impl
);
auto
tst
=
spawn_typed
(
testee_impl
);
self
->
sync_send
(
tst
,
abc_atom
::
value
).
await
(
self
->
sync_send
(
tst
,
abc_atom
::
value
).
await
(
[](
int
i
)
{
[](
int
i
)
{
CAF_CHECK_EQUAL
(
i
,
42
);
CAF_CHECK_EQUAL
(
i
,
42
);
}
}
);
);
self
->
await_all_other_actors_done
();
}
shutdown
();
}
}
CAF_TEST_FIXTURE_SCOPE_END
()
libcaf_core/test/message_lifetime.cpp
View file @
ff54e90a
...
@@ -31,6 +31,13 @@ using namespace caf;
...
@@ -31,6 +31,13 @@ using namespace caf;
namespace
{
namespace
{
struct
fixture
{
~
fixture
()
{
await_all_actors_done
();
shutdown
();
}
};
class
testee
:
public
event_based_actor
{
class
testee
:
public
event_based_actor
{
public:
public:
testee
();
testee
();
...
@@ -81,13 +88,13 @@ behavior tester::make_behavior() {
...
@@ -81,13 +88,13 @@ behavior tester::make_behavior() {
send
(
m_aut
,
m_msg
);
send
(
m_aut
,
m_msg
);
return
{
return
{
on
(
1
,
2
,
3
)
>>
[
=
]
{
on
(
1
,
2
,
3
)
>>
[
=
]
{
CAF_CHECK
_EQUAL
(
current_message
().
cvals
()
->
get_reference_count
(),
2
);
CAF_CHECK
(
current_message
().
cvals
()
->
get_reference_count
()
==
2
CAF_CHECK
(
current_message
().
cvals
().
get
()
==
m_msg
.
cvals
().
get
());
&&
current_message
().
cvals
().
get
()
==
m_msg
.
cvals
().
get
());
},
},
[
=
](
const
down_msg
&
dm
)
{
[
=
](
const
down_msg
&
dm
)
{
CAF_CHECK
(
dm
.
source
==
m_aut
);
CAF_CHECK
(
dm
.
source
==
m_aut
CAF_CHECK_EQUAL
(
dm
.
reason
,
exit_reason
::
normal
);
&&
dm
.
reason
==
exit_reason
::
normal
CAF_CHECK_EQUAL
(
current_message
().
cvals
()
->
get_reference_count
(),
1
);
&&
current_message
().
cvals
()
->
get_reference_count
()
==
1
);
quit
();
quit
();
},
},
others
>>
[
&
]
{
others
>>
[
&
]
{
...
@@ -96,7 +103,19 @@ behavior tester::make_behavior() {
...
@@ -96,7 +103,19 @@ behavior tester::make_behavior() {
};
};
}
}
void
message_lifetime_in_scoped_actor
()
{
template
<
spawn_options
Os
>
void
test_message_lifetime
()
{
// put some preassure on the scheduler (check for thread safety)
for
(
size_t
i
=
0
;
i
<
100
;
++
i
)
{
spawn
<
tester
>
(
spawn
<
testee
,
Os
>
());
}
}
}
// namespace <anonymous>
CAF_TEST_FIXTURE_SCOPE
(
message_lifetime_tests
,
fixture
)
CAF_TEST
(
message_lifetime_in_scoped_actor
)
{
auto
msg
=
make_message
(
1
,
2
,
3
);
auto
msg
=
make_message
(
1
,
2
,
3
);
scoped_actor
self
;
scoped_actor
self
;
self
->
send
(
self
,
msg
);
self
->
send
(
self
,
msg
);
...
@@ -121,30 +140,12 @@ void message_lifetime_in_scoped_actor() {
...
@@ -121,30 +140,12 @@ void message_lifetime_in_scoped_actor() {
CAF_CHECK_EQUAL
(
msg
.
get_as
<
int
>
(
0
),
42
);
CAF_CHECK_EQUAL
(
msg
.
get_as
<
int
>
(
0
),
42
);
}
}
template
<
spawn_options
Os
>
CAF_TEST
(
message_lifetime_no_spawn_options
)
{
void
test_message_lifetime
()
{
message_lifetime_in_scoped_actor
();
// put some preassure on the scheduler (check for thread safety)
for
(
size_t
i
=
0
;
i
<
100
;
++
i
)
{
spawn
<
tester
>
(
spawn
<
testee
,
Os
>
());
}
}
}
// namespace <anonymous>
CAF_TEST
(
test_message_lifetime_in_scoped_actor
)
{
message_lifetime_in_scoped_actor
();
}
CAF_TEST
(
test_message_lifetime_no_spawn_options
)
{
CAF_MESSAGE
(
"test_message_lifetime<no_spawn_options>"
);
test_message_lifetime
<
no_spawn_options
>
();
test_message_lifetime
<
no_spawn_options
>
();
}
}
CAF_TEST
(
test_message_lifetime_priority_aware
)
{
CAF_TEST
(
message_lifetime_priority_aware
)
{
CAF_MESSAGE
(
"test_message_lifetime<priority_aware>"
);
test_message_lifetime
<
priority_aware
>
();
test_message_lifetime
<
priority_aware
>
();
await_all_actors_done
();
shutdown
();
}
}
CAF_TEST_FIXTURE_SCOPE_END
()
libcaf_core/test/serialization.cpp
View file @
ff54e90a
...
@@ -122,21 +122,21 @@ enum class test_enum {
...
@@ -122,21 +122,21 @@ enum class test_enum {
c
c
};
};
struct
common_
fixture
{
struct
fixture
{
int32_t
i32
=
-
345
;
int32_t
i32
=
-
345
;
test_enum
te
=
test_enum
::
b
;
test_enum
te
=
test_enum
::
b
;
string
str
=
"Lorem ipsum dolor sit amet."
;
string
str
=
"Lorem ipsum dolor sit amet."
;
raw_struct
rs
;
raw_struct
rs
;
message
msg
;
message
msg
;
common_
fixture
()
{
fixture
()
{
announce
<
test_enum
>
(
"test_enum"
);
announce
<
test_enum
>
(
"test_enum"
);
announce
(
typeid
(
raw_struct
),
uniform_type_info_ptr
{
new
raw_struct_type_info
});
announce
(
typeid
(
raw_struct
),
uniform_type_info_ptr
{
new
raw_struct_type_info
});
rs
.
str
.
assign
(
string
(
str
.
rbegin
(),
str
.
rend
()));
rs
.
str
.
assign
(
string
(
str
.
rbegin
(),
str
.
rend
()));
msg
=
make_message
(
i32
,
te
,
str
,
rs
);
msg
=
make_message
(
i32
,
te
,
str
,
rs
);
}
}
~
common_
fixture
()
{
~
fixture
()
{
await_all_actors_done
();
await_all_actors_done
();
shutdown
();
shutdown
();
}
}
...
@@ -211,7 +211,7 @@ struct is_message {
...
@@ -211,7 +211,7 @@ struct is_message {
}
// namespace <anonymous>
}
// namespace <anonymous>
CAF_TEST_FIXTURE_SCOPE
(
serialization_tests
,
common_
fixture
)
CAF_TEST_FIXTURE_SCOPE
(
serialization_tests
,
fixture
)
CAF_TEST
(
test_serialization
)
{
CAF_TEST
(
test_serialization
)
{
using
token
=
std
::
integral_constant
<
int
,
detail
::
impl_id
<
strmap
>
()
>
;
using
token
=
std
::
integral_constant
<
int
,
detail
::
impl_id
<
strmap
>
()
>
;
...
...
libcaf_core/test/spawn.cpp
View file @
ff54e90a
...
@@ -925,6 +925,36 @@ CAF_TEST(test_exit_reason_scoped_actor) {
...
@@ -925,6 +925,36 @@ CAF_TEST(test_exit_reason_scoped_actor) {
shutdown
();
shutdown
();
}
}
CAF_TEST
(
test_spawn_fun
)
{
class
my_actor
:
public
event_based_actor
{
public:
behavior
make_behavior
()
override
{
return
{
[
=
](
sys_atom
,
std
::
function
<
behavior
(
my_actor
*
)
>&
fun
)
{
become
(
fun
(
this
));
}
};
}
};
auto
ma
=
spawn
<
my_actor
>
();
std
::
function
<
behavior
(
my_actor
*
)
>
fun
=
[](
my_actor
*
)
->
behavior
{
return
{
[](
int
x
,
int
y
)
{
return
x
+
y
;
}
};
};
scoped_actor
self
;
self
->
send
(
ma
,
sys_atom
::
value
,
fun
);
self
->
sync_send
(
ma
,
10
,
20
).
await
(
[](
int
res
)
{
CAF_CHECK_EQUAL
(
res
,
10
+
20
);
}
);
self
->
send_exit
(
ma
,
exit_reason
::
kill
);
self
->
await_all_other_actors_done
();
}
CAF_TEST
(
test_number_of_instances
)
{
CAF_TEST
(
test_number_of_instances
)
{
CAF_CHECK_EQUAL
(
s_actor_instances
.
load
(),
0
);
CAF_CHECK_EQUAL
(
s_actor_instances
.
load
(),
0
);
CAF_MESSAGE
(
"max. nr. of actor instances: "
<<
s_max_actor_instances
.
load
());
CAF_MESSAGE
(
"max. nr. of actor instances: "
<<
s_max_actor_instances
.
load
());
...
...
libcaf_test/caf/test/unit_test.hpp
View file @
ff54e90a
...
@@ -36,6 +36,14 @@ namespace caf {
...
@@ -36,6 +36,14 @@ namespace caf {
class
message
;
class
message
;
namespace
test
{
namespace
test
{
/**
* A sequence of *checks*.
*/
class
check_sequence
{
virtual
~
check_sequence
();
virtual
void
run
()
=
0
;
};
/**
/**
* A sequence of *checks*.
* A sequence of *checks*.
*/
*/
...
@@ -61,7 +69,9 @@ class test {
...
@@ -61,7 +69,9 @@ class test {
return
m_bad
;
return
m_bad
;
}
}
virtual
void
run
()
=
0
;
void
run
();
virtual
std
::
unique_ptr
<
check_sequence
>
make_sequence
()
=
0
;
private:
private:
size_t
m_expected_failures
;
size_t
m_expected_failures
;
...
@@ -219,14 +229,12 @@ class engine {
...
@@ -219,14 +229,12 @@ class engine {
*/
*/
static
char
*
path
();
static
char
*
path
();
using
test_generator
=
std
::
function
<
std
::
unique_ptr
<
test
>
()
>
;
/**
/**
* Adds a test to the engine.
* Adds a test to the engine.
* @param name The name of the suite.
* @param name The name of the suite.
* @param t The test to register.
* @param t The test to register.
*/
*/
static
void
add
(
const
char
*
name
,
test_generator
generato
r
);
static
void
add
(
const
char
*
name
,
std
::
unique_ptr
<
test
>
pt
r
);
/**
/**
* Invokes tests in all suites.
* Invokes tests in all suites.
...
@@ -296,7 +304,7 @@ class engine {
...
@@ -296,7 +304,7 @@ class engine {
const
char
*
m_check_file
=
"<none>"
;
const
char
*
m_check_file
=
"<none>"
;
size_t
m_check_line
=
0
;
size_t
m_check_line
=
0
;
test
*
m_current_test
=
nullptr
;
test
*
m_current_test
=
nullptr
;
std
::
map
<
std
::
string
,
std
::
vector
<
test_generator
>>
m_suites
;
std
::
map
<
std
::
string
,
std
::
vector
<
std
::
unique_ptr
<
test
>
>>
m_suites
;
};
};
namespace
detail
{
namespace
detail
{
...
@@ -598,8 +606,7 @@ using caf_test_case_auto_fixture = caf::test::dummy_fixture;
...
@@ -598,8 +606,7 @@ using caf_test_case_auto_fixture = caf::test::dummy_fixture;
#define CAF_TEST(name) \
#define CAF_TEST(name) \
namespace { \
namespace { \
struct CAF_UNIQUE(test) : public ::caf::test::test, \
struct CAF_UNIQUE(test) : public ::caf::test::test { \
public caf_test_case_auto_fixture { \
CAF_UNIQUE(test)() : test{CAF_XSTR(name)} { } \
CAF_UNIQUE(test)() : test{CAF_XSTR(name)} { } \
void run() final; \
void run() final; \
}; \
}; \
...
...
libcaf_test/caf/test/unit_test_impl.hpp
View file @
ff54e90a
...
@@ -81,6 +81,10 @@ void watchdog::stop() {
...
@@ -81,6 +81,10 @@ void watchdog::stop() {
delete
s_watchdog
;
delete
s_watchdog
;
}
}
check_sequence
::~
check_sequence
()
{
// nop
}
test
::
test
(
std
::
string
test_name
)
test
::
test
(
std
::
string
test_name
)
:
m_expected_failures
(
0
),
:
m_expected_failures
(
0
),
m_name
(
std
::
move
(
test_name
)),
m_name
(
std
::
move
(
test_name
)),
...
@@ -114,6 +118,11 @@ const std::string& test::name() const {
...
@@ -114,6 +118,11 @@ const std::string& test::name() const {
return
m_name
;
return
m_name
;
}
}
void
test
::
run
()
{
auto
runner
=
make_sequence
();
runner
->
run
();
}
namespace
detail
{
namespace
detail
{
require_error
::
require_error
(
const
std
::
string
&
msg
)
:
std
::
logic_error
(
msg
)
{
require_error
::
require_error
(
const
std
::
string
&
msg
)
:
std
::
logic_error
(
msg
)
{
...
@@ -241,10 +250,16 @@ char* engine::path() {
...
@@ -241,10 +250,16 @@ char* engine::path() {
return
instance
().
m_path
;
return
instance
().
m_path
;
}
}
void
engine
::
add
(
const
char
*
cstr_name
,
test_generator
generato
r
)
{
void
engine
::
add
(
const
char
*
cstr_name
,
std
::
unique_ptr
<
test
>
pt
r
)
{
std
::
string
name
=
cstr_name
?
cstr_name
:
""
;
std
::
string
name
=
cstr_name
?
cstr_name
:
""
;
auto
&
suite
=
instance
().
m_suites
[
name
];
auto
&
suite
=
instance
().
m_suites
[
name
];
suite
.
emplace_back
(
std
::
move
(
generator
));
for
(
auto
&
x
:
suite
)
{
if
(
x
->
name
()
==
ptr
->
name
())
{
std
::
cout
<<
"duplicate test name: "
<<
ptr
->
name
()
<<
'\n'
;
std
::
abort
();
}
}
suite
.
emplace_back
(
std
::
move
(
ptr
));
}
}
bool
engine
::
run
(
bool
colorize
,
bool
engine
::
run
(
bool
colorize
,
...
...
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