diff --git a/.github/workflows/ctest.yml b/.github/workflows/ctest.yml new file mode 100644 index 0000000..3cc5790 --- /dev/null +++ b/.github/workflows/ctest.yml @@ -0,0 +1,59 @@ +name: Cross-Platform Build & Test + +on: + push: + branches: [ "main" ] + pull_request: + +permissions: + contents: read + checks: write + pull-requests: write + +jobs: + build-and-test: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + + strategy: + fail-fast: false + matrix: + include: + - name: Linux GCC + os: ubuntu-latest + cc: gcc + + - name: Linux Clang + os: ubuntu-latest + cc: clang + + - name: Windows MSVC + os: windows-latest + + steps: + - uses: actions/checkout@v6 + + - name: Configure CMake (Unix) + if: runner.os != 'Windows' + run: cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=ON + env: + CC: ${{ matrix.cc }} + + - name: Configure CMake (Windows) + if: runner.os == 'Windows' + run: cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=ON -G "Visual Studio 17 2022" + + - name: Build + run: cmake --build build --config Release + + - name: Run Tests + working-directory: build + run: ctest -C Release --output-on-failure --output-junit test-results.xml + + - name: Publish Test Results + uses: dorny/test-reporter@v2 + if: success() || failure() + with: + name: Tests (${{ matrix.name }}) + path: build/test-results.xml + reporter: java-junit \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ceda92..4b704d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -112,6 +112,8 @@ if(PROJECT_IS_TOP_LEVEL) # --- Build Examples --- if(BUILD_EXAMPLES) + enable_testing() + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/examples/CMakeLists.txt") add_subdirectory(examples) endif() diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index e29402f..bca823d 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -3,11 +3,21 @@ file(GLOB EXAMPLE_SOURCES CONFIGURE_DEPENDS "example*.c") foreach(SOURCE_FILE ${EXAMPLE_SOURCES}) get_filename_component(TARGET_NAME ${SOURCE_FILE} NAME_WE) + add_executable(${TARGET_NAME} ${SOURCE_FILE}) target_link_libraries(${TARGET_NAME} PRIVATE c_traceback::c_traceback) + if(ENABLE_SANITIZERS AND NOT MSVC) target_compile_options(${TARGET_NAME} PRIVATE -fsanitize=address,undefined) target_link_options(${TARGET_NAME} PRIVATE -fsanitize=address,undefined) endif() + # Test + add_test( + NAME ${TARGET_NAME} + COMMAND ${CMAKE_COMMAND} + -DTEST_PROG=$ + -P ${CMAKE_CURRENT_SOURCE_DIR}/check_test.cmake + ) + endforeach() diff --git a/examples/check_test.cmake b/examples/check_test.cmake new file mode 100644 index 0000000..20b346e --- /dev/null +++ b/examples/check_test.cmake @@ -0,0 +1,20 @@ +execute_process( + COMMAND ${TEST_PROG} + OUTPUT_VARIABLE TEST_OUTPUT + ERROR_VARIABLE TEST_OUTPUT + RESULT_VARIABLE TEST_RESULT +) + +message("${TEST_OUTPUT}") + +# Determine Success +# The output contains "Traceback" (Even if it crashed) +if(TEST_OUTPUT MATCHES "Traceback") + message(STATUS "Traceback detected. Test Passed.") +# The program ran successfully (Exit code 0) +elseif(TEST_RESULT EQUAL 0) + message(STATUS "Clean exit. Test Passed.") +else() +# Fail: It crashed AND didn't print a Traceback + message(FATAL_ERROR "Test Failed: Process crashed (Code: ${TEST_RESULT}) and no 'Traceback' found.") +endif() diff --git a/examples/example_keyboard_interrupt.c b/examples/example_keyboard_interrupt.c deleted file mode 100644 index bd39c94..0000000 --- a/examples/example_keyboard_interrupt.c +++ /dev/null @@ -1,16 +0,0 @@ -#include - -#include "c_traceback.h" - -int main(void) -{ - TRACE(ctb_install_signal_handler()); - - printf("Press Ctrl+C to trigger a keyboard interrupt...\n"); - while (1) - { - /* Do nothing */ - } - - return 0; -} diff --git a/examples/example_stack_overflow.c b/examples/example_stack_overflow.c deleted file mode 100644 index 9a36e21..0000000 --- a/examples/example_stack_overflow.c +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include - -#include "c_traceback.h" - -void stack_overflow(int depth) -{ - char buffer[10240]; // Allocate some stack space - memset(buffer, 0, sizeof(buffer)); - printf("Recursion depth: %d\n", depth); - stack_overflow(depth + 1); -} - -int main(void) -{ - TRACE(ctb_install_signal_handler()); - - // Stack overflow - TRACE(stack_overflow(1)); - - return 0; -}