Project
Loading...
Searching...
No Matches
test_Variants.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12#include <catch_amalgamated.hpp>
13#include "Framework/Variant.h"
16#include <sstream>
17#include <cstring>
18
19using namespace o2::framework;
20
22{
23 auto const& err = error_from_ref(ref);
24 return strcmp(err.what, "Mismatch between types") == 0;
25}
26
27TEST_CASE("VariantTest")
28{
29 std::ostringstream ss{};
30 Variant a(10);
31 REQUIRE(a.get<int>() == 10);
32 ss << a;
33 Variant b(10.1f);
34 REQUIRE(b.get<float>() == 10.1f);
35 ss << b;
36 Variant c(10.2);
37 REQUIRE(c.get<double>() == 10.2);
38 ss << c;
39 REQUIRE_THROWS_AS(a.get<char*>(), RuntimeErrorRef);
40 Variant d("foo");
41 ss << d;
42 REQUIRE(std::string(d.get<const char*>()) == "foo");
43 REQUIRE(std::string(d.get<std::string_view>()) == "foo");
44 REQUIRE(std::string(d.get<std::string>()) == "foo");
45
46 Variant e(true);
47 REQUIRE(e.get<bool>() == true);
48
49 Variant f(false);
50 REQUIRE(f.get<bool>() == false);
51
52 REQUIRE(ss.str() == "1010.110.2foo");
53 // Spotted valgrind error while deleting a vector of variants.
54 std::vector<Variant> vector{1, 1.2, 1.1f, "foo"};
55 Variant sa("foo");
56 Variant sb(sa); // Copy constructor
57 Variant sc(std::move(sa)); // Move constructor
58 Variant sd = sc; // Copy assignment
59
60 REQUIRE(std::string(sb.get<const char*>()) == "foo");
61 REQUIRE(std::string(sc.get<const char*>()) == "foo");
62 REQUIRE(std::string(sd.get<const char*>()) == "foo");
63 REQUIRE(sa.get<const char*>() == nullptr);
64
65 int iarr[] = {1, 2, 3, 4, 5};
66 float farr[] = {0.2, 0.3, 123.123, 123.123, 3.005e-5, 1.1e6};
67 std::vector<double> dvec = {0.1, 0.2, 0.4, 0.9, 1.3, 14.5, 123.234, 1.213e-20};
68 Variant viarr(iarr, 5);
69 Variant vfarr(farr, 6);
70 Variant vdvec(dvec);
71
72 REQUIRE(viarr.size() == 5);
73 REQUIRE(viarr.get<int*>() != iarr);
74 for (auto i = 0u; i < viarr.size(); ++i) {
75 REQUIRE(iarr[i] == (viarr.get<int*>())[i]);
76 }
77
78 REQUIRE(vfarr.size() == 6);
79 REQUIRE(vfarr.get<float*>() != farr);
80 for (auto i = 0u; i < vfarr.size(); ++i) {
81 REQUIRE(farr[i] == (vfarr.get<float*>())[i]);
82 }
83
84 REQUIRE(vdvec.size() == dvec.size());
85 REQUIRE(vdvec.get<double*>() != dvec.data());
86 for (auto i = 0u; i < dvec.size(); ++i) {
87 REQUIRE(dvec[i] == (vdvec.get<double*>())[i]);
88 }
89
90 Variant fb(vfarr); // Copy constructor
91 Variant fc(std::move(vfarr)); // Move constructor
92 Variant fd = fc; // Copy assignment
93
94 REQUIRE(vfarr.get<float*>() == nullptr);
95
96 REQUIRE(fb.get<float*>() != farr);
97 for (auto i = 0u; i < fb.size(); ++i) {
98 REQUIRE(farr[i] == (fb.get<float*>())[i]);
99 }
100 REQUIRE(fc.get<float*>() != farr);
101 for (auto i = 0u; i < fc.size(); ++i) {
102 REQUIRE(farr[i] == (fc.get<float*>())[i]);
103 }
104 REQUIRE(fd.get<float*>() != farr);
105 for (auto i = 0u; i < fd.size(); ++i) {
106 REQUIRE(farr[i] == (fd.get<float*>())[i]);
107 }
108
109 std::vector<std::string> vstrings{"s1", "s2", "s3"};
110 std::string strings[] = {"l1", "l2", "l3"};
111 Variant vstr(strings, 3);
112 Variant vvstr(vstrings);
113
114 REQUIRE(vstr.size() == 3);
115 REQUIRE(vvstr.size() == 3);
116 for (auto i = 0u; i < vstr.size(); ++i) {
117 REQUIRE(strings[i] == (vstr.get<std::string*>())[i]);
118 }
119 for (auto i = 0u; i < vvstr.size(); ++i) {
120 REQUIRE(vstrings[i] == (vvstr.get<std::string*>())[i]);
121 }
122
123 Variant vsc(vstr); // Copy constructor
124 Variant vsm(std::move(vstr)); // Move constructor
125 Variant vscc = vsm; // Copy assignment
126 for (auto i = 0u; i < vsm.size(); ++i) {
127 REQUIRE(strings[i] == (vsm.get<std::string*>())[i]);
128 }
129 for (auto i = 0u; i < vscc.size(); ++i) {
130 REQUIRE(strings[i] == (vscc.get<std::string*>())[i]);
131 }
132
133 Variant vsca(vvstr); // Copy constructor
134 Variant vsma(std::move(vvstr)); // Move constructor
135 Variant vscca = vsma; // Copy assignment
136 for (auto i = 0u; i < vsma.size(); ++i) {
137 REQUIRE(vstrings[i] == (vsma.get<std::string*>())[i]);
138 }
139 for (auto i = 0u; i < vscca.size(); ++i) {
140 REQUIRE(vstrings[i] == (vscca.get<std::string*>())[i]);
141 }
142
143 float m[3][4] = {{0.5, 0.25, 0.125, 0.0625}, {1.0, 2.0, 3.0, 4.0}, {2.0, 0.5, 4.0, 0.25}};
144 Array2D mm(&m[0][0], 3, 4);
145 Variant vmm(mm);
146 auto const& mmc = vmm.get<Array2D<float>>();
147 for (auto i = 0u; i < 3; ++i) {
148 for (auto j = 0u; j < 4; ++j) {
149 REQUIRE(mmc(i, j) == mm(i, j));
150 }
151 }
152
153 Variant vmmc(vmm); // Copy constructor
154 Variant vmmm(std::move(vmm)); // Move constructor
155 Variant vmma = vmmm; // Copy assignment
156 auto const& mmc2 = vmmc.get<Array2D<float>>();
157 for (auto i = 0u; i < 3; ++i) {
158 for (auto j = 0u; j < 4; ++j) {
159 REQUIRE(mmc2(i, j) == mm(i, j));
160 }
161 }
162 auto const& mmc3 = vmma.get<Array2D<float>>();
163 for (auto i = 0u; i < 3; ++i) {
164 for (auto j = 0u; j < 4; ++j) {
165 REQUIRE(mmc3(i, j) == mm(i, j));
166 }
167 }
168 std::stringstream ssm;
169 ssm << vmma;
170 REQUIRE(ssm.str() == "{\"values\":[[0.5,0.25,0.125,0.0625],[1.0,2.0,3.0,4.0],[2.0,0.5,4.0,0.25]]}");
171
172 LabeledArray<float> laf{&m[0][0], 3, 4, {"r1", "r2", "r3"}, {"c1", "c2", "c3", "c4"}};
173 Variant vlaf(laf);
174 auto const& lafc = vlaf.get<LabeledArray<float>>();
175 for (auto i = 0u; i < 3; ++i) {
176 for (auto j = 0u; j < 4; ++j) {
177 REQUIRE(laf.get(i, j) == lafc.get(i, j));
178 }
179 }
180
181 Variant vlafc(vlaf); // Copy constructor
182 Variant vlafm(std::move(vlaf)); // Move constructor
183 Variant vlafa = vlafm; // Copy assignment
184 auto const& lafc2 = vlafc.get<LabeledArray<float>>();
185 for (auto i = 0U; i < 3; ++i) {
186 for (auto j = 0U; j < 4; ++j) {
187 REQUIRE(lafc2.get(i, j) == mm(i, j));
188 }
189 }
190 auto const& lafc3 = vlafa.get<LabeledArray<float>>();
191 for (auto i = 0U; i < 3; ++i) {
192 for (auto j = 0U; j < 4; ++j) {
193 REQUIRE(lafc3.get(i, j) == mm(i, j));
194 }
195 }
196
197 std::vector<Variant> collection;
198 collection.push_back(vlafc);
199 collection.push_back(vlafm);
200 collection.push_back(vlafa);
201}
202
203TEST_CASE("Array2DTest")
204{
205 float m[3][4] = {{0.1, 0.2, 0.3, 0.4}, {0.5, 0.6, 0.7, 0.8}, {0.9, 1.0, 1.1, 1.2}};
206 Array2D mm(&m[0][0], 3, 4);
207 for (auto i = 0U; i < 3; ++i) {
208 for (auto j = 0U; j < 4; ++j) {
209 REQUIRE(mm(i, j) == m[i][j]);
210 }
211 }
212 std::vector<float> v = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2};
213 Array2D mv(v, 3, 4);
214 for (auto i = 0U; i < 3; ++i) {
215 for (auto j = 0U; j < 4; ++j) {
216 REQUIRE(mm(i, j) == v[i * 4 + j]);
217 }
218 }
219 for (auto i = 0U; i < 3; ++i) {
220 auto const& vv = mm[i];
221 for (auto j = 0u; j < 4; ++j) {
222 REQUIRE(vv[j] == mm(i, j));
223 }
224 }
225 std::vector<std::string> s = {"one", "two", "three", "four"};
226 Array2D ms(s, 4, 1);
227 for (auto i = 0U; i < 4; ++i) {
228 REQUIRE(ms(i, 0) == s[i]);
229 }
230}
231
232TEST_CASE("LabeledArrayTest")
233{
234 float m[3][4] = {{0.1, 0.2, 0.3, 0.4}, {0.5, 0.6, 0.7, 0.8}, {0.9, 1.0, 1.1, 1.2}};
235 std::string mS[3][4] = {{"a", "b", "c", "d"}, {"e", "f", "g", "h"}, {"i", "l", "m", "n"}};
236 std::string xl[] = {"c1", "c2", "c3", "c4"};
237 std::string yl[] = {"r1", "r2", "r3"};
238 LabeledArray<float> laf{&m[0][0], 3, 4, {"r1", "r2", "r3"}, {"c1", "c2", "c3", "c4"}};
239 LabeledArray<std::string> las{&mS[0][0], 3, 4, {"r1", "r2", "r3"}, {"c1", "c2", "c3", "c4"}};
240 for (auto i = 0u; i < 3; ++i) {
241 for (auto j = 0u; j < 4; ++j) {
242 REQUIRE(laf.get(yl[i].c_str(), xl[j].c_str()) == laf.get(i, j));
243 REQUIRE(laf.get(i, xl[j].c_str()) == laf.get(i, j));
244 REQUIRE(laf.get(yl[i].c_str(), j) == laf.get(i, j));
245
246 REQUIRE(las.get(yl[i].c_str(), xl[j].c_str()) == las.get(i, j));
247 REQUIRE(las.get(i, xl[j].c_str()) == las.get(i, j));
248 REQUIRE(las.get(yl[i].c_str(), j) == las.get(i, j));
249 }
250 }
251}
252
253TEST_CASE("VariantTreeConversionsTest")
254{
255 std::vector<std::string> vstrings{"0 1", "0 2", "0 3"};
256 Variant vvstr(std::move(vstrings));
257
258 auto tree = vectorToBranch(vvstr.get<std::string*>(), vvstr.size());
259 auto v = Variant(vectorFromBranch<std::string>(tree));
260
261 for (auto i = 0U; i < vvstr.size(); ++i) {
262 REQUIRE(vvstr.get<std::string*>()[i] == v.get<std::string*>()[i]);
263 }
264}
265
266TEST_CASE("VariantJSONConversionsTest")
267{
268 int iarr[] = {1, 2, 3, 4, 5};
269 Variant viarr(iarr, 5);
270 std::stringstream os;
271 VariantJSONHelpers::write(os, viarr);
272
273 std::stringstream is;
274 is.str(os.str());
275 auto v = VariantJSONHelpers::read<VariantType::ArrayInt>(is);
276 for (auto i = 0u; i < viarr.size(); ++i) {
277 REQUIRE(v.get<int*>()[i] == viarr.get<int*>()[i]);
278 }
279 os.str("");
280
281 float m[3][4] = {{0.1, 0.2, 0.3, 0.4}, {0.5, 0.6, 0.7, 0.8}, {0.9, 1.0, 1.1, 1.2}};
282 Array2D mm(&m[0][0], 3, 4);
283 Variant vmm(mm);
284 std::stringstream osm;
286
287 std::stringstream ism;
288 ism.str(osm.str());
289 auto vm = VariantJSONHelpers::read<VariantType::Array2DFloat>(ism);
290
291 for (auto i = 0u; i < mm.rows; ++i) {
292 for (auto j = 0u; j < mm.cols; ++j) {
293 REQUIRE(vmm.get<Array2D<float>>()(i, j) == vm.get<Array2D<float>>()(i, j));
294 }
295 }
296
297 LabeledArray<float> laf{&m[0][0], 3, 4, {"r1", "r2", "r3"}, {"c1", "c2", "c3", "c4"}};
298 Variant vlaf(laf);
299 std::stringstream osl;
300 VariantJSONHelpers::write(osl, vlaf);
301
302 std::stringstream isl;
303 isl.str(osl.str());
304 auto vlafc = VariantJSONHelpers::read<VariantType::LabeledArrayFloat>(isl);
305
306 for (auto i = 0u; i < vlafc.get<LabeledArray<float>>().rows(); ++i) {
307 for (auto j = 0u; j < vlafc.get<LabeledArray<float>>().cols(); ++j) {
308 REQUIRE(vlaf.get<LabeledArray<float>>().get(i, j) == vlafc.get<LabeledArray<float>>().get(i, j));
309 }
310 }
311
312 std::string mS[3][4] = {{"a", "b", "c", "d"}, {"e", "f", "g", "h"}, {"i", "l", "m", "n"}};
313 LabeledArray<std::string> las{&mS[0][0], 3, 4, {"r1", "r2", "r3"}, {"c1", "c2", "c3", "c4"}};
314 Variant vms(las);
315 std::stringstream ossl;
316 VariantJSONHelpers::write(ossl, vms);
317
318 std::stringstream issl;
319 issl.str(ossl.str());
320 auto vmsa = VariantJSONHelpers::read<VariantType::LabeledArrayString>(issl);
321
322 for (auto i = 0U; i < vmsa.get<LabeledArray<std::string>>().rows(); ++i) {
323 for (auto j = 0U; j < vmsa.get<LabeledArray<std::string>>().cols(); ++j) {
324 REQUIRE(vmsa.get<LabeledArray<std::string>>().get(i, j) == vms.get<LabeledArray<std::string>>().get(i, j));
325 }
326 }
327
328 std::vector<std::string> vstrings{"myoption_one", "myoption_two"};
329 Variant vvstr(vstrings);
330 std::stringstream osal;
331 VariantJSONHelpers::write(osal, vvstr);
332
333 std::stringstream isal;
334 isal.str(osal.str());
335 auto vvstra = VariantJSONHelpers::read<VariantType::ArrayString>(isal);
336
337 for (auto i = 0U; i < vvstra.size(); ++i) {
338 REQUIRE(vstrings[i] == vvstra.get<std::string*>()[i]);
339 }
340}
341
342TEST_CASE("VariantThrowing")
343{
344 Variant a("true");
345 REQUIRE_THROWS_AS(a.get<int>(), o2::framework::RuntimeErrorRef);
346 try {
347 a.get<int>();
348 } catch (RuntimeErrorRef& ref) {
350 REQUIRE(error.what == std::string("Variant::get: Mismatch between types 4 0."));
351 }
352}
int32_t i
uint32_t j
Definition RawData.h:0
uint32_t c
Definition RawData.h:2
uint32_t cols
T get(uint32_t y, uint32_t x) const
Definition Array2D.h:199
Variant for configuration parameter storage. Owns stored data.
Definition Variant.h:307
size_t size() const
Definition Variant.h:391
const GLfloat * m
Definition glcorearb.h:4066
GLsizei const GLchar *const * strings
Definition glcorearb.h:1907
const GLdouble * v
Definition glcorearb.h:832
GLdouble f
Definition glcorearb.h:310
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
TEST_CASE("test_prepareArguments")
boost::property_tree::ptree vectorToBranch(T *values, size_t size)
RuntimeError & error_from_ref(RuntimeErrorRef)
char what[MAX_RUNTIME_ERROR_SIZE]
static void write(std::ostream &o, Variant const &v)
bool unknown_type(RuntimeErrorRef const &ref)
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))
std::vector< ReadoutWindowData > rows