ifw-daq 3.1.0
IFW Data Acquisition modules
Loading...
Searching...
No Matches
testDpmService.cpp
Go to the documentation of this file.
1/**
2 * @file
3 * @ingroup daq_common_libdpm
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 Unit tests for daq::dpm::DpmService
9 */
10
11#include <daq/dpm/scheduler.hpp>
12
13#include <utility>
14
15#include <gmock/gmock.h>
16#include <gtest/gtest.h>
17
18#include <daq/test/progress.hpp>
19
20#include "daqifFake.hpp"
21#include "mock/mockMal.hpp"
23#include "mock/mockWorkspace.hpp"
25
26namespace daq::dpm {
27
28class TestDpmService : public ::testing::Test {
29public:
31 }
32
33 void SetUp() override {
34 m_service =
35 std::make_unique<DpmService>(m_executor, m_mal_mock, m_ws_mock, m_scheduler_mock);
36 }
37 void TearDown() override {
38 // Execute possibly pending completions handlers.
39 EXPECT_NO_THROW(m_io_ctx.poll());
40 }
41
42protected:
43 boost::asio::io_context m_io_ctx;
45
49
50 std::unique_ptr<DpmService> m_service;
51};
52
53using namespace ::testing;
54
55TEST_F(TestDpmService, QueryStorageStatusSuceeds) {
56 // Setup
57 std::filesystem::space_info status = {};
58 status.available = 123;
59 status.free = 456;
60 status.capacity = 789;
61
62 EXPECT_CALL(m_ws_mock, QueryStorageStatus()).WillOnce(Return(status));
63
64 auto* fake_reply(new daqif::StorageStatusFake);
65 EXPECT_CALL(m_mal_mock, getDataEntityUnsafe(_, "daqif_StorageStatus"))
66 .WillOnce(Return(fake_reply))
67 .RetiresOnSaturation();
68
69 // Run
70 auto fut = m_service->QueryStorageStatus();
71 m_io_ctx.poll();
72
73 ASSERT_TRUE(fut.is_ready());
74 auto daqif_status = fut.get();
75 EXPECT_EQ(daqif_status->getCapacity(), status.capacity);
76 EXPECT_EQ(daqif_status->getFree(), status.free);
77 EXPECT_EQ(daqif_status->getAvailable(), status.available);
78}
79
80TEST_F(TestDpmService, QueryStorageStatusFails) {
81 // Setup
82 EXPECT_CALL(m_ws_mock, QueryStorageStatus()).WillOnce(Throw(std::runtime_error("ERROR")));
83
84 // Run
85 auto fut = m_service->QueryStorageStatus();
86 m_io_ctx.poll();
87
88 ASSERT_TRUE(fut.is_ready());
89 EXPECT_THROW(fut.get(), daqif::RuntimeError);
90}
91
92TEST_F(TestDpmService, QueueDaqSucceeds) {
93 // Setup
94 auto* fake_reply(new daqif::DaqReplyFake);
95 EXPECT_CALL(m_mal_mock, getDataEntityUnsafe(_, "daqif_DaqReply"))
96 .WillOnce(Return(fake_reply))
97 .RetiresOnSaturation();
98 EXPECT_CALL(m_scheduler_mock, QueueDaq("STATUS", "SPEC")).WillOnce(Return("ID"));
99
100 // Run
101 auto fut = m_service->QueueDaq("STATUS", "SPEC");
102 m_io_ctx.poll();
103
104 ASSERT_TRUE(fut.is_ready());
105 auto reply = fut.get();
106 EXPECT_EQ(reply->getId(), "ID");
107}
108
109TEST_F(TestDpmService, QueueDaqThrows) {
110 // Setup
111 EXPECT_CALL(m_scheduler_mock, QueueDaq("STATUS", "SPEC"))
112 .WillOnce(Throw(std::runtime_error("ID")));
113
114 // Run
115 auto fut = m_service->QueueDaq("STATUS", "SPEC");
116 m_io_ctx.poll();
117
118 ASSERT_TRUE(fut.is_ready());
119 EXPECT_THROW(fut.get(), daqif::DaqException);
120}
121
122TEST_F(TestDpmService, AbortDaqSucceeds) {
123 // Setup
124 auto* fake_reply(new daqif::DaqReplyFake);
125 EXPECT_CALL(m_mal_mock, getDataEntityUnsafe(_, "daqif_DaqReply"))
126 .WillOnce(Return(fake_reply))
127 .RetiresOnSaturation();
128 EXPECT_CALL(m_scheduler_mock, AbortDaq("TEST.ID")).Times(1);
129
130 // Run
131 auto fut = m_service->AbortDaq("TEST.ID");
132 m_io_ctx.poll();
133
134 ASSERT_TRUE(fut.is_ready());
135 auto reply = fut.get();
136 EXPECT_EQ(reply->getId(), "TEST.ID");
137 EXPECT_FALSE(reply->getError());
138}
139
140TEST_F(TestDpmService, AbortDaqThrows) {
141 // Setup
142 EXPECT_CALL(m_scheduler_mock, AbortDaq("ID")).WillOnce(Throw(std::runtime_error("ID")));
143
144 // Run
145 auto fut = m_service->AbortDaq("ID");
146 m_io_ctx.poll();
147
148 ASSERT_TRUE(fut.is_ready());
149 EXPECT_THROW(fut.get(), daqif::DaqException);
150}
151
152TEST_F(TestDpmService, GetDaqStatusSucceeds) {
153 // Setup
154 auto* fake_reply(new daqif::DaqStatusFake);
155 EXPECT_CALL(m_mal_mock, getDataEntityUnsafe(_, "daqif_DaqStatus"))
156 .WillOnce(Return(fake_reply))
157 .RetiresOnSaturation();
158
159 Status status = {};
160 status.id = "TEST.ID";
161 status.state = State::Merging;
162 EXPECT_CALL(m_scheduler_mock, GetDaqStatus("TEST.ID")).WillOnce(Return(status));
163
164 // Run
165 auto fut = m_service->GetDaqStatus("TEST.ID");
166 m_io_ctx.poll();
167
168 ASSERT_TRUE(fut.is_ready());
169 auto reply = fut.get();
170 EXPECT_EQ(reply->getId(), "TEST.ID");
171 EXPECT_EQ(reply->getState(), daqif::StateMerging);
172 EXPECT_EQ(reply->getSubState(), daqif::Merging);
173 EXPECT_FALSE(reply->getError());
174}
175
176TEST_F(TestDpmService, GetDaqStatusThrows) {
177 // Setup
178 EXPECT_CALL(m_scheduler_mock, GetDaqStatus("TEST.ID"))
179 .WillOnce(Throw(std::runtime_error("oops")));
180
181 // Run
182 auto fut = m_service->GetDaqStatus("TEST.ID");
183 m_io_ctx.poll();
184
185 ASSERT_TRUE(fut.is_ready());
186 EXPECT_THROW(fut.get(), daqif::DaqException);
187}
188
189TEST_F(TestDpmService, GetActiveDaqsSucceeds) {
190 // Setup
191 auto* fake_reply1(new daqif::DaqStatusFake);
192 auto* fake_reply2(new daqif::DaqStatusFake);
193 EXPECT_CALL(m_mal_mock, getDataEntityUnsafe(_, "daqif_DaqStatus"))
194 .WillOnce(Return(fake_reply1))
195 .WillOnce(Return(fake_reply2))
196 .RetiresOnSaturation();
197
198 Status status1 = {};
199 status1.id = "TEST.ID";
200 status1.state = State::Collecting;
201
202 Status status2 = {};
203 status2.id = "TEST.ID2";
205
206 std::vector<std::string> ids = {"TEST.ID", "TEST.ID2"};
207 EXPECT_CALL(m_scheduler_mock, GetQueue()).WillOnce(Return(ids));
208 EXPECT_CALL(m_scheduler_mock, GetDaqStatus("TEST.ID")).WillOnce(Return(status1));
209 EXPECT_CALL(m_scheduler_mock, GetDaqStatus("TEST.ID2")).WillOnce(Return(status2));
210
211 // Run
212 auto fut = m_service->GetActiveDaqs();
213 m_io_ctx.poll();
214
215 ASSERT_TRUE(fut.is_ready());
216 std::vector<std::shared_ptr<::daqif::DaqStatus>> reply = fut.get();
217 ASSERT_EQ(reply.size(), 2u);
218
219 EXPECT_EQ(reply[0]->getId(), "TEST.ID");
220 EXPECT_EQ(reply[0]->getState(), daqif::StateMerging);
221 EXPECT_EQ(reply[0]->getSubState(), daqif::Collecting);
222 EXPECT_FALSE(reply[0]->getError());
223
224 EXPECT_EQ(reply[1]->getId(), "TEST.ID2");
225 EXPECT_EQ(reply[1]->getState(), daqif::StateMerging);
226 EXPECT_EQ(reply[1]->getSubState(), daqif::Aborting);
227 EXPECT_FALSE(reply[1]->getError());
228}
229
230TEST_F(TestDpmService, GetActiveDaqsThrowws) {
231 // Setup
232 std::vector<std::string> ids = {"TEST.ID", "TEST.ID2"};
233 EXPECT_CALL(m_scheduler_mock, GetQueue()).WillOnce(Return(ids));
234 EXPECT_CALL(m_scheduler_mock, GetDaqStatus("TEST.ID"))
235 .WillOnce(Throw(std::runtime_error("oops")));
236
237 // Run
238 auto fut = m_service->GetActiveDaqs();
239 m_io_ctx.poll();
240
241 ASSERT_TRUE(fut.is_ready());
242 EXPECT_THROW(fut.get(), daqif::DaqException);
243}
244} // namespace daq::dpm
rad::IoExecutor m_executor
std::unique_ptr< DpmService > m_service
daq::dpm::MockWorkspace m_ws_mock
boost::asio::io_context m_io_ctx
daq::dpm::MockScheduler m_scheduler_mock
Adapts boost::asio::io_context into a compatible boost::thread Executor type.
Definition: ioExecutor.hpp:12
daq::dpm::DpmService implements MAL services daqif::DpmControl and daqif::DpmDaqControl.
Mocks for daq::dpm::Workspace and daq::dpm::DaqWorkspace.
Mocks for daq::dpm::Scheduler and daq::dpm::DaqScheduler.
TEST_F(TestDaqController, ScheduledTransitionsToCollecting)
@ Collecting
Input files are being collected.
@ Merging
DAQ is being merged.
@ AbortingMerging
Transitional state for aborting during merging.
Defines shared test progress utilities.
daq::dpm::Scheduler and related class declarations.
Non observable status object that keeps stores status of data acquisition.
Definition: status.hpp:164
State state
Definition: status.hpp:186
std::string id
Definition: status.hpp:184
EXPECT_EQ(meta.rr_uri, "zpb.rr://meta")
ASSERT_EQ(meta.keyword_rules.size(), 1u)
ASSERT_TRUE(std::holds_alternative< OlasReceiver >(spec.receivers[0]))