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
9ebf640e
Unverified
Commit
9ebf640e
authored
Aug 18, 2023
by
Dominik Charousset
Committed by
GitHub
Aug 18, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1532
Re-implement inject in the deterministic fixture
parents
d6c99643
5571c169
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
118 additions
and
24 deletions
+118
-24
libcaf_core/CMakeLists.txt
libcaf_core/CMakeLists.txt
+1
-1
libcaf_core/caf/action.hpp
libcaf_core/caf/action.hpp
+10
-0
libcaf_core/caf/action.test.cpp
libcaf_core/caf/action.test.cpp
+21
-23
libcaf_test/caf/test/fixture/deterministic.hpp
libcaf_test/caf/test/fixture/deterministic.hpp
+86
-0
No files found.
libcaf_core/CMakeLists.txt
View file @
9ebf640e
...
...
@@ -71,6 +71,7 @@ caf_add_component(
caf/abstract_group.cpp
caf/abstract_mailbox.cpp
caf/action.cpp
caf/action.test.cpp
caf/actor.cpp
caf/actor_addr.cpp
caf/actor_clock.cpp
...
...
@@ -232,7 +233,6 @@ caf_add_component(
tests/legacy/core-test.cpp
tests/legacy/nasty.cpp
LEGACY_TEST_SUITES
action
actor_clock
actor_factory
actor_lifetime
...
...
libcaf_core/caf/action.hpp
View file @
9ebf640e
...
...
@@ -118,6 +118,16 @@ private:
impl_ptr
pimpl_
;
};
/// Checks whether two actions are equal by comparing their pointers.
inline
bool
operator
==
(
const
action
&
lhs
,
const
action
&
rhs
)
noexcept
{
return
lhs
.
ptr
()
==
rhs
.
ptr
();
}
/// Checks whether two actions are not equal by comparing their pointers.
inline
bool
operator
!=
(
const
action
&
lhs
,
const
action
&
rhs
)
noexcept
{
return
!
(
lhs
==
rhs
);
}
}
// namespace caf
namespace
caf
::
detail
{
...
...
libcaf_core/
tests/legacy/action
.cpp
→
libcaf_core/
caf/action.test
.cpp
View file @
9ebf640e
...
...
@@ -2,21 +2,15 @@
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
#define CAF_SUITE action
#include "caf/action.hpp"
#include "core-test.hpp"
using
namespace
caf
;
namespace
{
#include "caf/test/caf_test_main.hpp"
#include "caf/test/fixture/deterministic.hpp"
#include "caf/test/scenario.hpp"
using
fixture
=
test_coordinator_fixture
<>
;
#include "caf/event_based_actor.hpp"
}
// namespace
BEGIN_FIXTURE_SCOPE
(
fixture
)
using
namespace
caf
;
SCENARIO
(
"actions wrap function calls"
)
{
GIVEN
(
"an action wrapping a lambda"
)
{
...
...
@@ -24,21 +18,21 @@ SCENARIO("actions wrap function calls") {
THEN
(
"it calls the lambda and transitions from scheduled to invoked"
)
{
auto
called
=
false
;
auto
uut
=
make_action
([
&
called
]
{
called
=
true
;
});
CHECK
(
uut
.
scheduled
());
check
(
uut
.
scheduled
());
uut
.
run
();
CHECK
(
called
);
check
(
called
);
}
}
WHEN
(
"disposing the action"
)
{
THEN
(
"it transitions to disposed and run no longer calls the lambda"
)
{
auto
called
=
false
;
auto
uut
=
make_action
([
&
called
]
{
called
=
true
;
});
CHECK
(
uut
.
scheduled
());
check
(
uut
.
scheduled
());
uut
.
dispose
();
CHECK
(
uut
.
disposed
());
check
(
uut
.
disposed
());
uut
.
run
();
CHECK
(
!
called
);
CHECK
(
uut
.
disposed
());
check
(
!
called
);
check
(
uut
.
disposed
());
}
}
WHEN
(
"running the action multiple times"
)
{
...
...
@@ -48,7 +42,7 @@ SCENARIO("actions wrap function calls") {
uut
.
run
();
uut
.
run
();
uut
.
run
();
CHECK_EQ
(
n
,
3
);
check_eq
(
n
,
3
);
}
}
WHEN
(
"converting an action to a disposable"
)
{
...
...
@@ -56,13 +50,15 @@ SCENARIO("actions wrap function calls") {
auto
uut
=
make_action
([]
{});
auto
d1
=
uut
.
as_disposable
();
// const& overload
auto
d2
=
action
{
uut
}.
as_disposable
();
// && overload
CHECK_EQ
(
uut
.
ptr
(),
d1
.
ptr
());
CHECK_EQ
(
uut
.
ptr
(),
d2
.
ptr
());
check_eq
(
uut
.
ptr
(),
d1
.
ptr
());
check_eq
(
uut
.
ptr
(),
d2
.
ptr
());
}
}
}
}
WITH_FIXTURE
(
test
::
fixture
::
deterministic
)
{
SCENARIO
(
"actors run actions that they receive"
)
{
GIVEN
(
"a scheduled actor"
)
{
WHEN
(
"sending it an action"
)
{
...
...
@@ -73,11 +69,13 @@ SCENARIO("actors run actions that they receive") {
};
});
auto
n
=
0
;
inject
(
(
action
),
to
(
aut
).
with
(
make_action
([
&
n
]
{
++
n
;
}))
);
CHECK_EQ
(
n
,
1
);
inject
(
).
with
(
make_action
([
&
n
]
{
++
n
;
})).
to
(
aut
);
check_eq
(
n
,
1
);
}
}
}
}
END_FIXTURE_SCOPE
()
}
// WITH_FIXTURE(test::fixture::deterministic)
CAF_TEST_MAIN
()
libcaf_test/caf/test/fixture/deterministic.hpp
View file @
9ebf640e
...
...
@@ -318,6 +318,73 @@ public:
message_predicate
<
Ts
...
>
with_
;
};
/// Utility class for injecting messages into the mailbox of an actor and then
/// checking whether the actor handles the message as expected.
template
<
class
...
Ts
>
class
injector
{
public:
injector
(
deterministic
*
fix
,
detail
::
source_location
loc
,
Ts
...
values
)
:
fix_
(
fix
),
loc_
(
loc
),
values_
(
std
::
move
(
values
)...)
{
// nop
}
injector
()
=
delete
;
injector
(
injector
&&
)
noexcept
=
default
;
injector
&
operator
=
(
injector
&&
)
noexcept
=
default
;
injector
(
const
injector
&
)
=
delete
;
injector
&
operator
=
(
const
injector
&
)
=
delete
;
/// Adds a predicate for the sender of the next message that matches only if
/// the sender is `src`.
injector
&&
from
(
const
strong_actor_ptr
&
src
)
&&
{
from_
=
src
;
return
std
::
move
(
*
this
);
}
/// Adds a predicate for the sender of the next message that matches only if
/// the sender is `src`.
injector
&&
from
(
const
actor
&
src
)
&&
{
from_
=
actor_cast
<
strong_actor_ptr
>
(
src
);
return
std
::
move
(
*
this
);
}
/// Adds a predicate for the sender of the next message that matches only if
/// the sender is `src`.
template
<
class
...
Us
>
injector
&&
from
(
const
typed_actor
<
Us
...
>&
src
)
&&
{
from_
=
actor_cast
<
strong_actor_ptr
>
(
src
);
return
std
::
move
(
*
this
);
}
/// Sets the target actor for this injector, sends the message, and then
/// checks whether the actor handles the message as expected.
template
<
class
T
>
void
to
(
const
T
&
dst
)
&&
{
to_impl
(
dst
,
std
::
make_index_sequence
<
sizeof
...(
Ts
)
>
{});
}
private:
template
<
class
T
,
size_t
...
Is
>
void
to_impl
(
const
T
&
dst
,
std
::
index_sequence
<
Is
...
>
)
{
auto
ptr
=
actor_cast
<
abstract_actor
*>
(
dst
);
ptr
->
eq_impl
(
make_message_id
(),
from_
,
nullptr
,
make_message
(
std
::
get
<
Is
>
(
values_
)...));
fix_
->
expect
<
Ts
...
>
(
loc_
)
.
from
(
from_
)
.
with
(
std
::
get
<
Is
>
(
values_
)...)
.
to
(
dst
);
}
deterministic
*
fix_
;
detail
::
source_location
loc_
;
strong_actor_ptr
from_
;
std
::
tuple
<
Ts
...
>
values_
;
};
// -- friends ----------------------------------------------------------------
friend
class
mailbox_impl
;
...
...
@@ -379,6 +446,25 @@ public:
return
evaluator
<
Ts
...
>
{
this
,
loc
,
evaluator_algorithm
::
allow
};
}
/// Helper class for `inject` that only provides `with`.
struct
inject_helper
{
deterministic
*
fix
;
detail
::
source_location
loc
;
template
<
class
...
Ts
>
auto
with
(
Ts
...
values
)
{
return
injector
<
Ts
...
>
{
fix
,
loc
,
std
::
move
(
values
)...};
}
};
/// Starts an `inject` clause. Inject clauses provide a shortcut for sending a
/// message to an actor and then calling `expect` with the same arguments to
/// check whether the actor handles the message as expected.
auto
inject
(
const
detail
::
source_location
&
loc
=
detail
::
source_location
::
current
())
{
return
inject_helper
{
this
,
loc
};
}
/// Tries to prepone a message, i.e., reorders the messages in the mailbox of
/// the receiver such that the next call to `dispatch_message` will run it.
/// @returns `true` if the message could be preponed, `false` otherwise.
...
...
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