diff --git a/CMakeLists.txt b/CMakeLists.txt index 70f38f6f0688701fb06281064ed53a173222e039..7b3937a2e9334d6f0a585b21dd20d5ffb26a5c94 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -321,6 +321,8 @@ if (OPENDHT_TESTS) tests/dhtrunnertester.cpp tests/peerdiscoverytester.h tests/peerdiscoverytester.cpp + tests/threadpooltester.h + tests/threadpooltester.cpp ) if (OPENDHT_PROXY_SERVER AND OPENDHT_PROXY_CLIENT) list (APPEND test_FILES diff --git a/tests/threadpooltester.cpp b/tests/threadpooltester.cpp new file mode 100644 index 0000000000000000000000000000000000000000..769da3b6240def4da96a22de6abe7dd04d696e42 --- /dev/null +++ b/tests/threadpooltester.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2019 Savoir-faire Linux Inc. + * + * Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include "threadpooltester.h" + +#include "opendht/thread_pool.h" +#include <atomic> + +namespace test { +CPPUNIT_TEST_SUITE_REGISTRATION(ThreadPoolTester); +using clock = std::chrono::steady_clock; + +void +ThreadPoolTester::setUp() { + +} + +void +ThreadPoolTester::testThreadPool() { + dht::ThreadPool pool(16); + + constexpr unsigned N = 64 * 1024; + std::atomic_uint count {0}; + for (unsigned i=0; i<N; i++) + pool.run([&] { + count++; + }); + + auto start = clock::now(); + while (count.load() != N && clock::now() - start < std::chrono::seconds(10)) + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + + pool.join(); + CPPUNIT_ASSERT(count.load() == N); +} + +void +ThreadPoolTester::testExecutor() +{ + dht::ThreadPool pool(8); + auto executor1 = std::make_shared<dht::Executor>(pool, 1); + auto executor4 = std::make_shared<dht::Executor>(pool, 4); + auto executor8 = std::make_shared<dht::Executor>(pool, 8); + + constexpr unsigned N = 64 * 1024; + std::atomic_uint count1 {0}; + std::atomic_uint count4 {0}; + std::atomic_uint count8 {0}; + for (unsigned i=0; i<N; i++) { + executor1->run([&] { count1++; }); + executor4->run([&] { count4++; }); + executor8->run([&] { count8++; }); + } + + auto start = clock::now(); + while ((count1.load() != N || + count4.load() != N || + count8.load() != N) && clock::now() - start < std::chrono::seconds(20)) + { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + executor1.reset(); + executor4.reset(); + executor8.reset(); + CPPUNIT_ASSERT_EQUAL(N, count1.load()); + CPPUNIT_ASSERT_EQUAL(N, count4.load()); + CPPUNIT_ASSERT_EQUAL(N, count8.load()); +} + +void +ThreadPoolTester::tearDown() { +} + +} // namespace test diff --git a/tests/threadpooltester.h b/tests/threadpooltester.h new file mode 100644 index 0000000000000000000000000000000000000000..f55addbf528781f19ccde22854cff85ba3042633 --- /dev/null +++ b/tests/threadpooltester.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2019 Savoir-faire Linux Inc. + * + * Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#pragma once + +// cppunit +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> + +namespace test { + +class ThreadPoolTester : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(ThreadPoolTester); + CPPUNIT_TEST(testThreadPool); + CPPUNIT_TEST(testExecutor); + CPPUNIT_TEST_SUITE_END(); + + public: + /** + * Method automatically called before each test by CppUnit + */ + void setUp(); + /** + * Method automatically called after each test CppUnit + */ + void tearDown(); + + void testThreadPool(); + void testExecutor(); +}; + +} // namespace test