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>
32#include <TStreamerInfo.h>
38#include <boost/property_tree/json_parser.hpp>
39#include <boost/property_tree/ptree.hpp>
40#include <boost/foreach.hpp>
41#include <boost/optional/optional.hpp>
45namespace utf = boost::unit_test;
49static string basePath;
59 ccdbUrl =
"http://ccdb-test.cern.ch:8080";
61 cout <<
"ccdb url: " <<
ccdbUrl << endl;
64 char hostname[_POSIX_HOST_NAME_MAX];
65 gethostname(hostname, _POSIX_HOST_NAME_MAX);
66 basePath =
string(
"Test/TestCcdbApi/") + hostname +
"/pid" + getpid() +
"/";
68 std::replace(basePath.begin(), basePath.end(),
'-',
'_');
69 cout <<
"Path we will use in this test suite : " + basePath << endl;
75 map<string, string> metadata;
78 cout <<
"Test data truncated (" << basePath <<
")" << endl;
102 std::cout <<
"*** " << boost::unit_test::framework::current_test_case().p_name <<
" ***" << std::endl;
114 TH1F h1(
"th1name",
"th1name", 100, 0, 99);
115 h1.FillRandom(
"gaus", 10000);
117 cout << basePath +
"th1" << endl;
118 f.api.storeAsTFile(&h1, basePath +
"th1",
f.metadata);
121 graph.SetPoint(0, 2, 3);
122 f.api.storeAsTFile(&graph, basePath +
"graph",
f.metadata);
124 TTree
tree(
"mytree",
"mytree");
126 tree.Branch(
"det", &
a,
"a/I");
128 f.api.storeAsTFile(&
tree, basePath +
"tree",
f.metadata);
138 path.setPath(
"HelloWorld");
140 f.api.storeAsTFileAny(&
path, basePath +
"CCDBPath",
f.metadata);
146 path2 =
f.api.retrieveFromTFileAny<
o2::ccdb::IdPath>(basePath +
"CCDBPath",
f.metadata);
147 BOOST_CHECK_NE(path2,
nullptr);
156 map<string, string> md;
157 path2 =
f.api.retrieveFromTFileAny<
o2::ccdb::IdPath>(basePath +
"CCDBPath",
f.metadata, -1, &md);
164 auto tree =
new TTree(
"tree123",
"tree123");
166 tree->Branch(
"det", &
a,
"a/I");
168 f.api.storeAsTFileAny(
tree, basePath +
"tree2",
f.metadata);
172 tree =
f.api.retrieveFromTFileAny<TTree>(basePath +
"tree2",
f.metadata);
183 std::filesystem::create_directories(ph);
184 std::cout <<
"Creating snapshot at " << ph <<
"\n";
186 std::cout <<
"Creating snapshot at " << ph <<
"\n";
196 auto tree = snapshot.retrieveFromTFileAny<TTree>(basePath +
"tree2",
f.metadata);
203 if (std::filesystem::exists(ph)) {
204 std::filesystem::remove_all(ph);
215 path.setPath(
"HelloWorld");
217 int result =
f.api.storeAsTFileAny(&
path, basePath +
"CCDBPath",
f.metadata);
219 result =
f.api.storeAsTFileAny(&
path, basePath +
"CCDBPath",
f.metadata, -1, -1, 1 );
231 path.setPath(
"HelloWorld");
233 const long timestamp = 1000;
234 const long endvalidity = timestamp + 10;
235 f.api.storeAsTFileAny(&
path, basePath +
"CCDBPathUnitTest",
f.metadata, timestamp, endvalidity);
241 path2 =
f.api.retrieveFromTFileAny<
o2::ccdb::IdPath>(basePath +
"CCDBPathUnitTest",
f.metadata, timestamp);
242 BOOST_CHECK_NE(path2,
nullptr);
245 for (
int t = timestamp; t < endvalidity; ++t) {
246 auto p =
f.api.retrieveFromTFileAny<
o2::ccdb::IdPath>(basePath +
"CCDBPathUnitTest",
f.metadata, t);
247 BOOST_CHECK_NE(p,
nullptr);
251 auto plower =
f.api.retrieveFromTFileAny<
o2::ccdb::IdPath>(basePath +
"CCDBPathUnitTest",
f.metadata, timestamp - 1);
254 auto pupper =
f.api.retrieveFromTFileAny<
o2::ccdb::IdPath>(basePath +
"CCDBPathUnitTest",
f.metadata, endvalidity);
264 path.setPath(
"HelloWorld");
267 f.api.storeAsTFileAny(&
path, basePath +
"CCDBPathUnitTest",
f.metadata, from, to);
270 std::map<std::string, std::string> headers;
271 std::map<std::string, std::string> meta;
272 cout <<
"basePath + \"CCDBPathUnitTest\" : " << basePath +
"CCDBPathUnitTest" << endl;
273 cout <<
"from+1 : " << from + 1 << endl;
274 auto*
object =
f.api.retrieveFromTFileAny<
o2::ccdb::IdPath>(basePath +
"CCDBPathUnitTest", meta, from + 1, &headers);
283 TObject* obj =
f.api.retrieveFromTFileAny<
TObject>(basePath +
"th1",
f.metadata);
284 BOOST_CHECK_NE(obj,
nullptr);
286 auto h1 =
dynamic_cast<TH1F*
>(obj);
287 BOOST_CHECK_NE(h1,
nullptr);
291 obj =
f.api.retrieveFromTFileAny<
TObject>(basePath +
"graph",
f.metadata);
292 BOOST_CHECK_NE(obj,
nullptr);
294 auto graph =
dynamic_cast<TGraph*
>(obj);
295 BOOST_CHECK_NE(graph,
nullptr);
297 int ret = graph->GetPoint(0,
x,
y);
303 std::map<std::string, std::string> headers;
304 obj =
f.api.retrieveFromTFileAny<
TObject>(basePath +
"tree",
f.metadata, -1, &headers);
305 BOOST_CHECK_NE(obj,
nullptr);
307 auto tree =
dynamic_cast<TTree*
>(obj);
308 BOOST_CHECK_NE(
tree,
nullptr);
316 obj =
f.api.retrieveFromTFileAny<
TObject>(
"Wrong/wrong",
f.metadata);
324 TH1F
h(
"object1",
"object1", 100, 0, 99);
325 f.api.storeAsTFile(&
h, basePath +
"Detector",
f.metadata);
326 auto h1 =
f.api.retrieveFromTFileAny<TH1F>(basePath +
"Detector",
f.metadata);
328 f.api.truncate(basePath +
"Detector");
329 h1 =
f.api.retrieveFromTFileAny<TH1F>(basePath +
"Detector",
f.metadata);
337 TH1F h1(
"object1",
"object1", 100, 0, 99);
340 f.api.storeAsTFile(&h1, basePath +
"Detector",
f.metadata, from, to);
341 auto h2 =
f.api.retrieveFromTFileAny<TH1F>(basePath +
"Detector",
f.metadata);
343 f.api.deleteObject(basePath +
"Detector");
344 h2 =
f.api.retrieveFromTFileAny<TH1F>(basePath +
"Detector",
f.metadata);
348void countItems(
const string& s,
int& countObjects,
int& countSubfolders)
352 std::stringstream ss(s);
354 boost::property_tree::ptree pt;
355 boost::property_tree::read_json(ss, pt);
357 if (pt.count(
"objects") > 0) {
358 countObjects = pt.get_child(
"objects").size();
361 if (pt.count(
"subfolders") > 0) {
362 countSubfolders = pt.get_child(
"subfolders").size();
371 string s =
f.api.list(
"",
"application/json");
372 long nbLines = std::count(s.begin(), s.end(),
'\n') + 1;
376 f.api.truncate(basePath +
"Detector*");
377 s =
f.api.list(basePath +
"Detector",
false,
"application/json");
378 int countObjects = 0;
379 int countSubfolders = 0;
384 TH1F h1(
"object1",
"object1", 100, 0, 99);
385 cout <<
"storing object 2 in Test/Detector" << endl;
386 f.api.storeAsTFile(&h1, basePath +
"Detector",
f.metadata);
387 cout <<
"storing object 3 in Test/Detector" << endl;
388 f.api.storeAsTFile(&h1, basePath +
"Detector",
f.metadata);
389 cout <<
"storing object 4 in Test/Detector" << endl;
390 f.api.storeAsTFile(&h1, basePath +
"Detector",
f.metadata);
391 cout <<
"storing object 5 in Test/Detector/Sub/abc" << endl;
392 f.api.storeAsTFile(&h1, basePath +
"Detector/Sub/abc",
f.metadata);
394 s =
f.api.list(basePath +
"Detector",
false,
"application/json");
399 s =
f.api.list(basePath +
"Detector*",
false,
"application/json");
404 s =
f.api.list(basePath +
"Detector",
true,
"application/json");
411 std::vector<std::string> headers = {
413 "Content-Location: /download/6dcb77c0-ca56-11e9-a807-200114580202",
414 "Date: Thu, 26 Sep 2019 08:09:20 GMT",
415 "Valid-Until: 1567771311999",
416 "Valid-From: 1567080816927",
417 "InitialValidityLimit: 1598616816927",
418 "Created: 1567080816956",
419 "ETag: \"6dcb77c0-ca56-11e9-a807-200114580202\"",
420 "Last-Modified: Thu, 29 Aug 2019 12:13:36 GMT",
421 "UpdatedFrom: 2001:1458:202:28:0:0:100:35",
423 "Content-Disposition: inline;filename=\"o2::dataformats::CalibLHCphaseTOF_1567080816916.root\"",
424 "Accept-Ranges: bytes",
425 "Content-MD5: 9481c9d036660f80e21dae5943c2096f",
426 "Content-Type: application/octet-stream",
427 "Content-Length: 2097152"};
428 std::vector<std::string> results;
432 BOOST_REQUIRE_EQUAL(results.size(), 1);
439 string objectPath = basePath +
"objectETag";
441 TH1F h1(
"objectETag",
"objectETag", 100, 0, 99);
442 f.api.storeAsTFile(&h1, objectPath,
f.metadata);
446 std::vector<std::string> headers;
447 std::vector<std::string> pfns;
451 BOOST_REQUIRE(headers.size() != 0);
453 BOOST_REQUIRE(etag !=
"");
454 BOOST_REQUIRE(pfns.size());
463 TH1F h1(
"object1",
"object1", 100, 0, 99);
464 cout <<
"storing object 1 in " << basePath <<
"Test" << endl;
465 map<string, string> metadata;
466 metadata[
"custom"] =
"whatever";
467 f.api.storeAsTFile(&h1, basePath +
"Test", metadata);
469 std::map<std::string, std::string> headers =
f.api.retrieveHeaders(basePath +
"Test", metadata);
470 BOOST_CHECK_NE(headers.size(), 0);
471 std::string
h = headers[
"custom"];
475 for (
auto h : headers) {
476 cout <<
i++ <<
" : " <<
h.first <<
" -> " <<
h.second << endl;
479 headers =
f.api.retrieveHeaders(basePath +
"Test", metadata);
480 BOOST_CHECK_NE(headers.size(), 0);
481 h = headers[
"custom"];
484 metadata[
"custom"] =
"something";
485 headers =
f.api.retrieveHeaders(basePath +
"Test", metadata);
488 for (
auto h : headers) {
489 cout <<
i++ <<
" : " <<
h.first <<
" -> " <<
h.second << endl;
499 TH1F h1(
"object1",
"object1", 100, 0, 99);
500 cout <<
"storing object 1 in " << basePath <<
"Test" << endl;
501 map<string, string> metadata;
502 metadata[
"custom"] =
"whatever";
503 metadata[
"id"] =
"first";
504 f.api.storeAsTFile(&h1, basePath +
"Test", metadata);
507 std::map<std::string, std::string> headers =
f.api.retrieveHeaders(basePath +
"Test", metadata);
510 string firstID = headers.at(
"ETag");
511 firstID.erase(std::remove(firstID.begin(), firstID.end(),
'"'), firstID.end());
513 map<string, string> newMetadata;
514 newMetadata[
"custom"] =
"somethingelse";
518 headers =
f.api.retrieveHeaders(basePath +
"Test", newMetadata);
520 BOOST_CHECK(headers.at(
"custom") ==
"somethingelse");
523 cout <<
"storing object 2 in " << basePath <<
"Test" << endl;
525 metadata[
"custom"] =
"whatever";
526 metadata[
"id"] =
"second";
527 f.api.storeAsTFile(&h1, basePath +
"Test", metadata);
530 cout <<
"get id" << endl;
531 headers =
f.api.retrieveHeaders(basePath +
"Test", metadata);
532 string secondID = headers.at(
"ETag");
533 secondID.erase(std::remove(secondID.begin(), secondID.end(),
'"'), secondID.end());
536 cout <<
"update the metadata by id" << endl;
538 newMetadata[
"custom"] =
"first";
541 newMetadata[
"custom"] =
"second";
546 metadata[
"id"] =
"first";
547 headers =
f.api.retrieveHeaders(basePath +
"Test", metadata);
551 metadata[
"id"] =
"second";
552 headers =
f.api.retrieveHeaders(basePath +
"Test", metadata);
560 api.
init(
"http://bogus-host.cern.ch,http://ccdb-test.cern.ch:8080");
561 std::map<std::string, std::string> metadata;
562 std::map<std::string, std::string> headers;
564 std::string url =
"Analysis/ALICE3/Centrality";
572 api.
init(
"http://ccdb-test.cern.ch:8080");
574 int TEST_SAMPLE_SIZE = 5;
575 std::vector<o2::pmr::vector<char>> dests(TEST_SAMPLE_SIZE);
576 std::vector<std::map<std::string, std::string>> metadatas(TEST_SAMPLE_SIZE);
577 std::vector<std::map<std::string, std::string>> headers(TEST_SAMPLE_SIZE);
579 std::vector<CcdbApi::RequestContext> contexts;
580 for (
int i = 0;
i < TEST_SAMPLE_SIZE;
i++) {
582 contexts.at(
i).path =
"Analysis/ALICE3/Centrality";
583 contexts.at(
i).timestamp = 1645780010602;
584 contexts.at(
i).considerSnapshot =
true;
589 for (
auto context : contexts) {
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 * string
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, o2::pmr::polymorphic_allocator< T > > vector
Defining DataPointCompositeObject explicitly as copiable.
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)
map< string, string > metadata
BOOST_AUTO_TEST_CASE(storeTMemFile_test, *utf::precondition(if_reachable()))
BOOST_GLOBAL_FIXTURE(Fixture)
void countItems(const string &s, int &countObjects, int &countSubfolders)
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))
BOOST_CHECK_EQUAL(triggersD.size(), triggers.size())