diff --git a/Userland/Libraries/LibTest/CMakeLists.txt b/Userland/Libraries/LibTest/CMakeLists.txt index 7816fdac71c..ad5f2bb251c 100644 --- a/Userland/Libraries/LibTest/CMakeLists.txt +++ b/Userland/Libraries/LibTest/CMakeLists.txt @@ -2,6 +2,7 @@ serenity_install_sources("Userland/Libraries/LibTest") set(SOURCES TestSuite.cpp + CrashTest.cpp ) serenity_lib(LibTest test) diff --git a/Userland/Libraries/LibTest/CrashTest.cpp b/Userland/Libraries/LibTest/CrashTest.cpp new file mode 100644 index 00000000000..fcdb3ffc6fb --- /dev/null +++ b/Userland/Libraries/LibTest/CrashTest.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling + * Copyright (c) 2019-2020, Shannon Booth + * Copyright (c) 2021, Brian Gianforcaro + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +namespace Test { + +Crash::Crash(String test_type, Function crash_function) + : m_type(test_type) + , m_crash_function(move(crash_function)) +{ +} + +void Crash::run(RunType run_type = RunType::UsingChildProcess) +{ + printf("\x1B[33mTesting\x1B[0m: \"%s\"\n", m_type.characters()); + + auto run_crash_and_print_if_error = [this]() { + auto failure = m_crash_function(); + + // If we got here something went wrong + printf("\x1B[31mFAIL\x1B[0m: "); + switch (failure) { + case Failure::DidNotCrash: + printf("Did not crash!\n"); + break; + case Failure::UnexpectedError: + printf("Unexpected error!\n"); + break; + default: + VERIFY_NOT_REACHED(); + } + }; + + if (run_type == RunType::UsingCurrentProcess) { + run_crash_and_print_if_error(); + } else { + + // Run the test in a child process so that we do not crash the crash program :^) + pid_t pid = fork(); + if (pid < 0) { + perror("fork"); + VERIFY_NOT_REACHED(); + } else if (pid == 0) { + run_crash_and_print_if_error(); + exit(0); + } + + int status; + waitpid(pid, &status, 0); + if (WIFSIGNALED(status)) + printf("\x1B[32mPASS\x1B[0m: Terminated with signal %d\n", WTERMSIG(status)); + } +} + +} diff --git a/Userland/Libraries/LibTest/CrashTest.h b/Userland/Libraries/LibTest/CrashTest.h new file mode 100644 index 00000000000..40bc7f57277 --- /dev/null +++ b/Userland/Libraries/LibTest/CrashTest.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling + * Copyright (c) 2019-2020, Shannon Booth + * Copyright (c) 2021, Brian Gianforaro + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include + +namespace Test { + +class Crash { +public: + enum class RunType { + UsingChildProcess, + UsingCurrentProcess, + }; + + enum class Failure { + DidNotCrash, + UnexpectedError, + }; + + Crash(String test_type, Function crash_function); + + void run(RunType run_type); + +private: + String m_type; + Function m_crash_function; +}; + +} diff --git a/Userland/Utilities/CMakeLists.txt b/Userland/Utilities/CMakeLists.txt index c8caada9737..4aeac62acfc 100644 --- a/Userland/Utilities/CMakeLists.txt +++ b/Userland/Utilities/CMakeLists.txt @@ -22,6 +22,7 @@ target_link_libraries(checksum LibCrypto) target_link_libraries(chres LibGUI) target_link_libraries(cksum LibCrypto) target_link_libraries(copy LibGUI) +target_link_libraries(crash LibTest) target_link_libraries(disasm LibX86) target_link_libraries(expr LibRegex) target_link_libraries(functrace LibDebug LibX86) diff --git a/Userland/Utilities/crash.cpp b/Userland/Utilities/crash.cpp index 743b75c1d3e..f655d3a51c2 100644 --- a/Userland/Utilities/crash.cpp +++ b/Userland/Utilities/crash.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -16,73 +17,10 @@ #include #include +using Test::Crash; + #pragma GCC optimize("O0") -class Crash { -public: - enum class RunType { - UsingChildProcess, - UsingCurrentProcess, - }; - - enum class Failure { - DidNotCrash, - UnexpectedError, - }; - - Crash(String test_type, Function crash_function) - : m_type(test_type) - , m_crash_function(move(crash_function)) - { - } - - void run(RunType run_type) - { - printf("\x1B[33mTesting\x1B[0m: \"%s\"\n", m_type.characters()); - - auto run_crash_and_print_if_error = [this]() { - auto failure = m_crash_function(); - - // If we got here something went wrong - printf("\x1B[31mFAIL\x1B[0m: "); - switch (failure) { - case Failure::DidNotCrash: - printf("Did not crash!\n"); - break; - case Failure::UnexpectedError: - printf("Unexpected error!\n"); - break; - default: - VERIFY_NOT_REACHED(); - } - }; - - if (run_type == RunType::UsingCurrentProcess) { - run_crash_and_print_if_error(); - } else { - - // Run the test in a child process so that we do not crash the crash program :^) - pid_t pid = fork(); - if (pid < 0) { - perror("fork"); - VERIFY_NOT_REACHED(); - } else if (pid == 0) { - run_crash_and_print_if_error(); - exit(0); - } - - int status; - waitpid(pid, &status, 0); - if (WIFSIGNALED(status)) - printf("\x1B[32mPASS\x1B[0m: Terminated with signal %d\n", WTERMSIG(status)); - } - } - -private: - String m_type; - Function m_crash_function; -}; - int main(int argc, char** argv) { bool do_all_crash_types = false;