ProviderList_test.cc
Go to the documentation of this file.
1 /**
2  * @file ProviderList_test.cc
3  * @brief Unit test for ProviderList.h
4  * @date April 22nd, 2016
5  * @author Gianluca Petrillo (petrillo@fnal.gov)
6  * @see ProviderList.h
7  *
8  * This test does not take any argument.
9  *
10  */
11 
12 
13 // LArSoft libraries
15 
16 // Boost libraries
17 #define BOOST_TEST_MODULE ProviderList_test
18 #include <boost/test/unit_test.hpp>
19 
20 // C/C++ standard library
21 #include <set>
22 #include <memory> // std::unique_ptr<>
23 
24 
25 //------------------------------------------------------------------------------
26 
27 std::set<void*> TrackedMemory; // track allocated objects
28 
29 
30 //------------------------------------------------------------------------------
31 // mock up providers
32 //
33 struct NormalDatumClass {
34  explicit NormalDatumClass(unsigned int v): value(v)
35  { TrackedMemory.insert(this); }
36 
37  NormalDatumClass(NormalDatumClass const&) = default;
39  NormalDatumClass& operator= (NormalDatumClass const&) = default;
41  ~NormalDatumClass() { TrackedMemory.erase(this); }
42 
43  unsigned int value;
44 }; // class NormalDatumClass
45 
46 
47 struct UncopiableDatumClass {
48  explicit UncopiableDatumClass(const char* v): value(v)
49  { TrackedMemory.insert(this); }
54  ~UncopiableDatumClass() { TrackedMemory.erase(this); }
55 
56  const char* value;
57 
58 }; // class UncopiableDatumClass
59 
60 
61 struct UnmovableDatumClass {
63  { TrackedMemory.insert(this); }
64  UnmovableDatumClass(UnmovableDatumClass const&) = default;
68  ~UnmovableDatumClass() { TrackedMemory.erase(this); }
69 }; // class UnmovableDatumClass
70 
71 namespace testing {
72 
73  template <>
74  std::unique_ptr<UnmovableDatumClass> setupProvider<UnmovableDatumClass>() {
75  BOOST_TEST_MESSAGE
76  (" *** special setup for UnmovableDatumClass *** ");
77  return std::make_unique<UnmovableDatumClass>();
78  } // setupProvider<UnmovableDatumClass>()
79 
80 } // namespace testing
81 
82 
83 struct PinnedDatumClassBase {
84  virtual ~PinnedDatumClassBase() = default;
85 
86  virtual bool abstract() const = 0;
87 }; // PinnedDatumClassBase
88 
90  explicit PinnedDatumClass(float x, float y): value1(x), value2(y)
91  { TrackedMemory.insert(this); }
92  PinnedDatumClass(PinnedDatumClass const&) = delete;
96  virtual ~PinnedDatumClass() { TrackedMemory.erase(this); }
97  virtual bool abstract() const override { return false; }
98 
99  static std::unique_ptr<PinnedDatumClass> New(float x, float y)
100  {
101  ++nNewCalls;
102  return
104  }
105 
106  static unsigned int nNewCalls;
107 
108  float value1, value2;
109 }; // class PinnedDatumClass
110 
111 unsigned int PinnedDatumClass::nNewCalls = 0;
112 
113 //------------------------------------------------------------------------------
114 // test functions
115 //
116 
117 template <typename T, typename LIST>
118 void TestElement(LIST& l, std::string label = "", bool present = true) {
119 
120  BOOST_TEST_MESSAGE("Testing class '" << typeid(T).name() << "' label \""
121  << label << "\" (" << (present? "present": "not present") << ")" );
122  BOOST_TEST(l.template known<T>(label) == present);
123  BOOST_TEST(l.template valid<T>(label) == present);
124  try {
125  auto const& item = l.template get<T>(label);
126  BOOST_TEST(present); // if not present, we should not be here!
127  BOOST_TEST(&item);
128  }
130  BOOST_TEST(!present); // if present, we should not be here!
131  }
132 
133 } // TestElement()
134 
135 
136 template <typename LIST>
137 void TestBase(LIST& l) {
138 
139  TestElement<NormalDatumClass>(l);
140  TestElement<UncopiableDatumClass>(l, "", false); // empty label not present
141  TestElement<UncopiableDatumClass>(l, "One"); // label "One" present
142  TestElement<UncopiableDatumClass>(l, "Two", false); // label "Two" not there
143  TestElement<UnmovableDatumClass>(l);
144  TestElement<PinnedDatumClass>(l);
145  TestElement<PinnedDatumClassBase>(l);
146  TestElement<int>(l, "", false); // no int present
147 
148  // test that the polymorphism is preserved by aliases
149  BOOST_TEST(!l.template get<PinnedDatumClassBase>().abstract());
150 
151 } // TestBase()
152 
153 
156  TestBase(l);
157 
158  // check that no "Acquired" is available yet
159  TestElement<UncopiableDatumClass>(l, "Acquired", false);
160 
161  // acquire a new one
162  BOOST_TEST(
163  l.acquire(std::make_unique<UncopiableDatumClass>
164  ("another uncopiable"), "Acquired")
165  );
166  TestElement<UncopiableDatumClass>(l, "Acquired", true);
167 
168  // erase it
169  BOOST_TEST(l.erase<UncopiableDatumClass>("Acquired"));
170  TestElement<UncopiableDatumClass>(l, "Acquired", false);
171 
172  // erase it again
173  BOOST_TEST(!l.erase<UncopiableDatumClass>("Acquired"));
174  TestElement<UncopiableDatumClass>(l, "Acquired", false);
175 
176  // erase something that was never there
177  BOOST_TEST(!l.erase<UncopiableDatumClass>("Never"));
178  TestElement<UncopiableDatumClass>(l, "Never", false);
179 
180 } // NonConstTest()
181 
182 
183 //------------------------------------------------------------------------------
184 // tests
185 //
186 BOOST_AUTO_TEST_CASE(ProviderListTest)
187 {
188  BOOST_TEST_MESSAGE("Construction and instantiation of ProviderList");
189  auto l = std::make_unique<testing::ProviderList>();
190 
191  BOOST_TEST(l->setup<NormalDatumClass>(12));
192  BOOST_TEST(l->setup_instance<UncopiableDatumClass>("One", "uncopiable"));
193  BOOST_TEST(l->setup<UnmovableDatumClass>());
194  BOOST_TEST
195  (l->custom_setup<PinnedDatumClass>(&PinnedDatumClass::New, 1.0, 0.0));
196  BOOST_TEST((l->set_alias<PinnedDatumClass, PinnedDatumClassBase>()));
197 
198  // second creation shoudl fail
199  BOOST_TEST(!l->setup_instance<UncopiableDatumClass>("One", "uncopiableII"));
200 
201  BOOST_TEST_MESSAGE("Constant list test");
202  ConstTest(*l);
203  BOOST_TEST_MESSAGE("Mutable list test");
204  NonConstTest(*l);
205 
206  BOOST_TEST_MESSAGE("ProviderListTest completed");
207 
208  // make sure that we did not leak anything
209  l.reset();
210  BOOST_TEST(TrackedMemory.empty());
211 
212  // check that we noticed a single call for a custom setup
213  BOOST_TEST(PinnedDatumClass::nNewCalls == 1U);
214 
215 } // BOOST_AUTO_TEST_CASE(ProviderListTest)
static QCString name
Definition: declinfo.cpp:673
Container of service providers accessed by type and optional label.
Definition: ProviderList.h:160
NormalDatumClass & operator=(NormalDatumClass const &)=default
LArSoft test utilities.
Exception thrown on a request about an unregistered type.
Definition: ProviderList.h:184
static std::unique_ptr< PinnedDatumClass > New(float x, float y)
std::string string
Definition: nybbler.cc:12
void TestBase(LIST &l)
virtual ~PinnedDatumClass()
static std::unique_ptr< Prov > setup(Args &&...args)
Instantiates a new provider with specified arguments for constructor.
UncopiableDatumClass(const char *v)
static QStrList * l
Definition: config.cpp:1044
std::unique_ptr< UnmovableDatumClass > setupProvider< UnmovableDatumClass >()
std::set< void * > TrackedMemory
NormalDatumClass(unsigned int v)
const double e
static unsigned int nNewCalls
void TestElement(LIST &l, std::string label="", bool present=true)
void NonConstTest(testing::ProviderList &l)
void ConstTest(testing::ProviderList const &l)
BOOST_AUTO_TEST_CASE(ProviderListTest)
PinnedDatumClass(float x, float y)
list x
Definition: train.py:276
constexpr ProductStatus present() noexcept
Definition: ProductStatus.h:10