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