Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

CdbProxyBaseTest.cc

Go to the documentation of this file.
00001 // File and Version Information:
00002 //      $Id: CdbProxyBaseTest.cc,v 1.8 2004/12/08 09:49:49 gapon Exp $
00003 #include "BaBar/BaBar.hh"
00004 
00005 /// This is a test application for the CdbBdbProxyBase class
00006 /**
00007   * This application implements a simple proxy class deriving
00008   * from the CdbBdbProxyBase class.
00009   */
00010 #include "CdbBdbWrapper/CdbBdbWrapper.hh"
00011 
00012 #include "CdbBdb/CdbBdbProxyBase.hh"
00013 #include "CdbBdb/CdbBdbProxyElement.hh"
00014 #include "CdbBdb/CdbBdbEnvProxy.hh"
00015 
00016 #include "BdbTime/BdbTime.hh"
00017 
00018 #include "BdbCond/BdbConditions.hh"
00019 #include "BdbCondTests/EmcFooClassP.hh"
00020 
00021 #include "ProxyDict/IfdSimpleProxyDict.hh"
00022 #include "ProxyDict/Ifd.hh"
00023 #include "ProxyDict/IfdStrKey.hh"
00024 
00025 #include "AbsEnv/AbsEnv.hh"
00026 #include "GenEnv/GenEnv.hh"
00027 
00028 #include <stdio.h>  // sscanf()
00029 
00030 #include <string>
00031 using std::cerr;
00032 using std::cout;
00033 using std::endl;
00034 
00035 /// The transient product of our test proxy
00036 /**
00037   * This class is meant to test the simple proxy. When it's
00038   * constructor is called a persistent reference onto the real
00039   * condition object is stored as adata member of the class.
00040   */
00041 class SimpleProxyProduct {
00042 private:
00043 
00044   /// Default constructor (NOT IMMPLEMENTED)
00045 
00046     SimpleProxyProduct( );
00047 
00048 public:
00049 
00050   /// Normal constructor
00051 
00052     SimpleProxyProduct( const BdbRef(BdbObject)& theRef ) :
00053         ref(theRef)
00054     { }
00055 
00056 public:
00057 
00058     BdbRef(BdbObject) ref;
00059 };
00060 
00061 /// The simple proxy class
00062 /**
00063   * In order to test this class, the corresponding persistent condition
00064   * must exist in the database.
00065   */
00066 class SimpleProxy : public CdbBdbProxyBase<SimpleProxyProduct> {
00067 
00068 public:
00069 
00070     SimpleProxy( )
00071     {
00072         subscribeCondition( "/emc/EmcFooClassP" );
00073     }
00074 static void doTest( const std::string& theRevisionName,
00075                     unsigned int       thePartitionId );
00076 
00077     virtual ~SimpleProxy( )
00078     { }
00079 
00080   /// Implement the user defined fault handler.
00081   /**
00082     * Remember, that the base class gurantees that the following method
00083     * is executed within the read mode transaction. Therefore we can get
00084     * updated persistent and build the transient product.
00085     *
00086     * We also should not warry about the lifetime of the transient product,
00087     * all of this will be handled by the caller.
00088     */
00089     virtual SimpleProxyProduct* redefinedFaultHandler( const std::vector<CdbBdbProxyElement>& listOfElements )
00090     {
00091         cout << "SimpleProxy::redefinedFaultHandler() - BEGIN" << endl
00092              << endl;
00093 
00094         cout << "    FAULT TIME: " << faultTime( ) << endl;
00095 
00096         CdbBdbProxyElement e;
00097 
00098         std::vector<CdbBdbProxyElement>::const_iterator itr;
00099         for( itr = listOfElements.begin( ); itr < listOfElements.end( ); ++itr ) {
00100 
00101             e = (*itr);
00102 
00103             cout << "    CONDITION NAME:       " << e.name( ) << endl
00104                  << "    CONDITION SHORT NAME: " << e.shortName( ) << endl
00105                  << "    VALIDITY INTERVAL:    " << e.validity( ) << endl
00106                  << "    OBJECT:               " << e.objectRef( ).sprint( ) << endl
00107                  << "    HAS BEEN UPDATED:     " << ( e.updated( ) ? "Yes" : "No" ) << endl
00108                  << endl;
00109         }
00110         cout << "SimpleProxy::redefinedFaultHandler() - END" << endl;
00111 
00112       // Construct the transient product and pass a persistent reference to it.
00113       // Looks a bit silly, but it's fine for the testing purposes.
00114 
00115         return new SimpleProxyProduct( e.objectRef( ));
00116     }
00117 };
00118 
00119 /// The simple proxy class using explicitly specified revision name and a partition
00120 /**
00121   * In order to test this class, the corresponding persistent condition
00122   * must exist in the database.
00123   */
00124 class SimpleProxyUsingRevision : public CdbBdbProxyBaseUsingRevision<SimpleProxyProduct> {
00125 
00126 public:
00127 
00128     SimpleProxyUsingRevision( const std::string& theRevisionName,
00129                               unsigned int       thePartitionId ) :
00130         CdbBdbProxyBaseUsingRevision<SimpleProxyProduct>( theRevisionName,
00131                                                           thePartitionId )
00132     {
00133         subscribeCondition( "/emc/EmcFooClassP" );
00134     }
00135     virtual ~SimpleProxyUsingRevision( )
00136     { }
00137 
00138   /// Implement the user defined fault handler.
00139   /**
00140     * Remember, that the base class gurantees that the following method
00141     * is executed within the read mode transaction. Therefore we can get
00142     * updated persistent and build the transient product.
00143     *
00144     * We also should not warry about the lifetime of the transient product,
00145     * all of this will be handled by the caller.
00146     */
00147     virtual SimpleProxyProduct* redefinedFaultHandler( const std::vector<CdbBdbProxyElement>& listOfElements )
00148     {
00149         cout << "SimpleProxyUsingRevision::redefinedFaultHandler() - BEGIN" << endl
00150              << endl;
00151 
00152         cout << "    FAULT TIME: " << faultTime( ) << endl;
00153 
00154         CdbBdbProxyElement e;
00155 
00156         std::vector<CdbBdbProxyElement>::const_iterator itr;
00157         for( itr = listOfElements.begin( ); itr < listOfElements.end( ); ++itr ) {
00158 
00159             e = (*itr);
00160 
00161             cout << "    CONDITION NAME:       " << e.name( ) << endl
00162                  << "    CONDITION SHORT NAME: " << e.shortName( ) << endl
00163                  << "    VALIDITY INTERVAL:    " << e.validity( ) << endl
00164                  << "    OBJECT:               " << e.objectRef( ).sprint( ) << endl
00165                  << "    HAS BEEN UPDATED:     " << ( e.updated( ) ? "Yes" : "No" ) << endl
00166                  << endl;
00167         }
00168         cout << "SimpleProxy::redefinedFaultHandler() - END" << endl;
00169 
00170       // Construct the transient product and pass a persistent reference to it.
00171       // Looks a bit silly, but it's fine for the testing purposes.
00172 
00173         return new SimpleProxyProduct( e.objectRef( ));
00174     }
00175 };
00176 
00177 ///////////
00178 // Tests //
00179 ///////////
00180 
00181 static void doTest( IfdDataProxyTemplate<SimpleProxyProduct>* theProxyPtr );
00182 
00183 /////////////
00184 // Helpers //
00185 /////////////
00186 
00187 static void usage( )
00188 {
00189     cout << "Usage: simple" << endl
00190          << "       using_revision [ <revision_name> <partition_id>]" << endl;
00191 }
00192 
00193 ////////////////////////////////////////
00194 // Starting point for the application //
00195 ////////////////////////////////////////
00196 
00197 int
00198 main( int argc, char** argv )
00199 {
00200   // Translate input parameters. The valid syntax is:
00201   //
00202   // simple
00203   // using_revision [ <revision_name> <partition_id>]
00204 
00205     if( argc <= 1 ) {
00206         usage( );
00207         return 0;
00208     }
00209     int numArgs = argc - 1;
00210     int nextArg = 1;
00211 
00212     std::string command = argv[nextArg++];
00213     numArgs = numArgs - 1;
00214 
00215     std::string  revisionName;
00216     unsigned int partitionId;
00217 
00218     if( "simple" == command ) {
00219 
00220       // No more parameters
00221 
00222         ;
00223 
00224     } else if( "using_revision" == command ) {
00225 
00226         if( numArgs < 2 ) {
00227             cerr << "error: illegal number of argments." << endl;
00228             usage( );
00229             return 1;
00230         }
00231         revisionName = argv[nextArg++];
00232         if( 1 != sscanf( argv[nextArg++], "%u", &partitionId )) {
00233             cerr << "error: failed to translate the partition identifier." << endl;
00234             usage( );
00235             return 1;
00236         }
00237         numArgs = numArgs - 2;
00238     }
00239     if( 0 != numArgs ) {
00240         cerr << "error: unexpected parameters found in the command line." << endl;
00241         usage( );
00242         return 1;
00243     }
00244 
00245   // Make sure the proper libraries are linked and factories
00246   // are instantiated.
00247 
00248     CdbBdbWrapper::forceLoad( );
00249 
00250   // The current implementation requires _external_ transaction management.
00251 
00252     BdbConditions::instance( )->startRead( );
00253 
00254     if     ( "simple"         == command ) doTest( new SimpleProxy( ));
00255     else if( "using_revision" == command ) doTest( new SimpleProxyUsingRevision( revisionName, partitionId ));
00256     else {
00257         assert( 0 );
00258     }
00259 
00260     BdbConditions::instance( )->commit( );
00261 }
00262 
00263 static void
00264 doTest( IfdDataProxyTemplate<SimpleProxyProduct>* theProxyPtr )
00265 {
00266     assert( 0 != theProxyPtr );
00267 
00268   // Simulate global environment
00269 
00270     gblEnv = new AbsEnv( );
00271     gblEnv->setGen( new GenEnv( ));
00272 
00273     BdbTime currentTime( BdbTime::now( ));
00274     EidCondKeyTriplet primaryTriplet   ( 0, 0, currentTime );
00275     EidCondKeyTriplet backgroundTriplet( 0, 0, currentTime );
00276 
00277     gblEnv->getGen( )->setConditionsKeys( &currentTime,
00278                                                       &primaryTriplet, 
00279                                                       &backgroundTriplet );
00280 
00281     gblPEnv = new IfdSimpleProxyDict;
00282 
00283   // Register our simple proxy
00284 
00285     bool result = Ifd<SimpleProxyProduct>::put( gblPEnv,
00286                                                 theProxyPtr,
00287                                                 IfdStrKey( "EmcFooClassP" ));
00288     if( !result ) cerr << "failed to put the proxy into the dictionary." << endl;
00289 
00290   // Try to use the proxy
00291 
00292     const SimpleProxyProduct* t;
00293     
00294     for( int i = 0; i < 5; ++i ) {
00295         t = Ifd<SimpleProxyProduct>::get( gblPEnv,
00296                                           IfdStrKey( "EmcFooClassP" ));
00297         if( 0 == t ) {
00298             cout << "Ifd<T>::get() failed and returned 0 pointer onto a transient object." << endl
00299                  << endl;
00300         } else {
00301             cout << "Ifd<T>::get() succeded. The OID: " << t->ref.sprint( ) << endl
00302                  << endl;
00303         }
00304 
00305       // Change the time at the global environment. This will invalidate the proxy
00306 
00307         currentTime       = BdbTime( BdbTime::now( ));
00308         primaryTriplet    = EidCondKeyTriplet( 0, 0, currentTime );
00309         backgroundTriplet = EidCondKeyTriplet( 0, 0, currentTime );
00310 
00311         gblEnv->getGen( )->setConditionsKeys( &currentTime,
00312                                                       &primaryTriplet, 
00313                                                       &backgroundTriplet );
00314     }
00315 
00316   // Just do the compilation test for the "Environment" proxy
00317 
00318     CdbBdbEnvProxy<EmcFooClass,EmcFooClassP> envProxyTest( "emc", "EmcFooClassP" );
00319 }
00320 
00321 /////////////////
00322 // End Of File //
00323 /////////////////

Generated on Mon Dec 5 18:22:08 2005 for CDB by doxygen1.3-rc3