17#define BOOST_BIND_GLOBAL_PLACEHOLDERS
18#define BOOST_TEST_MODULE CCDB
19#define BOOST_TEST_MAIN
20#define BOOST_TEST_DYN_LINK
26#include <boost/test/unit_test.hpp>
33#include <TStreamerInfo.h>
39#include <boost/property_tree/json_parser.hpp>
40#include <boost/property_tree/ptree.hpp>
41#include <boost/foreach.hpp>
42#include <boost/optional/optional.hpp>
46namespace utf = boost::unit_test;
49static std::string
ccdbUrl =
"http://ccdb-test.cern.ch:8080";
50static std::string basePath;
62 if (
const char* host = std::getenv(
"ALICEO2_CCDB_HOST")) {
66 cout <<
"ccdb url: " <<
ccdbUrl << endl;
69 char hostname[_POSIX_HOST_NAME_MAX];
70 gethostname(hostname, _POSIX_HOST_NAME_MAX);
71 basePath = std::string(
"Test/TestCcdbApi/") + hostname +
"/pid" + getpid() +
"/";
73 std::replace(basePath.begin(), basePath.end(),
'-',
'_');
74 cout <<
"Path we will use in this test suite : " + basePath << endl;
80 std::map<std::string, std::string> metadata;
83 cout <<
"Test data truncated (" << basePath <<
")" << endl;
107 std::cout <<
"*** " << boost::unit_test::framework::current_test_case().p_name <<
" ***" << std::endl;
119 TH1F h1(
"th1name",
"th1name", 100, 0, 99);
120 h1.FillRandom(
"gaus", 10000);
122 cout << basePath +
"th1" << endl;
123 f.api.storeAsTFile(&h1, basePath +
"th1",
f.metadata);
126 graph.SetPoint(0, 2, 3);
127 f.api.storeAsTFile(&graph, basePath +
"graph",
f.metadata);
129 TTree
tree(
"mytree",
"mytree");
131 tree.Branch(
"det", &
a,
"a/I");
133 f.api.storeAsTFile(&
tree, basePath +
"tree",
f.metadata);
143 path.setPath(
"HelloWorld");
145 f.api.storeAsTFileAny(&
path, basePath +
"CCDBPath",
f.metadata);
151 path2 =
f.api.retrieveFromTFileAny<
o2::ccdb::IdPath>(basePath +
"CCDBPath",
f.metadata);
152 BOOST_CHECK_NE(path2,
nullptr);
161 std::map<std::string, std::string> md;
162 path2 =
f.api.retrieveFromTFileAny<
o2::ccdb::IdPath>(basePath +
"CCDBPath",
f.metadata, -1, &md);
169 auto tree =
new TTree(
"tree123",
"tree123");
171 tree->Branch(
"det", &
a,
"a/I");
173 f.api.storeAsTFileAny(
tree, basePath +
"tree2",
f.metadata);
177 tree =
f.api.retrieveFromTFileAny<TTree>(basePath +
"tree2",
f.metadata);
188 std::filesystem::create_directories(ph);
189 std::cout <<
"Creating snapshot at " << ph <<
"\n";
191 std::cout <<
"Creating snapshot at " << ph <<
"\n";
201 auto tree = snapshot.retrieveFromTFileAny<TTree>(basePath +
"tree2",
f.metadata);
208 if (std::filesystem::exists(ph)) {
209 std::filesystem::remove_all(ph);
220 path.setPath(
"HelloWorld");
222 int result =
f.api.storeAsTFileAny(&
path, basePath +
"CCDBPath",
f.metadata);
224 result =
f.api.storeAsTFileAny(&
path, basePath +
"CCDBPath",
f.metadata, -1, -1, 1 );
236 path.setPath(
"HelloWorld");
238 const long timestamp = 1000;
239 const long endvalidity = timestamp + 10;
240 f.api.storeAsTFileAny(&
path, basePath +
"CCDBPathUnitTest",
f.metadata, timestamp, endvalidity);
246 path2 =
f.api.retrieveFromTFileAny<
o2::ccdb::IdPath>(basePath +
"CCDBPathUnitTest",
f.metadata, timestamp);
247 BOOST_CHECK_NE(path2,
nullptr);
250 for (
int t = timestamp;
t < endvalidity; ++
t) {
251 auto p =
f.api.retrieveFromTFileAny<
o2::ccdb::IdPath>(basePath +
"CCDBPathUnitTest",
f.metadata,
t);
252 BOOST_CHECK_NE(p,
nullptr);
256 auto plower =
f.api.retrieveFromTFileAny<
o2::ccdb::IdPath>(basePath +
"CCDBPathUnitTest",
f.metadata, timestamp - 1);
259 auto pupper =
f.api.retrieveFromTFileAny<
o2::ccdb::IdPath>(basePath +
"CCDBPathUnitTest",
f.metadata, endvalidity);
269 path.setPath(
"HelloWorld");
272 f.api.storeAsTFileAny(&
path, basePath +
"CCDBPathUnitTest",
f.metadata, from, to);
275 std::map<std::string, std::string> headers;
276 std::map<std::string, std::string> meta;
277 cout <<
"basePath + \"CCDBPathUnitTest\" : " << basePath +
"CCDBPathUnitTest" << endl;
278 cout <<
"from+1 : " << from + 1 << endl;
279 auto*
object =
f.api.retrieveFromTFileAny<
o2::ccdb::IdPath>(basePath +
"CCDBPathUnitTest", meta, from + 1, &headers);
288 TObject* obj =
f.api.retrieveFromTFileAny<
TObject>(basePath +
"th1",
f.metadata);
289 BOOST_CHECK_NE(obj,
nullptr);
291 auto h1 =
dynamic_cast<TH1F*
>(obj);
292 BOOST_CHECK_NE(h1,
nullptr);
296 obj =
f.api.retrieveFromTFileAny<
TObject>(basePath +
"graph",
f.metadata);
297 BOOST_CHECK_NE(obj,
nullptr);
299 auto graph =
dynamic_cast<TGraph*
>(obj);
300 BOOST_CHECK_NE(graph,
nullptr);
302 int ret = graph->GetPoint(0,
x,
y);
308 std::map<std::string, std::string> headers;
309 obj =
f.api.retrieveFromTFileAny<
TObject>(basePath +
"tree",
f.metadata, -1, &headers);
310 BOOST_CHECK_NE(obj,
nullptr);
312 auto tree =
dynamic_cast<TTree*
>(obj);
313 BOOST_CHECK_NE(
tree,
nullptr);
321 obj =
f.api.retrieveFromTFileAny<
TObject>(
"Wrong/wrong",
f.metadata);
329 TH1F
h(
"object1",
"object1", 100, 0, 99);
330 f.api.storeAsTFile(&
h, basePath +
"Detector",
f.metadata);
331 auto h1 =
f.api.retrieveFromTFileAny<TH1F>(basePath +
"Detector",
f.metadata);
333 f.api.truncate(basePath +
"Detector");
334 h1 =
f.api.retrieveFromTFileAny<TH1F>(basePath +
"Detector",
f.metadata);
342 TH1F h1(
"object1",
"object1", 100, 0, 99);
345 f.api.storeAsTFile(&h1, basePath +
"Detector",
f.metadata, from, to);
346 auto h2 =
f.api.retrieveFromTFileAny<TH1F>(basePath +
"Detector",
f.metadata);
348 f.api.deleteObject(basePath +
"Detector");
349 h2 =
f.api.retrieveFromTFileAny<TH1F>(basePath +
"Detector",
f.metadata);
353void countItems(
const std::string&
s,
int& countObjects,
int& countSubfolders)
357 std::stringstream ss(
s);
359 boost::property_tree::ptree pt;
360 boost::property_tree::read_json(ss, pt);
362 if (pt.count(
"objects") > 0) {
363 countObjects = pt.get_child(
"objects").size();
366 if (pt.count(
"subfolders") > 0) {
367 countSubfolders = pt.get_child(
"subfolders").size();
376 std::string
s =
f.api.list(
"",
"application/json");
377 long nbLines = std::count(
s.begin(),
s.end(),
'\n') + 1;
381 f.api.truncate(basePath +
"Detector*");
382 s =
f.api.list(basePath +
"Detector",
false,
"application/json");
383 int countObjects = 0;
384 int countSubfolders = 0;
389 TH1F h1(
"object1",
"object1", 100, 0, 99);
390 cout <<
"storing object 2 in Test/Detector" << endl;
391 f.api.storeAsTFile(&h1, basePath +
"Detector",
f.metadata);
392 cout <<
"storing object 3 in Test/Detector" << endl;
393 f.api.storeAsTFile(&h1, basePath +
"Detector",
f.metadata);
394 cout <<
"storing object 4 in Test/Detector" << endl;
395 f.api.storeAsTFile(&h1, basePath +
"Detector",
f.metadata);
396 cout <<
"storing object 5 in Test/Detector/Sub/abc" << endl;
397 f.api.storeAsTFile(&h1, basePath +
"Detector/Sub/abc",
f.metadata);
399 s =
f.api.list(basePath +
"Detector",
false,
"application/json");
404 s =
f.api.list(basePath +
"Detector*",
false,
"application/json");
409 s =
f.api.list(basePath +
"Detector",
true,
"application/json");
416 std::vector<std::string> headers = {
418 "Content-Location: /download/6dcb77c0-ca56-11e9-a807-200114580202",
419 "Date: Thu, 26 Sep 2019 08:09:20 GMT",
420 "Valid-Until: 1567771311999",
421 "Valid-From: 1567080816927",
422 "InitialValidityLimit: 1598616816927",
423 "Created: 1567080816956",
424 "ETag: \"6dcb77c0-ca56-11e9-a807-200114580202\"",
425 "Last-Modified: Thu, 29 Aug 2019 12:13:36 GMT",
426 "UpdatedFrom: 2001:1458:202:28:0:0:100:35",
428 "Content-Disposition: inline;filename=\"o2::dataformats::CalibLHCphaseTOF_1567080816916.root\"",
429 "Accept-Ranges: bytes",
430 "Content-MD5: 9481c9d036660f80e21dae5943c2096f",
431 "Content-Type: application/octet-stream",
432 "Content-Length: 2097152"};
433 std::vector<std::string> results;
437 BOOST_REQUIRE_EQUAL(results.size(), 1);
444 std::string objectPath = basePath +
"objectETag";
446 TH1F h1(
"objectETag",
"objectETag", 100, 0, 99);
447 f.api.storeAsTFile(&h1, objectPath,
f.metadata);
451 std::vector<std::string> headers;
452 std::vector<std::string> pfns;
456 BOOST_REQUIRE(headers.size() != 0);
458 BOOST_REQUIRE(
etag !=
"");
459 BOOST_REQUIRE(pfns.size());
468 TH1F h1(
"object1",
"object1", 100, 0, 99);
469 cout <<
"storing object 1 in " << basePath <<
"Test" << endl;
470 std::map<std::string, std::string> metadata;
471 metadata[
"custom"] =
"whatever";
472 f.api.storeAsTFile(&h1, basePath +
"Test", metadata);
474 std::map<std::string, std::string> headers =
f.api.retrieveHeaders(basePath +
"Test", metadata);
475 BOOST_CHECK_NE(headers.size(), 0);
476 std::string
h = headers[
"custom"];
480 for (
auto h : headers) {
481 cout <<
i++ <<
" : " <<
h.first <<
" -> " <<
h.second << endl;
484 headers =
f.api.retrieveHeaders(basePath +
"Test", metadata);
485 BOOST_CHECK_NE(headers.size(), 0);
486 h = headers[
"custom"];
489 metadata[
"custom"] =
"something";
490 headers =
f.api.retrieveHeaders(basePath +
"Test", metadata);
493 for (
auto h : headers) {
494 cout <<
i++ <<
" : " <<
h.first <<
" -> " <<
h.second << endl;
504 TH1F h1(
"object1",
"object1", 100, 0, 99);
505 cout <<
"storing object 1 in " << basePath <<
"Test" << endl;
506 std::map<std::string, std::string> metadata;
507 metadata[
"custom"] =
"whatever";
508 metadata[
"id"] =
"first";
509 f.api.storeAsTFile(&h1, basePath +
"Test", metadata);
512 std::map<std::string, std::string> headers =
f.api.retrieveHeaders(basePath +
"Test", metadata);
515 std::string firstID = headers.at(
"ETag");
516 firstID.erase(std::remove(firstID.begin(), firstID.end(),
'"'), firstID.end());
518 std::map<std::string, std::string> newMetadata;
519 newMetadata[
"custom"] =
"somethingelse";
523 headers =
f.api.retrieveHeaders(basePath +
"Test", newMetadata);
525 BOOST_CHECK(headers.at(
"custom") ==
"somethingelse");
528 cout <<
"storing object 2 in " << basePath <<
"Test" << endl;
530 metadata[
"custom"] =
"whatever";
531 metadata[
"id"] =
"second";
532 f.api.storeAsTFile(&h1, basePath +
"Test", metadata);
535 cout <<
"get id" << endl;
536 headers =
f.api.retrieveHeaders(basePath +
"Test", metadata);
537 std::string secondID = headers.at(
"ETag");
538 secondID.erase(std::remove(secondID.begin(), secondID.end(),
'"'), secondID.end());
541 cout <<
"update the metadata by id" << endl;
543 newMetadata[
"custom"] =
"first";
546 newMetadata[
"custom"] =
"second";
551 metadata[
"id"] =
"first";
552 headers =
f.api.retrieveHeaders(basePath +
"Test", metadata);
556 metadata[
"id"] =
"second";
557 headers =
f.api.retrieveHeaders(basePath +
"Test", metadata);
566 std::map<std::string, std::string> metadata;
567 std::map<std::string, std::string> headers;
569 std::string
url =
"Analysis/ALICE3/Centrality";
579 int TEST_SAMPLE_SIZE = 5;
580 std::vector<o2::pmr::vector<char>> dests(TEST_SAMPLE_SIZE);
581 std::vector<std::map<std::string, std::string>> metadatas(TEST_SAMPLE_SIZE);
582 std::vector<std::map<std::string, std::string>> headers(TEST_SAMPLE_SIZE);
584 std::vector<CcdbApi::RequestContext> contexts;
585 for (
int i = 0;
i < TEST_SAMPLE_SIZE;
i++) {
587 contexts.at(
i).path =
"Analysis/ALICE3/Centrality";
588 contexts.at(
i).timestamp = 1645780010602;
589 contexts.at(
i).considerSnapshot =
true;
594 for (
auto context : contexts) {
603 BOOST_CHECK_EXCEPTION(api.
init(
url), invalid_argument, [](std::invalid_argument
const&) ->
bool { return true; });
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error s
Class for time synchronization of RawReader instances.
void init(std::string const &hosts)
bool isHostReachable() const
void loadFileToMemory(std::vector< char > &dest, std::string const &path, std::map< std::string, std::string > const &metadata, long timestamp, std::map< std::string, std::string > *headers, std::string const &etag, const std::string &createdNotAfter, const std::string &createdNotBefore, bool considerSnapshot=true) const
void vectoredLoadFileToMemory(std::vector< RequestContext > &requestContext) const
static bool getCCDBEntryHeaders(std::string const &url, std::string const &etag, std::vector< std::string > &headers, const std::string &agentID="")
void truncate(std::string const &path) const
static void parseCCDBHeaders(std::vector< std::string > const &headers, std::vector< std::string > &pfns, std::string &etag)
const TString & getPathString() const
GLsizei const GLchar *const * path
GLboolean GLboolean GLboolean GLboolean a
information complementary to a CCDB object (path, metadata, startTimeValidity, endTimeValidity etc)
long getCurrentTimestamp()
returns the timestamp in long corresponding to "now"
long getFutureTimestamp(int secondsInFuture)
returns the timestamp in long corresponding to "now + secondsInFuture"
std::vector< T, fair::mq::pmr::polymorphic_allocator< T > > vector
std::string to_string(gsl::span< T, Size > span)
tt::assertion_result operator()(utf::test_unit_id)
static std::string concat_string(Ts const &... ts)
static std::string create_unique_path(const std::string_view prefix="", int length=16)
std::map< std::string, std::string > metadata
void countItems(const std::string &s, int &countObjects, int &countSubfolders)
BOOST_AUTO_TEST_CASE(storeTMemFile_test, *utf::precondition(if_reachable()))
BOOST_GLOBAL_FIXTURE(Fixture)
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))
BOOST_CHECK_EQUAL(triggersD.size(), triggers.size())