Skip to content

Commit 2a1015d

Browse files
committed
DPL CCDB: adapt to newly introduced helper.
The new helper is a bit more generic and can be used for also for the case where we multiplex multiple CCDB object on top of the same output, like we do in analysis.
1 parent 5b2351f commit 2a1015d

File tree

3 files changed

+70
-142
lines changed

3 files changed

+70
-142
lines changed

Framework/CCDBSupport/CMakeLists.txt

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,13 @@ o2_add_library(FrameworkCCDBSupport
1717
PRIVATE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/src
1818
PUBLIC_LINK_LIBRARIES O2::Framework O2::CCDB)
1919

20-
o2_add_test(CCDBHelpers NAME test_Framework_test_CCDBHelpers
21-
SOURCES test/test_CCDBHelpers.cxx
22-
COMPONENT_NAME Framework
23-
LABELS framework
24-
PUBLIC_LINK_LIBRARIES O2::Framework O2::FrameworkCCDBSupport)
20+
add_executable(o2-test-framework-ccdbsupport
21+
test/test_CCDBHelpers.cxx)
22+
target_link_libraries(o2-test-framework-ccdbsupport PRIVATE O2::Framework)
23+
target_link_libraries(o2-test-framework-ccdbsupport PRIVATE O2::FrameworkCCDBSupport)
24+
target_link_libraries(o2-test-framework-ccdbsupport PRIVATE O2::Catch2)
25+
26+
get_filename_component(outdir ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/../tests ABSOLUTE)
27+
set_property(TARGET o2-test-framework-ccdbsupport PROPERTY RUNTIME_OUTPUT_DIRECTORY ${outdir})
28+
29+
add_test(NAME framework:ccdbsupport COMMAND o2-test-framework-ccdbsupport --skip-benchmarks)

Framework/CCDBSupport/src/CCDBHelpers.cxx

Lines changed: 36 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -23,121 +23,19 @@
2323
#include "Framework/Signpost.h"
2424
#include <TError.h>
2525
#include <TMemFile.h>
26+
#include <ctime>
2627

2728
O2_DECLARE_DYNAMIC_LOG(ccdb);
2829

2930
namespace o2::framework
3031
{
3132

32-
bool isPrefix(std::string_view prefix, std::string_view full)
33-
{
34-
return prefix == full.substr(0, prefix.size());
35-
}
36-
37-
CCDBHelpers::ParserResult CCDBHelpers::parseRemappings(char const* str)
38-
{
39-
std::unordered_map<std::string, std::string> remappings;
40-
std::string currentUrl = "";
41-
42-
enum ParsingStates {
43-
IN_BEGIN,
44-
IN_BEGIN_URL,
45-
IN_BEGIN_TARGET,
46-
IN_END_TARGET,
47-
IN_END_URL
48-
};
49-
ParsingStates state = IN_BEGIN;
50-
51-
while (true) {
52-
switch (state) {
53-
case IN_BEGIN: {
54-
if (*str == 0) {
55-
return {remappings, ""};
56-
}
57-
state = IN_BEGIN_URL;
58-
}
59-
case IN_BEGIN_URL: {
60-
if ((strncmp("http://", str, 7) != 0) && (strncmp("https://", str, 8) != 0 && (strncmp("file://", str, 7) != 0))) {
61-
return {remappings, "URL should start with either http:// or https:// or file://"};
62-
}
63-
state = IN_END_URL;
64-
} break;
65-
case IN_END_URL: {
66-
char const* c = strchr(str, '=');
67-
if (c == nullptr) {
68-
return {remappings, "Expecting at least one target path, missing `='?"};
69-
}
70-
if ((c - str) == 0) {
71-
return {remappings, "Empty url"};
72-
}
73-
currentUrl = std::string_view(str, c - str);
74-
state = IN_BEGIN_TARGET;
75-
str = c + 1;
76-
} break;
77-
case IN_BEGIN_TARGET: {
78-
if (*str == 0) {
79-
return {remappings, "Empty target"};
80-
}
81-
state = IN_END_TARGET;
82-
} break;
83-
case IN_END_TARGET: {
84-
char const* c = strpbrk(str, ",;");
85-
if (c == nullptr) {
86-
if (remappings.count(str)) {
87-
return {remappings, fmt::format("Path {} requested more than once.", str)};
88-
}
89-
remappings[std::string(str)] = currentUrl;
90-
return {remappings, ""};
91-
}
92-
if ((c - str) == 0) {
93-
return {remappings, "Empty target"};
94-
}
95-
auto key = std::string(str, c - str);
96-
if (remappings.count(str)) {
97-
return {remappings, fmt::format("Path {} requested more than once.", key)};
98-
}
99-
remappings[key] = currentUrl;
100-
if (*c == ';') {
101-
state = IN_BEGIN_URL;
102-
} else {
103-
state = IN_BEGIN_TARGET;
104-
}
105-
str = c + 1;
106-
} break;
107-
}
108-
}
109-
}
110-
111-
void initialiseHelper(CCDBFetcherHelper& helper, ConfigParamRegistry const& options, std::vector<o2::framework::OutputRoute> const& outputRoutes)
112-
{
33+
// Fill valid routes. Here we consider only the routes which have
34+
// Lifetime::Condition. Notice the way we do it for analysis will be
35+
// different.
36+
namespace {
37+
void fillValidRoutes(CCDBFetcherHelper& helper, std::vector<o2::framework::OutputRoute> const& outputRoutes) {
11338
std::unordered_map<std::string, bool> accountedSpecs;
114-
auto defHost = options.get<std::string>("condition-backend");
115-
auto checkRate = options.get<int>("condition-tf-per-query");
116-
auto checkMult = options.get<int>("condition-tf-per-query-multiplier");
117-
helper.timeToleranceMS = options.get<int64_t>("condition-time-tolerance");
118-
helper.queryPeriodGlo = checkRate > 0 ? checkRate : std::numeric_limits<int>::max();
119-
helper.queryPeriodFactor = checkMult > 0 ? checkMult : 1;
120-
LOGP(info, "CCDB Backend at: {}, validity check for every {} TF{}", defHost, helper.queryPeriodGlo, helper.queryPeriodFactor == 1 ? std::string{} : fmt::format(", (query for high-rate objects downscaled by {})", helper.queryPeriodFactor));
121-
LOGP(info, "Hook to enable signposts for CCDB messages at {}", (void*)&private_o2_log_ccdb->stacktrace);
122-
auto remapString = options.get<std::string>("condition-remap");
123-
CCDBHelpers::ParserResult result = CCDBHelpers::parseRemappings(remapString.c_str());
124-
if (!result.error.empty()) {
125-
throw runtime_error_f("Error while parsing remapping string %s", result.error.c_str());
126-
}
127-
helper.remappings = result.remappings;
128-
helper.apis[""].init(defHost); // default backend
129-
LOGP(info, "Initialised default CCDB host {}", defHost);
130-
//
131-
for (auto& entry : helper.remappings) { // init api instances for every host seen in the remapping
132-
if (helper.apis.find(entry.second) == helper.apis.end()) {
133-
helper.apis[entry.second].init(entry.second);
134-
LOGP(info, "Initialised custom CCDB host {}", entry.second);
135-
}
136-
LOGP(info, "{} is remapped to {}", entry.first, entry.second);
137-
}
138-
helper.createdNotBefore = std::to_string(options.get<int64_t>("condition-not-before"));
139-
helper.createdNotAfter = std::to_string(options.get<int64_t>("condition-not-after"));
140-
14139
for (auto& route : outputRoutes) {
14240
if (route.matcher.lifetime != Lifetime::Condition) {
14341
continue;
@@ -156,6 +54,7 @@ void initialiseHelper(CCDBFetcherHelper& helper, ConfigParamRegistry const& opti
15654
}
15755
}
15856
}
57+
}
15958

16059
auto getOrbitResetTime(o2::pmr::vector<char> const& v) -> Long64_t
16160
{
@@ -180,7 +79,8 @@ AlgorithmSpec CCDBHelpers::fetchFromCCDB()
18079
{
18180
return adaptStateful([](CallbackService& callbacks, ConfigParamRegistry const& options, DeviceSpec const& spec) {
18281
std::shared_ptr<CCDBFetcherHelper> helper = std::make_shared<CCDBFetcherHelper>();
183-
initialiseHelper(*helper, options, spec.outputs);
82+
CCDBFetcherHelper::initialiseHelper(*helper, options);
83+
fillValidRoutes(*helper, spec.outputs);
18484
/// Add a callback on stop which dumps the statistics for the caching per
18585
/// path
18686
callbacks.set<CallbackService::Id::Stop>([helper]() {
@@ -279,6 +179,33 @@ AlgorithmSpec CCDBHelpers::fetchFromCCDB()
279179
// Fetch the rest of the objects.
280180
O2_SIGNPOST_EVENT_EMIT(ccdb, sid, "fetchFromCCDB", "Fetching objects. Run %{public}s. OrbitResetTime %lld. Creation %lld. Timestamp %lld. firstTForbit %" PRIu32,
281181
dtc.runNumber.data(), orbitResetTime, timingInfo.creation, timestamp, timingInfo.firstTForbit);
182+
std::vector<CCDBFetcherHelper::FetchOp> ops;
183+
int runNumber = 0;
184+
std::string ccdbMetadataPrefix = "ccdb-metadata-";
185+
for (auto &route : helper->routes) {
186+
CCDBFetcherHelper::FetchOp op{.spec = route.matcher, .timestamp = timestamp, .runNumber = std::stoi(dtc.runNumber)};
187+
for (auto& meta : route.matcher.metadata) {
188+
if (meta.name == "ccdb-path") {
189+
op.url = meta.defaultValue.get<std::string>();
190+
} else if (meta.name == "ccdb-run-dependent" && meta.defaultValue.get<int>() > 0) {
191+
if (meta.defaultValue.get<int>() == 1) {
192+
op.runNumber = runNumber;
193+
} else if (meta.defaultValue.get<int>() == 2) {
194+
op.timestamp = runNumber;
195+
} else {
196+
LOGP(fatal, "Undefined ccdb-run-dependent option {} for spec {}", meta.defaultValue.get<int>(), DataSpecUtils::describe(route.matcher));
197+
}
198+
} else if (meta.name.starts_with(ccdbMetadataPrefix)) {
199+
std::string key = meta.name.substr(ccdbMetadataPrefix.size());
200+
auto value = meta.defaultValue.get<std::string>();
201+
O2_SIGNPOST_EVENT_EMIT(ccdb, sid, "populateCacheWith", "Adding metadata %{public}s: %{public}s to the request", key.data(), value.data());
202+
op.metadata.push_back({key, value});
203+
} else if (meta.name == "ccdb-query-rate") {
204+
op.queryRate = meta.defaultValue.get<int>() * helper->queryPeriodFactor;
205+
}
206+
}
207+
ops.push_back(op);
208+
}
282209

283210
CCDBFetcherHelper::populateCacheWith(helper, ops, timingInfo, dtc, allocator);
284211
O2_SIGNPOST_END(ccdb, _o2_signpost_id_t{(int64_t)timingInfo.timeslice}, "fetchFromCCDB", "Fetching CCDB objects");

Framework/CCDBSupport/test/test_CCDBHelpers.cxx

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,43 +9,39 @@
99
// granted to it by virtue of its status as an Intergovernmental Organization
1010
// or submit itself to any jurisdiction.
1111

12-
#define BOOST_TEST_MODULE Test Framework CCDBHelpers
13-
#define BOOST_TEST_MAIN
14-
#define BOOST_TEST_DYN_LINK
15-
16-
#include <boost/test/unit_test.hpp>
17-
#include "../src/CCDBHelpers.h"
12+
#include <catch_amalgamated.hpp>
13+
#include "../src/CCDBFetcherHelper.h"
1814

1915
using namespace o2::framework;
2016

21-
BOOST_AUTO_TEST_CASE(TestSorting)
17+
TEST_CASE("TestSorting")
2218
{
23-
auto result = CCDBHelpers::parseRemappings("");
24-
BOOST_CHECK_EQUAL(result.error, ""); // not an error
19+
auto result = CCDBFetcherHelper::parseRemappings("");
20+
CHECK(result.error == ""); // not an error
2521

26-
result = CCDBHelpers::parseRemappings("https");
27-
BOOST_CHECK_EQUAL(result.error, "URL should start with either http:// or https:// or file://");
22+
result = CCDBFetcherHelper::parseRemappings("https");
23+
CHECK(result.error == "URL should start with either http:// or https:// or file://");
2824

29-
result = CCDBHelpers::parseRemappings("https://alice.cern.ch:8000");
30-
BOOST_CHECK_EQUAL(result.error, "Expecting at least one target path, missing `='?");
25+
result = CCDBFetcherHelper::parseRemappings("https://alice.cern.ch:8000");
26+
CHECK(result.error == "Expecting at least one target path, missing `='?");
3127

32-
result = CCDBHelpers::parseRemappings("https://alice.cern.ch:8000=");
33-
BOOST_CHECK_EQUAL(result.error, "Empty target");
28+
result = CCDBFetcherHelper::parseRemappings("https://alice.cern.ch:8000=");
29+
CHECK(result.error == "Empty target");
3430

35-
result = CCDBHelpers::parseRemappings("https://alice.cern.ch:8000=/foo/bar,");
36-
BOOST_CHECK_EQUAL(result.error, "Empty target");
31+
result = CCDBFetcherHelper::parseRemappings("https://alice.cern.ch:8000=/foo/bar,");
32+
CHECK(result.error == "Empty target");
3733

38-
result = CCDBHelpers::parseRemappings("https://alice.cern.ch:8000=/foo/bar,/foo/bar;");
39-
BOOST_CHECK_EQUAL(result.error, "URL should start with either http:// or https:// or file://");
34+
result = CCDBFetcherHelper::parseRemappings("https://alice.cern.ch:8000=/foo/bar,/foo/bar;");
35+
CHECK(result.error == "URL should start with either http:// or https:// or file://");
4036

41-
result = CCDBHelpers::parseRemappings("https://alice.cern.ch:8000=/foo/bar,/foo/barbar;file://user/test=/foo/barr");
42-
BOOST_CHECK_EQUAL(result.error, "");
43-
BOOST_CHECK_EQUAL(result.remappings.size(), 3);
44-
BOOST_CHECK_EQUAL(result.remappings["/foo/bar"], "https://alice.cern.ch:8000");
45-
BOOST_CHECK_EQUAL(result.remappings["/foo/barbar"], "https://alice.cern.ch:8000");
46-
BOOST_CHECK_EQUAL(result.remappings["/foo/barr"], "file://user/test");
37+
result = CCDBFetcherHelper::parseRemappings("https://alice.cern.ch:8000=/foo/bar,/foo/barbar;file://user/test=/foo/barr");
38+
CHECK(result.error == "");
39+
CHECK(result.remappings.size() == 3);
40+
CHECK(result.remappings["/foo/bar"] == "https://alice.cern.ch:8000");
41+
CHECK(result.remappings["/foo/barbar"] == "https://alice.cern.ch:8000");
42+
CHECK(result.remappings["/foo/barr"] == "file://user/test");
4743

48-
result = CCDBHelpers::parseRemappings("https://alice.cern.ch:8000=/foo/bar;file://user/test=/foo/bar");
49-
BOOST_CHECK_EQUAL(result.remappings.size(), 1);
50-
BOOST_CHECK_EQUAL(result.error, "Path /foo/bar requested more than once.");
44+
result = CCDBFetcherHelper::parseRemappings("https://alice.cern.ch:8000=/foo/bar;file://user/test=/foo/bar");
45+
CHECK(result.remappings.size() == 1);
46+
CHECK(result.error == "Path /foo/bar requested more than once.");
5147
}

0 commit comments

Comments
 (0)