ATLAS Offline Software
UnitTestFixture.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 
8 //
9 // includes
10 //
11 
13 
15 #include <EventLoop/Driver.h>
19 #include <RootCoreUtils/Assert.h>
20 #include <RootCoreUtils/ThrowMsg.h>
26 #include <TChain.h>
27 #include <TFile.h>
28 #include <TH1.h>
29 #include <TTree.h>
30 #include <TSystem.h>
31 
32 //
33 // method implementations
34 //
35 
36 namespace EL
37 {
38  namespace
39  {
40  std::vector<std::string>
41  readVectorFromTree (SH::Sample *sample, const std::string& treeName,
42  const std::string& branchName)
43  {
44  std::vector<std::string> result;
45  auto fileNames = sample->makeFileList();
46  TString *var = nullptr;
47  for (auto& fileName : fileNames)
48  {
49  std::unique_ptr<TFile> file (TFile::Open (fileName.c_str(), "READ"));
50  if (file == nullptr)
51  RCU_THROW_MSG ("failed to open file: " + fileName);
52  TTree *tree = dynamic_cast<TTree*>(file->Get (treeName.c_str()));
53  Long64_t nentries = 0;
54  if (tree != nullptr && (nentries = tree->GetEntries()) > 0)
55  {
56  TBranch *branch = nullptr;
57  tree->SetBranchAddress (branchName.c_str(), &var, &branch);
58  for (Long64_t entry = 0; entry < nentries; ++ entry)
59  {
60  if (branch->GetEntry(entry) <= 0)
61  RCU_THROW_MSG ("failed to read entry from branch");
62  result.push_back (var->Data());
63  }
64  }
65  }
66  return result;
67  }
68  }
69 
70 
71 
72 
73  std::map<std::shared_ptr<Driver>,std::string> UnitTestFixture::m_jobs;
74 
76  getSample (const std::string& sampleName)
77  {
78  if (sampleName == "empty")
79  {
80  static SH::SamplePtr result;
81  if (result.empty())
82  {
83  std::unique_ptr<SH::SampleLocal> myresult (new SH::SampleLocal ("empty"));
84  myresult->add (makeFile ({}));
85  result = myresult.release();
86  }
87  return result;
88  }
89  if (sampleName == "single")
90  {
91  static SH::SamplePtr result;
92  if (result.empty())
93  {
94  std::unique_ptr<SH::SampleLocal> myresult (new SH::SampleLocal ("single"));
95  std::vector<unsigned> entries;
96  for (unsigned iter = 0; iter != 10000; ++ iter)
97  entries.push_back (iter % 10);
98  myresult->add (makeFile (entries));
99  result = myresult.release();
100  }
101  return result;
102  }
103  if (sampleName == "multi")
104  {
105  static SH::SamplePtr result;
106  if (result.empty())
107  {
108  std::unique_ptr<SH::SampleLocal> myresult (new SH::SampleLocal ("multi"));
109  for (unsigned jter = 0; jter != 10; ++ jter)
110  {
111  std::vector<unsigned> entries;
112  for (unsigned iter = 0; iter != 10000; ++ iter)
113  entries.push_back (iter % 10);
114  myresult->add (makeFile (entries));
115  }
116  result = myresult.release();
117  }
118  return result;
119  }
120  RCU_THROW_MSG ("unknown sample: " + sampleName);
121  }
122 
123 
124 
126  getSH ()
127  {
129  sh.add (getSample ("empty"));
130  sh.add (getSample ("single"));
131  sh.add (getSample ("multi"));
132  sh.setMetaString (SH::MetaFields::treeName, "physics");
133  return sh;
134  }
135 
136 
137 
138  std::string UnitTestFixture ::
139  getJob ()
140  {
141  using namespace asg::msgUserCode;
142  ANA_MSG_INFO ("in EventLoopTest");
143 
144  std::shared_ptr<Driver> driver = GetParam().m_driver;
145  auto iter = m_jobs.find (driver);
146  if (iter != m_jobs.end())
147  return iter->second;
148 
149  Job job;
150  job.sampleHandler (getSH());
151  GetParam().setupJob (job);
152  {
154  config.setType ("EL::UnitTestAlg2");
155  config.setName ("newAlg");
156  config.setUseXAODs (false);
157  ANA_CHECK_THROW (config.setProperty ("property", 42));
158  job.algsAdd (config);
159  }
160  {
161  std::unique_ptr<UnitTestAlg1> alg (new UnitTestAlg1);
162  job.algsAdd (alg.release());
163  }
164 
165  std::ostringstream submit;
166  submit << "submit-" << driver.get();
167  driver->submit (job, submit.str());
168  driver->wait (submit.str());
169  m_jobs[driver] = submit.str();
170  return submit.str();
171  }
172 
173 
174 
176  getTObject (const std::string& sampleName,
177  const std::string& objectName,
178  bool isMandatory)
179  {
181  sh.load (getJob() + "/hist");
182  SH::Sample *sample = sh.get (sampleName);
183  if (sample == nullptr)
184  RCU_THROW_MSG ("couldn't find sample: " + sampleName);
185  TObject *object = sample->readHist (objectName);
186  if (isMandatory && object == nullptr)
187  RCU_THROW_MSG ("couldn't find object: " + objectName);
188  return object;
189  }
190 
191 
192 
194  eventCount (const std::string& sampleName)
195  {
196  TH1 *hist = getHist<TH1> (sampleName, "EventLoop_EventCount", true);
197  return hist->GetBinContent (1);
198  }
199 
200 
201 
203  getCallbacks (const std::string& sampleName)
204  {
205  return getHist<TH1> (sampleName, "callbacks", true);
206  }
207 
208 
209 
211  checkFileExecuted (const std::string& sampleName)
212  {
213  std::set<std::string> filesOut;
214  {
216  sh.load (getJob() + "/hist");
217  SH::Sample *sample = sh.get (sampleName);
218  if (sample == nullptr)
219  RCU_THROW_MSG ("couldn't find sample: " + sampleName);
220  auto vec = readVectorFromTree (sample, "EventLoop_FileExecuted", "file");
221  filesOut.insert (vec.begin(), vec.end());
222  }
223  std::set<std::string> filesIn;
224  for (auto& file : getSample (sampleName)->makeFileList())
225  {
226  auto split = file.rfind ('/');
227  if (split == std::string::npos)
228  split = 0;
229  else
230  ++ split;
231  std::string fileName = file.substr (split);
232  ASSERT_TRUE (filesIn.find (fileName) == filesIn.end());
233  filesIn.insert (fileName);
234  }
235  ASSERT_EQ (filesIn, filesOut);
236  }
237 
238 
239 
240  std::string UnitTestFixture ::
241  makeFile (const std::vector<unsigned>& entries)
242  {
243  static unsigned index = 0;
244  std::ostringstream fileName;
245  fileName << "file-" << ++ index << ".root";
246 
247  std::unique_ptr<SH::DiskWriter> file
248  = GetParam().make_file_writer (fileName.str());
249  {
250  if (!entries.empty())
251  {
252  TTree *tree = new TTree ("physics", "physics");
253  Int_t el_n = 0;
254  tree->Branch ("el_n", &el_n, "el_n/I");
255  for (auto entry : entries)
256  {
257  el_n = entry;
258  tree->Fill ();
259  }
260  }
261  file->file()->Write ();
262  file->close ();
263  }
264  return file->path();
265  }
266 
267 
268 
269  TEST_P (UnitTestFixture, empty_eventCount)
270  {
271  EXPECT_EQ (eventCount ("empty"), 0u);
272  }
273 
274 
275 
276  TEST_P (UnitTestFixture, empty_callbacks)
277  {
278  TH1 *callbacks = getCallbacks ("empty");
279  EXPECT_EQ (0, callbacks->GetBinContent (1 + UnitTestAlg1::CB_CHANGE_INPUT_FIRST));
280  EXPECT_EQ (0, callbacks->GetBinContent (1 + UnitTestAlg1::CB_CHANGE_INPUT_OTHER));
281  EXPECT_EQ (0, callbacks->GetBinContent (1 + UnitTestAlg1::CB_INITIALIZE));
282  EXPECT_LE (1, callbacks->GetBinContent (1 + UnitTestAlg1::CB_HIST_INITIALIZE));
283  EXPECT_EQ (0, callbacks->GetBinContent (1 + UnitTestAlg1::CB_EXECUTE));
284  EXPECT_EQ (1, callbacks->GetBinContent (1 + UnitTestAlg1::CB_FILE_EXECUTE));
285  EXPECT_EQ (0, callbacks->GetBinContent (1 + UnitTestAlg1::CB_FINALIZE));
286  EXPECT_LE (1, callbacks->GetBinContent (1 + UnitTestAlg1::CB_HIST_FINALIZE));
287  }
288 
289 
290 
291  TEST_P (UnitTestFixture, empty_fileExecuted)
292  {
293  checkFileExecuted ("empty");
294  }
295 
296 
297 
298  TEST_P (UnitTestFixture, single_eventCount)
299  {
300  EXPECT_EQ (eventCount ("single"), 10000u);
301  }
302 
303 
304 
305  TEST_P (UnitTestFixture, single_callbacks)
306  {
307  TH1 *callbacks = getCallbacks ("single");
308  EXPECT_LE (1, callbacks->GetBinContent (1 + UnitTestAlg1::CB_CHANGE_INPUT_FIRST));
309  EXPECT_LE (0, callbacks->GetBinContent (1 + UnitTestAlg1::CB_CHANGE_INPUT_OTHER));
310  EXPECT_LE (1, callbacks->GetBinContent (1 + UnitTestAlg1::CB_INITIALIZE));
311  EXPECT_LE (1, callbacks->GetBinContent (1 + UnitTestAlg1::CB_HIST_INITIALIZE));
312  EXPECT_EQ (10000, callbacks->GetBinContent (1 + UnitTestAlg1::CB_EXECUTE));
313  EXPECT_EQ (1, callbacks->GetBinContent (1 + UnitTestAlg1::CB_FILE_EXECUTE));
314  EXPECT_LE (1, callbacks->GetBinContent (1 + UnitTestAlg1::CB_FINALIZE));
315  EXPECT_LE (1, callbacks->GetBinContent (1 + UnitTestAlg1::CB_HIST_FINALIZE));
316  }
317 
318 
319 
320  TEST_P (UnitTestFixture, single_fileExecuted)
321  {
322  checkFileExecuted ("single");
323  }
324 
325 
326 
327  TEST_P (UnitTestFixture, multi_eventCount)
328  {
329  EXPECT_EQ (eventCount ("multi"), 100000u);
330  }
331 
332 
333 
334  TEST_P (UnitTestFixture, multi_callbacks)
335  {
336  TH1 *callbacks = getCallbacks ("multi");
337  EXPECT_LE (1, callbacks->GetBinContent (1 + UnitTestAlg1::CB_CHANGE_INPUT_FIRST));
338  EXPECT_LE (0, callbacks->GetBinContent (1 + UnitTestAlg1::CB_CHANGE_INPUT_OTHER));
339  EXPECT_LE (1, callbacks->GetBinContent (1 + UnitTestAlg1::CB_INITIALIZE));
340  EXPECT_LE (1, callbacks->GetBinContent (1 + UnitTestAlg1::CB_HIST_INITIALIZE));
341  EXPECT_EQ (100000, callbacks->GetBinContent (1 + UnitTestAlg1::CB_EXECUTE));
342  EXPECT_EQ (10, callbacks->GetBinContent (1 + UnitTestAlg1::CB_FILE_EXECUTE));
343  EXPECT_LE (1, callbacks->GetBinContent (1 + UnitTestAlg1::CB_FINALIZE));
344  EXPECT_LE (1, callbacks->GetBinContent (1 + UnitTestAlg1::CB_HIST_FINALIZE));
345  }
346 
347 
348 
349  TEST_P (UnitTestFixture, multi_fileExecuted)
350  {
351  checkFileExecuted ("multi");
352  }
353 
354 
355 
356  TEST_P (UnitTestFixture, multi_out_empty)
357  {
359  sh.load (getJob() + "/output-out_empty");
360  SH::Sample *sample = sh.get ("multi");
361  ASSERT_TRUE (sample != nullptr);
362 
363  for (auto fileName : sample->makeFileList())
364  {
365  std::unique_ptr<TFile> file (TFile::Open (fileName.c_str(), "READ"));
366  }
367  }
368 }
EL::UnitTestAlg1::CB_CHANGE_INPUT_OTHER
@ CB_CHANGE_INPUT_OTHER
Definition: UnitTestAlg1.h:63
beamspotnt.var
var
Definition: bin/beamspotnt.py:1394
SGout2dot.alg
alg
Definition: SGout2dot.py:243
get_generator_info.result
result
Definition: get_generator_info.py:21
Driver.h
checkxAOD.fileNames
fileNames
Definition: Tools/PyUtils/bin/checkxAOD.py:74
index
Definition: index.py:1
EL::UnitTestAlg1::CB_EXECUTE
@ CB_EXECUTE
Definition: UnitTestAlg1.h:66
plotmaker.hist
hist
Definition: plotmaker.py:148
tree
TChain * tree
Definition: tile_monitor.h:30
SampleHandler.h
vec
std::vector< size_t > vec
Definition: CombinationsGeneratorTest.cxx:12
EL::AnaAlgorithmConfig
an object that can create a AnaAlgorithm
Definition: AnaAlgorithmConfig.h:29
Assert.h
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:77
submit
Definition: submit.py:1
FullCPAlgorithmsTest_eljob.driver
driver
Definition: FullCPAlgorithmsTest_eljob.py:175
EL::UnitTestFixture::getJob
std::string getJob()
Definition: UnitTestFixture.cxx:139
config
Definition: PhysicsAnalysis/AnalysisCommon/AssociationUtils/python/config.py:1
ANA_CHECK_THROW
#define ANA_CHECK_THROW(EXP)
check whether the given expression was successful, throwing an exception on failure
Definition: Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h:339
SamplePtr.h
PlotCalibFromCool.nentries
nentries
Definition: PlotCalibFromCool.py:798
SampleLocal.h
EL::UnitTestFixture::m_jobs
static std::map< std::shared_ptr< Driver >, std::string > m_jobs
Definition: UnitTestFixture.h:47
FortranAlgorithmOptions.fileName
fileName
Definition: FortranAlgorithmOptions.py:13
FullCPAlgorithmsTest_eljob.sh
sh
Definition: FullCPAlgorithmsTest_eljob.py:114
FullCPAlgorithmsTest_eljob.sample
sample
Definition: FullCPAlgorithmsTest_eljob.py:116
RCU::Shell
Definition: ShellExec.cxx:28
ANA_MSG_INFO
#define ANA_MSG_INFO(xmsg)
Macro printing info messages.
Definition: Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h:290
DiskWriter.h
MessageCheck.h
macros for messaging and checking status codes
file
TFile * file
Definition: tile_monitor.h:29
EL::UnitTestFixture::getSH
SH::SampleHandler getSH()
Definition: UnitTestFixture.cxx:126
dumpFileToPlots.treeName
string treeName
Definition: dumpFileToPlots.py:20
EL
This module defines the arguments passed from the BATCH driver to the BATCH worker.
Definition: AlgorithmWorkerData.h:24
EL::UnitTestAlg1::CB_HIST_INITIALIZE
@ CB_HIST_INITIALIZE
Definition: UnitTestAlg1.h:65
SH::MetaFields::treeName
static const std::string treeName
the name of the tree in the sample
Definition: MetaFields.h:52
EL::UnitTestFixture::getTObject
TObject * getTObject(const std::string &sampleName, const std::string &objectName, bool isMandatory)
Definition: UnitTestFixture.cxx:176
SH::Sample
a base class that manages a set of files belonging to a particular data set and the associated meta-d...
Definition: Sample.h:54
EL::UnitTestAlg1::CB_FINALIZE
@ CB_FINALIZE
Definition: UnitTestAlg1.h:68
GetAllXsec.entry
list entry
Definition: GetAllXsec.py:132
EL::UnitTestFixture::makeFile
std::string makeFile(const std::vector< unsigned > &entries)
Definition: UnitTestFixture.cxx:241
EL::UnitTestAlg1
Definition: UnitTestAlg1.h:34
MetaFields.h
ThrowMsg.h
SH::SamplePtr
A smart pointer class that holds a single Sample object.
Definition: SamplePtr.h:35
UnitTestConfig.h
EL::UnitTestAlg1::CB_CHANGE_INPUT_FIRST
@ CB_CHANGE_INPUT_FIRST
Definition: UnitTestAlg1.h:62
UnitTestFixture.h
EL::UnitTestAlg1::CB_INITIALIZE
@ CB_INITIALIZE
Definition: UnitTestAlg1.h:64
RTTAlgmain.branch
branch
Definition: RTTAlgmain.py:61
EL::UnitTestFixture::checkFileExecuted
void checkFileExecuted(const std::string &sampleName)
Definition: UnitTestFixture.cxx:211
EL::TEST_P
TEST_P(UnitTestFixture, empty_eventCount)
Definition: UnitTestFixture.cxx:269
config
std::vector< std::string > config
Definition: fbtTestBasics.cxx:74
SH::SampleLocal
A Sample based on a simple file list.
Definition: SampleLocal.h:38
entries
double entries
Definition: listroot.cxx:49
EL::UnitTestFixture::getCallbacks
TH1 * getCallbacks(const std::string &sampleName)
Definition: UnitTestFixture.cxx:203
EL::UnitTestAlg1::CB_FILE_EXECUTE
@ CB_FILE_EXECUTE
Definition: UnitTestAlg1.h:67
pickleTool.object
object
Definition: pickleTool.py:30
SH::SampleHandler
A class that manages a list of Sample objects.
Definition: SampleHandler.h:60
RCU_THROW_MSG
#define RCU_THROW_MSG(message)
Definition: PrintMsg.h:58
SH::SampleLocal::add
void add(const std::string &file)
add a file to the list
EL::Job
Definition: Job.h:51
test_interactive_athena.job
job
Definition: test_interactive_athena.py:6
EL::UnitTestFixture::eventCount
unsigned eventCount(const std::string &sampleName)
Definition: UnitTestFixture.cxx:194
EL::UnitTestAlg1::CB_HIST_FINALIZE
@ CB_HIST_FINALIZE
Definition: UnitTestAlg1.h:69
UnitTestAlg1.h
Trk::split
@ split
Definition: LayerMaterialProperties.h:38
EL::UnitTestFixture
Definition: UnitTestFixture.h:23
EL::UnitTestFixture::getSample
SH::SamplePtr getSample(const std::string &sameName)
Definition: UnitTestFixture.cxx:76
AnaAlgorithmConfig.h