From 3147468d353a35bf4a6d67bcd594f30fcc717f41 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Mon, 23 Apr 2018 18:56:23 +0100 Subject: [PATCH] unit_tests: add threadpool unit test --- tests/unit_tests/CMakeLists.txt | 1 + tests/unit_tests/threadpool.cpp | 101 ++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 tests/unit_tests/threadpool.cpp diff --git a/tests/unit_tests/CMakeLists.txt b/tests/unit_tests/CMakeLists.txt index 9c58536c9..46fd3f886 100644 --- a/tests/unit_tests/CMakeLists.txt +++ b/tests/unit_tests/CMakeLists.txt @@ -62,6 +62,7 @@ set(unit_tests_sources test_tx_utils.cpp test_peerlist.cpp test_protocol_pack.cpp + threadpool.cpp hardfork.cpp unbound.cpp uri.cpp diff --git a/tests/unit_tests/threadpool.cpp b/tests/unit_tests/threadpool.cpp new file mode 100644 index 000000000..34be1417a --- /dev/null +++ b/tests/unit_tests/threadpool.cpp @@ -0,0 +1,101 @@ +// Copyright (c) 2018, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include +#include "gtest/gtest.h" +#include "misc_language.h" +#include "common/threadpool.h" + +TEST(threadpool, wait_nothing) +{ + std::shared_ptr tpool(tools::threadpool::getNewForUnitTests()); + tools::threadpool::waiter waiter; + waiter.wait(); +} + +TEST(threadpool, wait_waits) +{ + std::shared_ptr tpool(tools::threadpool::getNewForUnitTests()); + tools::threadpool::waiter waiter; + std::atomic b(false); + tpool->submit(&waiter, [&b](){ epee::misc_utils::sleep_no_w(1000); b = true; }); + ASSERT_FALSE(b); + waiter.wait(); + ASSERT_TRUE(b); +} + +TEST(threadpool, one_thread) +{ + std::shared_ptr tpool(tools::threadpool::getNewForUnitTests(1)); + tools::threadpool::waiter waiter; + + std::atomic counter(0); + for (size_t n = 0; n < 4096; ++n) + { + tpool->submit(&waiter, [&counter](){++counter;}); + } + waiter.wait(); + ASSERT_EQ(counter, 4096); +} + +TEST(threadpool, many_threads) +{ + std::shared_ptr tpool(tools::threadpool::getNewForUnitTests(256)); + tools::threadpool::waiter waiter; + + std::atomic counter(0); + for (size_t n = 0; n < 4096; ++n) + { + tpool->submit(&waiter, [&counter](){++counter;}); + } + waiter.wait(); + ASSERT_EQ(counter, 4096); +} + +static uint64_t fibonacci(std::shared_ptr tpool, uint64_t n) +{ + if (n <= 1) + return n; + uint64_t f1, f2; + tools::threadpool::waiter waiter; + tpool->submit(&waiter, [&tpool, &f1, n](){ f1 = fibonacci(tpool, n-1); }); + tpool->submit(&waiter, [&tpool, &f2, n](){ f2 = fibonacci(tpool, n-2); }); + waiter.wait(); + return f1 + f2; +} + +TEST(threadpool, reentrency) +{ + std::shared_ptr tpool(tools::threadpool::getNewForUnitTests(4)); + tools::threadpool::waiter waiter; + + uint64_t f = fibonacci(tpool, 13); + waiter.wait(); + ASSERT_EQ(f, 233); +} +