From: Jelte Jansen Date: Mon, 18 Feb 2013 17:35:57 +0000 (+0100) Subject: [2669] Use valgrind-check in fork/thread tests X-Git-Tag: bind10-1.1.0beta1-release~88^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=462f0ff4fbef6bdf657f4833c2d8f0e2cce1cd41;p=thirdparty%2Fkea.git [2669] Use valgrind-check in fork/thread tests Similar to how it is checked for death tests; if valgrind is detected (when possible), parts of tests are skipped --- diff --git a/Makefile.am b/Makefile.am index e6f343df7a..fe995a7b8d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -29,7 +29,7 @@ install-exec-hook: check-valgrind: if HAVE_VALGRIND - @VALGRIND_COMMAND="$(VALGRIND) -q --gen-suppressions=all --track-origins=yes --num-callers=48 --leak-check=full --child-silent-after-fork=yes --fullpath-after=" \ + @VALGRIND_COMMAND="$(VALGRIND) -q --gen-suppressions=all --track-origins=yes --num-callers=48 --leak-check=full --fullpath-after=" \ make -C $(abs_top_builddir) check else @echo "*** Valgrind is required for check-valgrind ***"; exit 1; @@ -37,7 +37,7 @@ endif check-valgrind-suppress: if HAVE_VALGRIND - @VALGRIND_COMMAND="$(VALGRIND) -q --gen-suppressions=all --track-origins=yes --error-exitcode=1 --child-silent-after-fork=yes --suppressions=$(abs_top_srcdir)/src/valgrind-suppressions --suppressions=$(abs_top_srcdir)/src/valgrind-suppressions.revisit --num-callers=48 --leak-check=full --fullpath-after=" \ + @VALGRIND_COMMAND="$(VALGRIND) -q --gen-suppressions=all --track-origins=yes --error-exitcode=1 --suppressions=$(abs_top_srcdir)/src/valgrind-suppressions --suppressions=$(abs_top_srcdir)/src/valgrind-suppressions.revisit --num-callers=48 --leak-check=full --fullpath-after=" \ make -C $(abs_top_builddir) check else @echo "*** Valgrind is required for check-valgrind-suppress ***"; exit 1; diff --git a/src/lib/server_common/tests/socket_requestor_test.cc b/src/lib/server_common/tests/socket_requestor_test.cc index 9085ba9243..8da545e160 100644 --- a/src/lib/server_common/tests/socket_requestor_test.cc +++ b/src/lib/server_common/tests/socket_requestor_test.cc @@ -35,6 +35,7 @@ #include #include +#include using namespace isc::data; using namespace isc::config; @@ -509,81 +510,83 @@ private: }; TEST_F(SocketRequestorTest, testSocketPassing) { - TestSocket ts; - std::vector > data; - data.push_back(std::pair("foo\n", 1)); - data.push_back(std::pair("bar\n", 2)); - data.push_back(std::pair("foo\n", 3)); - data.push_back(std::pair("foo\n", 1)); - data.push_back(std::pair("foo\n", -1)); - data.push_back(std::pair("foo\n", -2)); - - // run() returns true iff we can specify read timeout so we avoid a - // deadlock. Unless there's a bug the test should succeed even without the - // timeout, but we don't want to make the test hang up in case with an - // unexpected bug, so we'd rather skip most of the tests in that case. - const bool timo_ok = ts.run(data); - SocketRequestor::SocketID socket_id; - if (timo_ok) { - // 1 should be ok - addAnswer("foo", ts.getPath()); - socket_id = doRequest(); - EXPECT_EQ("foo", socket_id.second); - EXPECT_EQ(0, close(socket_id.first)); - - // 2 should be ok too - addAnswer("bar", ts.getPath()); - socket_id = doRequest(); - EXPECT_EQ("bar", socket_id.second); - EXPECT_EQ(0, close(socket_id.first)); - - // 3 should be ok too (reuse earlier token) - addAnswer("foo", ts.getPath()); - socket_id = doRequest(); - EXPECT_EQ("foo", socket_id.second); - EXPECT_EQ(0, close(socket_id.first)); - } - // Create a second socket server, to test that multiple different - // domains sockets would work as well (even though we don't actually - // use that feature) - TestSocket ts2; - std::vector > data2; - data2.push_back(std::pair("foo\n", 1)); - const bool timo_ok2 = ts2.run(data2); - - if (timo_ok2) { - // 1 should be ok - addAnswer("foo", ts2.getPath()); - socket_id = doRequest(); - EXPECT_EQ("foo", socket_id.second); - EXPECT_EQ(0, close(socket_id.first)); - } + if (!isc::util::unittests::runningOnValgrind()) { + TestSocket ts; + std::vector > data; + data.push_back(std::pair("foo\n", 1)); + data.push_back(std::pair("bar\n", 2)); + data.push_back(std::pair("foo\n", 3)); + data.push_back(std::pair("foo\n", 1)); + data.push_back(std::pair("foo\n", -1)); + data.push_back(std::pair("foo\n", -2)); + + // run() returns true iff we can specify read timeout so we avoid a + // deadlock. Unless there's a bug the test should succeed even without the + // timeout, but we don't want to make the test hang up in case with an + // unexpected bug, so we'd rather skip most of the tests in that case. + const bool timo_ok = ts.run(data); + SocketRequestor::SocketID socket_id; + if (timo_ok) { + // 1 should be ok + addAnswer("foo", ts.getPath()); + socket_id = doRequest(); + EXPECT_EQ("foo", socket_id.second); + EXPECT_EQ(0, close(socket_id.first)); + + // 2 should be ok too + addAnswer("bar", ts.getPath()); + socket_id = doRequest(); + EXPECT_EQ("bar", socket_id.second); + EXPECT_EQ(0, close(socket_id.first)); + + // 3 should be ok too (reuse earlier token) + addAnswer("foo", ts.getPath()); + socket_id = doRequest(); + EXPECT_EQ("foo", socket_id.second); + EXPECT_EQ(0, close(socket_id.first)); + } + // Create a second socket server, to test that multiple different + // domains sockets would work as well (even though we don't actually + // use that feature) + TestSocket ts2; + std::vector > data2; + data2.push_back(std::pair("foo\n", 1)); + const bool timo_ok2 = ts2.run(data2); + + if (timo_ok2) { + // 1 should be ok + addAnswer("foo", ts2.getPath()); + socket_id = doRequest(); + EXPECT_EQ("foo", socket_id.second); + EXPECT_EQ(0, close(socket_id.first)); + } - if (timo_ok) { - // Now use first socket again - addAnswer("foo", ts.getPath()); - socket_id = doRequest(); - EXPECT_EQ("foo", socket_id.second); - EXPECT_EQ(0, close(socket_id.first)); + if (timo_ok) { + // Now use first socket again + addAnswer("foo", ts.getPath()); + socket_id = doRequest(); + EXPECT_EQ("foo", socket_id.second); + EXPECT_EQ(0, close(socket_id.first)); + + // -1 is a "normal" error + addAnswer("foo", ts.getPath()); + EXPECT_THROW(doRequest(), SocketRequestor::SocketError); + + // -2 is an unexpected error. After this point it's not guaranteed the + // connection works as intended. + addAnswer("foo", ts.getPath()); + EXPECT_THROW(doRequest(), SocketRequestor::SocketError); + } - // -1 is a "normal" error + // Vector is of first socket is now empty, so the socket should be gone addAnswer("foo", ts.getPath()); EXPECT_THROW(doRequest(), SocketRequestor::SocketError); - // -2 is an unexpected error. After this point it's not guaranteed the - // connection works as intended. - addAnswer("foo", ts.getPath()); + // Vector is of second socket is now empty too, so the socket should be + // gone + addAnswer("foo", ts2.getPath()); EXPECT_THROW(doRequest(), SocketRequestor::SocketError); } - - // Vector is of first socket is now empty, so the socket should be gone - addAnswer("foo", ts.getPath()); - EXPECT_THROW(doRequest(), SocketRequestor::SocketError); - - // Vector is of second socket is now empty too, so the socket should be - // gone - addAnswer("foo", ts2.getPath()); - EXPECT_THROW(doRequest(), SocketRequestor::SocketError); } } diff --git a/src/lib/util/tests/fd_share_tests.cc b/src/lib/util/tests/fd_share_tests.cc index cc92e47487..b4eccb7bce 100644 --- a/src/lib/util/tests/fd_share_tests.cc +++ b/src/lib/util/tests/fd_share_tests.cc @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -30,44 +31,47 @@ namespace { // We test that we can transfer a pipe over other pipe TEST(FDShare, transfer) { - // Get a pipe and fork - int pipes[2]; - ASSERT_NE(-1, socketpair(AF_UNIX, SOCK_STREAM, 0, pipes)); - pid_t sender(fork()); - ASSERT_NE(-1, sender); - if(sender) { // We are in parent - // Close the other side of pipe, we want only writible one - EXPECT_NE(-1, close(pipes[0])); - // Get a process to check data - int fd(0); - pid_t checker(check_output(&fd, "data", 4)); - ASSERT_NE(-1, checker); - // Now, send the file descriptor, close it and close the pipe - EXPECT_NE(-1, send_fd(pipes[1], fd)); - EXPECT_NE(-1, close(pipes[1])); - EXPECT_NE(-1, close(fd)); - // Check both subprocesses ended well - EXPECT_TRUE(process_ok(sender)); - EXPECT_TRUE(process_ok(checker)); - } else { // We are in child. We do not use ASSERT here - // Close the write end, we only read - if(close(pipes[1])) { - exit(1); - } - // Get the file descriptor - int fd(recv_fd(pipes[0])); - if(fd == -1) { - exit(1); - } - // This pipe is not needed - if(close(pipes[0])) { - exit(1); - } - // Send "data" trough the received fd, close it and be done - if(!write_data(fd, "data", 4) || close(fd) == -1) { - exit(1); + + if (!isc::util::unittests::runningOnValgrind()) { + // Get a pipe and fork + int pipes[2]; + ASSERT_NE(-1, socketpair(AF_UNIX, SOCK_STREAM, 0, pipes)); + pid_t sender(fork()); + ASSERT_NE(-1, sender); + if(sender) { // We are in parent + // Close the other side of pipe, we want only writible one + EXPECT_NE(-1, close(pipes[0])); + // Get a process to check data + int fd(0); + pid_t checker(check_output(&fd, "data", 4)); + ASSERT_NE(-1, checker); + // Now, send the file descriptor, close it and close the pipe + EXPECT_NE(-1, send_fd(pipes[1], fd)); + EXPECT_NE(-1, close(pipes[1])); + EXPECT_NE(-1, close(fd)); + // Check both subprocesses ended well + EXPECT_TRUE(process_ok(sender)); + EXPECT_TRUE(process_ok(checker)); + } else { // We are in child. We do not use ASSERT here + // Close the write end, we only read + if(close(pipes[1])) { + exit(1); + } + // Get the file descriptor + int fd(recv_fd(pipes[0])); + if(fd == -1) { + exit(1); + } + // This pipe is not needed + if(close(pipes[0])) { + exit(1); + } + // Send "data" trough the received fd, close it and be done + if(!write_data(fd, "data", 4) || close(fd) == -1) { + exit(1); + } + exit(0); } - exit(0); } } diff --git a/src/lib/util/tests/fd_tests.cc b/src/lib/util/tests/fd_tests.cc index b709405116..1a1d3ee7c1 100644 --- a/src/lib/util/tests/fd_tests.cc +++ b/src/lib/util/tests/fd_tests.cc @@ -12,6 +12,8 @@ // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. +#include + #include #include @@ -45,24 +47,28 @@ class FDTest : public ::testing::Test { // Test we read what was sent TEST_F(FDTest, read) { - int read_pipe(0); - buffer = new unsigned char[TEST_DATA_SIZE]; - pid_t feeder(provide_input(&read_pipe, data, TEST_DATA_SIZE)); - ASSERT_GE(feeder, 0); - ssize_t received(read_data(read_pipe, buffer, TEST_DATA_SIZE)); - EXPECT_TRUE(process_ok(feeder)); - EXPECT_EQ(TEST_DATA_SIZE, received); - EXPECT_EQ(0, memcmp(data, buffer, received)); + if (!isc::util::unittests::runningOnValgrind()) { + int read_pipe(0); + buffer = new unsigned char[TEST_DATA_SIZE]; + pid_t feeder(provide_input(&read_pipe, data, TEST_DATA_SIZE)); + ASSERT_GE(feeder, 0); + ssize_t received(read_data(read_pipe, buffer, TEST_DATA_SIZE)); + EXPECT_TRUE(process_ok(feeder)); + EXPECT_EQ(TEST_DATA_SIZE, received); + EXPECT_EQ(0, memcmp(data, buffer, received)); + } } // Test we write the correct thing TEST_F(FDTest, write) { - int write_pipe(0); - pid_t checker(check_output(&write_pipe, data, TEST_DATA_SIZE)); - ASSERT_GE(checker, 0); - EXPECT_TRUE(write_data(write_pipe, data, TEST_DATA_SIZE)); - EXPECT_EQ(0, close(write_pipe)); - EXPECT_TRUE(process_ok(checker)); + if (!isc::util::unittests::runningOnValgrind()) { + int write_pipe(0); + pid_t checker(check_output(&write_pipe, data, TEST_DATA_SIZE)); + ASSERT_GE(checker, 0); + EXPECT_TRUE(write_data(write_pipe, data, TEST_DATA_SIZE)); + EXPECT_EQ(0, close(write_pipe)); + EXPECT_TRUE(process_ok(checker)); + } } } diff --git a/src/lib/util/tests/interprocess_sync_file_unittest.cc b/src/lib/util/tests/interprocess_sync_file_unittest.cc index 9a1b02511a..6f23558086 100644 --- a/src/lib/util/tests/interprocess_sync_file_unittest.cc +++ b/src/lib/util/tests/interprocess_sync_file_unittest.cc @@ -13,6 +13,8 @@ // PERFORMANCE OF THIS SOFTWARE. #include "util/interprocess_sync_file.h" + +#include #include #include @@ -53,59 +55,62 @@ parentReadLockedState (int fd) { } TEST(InterprocessSyncFileTest, TestLock) { - InterprocessSyncFile sync("test"); - InterprocessSyncLocker locker(sync); + InterprocessSyncFile sync("test"); + InterprocessSyncLocker locker(sync); - EXPECT_FALSE(locker.isLocked()); - EXPECT_TRUE(locker.lock()); - EXPECT_TRUE(locker.isLocked()); + EXPECT_FALSE(locker.isLocked()); + EXPECT_TRUE(locker.lock()); + EXPECT_TRUE(locker.isLocked()); - int fds[2]; + if (!isc::util::unittests::runningOnValgrind()) { - // Here, we check that a lock has been taken by forking and - // checking from the child that a lock exists. This has to be - // done from a separate process as we test by trying to lock the - // range again on the lock file. The lock attempt would pass if - // done from the same process for the granted range. The lock - // attempt must fail to pass our check. + int fds[2]; - EXPECT_EQ(0, pipe(fds)); + // Here, we check that a lock has been taken by forking and + // checking from the child that a lock exists. This has to be + // done from a separate process as we test by trying to lock the + // range again on the lock file. The lock attempt would pass if + // done from the same process for the granted range. The lock + // attempt must fail to pass our check. - if (fork() == 0) { - unsigned char locked = 0; - // Child writes to pipe - close(fds[0]); + EXPECT_EQ(0, pipe(fds)); - InterprocessSyncFile sync2("test"); - InterprocessSyncLocker locker2(sync2); + if (fork() == 0) { + unsigned char locked = 0; + // Child writes to pipe + close(fds[0]); - if (!locker2.tryLock()) { - EXPECT_FALSE(locker2.isLocked()); - locked = 1; - } else { - EXPECT_TRUE(locker2.isLocked()); - } + InterprocessSyncFile sync2("test"); + InterprocessSyncLocker locker2(sync2); - ssize_t bytes_written = write(fds[1], &locked, sizeof(locked)); - EXPECT_EQ(sizeof(locked), bytes_written); + if (!locker2.tryLock()) { + EXPECT_FALSE(locker2.isLocked()); + locked = 1; + } else { + EXPECT_TRUE(locker2.isLocked()); + } - close(fds[1]); - exit(0); - } else { - // Parent reads from pipe - close(fds[1]); + ssize_t bytes_written = write(fds[1], &locked, sizeof(locked)); + EXPECT_EQ(sizeof(locked), bytes_written); - const unsigned char locked = parentReadLockedState(fds[0]); + close(fds[1]); + exit(0); + } else { + // Parent reads from pipe + close(fds[1]); - close(fds[0]); + const unsigned char locked = parentReadLockedState(fds[0]); - EXPECT_EQ(1, locked); - } + close(fds[0]); - EXPECT_TRUE(locker.unlock()); - EXPECT_FALSE(locker.isLocked()); + EXPECT_EQ(1, locked); + } + } + + EXPECT_TRUE(locker.unlock()); + EXPECT_FALSE(locker.isLocked()); - EXPECT_EQ (0, unlink(TEST_DATA_TOPBUILDDIR "/test_lockfile")); + EXPECT_EQ (0, unlink(TEST_DATA_TOPBUILDDIR "/test_lockfile")); } TEST(InterprocessSyncFileTest, TestMultipleFilesDirect) { @@ -126,49 +131,53 @@ TEST(InterprocessSyncFileTest, TestMultipleFilesDirect) { } TEST(InterprocessSyncFileTest, TestMultipleFilesForked) { - InterprocessSyncFile sync("test1"); - InterprocessSyncLocker locker(sync); + InterprocessSyncFile sync("test1"); + InterprocessSyncLocker locker(sync); - EXPECT_TRUE(locker.lock()); + EXPECT_TRUE(locker.lock()); - int fds[2]; + if (!isc::util::unittests::runningOnValgrind()) { - EXPECT_EQ(0, pipe(fds)); + int fds[2]; - if (fork() == 0) { - unsigned char locked = 0xff; - // Child writes to pipe - close(fds[0]); + EXPECT_EQ(0, pipe(fds)); - InterprocessSyncFile sync2("test2"); - InterprocessSyncLocker locker2(sync2); + if (fork() == 0) { + unsigned char locked = 0xff; + // Child writes to pipe + close(fds[0]); - if (locker2.tryLock()) { - locked = 0; - } + InterprocessSyncFile sync2("test2"); + InterprocessSyncLocker locker2(sync2); - ssize_t bytes_written = write(fds[1], &locked, sizeof(locked)); - EXPECT_EQ(sizeof(locked), bytes_written); + if (locker2.tryLock()) { + locked = 0; + } - close(fds[1]); - exit(0); - } else { - // Parent reads from pipe - close(fds[1]); + ssize_t bytes_written = write(fds[1], &locked, sizeof(locked)); + EXPECT_EQ(sizeof(locked), bytes_written); - const unsigned char locked = parentReadLockedState(fds[0]); + close(fds[1]); + exit(0); + } else { + // Parent reads from pipe + close(fds[1]); - close(fds[0]); + const unsigned char locked = parentReadLockedState(fds[0]); - EXPECT_EQ(0, locked); - } + close(fds[0]); - EXPECT_TRUE(locker.unlock()); + EXPECT_EQ(0, locked); + } - EXPECT_EQ (0, unlink(TEST_DATA_TOPBUILDDIR "/test1_lockfile")); - EXPECT_EQ (0, unlink(TEST_DATA_TOPBUILDDIR "/test2_lockfile")); -} + EXPECT_EQ (0, unlink(TEST_DATA_TOPBUILDDIR "/test2_lockfile")); + } + + EXPECT_TRUE(locker.unlock()); + + EXPECT_EQ (0, unlink(TEST_DATA_TOPBUILDDIR "/test1_lockfile")); } +} // anonymous namespace } // namespace util } // namespace isc diff --git a/src/lib/util/threads/tests/condvar_unittest.cc b/src/lib/util/threads/tests/condvar_unittest.cc index 1e04efa3ff..3bb7230e39 100644 --- a/src/lib/util/threads/tests/condvar_unittest.cc +++ b/src/lib/util/threads/tests/condvar_unittest.cc @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -84,12 +85,14 @@ ringSignal(CondVar* condvar, Mutex* mutex, int* arg) { // A simple wait-signal operation on a condition variable. TEST_F(CondVarTest, waitAndSignal) { - Mutex::Locker locker(mutex_); - int shared_var = 0; // let the other thread increment this - Thread t(boost::bind(&ringSignal, &condvar_, &mutex_, &shared_var)); - condvar_.wait(mutex_); - t.wait(); - EXPECT_EQ(1, shared_var); + if (!isc::util::unittests::runningOnValgrind()) { + Mutex::Locker locker(mutex_); + int shared_var = 0; // let the other thread increment this + Thread t(boost::bind(&ringSignal, &condvar_, &mutex_, &shared_var)); + condvar_.wait(mutex_); + t.wait(); + EXPECT_EQ(1, shared_var); + } } // Thread's main code for the next test @@ -143,12 +146,14 @@ signalAndWait(CondVar* condvar, Mutex* mutex) { TEST_F(CondVarTest, destroyWhileWait) { // We'll destroy a CondVar object while the thread is still waiting // on it. This will trigger an assertion failure. - EXPECT_DEATH_IF_SUPPORTED({ - CondVar cond; - Mutex::Locker locker(mutex_); - Thread t(boost::bind(&signalAndWait, &cond, &mutex_)); - cond.wait(mutex_); - }, ""); + if (!isc::util::unittests::runningOnValgrind()) { + EXPECT_DEATH_IF_SUPPORTED({ + CondVar cond; + Mutex::Locker locker(mutex_); + Thread t(boost::bind(&signalAndWait, &cond, &mutex_)); + cond.wait(mutex_); + }, ""); + } } #endif // !HAS_UNDEFINED_PTHREAD_BEHAVIOR diff --git a/src/lib/util/threads/tests/lock_unittest.cc b/src/lib/util/threads/tests/lock_unittest.cc index 1abc3fac99..4c4f831876 100644 --- a/src/lib/util/threads/tests/lock_unittest.cc +++ b/src/lib/util/threads/tests/lock_unittest.cc @@ -94,33 +94,35 @@ void noHandler(int) {} TEST(MutexTest, swarm) { - // Create a timeout in case something got stuck here - struct sigaction ignored, original; - memset(&ignored, 0, sizeof(ignored)); - ignored.sa_handler = noHandler; - if (sigaction(SIGALRM, &ignored, &original)) { - FAIL() << "Couldn't set alarm"; - } - alarm(10); - // This type has a low chance of being atomic itself, further raising - // the chance of problems appearing. - double canary = 0; - Mutex mutex; - // Run two parallel threads - bool ready1 = false; - bool ready2 = false; - Thread t1(boost::bind(&performIncrement, &canary, &ready1, &ready2, - &mutex)); - Thread t2(boost::bind(&performIncrement, &canary, &ready2, &ready1, - &mutex)); - t1.wait(); - t2.wait(); - // Check it the sum is the expected value. - EXPECT_EQ(iterations * 2, canary) << "Threads are badly synchronized"; - // Cancel the alarm and return the original handler - alarm(0); - if (sigaction(SIGALRM, &original, NULL)) { - FAIL() << "Couldn't restore alarm"; + if (!isc::util::unittests::runningOnValgrind()) { + // Create a timeout in case something got stuck here + struct sigaction ignored, original; + memset(&ignored, 0, sizeof(ignored)); + ignored.sa_handler = noHandler; + if (sigaction(SIGALRM, &ignored, &original)) { + FAIL() << "Couldn't set alarm"; + } + alarm(10); + // This type has a low chance of being atomic itself, further raising + // the chance of problems appearing. + double canary = 0; + Mutex mutex; + // Run two parallel threads + bool ready1 = false; + bool ready2 = false; + Thread t1(boost::bind(&performIncrement, &canary, &ready1, &ready2, + &mutex)); + Thread t2(boost::bind(&performIncrement, &canary, &ready2, &ready1, + &mutex)); + t1.wait(); + t2.wait(); + // Check it the sum is the expected value. + EXPECT_EQ(iterations * 2, canary) << "Threads are badly synchronized"; + // Cancel the alarm and return the original handler + alarm(0); + if (sigaction(SIGALRM, &original, NULL)) { + FAIL() << "Couldn't restore alarm"; + } } } diff --git a/src/lib/util/threads/tests/thread_unittest.cc b/src/lib/util/threads/tests/thread_unittest.cc index 5afdf3f537..0a8df4135d 100644 --- a/src/lib/util/threads/tests/thread_unittest.cc +++ b/src/lib/util/threads/tests/thread_unittest.cc @@ -13,6 +13,7 @@ // PERFORMANCE OF THIS SOFTWARE. #include +#include #include @@ -41,9 +42,11 @@ doSomething(int*) { } // We just test that we can forget about the thread and nothing // bad will happen on our side. TEST(ThreadTest, detached) { - int x; - for (size_t i = 0; i < detached_iterations; ++i) { - Thread thread(boost::bind(&doSomething, &x)); + if (!isc::util::unittests::runningOnValgrind()) { + int x; + for (size_t i = 0; i < detached_iterations; ++i) { + Thread thread(boost::bind(&doSomething, &x)); + } } } @@ -55,13 +58,15 @@ markRun(bool* mark) { // Wait for a thread to end first. The variable must be set at the time. TEST(ThreadTest, wait) { - for (size_t i = 0; i < iterations; ++i) { - bool mark = false; - Thread thread(boost::bind(markRun, &mark)); - thread.wait(); - ASSERT_TRUE(mark) << "Not finished yet in " << i << "th iteration"; - // Can't wait second time - ASSERT_THROW(thread.wait(), isc::InvalidOperation); + if (!isc::util::unittests::runningOnValgrind()) { + for (size_t i = 0; i < iterations; ++i) { + bool mark = false; + Thread thread(boost::bind(markRun, &mark)); + thread.wait(); + ASSERT_TRUE(mark) << "Not finished yet in " << i << "th iteration"; + // Can't wait second time + ASSERT_THROW(thread.wait(), isc::InvalidOperation); + } } } @@ -77,21 +82,25 @@ throwException() { // Exception in the thread we forget about should not do anything to us TEST(ThreadTest, detachedException) { - for (size_t i = 0; i < detached_iterations; ++i) { - Thread thread(throwSomething); - } - for (size_t i = 0; i < detached_iterations; ++i) { - Thread thread(throwException); + if (!isc::util::unittests::runningOnValgrind()) { + for (size_t i = 0; i < detached_iterations; ++i) { + Thread thread(throwSomething); + } + for (size_t i = 0; i < detached_iterations; ++i) { + Thread thread(throwException); + } } } // An uncaught exception in the thread should propagate through wait TEST(ThreadTest, exception) { - for (size_t i = 0; i < iterations; ++i) { - Thread thread(throwSomething); - Thread thread2(throwException); - ASSERT_THROW(thread.wait(), Thread::UncaughtException); - ASSERT_THROW(thread2.wait(), Thread::UncaughtException); + if (!isc::util::unittests::runningOnValgrind()) { + for (size_t i = 0; i < iterations; ++i) { + Thread thread(throwSomething); + Thread thread2(throwException); + ASSERT_THROW(thread.wait(), Thread::UncaughtException); + ASSERT_THROW(thread2.wait(), Thread::UncaughtException); + } } } diff --git a/src/lib/util/unittests/fork.cc b/src/lib/util/unittests/fork.cc index 7ed22f8251..2d5efb0b71 100644 --- a/src/lib/util/unittests/fork.cc +++ b/src/lib/util/unittests/fork.cc @@ -77,6 +77,7 @@ provide_input(int *read_pipe, const void *input, const size_t length) return -1; } *read_pipe = pipes[0]; + pid_t pid(fork()); if (pid) { // We are in the parent return pid; @@ -91,6 +92,7 @@ provide_input(int *read_pipe, const void *input, const size_t length) } } + /* * This creates a pipe, forks and reads the pipe and compares it * with given data. Used to check output of run in an asynchronous way. diff --git a/tests/tools/perfdhcp/test_control.cc b/tests/tools/perfdhcp/test_control.cc index f7f4978fd7..e51065f4a9 100644 --- a/tests/tools/perfdhcp/test_control.cc +++ b/tests/tools/perfdhcp/test_control.cc @@ -13,27 +13,28 @@ // PERFORMANCE OF THIS SOFTWARE. -#include -#include -#include -#include -#include -#include -#include - -#include - #include #include #include #include #include #include +#include #include "test_control.h" #include "command_options.h" #include "perf_pkt4.h" #include "perf_pkt6.h" +#include +#include +#include +#include +#include +#include +#include + +#include + using namespace std; using namespace boost::posix_time; using namespace isc; @@ -724,7 +725,7 @@ TestControl::printDiagnostics() const { std::cout << "Set MAC to " << vector2Hex(options.getMacTemplate(), "::") << std::endl; if (options.getDuidTemplate().size() > 0) { - std::cout << "Set DUID to " << vector2Hex(options.getDuidTemplate()) << std::endl; + std::cout << "Set DUID to " << vector2Hex(options.getDuidTemplate()) << std::endl; } } }