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