ClosedRangeSetHandler_t.cc
Go to the documentation of this file.
1 #define BOOST_TEST_MODULE (ClosedRangeSetHandler_t)
2 #include "boost/test/unit_test.hpp"
3 
4 //======================================================================================
5 // Test of ClosedRangeSetHandler
6 //
7 // Consider the following set of SubRuns and events for Run 1. The
8 // last row of numbers corresponds to the RangeSet for the SubRun
9 // labeled above that line. Note that there is a discontinuity in the
10 // SubRun 1 event ranges.
11 //
12 // -------------- --------------------------------
13 // ------------------------------
14 // | Run 1 : (Run 1) : (Run 1) | | SubRun 0 |
15 // SubRun 1 | SubRun 2 | | 5 6 7 8 9
16 // 10 | 1 2 3 4 5 6 : 9 10 11 12 13 14 | 3 4 5 6 7 8 9 10 11 12 13 14 |
17 // -------------- --------------------------------
18 // ------------------------------
19 //
20 // For Run 1, the RangeSet corresponding to the above diagram would be
21 // printed out as:
22 //
23 // Run 1:
24 // SubRun: 0 Event range: [5,11)
25 // SubRun: 1 Event range: [1,7)
26 // SubRun: 1 Event range: [9,15)
27 // SubRun: 2 Event range: [3,15)
28 //
29 // This test exercises the system by simulating a given number of
30 // processed events, and then retrieving the 'seen' event ranges based
31 // on when a file switch is simulated.
32 //
33 // We test three situations:
34 //
35 // (1) No events processed -- i.e. the RangeSets as shown above should
36 // be forwarded to an output file with no splitting.
37 //
38 // (2) Events with Run = 1, SubRun = 1 and Event = 3, 4, 5, and 10 are
39 // processed, with a file switch after event 5.
40 //
41 // (3) Events with Run = 1, SubRun = 1 and Event = 3, 4, and 5 are
42 // processed, with a file switch after event 5.
43 //======================================================================================
44 
49 
50 #include <vector>
51 
52 using namespace art;
54 
55 namespace {
56 
57  auto
58  eventRanges(unsigned const subrun)
59  {
60  std::vector<EventRange> ranges;
61  if (subrun == 0u) {
62  ranges.emplace_back(0, 5, 11);
63  } else if (subrun == 1u) {
64  ranges.emplace_back(1, 1, 7);
65  ranges.emplace_back(1, 9, 15);
66  } else if (subrun == 2u) {
67  ranges.emplace_back(2, 3, 15);
68  }
69  return ranges;
70  }
71 
72  template <typename T>
73  auto
74  concatenate(std::vector<T>& l, std::vector<T> const& r)
75  {
77  }
78 
79  struct RSHandler {
80  RSHandler()
81  {
82  std::vector<EventRange> runRanges;
83  for (std::size_t i{0}; i != 3; ++i) {
84  auto const& ranges = eventRanges(i);
85  auto const& rs = RangeSet{1, ranges};
86  srHandlers.push_back(std::make_unique<ClosedRangeSetHandler>(rs));
87  concatenate(runRanges, ranges);
88  }
89  rHandler =
90  std::make_unique<ClosedRangeSetHandler>(RangeSet{1, runRanges});
91  }
92  std::vector<std::unique_ptr<RangeSetHandler>>
93  srHandlers; // 3 separate RangeSetHandlers
94  std::unique_ptr<RangeSetHandler>
95  rHandler; // 1 RangeSetHandler with all ranges
96  };
97 
98 } // namespace
99 
100 BOOST_FIXTURE_TEST_SUITE(ClosedRangeSetHandler_t, RSHandler)
101 
102 BOOST_AUTO_TEST_CASE(EmptyRunAndSubRuns)
103 {
104  // In this case, no events were seen in any of the runs/subruns. So
105  // flush the ranges.
106  for (std::size_t i{0}; i != 3; ++i) {
107  srHandlers[i]->flushRanges();
108  auto const& rs = RangeSet{1, eventRanges(i)};
109  BOOST_TEST(srHandlers[i]->seenRanges() == rs);
110  }
111 
112  rHandler->flushRanges();
113  std::vector<EventRange> runRef;
114  for (std::size_t i{0}; i != 3; ++i) {
115  concatenate(runRef, eventRanges(i));
116  }
117  RangeSet const runRSRef{1, runRef};
118  BOOST_TEST(rHandler->seenRanges() == runRSRef);
119 }
120 
121 BOOST_AUTO_TEST_CASE(SplitOnNonLastSubRunEvent)
122 {
123  // For this test, we're in the middle of processing SubRun 1 at
124  // event 5, when we decide to switch to a new input file. In this
125  // case, 5 IS NOT the last processed event in the SubRun.
126 
127  std::vector<SimpleEvent> events;
128  events.emplace_back(EventID{1, 1, 3}, false);
129  events.emplace_back(EventID{1, 1, 4}, false);
130  events.emplace_back(EventID{1, 1, 5}, false);
131 
132  auto const& srHandler = srHandlers[1];
133  // Process events
134  for (auto const& e : events) {
135  srHandler->update(e.id, e.lastInSubRun);
136  rHandler->update(e.id, e.lastInSubRun);
137  }
138 
139  // Simulate file switch
140  // 1. Maybe split range
141  srHandler->maybeSplitRange();
142  rHandler->maybeSplitRange();
143 
144  {
145  std::vector<EventRange> subRunRef;
146  subRunRef.emplace_back(1, 1, 6);
147  RangeSet const subRunRSRef{1, subRunRef};
148  BOOST_TEST(srHandler->seenRanges() == subRunRSRef);
149  }
150 
151  {
152  std::vector<EventRange> runRef;
153  runRef.emplace_back(0, 5, 11);
154  runRef.emplace_back(1, 1, 6);
155  RangeSet const runRSRef{1, runRef};
156  BOOST_TEST(rHandler->seenRanges() == runRSRef);
157  }
158 
159  // 2. Rebase ranges
160  srHandler->rebase();
161  rHandler->rebase();
162 
163  // Process last event
164  SimpleEvent const lastEvent{EventID{1, 1, 10}, true};
165  srHandler->update(lastEvent.id, lastEvent.lastInSubRun);
166  rHandler->update(lastEvent.id, lastEvent.lastInSubRun);
167 
168  // Simulate end of subrun and run
169  srHandler->flushRanges();
170  rHandler->flushRanges();
171  {
172  std::vector<EventRange> subRunRef;
173  subRunRef.emplace_back(1, 6, 7);
174  subRunRef.emplace_back(1, 9, 15);
175  RangeSet const subRunRSRef{1, subRunRef};
176  BOOST_TEST(srHandler->seenRanges() == subRunRSRef);
177  }
178  {
179  std::vector<EventRange> runRef;
180  runRef.emplace_back(1, 6, 7);
181  runRef.emplace_back(1, 9, 15);
182  runRef.emplace_back(2, 3, 15);
183  RangeSet const runRSRef{1, runRef};
184  BOOST_TEST(rHandler->seenRanges() == runRSRef);
185  }
186 }
187 
188 BOOST_AUTO_TEST_CASE(SplitOnLastSubRunEvent)
189 {
190  // For this test, we're in the middle of processing SubRun 1 at
191  // event 5, when we decide to switch to a new input file. In this
192  // case, 5 IS the last processed event in the SubRun.
193 
194  std::vector<SimpleEvent> events;
195  events.emplace_back(EventID{1, 1, 3}, false);
196  events.emplace_back(EventID{1, 1, 4}, false);
197  events.emplace_back(EventID{1, 1, 5}, true);
198 
199  auto const& srHandler = srHandlers[1];
200  // Process events
201  for (auto const& e : events) {
202  srHandler->update(e.id, e.lastInSubRun);
203  rHandler->update(e.id, e.lastInSubRun);
204  }
205 
206  // Simulate file switch
207  srHandler->maybeSplitRange();
208  rHandler->maybeSplitRange();
209  {
210  RangeSet const subRunRSRef{1, eventRanges(1)};
211  BOOST_TEST(srHandler->seenRanges() == subRunRSRef);
212  }
213  {
214  std::vector<EventRange> runRef;
215  concatenate(runRef, eventRanges(0));
216  concatenate(runRef, eventRanges(1));
217  RangeSet const runRSRef{1, runRef};
218  BOOST_TEST(rHandler->seenRanges() == runRSRef);
219  }
220  srHandler->rebase();
221  rHandler->rebase();
222 
223  // Both RangeSets should now be empty (have not yet processed any
224  // events from SubRun 2).
225  RangeSet const emptyRS{1, std::vector<EventRange>{}};
226  BOOST_TEST(srHandler->seenRanges() == emptyRS);
227  BOOST_TEST(rHandler->seenRanges() == emptyRS);
228 }
229 
230 BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(EmptyRunAndSubRuns)
std::string concatenate(H const &h, T const &...t)
Definition: select.h:138
static QStrList * l
Definition: config.cpp:1044
const double e