diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2c722362d..c625389a3 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,34 +1,35 @@ ############################ # Tests ############################ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall -fexceptions") string (REPLACE "-std=gnu++11" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) SET(Tests_SRCS tests/TestMain.cpp + tests/abortutil.cpp tests/compositiontest.cpp tests/effectstest.cpp tests/groupstest.cpp tests/keyframetest.cpp tests/markertest.cpp tests/modeltest.cpp tests/regressions.cpp tests/snaptest.cpp tests/test_utils.cpp tests/timewarptest.cpp - tests/trimmingtest.cpp tests/treetest.cpp + tests/trimmingtest.cpp PARENT_SCOPE ) include_directories( ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}/src ${MLT_INCLUDE_DIR} ${MLTPP_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/lib/external ${CMAKE_CURRENT_SOURCE_DIR}/lib ../src ) diff --git a/tests/abortutil.cpp b/tests/abortutil.cpp new file mode 100644 index 000000000..0fca9ba96 --- /dev/null +++ b/tests/abortutil.cpp @@ -0,0 +1,11 @@ +#include "abortutil.hpp" +#ifdef __linux__ + +void Disable_Console_Output() +{ + // close C file descriptors + fclose(stdout); + fclose(stderr); +} + +#endif diff --git a/tests/abortutil.hpp b/tests/abortutil.hpp index c6f9c0b4d..a7563444e 100644 --- a/tests/abortutil.hpp +++ b/tests/abortutil.hpp @@ -1,95 +1,90 @@ #pragma once #ifdef __linux__ #include #include #include #include #include #include #include // copied from cppreference as possible implementation namespace detail { template inline auto INVOKE(F &&f, Args &&... args) -> decltype(std::forward(f)(std::forward(args)...)) { return std::forward(f)(std::forward(args)...); } template inline auto INVOKE(T Base::*pmd, Derived &&ref) -> decltype(std::forward(ref).*pmd) { return std::forward(ref).*pmd; } template inline auto INVOKE(PMD pmd, Pointer &&ptr) -> decltype((*std::forward(ptr)).*pmd) { return (*std::forward(ptr)).*pmd; } template inline auto INVOKE(T Base::*pmf, Derived &&ref, Args &&... args) -> decltype((std::forward(ref).*pmf)(std::forward(args)...)) { return (std::forward(ref).*pmf)(std::forward(args)...); } template inline auto INVOKE(PMF pmf, Pointer &&ptr, Args &&... args) -> decltype(((*std::forward(ptr)).*pmf)(std::forward(args)...)) { return ((*std::forward(ptr)).*pmf)(std::forward(args)...); } } // namespace detail namespace util { template decltype(auto) invoke(F &&f, ArgTypes &&... args) { return detail::INVOKE(std::forward(f), std::forward(args)...); } } // namespace util -void Disable_Console_Output() -{ - // close C file descriptors - fclose(stdout); - fclose(stderr); -} +void Disable_Console_Output(); template bool ABORTS(F &&f, Args &&... args) { // pipe int fd[2]; pipe(fd); // spawn a new process auto child_pid = fork(); bool aborted = false; // if the fork succeeded if (child_pid >= 0) { // if we are in the child process if (child_pid == 0) { close(fd[0]); // call the function that we expect to abort Disable_Console_Output(); util::invoke(std::forward(f), std::forward(args)...); char succ[] = "1"; write(fd[1], succ, 2); // if the function didn't abort, we'll exit cleanly std::exit(EXIT_SUCCESS); } else { close(fd[1]); char buff[128]; int n = read(fd[0], buff, 127); aborted = n == 0; } } - return true; + return aborted; } #else template bool ABORTS(F &&, Args &&...) { return true; } #endif