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
07acd352
Commit
07acd352
authored
Oct 13, 2019
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Extend unit tests for actor_system_config
parent
01102251
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
220 additions
and
40 deletions
+220
-40
libcaf_core/test/actor_system_config.cpp
libcaf_core/test/actor_system_config.cpp
+220
-40
No files found.
libcaf_core/test/actor_system_config.cpp
View file @
07acd352
...
...
@@ -22,41 +22,64 @@
#include "caf/test/dsl.hpp"
#include <deque>
#include <list>
#include <map>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using
namespace
caf
;
namespace
{
// TODO: switch to std::operator""s when switching to C++14
std
::
string
operator
""
_s
(
const
char
*
str
,
size_t
size
)
{
return
std
::
string
{
str
,
size
};
}
timespan
operator
""
_ms
(
unsigned
long
long
x
)
{
return
std
::
chrono
::
duration_cast
<
timespan
>
(
std
::
chrono
::
milliseconds
(
x
));
}
uri
operator
""
_u
(
const
char
*
str
,
size_t
size
)
{
return
unbox
(
make_uri
(
string_view
{
str
,
size
}));
}
atom_value
operator
""
_a
(
const
char
*
str
,
size_t
size
)
{
return
atom_from_string
(
string_view
{
str
,
size
});
}
using
string_list
=
std
::
vector
<
std
::
string
>
;
struct
config
:
actor_system_config
{
config
()
{
opt_group
{
custom_options_
,
"?foo"
}
.
add
<
std
::
string
>
(
"bar,b"
,
"some string parameter"
);
config_option_adder
options
(
string_view
category
)
{
return
opt_group
{
custom_options_
,
category
};
}
void
clear
()
{
content
.
clear
();
remainder
.
clear
();
}
};
struct
fixture
{
fixture
()
{
ini
<<
"[foo]
\n
bar=
\"
hello
\"
"
;
}
config
cfg
;
error
parse
(
string_list
args
)
{
opts
.
clear
();
remainder
.
clear
();
config
cfg
;
auto
result
=
cfg
.
parse
(
std
::
move
(
args
),
ini
);
opts
=
content
(
cfg
);
remainder
=
cfg
.
remainder
;
return
result
;
config_option_adder
options
(
string_view
category
)
{
return
cfg
.
options
(
category
);
}
std
::
stringstream
ini
;
settings
opts
;
std
::
vector
<
std
::
string
>
remainder
;
void
parse
(
const
char
*
file_content
,
string_list
args
=
{})
{
cfg
.
clear
();
cfg
.
remainder
.
clear
();
std
::
istringstream
ini
{
file_content
};
if
(
auto
err
=
cfg
.
parse
(
std
::
move
(
args
),
ini
))
CAF_FAIL
(
"parse() failed: "
<<
cfg
.
render
(
err
));
}
};
}
// namespace
...
...
@@ -64,37 +87,194 @@ struct fixture {
CAF_TEST_FIXTURE_SCOPE
(
actor_system_config_tests
,
fixture
)
CAF_TEST
(
parsing
-
without
CLI
arguments
)
{
CAF_CHECK_EQUAL
(
parse
({}),
none
);
CAF_CHECK
(
remainder
.
empty
());
CAF_CHECK_EQUAL
(
get_or
(
opts
,
"foo.bar"
,
""
),
"hello"
);
auto
text
=
"[foo]
\n
bar=
\"
hello
\"
"
;
options
(
"?foo"
).
add
<
std
::
string
>
(
"bar,b"
,
"some string parameter"
);
parse
(
text
);
CAF_CHECK
(
cfg
.
remainder
.
empty
());
CAF_CHECK_EQUAL
(
get_or
(
cfg
,
"foo.bar"
,
""
),
"hello"
);
}
CAF_TEST
(
parsing
-
without
CLI
remainder
)
{
CAF_TEST
(
parsing
-
without
CLI
cfg
.
remainder
)
{
auto
text
=
"[foo]
\n
bar=
\"
hello
\"
"
;
options
(
"?foo"
).
add
<
std
::
string
>
(
"bar,b"
,
"some string parameter"
);
CAF_MESSAGE
(
"CLI long name"
);
CAF_CHECK_EQUAL
(
parse
({
"--foo.bar=test"
}),
none
);
CAF_CHECK
(
remainder
.
empty
());
CAF_CHECK_EQUAL
(
get_or
(
opts
,
"foo.bar"
,
""
),
"test"
);
parse
(
text
,
{
"--foo.bar=test"
}
);
CAF_CHECK
(
cfg
.
remainder
.
empty
());
CAF_CHECK_EQUAL
(
get_or
(
cfg
,
"foo.bar"
,
""
),
"test"
);
CAF_MESSAGE
(
"CLI abbreviated long name"
);
CAF_CHECK_EQUAL
(
parse
({
"--bar=test"
}),
none
);
CAF_CHECK
(
remainder
.
empty
());
CAF_CHECK_EQUAL
(
get_or
(
opts
,
"foo.bar"
,
""
),
"test"
);
parse
(
text
,
{
"--bar=test"
}
);
CAF_CHECK
(
cfg
.
remainder
.
empty
());
CAF_CHECK_EQUAL
(
get_or
(
cfg
,
"foo.bar"
,
""
),
"test"
);
CAF_MESSAGE
(
"CLI short name"
);
CAF_CHECK_EQUAL
(
parse
({
"-b"
,
"test"
}),
none
);
CAF_CHECK
(
remainder
.
empty
());
CAF_CHECK_EQUAL
(
get_or
(
opts
,
"foo.bar"
,
""
),
"test"
);
parse
(
text
,
{
"-b"
,
"test"
}
);
CAF_CHECK
(
cfg
.
remainder
.
empty
());
CAF_CHECK_EQUAL
(
get_or
(
cfg
,
"foo.bar"
,
""
),
"test"
);
CAF_MESSAGE
(
"CLI short name without whitespace"
);
CAF_CHECK_EQUAL
(
parse
({
"-btest"
}),
none
);
CAF_CHECK
(
remainder
.
empty
());
CAF_CHECK_EQUAL
(
get_or
(
opts
,
"foo.bar"
,
""
),
"test"
);
parse
(
text
,
{
"-btest"
});
CAF_CHECK
(
cfg
.
remainder
.
empty
());
CAF_CHECK_EQUAL
(
get_or
(
cfg
,
"foo.bar"
,
""
),
"test"
);
}
CAF_TEST
(
parsing
-
with
CLI
cfg
.
remainder
)
{
auto
text
=
"[foo]
\n
bar=
\"
hello
\"
"
;
options
(
"?foo"
).
add
<
std
::
string
>
(
"bar,b"
,
"some string parameter"
);
CAF_MESSAGE
(
"valid cfg.remainder"
);
parse
(
text
,
{
"-b"
,
"test"
,
"hello"
,
"world"
});
CAF_CHECK_EQUAL
(
get_or
(
cfg
,
"foo.bar"
,
""
),
"test"
);
CAF_CHECK_EQUAL
(
cfg
.
remainder
,
string_list
({
"hello"
,
"world"
}));
CAF_MESSAGE
(
"invalid cfg.remainder"
);
}
// Checks whether both a synced variable and the corresponding entry in
// content(cfg) are equal to `value`.
#define CHECK_SYNCED(var, value) \
do { \
CAF_CHECK_EQUAL(var, value); \
CAF_CHECK_EQUAL(get_if<decltype(var)>(&cfg, #var), value); \
} while (false)
// Checks whether an entry in content(cfg) is equal to `value`.
#define CHECK_TEXT_ONLY(type, var, value) \
CAF_CHECK_EQUAL(get_if<type>(&cfg, #var), value)
#define ADD(var) add(var, #var, "...")
#define VAR(type) \
auto some_##type = type{}; \
options("global").add(some_##type, "some_" #type, "...")
#define NAMED_VAR(type, name) \
auto name = type{}; \
options("global").add(name, #name, "...")
CAF_TEST
(
integers
and
integer
containers
options
)
{
// Use a wild mess of "list-like" and "map-like" containers from the STL.
using
int_list
=
std
::
vector
<
int
>
;
using
int_list_list
=
std
::
list
<
std
::
deque
<
int
>>
;
using
int_map
=
std
::
unordered_map
<
std
::
string
,
int
>
;
using
int_list_map
=
std
::
map
<
std
::
string
,
std
::
unordered_set
<
int
>>
;
using
int_map_list
=
std
::
set
<
std
::
map
<
std
::
string
,
int
>>
;
auto
text
=
R"__(
some_int = 42
yet_another_int = 123
some_int_list = [1, 2, 3]
some_int_list_list = [[1, 2, 3], [4, 5, 6]]
some_int_map = {a = 1, b = 2, c = 3}
some_int_list_map = {a = [1, 2, 3], b = [4, 5, 6]}
some_int_map_list = [{a = 1, b = 2, c = 3}, {d = 4, e = 5, f = 6}]
)__"
;
NAMED_VAR
(
int
,
some_other_int
);
VAR
(
int
);
VAR
(
int_list
);
VAR
(
int_list_list
);
VAR
(
int_map
);
VAR
(
int_list_map
);
VAR
(
int_map_list
);
parse
(
text
,
{
"--some_other_int=23"
});
CHECK_SYNCED
(
some_int
,
42
);
CHECK_SYNCED
(
some_other_int
,
23
);
CHECK_TEXT_ONLY
(
int
,
yet_another_int
,
123
);
CHECK_SYNCED
(
some_int_list
,
int_list
({
1
,
2
,
3
}));
CHECK_SYNCED
(
some_int_list_list
,
int_list_list
({{
1
,
2
,
3
},
{
4
,
5
,
6
}}));
CHECK_SYNCED
(
some_int_map
,
int_map
({{{
"a"
,
1
},
{
"b"
,
2
},
{
"c"
,
3
}}}));
CHECK_SYNCED
(
some_int_list_map
,
int_list_map
({{{
"a"
,
{
1
,
2
,
3
}},
{
"b"
,
{
4
,
5
,
6
}}}}));
CHECK_SYNCED
(
some_int_map_list
,
int_map_list
({{{
"a"
,
1
},
{
"b"
,
2
},
{
"c"
,
3
}},
{{
"d"
,
4
},
{
"e"
,
5
},
{
"f"
,
6
}}}));
}
CAF_TEST
(
parsing
-
with
CLI
remainder
)
{
CAF_MESSAGE
(
"valid remainder"
);
CAF_CHECK_EQUAL
(
parse
({
"-b"
,
"test"
,
"hello"
,
"world"
}),
none
);
CAF_CHECK_EQUAL
(
get_or
(
opts
,
"foo.bar"
,
""
),
"test"
);
CAF_CHECK_EQUAL
(
remainder
,
string_list
({
"hello"
,
"world"
}));
CAF_MESSAGE
(
"invalid remainder"
);
CAF_CHECK_NOT_EQUAL
(
parse
({
"-b"
,
"test"
,
"-abc"
}),
none
);
CAF_TEST
(
basic
and
basic
containers
options
)
{
using
std
::
map
;
using
std
::
string
;
using
std
::
vector
;
using
int_list
=
vector
<
int
>
;
using
bool_list
=
vector
<
bool
>
;
using
double_list
=
vector
<
double
>
;
using
atom_value_list
=
vector
<
atom_value
>
;
using
timespan_list
=
vector
<
timespan
>
;
using
uri_list
=
vector
<
uri
>
;
using
string_list
=
vector
<
string
>
;
using
int_map
=
map
<
string
,
int
>
;
using
bool_map
=
map
<
string
,
bool
>
;
using
double_map
=
map
<
string
,
double
>
;
using
atom_value_map
=
map
<
string
,
atom_value
>
;
using
timespan_map
=
map
<
string
,
timespan
>
;
using
uri_map
=
map
<
string
,
uri
>
;
using
string_map
=
map
<
string
,
string
>
;
auto
text
=
R"__(
some_int = 42
some_bool = true
some_double = 1e23
some_atom_value = 'atom'
some_timespan = 123ms
some_uri = <foo:bar>
some_string = "string"
some_int_list = [1, 2, 3]
some_bool_list = [false, true]
some_double_list = [1., 2., 3.]
some_atom_value_list = ['a', 'b', 'c']
some_timespan_list = [123ms, 234ms, 345ms]
some_uri_list = [<foo:a>, <foo:b>, <foo:c>]
some_string_list = ["a", "b", "c"]
some_int_map = {a = 1, b = 2, c = 3}
some_bool_map = {a = true, b = false}
some_double_map = {a = 1., b = 2., c = 3.}
some_atom_value_map = {a = '1', b = '2', c = '3'}
some_timespan_map = {a = 123ms, b = 234ms, c = 345ms}
some_uri_map = {a = <foo:a>, b = <foo:b>, c = <foo:c>}
some_string_map = {a = "1", b = "2", c = "3"}
)__"
;
VAR
(
int
);
VAR
(
bool
);
VAR
(
double
);
VAR
(
atom_value
);
VAR
(
timespan
);
VAR
(
uri
);
VAR
(
string
);
VAR
(
int_list
);
VAR
(
bool_list
);
VAR
(
double_list
);
VAR
(
atom_value_list
);
VAR
(
timespan_list
);
VAR
(
uri_list
);
VAR
(
string_list
);
VAR
(
int_map
);
VAR
(
bool_map
);
VAR
(
double_map
);
VAR
(
atom_value_map
);
VAR
(
timespan_map
);
VAR
(
uri_map
);
VAR
(
string_map
);
parse
(
text
);
CAF_MESSAGE
(
"check primitive types"
);
CHECK_SYNCED
(
some_int
,
42
);
CHECK_SYNCED
(
some_bool
,
true
);
CHECK_SYNCED
(
some_double
,
1e23
);
CHECK_SYNCED
(
some_atom_value
,
"atom"
_a
);
CHECK_SYNCED
(
some_timespan
,
123
_ms
);
CHECK_SYNCED
(
some_uri
,
"foo:bar"
_u
);
CHECK_SYNCED
(
some_string
,
"string"
_s
);
CAF_MESSAGE
(
"check list types"
);
CHECK_SYNCED
(
some_int_list
,
int_list
({
1
,
2
,
3
}));
CHECK_SYNCED
(
some_bool_list
,
bool_list
({
false
,
true
}));
CHECK_SYNCED
(
some_double_list
,
double_list
({
1.
,
2.
,
3.
}));
CHECK_SYNCED
(
some_atom_value_list
,
atom_value_list
({
"a"
_a
,
"b"
_a
,
"c"
_a
}));
CHECK_SYNCED
(
some_timespan_list
,
timespan_list
({
123
_ms
,
234
_ms
,
345
_ms
}));
CHECK_SYNCED
(
some_uri_list
,
uri_list
({
"foo:a"
_u
,
"foo:b"
_u
,
"foo:c"
_u
}));
CHECK_SYNCED
(
some_string_list
,
string_list
({
"a"
,
"b"
,
"c"
}));
CAF_MESSAGE
(
"check dictionary types"
);
CHECK_SYNCED
(
some_int_map
,
int_map
({{
"a"
,
1
},
{
"b"
,
2
},
{
"c"
,
3
}}));
CHECK_SYNCED
(
some_bool_map
,
bool_map
({{
"a"
,
true
},
{
"b"
,
false
}}));
CHECK_SYNCED
(
some_double_map
,
double_map
({{
"a"
,
1.
},
{
"b"
,
2.
},
{
"c"
,
3.
}}));
CHECK_SYNCED
(
some_atom_value_map
,
atom_value_map
({{
"a"
,
"1"
_a
},
{
"b"
,
"2"
_a
},
{
"c"
,
"3"
_a
}}));
CHECK_SYNCED
(
some_timespan_map
,
timespan_map
({{
"a"
,
123
_ms
},
{
"b"
,
234
_ms
},
{
"c"
,
345
_ms
}}));
CHECK_SYNCED
(
some_uri_map
,
uri_map
({{
"a"
,
"foo:a"
_u
},
{
"b"
,
"foo:b"
_u
},
{
"c"
,
"foo:c"
_u
}}));
CHECK_SYNCED
(
some_string_map
,
string_map
({{
"a"
,
"1"
},
{
"b"
,
"2"
},
{
"c"
,
"3"
}}));
}
CAF_TEST_FIXTURE_SCOPE_END
()
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