diff --git a/src/scheduled_executor.cpp b/src/scheduled_executor.cpp index 6119f2ed129c061ae2660eb23de5355f8ba9e944..2d98f6b0d687cfa260fd4abc89c30dd9a0f6779e 100644 --- a/src/scheduled_executor.cpp +++ b/src/scheduled_executor.cpp @@ -109,8 +109,10 @@ ScheduledExecutor::loop() while (running_ and (jobs_.empty() or jobs_.begin()->first > clock::now())) { if (jobs_.empty()) cv_.wait(lock); - else - cv_.wait_until(lock, jobs_.begin()->first); + else { + auto nextJob = jobs_.begin()->first; + cv_.wait_until(lock, nextJob); + } } if (not running_) return; diff --git a/test/unitTest/Makefile.am b/test/unitTest/Makefile.am index 4747e2e5645eb9b67824f2053abeb950209de7fe..495fb4a685b2cdae5a3bec37f13bda28ceb1dad2 100644 --- a/test/unitTest/Makefile.am +++ b/test/unitTest/Makefile.am @@ -20,6 +20,13 @@ check_PROGRAMS += ut_certstore ut_certstore_SOURCES = certstore.cpp ut_certstore_LDADD = @OPENDHT_LIBS@ +# +# scheduler +# +check_PROGRAMS += ut_scheduler +ut_scheduler_SOURCES = scheduler.cpp +ut_scheduler_LDADD = @OPENDHT_LIBS@ + # # base64 # diff --git a/test/unitTest/scheduler.cpp b/test/unitTest/scheduler.cpp new file mode 100644 index 0000000000000000000000000000000000000000..125403c86aca97dbacafa4cd7f84ae963a2d3d2b --- /dev/null +++ b/test/unitTest/scheduler.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2004-2020 Savoir-faire Linux Inc. + * + * Author: Adrien Béraud <adrien.beraud@savoirfaielinux.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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <cppunit/TestAssert.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> + +#include "test_runner.h" + +#include "scheduled_executor.h" +#include <opendht/rng.h> + +namespace jami { namespace test { + +class SchedulerTest : public CppUnit::TestFixture { +public: + static std::string name() { return "scheduler"; } + +private: + void schedulerTest(); + + CPPUNIT_TEST_SUITE(SchedulerTest); + CPPUNIT_TEST(schedulerTest); + CPPUNIT_TEST_SUITE_END(); +}; + +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(SchedulerTest, SchedulerTest::name()); + +void +SchedulerTest::schedulerTest() +{ + jami::ScheduledExecutor executor; + + constexpr unsigned N = 1024; + std::mutex mtx; + std::condition_variable cv; + std::unique_lock<std::mutex> lk(mtx); + + std::atomic_uint64_t taskRun {0}; + std::atomic_uint64_t result {0}; + + auto task = [&]{ + auto rng = dht::crypto::getSeededRandomEngine(); + uint64_t sum {0}; + for (uint64_t i=0; i<64 * N; i++) + sum += rng(); + result += sum; + std::lock_guard<std::mutex> l(mtx); + if (++taskRun == N) + cv.notify_all(); + }; + CPPUNIT_ASSERT(taskRun == 0); + + for (unsigned i=0; i<N; i++) + executor.run(task); + + CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(2), [&]{ + return taskRun == N; + })); + + for (unsigned i=0; i<N; i++) + executor.scheduleIn(task, std::chrono::microseconds(1)); + + CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(2), [&]{ + return taskRun == 2 * N; + })); + + for (unsigned i=0; i<N; i++) + executor.scheduleIn(task, std::chrono::microseconds(1)); + executor.stop(); +} + +}} // namespace jami::test + +RING_TEST_RUNNER(jami::test::SchedulerTest::name());