Darwin  1.0
Event loop based prototype framework
Options.cc File Reference
#include <optional>
#include <boost/test/included/unit_test.hpp>
#include <boost/exception/all.hpp>
#include "darwin.h"
#include "test.h"
#include "Options.h"
#include <TFile.h>
+ Include dependency graph for Options.cc:

Macros

#define BOOST_TEST_MODULE   testOptions
 
#define DARWIN_EXAMPLE   DARWIN "/test/example.info"
 

Functions

 BOOST_AUTO_TEST_CASE (test_default)
 
 BOOST_AUTO_TEST_CASE (test_example_config)
 
 BOOST_AUTO_TEST_CASE (test_splitting)
 
 BOOST_AUTO_TEST_CASE (test_parse_env_var)
 
 BOOST_AUTO_TEST_CASE (test_config)
 
 BOOST_AUTO_TEST_CASE (test_args)
 
 BOOST_AUTO_TEST_CASE (test_stages)
 
 BOOST_AUTO_TEST_CASE (multiple_inputs)
 

Macro Definition Documentation

◆ BOOST_TEST_MODULE

#define BOOST_TEST_MODULE   testOptions

◆ DARWIN_EXAMPLE

#define DARWIN_EXAMPLE   DARWIN "/test/example.info"

Function Documentation

◆ BOOST_AUTO_TEST_CASE() [1/8]

BOOST_AUTO_TEST_CASE ( multiple_inputs  )
199  {
200  for (int i = 0; i < 3; ++i)
201  TFile::Open(Form("input%d.root", i), "RECREATE")->Close();
202 
203  {
204  Options options("Test");
205  vector<fs::path> inputs;
206  BOOST_REQUIRE_NO_THROW( options.inputs("inputs", &inputs, "input ROOT files") );
207 
208  system("ls input*.root");
209  auto const args = tokenize("exec input*.root");
210  BOOST_REQUIRE_NO_THROW( options(args.size(), args.data()) );
211  BOOST_TEST( inputs.size() == 3ul );
212  for (auto const& input: inputs)
213  cout << input << ' ';
214  cout << endl;
215  }
216 
217  {
218  Options options("Test");
219  vector<fs::path> inputs;
220  fs::path output;
221  BOOST_REQUIRE_NO_THROW( options.inputs("inputs", &inputs, "input ROOT files") );
222  options.output("output", &output, "output ROOT file");
223 
224  auto const args = tokenize("exec input*.root output.root");
225  BOOST_REQUIRE_NO_THROW( options(args.size(), args.data()) );
226  BOOST_TEST( inputs.size() == 3ul );
227  for (auto const& input: inputs)
228  cout << input << ' ';
229  cout << endl;
230  BOOST_TEST( output == "output.root" );
231  }
232 
233  for (int i = 0; i < 3; ++i)
234  fs::remove(Form("input%d.root", i));
235  fs::remove("output.root");
236 
237  {
238  Options options("Test");
239  vector<fs::path> inputs;
240  options.inputs("inputs", &inputs, "input ROOT files");
241  auto const args = tokenize("exec input*.root"); // no such file exists
242  BOOST_REQUIRE_THROW( options(args.size(), args.data()), boost::wrapexcept<fs::filesystem_error> );
243  }
244  }

◆ BOOST_AUTO_TEST_CASE() [2/8]

BOOST_AUTO_TEST_CASE ( test_args  )
173  {
174  Options options("Test");
175 
176  TFile::Open("input.root", "RECREATE")->Close();
177 
178  fs::path input, output;
179  options.input("input", &input, "input")
180  .args("labels", "labels", "labels");
181  BOOST_REQUIRE_THROW( options.output("output", &output, "output"), runtime_error );
182 
183  fs::remove("input.root");
184  }

◆ BOOST_AUTO_TEST_CASE() [3/8]

BOOST_AUTO_TEST_CASE ( test_config  )
133  {
134  BOOST_REQUIRE_NO_THROW( Options("Test", config) );
135  Options options("Test", config);
136 
137  TFile::Open("input.root", "RECREATE")->Close();
138 
139  fs::path input, output;
140  BOOST_REQUIRE_NO_THROW( options.input("input", &input, "input ROOT file") );
141  BOOST_REQUIRE_NO_THROW( options.output("output", &output, "output ROOT file") );
142 
143  // testing normal commands
144  auto const args = tokenize("exec input.root output.root -c " DARWIN_EXAMPLE);
145  BOOST_TEST_REQUIRE( Options::parse_env_var("${DARWIN_TABLES}") ); // is used in `example.info`
146  BOOST_REQUIRE_NO_THROW( options(args.size(), args.data()) );
147  auto const& config = options(args.size(), args.data());
148  BOOST_TEST( !config.empty() );
149  for (auto it: config)
150  cout << it.first << endl;
151  BOOST_TEST( config.count("flags") );
152  BOOST_TEST( config.count("corrections") );
153 
154  auto const flags = config.get_child("flags");
155  BOOST_TEST( flags.count("isMC") );
156  BOOST_TEST( flags.count("year") );
157  BOOST_TEST( flags.count("R") );
158 
159  auto const corrections = config.get_child("corrections");
160  BOOST_TEST( corrections.count("METfilters") );
161  BOOST_TEST( corrections.count("hotzones") );
162  BOOST_TEST( corrections.count("lumi") );
163  BOOST_TEST( corrections.count("xsecs") );
164  BOOST_TEST( corrections.count("JES") );
165  BOOST_TEST( corrections.count("triggers") );
166  BOOST_TEST( corrections.count("PUstaub") );
167 
168  fs::remove("input.root");
169  fs::remove("output.root");
170  }

◆ BOOST_AUTO_TEST_CASE() [4/8]

BOOST_AUTO_TEST_CASE ( test_default  )
29  {
30  BOOST_REQUIRE_NO_THROW( Options("Test") );
31 
32  Options options("Test"); // no config, no splitting by default
33  BOOST_TEST( options.full_cmd.empty() );
34 
35  // check that we have a commit SHA
36  BOOST_TEST( options.commit().size() == 40 );
37 
38  TFile::Open("input.root", "RECREATE")->Close();
39 
40  fs::path input, output;
41  BOOST_REQUIRE_NO_THROW( options.input("input", &input, "input ROOT file") );
42  BOOST_REQUIRE_NO_THROW( options.output("output", &output, "output ROOT file") );
43 
44  {
45  // testing normal commands
46  auto const args = tokenize("exec input.root output.root --unknown");
47  BOOST_REQUIRE_THROW( options(args.size(), args.data()), boost::wrapexcept<po::error> );
48  }
49 
50  {
51  // testing normal commands
52  auto const args = tokenize("exec input.root output.root");
53  BOOST_REQUIRE_NO_THROW( options(args.size(), args.data()) );
54  BOOST_TEST( input == "input.root" );
55  BOOST_TEST( output == "output.root" );
56  cout << options.full_cmd << endl;
57  BOOST_TEST( !options.full_cmd.empty() );
58  }
59 
60  fs::remove("output.root");
61 
62  {
63  // testing bad input
64  auto const args = tokenize("exec inpu.root output.root");
65  BOOST_REQUIRE_THROW( options(args.size(),args.data()), boost::wrapexcept<fs::filesystem_error> );
66  }
67 
68  {
69  // testing bad output
70  auto const args = tokenize("exec input.root .");
71  BOOST_REQUIRE_THROW( options(args.size(),args.data()), boost::wrapexcept<fs::filesystem_error> );
72  }
73 
74  {
75  // testing non-readable input
76  fs::permissions("input.root", fs::perms::owner_read, fs::perm_options::remove);
77  auto const args = tokenize("exec input.root output.root");
78  BOOST_REQUIRE_THROW( options(args.size(),args.data()), boost::wrapexcept<fs::filesystem_error> );
79  fs::permissions("input.root", fs::perms::owner_read, fs::perm_options::add);
80  }
81 
82  TFile::Open("output.root", "RECREATE")->Close();
83 
84  {
85  // testing non-writable output
86  fs::permissions("output.root", fs::perms::owner_write, fs::perm_options::remove);
87  auto const args = tokenize("exec input.root output.root");
88  BOOST_REQUIRE_THROW( options(args.size(),args.data()), boost::wrapexcept<fs::filesystem_error> );
89  fs::permissions("output.root", fs::perms::owner_write, fs::perm_options::add);
90  }
91 
92  fs::remove("input.root");
93  fs::remove("output.root");
94  }

◆ BOOST_AUTO_TEST_CASE() [5/8]

BOOST_AUTO_TEST_CASE ( test_example_config  )
97  {
98  Options options("Test", config);
99  options.arg<fs::path>("blah", "foo.bar", "this must fail bc this path does not exist in the example config");
100  auto const args = tokenize("exec -e");
101  BOOST_REQUIRE_THROW( options(args.size(), args.data()), boost::wrapexcept<pt::ptree_bad_path> );
102  }

◆ BOOST_AUTO_TEST_CASE() [6/8]

BOOST_AUTO_TEST_CASE ( test_parse_env_var  )
127  {
128  BOOST_REQUIRE_NO_THROW( Options::parse_env_var("${HOME}") );
129  BOOST_REQUIRE_THROW( Options::parse_env_var("${THISVARDOESNOTEXIST}"), boost::wrapexcept<std::runtime_error> );
130  }

◆ BOOST_AUTO_TEST_CASE() [7/8]

BOOST_AUTO_TEST_CASE ( test_splitting  )
105  {
106  BOOST_REQUIRE_NO_THROW( Options("Test", split) );
107  Options options("Test", split);
108 
109  TFile::Open("input.root", "RECREATE")->Close();
110 
111  fs::path input, output;
112  BOOST_REQUIRE_NO_THROW( options.input("input", &input, "input ROOT file") );
113  BOOST_REQUIRE_NO_THROW( options.output("output", &output, "output ROOT file") );
114 
115  // testing normal commands
116  auto const args = tokenize("exec input.root output.root -j 42 -k 24");
117  BOOST_REQUIRE_NO_THROW( options(args.size(), args.data()) );
118  auto const slice = options.slice();
119  BOOST_TEST( slice.first == 42u );
120  BOOST_TEST( slice.second == 24u );
121 
122  fs::remove("input.root");
123  fs::remove("output.root");
124  }

◆ BOOST_AUTO_TEST_CASE() [8/8]

BOOST_AUTO_TEST_CASE ( test_stages  )
187  {
188  Options options("Test");
189 
190  TFile::Open("input.root", "RECREATE")->Close();
191  fs::path output, input;
192  options.output("output", &output, "output");
193  BOOST_REQUIRE_NO_THROW( options.arg<int>("R", "R", "R") );
194  BOOST_REQUIRE_THROW( options.input("input", &input, "input"), runtime_error );
195  fs::remove("input.root");
196  }
Darwin::Tools::Options
Common class to interpret the command line, based on Boost Program Options.
Definition: Options.h:56
DARWIN_EXAMPLE
#define DARWIN_EXAMPLE
Definition: Options.cc:16
Darwin::Tools::split
@ split
activate -k and -j to define slice
Definition: Options.h:26
Darwin::Tools::config
@ config
activate -c option to provide config file
Definition: Options.h:25
Darwin::Tools::tokenize
std::vector< const char * > tokenize(const char *str)
Definition: test.h:15