diff --git a/Common/Core/MetadataHelper.cxx b/Common/Core/MetadataHelper.cxx index b025c5df7a1..70af2dbec2b 100644 --- a/Common/Core/MetadataHelper.cxx +++ b/Common/Core/MetadataHelper.cxx @@ -21,6 +21,8 @@ #include #include +#include + #include #include @@ -140,3 +142,31 @@ std::string MetadataHelper::makeMetadataLabel() const } return label; } + +std::string MetadataHelper::getO2Version() const +{ + if (!mIsInitialized) { + LOG(warning) << "Metadata not initialized"; + return "undefined"; + } + return get("O2Version"); +} + +bool MetadataHelper::isCommitInSoftwareTag(const std::string& commitHash, const std::string& ccdbUrl) const +{ + const std::string softwareTag = getO2Version(); + std::string command = "curl -i -L "; + command += ccdbUrl; + command += "O2Version/CommitHash/"; + command += commitHash; + command += "/-1/"; + command += "O2Version=" + softwareTag; + command += " 2>&1 | grep --text O2Version:"; + // LOG(info) << "Command to check if commit " << commitHash << " is in software tag " << softwareTag << ": " << command; + TString res = gSystem->GetFromPipe(command.c_str()); + if (res.Contains(Form("O2Version: %s", softwareTag.c_str()))) { + LOG(debug) << "Commit " << commitHash << " is contained in software tag " << softwareTag; + return true; + } + return false; +} diff --git a/Common/Core/MetadataHelper.h b/Common/Core/MetadataHelper.h index 3854820bd84..7b871084f9a 100644 --- a/Common/Core/MetadataHelper.h +++ b/Common/Core/MetadataHelper.h @@ -51,11 +51,21 @@ struct MetadataHelper { /// @return true if the data has been initialized, false otherwise bool isInitialized() const; + /// @brief Function to get the O2 version from the metadata in the monalisa format + /// @return the O2 version from the metadata + std::string getO2Version() const; + /// @brief Function to get the metadata value for a given key /// @param key the key of the metadata /// @return the value of the metadata. Throws an exception if the key is not found std::string get(const std::string& key) const; + /// @brief Function to set a metadata key to a given value + /// @param key the key of the metadata + /// @param value the value to set + /// Note: this function does not check if the key is valid + void set(const std::string& key, const std::string& value) { mMetadata[key] = value; } + /// @brief Function to check if a key is defined in the metadata /// @param key the key to check /// @return true if the key is defined, false otherwise. Throws an exception if the key is not found @@ -64,6 +74,11 @@ struct MetadataHelper { /// @brief Function to create a label with the metadata information, useful e.g. for histogram naming std::string makeMetadataLabel() const; + /// Function to check if a commit is included in the software tag + /// @param commitHash the commit hash to check + /// @return true if the commit is included in the software tag, false otherwise + bool isCommitInSoftwareTag(const std::string& commitHash, const std::string& ccdbUrl = "http://ccdb-test.cern.ch:8080/") const; + private: std::map mMetadata; /// < The metadata map bool mIsInitialized = false; /// < Flag to check if the metadata has been initialized diff --git a/Common/Core/macros/testMetadataHelper.C b/Common/Core/macros/testMetadataHelper.C index 30c109f7840..27371aaf0e3 100644 --- a/Common/Core/macros/testMetadataHelper.C +++ b/Common/Core/macros/testMetadataHelper.C @@ -15,6 +15,7 @@ #include "Common/Core/MetadataHelper.h" +#include #include #include #include @@ -24,7 +25,9 @@ #include #include #include +#include +#include #include #include #include @@ -57,8 +60,100 @@ auto readMetadata(std::unique_ptr& currentFile) -> std::vectorHostName() ? gSystem->HostName() : ""; + if (host.find("lxplus") == std::string::npos) { + LOG(warn) << "Not on lxplus (" << host << "); skipping creation of /tmp/o2version.txt"; + return; + } + // If file exists, do nothing + std::ifstream infile("/tmp/o2version.txt"); + if (infile.is_open()) { + return; + } + gSystem->Exec("alienv q | grep VO_ALICE@O2:: > /tmp/o2version.txt"); +} + +std::map buildMapForCommitHash(const std::string& hash) +{ + // Change directory to /tmp + std::map results; + std::ifstream infileO2Versions("/tmp/o2version.txt"); + std::string lineOfO2Version; + const std::string fileContainingCommit = "/tmp/branches_" + hash + ".txt"; + std::ifstream infileO2VersionsWithHash(fileContainingCommit); + if (!infileO2VersionsWithHash.is_open()) { + gSystem->cd("/tmp/"); + gSystem->Exec("git clone git@github.com:AliceO2Group/AliceO2.git"); + gSystem->cd("AliceO2"); + std::string cmd = Form("git branch -r --contains %s > %s 2>&1", hash.c_str(), fileContainingCommit.c_str()); + LOG(info) << "Executing command " << cmd; + gSystem->Exec(cmd.c_str()); + } + std::string lineOfO2VersionsWithHash; + while (std::getline(infileO2Versions, lineOfO2Version)) { + // Extract the tag + int stripSize = 4; + std::string tag = lineOfO2Version.substr(lineOfO2Version.find("O2::") + stripSize); + // Strip a trailing "-1" (some alienv entries append this) + stripSize = 2; + if (tag.size() >= stripSize && tag.compare(tag.size() - stripSize, stripSize, "-1") == 0) { + tag.resize(tag.size() - stripSize); + } + LOG(debug) << "Checking tag '" << lineOfO2Version << "' tag (" << tag << ")"; + bool found = false; + infileO2VersionsWithHash.open(fileContainingCommit); + while (std::getline(infileO2VersionsWithHash, lineOfO2VersionsWithHash)) { + // LOG(info) << "Comparing " << lineOfO2Version << " with " << lineOfO2VersionsWithHash; + if (lineOfO2VersionsWithHash.find(tag) != std::string::npos) { + LOG(info) << "Tag " << tag << " contains hash " << hash; + found = true; + break; + } + } + infileO2VersionsWithHash.close(); + results[tag] = found; + } + return results; +} + +void populateCCDBWithCommitAvailability(std::map hasHashMap, + const std::string commitHash const std::string ccdbUrl = "http://ccdb-test.cern.ch:8080/") +{ + // First, init the CCDB manager to test if the ccdb is already populated + o2::ccdb::CcdbApi api; + api.init(ccdbUrl); + if (!api.isHostReachable()) { + LOG(fatal) << "CCDB host " << ccdbUrl << " is not reacheable, cannot go forward"; + } + for (const auto& entry : hasHashMap) { + if (!entry.second) { // Version of the code does not have the hash + continue; + } + LOG(info) << "Populating CCDB with information that commit hash " << commitHash << " is contained in software tag " << entry.first; + std::map metadata; + metadata["O2Version"] = entry.first; + const std::string ccdbPath = "O2Version/CommitHash/" + commitHash; + auto headers = api.retrieveHeaders(ccdbPath, metadata, -1); + if (headers.size() != 0) { + LOG(info) << "Entry in CCDB already present for commit hash " << commitHash << ", skipping creation"; + continue; + } + LOG(info) << "No entry in CCDB for commit hash " << commitHash << ", creating it"; + std::string s = "available"; + api.storeAsTFileAny(&s, ccdbPath, metadata); + } +} + void testMetadataHelper(std::string aod = "/tmp/AO2D.root") { + createO2VersionFile(); + const std::string commitHash = "63bc2e3893851ef0f849bb4c98c65eae1ba21e47"; + const std::map hasHashMap = buildMapForCommitHash(commitHash); + populateCCDBWithCommitAvailability(hasHashMap, commitHash); TFile* file = TFile::Open(aod.c_str()); if (!file || file->IsZombie()) { @@ -79,6 +174,23 @@ void testMetadataHelper(std::string aod = "/tmp/AO2D.root") aodCfg.options().get("aod-metadata-DataType"); o2::common::core::MetadataHelper metadataInfo; metadataInfo.initMetadata(aodCfg); + metadataInfo.set("O2Version", "epn-20250715"); // Override the O2 version to a known one metadataInfo.print(); LOG(info) << "Metadata label: " << metadataInfo.makeMetadataLabel(); + + // Check if the hash is in the software tag + const std::string v = metadataInfo.getO2Version(); + if (hasHashMap.find(v) == hasHashMap.end()) { + LOG(fatal) << "Software tag " << v << " not found in available O2 versions"; + } + if (hasHashMap.at(v)) { + LOG(info) << "Hash " << commitHash << " is contained in software tag " << v; + } else { + LOG(warn) << "Hash " << commitHash << " is NOT contained in software tag " << v; + } + if (metadataInfo.isCommitInSoftwareTag(commitHash)) { + LOG(info) << "MetadataHelper confirms that hash " << commitHash << " is contained in software tag " << v; + } else { + LOG(warn) << "MetadataHelper confirms that hash " << commitHash << " is NOT contained in software tag " << v; + } }