diff options
Diffstat (limited to 'vespalib/src/tests/signalhandler/signalhandler_test.cpp')
-rw-r--r-- | vespalib/src/tests/signalhandler/signalhandler_test.cpp | 56 |
1 files changed, 48 insertions, 8 deletions
diff --git a/vespalib/src/tests/signalhandler/signalhandler_test.cpp b/vespalib/src/tests/signalhandler/signalhandler_test.cpp index ba70fafddb3..9e1052bb588 100644 --- a/vespalib/src/tests/signalhandler/signalhandler_test.cpp +++ b/vespalib/src/tests/signalhandler/signalhandler_test.cpp @@ -1,20 +1,21 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <vespa/vespalib/testkit/testapp.h> +#include "my_shared_library.h" #include <vespa/vespalib/util/signalhandler.h> +#include <vespa/vespalib/gtest/gtest.h> +#include <gmock/gmock.h> +#include <latch> +#include <thread> #include <unistd.h> #include <vespa/log/log.h> LOG_SETUP("signalhandler_test"); using namespace vespalib; +using namespace ::testing; -TEST_SETUP(Test); - -int -Test::Main() +TEST(SignalHandlerTest, signal_handler_can_intercept_hooked_signals) { - TEST_INIT("signalhandler_test"); EXPECT_TRUE(!SignalHandler::INT.check()); EXPECT_TRUE(!SignalHandler::TERM.check()); SignalHandler::INT.ignore(); @@ -32,6 +33,45 @@ Test::Main() SignalHandler::TERM.clear(); EXPECT_TRUE(!SignalHandler::INT.check()); EXPECT_TRUE(!SignalHandler::TERM.check()); - EXPECT_EQUAL(0, system("res=`./vespalib_victim_app`; test \"$res\" = \"GOT TERM\"")); - TEST_DONE(); + EXPECT_EQ(0, system("res=`./vespalib_victim_app`; test \"$res\" = \"GOT TERM\"")); +} + +TEST(SignalHandlerTest, can_dump_stack_of_another_thread) +{ + std::latch arrival_latch(2); + std::latch departure_latch(2); + + std::thread t([&]{ + my_cool_function(arrival_latch, departure_latch); + }); + arrival_latch.arrive_and_wait(); + + auto trace = SignalHandler::get_cross_thread_stack_trace(t.native_handle()); + EXPECT_THAT(trace, HasSubstr("my_cool_function")); + + departure_latch.arrive_and_wait(); + t.join(); +} + +TEST(SignalHandlerTest, dumping_stack_of_an_ex_thread_does_not_crash) +{ + std::thread t([]() noexcept { + // Do a lot of nothing at all. + }); + auto tid = t.native_handle(); + t.join(); + auto trace = SignalHandler::get_cross_thread_stack_trace(tid); + EXPECT_EQ(trace, "(pthread_kill() failed; could not get backtrace)"); +} + +TEST(SignalHandlerTest, can_get_stack_trace_of_own_thread) +{ + auto trace = my_totally_tubular_and_groovy_function(); + EXPECT_THAT(trace, HasSubstr("my_totally_tubular_and_groovy_function")); +} + +int main(int argc, char* argv[]) { + ::testing::InitGoogleTest(&argc, argv); + SignalHandler::enable_cross_thread_stack_tracing(); + return RUN_ALL_TESTS(); } |