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