The Gaudi Framework  master (181af51f)
Loading...
Searching...
No Matches
ToolVisitorTestLib.cpp
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations *
3* *
4* This software is distributed under the terms of the Apache version 2 licence, *
5* copied verbatim in the file "LICENSE". *
6* *
7* In applying this licence, CERN does not waive the privileges and immunities *
8* granted to it by virtue of its status as an Intergovernmental Organization *
9* or submit itself to any jurisdiction. *
10\***********************************************************************************/
11#include "GaudiEnv.h"
12#include "ITestTool.h"
13#include <GaudiKernel/AlgTool.h>
17#include <deque>
18#include <sstream>
19
20#ifndef NDEBUG
21# include <iostream>
22#endif
23
24namespace GaudiTesting {
25 void throwConditionFailed( bool condition, const std::string& file_name, int line_no,
26 const std::string& condition_string ) {
27 if ( !condition ) {
28 std::stringstream msg;
29 msg << "Conditoin Failed: " << file_name << ":" << line_no << " " << condition_string;
30 throw std::runtime_error( msg.str() );
31 }
32 }
33
34 std::string extractBaseName( const std::string& full_name ) {
35 std::string::size_type pos = full_name.rfind( "." );
36 std::string::size_type pos2 = full_name.rfind( "/" );
37 if ( pos == std::string::npos ) {
38 pos = pos2;
39 } else if ( pos2 > pos ) {
40 pos = pos2;
41 }
42 return pos != std::string::npos ? full_name.substr( pos + 1 ) : full_name;
43 }
44
45 class TestTool : public extends<AlgTool, ITestTool> {
46 public:
47 TestTool( const std::string& type, const std::string& name, const IInterface* parent )
48 : base_class( type, name, parent ) {
50 }
51
52 void process() const override {}
53 void setDefaults() {
54 std::string base_name( extractBaseName( name() ) );
55 DEBUG_TRACE( std::cout << "DEBUG " << name() << " setDefaults" << base_name << std::endl; );
56 if ( base_name == "tool1" ) {
57 addInput( "Renounce" );
58 addInput( "Input11" );
59 } else if ( base_name == "tool2" ) {
60 addInput( "Input21" );
61 addInput( "Input22" );
62 addTool( "tool1" );
63 } else if ( base_name == "tool3" ) {
64 addInput( "Input31" );
65 addInput( "Input32" );
66 addTool( "tool4" );
67 addTool( "tool2" );
68 } else if ( base_name == "tool4" ) {
69 addInput( "Input41" );
70 addInput( "Input42" );
71 addInput( "Renounce" );
72 } else if ( base_name == "tool5" || base_name == "tool5Bug" ) {
73 addInput( "Input51" );
74 addInput( "Input52" );
75 addOutput( "Renounce" );
76 addTool( "tool3" );
77 } else if ( base_name == "tool6" ) {
78 addInput( "Input61" );
79 addTool( "tool5" );
80 }
81 DEBUG_TRACE( std::cout << "DEBUG " << name() << " added tools:" << m_algTools.size()
82 << ", data handles:" << m_handles.size() << std::endl );
83 }
84
85 // a do-nothing helper class which implements the logger interface
87 void renounce( [[maybe_unused]] std::string_view tool, [[maybe_unused]] std::string_view input ) override {
88 DEBUG_TRACE( std::cout << "renounce " << tool << " . " << input << std::endl );
89 }
90 };
91
92 void addInput( const std::string& key ) {
93 m_keys.emplace_back( key );
94 m_handles.emplace_back( m_keys.back(), Gaudi::DataHandle::Reader, this );
95 this->declare( m_handles.back() );
96 }
97 void addOutput( const std::string& key ) {
98 m_keys.emplace_back( key );
99 m_handles.emplace_back( m_keys.back(), Gaudi::DataHandle::Writer, this );
100 this->declare( m_handles.back() );
101 }
102 void addTool( const std::string& name ) {
103 m_algTools.emplace_back( this, name, "GaudiTesting::TestTool/" + name, "" );
104 Ensures( this->declareTool( m_algTools.back(), m_algTools.back().typeAndName(), true ).isSuccess() );
105 }
107 DEBUG_TRACE( std::cout << "DEBUG " << name() << " initialize." << std::endl );
108 std::string base_name( extractBaseName( name() ) );
109 for ( auto& handle : m_algTools ) {
110 DEBUG_TRACE( std::cout << name() << " tool:" << handle.typeAndName() << std::endl );
111 handle.retrieve().ignore();
112 }
113 if ( base_name == "tool5" ) {
114 auto i = std::find_if( m_handles.begin(), m_handles.end(), []( const auto& data ) {
115 return data.mode() == Gaudi::DataHandle::Writer && data.objKey() == "Renounce";
116 } );
117 if ( i != m_handles.end() ) {
118 TestTool::Logger logger;
119 DEBUG_TRACE( std::cout << "DEBUG " << name() << " renounce tools "
120 << "Renounce" << std::endl );
121 auto visitor = RenounceToolInputsVisitor{ { i->fullKey() }, logger };
122 ToolVisitor::visit( tools(), visitor );
123 }
124 }
125 DEBUG_TRACE( std::cout << "DEBUG " << name() << " INITIALIZED: tools " << m_algTools.size()
126 << ", data handles:" << m_handles.size() << std::endl );
127 return StatusCode::SUCCESS;
128 }
129
130 std::vector<DataObjID> m_keys;
131 std::deque<Gaudi::DataHandle> m_handles;
132 std::deque<ToolHandle<ITestTool>> m_algTools;
133 };
134
135 class TestAlg : public Algorithm {
136 public:
137 TestAlg( const std::string& aname, ISvcLocator* svc_Locator ) : Algorithm( aname, svc_Locator ) {
138 Ensures( setProperty( "FilterCircularDependencies", false ).isSuccess() );
139 DEBUG_TRACE( std::cout << "DEBUG TestAlg ctor " << name() << std::endl );
140 if ( extractBaseName( name() ) == "TestAlgBug" ) {
141 addTool( "GaudiTesting::TestTool/tool5Bug" );
142 Ensures( this->setProperty( "OutputLevel", static_cast<int>( MSG::FATAL ) ).isSuccess() );
143 } else {
144 addTool( "GaudiTesting::TestTool/tool5" );
145 }
146 }
147 ~TestAlg() { DEBUG_TRACE( std::cout << "DEBUG " << name() << "::dtor" << std::endl ); }
149 for ( auto& handle : m_algTools ) {
150 DEBUG_TRACE( std::cout << name() << " tool:" << handle.typeAndName() << std::endl );
151 if ( handle.retrieve().isFailure() ) { return StatusCode::FAILURE; }
152 }
153 dumpData( "Renounce" );
154 return StatusCode::SUCCESS;
155 }
156 void dumpData( const std::string& pattern ) const {
157 auto dumper = [&pattern]( const IAlgTool* tool ) {
158 const AlgTool* alg_tool = dynamic_cast<const AlgTool*>( tool );
159 if ( alg_tool ) {
160 for ( Gaudi::DataHandle* handle : alg_tool->inputHandles() ) {
161 if ( handle->objKey().find( pattern ) != std::string::npos ) {
162 DEBUG_TRACE( std::cout << "DEBUG input Handle " << tool->name() << " . " << handle->objKey()
163 << std::endl );
164 }
165 }
166 for ( Gaudi::DataHandle* handle : alg_tool->outputHandles() ) {
167 if ( handle->objKey().find( pattern ) != std::string::npos ) {
168 DEBUG_TRACE( std::cout << "DEBUG output Handle " << tool->name() << " . " << handle->objKey()
169 << std::endl );
170 }
171 }
172 for ( auto elm : alg_tool->inputDataObjs() ) {
173 if ( elm.key().find( pattern ) != std::string::npos ) {
174 DEBUG_TRACE( std::cout << "DEBUGinput Handle " << tool->name() << " . " << elm.key() << std::endl );
175 }
176 }
177 }
178 };
179 ToolVisitor::visit( tools(), dumper );
180 }
182 StatusCode finalize() override {
183#ifndef NDEBUG
184 for ( const DataObjID& const_obj_id : this->inputDataObjs() ) {
185 DEBUG_TRACE( std::cout << "DEBUG " << name() << " input:" << const_obj_id.key() << std::endl );
186 }
187 for ( const DataObjID& const_obj_id : this->outputDataObjs() ) {
188 DEBUG_TRACE( std::cout << "DEBUG " << name() << " output:" << const_obj_id.key() << std::endl );
189 }
190#endif
191 return StatusCode::SUCCESS;
192 }
193
194 private:
195 void addTool( const std::string& name ) {
196 m_algTools.emplace_back( this, name, "GaudiTesting::TestTool/" + name, "" );
197 Ensures( this->declareTool( m_algTools.back(), m_algTools.back().typeAndName(), true ).isSuccess() );
198 }
199 std::deque<ToolHandle<ITestTool>> m_algTools;
200 };
201
204} // namespace GaudiTesting
bool PyHelper setProperty(IInterface *p, char *name, char *value)
#define DEBUG_TRACE(a)
Definition GaudiEnv.h:28
#define Ensures(a)
Definition GaudiEnv.h:26
#define DECLARE_COMPONENT(type)
Base class from which all the concrete tool classes should be derived.
Definition AlgTool.h:55
const IInterface * parent() const override
Retrieve parent of the sub-algtool.
Definition AlgTool.cpp:76
const std::string & type() const override
Retrieve type (concrete class) of the sub-algtool.
Definition AlgTool.cpp:74
const std::vector< IAlgTool * > & tools() const
Definition AlgTool.cpp:343
const std::string & name() const override
Retrieve full identifying name of the concrete tool object.
Definition AlgTool.cpp:72
StatusCode declareTool(ToolHandle< T > &handle, bool createIf=true)
Definition AlgTool.h:152
std::vector< Gaudi::DataHandle * > inputHandles() const override
std::vector< Gaudi::DataHandle * > outputHandles() const override
const DataObjIDColl & inputDataObjs() const override
const std::vector< IAlgTool * > & tools() const
Algorithm(std::string name, ISvcLocator *svcloc, std::string version=PACKAGE_VERSION)
Constructor.
Definition Algorithm.h:98
StatusCode declareTool(ToolHandle< T > &handle, bool createIf=true)
Definition Algorithm.h:349
const std::string & name() const override
The identifying name of the algorithm object.
void addTool(const std::string &name)
StatusCode execute() override
StatusCode finalize() override
StatusCode initialize() override
std::deque< ToolHandle< ITestTool > > m_algTools
TestAlg(const std::string &aname, ISvcLocator *svc_Locator)
void dumpData(const std::string &pattern) const
std::vector< DataObjID > m_keys
std::deque< Gaudi::DataHandle > m_handles
void addOutput(const std::string &key)
StatusCode initialize() override
std::deque< ToolHandle< ITestTool > > m_algTools
TestTool(const std::string &type, const std::string &name, const IInterface *parent)
void process() const override
void addTool(const std::string &name)
void addInput(const std::string &key)
The interface implemented by the AlgTool base class.
Definition IAlgTool.h:29
Definition of the basic interface.
Definition IInterface.h:225
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition ISvcLocator.h:42
Helper class to be used in conjunction with the recursive tool visitor to renounce certain inputs.
This class is used for returning status codes from appropriate routines.
Definition StatusCode.h:64
bool isSuccess() const
Definition StatusCode.h:314
constexpr static const auto SUCCESS
Definition StatusCode.h:99
constexpr static const auto FAILURE
Definition StatusCode.h:100
Base class used to extend a class implementing other interfaces.
Definition extends.h:19
void throwConditionFailed(bool condition, const std::string &file_name, int line_no, const std::string &condition_string)
std::string extractBaseName(const std::string &full_name)
@ FATAL
Definition IMessageSvc.h:22
void renounce(std::string_view tool, std::string_view input) override
Helper class interface to optionally log renounce operations.