Add mocking unit tests for rcl_yaml_param_parser (coverage part 3/3) (#772)
* Add mocking unit tests for rcl_yaml Signed-off-by: Stephen Brawner <brawner@gmail.com> * deallocate test_path Signed-off-by: Stephen Brawner <brawner@gmail.com> * Fix memory leaks Signed-off-by: Stephen Brawner <brawner@gmail.com>
This commit is contained in:
parent
08bbdde860
commit
b62b83b5cd
5 changed files with 494 additions and 2 deletions
|
@ -107,7 +107,7 @@ if(BUILD_TESTING)
|
|||
"rcutils"
|
||||
"osrf_testing_tools_cpp"
|
||||
)
|
||||
target_link_libraries(test_parse ${PROJECT_NAME})
|
||||
target_link_libraries(test_parse ${PROJECT_NAME} mimick)
|
||||
endif()
|
||||
|
||||
ament_add_gtest(test_parser
|
||||
|
@ -119,7 +119,7 @@ if(BUILD_TESTING)
|
|||
"rcutils"
|
||||
"osrf_testing_tools_cpp"
|
||||
)
|
||||
target_link_libraries(test_parser ${PROJECT_NAME})
|
||||
target_link_libraries(test_parser ${PROJECT_NAME} mimick)
|
||||
target_compile_definitions(test_parser PUBLIC RCUTILS_ENABLE_FAULT_INJECTION)
|
||||
endif()
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
<test_depend>ament_cmake_gtest</test_depend>
|
||||
<test_depend>ament_lint_common</test_depend>
|
||||
<test_depend>ament_lint_auto</test_depend>
|
||||
<test_depend>mimick_vendor</test_depend>
|
||||
<test_depend>osrf_testing_tools_cpp</test_depend>
|
||||
<test_depend>performance_test_fixture</test_depend>
|
||||
<test_depend>rcpputils</test_depend>
|
||||
|
|
376
rcl_yaml_param_parser/test/mocking_utils/patch.hpp
Normal file
376
rcl_yaml_param_parser/test/mocking_utils/patch.hpp
Normal file
|
@ -0,0 +1,376 @@
|
|||
// 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.
|
||||
|
||||
// Original file taken from:
|
||||
// https://github.com/ros2/rcutils/blob/master/test/mocking_utils/patch.hpp
|
||||
|
||||
#ifndef MOCKING_UTILS__PATCH_HPP_
|
||||
#define MOCKING_UTILS__PATCH_HPP_
|
||||
|
||||
#define MOCKING_UTILS_SUPPORT_VA_LIST
|
||||
#if (defined(__aarch64__) || defined(__arm__) || defined(_M_ARM) || defined(__thumb__))
|
||||
// In ARM machines, va_list does not define comparison operators
|
||||
// nor the compiler allows defining them via operator overloads.
|
||||
// Thus, Mimick argument matching code will not compile.
|
||||
#undef MOCKING_UTILS_SUPPORT_VA_LIST
|
||||
#endif
|
||||
|
||||
#ifdef MOCKING_UTILS_SUPPORT_VA_LIST
|
||||
#include <cstdarg>
|
||||
#endif
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "mimick/mimick.h"
|
||||
#include "rcutils/macros.h"
|
||||
|
||||
namespace mocking_utils
|
||||
{
|
||||
|
||||
/// Mimick specific traits for each mocking_utils::Patch instance.
|
||||
/**
|
||||
* \tparam ID Numerical identifier of the patch. Ought to be unique.
|
||||
* \tparam SignatureT Type of the symbol to be patched.
|
||||
*/
|
||||
template<size_t ID, typename SignatureT>
|
||||
struct PatchTraits;
|
||||
|
||||
/// Traits specialization for ReturnT(void) free functions.
|
||||
/**
|
||||
* \tparam ID Numerical identifier of the patch. Ought to be unique.
|
||||
* \tparam ReturnT Return value type.
|
||||
*/
|
||||
template<size_t ID, typename ReturnT>
|
||||
struct PatchTraits<ID, ReturnT(void)>
|
||||
{
|
||||
mmk_mock_define(mock_type, ReturnT);
|
||||
};
|
||||
|
||||
/// Traits specialization for ReturnT(ArgT0) free functions.
|
||||
/**
|
||||
* \tparam ID Numerical identifier of the patch. Ought to be unique.
|
||||
* \tparam ReturnT Return value type.
|
||||
* \tparam ArgT0 Argument type.
|
||||
*/
|
||||
template<size_t ID, typename ReturnT, typename ArgT0>
|
||||
struct PatchTraits<ID, ReturnT(ArgT0)>
|
||||
{
|
||||
mmk_mock_define(mock_type, ReturnT, ArgT0);
|
||||
};
|
||||
|
||||
/// Traits specialization for ReturnT(ArgT0, ArgT1) free functions.
|
||||
/**
|
||||
* \tparam ID Numerical identifier of the patch. Ought to be unique.
|
||||
* \tparam ReturnT Return value type.
|
||||
* \tparam ArgTx Argument types.
|
||||
*/
|
||||
template<size_t ID, typename ReturnT,
|
||||
typename ArgT0, typename ArgT1>
|
||||
struct PatchTraits<ID, ReturnT(ArgT0, ArgT1)>
|
||||
{
|
||||
mmk_mock_define(mock_type, ReturnT, ArgT0, ArgT1);
|
||||
};
|
||||
|
||||
/// Traits specialization for ReturnT(ArgT0, ArgT1, ArgT2) free functions.
|
||||
/**
|
||||
* \tparam ID Numerical identifier of the patch. Ought to be unique.
|
||||
* \tparam ReturnT Return value type.
|
||||
* \tparam ArgTx Argument types.
|
||||
*/
|
||||
template<size_t ID, typename ReturnT,
|
||||
typename ArgT0, typename ArgT1, typename ArgT2>
|
||||
struct PatchTraits<ID, ReturnT(ArgT0, ArgT1, ArgT2)>
|
||||
{
|
||||
mmk_mock_define(mock_type, ReturnT, ArgT0, ArgT1, ArgT2);
|
||||
};
|
||||
|
||||
/// Traits specialization for ReturnT(ArgT0, ArgT1, ArgT2, ArgT3) free functions.
|
||||
/**
|
||||
* \tparam ID Numerical identifier of the patch. Ought to be unique.
|
||||
* \tparam ReturnT Return value type.
|
||||
* \tparam ArgTx Argument types.
|
||||
*/
|
||||
template<size_t ID, typename ReturnT,
|
||||
typename ArgT0, typename ArgT1,
|
||||
typename ArgT2, typename ArgT3>
|
||||
struct PatchTraits<ID, ReturnT(ArgT0, ArgT1, ArgT2, ArgT3)>
|
||||
{
|
||||
mmk_mock_define(mock_type, ReturnT, ArgT0, ArgT1, ArgT2, ArgT3);
|
||||
};
|
||||
|
||||
/// Traits specialization for ReturnT(ArgT0, ArgT1, ArgT2, ArgT3, ArgT4)
|
||||
/// free functions.
|
||||
/**
|
||||
* \tparam ID Numerical identifier of the patch. Ought to be unique.
|
||||
* \tparam ReturnT Return value type.
|
||||
* \tparam ArgTx Argument types.
|
||||
*/
|
||||
template<size_t ID, typename ReturnT,
|
||||
typename ArgT0, typename ArgT1,
|
||||
typename ArgT2, typename ArgT3, typename ArgT4>
|
||||
struct PatchTraits<ID, ReturnT(ArgT0, ArgT1, ArgT2, ArgT3, ArgT4)>
|
||||
{
|
||||
mmk_mock_define(mock_type, ReturnT, ArgT0, ArgT1, ArgT2, ArgT3, ArgT4);
|
||||
};
|
||||
|
||||
/// Traits specialization for ReturnT(ArgT0, ArgT1, ArgT2, ArgT3, ArgT4, ArgT5)
|
||||
/// free functions.
|
||||
/**
|
||||
* \tparam ID Numerical identifier of the patch. Ought to be unique.
|
||||
* \tparam ReturnT Return value type.
|
||||
* \tparam ArgTx Argument types.
|
||||
*/
|
||||
template<size_t ID, typename ReturnT,
|
||||
typename ArgT0, typename ArgT1,
|
||||
typename ArgT2, typename ArgT3,
|
||||
typename ArgT4, typename ArgT5>
|
||||
struct PatchTraits<ID, ReturnT(ArgT0, ArgT1, ArgT2, ArgT3, ArgT4, ArgT5)>
|
||||
{
|
||||
mmk_mock_define(
|
||||
mock_type, ReturnT, ArgT0, ArgT1, ArgT2, ArgT3, ArgT4, ArgT5);
|
||||
};
|
||||
|
||||
/// Generic trampoline to wrap generalized callables in plain functions.
|
||||
/**
|
||||
* \tparam ID Numerical identifier of this trampoline. Ought to be unique.
|
||||
* \tparam SignatureT Type of the symbol this trampoline replaces.
|
||||
*/
|
||||
template<size_t ID, typename SignatureT>
|
||||
struct Trampoline;
|
||||
|
||||
/// Trampoline specialization for free functions.
|
||||
template<size_t ID, typename ReturnT, typename ... ArgTs>
|
||||
struct Trampoline<ID, ReturnT(ArgTs...)>
|
||||
{
|
||||
static ReturnT base(ArgTs... args)
|
||||
{
|
||||
return target(std::forward<ArgTs>(args)...);
|
||||
}
|
||||
|
||||
static std::function<ReturnT(ArgTs...)> target;
|
||||
};
|
||||
|
||||
template<size_t ID, typename ReturnT, typename ... ArgTs>
|
||||
std::function<ReturnT(ArgTs...)>
|
||||
Trampoline<ID, ReturnT(ArgTs...)>::target;
|
||||
|
||||
/// Setup trampoline with the given @p target.
|
||||
/**
|
||||
* \param[in] target Callable that this trampoline will target.
|
||||
* \return the plain base function of this trampoline.
|
||||
*
|
||||
* \tparam ID Numerical identifier of this trampoline. Ought to be unique.
|
||||
* \tparam SignatureT Type of the symbol this trampoline replaces.
|
||||
*/
|
||||
template<size_t ID, typename SignatureT>
|
||||
auto prepare_trampoline(std::function<SignatureT> target)
|
||||
{
|
||||
Trampoline<ID, SignatureT>::target = target;
|
||||
return Trampoline<ID, SignatureT>::base;
|
||||
}
|
||||
|
||||
/// Patch class for binary API mocking
|
||||
/**
|
||||
* Built on top of Mimick, to enable symbol mocking on a per dynamically
|
||||
* linked binary object basis.
|
||||
*
|
||||
* \tparam ID Numerical identifier for this patch. Ought to be unique.
|
||||
* \tparam SignatureT Type of the symbol to be patched.
|
||||
*/
|
||||
template<size_t ID, typename SignatureT>
|
||||
class Patch;
|
||||
|
||||
/// Patch specialization for ReturnT(ArgTs...) free functions.
|
||||
/**
|
||||
* \tparam ID Numerical identifier for this patch. Ought to be unique.
|
||||
* \tparam ReturnT Return value type.
|
||||
* \tparam ArgTs Argument types.
|
||||
*/
|
||||
template<size_t ID, typename ReturnT, typename ... ArgTs>
|
||||
class Patch<ID, ReturnT(ArgTs...)>
|
||||
{
|
||||
public:
|
||||
using mock_type = typename PatchTraits<ID, ReturnT(ArgTs...)>::mock_type;
|
||||
|
||||
/// Construct a patch.
|
||||
/**
|
||||
* \param[in] target Symbol target string, using Mimick syntax
|
||||
* i.e. "symbol(@scope)?", where scope may be "self" to target the current
|
||||
* binary, "lib:library_name" to target a given library, "file:path/to/library"
|
||||
* to target a given file, or "sym:other_symbol" to target the first library
|
||||
* that defines said symbol.
|
||||
* \param[in] proxy An indirection to call the target function.
|
||||
* This indirection must ensure this call goes through the function's
|
||||
* trampoline, as setup by the dynamic linker.
|
||||
* \return a mocking_utils::Patch instance.
|
||||
*/
|
||||
explicit Patch(const std::string & target, std::function<ReturnT(ArgTs...)> proxy)
|
||||
: target_(target), proxy_(proxy)
|
||||
{
|
||||
}
|
||||
|
||||
// Copy construction and assignment are disabled.
|
||||
Patch(const Patch &) = delete;
|
||||
Patch & operator=(const Patch &) = delete;
|
||||
|
||||
Patch(Patch && other)
|
||||
{
|
||||
mock_ = other.mock_;
|
||||
other.mock_ = nullptr;
|
||||
}
|
||||
|
||||
Patch & operator=(Patch && other)
|
||||
{
|
||||
if (mock_) {
|
||||
mmk_reset(mock_);
|
||||
}
|
||||
mock_ = other.mock_;
|
||||
other.mock_ = nullptr;
|
||||
}
|
||||
|
||||
~Patch()
|
||||
{
|
||||
if (mock_) {
|
||||
mmk_reset(mock_);
|
||||
}
|
||||
}
|
||||
|
||||
/// Inject a @p replacement for the patched function.
|
||||
Patch & then_call(std::function<ReturnT(ArgTs...)> replacement) &
|
||||
{
|
||||
replace_with(replacement);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Inject a @p replacement for the patched function.
|
||||
Patch && then_call(std::function<ReturnT(ArgTs...)> replacement) &&
|
||||
{
|
||||
replace_with(replacement);
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
private:
|
||||
// Helper for template parameter pack expansion using `mmk_any`
|
||||
// macro as pattern.
|
||||
template<typename T>
|
||||
T any() {return mmk_any(T);}
|
||||
|
||||
void replace_with(std::function<ReturnT(ArgTs...)> replacement)
|
||||
{
|
||||
if (mock_) {
|
||||
throw std::logic_error("Cannot configure patch more than once");
|
||||
}
|
||||
auto type_erased_trampoline =
|
||||
reinterpret_cast<mmk_fn>(prepare_trampoline<ID>(replacement));
|
||||
auto MMK_MANGLE(mock_type, create) =
|
||||
PatchTraits<ID, ReturnT(ArgTs...)>::MMK_MANGLE(mock_type, create);
|
||||
mock_ = mmk_mock(target_.c_str(), mock_type);
|
||||
mmk_when(proxy_(any<ArgTs>()...), .then_call = type_erased_trampoline);
|
||||
}
|
||||
|
||||
mock_type mock_{nullptr};
|
||||
std::string target_;
|
||||
std::function<ReturnT(ArgTs...)> proxy_;
|
||||
};
|
||||
|
||||
/// Make a patch for a `target` function.
|
||||
/**
|
||||
* Useful for type deduction during \ref mocking_utils::Patch construction.
|
||||
*
|
||||
* \param[in] target Symbol target string, using Mimick syntax.
|
||||
* \param[in] proxy An indirection to call the target function.
|
||||
* \return a mocking_utils::Patch instance.
|
||||
*
|
||||
* \tparam ID Numerical identifier for this patch. Ought to be unique.
|
||||
* \tparam SignatureT Type of the function to be patched.
|
||||
*
|
||||
* \sa mocking_utils::Patch for further reference.
|
||||
*/
|
||||
template<size_t ID, typename SignatureT>
|
||||
auto make_patch(const std::string & target, std::function<SignatureT> proxy)
|
||||
{
|
||||
return Patch<ID, SignatureT>(target, proxy);
|
||||
}
|
||||
|
||||
/// Define a dummy operator `op` for a given `type`.
|
||||
/**
|
||||
* Useful to enable patching functions that take arguments whose types
|
||||
* do not define basic comparison operators, as required by Mimick.
|
||||
*/
|
||||
#define MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(type_, op) \
|
||||
template<typename T> \
|
||||
typename std::enable_if<std::is_same<T, type_>::value, bool>::type \
|
||||
operator op(const T &, const T &) { \
|
||||
return false; \
|
||||
}
|
||||
|
||||
/// Get the exact \ref mocking_utils::Patch type for a given `id` and `function`.
|
||||
/**
|
||||
* Useful to avoid ignored attribute warnings when using the \b decltype operator.
|
||||
*/
|
||||
#define MOCKING_UTILS_PATCH_TYPE(id, function) \
|
||||
decltype(mocking_utils::make_patch<id, decltype(function)>("", nullptr))
|
||||
|
||||
/// A transparent forwarding proxy to a given `function`.
|
||||
/**
|
||||
* Useful to ensure a call to `function` goes through its trampoline.
|
||||
*/
|
||||
#define MOCKING_UTILS_PATCH_PROXY(function) \
|
||||
[] (auto && ... args)->decltype(auto) { \
|
||||
return function(std::forward<decltype(args)>(args)...); \
|
||||
}
|
||||
|
||||
/// Compute a Mimick symbol target string based on which `function` is to be patched
|
||||
/// in which `scope`.
|
||||
#define MOCKING_UTILS_PATCH_TARGET(scope, function) \
|
||||
(std::string(RCUTILS_STRINGIFY(function)) + "@" + (scope))
|
||||
|
||||
/// Prepare a mocking_utils::Patch for patching a `function` in a given `scope`
|
||||
/// but defer applying any changes.
|
||||
#define prepare_patch(scope, function) \
|
||||
make_patch<__COUNTER__, decltype(function)>( \
|
||||
MOCKING_UTILS_PATCH_TARGET(scope, function), MOCKING_UTILS_PATCH_PROXY(function) \
|
||||
)
|
||||
|
||||
/// Patch a `function` with a used-provided `replacement` in a given `scope`.
|
||||
#define patch(scope, function, replacement) \
|
||||
prepare_patch(scope, function).then_call(replacement)
|
||||
|
||||
/// Patch a `function` to always yield a given `return_code` in a given `scope`.
|
||||
#define patch_and_return(scope, function, return_code) \
|
||||
patch(scope, function, [&](auto && ...) {return return_code;})
|
||||
|
||||
/// Patch a `function` to execute normally but always yield a given `return_code`
|
||||
/// in a given `scope`.
|
||||
#define inject_on_return(scope, function, return_code) \
|
||||
patch( \
|
||||
scope, function, ([&, base = function](auto && ... __args) { \
|
||||
static_cast<void>(base(std::forward<decltype(__args)>(__args)...)); \
|
||||
return return_code; \
|
||||
}))
|
||||
|
||||
} // namespace mocking_utils
|
||||
|
||||
#ifdef MOCKING_UTILS_SUPPORT_VA_LIST
|
||||
// Define dummy comparison operators for C standard va_list type
|
||||
MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(va_list, ==)
|
||||
MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(va_list, !=)
|
||||
MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(va_list, <)
|
||||
MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(va_list, >)
|
||||
#endif
|
||||
|
||||
#endif // MOCKING_UTILS__PATCH_HPP_
|
|
@ -25,6 +25,8 @@
|
|||
#include "../src/impl/node_params.h"
|
||||
#include "rcutils/filesystem.h"
|
||||
|
||||
#include "./mocking_utils/patch.hpp"
|
||||
|
||||
TEST(TestParse, parse_value) {
|
||||
rcutils_allocator_t allocator = rcutils_get_default_allocator();
|
||||
yaml_event_t event;
|
||||
|
@ -446,3 +448,73 @@ TEST(TestParse, parse_key_bad_args)
|
|||
EXPECT_TRUE(rcutils_error_is_set());
|
||||
rcutils_reset_error();
|
||||
}
|
||||
|
||||
TEST(TestParse, parse_file_events_mock_yaml_parser_parse) {
|
||||
char cur_dir[1024];
|
||||
rcutils_reset_error();
|
||||
EXPECT_TRUE(rcutils_get_cwd(cur_dir, 1024)) << rcutils_get_error_string().str;
|
||||
|
||||
rcutils_allocator_t allocator = rcutils_get_default_allocator();
|
||||
char * test_path = rcutils_join_path(cur_dir, "test", allocator);
|
||||
char * path = rcutils_join_path(test_path, "correct_config.yaml", allocator);
|
||||
ASSERT_TRUE(NULL != path) << rcutils_get_error_string().str;
|
||||
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
|
||||
{
|
||||
allocator.deallocate(test_path, allocator.state);
|
||||
allocator.deallocate(path, allocator.state);
|
||||
});
|
||||
|
||||
rcl_params_t * params_hdl = rcl_yaml_node_struct_init(allocator);
|
||||
ASSERT_NE(nullptr, params_hdl);
|
||||
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
|
||||
{
|
||||
rcl_yaml_node_struct_fini(params_hdl);
|
||||
});
|
||||
|
||||
yaml_parser_t parser;
|
||||
ASSERT_NE(0, yaml_parser_initialize(&parser));
|
||||
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
|
||||
{
|
||||
yaml_parser_delete(&parser);
|
||||
});
|
||||
|
||||
FILE * yaml_file = fopen(path, "r");
|
||||
ASSERT_NE(nullptr, yaml_file);
|
||||
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
|
||||
{
|
||||
fclose(yaml_file);
|
||||
});
|
||||
yaml_parser_set_input_file(&parser, yaml_file);
|
||||
|
||||
namespace_tracker_t ns_tracker;
|
||||
memset(&ns_tracker, 0, sizeof(namespace_tracker_t));
|
||||
|
||||
auto mock = mocking_utils::patch(
|
||||
"lib:rcl_yaml_param_parser", yaml_parser_parse, [](yaml_parser_t *, yaml_event_t * event) {
|
||||
event->start_mark.line = 0u;
|
||||
event->type = YAML_NO_EVENT;
|
||||
return 1;
|
||||
});
|
||||
EXPECT_EQ(RCUTILS_RET_ERROR, parse_file_events(&parser, &ns_tracker, params_hdl));
|
||||
}
|
||||
|
||||
TEST(TestParse, parse_value_events_mock_yaml_parser_parse) {
|
||||
constexpr char node_name[] = "node name";
|
||||
constexpr char param_name[] = "param name";
|
||||
constexpr char yaml_value[] = "true";
|
||||
rcutils_allocator_t allocator = rcutils_get_default_allocator();
|
||||
|
||||
rcl_params_t * params_st = rcl_yaml_node_struct_init(allocator);
|
||||
ASSERT_NE(params_st, nullptr);
|
||||
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
|
||||
{
|
||||
rcl_yaml_node_struct_fini(params_st);
|
||||
});
|
||||
auto mock = mocking_utils::patch(
|
||||
"lib:rcl_yaml_param_parser", yaml_parser_parse, [](yaml_parser_t *, yaml_event_t * event) {
|
||||
event->start_mark.line = 0u;
|
||||
event->type = YAML_NO_EVENT;
|
||||
return 1;
|
||||
});
|
||||
EXPECT_FALSE(rcl_parse_yaml_value(node_name, param_name, yaml_value, params_st));
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <yaml.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@ -22,6 +24,7 @@
|
|||
#include "rcutils/error_handling.h"
|
||||
#include "rcutils/filesystem.h"
|
||||
#include "rcutils/testing/fault_injection.h"
|
||||
#include "./mocking_utils/patch.hpp"
|
||||
#include "./time_bomb_allocator_testing_utils.h"
|
||||
|
||||
TEST(RclYamlParamParser, node_init_fini) {
|
||||
|
@ -361,6 +364,46 @@ TEST(RclYamlParamParser, test_parse_file_with_bad_allocator) {
|
|||
}
|
||||
}
|
||||
|
||||
TEST(RclYamlParamParser, test_parse_yaml_initialize_mock) {
|
||||
char cur_dir[1024];
|
||||
rcutils_reset_error();
|
||||
EXPECT_TRUE(rcutils_get_cwd(cur_dir, 1024)) << rcutils_get_error_string().str;
|
||||
|
||||
rcutils_allocator_t allocator = rcutils_get_default_allocator();
|
||||
char * test_path = rcutils_join_path(cur_dir, "test", allocator);
|
||||
|
||||
char * path = rcutils_join_path(test_path, "correct_config.yaml", allocator);
|
||||
ASSERT_TRUE(NULL != path) << rcutils_get_error_string().str;
|
||||
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
|
||||
{
|
||||
allocator.deallocate(test_path, allocator.state);
|
||||
allocator.deallocate(path, allocator.state);
|
||||
});
|
||||
|
||||
rcl_params_t * params_hdl = rcl_yaml_node_struct_init(allocator);
|
||||
ASSERT_NE(nullptr, params_hdl);
|
||||
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
|
||||
{
|
||||
rcl_yaml_node_struct_fini(params_hdl);
|
||||
});
|
||||
auto mock = mocking_utils::patch_and_return(
|
||||
"lib:rcl_yaml_param_parser", yaml_parser_initialize, false);
|
||||
|
||||
EXPECT_FALSE(rcl_parse_yaml_file(path, params_hdl));
|
||||
|
||||
constexpr char node_name[] = "node name";
|
||||
constexpr char param_name[] = "param name";
|
||||
constexpr char yaml_value[] = "true";
|
||||
|
||||
rcl_params_t * params_st = rcl_yaml_node_struct_init(allocator);
|
||||
ASSERT_NE(params_st, nullptr);
|
||||
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
|
||||
{
|
||||
rcl_yaml_node_struct_fini(params_st);
|
||||
});
|
||||
EXPECT_FALSE(rcl_parse_yaml_value(node_name, param_name, yaml_value, params_st));
|
||||
}
|
||||
|
||||
|
||||
int32_t main(int32_t argc, char ** argv)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue