Conversation
0fb4e3b to
bcb394d
Compare
|
This isn't PR material just yet, but I wanted to open it early enough for folks to take a look at how tests are looking like, and, ideally, compare it side-by-side with @brawner's fault injection tooling. There are cases that definitely suit mocking conceptually (e.g. dealing with bad system clocks), others not so much (e.g. failing a finalization). |
4233dee to
c9d722a
Compare
|
Total coverage is over 95%, but there're places where it is still below that mark. Those places were left out on purpose, and can be split into three (3) groups:
|
test/mocking_utils.hpp
Outdated
| #if !defined(_WIN32) | ||
| #if defined(__MACH__) | ||
|
|
||
| class fake_clock : unique_in_scope<fake_clock> |
There was a problem hiding this comment.
fake_* isn't a very helpful naming style for all these classes. What about rcutils_mock_* or something that helps people get where it's coming from and what its use is?
There was a problem hiding this comment.
Being an internal testing tool, I didn't see the need to standardize their names. But moving them out into rcpputils we have to.
test/mocking_utils.hpp
Outdated
|
|
||
| #else // defined(__MACH__) | ||
|
|
||
| class fake_clock : unique_in_scope<fake_clock> |
There was a problem hiding this comment.
Correct me if I'm wrong, but the only difference between these same class definitions is that do_clock_get_time returns a kern_return_t vs an int? Can you consolidate these differencese to a much smaller #if defined block to reduce duplicated code? I think some of the other classes can be consolidated in a similar way.
There was a problem hiding this comment.
Can you consolidate these differences to a much smaller #if defined block to reduce duplicated code?
In this particular case, yes we can. A few using directives can go a long way here.
In general, all "equivalent" classes can be consolidated into one, but in some cases I think interleaving all platform-specific details works against readability and thus I tend to split.
Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
c9d722a to
9e004d7
Compare
Blast545
left a comment
There was a problem hiding this comment.
Amazing work what you did here to improve Mimick's usage! Left a couple of minor comments to consider before merging
| fs.file_info(path).st_mode |= mocking_utils::filesystem::FileTypes::DIRECTORY; | ||
| fs.exhaust_file_descriptors(); | ||
| size = rcutils_calculate_directory_size(path, g_allocator); | ||
| EXPECT_EQ(0u, size); |
There was a problem hiding this comment.
Should be checked here as well the output from the error or errno? saw the rcutils_calculate_directory_size code and it's printed with fprintf to stderr, should that be changed to rcutils_set_error?
There was a problem hiding this comment.
It could, but I'd keep changes to rcutils implementation out of this PR. Same as before.
There was a problem hiding this comment.
Sounds good, I can help you opening an enhancement issue targeting that if you'd like.
Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
| }; | ||
|
|
||
| template<size_t N> | ||
| class FileSystem |
There was a problem hiding this comment.
I know it's a bit subjective and I suggested the opposite on a different file, but this class doesn't seem to reuse much code across #ifdef blocks. Since it's the filesystem and each OS handles it differently, I think this file makes sense define the full class in single ifdef blocks.
test/mocking_utils/patch.hpp
Outdated
| mmk_mock_define(mock_type, ReturnType); | ||
| }; | ||
|
|
||
| template<size_t N, typename ReturnType, typename ArgType0> |
There was a problem hiding this comment.
Is it not possible to use a parameter pack like you do the trampoline struct for the mmk_mock_define calls? I'm not familiar with parameter packs, but I'm guessing you would have used them if it were actually possible
There was a problem hiding this comment.
It's not because mmk_mock_define is a macro that needs all the parameter types given as separate arguments at the preprocessing stage -- it won't play along with parameter packs.
test/mocking_utils/patch.hpp
Outdated
| /// | ||
| /// Useful to enable patching functions that take arguments whose types | ||
| /// do not define basic comparison operators required by Mimick. | ||
| #define MOCKING_UTILS_DEFINE_DUMMY_OPERATOR(type, op) \ |
There was a problem hiding this comment.
suggest: MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE
Just so when people see it in code, it's a bit clearer what this macro is doing.
test/test_split.cpp
Outdated
| #include "rcutils/error_handling.h" | ||
| #include "rcutils/split.h" | ||
| #include "rcutils/types/string_array.h" | ||
| #include "rcutils/types/char_array.h" |
There was a problem hiding this comment.
That include actually shouldn't be there! It's a leftover, removed in 46a4c15.
Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
brawner
left a comment
There was a problem hiding this comment.
Looks good to me. Just a few minor comments.
| explicit FileSystem(const std::string & scope) | ||
| : opendir_mock_(MOCKING_UTILS_PATCH_TARGET(scope, opendir), | ||
| MOCKING_UTILS_PATCH_PROXY(opendir)), | ||
| #ifndef _GNU_SOURCE |
There was a problem hiding this comment.
Also seems like a good candidate for combining with the ifndef block at line 88 below. Line 87 is the only line shared between the two cases.
test/test_filesystem.cpp
Outdated
| EXPECT_FALSE(rcutils_is_readable(path)); | ||
| } | ||
| { | ||
| char * path = rcutils_join_path(this->test_path, "dummy_nonexisting_file.txt", g_allocator); |
There was a problem hiding this comment.
| char * path = rcutils_join_path(this->test_path, "dummy_nonexisting_file.txt", g_allocator); | |
| char * path = rcutils_join_path(this->test_path, "dummy_nonexistent_file.txt", g_allocator); |
test/test_filesystem.cpp
Outdated
| } | ||
| { | ||
| auto fs = mocking_utils::patch_filesystem("lib:rcutils"); | ||
| const char * path = "dummy_non_readable_file.txt"; |
There was a problem hiding this comment.
| const char * path = "dummy_non_readable_file.txt"; | |
| const char * path = "dummy_unreadable_file.txt"; |
test/test_filesystem.cpp
Outdated
| } | ||
| { | ||
| auto fs = mocking_utils::patch_filesystem("lib:rcutils"); | ||
| const char * path = "dummy_non_writable_file.txt"; |
There was a problem hiding this comment.
| const char * path = "dummy_non_writable_file.txt"; | |
| const char * path = "dummy_unwritable_file.txt"; |
Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
|
Well, it appears that there's something very peculiar about how I'll exclude the tests that mock |
Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
|
Oh well, |
Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
|
Alright, thanks for the reviews guys! |
|
I'm not completely sure if this PR is the root cause, but there are a bunch of new test failures on the nightlies https://ci.ros2.org/view/nightly/job/nightly_linux_release/1633/ (all related to rcutils tests). |
|
Indeed. Looks like another corner case when mocking |
Since most of them started 3 days ago (see https://ci.ros2.org/view/nightly/job/nightly_linux_extra_rmw_release/797/testReport/ and https://ci.ros2.org/view/nightly/job/nightly_linux_thread_sanitizer/504/testReport/) I would think so. |
|
Fix PR'd in #274. |
Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
Precisely what the title says, filling the gaps with mocks. Depends on ros2/Mimick#7.