From 26c9420ccf47d8ac2356032b91846929f7b94987 Mon Sep 17 00:00:00 2001 From: scott snyder <scott.snyder@cern.ch> Date: Thu, 20 Apr 2017 18:05:24 +0200 Subject: [PATCH] AthenaBaseComps: Extend algorithm base class to deal with handles to symlinked objects. --- .../AthenaBaseComps/AthAlgorithm.h | 13 ++ .../AthenaBaseComps/AthReentrantAlgorithm.h | 15 +- Control/AthenaBaseComps/CMakeLists.txt | 10 ++ .../share/AthAlgorithmDHUpdate_test.ref | 32 ++++ .../share/AthAlgorithm_test.ref | 33 ++++ Control/AthenaBaseComps/src/AthAlgorithm.cxx | 27 +++ .../src/AthAlgorithmDHUpdate.cxx | 94 ++++++++++ .../src/AthAlgorithmDHUpdate.h | 85 +++++++++ .../src/AthReentrantAlgorithm.cxx | 26 +++ .../test/AthAlgorithmDHUpdate_test.cxx | 164 ++++++++++++++++++ .../test/AthAlgorithm_test.cxx | 131 ++++++++++++++ .../test/AthReentrantAlgorithm_test.cxx | 19 +- 12 files changed, 646 insertions(+), 3 deletions(-) create mode 100644 Control/AthenaBaseComps/share/AthAlgorithmDHUpdate_test.ref create mode 100644 Control/AthenaBaseComps/share/AthAlgorithm_test.ref create mode 100644 Control/AthenaBaseComps/src/AthAlgorithmDHUpdate.cxx create mode 100644 Control/AthenaBaseComps/src/AthAlgorithmDHUpdate.h create mode 100644 Control/AthenaBaseComps/test/AthAlgorithmDHUpdate_test.cxx create mode 100644 Control/AthenaBaseComps/test/AthAlgorithm_test.cxx diff --git a/Control/AthenaBaseComps/AthenaBaseComps/AthAlgorithm.h b/Control/AthenaBaseComps/AthenaBaseComps/AthAlgorithm.h index e79468713bfb..6ca6da831830 100644 --- a/Control/AthenaBaseComps/AthenaBaseComps/AthAlgorithm.h +++ b/Control/AthenaBaseComps/AthenaBaseComps/AthAlgorithm.h @@ -234,6 +234,15 @@ public: } + /** + * @brief Return the list of extra output dependencies. + * + * This list is extended to include symlinks implied by inheritance + * relations. + */ + virtual const DataObjIDColl& extraOutputDeps() const override; + + /////////////////////////////////////////////////////////////////// // Non-const methods: /////////////////////////////////////////////////////////////////// @@ -266,6 +275,10 @@ public: typedef ServiceHandle<IUserDataSvc> UserDataSvc_t; /// Pointer to IUserDataSvc mutable UserDataSvc_t m_userStore; + + /// Extra output dependency collection, extended by AthAlgorithmDHUpdate + /// to add symlinks. Empty if no symlinks were found. + DataObjIDColl m_extendedExtraObjects; }; /////////////////////////////////////////////////////////////////// diff --git a/Control/AthenaBaseComps/AthenaBaseComps/AthReentrantAlgorithm.h b/Control/AthenaBaseComps/AthenaBaseComps/AthReentrantAlgorithm.h index e21626d3e063..0dd08e060b71 100644 --- a/Control/AthenaBaseComps/AthenaBaseComps/AthReentrantAlgorithm.h +++ b/Control/AthenaBaseComps/AthenaBaseComps/AthReentrantAlgorithm.h @@ -281,7 +281,16 @@ public: } - + + /** + * @brief Return the list of extra output dependencies. + * + * This list is extended to include symlinks implied by inheritance + * relations. + */ + virtual const DataObjIDColl& extraOutputDeps() const override; + + /////////////////////////////////////////////////////////////////// // Non-const methods: /////////////////////////////////////////////////////////////////// @@ -314,6 +323,10 @@ public: typedef ServiceHandle<IUserDataSvc> UserDataSvc_t; /// Pointer to IUserDataSvc mutable UserDataSvc_t m_userStore; + + /// Extra output dependency collection, extended by AthAlgorithmDHUpdate + /// to add symlinks. Empty if no symlinks were found. + DataObjIDColl m_extendedExtraObjects; }; /////////////////////////////////////////////////////////////////// diff --git a/Control/AthenaBaseComps/CMakeLists.txt b/Control/AthenaBaseComps/CMakeLists.txt index ece926545de7..fa62f1921cfa 100644 --- a/Control/AthenaBaseComps/CMakeLists.txt +++ b/Control/AthenaBaseComps/CMakeLists.txt @@ -38,3 +38,13 @@ atlas_add_test( AthReentrantAlgorithm_test SOURCES test/AthReentrantAlgorithm_test.cxx LINK_LIBRARIES StoreGateLib GaudiKernel TestTools AthenaBaseComps ENVIRONMENT "JOBOPTSEARCHPATH=${CMAKE_CURRENT_SOURCE_DIR}/share" ) + +atlas_add_test( AthAlgorithm_test + SOURCES test/AthAlgorithm_test.cxx + LINK_LIBRARIES StoreGateLib GaudiKernel TestTools AthenaBaseComps + ENVIRONMENT "JOBOPTSEARCHPATH=${CMAKE_CURRENT_SOURCE_DIR}/share" ) + +atlas_add_test( AthAlgorithmDHUpdate_test + SOURCES test/AthAlgorithmDHUpdate_test.cxx + LINK_LIBRARIES StoreGateLib GaudiKernel TestTools AthenaBaseComps + ENVIRONMENT "JOBOPTSEARCHPATH=${CMAKE_CURRENT_SOURCE_DIR}/share" ) diff --git a/Control/AthenaBaseComps/share/AthAlgorithmDHUpdate_test.ref b/Control/AthenaBaseComps/share/AthAlgorithmDHUpdate_test.ref new file mode 100644 index 000000000000..d535188fd9f8 --- /dev/null +++ b/Control/AthenaBaseComps/share/AthAlgorithmDHUpdate_test.ref @@ -0,0 +1,32 @@ + + +Initializing Gaudi ApplicationMgr using job opts ../share/propertyHandling_test.txt +JobOptionsSvc INFO # =======> /afs/cern.ch/user/s/ssnyder/atlas-work7/Control/AthenaBaseComps/share/../share/propertyHandling_test.txt +JobOptionsSvc INFO # (1,1): alg.rkey = "FooSvc/aaa" +JobOptionsSvc INFO # (2,1): alg.wkey = "BarSvc/bbb" +JobOptionsSvc INFO # (3,1): alg.ukey = "ccc" +JobOptionsSvc INFO # (4,1): alg.rhandle = "FooSvc/ddd" +JobOptionsSvc INFO # (5,1): alg.whandle = "BarSvc/eee" +JobOptionsSvc INFO # (6,1): alg.uhandle = "fff" +JobOptionsSvc INFO # (8,1): tool.rkey = "FooSvc/taa" +JobOptionsSvc INFO # (9,1): tool.wkey = "BarSvc/tbb" +JobOptionsSvc INFO # (10,1): tool.ukey = "tcc" +JobOptionsSvc INFO # (11,1): tool.rhandle = "FooSvc/tdd" +JobOptionsSvc INFO # (12,1): tool.whandle = "BarSvc/tee" +JobOptionsSvc INFO # (13,1): tool.uhandle = "tff" +JobOptionsSvc INFO # (15,1): ralg.rkey = "FooSvc/aaa" +JobOptionsSvc INFO # (16,1): ralg.whandle = "BarSvc/eee" +JobOptionsSvc INFO Job options successfully read in from ../share/propertyHandling_test.txt +ApplicationMgr SUCCESS +==================================================================================================================================== + Welcome to ApplicationMgr (GaudiCoreSvc v28r1) + running on lxplus042.cern.ch on Thu Apr 6 17:12:06 2017 +==================================================================================================================================== +ApplicationMgr INFO Application Manager Configured successfully +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 +test1 +ClassIDSvc INFO getRegistryEntries: read 677 CLIDRegistry entries for module ALL diff --git a/Control/AthenaBaseComps/share/AthAlgorithm_test.ref b/Control/AthenaBaseComps/share/AthAlgorithm_test.ref new file mode 100644 index 000000000000..351f76b87752 --- /dev/null +++ b/Control/AthenaBaseComps/share/AthAlgorithm_test.ref @@ -0,0 +1,33 @@ + + +Initializing Gaudi ApplicationMgr using job opts ../share/propertyHandling_test.txt +JobOptionsSvc INFO # =======> /afs/cern.ch/user/s/ssnyder/atlas-work7/Control/AthenaBaseComps/share/../share/propertyHandling_test.txt +JobOptionsSvc INFO # (1,1): alg.rkey = "FooSvc/aaa" +JobOptionsSvc INFO # (2,1): alg.wkey = "BarSvc/bbb" +JobOptionsSvc INFO # (3,1): alg.ukey = "ccc" +JobOptionsSvc INFO # (4,1): alg.rhandle = "FooSvc/ddd" +JobOptionsSvc INFO # (5,1): alg.whandle = "BarSvc/eee" +JobOptionsSvc INFO # (6,1): alg.uhandle = "fff" +JobOptionsSvc INFO # (8,1): tool.rkey = "FooSvc/taa" +JobOptionsSvc INFO # (9,1): tool.wkey = "BarSvc/tbb" +JobOptionsSvc INFO # (10,1): tool.ukey = "tcc" +JobOptionsSvc INFO # (11,1): tool.rhandle = "FooSvc/tdd" +JobOptionsSvc INFO # (12,1): tool.whandle = "BarSvc/tee" +JobOptionsSvc INFO # (13,1): tool.uhandle = "tff" +JobOptionsSvc INFO # (15,1): ralg.rkey = "FooSvc/aaa" +JobOptionsSvc INFO # (16,1): ralg.whandle = "BarSvc/eee" +JobOptionsSvc INFO Job options successfully read in from ../share/propertyHandling_test.txt +ApplicationMgr SUCCESS +==================================================================================================================================== + Welcome to ApplicationMgr (GaudiCoreSvc v28r1) + running on lxplus042.cern.ch on Thu Apr 6 23:08:52 2017 +==================================================================================================================================== +ApplicationMgr INFO Application Manager Configured successfully +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 +test1 +ClassIDSvc INFO getRegistryEntries: read 727 CLIDRegistry entries for module ALL +ClassIDSvc INFO getRegistryEntries: read 359 CLIDRegistry entries for module ALL diff --git a/Control/AthenaBaseComps/src/AthAlgorithm.cxx b/Control/AthenaBaseComps/src/AthAlgorithm.cxx index e419251f6e8a..35f87bce7e3f 100644 --- a/Control/AthenaBaseComps/src/AthAlgorithm.cxx +++ b/Control/AthenaBaseComps/src/AthAlgorithm.cxx @@ -11,12 +11,14 @@ // AthenaBaseComps includes #include "AthenaBaseComps/AthAlgorithm.h" +#include "AthAlgorithmDHUpdate.h" // STL includes // FrameWork includes #include "GaudiKernel/Property.h" + /////////////////////////////////////////////////////////////////// // Public methods: /////////////////////////////////////////////////////////////////// @@ -61,6 +63,14 @@ AthAlgorithm::AthAlgorithm( const std::string& name, m_userStore = UserDataSvc_t ("UserDataSvc/UserDataSvc", name), "Handle to a UserDataSvc/UserDataSvc instance: it will be used to " "retrieve user data during the course of the job" ); + + // Set up to run AthAlgorithmDHUpdate in sysInitialize before + // merging depedency lists. This extends the output dependency + // list with any symlinks implied by inheritance relations. + m_updateDataHandles = + std::make_unique<AthenaBaseComps::AthAlgorithmDHUpdate> + (m_extendedExtraObjects, + std::move (m_updateDataHandles)); } // Destructor @@ -105,3 +115,20 @@ AthAlgorithm::msg_update_handler( Property& outputLevel ) msg().setLevel( msgLevel() ); } } + + +/** + * @brief Return the list of extra output dependencies. + * + * This list is extended to include symlinks implied by inheritance + * relations. + */ +const DataObjIDColl& AthAlgorithm::extraOutputDeps() const +{ + // If we didn't find any symlinks to add, just return the collection + // from the base class. Otherwise, return the extended collection. + if (!m_extendedExtraObjects.empty()) { + return m_extendedExtraObjects; + } + return Algorithm::extraOutputDeps(); +} diff --git a/Control/AthenaBaseComps/src/AthAlgorithmDHUpdate.cxx b/Control/AthenaBaseComps/src/AthAlgorithmDHUpdate.cxx new file mode 100644 index 000000000000..237817d08657 --- /dev/null +++ b/Control/AthenaBaseComps/src/AthAlgorithmDHUpdate.cxx @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration. + */ +// $Id$ +/** + * @file AthenaBaseComps/src/AthAlgorithmDHUpdate.cxx + * @author scott snyder <snyder@bnl.gov> + * @date Apr, 2017 + * @brief Update output dependencies to include symlinks. + */ + + +#include "AthAlgorithmDHUpdate.h" +#include "SGTools/BaseInfo.h" + + +namespace AthenaBaseComps { + + +/** + * @brief Constructor. + * @param linkedObjs Set to which entries for symlinks will be added. + * @param chain Hook to call after this one completes. + */ +AthAlgorithmDHUpdate::AthAlgorithmDHUpdate (DataObjIDColl& linkedObjs, + std::unique_ptr<IDataHandleVisitor> chain) + : m_linkedObjs (linkedObjs), + m_chain (std::move (chain)) +{ +} + + +/** + * @brief Walk over the dependencies of an algorithm. + * @param dhh The algorithm object. + * + * Finds output dependencies of the algorithms that have symlinks + * available and enters these links in @c linkedObjs. + */ +void AthAlgorithmDHUpdate::visit (const IDataHandleHolder* dhh) +{ + // Make a copy, as usually linkedObjs will be extraOutputDeps(). + DataObjIDColl ex = dhh->extraOutputDeps(); + + // Process all output dependencies. + for (const Gaudi::DataHandle* h : dhh->outputHandles()) { + if (!h->objKey().empty()) + handle (h->fullKey().clid(), h->objKey()); + } + + for (const DataObjID& dobj : ex) { + if (!dobj.key().empty()) + handle (dobj.clid(), dobj.key()); + } + + for (const DataObjID& dobj : dhh->outputDataObjs()) { + if (!dobj.key().empty()) + handle (dobj.clid(), dobj.key()); + } + + // If we put anything in linkedObjs, also add the contents + // of extraOutputDeps. + if (!m_linkedObjs.empty()) { + DataObjIDColl ex = dhh->extraOutputDeps(); + m_linkedObjs.insert (ex.begin(), ex.end()); + } + + // Call the next hook function, if any. + if (m_chain) { + m_chain->visit (dhh); + } +} + + +/** + * @brief Handle one output dependency. + * @param clid The CLID of the output. + * @param key The SG key of the output. + * + * If CLID has symlinks available, enter these links in @c linkedObjs. + */ +void AthAlgorithmDHUpdate::handle (CLID clid, const std::string& key) +{ + const SG::BaseInfoBase* bib = SG::BaseInfoBase::find (clid); + if (!bib) return; + for (CLID clid2 : bib->get_bases()) { + if (clid2 != clid) { + m_linkedObjs.emplace (clid2, key); + } + } +} + + +} // namespace AthenaBaseComps diff --git a/Control/AthenaBaseComps/src/AthAlgorithmDHUpdate.h b/Control/AthenaBaseComps/src/AthAlgorithmDHUpdate.h new file mode 100644 index 000000000000..45036ce0ce7f --- /dev/null +++ b/Control/AthenaBaseComps/src/AthAlgorithmDHUpdate.h @@ -0,0 +1,85 @@ +// This file's extension implies that it's C, but it's really -*- C++ -*-. +/* + * Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration. + */ +// $Id$ +/** + * @file AthenaBaseComps/src/AthAlgorithmDHUpdate.h + * @author scott snyder <snyder@bnl.gov> + * @date Apr, 2017 + * @brief Update output dependencies to include symlinks. + */ + + +#ifndef ATHENABASECOMPS_ATHALGORITHMDHUPDATE_H +#define ATHENABASECOMPS_ATHALGORITHMDHUPDATE_H + + +#include "GaudiKernel/IDataHandleHolder.h" +#include "GaudiKernel/DataObjID.h" +#include "GaudiKernel/ClassID.h" +#include <memory> + + +namespace AthenaBaseComps { + + +/** + * @brief Update output dependencies to include symlinks. + * + * This is intended to be installed in an algorithm via the + * m_updateDataHandles hook, to run before Algorithm::sysInitialize + * merges the sets of input and output dependencies. + * + * It makes a first pass over all the output dependences. For each, + * it examines the CLID to see if there are any other CLIDs to which + * it is convertable, and if so, adds them to the @c linkedObjs list. + * The intention is that the algorithm will then override + * @c extraOutputDeps so that it will include these extra entries. + */ +class AthAlgorithmDHUpdate + : public IDataHandleVisitor +{ +public: + /** + * @brief Constructor. + * @param linkedObjs Set to which entries for symlinks will be added. + * @param chain Hook to call after this one completes. + */ + AthAlgorithmDHUpdate (DataObjIDColl& linkedObjs, + std::unique_ptr<IDataHandleVisitor> chain); + + + /** + * @brief Walk over the dependencies of an algorithm. + * @param dhh The algorithm object. + * + * Finds output dependencies of the algorithms that have symlinks + * available and enters these links in @c linkedObjs. + */ + virtual void visit(const IDataHandleHolder* dhh) override; + + +private: + /** + * @brief Handle one output dependency. + * @param clid The CLID of the output. + * @param key The SG key of the output. + * + * If CLID has symlinks available, enter these links in @c linkedObjs. + */ + void handle (CLID clid, const std::string& key); + + + /// Set of additional output dependencies represented by links. + DataObjIDColl& m_linkedObjs; + + /// Hook to call after this one. + std::unique_ptr<IDataHandleVisitor> m_chain; +}; + + +} // namespace AthenaBaseComps + + +#endif // not ATHENABASECOMPS_ATHALGORITHMDHUPDATE_H diff --git a/Control/AthenaBaseComps/src/AthReentrantAlgorithm.cxx b/Control/AthenaBaseComps/src/AthReentrantAlgorithm.cxx index bc09e1db6f48..7846761c4a22 100644 --- a/Control/AthenaBaseComps/src/AthReentrantAlgorithm.cxx +++ b/Control/AthenaBaseComps/src/AthReentrantAlgorithm.cxx @@ -11,6 +11,7 @@ // AthenaBaseComps includes #include "AthenaBaseComps/AthReentrantAlgorithm.h" +#include "AthAlgorithmDHUpdate.h" // FrameWork includes #include "GaudiKernel/Property.h" @@ -62,6 +63,14 @@ AthReentrantAlgorithm::AthReentrantAlgorithm( const std::string& name, m_userStore = UserDataSvc_t ("UserDataSvc/UserDataSvc", name), "Handle to a UserDataSvc/UserDataSvc instance: it will be used to " "retrieve user data during the course of the job" ); + + // Set up to run AthAlgorithmDHUpdate in sysInitialize before + // merging depedency lists. This extends the output dependency + // list with any symlinks implied by inheritance relations. + m_updateDataHandles = + std::make_unique<AthenaBaseComps::AthAlgorithmDHUpdate> + (m_extendedExtraObjects, + std::move (m_updateDataHandles)); } // Destructor @@ -119,3 +128,20 @@ StatusCode AthReentrantAlgorithm::execute() return execute_r (Gaudi::Hive::currentContext()); } #endif + + +/** + * @brief Return the list of extra output dependencies. + * + * This list is extended to include symlinks implied by inheritance + * relations. + */ +const DataObjIDColl& AthReentrantAlgorithm::extraOutputDeps() const +{ + // If we didn't find any symlinks to add, just return the collection + // from the base class. Otherwise, return the extended collection. + if (!m_extendedExtraObjects.empty()) { + return m_extendedExtraObjects; + } + return Algorithm::extraOutputDeps(); +} diff --git a/Control/AthenaBaseComps/test/AthAlgorithmDHUpdate_test.cxx b/Control/AthenaBaseComps/test/AthAlgorithmDHUpdate_test.cxx new file mode 100644 index 000000000000..e57749a5018f --- /dev/null +++ b/Control/AthenaBaseComps/test/AthAlgorithmDHUpdate_test.cxx @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration. + */ + +// $Id$ +/** + * @file AthenaBaseComps/test/AthAlgorithmDHUpdate_test.cxx + * @author scott snyder <snyder@bnl.gov> + * @date Apr, 2017 + * @brief Test property handling for AthReentrantAlgorithm. + */ + + +#undef NDEBUG +#include "../src/AthAlgorithmDHUpdate.h" +#include "SGTools/CLASS_DEF.h" +#include "SGTools/BaseInfo.h" +#include "TestTools/initGaudi.h" +#include <cassert> +#include <iostream> + + +class A2 {}; +class A3 {}; +class A1 : public A2, public A3 {}; +CLASS_DEF (A1, 132102064, 0) +CLASS_DEF (A2, 132102065, 0) +CLASS_DEF (A3, 132102066, 0) +SG_BASES2 (A1, A2, A3); + +class B2 {}; +class B1 : public B2 {}; +CLASS_DEF (B1, 132102074, 0) +CLASS_DEF (B2, 132102075, 0) +SG_BASE (B1, B2); + +class C2 {}; +class C1 : public C2 {}; +CLASS_DEF (C1, 132102084, 0) +CLASS_DEF (C2, 132102085, 0) +SG_BASE (C1, C2); + +class TestHolder + : public IDataHandleHolder +{ +public: + virtual std::vector<Gaudi::DataHandle*> inputHandles() const override + { std::abort(); } + virtual const DataObjIDColl& extraInputDeps() const override + { std::abort(); } + virtual void acceptDHVisitor(IDataHandleVisitor*) const override + { std::abort(); } + virtual void commitHandles() override + { std::abort(); } + virtual const DataObjIDColl& inputDataObjs() const override + { std::abort(); } + virtual void addDependency(const DataObjID&, const Gaudi::DataHandle::Mode&) override + { std::abort(); } + virtual void declare(Gaudi::DataHandle&) override + { std::abort(); } + virtual void renounce(Gaudi::DataHandle&) override + { std::abort(); } + virtual unsigned long addRef() override + { std::abort(); } + virtual unsigned long release() override + { std::abort(); } + virtual StatusCode queryInterface(const InterfaceID&, void**) override + { std::abort(); } + virtual const std::string& name() const override + { std::abort(); } + + virtual std::vector<Gaudi::DataHandle*> outputHandles() const override; + virtual const DataObjIDColl& extraOutputDeps() const override; + virtual const DataObjIDColl& outputDataObjs() const override; + + + std::vector<Gaudi::DataHandle*> handle_ptrs; + DataObjIDColl outDeps; + DataObjIDColl extraOutDeps; +}; + + +std::vector<Gaudi::DataHandle*> TestHolder::outputHandles() const +{ + return handle_ptrs; +} + + +const DataObjIDColl& TestHolder::extraOutputDeps() const +{ + return extraOutDeps; +} + + +const DataObjIDColl& TestHolder::outputDataObjs() const +{ + return outDeps; +} + + +class TestChain + : public IDataHandleVisitor +{ +public: + virtual void visit(const IDataHandleHolder*) override; + + const IDataHandleHolder* visited = nullptr; +}; + + +void TestChain::visit (const IDataHandleHolder* dhh) +{ + visited = dhh; +} + + +void test1() +{ + std::cout << "test1\n"; + + TestHolder h; + Gaudi::DataHandle h1 (DataObjID (ClassID_traits<A1>::ID(), "a1")); + h.handle_ptrs.push_back (&h1); + + h.outDeps.emplace (ClassID_traits<B1>::ID(), "b1"); + h.outDeps.emplace (ClassID_traits<C1>::ID(), "c1"); + h.extraOutDeps.emplace (ClassID_traits<C1>::ID(), "c1"); + + DataObjIDColl linkedObjs; + auto chain = std::make_unique<TestChain>(); + TestChain* tc = chain.get(); + AthenaBaseComps::AthAlgorithmDHUpdate dhu (linkedObjs, std::move (chain)); + dhu.visit (&h); + assert (tc->visited == &h); + + DataObjIDColl exp = { + { ClassID_traits<A2>::ID(), "a1" }, + { ClassID_traits<A3>::ID(), "a1" }, + { ClassID_traits<B2>::ID(), "b1" }, + { ClassID_traits<C1>::ID(), "c1" }, + { ClassID_traits<C2>::ID(), "c1" }, + }; + + if (linkedObjs != exp) { + for (const DataObjID& o : linkedObjs) { + std::cout << "linked " << o.clid() << " " << o.key() << "\n"; + } + } + + // Quick test with null chain. + std::unique_ptr<IDataHandleVisitor> chain2; + AthenaBaseComps::AthAlgorithmDHUpdate dhu2 (linkedObjs, std::move (chain2)); + dhu2.visit (&h); +} + + +int main() +{ + ISvcLocator* svcLoc = nullptr; + Athena_test::initGaudi ("propertyHandling_test.txt", svcLoc); + + test1(); + return 0; +} diff --git a/Control/AthenaBaseComps/test/AthAlgorithm_test.cxx b/Control/AthenaBaseComps/test/AthAlgorithm_test.cxx new file mode 100644 index 000000000000..f0f2e494e004 --- /dev/null +++ b/Control/AthenaBaseComps/test/AthAlgorithm_test.cxx @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration. + */ + +// $Id$ +/** + * @file AthenaBaseComps/test/AthAlgorithm_test.cxx + * @author scott snyder <snyder@bnl.gov> + * @date Apr, 2017 + * @brief Test property handling for AthAlgorithm. + */ + + +#undef NDEBUG +#include "AthenaBaseComps/AthAlgorithm.h" +#include "StoreGate/ReadHandleKey.h" +#include "StoreGate/WriteHandle.h" +#include "TestTools/initGaudi.h" +#include "GaudiKernel/ThreadLocalContext.h" +#include <vector> +#include <cassert> +#include <iostream> + + +namespace AthenaBaseCompsTest { +class MyBase {}; +class MyObj : public MyBase {}; +} +CLASS_DEF (AthenaBaseCompsTest::MyBase, 293847296, 1) +CLASS_DEF (AthenaBaseCompsTest::MyObj, 293847295, 1) +SG_BASE (AthenaBaseCompsTest::MyObj, AthenaBaseCompsTest::MyBase); +using AthenaBaseCompsTest::MyObj; + + +class MyAlg + : public AthAlgorithm +{ +public: + MyAlg (const std::string& name, ISvcLocator* svcLoc); + + virtual StatusCode execute() override; + + virtual void declare(Gaudi::DataHandle& hnd) override; + + SG::ReadHandleKey<MyObj> rkey; + SG::WriteHandle<MyObj> whandle; + + std::vector<Gaudi::DataHandle*> inputs; + std::vector<Gaudi::DataHandle*> outputs; +}; + + +MyAlg::MyAlg (const std::string& name, ISvcLocator* svcLoc) + : AthAlgorithm (name, svcLoc) +{ + declareProperty ("rkey", rkey); + declareProperty ("whandle", whandle); +} + + +StatusCode MyAlg::execute() +{ + return StatusCode::SUCCESS; +} + + +void MyAlg::declare(Gaudi::DataHandle& hnd) { + if (hnd.mode() & Gaudi::DataHandle::Reader) + inputs.push_back( &hnd ); + if (hnd.mode() & Gaudi::DataHandle::Writer) + outputs.push_back( &hnd ); + AthAlgorithm::declare (hnd); +} + + +void test1 (ISvcLocator* svcLoc) +{ + std::cout << "test1\n"; + + MyAlg alg ("ralg", svcLoc); alg.addRef(); + //assert (alg.setProperties().isSuccess()); + assert (alg.sysInitialize().isSuccess()); + + assert (alg.rkey.clid() == 293847295); + assert (alg.rkey.key() == "aaa"); + assert (alg.rkey.storeHandle().name() == "FooSvc"); + assert (alg.rkey.mode() == Gaudi::DataHandle::Reader); + + assert (alg.whandle.clid() == 293847295); + assert (alg.whandle.key() == "eee"); + assert (alg.whandle.storeHandle().name() == "BarSvc"); + assert (alg.whandle.mode() == Gaudi::DataHandle::Writer); + + std::vector<std::string> inputKeys { "aaa" }; + assert (alg.inputs.size() == inputKeys.size()); + for (size_t i = 0; i < inputKeys.size(); i++) + assert (alg.inputs[i]->objKey() == inputKeys[i]); + + std::vector<std::string> outputKeys { "eee" }; + assert (alg.outputs.size() == outputKeys.size()); + for (size_t i = 0; i < outputKeys.size(); i++) + assert (alg.outputs[i]->objKey() == outputKeys[i]); + + IProxyDict* xdict = &*alg.evtStore(); + xdict = alg.evtStore()->hiveProxyDict(); + EventContext ctx; + ctx.setProxy (xdict); + Gaudi::Hive::setCurrentContext (ctx); + + assert (alg.execute().isSuccess()); + + DataObjIDColl exp = { + { ClassID_traits<AthenaBaseCompsTest::MyObj>::ID(), "eee" }, + { ClassID_traits<AthenaBaseCompsTest::MyBase>::ID(), "eee" }, + }; + if (exp != alg.outputDataObjs()) { + for (const DataObjID& o : alg.outputDataObjs()) { + std::cout << "obj " << o.clid() << " " << o.key() << "\n"; + } + } +} + + +int main() +{ + ISvcLocator* svcLoc = nullptr; + Athena_test::initGaudi ("propertyHandling_test.txt", svcLoc); + + test1 (svcLoc); + return 0; +} diff --git a/Control/AthenaBaseComps/test/AthReentrantAlgorithm_test.cxx b/Control/AthenaBaseComps/test/AthReentrantAlgorithm_test.cxx index d0d94d777810..51d4685b71cb 100644 --- a/Control/AthenaBaseComps/test/AthReentrantAlgorithm_test.cxx +++ b/Control/AthenaBaseComps/test/AthReentrantAlgorithm_test.cxx @@ -23,9 +23,12 @@ namespace AthenaBaseCompsTest { -class MyObj {}; +class MyBase {}; +class MyObj : public MyBase {}; } +CLASS_DEF (AthenaBaseCompsTest::MyBase, 293847296, 1) CLASS_DEF (AthenaBaseCompsTest::MyObj, 293847295, 1) +SG_BASE (AthenaBaseCompsTest::MyObj, AthenaBaseCompsTest::MyBase); using AthenaBaseCompsTest::MyObj; @@ -70,6 +73,7 @@ void MyAlg::declare(Gaudi::DataHandle& hnd) { inputs.push_back( &hnd ); if (hnd.mode() & Gaudi::DataHandle::Writer) outputs.push_back( &hnd ); + AthReentrantAlgorithm::declare (hnd); } @@ -78,7 +82,8 @@ void test1 (ISvcLocator* svcLoc) std::cout << "test1\n"; MyAlg alg ("ralg", svcLoc); alg.addRef(); - assert (alg.setProperties().isSuccess()); + //assert (alg.setProperties().isSuccess()); + assert (alg.sysInitialize().isSuccess()); assert (alg.rkey.clid() == 293847295); assert (alg.rkey.key() == "aaa"); @@ -108,6 +113,16 @@ void test1 (ISvcLocator* svcLoc) assert (alg.execute().isSuccess()); assert (pdict == xdict); + + DataObjIDColl exp = { + { ClassID_traits<AthenaBaseCompsTest::MyObj>::ID(), "eee" }, + { ClassID_traits<AthenaBaseCompsTest::MyBase>::ID(), "eee" }, + }; + if (exp != alg.outputDataObjs()) { + for (const DataObjID& o : alg.outputDataObjs()) { + std::cout << "obj " << o.clid() << " " << o.key() << "\n"; + } + } } -- GitLab