-
Notifications
You must be signed in to change notification settings - Fork 112
Complete rcutils API coverage #272
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
9e004d7
164a36d
253d053
e4cbb8a
b5098df
83140ec
46a4c15
418a433
004f3ca
018a0cf
55d5c3d
893c09c
c8db8bd
44109e7
2aaa433
3f6416c
55dfebe
44194a1
1758045
b22a57d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,172 @@ | ||
| // Copyright 2020 Open Source Robotics Foundation, Inc. | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| #ifndef MOCKING_UTILS__FILESYSTEM_HPP_ | ||
| #define MOCKING_UTILS__FILESYSTEM_HPP_ | ||
|
|
||
| #include <stdio.h> | ||
| #include <string.h> | ||
| #include <sys/stat.h> | ||
|
|
||
| #ifndef _WIN32 | ||
| #include <sys/types.h> | ||
| #include <dirent.h> | ||
| #else | ||
| #include <windows.h> | ||
| #endif | ||
|
|
||
| #include <map> | ||
| #include <string> | ||
| #include <type_traits> | ||
|
|
||
| #include "rcutils/macros.h" | ||
|
|
||
| #include "patch.hpp" | ||
|
|
||
| namespace mocking_utils | ||
| { | ||
| namespace filesystem | ||
| { | ||
|
|
||
| struct FileTypes | ||
| { | ||
| static constexpr mode_t REGULAR_FILE = S_IFREG; | ||
| static constexpr mode_t DIRECTORY = S_IFDIR; | ||
| }; | ||
|
|
||
| struct Permissions | ||
| { | ||
| #ifndef _WIN32 | ||
| static constexpr mode_t USER_READABLE = S_IRUSR; | ||
| static constexpr mode_t USER_WRITABLE = S_IWUSR; | ||
| #else | ||
| static constexpr mode_t USER_READABLE = _S_IREAD; | ||
| static constexpr mode_t USER_WRITABLE = _S_IWRITE; | ||
| #endif | ||
| }; | ||
|
|
||
| template<size_t N> | ||
| class FileSystem | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 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.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See 83140ec. |
||
| { | ||
| public: | ||
| explicit FileSystem(const std::string & target) | ||
| #ifndef _WIN32 | ||
| : opendir_mock_(MOCKING_UTILS_PATCH_TARGET(target, opendir), | ||
| MOCKING_UTILS_PATCH_PROXY(opendir)), | ||
| #else | ||
| : find_first_file_mock_(MOCKING_UTILS_PATCH_TARGET(target, FindFirstFile), | ||
| MOCKING_UTILS_PATCH_PROXY(FindFirstFile)), | ||
| #endif | ||
| #ifndef _GNU_SOURCE | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 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. |
||
| stat_mock_(MOCKING_UTILS_PATCH_TARGET(target, stat), | ||
| MOCKING_UTILS_PATCH_PROXY(stat)) | ||
| #else | ||
| __xstat_mock_(MOCKING_UTILS_PATCH_TARGET(target, __xstat), | ||
| MOCKING_UTILS_PATCH_PROXY(__xstat)) | ||
| #endif | ||
| { | ||
| #ifndef _WIN32 | ||
| opendir_mock_.then_call(std::bind(&FileSystem::do_opendir, this, std::placeholders::_1)); | ||
| #else | ||
| find_first_file_mock_.then_call( | ||
| std::bind( | ||
| &FileSystem::do_FindFirstFile, this, | ||
| std::placeholders::_1, std::placeholders::_2)) | ||
| #endif | ||
| #ifndef _GNU_SOURCE | ||
| stat_mock_.then_call( | ||
| std::bind( | ||
| &FileSystem::do_stat, this, | ||
| std::placeholders::_1, std::placeholders::_2)); | ||
| #else | ||
| __xstat_mock_.then_call( | ||
| std::bind( | ||
| &FileSystem::do___xstat, this, std::placeholders::_1, | ||
| std::placeholders::_2, std::placeholders::_3)); | ||
| #endif | ||
| } | ||
|
|
||
| void exhaust_file_descriptors() | ||
| { | ||
| #ifdef _WIN32 | ||
| forced_errno_ = ERROR_NO_MORE_SEARCH_HANDLES; | ||
| #else | ||
| forced_errno_ = EMFILE; | ||
| #endif | ||
| } | ||
|
|
||
| struct stat & file_info(const std::string & path) | ||
| { | ||
| return files_info_[path]; | ||
| } | ||
|
|
||
| private: | ||
| #ifndef _WIN32 | ||
| DIR * do_opendir(const char *) | ||
| { | ||
| if (forced_errno_ != 0) { | ||
| errno = forced_errno_; | ||
| return NULL; | ||
| } | ||
| errno = ENOENT; | ||
| return NULL; | ||
| } | ||
| MOCKING_UTILS_PATCH_TYPE(N, opendir) opendir_mock_; | ||
| #else | ||
| HANDLE do_FindFirstFile(LPCSTR, LPWIN32_FIND_DATAA) | ||
| { | ||
| if (forced_errno_ != 0) { | ||
| SetLastError(forced_errno_); | ||
| return INVALID_HANDLE_VALUE; | ||
| } | ||
| SetLastError(ERROR_FILE_NOT_FOUND); | ||
| return INVALID_HANDLE_VALUE; | ||
| } | ||
|
|
||
| MOCKING_UTILS_PATCH_TYPE(N, FindFirstFile) find_first_file_mock_; | ||
| #endif | ||
|
|
||
| #ifndef _GNU_SOURCE | ||
| int do_stat(const char * path, struct stat * info) | ||
| { | ||
| #else | ||
| int do___xstat(int, const char * path, struct stat * info) | ||
| { | ||
| #endif | ||
| if (files_info_.count(path) == 0) { | ||
| errno = ENOENT; | ||
| return -1; | ||
| } | ||
| *info = files_info_[path]; | ||
| return 0; | ||
| } | ||
|
|
||
| #ifndef _GNU_SOURCE | ||
| MOCKING_UTILS_PATCH_TYPE(N, stat) stat_mock_; | ||
| #else | ||
| MOCKING_UTILS_PATCH_TYPE(N, __xstat) __xstat_mock_; | ||
| #endif | ||
|
|
||
| int forced_errno_{0}; | ||
| std::map<std::string, struct stat> files_info_; | ||
| }; | ||
|
|
||
| } // namespace filesystem | ||
|
|
||
| /// Patch filesystem API, based on `what` binary object should be affected. | ||
| #define patch_filesystem(what) filesystem::FileSystem<__COUNTER__>(what) | ||
|
|
||
| } // namespace mocking_utils | ||
|
|
||
| #endif // MOCKING_UTILS__FILESYSTEM_HPP_ | ||
Uh oh!
There was an error while loading. Please reload this page.