ifw-daq 3.1.0
IFW Data Acquisition modules
Loading...
Searching...
No Matches
progress.hpp
Go to the documentation of this file.
1/**
2 * @file
3 * @ingroup daq_common_utsupport
4 * @copyright (c) Copyright ESO 2022
5 * All Rights Reserved
6 * ESO (eso.org) is an Intergovernmental Organisation, and therefore special legal conditions apply.
7 *
8 * @brief Defines shared test progress utilities.
9 */
10#ifndef OCM_DAQ_TEST_PROGRESS_HPP
11#define OCM_DAQ_TEST_PROGRESS_HPP
12// GCOVR_EXCL_START
13#include <thread>
14#include <chrono>
15
16#include <boost/chrono.hpp>
17
18#include <boost/asio/io_context.hpp>
19#include <gtest/gtest.h>
20
21namespace daq::test {
22/**
23 * Executes io_ctx::poll until @a pred returns true or it times out.
24 */
25template<class Predicate>
26void MakeTestProgressUntil(boost::asio::io_context& io_ctx, Predicate&& pred, std::chrono::milliseconds
27 timeout = std::chrono::seconds(3)) {
28 auto until = std::chrono::steady_clock::now() + timeout;
29
30 while(std::chrono::steady_clock::now() < until) {
31 io_ctx.restart();
32 io_ctx.poll();
33 if (pred()) {
34 return;
35 }
36 }
37 FAIL() << "MakeTestProgressUntil timed out";
38}
39
40/**
41 * Test helper that progress the test by executing pending jobs and optionally wait for
42 * a future to be ready.
43 *
44 * @ingroup daq_ocm_libdaq_test
45 */
46template <class Future = void>
47void MakeTestProgress(boost::asio::io_context& io_ctx, Future* fut = nullptr) {
48 using namespace std::chrono;
49 using namespace ::testing;
50
51 auto work = std::make_unique<boost::asio::io_context::work>(io_ctx);
52
53 // Run asio in its own thread so we can independenty wait for future
54 std::thread t([&]() {
55 try {
56 io_ctx.restart();
57 io_ctx.run();
58 // The run() function blocks until all work has finished and there are no more handlers to be dispatched
59 // or until the io_context has been stopped.
60 } catch (std::exception const& e) {
61 FAIL() << "MakeTestProgress caught std::exception: " << e.what();
62 } catch (...) {
63 FAIL() << "MakeTestProgress caught unknown exception";
64 }
65 });
66 std::this_thread::yield();
67 if constexpr (!std::is_same_v<Future, void>) {
68 if (fut) {
69 EXPECT_NO_THROW(fut->wait_for(boost::chrono::seconds(3)));
70 }
71 // remove work so that asio::io_context::run returns
72 work.reset();
73 // Explicitly stop io_ctx if future is ready. I.e. even if there are handlers pending
74 // we want to stop here since the caller might set up next step in the test.
75 io_ctx.stop();
76 t.join();
77 if (fut) {
78 ASSERT_TRUE(fut->is_ready()) << "Future is not ready after 1s, aborting";
79 }
80 } else {
81 // remove work so that asio::io_context::run returns
82 work.reset();
83 t.join();
84 }
85}
86
87} // namespace daq::test
88// GCOVR_EXCL_STOP
89#endif // #ifndef OCM_DAQ_TEST_PROGRESS_HPP
90
void MakeTestProgress(boost::asio::io_context &io_ctx, Future *fut=nullptr)
Test helper that progress the test by executing pending jobs and optionally wait for a future to be r...
Definition: progress.hpp:47
void MakeTestProgressUntil(boost::asio::io_context &io_ctx, Predicate &&pred, std::chrono::milliseconds timeout=std::chrono::seconds(3))
Executes io_ctx::poll until pred returns true or it times out.
Definition: progress.hpp:26
ASSERT_TRUE(std::holds_alternative< OlasReceiver >(spec.receivers[0]))