unit_test_base.h
Go to the documentation of this file.
1 /**
2  * @file unit_test_base.h
3  * @brief Base class for unit tests using FHiCL configuration
4  * @date December 1st, 2015
5  * @author petrillo@fnal.gov
6  *
7  * Provides an environment for easy set up of a message-facility-aware test.
8  *
9  * For an example of how to expand it to host services,
10  * see larcore/test/Geometry/geometry_unit_test_base.h
11  *
12  * Currently provides:
13  * - BasicEnvironmentConfiguration: a test environment configuration
14  * - TestSharedGlobalResource: mostly internal use
15  * - TesterEnvironment: a prepacked test environment with some provider support
16  *
17  * This is a pure template header. It will require the following libraries:
18  *
19  * * `MF_MessageLogger`
20  * * `fhiclcpp`
21  * * `cetlib`
22  *
23  */
24 
25 
26 #ifndef TEST_UNIT_TEST_BASE_H
27 #define TEST_UNIT_TEST_BASE_H
28 
29 // LArSoft libraries
33 
34 // utility libraries
35 #include "fhiclcpp/ParameterSet.h"
37 #include "fhiclcpp/parse.h"
38 #include "fhiclcpp/types/Comment.h"
39 #include "fhiclcpp/types/Name.h"
40 #include "fhiclcpp/types/Atom.h"
41 #include "fhiclcpp/types/Table.h"
42 // #include "fhiclcpp/exception.h"
44 
45 // CET libraries
46 #include "cetlib/filesystem.h" // cet::is_absolute_filepath()
47 #include "cetlib/filepath_maker.h"
48 #include "cetlib/search_path.h"
49 
50 // C/C++ standard libraries
51 #include <iostream> // for output before message facility is set up
52 #include <string>
53 #include <memory> // std::unique_ptr<>
54 #include <utility> // std::move(), std::forward()
55 #include <map>
56 #include <type_traits> // std::add_rvalue_reference()
57 #include <stdexcept> // std::logic_error
58 
59 
60 namespace testing {
61 
62  namespace details {
63 
64  /// Reads and makes available the command line parameters
65  class CommandLineArguments {
66  public:
67  /// Constructor: automatically parses from Boost arguments
69 
70  /// Constructor: parses from specified arguments
71  CommandLineArguments(int argc, char** argv)
72  { ParseArguments(argc, argv); }
73 
74  /// Parses arguments
75  void ParseArguments(int argc, char** argv);
76 
77  /// Returns the name of the executable as started
78  std::string Executable() const { return exec_name; }
79 
80  /// Returns the list of non-Boost-test arguments on the command line
81  std::vector<std::string> const& Arguments() const { return args; }
82 
83  /// Returns whether we have arguments up to the iArg-th (0-based)
84  bool hasArgument(size_t iArg) const { return iArg < args.size(); }
85 
86  /// Returns the value of the iArg-th (0-based; no range check!)
87  std::string const& Argument(size_t iArg) const { return args[iArg]; }
88 
89  private:
90  std::string exec_name; ///< name of the test executable (from argv[0])
91  std::vector<std::string> args; ///< command line arguments (from argv[0])
92 
93  /// Erases the stored arguments
94  void Clear() { exec_name.clear(); args.clear(); }
95 
96  }; // class CommandLineArguments
97 
98 
99  inline void CommandLineArguments::ParseArguments(int argc, char** argv) {
100  Clear();
101  if (argc == 0) return;
102 
103  exec_name = argv[0];
104 
105  args.resize(argc - 1);
106  std::copy(argv + 1, argv + argc, args.begin());
107 
108  } // CommandLineArguments:ParseArguments()
109 
110 
111  // forward declaration
112  template
113  <typename TestEnv, typename Pack, typename... Provs>
114  struct ProviderPackFiller;
115 
116  } // namespace details
117 
118 
119  /** **************************************************************************
120  * @brief Class holding a configuration for a test environment
121  *
122  * This class needs to be fully constructed by the default constructor
123  * in order to be useful as Boost unit test fixture.
124  * It is supposed to be passed as a template parameter to another class
125  * that can store an instance of it and extract configuration information
126  * from it.
127  */
129 
130  /// Default constructor; this is what is used in Boost unit test
131  BasicEnvironmentConfiguration() { DefaultInit(); }
132 
133  /// Constructor: acquires parameters from the command line
136  { ParseCommandLine(argc, argv); }
137 
138  /// Constructor; accepts the name as parameter
141  { SetApplicationName(name); }
142 
145  { SetApplicationName(name); }
146 
147  /// @{
148  /// @name Access to configuration
149  /// Name of the application
150  std::string ApplicationName() const { return appl_name; }
151 
152  /// Path to the configuration file
153  std::string ConfigurationPath() const { return config_path; }
154 
155  /// FHiCL path for the configuration of the test algorithm
157  {
158  auto iPath = test_paths.find(name);
159  return (iPath == test_paths.end())
160  ? ("physics.analyzers." + name): iPath->second;
161  }
162 
163  /// Name of the test algorithm instance
164  std::string MainTesterParameterSetName() const { return main_test_name; }
165 
166  /// FHiCL path for the configuration of the test algorithm
168  {
169  return MainTesterParameterSetName().empty()
170  ? "": TesterParameterSetPath(MainTesterParameterSetName());
171  }
172 
173  /// FHiCL path for the configuration of the service
175  {
176  auto iPath = service_paths.find(name);
177  return (iPath == service_paths.end())
178  ? ("services." + name): iPath->second;
179  } // ServiceParameterSetPath()
180 
181  /// A string describing default parameter set to configure specified test
183  { return analyzers_default_cfg.at(tester_name); }
184 
185  /// A string describing the default parameter set to configure the test
187  { return services_default_cfg.at(service_name); }
188 
189  /// A string describing the full default parameter set
191  { return BuildDefaultConfiguration(); }
192 
193  /// Returns the name of the executable as started
194  std::string ExecutablePath() const { return arguments.Executable(); }
195 
196  /// Returns the list of non-Boost-test arguments on the command line
197  std::vector<std::string> const& EexcutableArguments() const
198  { return arguments.Arguments(); }
199 
200  ///@}
201 
202 
203  /// @{
204  /// @name Set configuration
205 
206  /// Sets the name of the application
207  void SetApplicationName(std::string name) { appl_name = name; }
208 
209  /// Sets the path to the configuration file
210  void SetConfigurationPath(std::string path) { config_path = path; }
211 
212  /// Sets the FHiCL name for the configuration of the test algorithm
214  { main_test_name = name; }
215 
216  /// Sets the FHiCL path for the configuration of a test algorithm
218  { test_paths[test_name] = path; }
219 
220  /// Sets the FHiCL path for the configuration of the main test algorithm
222  {
223  if (MainTesterParameterSetName().empty()) {
224  throw std::logic_error
225  ("Request setting configuration of non-existent main tester");
226  }
227  SetTesterParameterSetPath(MainTesterParameterSetName(), path);
228  }
229 
230  /// Sets the FHiCL path for the configuration of a test algorithm
232  { service_paths[service_name] = path; }
233 
234  /// Adds a default configuration for the specified service
235  void AddDefaultServiceConfiguration
236  (std::string service_name, std::string service_cfg)
237  { services_default_cfg[service_name] = service_cfg; }
238 
239  /// Adds a default configuration for the specified tester
240  void AddDefaultTesterConfiguration
241  (std::string tester_name, std::string tester_cfg)
242  { analyzers_default_cfg[tester_name] = tester_cfg; }
243 
244  /// Adds a default configuration for the main tester
246  {
247  if (MainTesterParameterSetName().empty()) {
248  throw std::logic_error
249  ("Request adding configuration of non-existent main tester");
250  }
251  AddDefaultTesterConfiguration(MainTesterParameterSetName(), tester_cfg);
252  }
253 
254  ///@}
255 
256 
257 
258  protected:
259  using ConfigurationMap_t = std::map<std::string, std::string>;
260  using PathMap_t = std::map<std::string, std::string>;
261 
262  std::string appl_name; ///< name of the application
263  std::string config_path; ///< configuration file path
264  std::string main_test_name; ///< name of main test algorithm
265  std::string main_test_path; ///< path of main test algorithm configuration
266 
267  /// Returns the default test name
268  static std::string DefaultApplicationName() { return "Test"; }
269 
270  /// Configuration of all the services
271  ConfigurationMap_t services_default_cfg;
272  /// Configuration of all the analyzer modules
273  ConfigurationMap_t analyzers_default_cfg;
274 
275  /// Set of paths for tester configuration
276  PathMap_t test_paths;
277  /// Set of paths for service configuration
278  PathMap_t service_paths;
279 
280  /// Extracts arguments from the command line, uses first one as config path
281  void ParseCommandLine(int argc, char** argv)
282  {
283  arguments.ParseArguments(argc, argv);
284  if (arguments.hasArgument(0))
285  SetConfigurationPath(arguments.Argument(0)); // first argument
286  }
287 
288  /// Initialize with some default values
289  void DefaultInit()
290  {
291  SetApplicationName(DefaultApplicationName());
292  SetMainTesterParameterSetName("");
293  // a destination which will react to all messages from DEBUG up:
294  AddDefaultServiceConfiguration("message",
295  R"(
296  debugModules: [ '*' ]
297  destinations : {
298  stdout: {
299  type: cout
300  threshold: DEBUG
301  categories: {
302  default: {
303  limit: -1
304  }
305  } // categories
306  } // stdout
307  statistics: {type:cout}
308  } // destinations
309  )");
310  } // DefaultInit()
311 
312  /// A string describing the full default parameter set
314  { return BuildServiceConfiguration(services_default_cfg); }
315 
316  /// A string describing the full default parameter set
318  { return BuildTestConfiguration(analyzers_default_cfg); }
319 
320  /// A string describing the full default parameter set
322  {
323  return BuildConfiguration(services_default_cfg, analyzers_default_cfg);
324  }
325 
326 
327  /// A string with the service section from service parameter sets
328  static std::string BuildServiceConfiguration
329  (ConfigurationMap_t const& services)
330  {
331  std::string cfg;
332  cfg += "\nservices: {";
333  for (auto const& service_info: services) {
334  cfg += "\n " + service_info.first + ": {";
335  cfg += "\n" + service_info.second;
336  cfg += "\n } # " + service_info.first;
337  } // for services
338  cfg +=
339  "\n} # services"
340  "\n";
341  return cfg;
342  } // BuildServiceConfiguration()
343 
344  /// A string with the physics section from analyzer parameter sets
345  static std::string BuildTestConfiguration
346  (ConfigurationMap_t const& analyzers)
347  {
348  std::string cfg;
349  cfg +=
350  "\nphysics: {"
351  "\n analyzers: {"
352  ;
353  for (auto const& module_info: analyzers) {
354  cfg += "\n " + module_info.first + ": {";
355  cfg += "\n" + module_info.second;
356  cfg += "\n } # " + module_info.first;
357  } // for analyzers
358  cfg +=
359  "\n } # analyzers"
360  "\n} # physics";
361  return cfg;
362  } // BuildServiceConfiguration()
363 
364  /// A string describing the full default parameter set
365  static std::string BuildConfiguration
366  (ConfigurationMap_t const& services, ConfigurationMap_t const& modules)
367  {
368  std::string cfg;
369  cfg += BuildServiceConfiguration(services);
370  cfg += BuildTestConfiguration(modules);
371  return cfg;
372  } // BuildConfiguration()
373 
374  private:
375  details::CommandLineArguments arguments; ///< command line arguments
376 
377  }; // class BasicEnvironmentConfiguration<>
378 
379 
380 
381  /** **************************************************************************
382  * @brief Utility class providing singleton objects to the derived classes
383  * @tparam RES the type of object (include constantness if needed)
384  *
385  * The object is expected to be shared.
386  */
387  template <typename RES>
389  using Resource_t = RES;
390 
391  public:
392  using ResourcePtr_t = std::shared_ptr<Resource_t>;
393 
394  /// @name Add and share resources
395  /// @{
396 
397  /// Adds a shared resource to the resource registry
398  static void AddSharedResource(std::string res_name, ResourcePtr_t res_ptr)
399  { Resources[res_name] = res_ptr; }
400 
401  /// Adds a shared resource to the resource registry (empty name)
403  { AddSharedResource(std::string(), res_ptr); }
404 
405  /// Registers a shared resource only if none exists yet
406  template <typename... Args>
407  static ResourcePtr_t ProvideSharedResource
408  (std::string res_name, ResourcePtr_t res_ptr)
409  {
410  if (hasResource(res_name)) return ResourcePtr_t();
411  AddSharedResource(res_name, res_ptr);
412  return res_ptr;
413  }
414 
415  /// Creates a shared resource as default only if none exists yet
416  template <typename... Args>
418  { return ProvideSharedResource(std::string(), res_ptr); }
419 
420  //@{
421  /// Adds a shared resource only if it is old_res_ptr
423  std::string res_name,
424  Resource_t const* old_res_ptr, ResourcePtr_t res_ptr
425  )
426  {
427  ResourcePtr_t current_res_ptr = ShareResource();
428  if (current_res_ptr.get() != old_res_ptr) return false;
429  AddSharedResource(res_name, res_ptr);
430  return true;
431  }
432  static bool ReplaceSharedResource
433  (std::string res_name, ResourcePtr_t old_res_ptr, ResourcePtr_t res_ptr)
434  { return ReplaceSharedResource(res_name, old_res_ptr.get(), res_ptr); }
435  //@}
436 
437  //@{
438  /// Adds a shared resource as default resource only if it is old_res_ptr
439  static bool ReplaceDefaultSharedResource
440  (Resource_t const* old_res_ptr, ResourcePtr_t res_ptr)
441  { return ReplaceSharedResource(std::string(), old_res_ptr, res_ptr); }
442  static bool ReplaceDefaultSharedResource
443  (ResourcePtr_t old_res_ptr, ResourcePtr_t res_ptr)
444  { return ReplaceSharedResource(std::string(), old_res_ptr, res_ptr); }
445  //@}
446 
447  /// Constructs and registers a new resource with a specified name
448  template <typename... Args>
449  static ResourcePtr_t CreateResource(std::string res_name, Args&&... args)
450  {
451  ResourcePtr_t res_ptr(new Resource_t(std::forward<Args>(args)...));
452  AddSharedResource(res_name, res_ptr);
453  return res_ptr;
454  }
455 
456  /// Constructs and registers a new resource with no name
457  template <typename... Args>
458  static void CreateDefaultResource(Args&&... args)
459  { CreateResource(std::string(), std::forward<Args>(args)...); }
460 
461 
462  /// Creates a shared resource only if none exists yet
463  template <typename... Args>
464  static ResourcePtr_t ProposeSharedResource
465  (std::string res_name, Args&&... args)
466  {
467  return hasResource(res_name)?
468  ResourcePtr_t():
469  CreateResource(res_name, std::forward<Args>(args)...);
470  }
471 
472  /// Creates a shared resource as default only if none exists yet
473  template <typename... Args>
475  {
476  return ProposeSharedResource
477  (std::string(), std::forward<Args>(args)...);
478  }
479 
480  /// @}
481 
482  /// @name Resource access
483  /// @{
484 
485  /// Returns whether a resource exists
486  /// @throws std::out_of_range if not available
487  static bool hasResource(std::string name = "")
488  {
489  auto iRes = Resources.find(name);
490  return (iRes != Resources.end()) && bool(iRes->second);
491  }
492 
493  /// Retrieves the specified resource for sharing (nullptr if none)
495  {
496  auto iRes = Resources.find(name);
497  return (iRes == Resources.end())? ResourcePtr_t(): iRes->second;
498  }
499 
500  /// Retrieves the specified resource, or throws if not available
502  { return *(Resources.at(name).get()); }
503 
504  /// @}
505 
506  /// Destroys the specified resource (does nothing if no such resource)
508  { Resources.erase(name); }
509 
510  private:
511  static std::map<std::string, ResourcePtr_t> Resources;
512 
513  }; // class TestSharedGlobalResource<>
514 
515 
516  template <typename RES>
517  std::map<std::string, typename TestSharedGlobalResource<RES>::ResourcePtr_t>
519 
520 
521  /** **************************************************************************
522  * @brief Environment for a test
523  * @tparam ConfigurationClass a class providing compile-time configuration
524  *
525  * The test environment is set up on construction.
526  *
527  * The environment provides:
528  * - Parameters() method returning the complete FHiCL configuration
529  * - TesterParameters() method returning the configuration for the test
530  *
531  * This class or a derived one can be used as global fixture for unit tests.
532  *
533  * Unfortunately Boost does not give any control on the initialization of the
534  * object, so everything must be ready to go as hard coded.
535  * The ConfigurationClass class tries to alleviate that.
536  * That is another, small static class that BasicTesterEnvironment uses to
537  * get its parameters.
538  *
539  * The requirements for the ConfigurationClass are:
540  * - `std::string ApplicationName()`: the application name
541  * - `std::string ConfigurationPath()`: path to the configuration file
542  * - `std::string MainTesterParameterSetName()`: name of the
543  * configuration of the main test (commodity)
544  * - `std::string DefaultTesterConfiguration()` returning a FHiCL string
545  * to be parsed to extract the default test configuration
546  *
547  * Whether the configuration comes from a file or from the two provided
548  * defaults, it is always expected within the parameter set paths:
549  * the default configuration must also contain that path.
550  *
551  * Note that there is no room for polymorphism here since the setup happens
552  * on construction.
553  * Some methods are declared virtual in order to allow to tweak some steps
554  * of the set up, but it's not trivial to create a derived class that works
555  * correctly: the derived class must declare a new default constructor,
556  * and that default constructor must call the protected constructor
557  * (BasicTesterEnvironment<ConfigurationClass>(no_setup))
558  */
559  template <typename ConfigurationClass>
560  class BasicTesterEnvironment {
561 
562  public:
563  using Configuration_t = ConfigurationClass;
564 
565  /**
566  * @brief Constructor: sets everything up and declares the test started
567  * @param bSetup (_default: `true`_) call `Setup()` after construction
568  *
569  * The configuration is from a default-constructed ConfigurationClass.
570  * This is suitable for use as Boost unit test fixture.
571  */
572  BasicTesterEnvironment(bool bSetup = true) { if (bSetup) Setup(); }
573 
574  //@{
575  /**
576  * @brief Setup from a configuration
577  * @param configurer an instance of `ConfigurationClass`
578  * @param bSetup (_default: `true`_) call `Setup()` after construction
579  *
580  * The configuration is from the specified configurer class.
581  *
582  * This constructor allows to use a non-default-constructed configuration.
583  * This can't be used (at best of my knowledge) when using this class as
584  * Boost unit test fixture.
585  *
586  * In the r-value-reference constructor, the configurer is moved.
587  */
589  (Configuration_t const& configurer, bool bSetup = true):
590  config(configurer)
591  { if (bSetup) Setup(); }
592  BasicTesterEnvironment(Configuration_t&& configurer, bool bSetup = true):
593  config(configurer)
594  { if (bSetup) Setup(); }
595  //@}
596 
597  /// Destructor: closing remarks
598  virtual ~BasicTesterEnvironment();
599 
600 
601  /// @{
602  /// @name Configuration retrieval
603 
604  /// Returns the full configuration
605  fhicl::ParameterSet const& Parameters() const { return params; }
606 
607  /// Returns the configuration of the specified service
609  {
610  return params.get<fhicl::ParameterSet>
611  (config.ServiceParameterSetPath(service_name));
612  }
613 
614  /// Returns the configuration of the specified test
616  {
617  return params.get<fhicl::ParameterSet>
618  (config.TesterParameterSetPath(test_name));
619  }
620 
621  /// Returns the configuration of the main test (undefined if no main test)
623  {
624  if (config.MainTesterParameterSetName().empty()) return {};
625  else return TesterParameters(config.MainTesterParameterSetName());
626  }
627 
628  /// @}
629 
630  static fhicl::ParameterSet CompileParameterSet(std::string cfg);
631 
632  protected:
633 
634  /// Returns a read-only version of the configuration
635  Configuration_t const& Config() const { return config; }
636 
637  /// The complete initialization, ran at construction by default
638  virtual void Setup();
639 
640  /// Reads and translates the configuration
641  virtual void Configure();
642 
643  /**
644  * @brief Creates a full configuration for the test
645  * @return a parameters set with the complete configuration
646  */
648  { return CompileParameterSet(config.DefaultConfiguration()); }
649 
650  //@{
651  /// Sets up the message facility
652  virtual void SetupMessageFacility
653  (fhicl::ParameterSet const& pset, std::string appl_name = "") const;
654  virtual void SetupMessageFacility() const
655  { SetupMessageFacility(Parameters(), config.ApplicationName()); }
656  //@}
657 
658  /**
659  * @brief Fills the test configuration from file or from default
660  *
661  * If a FHiCL configuration file is specified, the configuration of the test
662  * is read from it according to the parameter set path of the test.
663  * Otherwise, it is parsed from the default one provided by the configurer.
664  */
665  /// Parses from file and returns a FHiCL data structure
666  static fhicl::ParameterSet ParseParameters(std::string config_path);
667 
668  private:
669  /// Test environment options
670  struct Options_t {
671  bool MessageLevels = false; ///< print message levels on screen
672  }; // Options_t
673 
674  Configuration_t config; ///< instance of the configurer
675  Options_t options; ///< options for the test environment
676 
677  /// Parses the configuration, looking for the test environment options
678  void ParseEnvironmentOptions();
679 
680  fhicl::ParameterSet params; ///< full configuration of the test
681 
682  }; // class BasicTesterEnvironment<>
683 
684 
685 
686  //****************************************************************************
687  /**
688  * @brief A test environment with some support for service providers
689  * @tparam ConfigurationClass a class providing compile-time configuration
690  *
691  * This test environment extends BasicTesterEnvironment with some basic
692  * support for service providers.
693  *
694  *
695  * Service provider support
696  * =========================
697  *
698  * This environment makes it available the method `Provider<Prov>()`, which
699  * returns a pointer to the provider of type Prov.
700  *
701  * All providers must be set up _after_ the test environment is constructed.
702  * The environment provides the following facilities:
703  *
704  * * SetupProvider() to set up a service provider with generic arguments
705  * * SetupProviderFromService() to set up a service provider with a parameter
706  * set extracted from the configuration
707  * * AcquireProvider() to register a service provider already available
708  * * DropProvider() to destroy an existing provider
709  *
710  * The set up methods support a `For` variant (e.g. `SetupProviderFor()`) to
711  * register the provider also under the type of its interface. For example,
712  * if `LArPropertiesStandard` is an implementation of `LArProperties`,
713  * the call:
714  *
715  * env.SetupProviderFor<LArProperties, LArPropertiesStandard>(pset);
716  *
717  * will set up a `LArPropertiesStandard` provider just like
718  *
719  * env.SetupProvider<LArPropertiesStandard>(pset);
720  *
721  * would, and it makes the provider available as `LArProperties` too, so that
722  * both calls:
723  *
724  * env.Provider<LArProperties>();
725  * env.Provider<LArPropertiesStandard>();
726  *
727  * are valid and return the same provider.
728  *
729  *
730  * Use as test fixture
731  * ====================
732  *
733  * The providers must be set up _after_ the test environment is constructed.
734  * This also means an additional complication for fixtures that require to
735  * be constructed in a final state, as it is the case for Boost unit test
736  * suite fixtures.
737  * In these cases, a class should publicly derive from TesterEnvironment, and
738  * the necessary setup should be added into the constructor of this derived
739  * class.
740  *
741  * Note that, as in the case of BasicTesterEnvironment, in this case there is
742  * no room for polymorphism here since the setup need to happen on
743  * construction.
744  */
745  template <typename ConfigurationClass>
746  class TesterEnvironment
747  : public BasicTesterEnvironment<ConfigurationClass>
748  {
751 
752  public:
753  // inherit constructors
754  using TesterEnvBase_t::TesterEnvBase_t;
755 
756  /**
757  * @brief Sets a service provider up by calling its testing::setupProvider()
758  * @tparam Prov type of provider
759  * @tparam Args type of arguments for the setup function
760  * @param args arguments for the setup function
761  * @return a pointer to the provider set up
762  * @throw runtime_error if the provider already exists
763  * @see SetupProviderFor(), AcquireProvider()
764  *
765  * A provider of type Prov is created, set up and recorded.
766  * Provider setup is delegated to `testing::setupProvider` function specific
767  * to the provider itself (that is, `testing::setupProvider<Prov>(args...)`)
768  * to which the setup arguments are forwarded.
769  * If the provider already exists, an exception is thrown.
770  */
771  template <typename Prov, typename... Args>
772  Prov* SetupProvider(Args&&... args)
773  {
774  if (!providers.setup<Prov>(std::forward<Args>(args)...))
775  throw std::runtime_error("Provider already exists!");
776  return providers.getPointer<Prov>();
777  }
778 
779  /**
780  * @brief Sets a service provider up by calling its testing::setupProvider()
781  * @tparam Prov type of provider
782  * @tparam Args type of arguments for the setup function
783  * @param name the service name (for configuration retrieval)
784  * @param args arguments for the setup function
785  * @return a pointer to the provider set up
786  * @see SetupProvider()
787  * @throw runtime_error if the provider already exists
788  *
789  * A provider of type Prov is created, set up and recorded.
790  * Provider setup is attempted by constructing the provider with a parameter
791  * set from the registered configuration of service with specified `name`.
792  */
793  template <typename Prov, typename... Args>
795  {
796  return SetupProvider<Prov>
797  (this->ServiceParameters(name, std::forward<Args>(args)...));
798  }
799 
800  /**
801  * @brief Acquires a service provider
802  * @tparam Prov type of provider
803  * @param prov the provider to be acquired
804  * @return a pointer to the provider
805  * @see SetupProvider()
806  * @throw runtime_error if the provider already exists
807  *
808  * This method registers and takes ownership of the specified provider.
809  * It is similar to SetupProvider() except that user is in charge of the
810  * preliminary creation and setup of the provider.
811  */
812  template <typename Prov>
813  Prov* AcquireProvider(std::unique_ptr<Prov>&& prov)
814  {
815  if (!providers.acquire(std::move(prov)))
816  throw std::runtime_error("Provider already exists!");
817  return providers.getPointer<Prov>();
818  }
819 
820  /**
821  * @brief Sets a provider up, recording it as implementation of Interface
822  * @tparam Interface type of provider interface being implemented
823  * @tparam Prov type of provider
824  * @tparam Args type of arguments for the setup function
825  * @param args arguments for the setup function
826  * @return a pointer to the provider set up
827  * @see SetupProvider()
828  *
829  * This method performs the same type of setup as SetupProvider().
830  * In addition, it registers the provider as an implementation of Interface.
831  * This means that the provider can be obtained not only with
832  * `provider<Prov>()`, which returns a pointer to the actual class Prov,
833  * but also as `provider<Interface>()`, which returns a pointer to the base
834  * class Interface.
835  */
836  template <typename Interface, typename Prov, typename... Args>
837  Prov* SetupProviderFor(Args&&... args)
838  {
839  auto prov = SetupProvider<Prov>(std::forward<Args>(args)...);
840  providers.set_alias<Prov, Interface>();
841  return prov;
842  }
843 
844  /**
845  * @brief Sets a provider up, recording it as implementation of Interface
846  * @tparam Interface type of provider interface being implemented
847  * @tparam Prov type of provider
848  * @tparam Args type of arguments for the setup function
849  * @param name the service name (for configuration retrieval)
850  * @param args arguments for the setup function
851  * @return a pointer to the provider set up
852  * @see SetupProviderFromService(), SetupProviderFor()
853  * @throw runtime_error if the provider already exists
854  *
855  * This method performs the same type of setup as
856  * SetupProviderFromService().
857  * In addition, it registers the provider as an implementation of Interface.
858  * This means that the provider can be obtained not only with
859  * `provider<Prov>()`, which returns a pointer to the actual class Prov,
860  * but also as `provider<Interface>()`, which returns a pointer to the base
861  * class Interface.
862  */
863  template <typename Interface, typename Prov, typename... Args>
865  {
866  auto* prov
867  = SetupProviderFromService<Prov>(name, std::forward<Args>(args)...);
868  providers.set_alias<Prov, Interface>();
869  return prov;
870  }
871 
872  /**
873  * @brief Acquires a service provider implementing an interface
874  * @tparam Prov type of provider
875  * @tparam Interface type provider alias
876  * @param prov the provider to be acquired
877  * @return a pointer to the provider
878  * @see SetupProviderFor(), AcquireProvider()
879  *
880  * This method registers and takes ownership of the specified provider,
881  * like AcquireProvider() does. It also registers the provider as an
882  * implementation of Interface class, as SetupProviderFor does.
883  * It is similar to SetupProvider() except that user is in charge of the
884  * preliminar creation and setup of the provider.
885  */
886  template <typename Interface, typename Prov>
887  Prov* AcquireProviderFor(std::unique_ptr<Prov>&& prov)
888  {
889  auto prov_ptr = providers.acquire(prov);
890  providers.set_alias<Prov, Interface>();
891  return prov_ptr;
892  }
893 
894  /**
895  * @brief Oversimplified provider setup
896  * @return a pointer to the provider
897  * @tparam Prov provider type
898  *
899  * This is a one-step setup of the specified provider.
900  *
901  * It is available only if Prov provider comes with an implementation of
902  * testing::SimpleEnvironmentSetupClass that explains how to set up an
903  * environment.
904  *
905  */
906  template <typename Prov>
907  Prov* SimpleProviderSetup() { return simpleEnvironmentSetup<Prov>(*this); }
908 
909  /**
910  * @brief Removes and destroys the specified provider
911  * @tparam Prov type of provider to be destroyed
912  * @throw runtime_error if the provider was not present
913  */
914  template <typename Prov>
916  {
917  if (!providers.erase<Prov>())
918  throw std::runtime_error("Provider not present!");
919  }
920 
921  /// Return the specified provider (throws if not available)
922  template <typename Prov>
923  Prov const* Provider() const
924  { return providers.getPointer<Prov>(); }
925 
926  /**
927  * @brief Fills the specified provider pack with providers
928  * @throw runtime_error and everything provider() method can throw
929  * @see Provider()
930  */
931  template <typename... Provs>
933  {
935  <TesterEnv_t, lar::ProviderPack<Provs...>, Provs...>
936  ::fill
937  (*this, pack);
938  } // FillProviderPack()
939 
940 
941  /**
942  * @brief Returns a provider pack for the specified provider
943  * @tparam Prov type of the provider
944  * @throw runtime_error and everything provider() method can throw
945  * @see FillProviderPack()
946  *
947  * The provider is required to have a `providers_type` type defined as an
948  * specialisation of lar::ProviderPack.
949  */
950  template <typename Prov>
951  typename Prov::providers_type ProviderPackFor() const
952  {
953  typename Prov::providers_type pack;
954  FillProviderPack(pack);
955  return pack;
956  } // ProviderPackFor()
957 
958 
959  protected:
960  ProviderList providers; ///< list of available providers
961  }; // class TesterEnvironment<>
962 
963 
964 
965  /**
966  * @brief Constructs and returns a TesterEnvironment object
967  * @tparam CONFIG type of configuration object (detected from arguments)
968  * @tparam TESTENV type of the tester environment (default: TesterEnvironment)
969  * @tparam ARGS pack of types of the remining constructor arguments (optional)
970  * @param config the configuration object to be used
971  * @param other_args the remaining arguments of the tester constructor
972  *
973  * This function creates and returns a tester environment.
974  * By default, the tester environment class is TesterEnvironment<CONFIG>
975  * and no additional constructor arguments are needed except for special
976  * needs. The simplest way to use the function with an already available
977  * configuration is:
978  *
979  * auto TestEnv = testing::CreateTesterEnvironment(config);
980  *
981  * where TestEnv is assigned a specialization of TesterEnvironment.
982  *
983  * The template class TESTENV undergoes the following requirement:
984  *
985  * - it must have a constructor using a CONFIG constant reference as first
986  * argument
987  *
988  * The CONFIG object is subject to no special requirements besides the ones
989  * from TESTENV constructor.
990  */
991  // Note: this function is expected to be used with automatic type detection;
992  // the rules on "universal references" dictate that if config is a (l-value)
993  // reference, CONFIG itself is a l-value reference. We don't want to create
994  // a TesterEnvironment<Config&>, so we explicitly remove the reference from
995  // CONFIG (decay does that and aso removes the constantness, that we also
996  // don't want to be embedded in CONFIG).
997  template <
998  typename CONFIG,
999  typename TESTENV = TesterEnvironment<std::decay_t<CONFIG>>,
1000  typename... ARGS
1001  >
1002  TESTENV CreateTesterEnvironment(CONFIG&& config, ARGS... other_args)
1003  {
1004  return TESTENV
1005  (std::forward<CONFIG>(config), std::forward<ARGS>(other_args)...);
1006  }
1007 
1008 
1009 
1010  //****************************************************************************
1011  namespace details {
1012  // Class to implement FHiCL file search.
1013  // This is badly ripped off from ART, but we need to stay out of it
1014  // so I have to replicate that functionality.
1015  // I used the same class name.
1016  class FirstAbsoluteOrLookupWithDotPolicy: public cet::filepath_maker {
1017  public:
1019  first(true), after_paths(paths)
1020  {}
1021 
1022  virtual std::string operator() (std::string const& filename);
1023 
1024  void reset() { first = true; }
1025 
1026  private:
1027  bool first; ///< whether we are waiting for the first query
1028  cet::search_path after_paths; ///< path for the other queries
1029 
1030  }; // class FirstAbsoluteOrLookupWithDotPolicy
1031 
1032 
1033  inline std::string FirstAbsoluteOrLookupWithDotPolicy::operator()
1034  (std::string const &filename)
1035  {
1036  if (first) {
1037  first = false;
1039  return cet::search_path("./:" + after_paths.to_string())
1040  .find_file(filename);
1041  } else {
1042  return after_paths.find_file(filename);
1043  }
1044  } // FirstAbsoluteOrLookupWithDotPolicy::operator()
1045 
1046 
1047  /// Helper to fill a provider pack: main specialisation
1048  template
1049  <typename TestEnv, typename Pack, typename Prov, typename... Others>
1050  struct ProviderPackFiller<TestEnv, Pack, Prov, Others...> {
1051  static void fill(TestEnv const& env, Pack& pack)
1052  {
1053  pack.set(env.template Provider<Prov>());
1055  } // fill()
1056 
1057  }; // ProviderPackFiller<TestEnv, Pack, Prov, Others...>
1058 
1059  // end-of-recursion specialisation
1060  template <typename TestEnv, typename Pack>
1061  struct ProviderPackFiller<TestEnv, Pack> {
1062  static void fill(TestEnv const&, Pack&) {}
1063  }; // ProviderPackFiller<>
1064 
1065 
1066  } // namespace details
1067 
1068 
1069  //****************************************************************************
1070  template <typename ConfigurationClass>
1072 
1073  mf::LogInfo("Test") << config.ApplicationName() << " completed.";
1074 
1075  } // BasicTesterEnvironment<>::~BasicTesterEnvironment()
1076 
1077 
1078  /** **************************************************************************
1079  * @brief Compiles a parameter set from a string
1080  * @return a parameters set with the complete configuration
1081  */
1082  template <typename ConfigurationClass>
1085  (std::string cfg)
1086  {
1087  fhicl::ParameterSet global_pset;
1088  global_pset = fhicl::ParameterSet::make(cfg);
1089  return global_pset;
1090  } // BasicTesterEnvironment<>::CompileParameterSet()
1091 
1092 
1093  /** **************************************************************************
1094  * @brief Returns the configuration from a FHiCL file
1095  * @param config_path full path of the FHiCL configuration file
1096  * @return a parameters set with the complete configuration from the file
1097  */
1098  template <typename ConfigurationClass>
1101  (std::string config_path)
1102  {
1103  // configuration file lookup policy
1104  char const* fhicl_env = getenv("FHICL_FILE_PATH");
1105  std::string search_path = fhicl_env? std::string(fhicl_env) + ":": ".:";
1106  details::FirstAbsoluteOrLookupWithDotPolicy policy(search_path);
1107 
1108  // parse a configuration file; obtain intermediate form
1110  table = fhicl::parse_document(config_path, policy);
1111 
1112  // translate into a parameter set
1113  fhicl::ParameterSet global_pset;
1114  global_pset = fhicl::ParameterSet::make(table);
1115 
1116  return global_pset;
1117  } // BasicTesterEnvironment<>::ParseParameters()
1118 
1119 
1120  /** **************************************************************************
1121  * @brief Fills the configuration
1122  *
1123  * The complete configuration (message facility and services) is read and
1124  * saved, hence accessible by Parameters() method.
1125  *
1126  * The configuration file path is taken by default from the first argument
1127  * of the test.
1128  * If that first argument is not present or empty, the default configuration
1129  * path is received from the configurer.
1130  * If the configuration path is still empty, a hard-coded configuration
1131  * is used; otherwise, the FHiCL file specified in that path is parsed and
1132  * used as full configuration.
1133  */
1134  template <typename ConfigurationClass>
1136  std::string config_path = config.ConfigurationPath();
1137  params = config_path.empty()?
1138  DefaultParameters(): ParseParameters(config_path);
1139  } // BasicTesterEnvironment::Configure()
1140 
1141 
1142  /** **************************************************************************
1143  * @brief Sets the message facility up
1144  *
1145  * Message facility configuration is expected in "services.message" parameter
1146  * set. If not there, the default configuration is used.
1147  */
1148  template <typename ConfigurationClass>
1150  (fhicl::ParameterSet const& pset, std::string appl_name /* = "" */) const
1151  {
1152  fhicl::ParameterSet mf_pset;
1153 
1154  if
1155  (!pset.get_if_present(config.ServiceParameterSetPath("message"), mf_pset))
1156  {
1157  mf_pset
1158  = CompileParameterSet(config.DefaultServiceConfiguration("message"));
1159  std::cout << "Using default message facility configuration:\n"
1160  << mf_pset.to_indented_string(1) << std::endl;
1161  } // if no configuration is available
1162 
1163  mf::StartMessageFacility(mf_pset);
1164  if (!appl_name.empty()) mf::SetApplicationName(appl_name);
1165  mf::SetContextIteration("Initialization");
1166  if (options.MessageLevels) {
1167  std::cout << "Printing message levels in 'MessageFacility' category."
1168  << std::endl;
1169 
1170  mf::LogProblem("MessageFacility") << "Error messages are shown.";
1171  mf::LogPrint("MessageFacility") << "Warning messages are shown.";
1172  mf::LogVerbatim("MessageFacility") << "Info messages are shown.";
1173  mf::LogTrace("MessageFacility") << "Debug messages are shown.";
1174  MF_LOG_TRACE("MessageFacility")
1175  << "MF_LOG_TRACE/MF_LOG_DEBUG messages are not compiled away.";
1176  } // if print message levels
1177  mf::LogInfo("MessageFacility") << "MessageFacility started.";
1178  mf::SetContextSinglet("main");
1179  } // BasicTesterEnvironment::SetupMessageFacility()
1180 
1181 
1182 
1183  template <typename ConfigurationClass>
1185  ) {
1186 
1187  //
1188  // get the configuration
1189  //
1190  Configure();
1191 
1192  //
1193  // parse the options specific to the test environment
1194  //
1195  ParseEnvironmentOptions();
1196 
1197  //
1198  // set up the message facility
1199  //
1201 
1202  //
1203  // Optionally print the configuration
1204  //
1205  {
1206  mf::LogInfo msg("Configuration");
1207  msg << "Complete configuration (";
1208  if (config.ConfigurationPath().empty()) msg << "default";
1209  else msg << "'" << config.ConfigurationPath() << "'";
1210  msg << "):\n" << Parameters().to_indented_string(1);
1211  }
1212 
1213 
1214  mf::LogInfo("Test") << config.ApplicationName() << " base setup complete.";
1215 
1216  } // BasicTesterEnvironment<>::Setup()
1217 
1218 
1219 
1220  template <typename ConfigurationClass>
1222 
1223  struct OptionsFromConfig_t {
1224  fhicl::Atom<bool> messageLevels{
1225  fhicl::Name("messageLevels"),
1226  fhicl::Comment("prints a message per level (to verify the visible ones"),
1227  false // default: no
1228  };
1229  fhicl::Atom<bool> printOptions{
1230  fhicl::Name("printOptions"),
1231  fhicl::Comment("prints a the list of options (this is one of them!)"),
1232  false // default: no
1233  };
1234  }; // OptionsFromConfig_t
1235 
1236 
1237  struct ValidationHelper {
1238  static void printDummy(std::ostream& out)
1239  {
1241  (fhicl::Name("test"), fhicl::Comment("Test environment options"))
1243  } // printDummy()
1244 
1246  (fhicl::ParameterSet const& pset)
1247  {
1248  try {
1249  return fhicl::Table<OptionsFromConfig_t>(pset, {});
1250  }
1251  catch (...) {
1252  std::cerr << "Error parsing environment test options! Valid options:"
1253  << std::endl;
1254  ValidationHelper::printDummy(std::cerr);
1255  throw;
1256  }
1257  } // validate()
1258  };
1259 
1260 
1261  fhicl::ParameterSet pset = params.get<fhicl::ParameterSet>("test", {});
1262 
1263  // automatically performs validation
1266 
1267  if (configTable().printOptions()) {
1268  std::cout
1269  << "The following options can be passed to the test environment"
1270  << " by putting them in the \"test: {}\" table of the configuration file:"
1271  << std::endl;
1272  ValidationHelper::printDummy(std::cout);
1273  }
1274 
1275  options.MessageLevels = configTable().messageLevels();
1276 
1277  } // BasicTesterEnvironment<>::ParseEnvironmentOptions()
1278 
1279 
1280 } // namespace testing
1281 
1282 #endif // TEST_UNIT_TEST_BASE_H
static QCString name
Definition: declinfo.cpp:673
Container of service providers accessed by type and optional label.
Definition: ProviderList.h:160
fhicl::ParameterSet const & Parameters() const
Returns the full configuration.
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
LArSoft test utilities.
Prov const * Provider() const
Return the specified provider (throws if not available)
static fhicl::ParameterSet ParseParameters(std::string config_path)
Fills the test configuration from file or from default.
static void CreateDefaultResource(Args &&...args)
Constructs and registers a new resource with no name.
void ParseArguments(int argc, char **argv)
Parses arguments.
void msg(const char *fmt,...)
Definition: message.cpp:107
std::string BuildDefaultConfiguration() const
A string describing the full default parameter set.
std::map< std::string, std::string > PathMap_t
Options_t options
options for the test environment
void SetApplicationName(std::string name)
Sets the name of the application.
std::map< std::string, std::string > ConfigurationMap_t
std::string DefaultConfiguration() const
A string describing the full default parameter set.
Prov * SetupProviderFromService(std::string name, Args &&...args)
Sets a service provider up by calling its testing::setupProvider()
virtual fhicl::ParameterSet DefaultParameters() const
Creates a full configuration for the test.
fhicl::ParameterSet TesterParameters(std::string test_name) const
Returns the configuration of the specified test.
std::string string
Definition: nybbler.cc:12
static ParameterSet make(intermediate_table const &tbl)
Definition: ParameterSet.cc:68
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
std::shared_ptr< Resource_t > ResourcePtr_t
BasicEnvironmentConfiguration(std::string name)
Constructor; accepts the name as parameter.
BasicTesterEnvironment(bool bSetup=true)
Constructor: sets everything up and declares the test started.
void SetMainTesterParameterSetName(std::string name)
Sets the FHiCL name for the configuration of the test algorithm.
std::string DefaultTesterConfiguration(std::string tester_name) const
A string describing default parameter set to configure specified test.
std::string ExecutablePath() const
Returns the name of the executable as started.
ChannelGroupService::Name Name
virtual void Configure()
Reads and translates the configuration.
Class holding a configuration for a test environment.
Environment for a test.
void FillProviderPack(lar::ProviderPack< Provs... > &pack) const
Fills the specified provider pack with providers.
static bool hasResource(std::string name="")
BasicEnvironmentConfiguration(int argc, char **argv, std::string name)
std::string Executable() const
Returns the name of the executable as started.
Data structure containing constant pointers to classes.
std::string TesterParameterSetPath(std::string name) const
FHiCL path for the configuration of the test algorithm.
static std::string DefaultApplicationName()
Returns the default test name.
Prov * SetupProviderFromServiceFor(std::string name, Args &&...args)
Sets a provider up, recording it as implementation of Interface.
Configuration_t const & Config() const
Returns a read-only version of the configuration.
Prov * AcquireProvider(std::unique_ptr< Prov > &&prov)
Acquires a service provider.
static void AddDefaultSharedResource(ResourcePtr_t res_ptr)
Adds a shared resource to the resource registry (empty name)
string filename
Definition: train.py:213
void ParseCommandLine(int argc, char **argv)
Extracts arguments from the command line, uses first one as config path.
void SetContextIteration(string const &val)
CommandLineArguments()
Constructor: automatically parses from Boost arguments.
std::string MainTesterParameterSetPath() const
FHiCL path for the configuration of the test algorithm.
CommandLineArguments(int argc, char **argv)
Constructor: parses from specified arguments.
void SetupMessageFacility(fhicl::ParameterSet const &pset, std::string applName="standalone")
Sets up the message facility service.
MaybeLogger_< ELseverityLevel::ELsev_error, true > LogProblem
std::string ServiceParameterSetPath(std::string name) const
FHiCL path for the configuration of the service.
void StartMessageFacility(fhicl::ParameterSet const &pset, string const &applicationName)
Prov::providers_type ProviderPackFor() const
Returns a provider pack for the specified provider.
static Resource_t & DestroyResource(std::string name="")
Destroys the specified resource (does nothing if no such resource)
Prov * SimpleProviderSetup()
Oversimplified provider setup.
bool hasArgument(size_t iArg) const
Returns whether we have arguments up to the iArg-th (0-based)
void DropProvider()
Removes and destroys the specified provider.
std::string MainTesterParameterSetName() const
Name of the test algorithm instance.
void ParseEnvironmentOptions()
Parses the configuration, looking for the test environment options.
std::vector< std::string > args
command line arguments (from argv[0])
static bool ReplaceSharedResource(std::string res_name, Resource_t const *old_res_ptr, ResourcePtr_t res_ptr)
Adds a shared resource only if it is old_res_ptr.
std::string DefaultServiceConfiguration(std::string service_name) const
A string describing the default parameter set to configure the test.
static Resource_t & Resource(std::string name="")
Retrieves the specified resource, or throws if not available.
static Config * config
Definition: config.cpp:1054
static ResourcePtr_t ShareResource(std::string name="")
Retrieves the specified resource for sharing (nullptr if none)
std::string print_allowed_configuration(LibraryInfo const &li, std::string const &prefix, std::string const &type_spec)
std::string getenv(std::string const &name)
Definition: getenv.cc:15
def move(depos, offset)
Definition: depos.py:107
std::vector< std::string > const & Arguments() const
Returns the list of non-Boost-test arguments on the command line.
std::string exec_name
name of the test executable (from argv[0])
#define MF_LOG_TRACE(id)
TESTENV CreateTesterEnvironment(CONFIG &&config, ARGS...other_args)
Constructs and returns a TesterEnvironment object.
bool is_absolute_filepath(std::string const &qualified_filename)
Definition: filesystem.cc:23
std::string to_indented_string() const
ConfigurationClass Configuration_t
fhicl::ParameterSet ServiceParameters(std::string service_name) const
Returns the configuration of the specified service.
std::string const & Argument(size_t iArg) const
Returns the value of the iArg-th (0-based; no range check!)
Reads and makes available the command line parameters.
Utility class providing singleton objects to the derived classes.
void SetTesterParameterSetPath(std::string test_name, std::string path)
Sets the FHiCL path for the configuration of a test algorithm.
std::string BuildDefaultTestConfiguration() const
A string describing the full default parameter set.
def validate(nxgraph, desc)
Definition: graph.py:45
Prov * SetupProvider(Args &&...args)
Sets a service provider up by calling its testing::setupProvider()
int operator()() const
virtual void Setup()
The complete initialization, ran at construction by default.
A test environment with some support for service providers.
BasicEnvironmentConfiguration()
Default constructor; this is what is used in Boost unit test.
Prov * AcquireProviderFor(std::unique_ptr< Prov > &&prov)
Acquires a service provider implementing an interface.
void SetConfigurationPath(std::string path)
Sets the path to the configuration file.
fhicl::ParameterSet TesterParameters() const
Returns the configuration of the main test (undefined if no main test)
void AddDefaultTesterConfiguration(std::string tester_cfg)
Adds a default configuration for the main tester.
#define Comment
static ResourcePtr_t ProvideDefaultSharedResource(ResourcePtr_t res_ptr)
Creates a shared resource as default only if none exists yet.
BasicTesterEnvironment(Configuration_t &&configurer, bool bSetup=true)
def fill(s)
Definition: translator.py:93
std::string ConfigurationPath() const
Path to the configuration file.
intermediate_table parse_document(std::string const &filename, cet::filepath_maker &maker)
Definition: parse.cc:720
Container for a list of pointers to providers.
Definition: ProviderPack.h:114
std::optional< T > get_if_present(std::string const &key) const
Definition: ParameterSet.h:224
void Configure(string mesg)
Definition: gEvServ.cxx:196
T copy(T const &v)
void SetContextSinglet(string const &val)
std::string BuildDefaultServiceConfiguration() const
A string describing the full default parameter set.
std::vector< std::string > const & EexcutableArguments() const
Returns the list of non-Boost-test arguments on the command line.
MaybeLogger_< ELseverityLevel::ELsev_success, true > LogTrace
void Clear()
Erases the stored arguments.
void SetServiceParameterSetPath(std::string service_name, std::string path)
Sets the FHiCL path for the configuration of a test algorithm.
void SetMainTesterParameterSetPath(std::string path)
Sets the FHiCL path for the configuration of the main test algorithm.
void DefaultInit()
Initialize with some default values.
static fhicl::ParameterSet CompileParameterSet(std::string cfg)
Compiles a parameter set from a string.
static ResourcePtr_t ProposeDefaultSharedResource(Args &&...args)
Creates a shared resource as default only if none exists yet.
void SetApplicationName(string const &applicationName)
static ResourcePtr_t CreateResource(std::string res_name, Args &&...args)
Constructs and registers a new resource with a specified name.
static void AddSharedResource(std::string res_name, ResourcePtr_t res_ptr)
Adds a shared resource to the resource registry.
virtual ~BasicTesterEnvironment()
Destructor: closing remarks.
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
Definition: StdUtils.h:97
MaybeLogger_< ELseverityLevel::ELsev_warning, true > LogPrint
QTextStream & endl(QTextStream &s)
virtual void SetupMessageFacility() const
Prov * SetupProviderFor(Args &&...args)
Sets a provider up, recording it as implementation of Interface.
BasicEnvironmentConfiguration(int argc, char **argv)
Constructor: acquires parameters from the command line.