diff options
author | Haavard <havardpe@yahoo-inc.com> | 2016-10-18 14:29:41 +0000 |
---|---|---|
committer | Haavard <havardpe@yahoo-inc.com> | 2016-10-18 14:29:41 +0000 |
commit | 560c734fc610963f3bf2de06a00ad5aaff5a6e0b (patch) | |
tree | e163066e525f3858459cac859f95fab5248bae9e /vespalib/src | |
parent | 53070df56b5749185fbf549fc5b6b0b157bffe46 (diff) |
added TimeBomb - protects against deadlocked unit tests
Diffstat (limited to 'vespalib/src')
6 files changed, 88 insertions, 1 deletions
diff --git a/vespalib/src/tests/testkit-time_bomb/CMakeLists.txt b/vespalib/src/tests/testkit-time_bomb/CMakeLists.txt new file mode 100644 index 00000000000..aa532f30913 --- /dev/null +++ b/vespalib/src/tests/testkit-time_bomb/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +vespa_add_executable(vespalib_testkit-time_bomb_test_app TEST + SOURCES + testkit-time_bomb_test.cpp + DEPENDS + vespalib +) +vespa_add_test(NAME vespalib_testkit-time_bomb_test_app COMMAND vespalib_testkit-time_bomb_test_app) diff --git a/vespalib/src/tests/testkit-time_bomb/testkit-time_bomb_test.cpp b/vespalib/src/tests/testkit-time_bomb/testkit-time_bomb_test.cpp new file mode 100644 index 00000000000..8294df209cd --- /dev/null +++ b/vespalib/src/tests/testkit-time_bomb/testkit-time_bomb_test.cpp @@ -0,0 +1,9 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include <vespa/vespalib/testkit/test_kit.h> + +TEST_MT_F("use time bomb in multi-threaded test", 4, vespalib::TimeBomb(60)) { + EXPECT_TRUE(true); +} + +TEST_MAIN() { TEST_RUN_ALL(); } diff --git a/vespalib/src/vespa/vespalib/testkit/CMakeLists.txt b/vespalib/src/vespa/vespalib/testkit/CMakeLists.txt index 51a69191619..3fff3877108 100644 --- a/vespalib/src/vespa/vespalib/testkit/CMakeLists.txt +++ b/vespalib/src/vespa/vespalib/testkit/CMakeLists.txt @@ -6,5 +6,6 @@ vespa_add_library(vespalib_vespalib_testkit OBJECT test_master.cpp test_state_guard.cpp testapp.cpp + time_bomb.cpp DEPENDS ) diff --git a/vespalib/src/vespa/vespalib/testkit/test_kit.h b/vespalib/src/vespa/vespalib/testkit/test_kit.h index 98fb7b42fa0..2439e0caf1e 100644 --- a/vespalib/src/vespa/vespalib/testkit/test_kit.h +++ b/vespalib/src/vespa/vespalib/testkit/test_kit.h @@ -9,4 +9,4 @@ #include "test_master.h" #include "test_hook.h" #include "test_state_guard.h" - +#include "time_bomb.h" diff --git a/vespalib/src/vespa/vespalib/testkit/time_bomb.cpp b/vespalib/src/vespa/vespalib/testkit/time_bomb.cpp new file mode 100644 index 00000000000..28cd638e724 --- /dev/null +++ b/vespalib/src/vespa/vespalib/testkit/time_bomb.cpp @@ -0,0 +1,41 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include <vespa/fastos/fastos.h> +#include "time_bomb.h" + +namespace vespalib { + +namespace { + +void bomb(Gate &gate, size_t seconds) { + if (seconds > 5) { + if (gate.await((seconds - 5) * 1000)) { + return; + } + } + size_t countdown = std::min(seconds, size_t(5)); + while (countdown > 0) { + fprintf(stderr, "...%zu...\n", countdown--); + if (gate.await(1000)) { + return; + } + } + fprintf(stderr, "BOOM!\n"); + abort(); +} + +} // namespace vespalib::<unnamed> + +TimeBomb::TimeBomb(size_t seconds) + : _gate(), + _thread(bomb, std::ref(_gate), seconds) +{ +} + +TimeBomb::~TimeBomb() +{ + _gate.countDown(); + _thread.join(); +} + +} // namespace vespalib diff --git a/vespalib/src/vespa/vespalib/testkit/time_bomb.h b/vespalib/src/vespa/vespalib/testkit/time_bomb.h new file mode 100644 index 00000000000..5d527443d29 --- /dev/null +++ b/vespalib/src/vespa/vespalib/testkit/time_bomb.h @@ -0,0 +1,28 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include <vespa/vespalib/util/sync.h> +#include <thread> + +namespace vespalib { + +/** + * A TimeBomb is used to protect against deadlocked unit tests. A + * TimeBomb is constructed with a given number of seconds. If the + * TimeBomb is not destructed before the time runs out, it will abort + * the program. The recommended way to use this class is as a fixture + * for multi-threaded tests where the test may hang if something is + * wrong. + **/ +class TimeBomb +{ +private: + Gate _gate; + std::thread _thread; +public: + TimeBomb(size_t seconds); + ~TimeBomb(); // defuse the bomb +}; + +} // namespace vespalib |