This is an automated email from the ASF dual-hosted git repository. jdanek pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/qpid-dispatch.git
commit f1d76afd7246396ca68ee66e6427e2f0280ae5e7 Author: Jiri Daněk <[email protected]> AuthorDate: Wed Dec 22 19:31:11 2021 +0100 DISPATCH-1783 first test using the cpp-stub tool The test was originally proposed on DISPATCH-1566 --- tests/CMakeLists.txt | 6 ++- tests/c_unittests/CMakeLists.txt | 9 +++- tests/c_unittests/c_unittests_main.cpp | 58 +++++++++++++++++++++- ...c_unittests_main.cpp => qdr_stubbing_probe.cpp} | 15 ++++-- ...c_unittests_main.cpp => qdr_stubbing_probe.hpp} | 26 ++++++++-- tests/c_unittests/test_terminus.cpp | 21 ++++++++ 6 files changed, 123 insertions(+), 12 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index fa6cad5..58507d2 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -274,7 +274,11 @@ install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/config-2 install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ssl_certs DESTINATION ${QPID_DISPATCH_HOME_INSTALLED}/tests) -add_subdirectory(c_unittests) +# cpp-stub requires Linux +if(UNIX AND NOT APPLE) + add_subdirectory(cpp-stub) + add_subdirectory(c_unittests) +endif() if(BUILD_BENCHMARKS) add_subdirectory(c_benchmarks) diff --git a/tests/c_unittests/CMakeLists.txt b/tests/c_unittests/CMakeLists.txt index be1364f..5a9a9e5 100644 --- a/tests/c_unittests/CMakeLists.txt +++ b/tests/c_unittests/CMakeLists.txt @@ -17,7 +17,11 @@ ## under the License. ## -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_STANDARD_FLAGS}") +# -fno-inline: just to be extra sure, no particular reason so far +# -fno-builtin: GCC would optimize e.g. abs() and we would not be able to stub +# -fno-stack-protector: https://stackoverflow.com/questions/12201625/disable-using-sprintf-chk +# -D_FORTIFY_SOURCE=0: for Ubuntu with -O1+, https://stackoverflow.com/questions/34907503/gcc-fread-chk-warn-warning +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_STANDARD_FLAGS} -fno-inline -fno-builtin -fno-stack-protector -U_FORTIFY_SOURCE") # DISPATCH-2196 Linking object files containing instances of the same C++ template fails on s390x with sanitizers enabled if(CMAKE_SYSTEM_PROCESSOR STREQUAL "s390x") # set the sanitizer flags only for linking, not for compilation; this workarounds the failure @@ -27,6 +31,7 @@ else() endif() add_executable(c_unittests + qdr_stubbing_probe.cpp c_unittests_main.cpp doctest.h qdr_doctest.hpp @@ -37,7 +42,7 @@ add_executable(c_unittests test_router_startup.cpp test_terminus.cpp $<TARGET_OBJECTS:qpid-dispatch>) -target_link_libraries(c_unittests pthread qpid-dispatch-libraries) +target_link_libraries(c_unittests cpp-stub pthread qpid-dispatch-libraries) file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/minimal_silent.conf diff --git a/tests/c_unittests/c_unittests_main.cpp b/tests/c_unittests/c_unittests_main.cpp index 651cc14..de06ee2 100644 --- a/tests/c_unittests/c_unittests_main.cpp +++ b/tests/c_unittests/c_unittests_main.cpp @@ -17,5 +17,61 @@ * under the License. */ -#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#define DOCTEST_CONFIG_IMPLEMENT #include "qdr_doctest.hpp" +#include "cpp_stub.h" +#include "qdr_stubbing_probe.hpp" + +#include <cstdio> +#include <cstdlib> + +bool check_stubbing_works() +{ + +#if (defined(__s390__) || defined(__s390x__) || defined(__zarch__)) + return false; // cpp-stub does not support +#endif + + { + Stub stub; + stub.set(probe, +[](int)->int { return 42; }); + if (probe(0) != 42) { + return false; + } + } + { + Stub stub; + stub.set(abs, +[](int)->int{ return 24; }); + if (probe(0) != 24) { + return false; + } + } + return true; +} + +// https://github.com/doctest/doctest/blob/master/doc/markdown/main.md +int main(int argc, char** argv) +{ + doctest::Context context; + + if (!check_stubbing_works()) { +#ifdef QD_REQUIRE_STUBBING_WORKS + fprintf(stderr, "QD_REQUIRE_STUBBING_WORKS was defined, but stubbing doesn't work\n"); + abort(); +#else + fprintf(stderr, "Stubbing doesn't work. Define QD_REQUIRE_STUBBING_WORKS to get an abort()\n"); +#endif + context.addFilter("test-case-exclude", "*_STUB_*"); // skip testcases that require stubbing + context.addFilter("subcase-exclude", "*_STUB_*"); // ditto for subcases + } + + context.applyCommandLine(argc, argv); + + int res = context.run(); + + if (context.shouldExit()) { + return res; + } + + return res; +} diff --git a/tests/c_unittests/c_unittests_main.cpp b/tests/c_unittests/qdr_stubbing_probe.cpp similarity index 78% copy from tests/c_unittests/c_unittests_main.cpp copy to tests/c_unittests/qdr_stubbing_probe.cpp index 651cc14..8fe9cfd 100644 --- a/tests/c_unittests/c_unittests_main.cpp +++ b/tests/c_unittests/qdr_stubbing_probe.cpp @@ -6,9 +6,9 @@ * to you 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 @@ -17,5 +17,12 @@ * under the License. */ -#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN -#include "qdr_doctest.hpp" +#include "qdr_stubbing_probe.hpp" + +#include <cstdlib> + +int probe(int i) +{ + // we need to compile tests with `-fno-builtin` so that GCC does not replace this with its own inlined implementation + return abs(i); +} diff --git a/tests/c_unittests/c_unittests_main.cpp b/tests/c_unittests/qdr_stubbing_probe.hpp similarity index 50% copy from tests/c_unittests/c_unittests_main.cpp copy to tests/c_unittests/qdr_stubbing_probe.hpp index 651cc14..10f29f0 100644 --- a/tests/c_unittests/c_unittests_main.cpp +++ b/tests/c_unittests/qdr_stubbing_probe.hpp @@ -6,9 +6,9 @@ * to you 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 @@ -17,5 +17,23 @@ * under the License. */ -#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN -#include "qdr_doctest.hpp" +#ifndef QPID_DISPATCH_QDR_STUBBING_PROBE +#define QPID_DISPATCH_QDR_STUBBING_PROBE + +/** + * + * This is an utility to perform ad-hoc check whether stubbing is succeeding. + * + * Note that `probe` is in a different compilation unit than `check_stubbing_works`. + * This is important, because functions called from the same compilation unit can be stubbed only + * with a Debug build (CMake profile), whereas functions in a different compilation unit + * can be stubbed even in RelWithDebInfo build. Enabling LTO seems to make any stubbing impossible. + */ + +/// dummy function returning abs(int), convenient target for stubbing +int probe(int); + +/// attempts to stub `probe` and returns true if successful +bool check_stubbing_works(); + +#endif // QPID_DISPATCH_QDR_STUBBING_PROBE diff --git a/tests/c_unittests/test_terminus.cpp b/tests/c_unittests/test_terminus.cpp index 52d91ce..0e5057b 100644 --- a/tests/c_unittests/test_terminus.cpp +++ b/tests/c_unittests/test_terminus.cpp @@ -18,6 +18,7 @@ */ #include "qdr_doctest.hpp" +#include "cpp_stub.h" extern "C" { #include "qpid/dispatch/router_core.h" @@ -29,6 +30,15 @@ extern "C" { #include <stdio.h> } +namespace vsnprintf_stub +{ +int rc = 0; +int stub(char *str, size_t size, const char *format, ...) +{ + return rc; +} +} // namespace vsnprintf_stub + TEST_CASE("test_safe_snprintf") { const int OUTPUT_SIZE = 128; const char *TEST_MESSAGE = "something"; @@ -73,6 +83,17 @@ TEST_CASE("test_safe_snprintf") { CHECK(0 == len); } } + + SUBCASE("vsnprintf failure (_STUB_)") { + Stub stub; + stub.set(vsnprintf, vsnprintf_stub::stub); + vsnprintf_stub::rc = -1; + + output[0] = 'a'; + len = safe_snprintf(output, LEN + 10, TEST_MESSAGE); + CHECK(0 == len); + CHECK('\0' == output[0]); + } } TEST_CASE("test_qdr_terminus_format") { --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
