diff --git a/Database/IOVDbSvc/CMakeLists.txt b/Database/IOVDbSvc/CMakeLists.txt index 4f0099f8451511920377f5b98f7a30e5f81c82cd..8409c53db5efb96b17d3036939817f38184b9992 100644 --- a/Database/IOVDbSvc/CMakeLists.txt +++ b/Database/IOVDbSvc/CMakeLists.txt @@ -49,3 +49,12 @@ atlas_add_component( IOVDbSvc # Install files from the package: atlas_install_python_modules( python/*.py ) atlas_install_joboptions( share/*.py ) + + +atlas_add_test( IOVDbSvc_test + SOURCES + test/IOVDbSvc_test.cxx + INCLUDE_DIRS ${COOL_INCLUDE_DIRS} + LINK_LIBRARIES AthenaBaseComps AthenaKernel SGTools StoreGateLib SGtests GaudiKernel TestTools EventInfo IOVSvcLib xAODEventInfo PersistentDataModel ${COOL_LIBRARIES} + EXTRA_PATTERNS "^HistogramPersis.* INFO|^IOVSvc +DEBUG|^IOVSvcTool +DEBUG" + ENVIRONMENT "JOBOPTSEARCHPATH=${CMAKE_CURRENT_SOURCE_DIR}/share" ) diff --git a/Database/IOVDbSvc/python/CondDB.py b/Database/IOVDbSvc/python/CondDB.py index 75b18dbd12708d28d7aea1da52e40b80f2563e0f..e9d3d2e23714857ac37a647fea9d2044af975495 100644 --- a/Database/IOVDbSvc/python/CondDB.py +++ b/Database/IOVDbSvc/python/CondDB.py @@ -1,4 +1,4 @@ -# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +# Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration # CondDB.py # Configuration for Athena conditions DB access @@ -203,8 +203,12 @@ class CondDB: self.msg.debug("Loading basic services for CondDBSetup... [DONE]") def addFolder(self,ident,folder,force=False,forceMC=False,forceData=False, - className=None): - "Add access to the given folder, in the identified subdetector schema" + className=None,extensible=False): + """Add access to the given folder, in the identified subdetector schema. +If EXTENSIBLE is set, then if we access an open-ended IOV at the end of the list, +the end time for this range will be set to just past the current event. +Subsequent accesses will update this end time for subsequent events. +This allows the possibility of later adding a new IOV using IOVSvc::setRange.""" # first check if access to this folder was blocked, unless forcing for block in self.blocklist: if (folder.find(block)>=0 and force==False): return @@ -219,6 +223,9 @@ class CondDB: folderadd='<db>sqlite://;schema=%s;dbname=%s</db> %s' % (ident,self._GetName(forceMC,forceData),folder) else: raise RuntimeError("Conditions database identifier %s is not defined" % ident) + if extensible: + folderadd = folderadd + '<extensible/>' + self.iovdbsvc.Folders+=[folderadd] if className: diff --git a/Database/IOVDbSvc/python/IOVDbSvcConfig.py b/Database/IOVDbSvc/python/IOVDbSvcConfig.py index 328a9b39e3f1e33c6d9eefb712721b5954a0e55e..1882f05c1eb5963aac46e417986643c102365677 100644 --- a/Database/IOVDbSvc/python/IOVDbSvcConfig.py +++ b/Database/IOVDbSvc/python/IOVDbSvcConfig.py @@ -1,4 +1,4 @@ -# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +# Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator, ConfigurationError from IOVSvc.IOVSvcConf import CondInputLoader @@ -77,9 +77,14 @@ def IOVDbSvcCfg(configFlags): #Convenience method to add folders: -def addFolders(configFlags,folderstrings,detDb=None,className=None): +def addFolders(configFlags,folderstrings,detDb=None,className=None,extensible=False): + """Add access to the given set of folders, in the identified subdetector schema. +If EXTENSIBLE is set, then if we access an open-ended IOV at the end of the list, +the end time for this range will be set to just past the current event. +Subsequent accesses will update this end time for subsequent events. +This allows the possibility of later adding a new IOV using IOVSvc::setRange.""" - #Convenince hack: Allow a single string as parameter: + #Convenience hack: Allow a single string as parameter: if isinstance(folderstrings,str): folderstrings=[folderstrings,] @@ -110,6 +115,8 @@ def addFolders(configFlags,folderstrings,detDb=None,className=None): for fs in folderstrings: + if extensible: + fs = fs + '<extensible/>' if fs.find("<db>")==-1: iovDbSvc.Folders.append(fs+dbstr) else: diff --git a/Database/IOVDbSvc/share/IOVDbSvc_test.ref b/Database/IOVDbSvc/share/IOVDbSvc_test.ref new file mode 100644 index 0000000000000000000000000000000000000000..64a1c3298599c1d079babf731d5b301744d475e5 --- /dev/null +++ b/Database/IOVDbSvc/share/IOVDbSvc_test.ref @@ -0,0 +1,49 @@ +IOVDbSvc_test + + +Initializing Gaudi ApplicationMgr using job opts ../share/IOVDbSvc_test.txt +JobOptionsSvc INFO # =======> /afs/cern.ch/work/s/ssnyder/builds/atlas-work3/build-x86_64-slc6-gcc62-dbg/Database/IOVDbSvc/unitTestRun/../share/IOVDbSvc_test.txt +JobOptionsSvc INFO # (1,1): ApplicationMgr.CreateSvc += ["StoreGateSvc/DetectorStore"] +JobOptionsSvc INFO # (2,1): IOVDbSvc.Folders = ["/key1", "/key2<extensible/>"] +JobOptionsSvc INFO # (3,1): EventPersistencySvc.CnvServices += ["AthenaPoolCnvSvc"] +JobOptionsSvc INFO Job options successfully read in from ../share/IOVDbSvc_test.txt +ApplicationMgr SUCCESS +==================================================================================================================================== + Welcome to ApplicationMgr (GaudiCoreSvc v30r4) + running on lxplus051.cern.ch on Sat Nov 10 04:16:03 2018 +==================================================================================================================================== +ApplicationMgr INFO Application Manager Configured successfully +ClassIDSvc INFO getRegistryEntries: read 642 CLIDRegistry entries for module ALL +EventLoopMgr WARNING Unable to locate service "EventSelector" +EventLoopMgr WARNING No events will be processed from external input. +HistogramPersis...WARNING Histograms saving not required. +ApplicationMgr INFO Application Manager Initialized successfully +ApplicationMgr Ready +PoolSvc INFO io_register[PoolSvc](xmlcatalog_file:PoolFileCatalog.xml) [ok] +PoolSvc INFO Set connectionsvc retry/timeout/IDLE timeout to 'ConnectionRetrialPeriod':300/ 'ConnectionRetrialTimeOut':3600/ 'ConnectionTimeOut':5 seconds with connection cleanup disabled +PoolSvc INFO Frontier compression level set to 5 +DBReplicaSvc INFO Frontier server at (serverurl=http://atlasfrontier-local.cern.ch:8000/atlr)(serverurl=http://atlasfrontier-ai.cern.ch:8000/atlr)(serverurl=http://lcgft-atlas.gridpp.rl.ac.uk:3128/frontierATLAS)(serverurl=http://ccfrontier.in2p3.fr:23128/ccin2p3-AtlasFrontier)(proxyurl=http://ca-proxy.cern.ch:3128)(proxyurl=http://ca-proxy-meyrin.cern.ch:3128)(proxyurl=http://ca-proxy-wigner.cern.ch:3128)(proxyurl=http://atlasbpfrontier.cern.ch:3127)(proxyurl=http://atlasbpfrontier.fnal.gov:3127) will be considered for COOL data +DBReplicaSvc INFO Read replica configuration from /cvmfs/atlas-nightlies.cern.ch/repo/sw/master/2018-11-08T2259/Athena/22.0.1/InstallArea/x86_64-slc6-gcc62-dbg/share/dbreplica.config +DBReplicaSvc INFO Total of 10 servers found for host lxplus051.cern.ch [ATLF ATLAS_COOLPROD atlas_dd ATLAS_CONFIG INT8R INTR ATONR_COOL ATONR_CONF DEVDB11 ATLF ] +PoolSvc INFO Successfully setup replica sorting algorithm +PoolSvc INFO Setting up APR FileCatalog and Streams +PoolSvc INFO POOL WriteCatalog is xmlcatalog_file:PoolFileCatalog.xml +DbSession INFO Open DbSession +Domain[ROOT_All] INFO > Access DbDomain READ [ROOT_All] +IOVDbSvc INFO Opened read transaction for POOL PersistencySvc +IOVDbSvc INFO Only 5 POOL conditions files will be open at once +IOVDbSvc INFO Extensible folder /key2 +IOVDbSvc INFO Initialised with 1 connections and 2 folders +IOVDbSvc INFO Service IOVDbSvc initialised successfully +IOVDbSvc INFO Opening COOL connection for sqlite://;schema=cooldummy.db;dbname=OFLP200 +IOVSvc INFO No IOVSvcTool associated with store "StoreGateSvc" +IOVSvcTool INFO IOVRanges will be checked at every Event +IOVDbSvc INFO Disconnecting from sqlite://;schema=cooldummy.db;dbname=OFLP200 +test1 +IOVDbSvc INFO Opening COOL connection for sqlite://;schema=cooldummy.db;dbname=OFLP200 +IOVDbSvc INFO Disconnecting from sqlite://;schema=cooldummy.db;dbname=OFLP200 +AthenaPoolCnvSvc INFO Initializing AthenaPoolCnvSvc - package version AthenaPoolCnvSvc-00-00-00 +EventPersistenc... INFO Added successfully Conversion service:AthenaPoolCnvSvc +IOVDbSvc INFO Increase cache length (step 1) for folder /key2 to 8589934590 at validityKey 85899345935 +IOVDbSvc INFO Opening COOL connection for sqlite://;schema=cooldummy.db;dbname=OFLP200 +IOVDbSvc INFO Disconnecting from sqlite://;schema=cooldummy.db;dbname=OFLP200 diff --git a/Database/IOVDbSvc/share/IOVDbSvc_test.txt b/Database/IOVDbSvc/share/IOVDbSvc_test.txt new file mode 100644 index 0000000000000000000000000000000000000000..16d0366b1a795add21841623765d5a335fbb4f4e --- /dev/null +++ b/Database/IOVDbSvc/share/IOVDbSvc_test.txt @@ -0,0 +1,3 @@ +ApplicationMgr.CreateSvc += { "StoreGateSvc/DetectorStore" }; +IOVDbSvc.Folders = { "/key1", "/key2<extensible/>" }; +EventPersistencySvc.CnvServices += { "AthenaPoolCnvSvc" }; diff --git a/Database/IOVDbSvc/src/IOVDbFolder.cxx b/Database/IOVDbSvc/src/IOVDbFolder.cxx index 19c6b63cefab7983a1a02347c37d975941438b89..64dd3acdfaac95b93826f218a9d09ff88b91df65 100644 --- a/Database/IOVDbSvc/src/IOVDbFolder.cxx +++ b/Database/IOVDbSvc/src/IOVDbFolder.cxx @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration */ // IOVDbFolder.cxx - helper class for IOVDbSvc to manage folder & data cache @@ -67,6 +67,7 @@ IOVDbFolder::IOVDbFolder(IOVDbConn* conn, m_notagoverride(false), m_writemeta(false), m_fromMetaDataOnly(false), + m_extensible(false), m_named(false), m_iovoverridden(false), m_jokey(false), @@ -196,6 +197,11 @@ IOVDbFolder::IOVDbFolder(IOVDbConn* conn, if (m_fromMetaDataOnly) { *m_log << MSG::INFO << "Read from meta data only for folder " << m_foldername << endmsg; } + + m_extensible=folderprop.getKey("extensible","",buf); + if (m_extensible) { + *m_log << MSG::INFO << "Extensible folder " << m_foldername << endmsg; + } } IOVDbFolder::~IOVDbFolder() { diff --git a/Database/IOVDbSvc/src/IOVDbFolder.h b/Database/IOVDbSvc/src/IOVDbFolder.h index c87c903cb1fdc6d90669be7c75dacbfcd99f2030..f423451f389c91616256952a98faeec086fe140b 100644 --- a/Database/IOVDbSvc/src/IOVDbFolder.h +++ b/Database/IOVDbSvc/src/IOVDbFolder.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration */ // IOVDbFolder.h @@ -61,6 +61,10 @@ public: bool writeMeta() const; // read from meta data only, otherwise ignore folder bool fromMetaDataOnly() const; + // If true, then the end time for an open-ended range will be set to just + // past the current event. The end time will be automatically updated on accesses + // in subsequent events. + bool extensible() const; bool dropped() const; const std::string& joTag() const; const std::string& resolvedTag() const; @@ -174,6 +178,7 @@ private: bool m_notagoverride;// tag must not be overridden from input file bool m_writemeta; // is writing to metadata bool m_fromMetaDataOnly; // to be read from metadata only + bool m_extensible; // xxx bool m_named; // folder has named channels bool m_iovoverridden;// folder has IOV override bool m_jokey; // folder has non-default key from joboptions @@ -260,6 +265,8 @@ inline bool IOVDbFolder::writeMeta() const { return m_writemeta; } inline bool IOVDbFolder::fromMetaDataOnly() const { return m_fromMetaDataOnly; } +inline bool IOVDbFolder::extensible() const { return m_extensible; } + inline bool IOVDbFolder::dropped() const { return m_dropped; } inline const std::string& IOVDbFolder::joTag() const { return m_jotag; } diff --git a/Database/IOVDbSvc/src/IOVDbSvc.cxx b/Database/IOVDbSvc/src/IOVDbSvc.cxx index f8e4f09ea9321cfc90e4847f09685eb61e1f883f..9136b1230040dbf77328bd00dbb018bbf10373ca 100644 --- a/Database/IOVDbSvc/src/IOVDbSvc.cxx +++ b/Database/IOVDbSvc/src/IOVDbSvc.cxx @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration */ // IOVDbSvc.cxx @@ -53,6 +53,26 @@ namespace { } +namespace { + + +/** + * @brief Helper to check if a range is open-ended. + */ +bool isOpenEnded (const IOVRange& range, bool isTimeStamp) +{ + if (isTimeStamp) { + return range.stop().timestamp() >= IOVTime::MAXTIMESTAMP; + } + else { + return range.stop().re_time() >= IOVTime::MAXRETIME; + } +} + + +} // anonymous namespace + + IOVDbSvc::IOVDbSvc( const std::string& name, ISvcLocator* svc ) : AthService( name, svc ), m_par_defaultConnection("sqlite://;schema=cooldummy.db;dbname=OFLP200"), @@ -671,6 +691,18 @@ StatusCode IOVDbSvc::getRange( const CLID& clid, // range=IOVRange(IOVTime(start),range.stop()); // } + // Special handling for open-ended ranges in extensible folders: + if (folder->extensible() && isOpenEnded (range, folder->timeStamp())) { + // Set the end time to just past the current event. + IOVTime extStop = range.stop(); + if (folder->timeStamp()) { + extStop.setTimestamp (time.timestamp() + 1); + } + else { + extStop.setRETime (time.re_time() + 1); + } + range = IOVRange (range.start(), extStop); + } diff --git a/Database/IOVDbSvc/test/IOVDbSvc_test.cxx b/Database/IOVDbSvc/test/IOVDbSvc_test.cxx new file mode 100644 index 0000000000000000000000000000000000000000..a213adb00e9a2c6dea8c1447b21a78f670765e5e --- /dev/null +++ b/Database/IOVDbSvc/test/IOVDbSvc_test.cxx @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration. + */ +/** + * @file IOVDbSvc/test/IOVDbSvc_test.cxx + * @author scott snyder <snyder@bnl.gov> + * @date Oct, 2018 + * @brief Some tests for IOVDbSvc. Not complete! + */ + + +#undef NDEBUG +#include "TestTools/initGaudi.h" +#include "AthenaKernel/IIOVDbSvc.h" +#include "AthenaKernel/IOVTime.h" +#include "AthenaKernel/IOVRange.h" +#include "AthenaKernel/IAddressProvider.h" +#include "CxxUtils/ubsan_suppress.h" +#include "CoolApplication/DatabaseSvcFactory.h" +#include "CoolKernel/pointers.h" +#include "CoolKernel/IDatabaseSvc.h" +#include "CoolKernel/IDatabase.h" +#include "CoolKernel/FolderSpecification.h" +#include "CoolKernel/Record.h" +#include "CoolKernel/IFolder.h" +#include "GaudiKernel/ServiceHandle.h" +#include "TInterpreter.h" +#include <cassert> +#include <iostream> + + +void test1 (IIOVDbSvc& iovdbsvc) +{ + std::cout << "test1\n"; + + IOVRange range; + std::string tag; + IOpaqueAddress* addr = nullptr; + assert( iovdbsvc.getRange (1238547719, "/key1", IOVTime (10, 15), + range, tag, addr).isSuccess() ); + assert (std::string(range) == "{[10,10] - [10,20]}"); + + assert( iovdbsvc.getRange (1238547719, "/key1", IOVTime (10, 35), + range, tag, addr).isSuccess() ); + assert (std::string(range) == "{[10,30] - [2147483647,4294967295]}"); + + assert( iovdbsvc.getRange (1238547719, "/key2", IOVTime (20, 15), + range, tag, addr).isSuccess() ); + assert (std::string(range) == "{[20,10] - [20,20]}"); + + assert( iovdbsvc.getRange (1238547719, "/key2", IOVTime (20, 35), + range, tag, addr).isSuccess() ); + assert (std::string(range) == "{[20,30] - [20,36]}"); +} + + +int main() +{ + std::cout << "IOVDbSvc_test\n"; + + CxxUtils::ubsan_suppress ([]() { TInterpreter::Instance(); } ); + ISvcLocator* svcLoc; + if (!Athena_test::initGaudi("IOVDbSvc_test.txt", svcLoc)) + return 1; + + unlink ("cooldummy.db"); + + cool::IDatabaseSvc& dbSvc=cool::DatabaseSvcFactory::databaseService(); + cool::IDatabasePtr coolDb = + dbSvc.createDatabase("sqlite://;schema=cooldummy.db;dbname=OFLP200"); + cool::RecordSpecification spec; + spec.extend ("int", cool::StorageType::Int32); + cool::FolderSpecification fSpec (cool::FolderVersioning::SINGLE_VERSION, + spec, + cool::PayloadMode::INLINEPAYLOAD); + std::string desc = "<timeStamp>run-event</timeStamp><addrHeader><address_header service_type=\"71\" clid=\"1238547719\" /></addrHeader><typeName>CondAttrListCollection</typeName>"; + + { + cool::IFolderPtr f = coolDb->createFolder ("/key1", fSpec, desc); + cool::Record payload (f->payloadSpecification()); + payload[0].setValue (1); + f->storeObject ((10ull<<32) + 10, (10ull<<32) + 20, payload, 0); + payload[0].setValue (2); + f->storeObject ((10ull<<32) + 30, cool::ValidityKeyMax, payload, 0); + } + { + cool::IFolderPtr f = coolDb->createFolder ("/key2", fSpec, desc); + cool::Record payload (f->payloadSpecification()); + payload[0].setValue (11); + f->storeObject ((20ull<<32) + 10, (20ull<<32) + 20, payload, 0); + payload[0].setValue (12); + f->storeObject ((20ull<<32) + 30, cool::ValidityKeyMax, payload, 0); + } + coolDb->closeDatabase(); + + ServiceHandle<IIOVDbSvc> iovdbsvc ("IOVDbSvc", "test"); + if (iovdbsvc.retrieve().isFailure()) return 1; + + IAddressProvider* iovdbsvc_ap = dynamic_cast<IAddressProvider*> (iovdbsvc.get()); + IAddressProvider::tadList tlist; + assert( iovdbsvc_ap->preLoadAddresses (StoreID::DETECTOR_STORE, tlist).isSuccess() ); + + test1 (*iovdbsvc); + + return 0; +}