Skip to content

Commit 3b9d809

Browse files
authored
Add possibility to verify commit hash from metadata
1 parent 3e05f1f commit 3b9d809

File tree

3 files changed

+152
-0
lines changed

3 files changed

+152
-0
lines changed

Common/Core/MetadataHelper.cxx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#include <Framework/InitContext.h>
2222
#include <Framework/Logger.h>
2323

24+
#include <TSystem.h>
25+
2426
#include <array>
2527
#include <string>
2628

@@ -140,3 +142,30 @@ std::string MetadataHelper::makeMetadataLabel() const
140142
}
141143
return label;
142144
}
145+
146+
std::string MetadataHelper::getO2Version() const
147+
{
148+
if (!mIsInitialized) {
149+
LOG(fatal) << "Metadata not initialized";
150+
}
151+
return get("O2Version");
152+
}
153+
154+
bool MetadataHelper::isCommitInSoftwareTag(const std::string& commitHash, const std::string & ccdbUrl) const
155+
{
156+
const std::string softwareTag = getO2Version();
157+
std::string command = "curl -i -L ";
158+
command += ccdbUrl;
159+
command += "O2Version/CommitHash/";
160+
command += commitHash;
161+
command += "/-1/";
162+
command += "O2Version=" + softwareTag;
163+
command += " 2>&1 | grep --text O2Version:";
164+
// LOG(info) << "Command to check if commit " << commitHash << " is in software tag " << softwareTag << ": " << command;
165+
TString res = gSystem->GetFromPipe(command.c_str());
166+
if (res.Contains(Form("O2Version: %s", softwareTag.c_str()))) {
167+
LOG(debug) << "Commit " << commitHash << " is contained in software tag " << softwareTag;
168+
return true;
169+
}
170+
return false;
171+
}

Common/Core/MetadataHelper.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,21 @@ struct MetadataHelper {
5151
/// @return true if the data has been initialized, false otherwise
5252
bool isInitialized() const;
5353

54+
/// @brief Function to get the O2 version from the metadata in the monalisa format
55+
/// @return the O2 version from the metadata
56+
std::string getO2Version() const;
57+
5458
/// @brief Function to get the metadata value for a given key
5559
/// @param key the key of the metadata
5660
/// @return the value of the metadata. Throws an exception if the key is not found
5761
std::string get(const std::string& key) const;
5862

63+
/// @brief Function to set a metadata key to a given value
64+
/// @param key the key of the metadata
65+
/// @param value the value to set
66+
/// Note: this function does not check if the key is valid
67+
void set(const std::string& key, const std::string& value) { mMetadata[key] = value; }
68+
5969
/// @brief Function to check if a key is defined in the metadata
6070
/// @param key the key to check
6171
/// @return true if the key is defined, false otherwise. Throws an exception if the key is not found
@@ -64,6 +74,11 @@ struct MetadataHelper {
6474
/// @brief Function to create a label with the metadata information, useful e.g. for histogram naming
6575
std::string makeMetadataLabel() const;
6676

77+
/// Function to check if a commit is included in the software tag
78+
/// @param commitHash the commit hash to check
79+
/// @return true if the commit is included in the software tag, false otherwise
80+
bool isCommitInSoftwareTag(const std::string& commitHash, const std::string& ccdbUrl = "http://ccdb-test.cern.ch:8080/") const;
81+
6782
private:
6883
std::map<std::string, std::string> mMetadata; /// < The metadata map
6984
bool mIsInitialized = false; /// < Flag to check if the metadata has been initialized

Common/Core/macros/testMetadataHelper.C

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "Common/Core/MetadataHelper.h"
1717

18+
#include <CCDB/CcdbApi.h>
1819
#include <Framework/ConfigContext.h>
1920
#include <Framework/ConfigParamRegistry.h>
2021
#include <Framework/ConfigParamStore.h>
@@ -24,6 +25,7 @@
2425
#include <TFile.h>
2526
#include <TMap.h>
2627
#include <TObjString.h>
28+
#include <TSystem.h>
2729

2830
#include <memory>
2931
#include <string>
@@ -57,8 +59,97 @@ auto readMetadata(std::unique_ptr<TFile>& currentFile) -> std::vector<o2::framew
5759
return results;
5860
}
5961

62+
// Create a file with all the versions of the O2 software with alienv q
63+
void createO2VersionFile()
64+
{
65+
// Can do this only if on lxplus
66+
std::string host = gSystem->HostName() ? gSystem->HostName() : "";
67+
if (host.find("lxplus") == std::string::npos) {
68+
LOG(warn) << "Not on lxplus (" << host << "); skipping creation of /tmp/o2version.txt";
69+
return;
70+
}
71+
// If file exists, do nothing
72+
std::ifstream infile("/tmp/o2version.txt");
73+
if (infile.is_open()) {
74+
return;
75+
}
76+
gSystem->Exec("alienv q | grep VO_ALICE@O2:: > /tmp/o2version.txt");
77+
}
78+
79+
std::map<std::string, bool> buildMapForCommitHash(const std::string& hash)
80+
{
81+
// Change directory to /tmp
82+
std::map<std::string, bool> results;
83+
std::ifstream infileO2Versions("/tmp/o2version.txt");
84+
std::string lineOfO2Version;
85+
const std::string fileContainingCommit = "/tmp/branches_" + hash + ".txt";
86+
std::ifstream infileO2VersionsWithHash(fileContainingCommit);
87+
if (!infileO2VersionsWithHash.is_open()) {
88+
gSystem->cd("/tmp/");
89+
gSystem->Exec("git clone git@github.com:AliceO2Group/AliceO2.git");
90+
gSystem->cd("AliceO2");
91+
std::string cmd = Form("git branch -r --contains %s > %s 2>&1", hash.c_str(), fileContainingCommit.c_str());
92+
LOG(info) << "Executing command " << cmd;
93+
gSystem->Exec(cmd.c_str());
94+
}
95+
std::string lineOfO2VersionsWithHash;
96+
while (std::getline(infileO2Versions, lineOfO2Version)) {
97+
std::string tag = lineOfO2Version.substr(lineOfO2Version.find("O2::") + 4);
98+
// Strip a trailing "-1" (some alienv entries append this)
99+
if (tag.size() >= 2 && tag.compare(tag.size() - 2, 2, "-1") == 0) {
100+
tag.resize(tag.size() - 2);
101+
}
102+
LOG(debug) << "Checking tag '" << lineOfO2Version << "' tag (" << tag << ")";
103+
bool found = false;
104+
infileO2VersionsWithHash.open(fileContainingCommit);
105+
while (std::getline(infileO2VersionsWithHash, lineOfO2VersionsWithHash)) {
106+
// LOG(info) << "Comparing " << lineOfO2Version << " with " << lineOfO2VersionsWithHash;
107+
if (lineOfO2VersionsWithHash.find(tag) != std::string::npos) {
108+
LOG(info) << "Tag " << tag << " contains hash " << hash;
109+
found = true;
110+
break;
111+
}
112+
}
113+
infileO2VersionsWithHash.close();
114+
results[tag] = found;
115+
}
116+
return results;
117+
}
118+
119+
void populateCCDBWithCommitAvailability(std::map<string, bool> hasHashMap,
120+
const std::string commitHash)
121+
{
122+
// First, init the CCDB manager to test if the ccdb is already populated
123+
o2::ccdb::CcdbApi api;
124+
api.init("http://ccdb-test.cern.ch:8080/");
125+
if (!api.isHostReachable()) {
126+
LOG(fatal) << "CCDB host http://ccdb-test.cern.ch:8080/ is not reacheable, cannot go forward";
127+
}
128+
for (const auto& entry : hasHashMap) {
129+
if (!entry.second) { // Version of the code does not have the hash
130+
continue;
131+
}
132+
LOG(info) << "Populating CCDB with information that commit hash " << commitHash << " is contained in software tag " << entry.first;
133+
std::map<std::string, std::string> metadata;
134+
metadata["O2Version"] = entry.first;
135+
const std::string ccdbPath = "O2Version/CommitHash/" + commitHash;
136+
auto headers = api.retrieveHeaders(ccdbPath, metadata, -1);
137+
if (headers.size() != 0) {
138+
LOG(info) << "Entry in CCDB already present for commit hash " << commitHash << ", skipping creation";
139+
continue;
140+
}
141+
LOG(info) << "No entry in CCDB for commit hash " << commitHash << ", creating it";
142+
std::string s = "available";
143+
api.storeAsTFileAny<std::string>(&s, ccdbPath, metadata);
144+
}
145+
}
146+
60147
void testMetadataHelper(std::string aod = "/tmp/AO2D.root")
61148
{
149+
createO2VersionFile();
150+
const std::string commitHash = "63bc2e3893851ef0f849bb4c98c65eae1ba21e47";
151+
const std::map<std::string, bool> hasHashMap = buildMapForCommitHash(commitHash);
152+
populateCCDBWithCommitAvailability(hasHashMap, commitHash);
62153

63154
TFile* file = TFile::Open(aod.c_str());
64155
if (!file || file->IsZombie()) {
@@ -79,6 +170,23 @@ void testMetadataHelper(std::string aod = "/tmp/AO2D.root")
79170
aodCfg.options().get<std::string>("aod-metadata-DataType");
80171
o2::common::core::MetadataHelper metadataInfo;
81172
metadataInfo.initMetadata(aodCfg);
173+
metadataInfo.set("O2Version", "epn-20250715"); // Override the O2 version to a known one
82174
metadataInfo.print();
83175
LOG(info) << "Metadata label: " << metadataInfo.makeMetadataLabel();
176+
177+
// Check if the hash is in the software tag
178+
const std::string v = metadataInfo.getO2Version();
179+
if (hasHashMap.find(v) == hasHashMap.end()) {
180+
LOG(fatal) << "Software tag " << v << " not found in available O2 versions";
181+
}
182+
if (hasHashMap.at(v)) {
183+
LOG(info) << "Hash " << commitHash << " is contained in software tag " << v;
184+
} else {
185+
LOG(warn) << "Hash " << commitHash << " is NOT contained in software tag " << v;
186+
}
187+
if (metadataInfo.isCommitInSoftwareTag(commitHash)) {
188+
LOG(info) << "MetadataHelper confirms that hash " << commitHash << " is contained in software tag " << v;
189+
} else {
190+
LOG(warn) << "MetadataHelper confirms that hash " << commitHash << " is NOT contained in software tag " << v;
191+
}
84192
}

0 commit comments

Comments
 (0)