Line data Source code
1 : #define BOOST_TEST_MODULE RoundRobin_policy_t
2 : #include <boost/test/unit_test.hpp>
3 :
4 : #include "artdaq/RoutingPolicies/RoutingManagerPolicy.hh"
5 : #include "artdaq/RoutingPolicies/makeRoutingManagerPolicy.hh"
6 : #include "fhiclcpp/ParameterSet.h"
7 :
8 : BOOST_AUTO_TEST_SUITE(RoundRobin_policy_t)
9 :
10 2 : BOOST_AUTO_TEST_CASE(VerifyRMPSharedPtr)
11 : {
12 3 : TLOG(TLVL_INFO) << "RoundRobin_policy_t Test Case VerifyRMPSharedPtr BEGIN";
13 2 : auto ps4 = fhicl::ParameterSet::make("");
14 2 : auto ps3 = fhicl::ParameterSet::make("");
15 2 : auto ps2 = fhicl::ParameterSet::make("");
16 :
17 1 : auto rrA = artdaq::makeRoutingManagerPolicy("RoundRobin", ps4);
18 :
19 1 : auto rrB = rrA;
20 1 : BOOST_REQUIRE_EQUAL(rrA, rrB);
21 :
22 2 : rrA = artdaq::makeRoutingManagerPolicy("RoundRobin", ps3);
23 1 : BOOST_REQUIRE(rrA != rrB);
24 :
25 : // force destructors to be run on first set of policies
26 1 : rrB = artdaq::makeRoutingManagerPolicy("RoundRobin", ps2);
27 :
28 3 : TLOG(TLVL_INFO) << "RoundRobin_policy_t Test Case VerifyRMPSharedPtr END";
29 1 : }
30 :
31 2 : BOOST_AUTO_TEST_CASE(Simple)
32 : {
33 3 : TLOG(TLVL_INFO) << "RoundRobin_policy_t Test Case Simple BEGIN";
34 2 : fhicl::ParameterSet ps = fhicl::ParameterSet::make("");
35 :
36 1 : auto rr = artdaq::makeRoutingManagerPolicy("RoundRobin", ps);
37 :
38 1 : rr->Reset();
39 1 : rr->AddReceiverToken(1, 1);
40 1 : rr->AddReceiverToken(3, 1);
41 1 : rr->AddReceiverToken(2, 1);
42 1 : rr->AddReceiverToken(4, 1);
43 1 : rr->AddReceiverToken(2, 1);
44 1 : BOOST_REQUIRE_EQUAL(rr->GetReceiverCount(), 4);
45 1 : auto secondTable = rr->GetCurrentTable();
46 1 : BOOST_REQUIRE_EQUAL(secondTable.size(), 4);
47 1 : BOOST_REQUIRE_EQUAL(secondTable[0].destination_rank, 1);
48 1 : BOOST_REQUIRE_EQUAL(secondTable[1].destination_rank, 2);
49 1 : BOOST_REQUIRE_EQUAL(secondTable[2].destination_rank, 3);
50 1 : BOOST_REQUIRE_EQUAL(secondTable[3].destination_rank, 4);
51 1 : BOOST_REQUIRE_EQUAL(secondTable[0].sequence_id, 1);
52 1 : BOOST_REQUIRE_EQUAL(secondTable[1].sequence_id, 2);
53 1 : BOOST_REQUIRE_EQUAL(secondTable[2].sequence_id, 3);
54 1 : BOOST_REQUIRE_EQUAL(secondTable[3].sequence_id, 4);
55 :
56 1 : rr->AddReceiverToken(1, 0);
57 :
58 1 : auto thirdTable = rr->GetCurrentTable();
59 1 : BOOST_REQUIRE_EQUAL(thirdTable.size(), 0);
60 :
61 1 : rr->AddReceiverToken(1, 2);
62 1 : rr->AddReceiverToken(2, 1);
63 1 : rr->AddReceiverToken(3, 1);
64 1 : rr->AddReceiverToken(4, 2);
65 1 : auto fourthTable = rr->GetCurrentTable();
66 1 : BOOST_REQUIRE_EQUAL(fourthTable.size(), 4);
67 1 : BOOST_REQUIRE_EQUAL(fourthTable[0].destination_rank, 1);
68 :
69 1 : rr->AddReceiverToken(3, 1);
70 1 : auto fifthTable = rr->GetCurrentTable();
71 1 : BOOST_REQUIRE_EQUAL(fifthTable.size(), 4);
72 1 : BOOST_REQUIRE_EQUAL(fifthTable[0].destination_rank, 1);
73 :
74 3 : TLOG(TLVL_INFO) << "RoundRobin_policy_t Test Case Simple END";
75 1 : }
76 :
77 2 : BOOST_AUTO_TEST_CASE(MinimumParticipants)
78 : {
79 3 : TLOG(TLVL_INFO) << "RoundRobin_policy_t Test Case MinimumParticipants BEGIN";
80 2 : fhicl::ParameterSet ps = fhicl::ParameterSet::make("minimum_participants: 2");
81 :
82 1 : auto rr = artdaq::makeRoutingManagerPolicy("RoundRobin", ps);
83 :
84 1 : rr->Reset();
85 1 : rr->AddReceiverToken(1, 1);
86 1 : rr->AddReceiverToken(3, 1);
87 1 : rr->AddReceiverToken(2, 1);
88 1 : rr->AddReceiverToken(4, 1);
89 1 : rr->AddReceiverToken(2, 1);
90 1 : BOOST_REQUIRE_EQUAL(rr->GetReceiverCount(), 4);
91 1 : auto secondTable = rr->GetCurrentTable();
92 1 : BOOST_REQUIRE_EQUAL(secondTable.size(), 4);
93 1 : BOOST_REQUIRE_EQUAL(secondTable[0].destination_rank, 1);
94 1 : BOOST_REQUIRE_EQUAL(secondTable[1].destination_rank, 2);
95 1 : BOOST_REQUIRE_EQUAL(secondTable[2].destination_rank, 3);
96 1 : BOOST_REQUIRE_EQUAL(secondTable[3].destination_rank, 4);
97 1 : BOOST_REQUIRE_EQUAL(secondTable[0].sequence_id, 1);
98 1 : BOOST_REQUIRE_EQUAL(secondTable[1].sequence_id, 2);
99 1 : BOOST_REQUIRE_EQUAL(secondTable[2].sequence_id, 3);
100 1 : BOOST_REQUIRE_EQUAL(secondTable[3].sequence_id, 4);
101 :
102 1 : rr->AddReceiverToken(1, 0);
103 :
104 1 : auto thirdTable = rr->GetCurrentTable();
105 1 : BOOST_REQUIRE_EQUAL(thirdTable.size(), 0);
106 :
107 1 : rr->AddReceiverToken(1, 1);
108 1 : auto fourthTable = rr->GetCurrentTable();
109 1 : BOOST_REQUIRE_EQUAL(fourthTable.size(), 2);
110 :
111 1 : BOOST_REQUIRE_EQUAL(fourthTable[0].destination_rank, 1);
112 1 : BOOST_REQUIRE_EQUAL(fourthTable[1].destination_rank, 2);
113 1 : BOOST_REQUIRE_EQUAL(fourthTable[0].sequence_id, 5);
114 1 : BOOST_REQUIRE_EQUAL(fourthTable[1].sequence_id, 6);
115 :
116 1 : rr->AddReceiverToken(1, 2);
117 1 : rr->AddReceiverToken(2, 2);
118 1 : rr->AddReceiverToken(3, 1);
119 1 : rr->AddReceiverToken(4, 2);
120 1 : auto fifthTable = rr->GetCurrentTable();
121 1 : BOOST_REQUIRE_EQUAL(fifthTable.size(), 7);
122 1 : BOOST_REQUIRE_EQUAL(fifthTable[0].destination_rank, 1);
123 :
124 1 : rr->AddReceiverToken(3, 1);
125 1 : auto sixthTable = rr->GetCurrentTable();
126 1 : BOOST_REQUIRE_EQUAL(sixthTable.size(), 0);
127 :
128 3 : TLOG(TLVL_INFO) << "RoundRobin_policy_t Test Case MinimumParticipants END";
129 1 : }
130 :
131 : // RECENT CHANGE IN BEHAVIOR! Since the number of receivers is now dynamic as tokens are added, RoundRobin_policy will ALWAYS wait for at least minimum_participants to be available when it is positive!
132 2 : BOOST_AUTO_TEST_CASE(LargeMinimumParticipants)
133 : {
134 3 : TLOG(TLVL_INFO) << "RoundRobin_policy_t Test Case LargeMinimumParticipants BEGIN";
135 2 : fhicl::ParameterSet ps = fhicl::ParameterSet::make("minimum_participants: 5");
136 :
137 1 : auto rr = artdaq::makeRoutingManagerPolicy("RoundRobin", ps);
138 :
139 1 : rr->Reset();
140 1 : rr->AddReceiverToken(1, 1);
141 1 : rr->AddReceiverToken(3, 1);
142 1 : rr->AddReceiverToken(2, 1);
143 1 : rr->AddReceiverToken(3, 1);
144 1 : rr->AddReceiverToken(2, 1);
145 1 : BOOST_REQUIRE_EQUAL(rr->GetReceiverCount(), 3);
146 1 : auto firstTable = rr->GetCurrentTable();
147 1 : BOOST_REQUIRE_EQUAL(firstTable.size(), 0);
148 :
149 1 : rr->AddReceiverToken(5, 1);
150 1 : rr->AddReceiverToken(6, 1);
151 :
152 1 : auto secondTable = rr->GetCurrentTable();
153 1 : BOOST_REQUIRE_EQUAL(secondTable.size(), 5);
154 1 : BOOST_REQUIRE_EQUAL(secondTable[0].destination_rank, 1);
155 1 : BOOST_REQUIRE_EQUAL(secondTable[1].destination_rank, 2);
156 1 : BOOST_REQUIRE_EQUAL(secondTable[2].destination_rank, 3);
157 1 : BOOST_REQUIRE_EQUAL(secondTable[3].destination_rank, 5);
158 1 : BOOST_REQUIRE_EQUAL(secondTable[4].destination_rank, 6);
159 :
160 1 : rr->AddReceiverToken(1, 1);
161 1 : auto thirdTable = rr->GetCurrentTable();
162 1 : BOOST_REQUIRE_EQUAL(thirdTable.size(), 0);
163 :
164 3 : TLOG(TLVL_INFO) << "RoundRobin_policy_t Test Case LargeMinimumParticipants END";
165 1 : }
166 :
167 2 : BOOST_AUTO_TEST_CASE(ManyMissingParticipants)
168 : {
169 3 : TLOG(TLVL_INFO) << "RoundRobin_policy_t Test Case ManyMissingParticipants BEGIN";
170 2 : fhicl::ParameterSet ps = fhicl::ParameterSet::make("minimum_participants: -5");
171 :
172 1 : auto rr = artdaq::makeRoutingManagerPolicy("RoundRobin", ps);
173 :
174 1 : rr->Reset();
175 1 : rr->AddReceiverToken(1, 1);
176 1 : rr->AddReceiverToken(3, 1);
177 1 : rr->AddReceiverToken(2, 1);
178 1 : rr->AddReceiverToken(3, 1);
179 1 : rr->AddReceiverToken(2, 1);
180 1 : BOOST_REQUIRE_EQUAL(rr->GetReceiverCount(), 3);
181 1 : auto secondTable = rr->GetCurrentTable();
182 1 : BOOST_REQUIRE_EQUAL(secondTable.size(), 5);
183 1 : BOOST_REQUIRE_EQUAL(secondTable[0].destination_rank, 1);
184 :
185 1 : rr->AddReceiverToken(1, 1);
186 1 : auto thirdTable = rr->GetCurrentTable();
187 1 : BOOST_REQUIRE_EQUAL(thirdTable.size(), 1);
188 :
189 3 : TLOG(TLVL_INFO) << "RoundRobin_policy_t Test Case ManyMissingParticipants END";
190 1 : }
191 :
192 2 : BOOST_AUTO_TEST_CASE(DataFlowMode)
193 : {
194 3 : TLOG(TLVL_INFO) << "RoundRobin_policy_t Test Case DataFlowMode BEGIN";
195 2 : fhicl::ParameterSet ps = fhicl::ParameterSet::make("routing_manager_mode: DataFlow");
196 :
197 1 : auto rr = artdaq::makeRoutingManagerPolicy("RoundRobin", ps);
198 :
199 1 : rr->Reset();
200 1 : rr->AddReceiverToken(1, 1);
201 1 : rr->AddReceiverToken(3, 1);
202 1 : rr->AddReceiverToken(2, 1);
203 1 : rr->AddReceiverToken(3, 1);
204 1 : rr->AddReceiverToken(2, 1);
205 1 : BOOST_REQUIRE_EQUAL(rr->GetReceiverCount(), 3);
206 1 : auto route = rr->GetRouteForSequenceID(1, 4);
207 1 : BOOST_REQUIRE_EQUAL(route.destination_rank, 1);
208 1 : BOOST_REQUIRE_EQUAL(route.sequence_id, 1);
209 :
210 : // Multiple hits for the same sequence ID are allowed, and should receive different information
211 1 : route = rr->GetRouteForSequenceID(1, 5);
212 1 : BOOST_REQUIRE_EQUAL(route.destination_rank, 2);
213 1 : BOOST_REQUIRE_EQUAL(route.sequence_id, 1);
214 :
215 : // Except, that the same sequence ID from the same host should always get the same info
216 1 : route = rr->GetRouteForSequenceID(1, 5);
217 1 : BOOST_REQUIRE_EQUAL(route.destination_rank, 2);
218 1 : BOOST_REQUIRE_EQUAL(route.sequence_id, 1);
219 :
220 1 : route = rr->GetRouteForSequenceID(2, 4);
221 1 : BOOST_REQUIRE_EQUAL(route.destination_rank, 3);
222 1 : BOOST_REQUIRE_EQUAL(route.sequence_id, 2);
223 :
224 1 : route = rr->GetRouteForSequenceID(2, 5);
225 1 : BOOST_REQUIRE_EQUAL(route.destination_rank, -1);
226 :
227 1 : rr->AddReceiverToken(1, 1);
228 1 : route = rr->GetRouteForSequenceID(2, 5);
229 1 : BOOST_REQUIRE_EQUAL(route.destination_rank, 1);
230 1 : BOOST_REQUIRE_EQUAL(route.sequence_id, 2);
231 :
232 : // Out-of-order sequence IDs are allowed
233 1 : route = rr->GetRouteForSequenceID(1, 6);
234 1 : BOOST_REQUIRE_EQUAL(route.destination_rank, 2);
235 1 : BOOST_REQUIRE_EQUAL(route.sequence_id, 1);
236 :
237 : // Arbitrary sequence IDs are allowed
238 1 : route = rr->GetRouteForSequenceID(10343, 4);
239 1 : BOOST_REQUIRE_EQUAL(route.destination_rank, 3);
240 1 : BOOST_REQUIRE_EQUAL(route.sequence_id, 10343);
241 :
242 3 : TLOG(TLVL_INFO) << "RoundRobin_policy_t Test Case DataFlowMode END";
243 1 : }
244 :
245 2 : BOOST_AUTO_TEST_CASE(RequestBasedEventBuilding)
246 : {
247 3 : TLOG(TLVL_INFO) << "RoundRobin_policy_t Test Case RequestBasedEventBuilding BEGIN";
248 2 : fhicl::ParameterSet ps = fhicl::ParameterSet::make("routing_manager_mode: RequestBasedEventBuilding routing_cache_size: 2");
249 :
250 1 : auto rr = artdaq::makeRoutingManagerPolicy("RoundRobin", ps);
251 :
252 1 : rr->Reset();
253 1 : rr->AddReceiverToken(1, 1);
254 1 : rr->AddReceiverToken(3, 1);
255 1 : rr->AddReceiverToken(2, 1);
256 1 : rr->AddReceiverToken(3, 1);
257 1 : rr->AddReceiverToken(2, 1);
258 1 : BOOST_REQUIRE_EQUAL(rr->GetReceiverCount(), 3);
259 :
260 1 : auto route = rr->GetRouteForSequenceID(1, 4);
261 1 : BOOST_REQUIRE_EQUAL(route.destination_rank, 1);
262 1 : BOOST_REQUIRE_EQUAL(route.sequence_id, 1);
263 :
264 : // Multiple hits for the same sequence ID should receive the same routing
265 1 : route = rr->GetRouteForSequenceID(1, 5);
266 1 : BOOST_REQUIRE_EQUAL(route.destination_rank, 1);
267 1 : BOOST_REQUIRE_EQUAL(route.sequence_id, 1);
268 :
269 : // Only events which have started routing should be in the table
270 1 : auto firstTable = rr->GetCurrentTable();
271 1 : BOOST_REQUIRE_EQUAL(firstTable.size(), 1);
272 1 : BOOST_REQUIRE_EQUAL(firstTable[0].destination_rank, 1);
273 :
274 : // Arbitrary Sequence IDs are allowed
275 1 : route = rr->GetRouteForSequenceID(12343, 4);
276 1 : BOOST_REQUIRE_EQUAL(route.destination_rank, 2);
277 1 : BOOST_REQUIRE_EQUAL(route.sequence_id, 12343);
278 :
279 : // Out-of-order Sequence IDs are allowed
280 1 : route = rr->GetRouteForSequenceID(4, 5);
281 1 : BOOST_REQUIRE_EQUAL(route.destination_rank, 3);
282 1 : BOOST_REQUIRE_EQUAL(route.sequence_id, 4);
283 :
284 : // Requests that arrive late still get the same info
285 1 : route = rr->GetRouteForSequenceID(1, 6);
286 1 : BOOST_REQUIRE_EQUAL(route.destination_rank, 1);
287 1 : BOOST_REQUIRE_EQUAL(route.sequence_id, 1);
288 :
289 : // Check that things behave when tokens are exhausted...
290 1 : route = rr->GetRouteForSequenceID(50, 4);
291 1 : BOOST_REQUIRE_EQUAL(route.destination_rank, -1);
292 :
293 1 : rr->AddReceiverToken(1, 1);
294 1 : route = rr->GetRouteForSequenceID(50, 4);
295 1 : BOOST_REQUIRE_EQUAL(route.destination_rank, 1);
296 1 : BOOST_REQUIRE_EQUAL(route.sequence_id, 50);
297 :
298 1 : route = rr->GetRouteForSequenceID(50, 5);
299 1 : BOOST_REQUIRE_EQUAL(route.destination_rank, 1);
300 1 : BOOST_REQUIRE_EQUAL(route.sequence_id, 50);
301 :
302 : // Routing cache is sorted by sequence ID
303 1 : auto secondTable = rr->GetCurrentTable();
304 1 : BOOST_REQUIRE_EQUAL(secondTable.size(), 3);
305 1 : BOOST_REQUIRE_EQUAL(secondTable[0].destination_rank, 3);
306 1 : BOOST_REQUIRE_EQUAL(secondTable[0].sequence_id, 4);
307 1 : BOOST_REQUIRE_EQUAL(secondTable[1].destination_rank, 1);
308 1 : BOOST_REQUIRE_EQUAL(secondTable[1].sequence_id, 50);
309 1 : BOOST_REQUIRE_EQUAL(secondTable[2].destination_rank, 2);
310 1 : BOOST_REQUIRE_EQUAL(secondTable[2].sequence_id, 12343);
311 :
312 : // Since the routing cache has been set to 2, only the highest two events routed are here, as the cache is checked when generating tables
313 1 : BOOST_REQUIRE_EQUAL(rr->GetCacheSize(), 2);
314 1 : auto thirdTable = rr->GetCurrentTable();
315 1 : BOOST_REQUIRE_EQUAL(thirdTable.size(), 0);
316 :
317 1 : BOOST_REQUIRE(rr->CacheHasRoute(50));
318 1 : BOOST_REQUIRE(!rr->CacheHasRoute(4));
319 1 : route = rr->GetRouteForSequenceID(50, 6);
320 1 : BOOST_REQUIRE_EQUAL(route.destination_rank, 1);
321 1 : BOOST_REQUIRE_EQUAL(route.sequence_id, 50);
322 :
323 3 : TLOG(TLVL_INFO) << "RoundRobin_policy_t Test Case RequestBasedEventBuilding END";
324 1 : }
325 :
326 : BOOST_AUTO_TEST_SUITE_END()
|