Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:17:43

0001 
0002 // Copyright 2020, Jefferson Science Associates, LLC.
0003 // Subject to the terms in the LICENSE file found in the top-level directory.
0004 
0005 #define CATCH_CONFIG_MAIN
0006 #include "catch.hpp"
0007 
0008 #include "JServiceLocatorTests.h"
0009 #include <JANA/JService.h>
0010 #include <JANA/Services/JServiceLocator.h>
0011 
0012 
0013 TEST_CASE("JServiceLocatorMissingServiceTest") {
0014     JServiceLocator sut;
0015     sut.wire_everything();
0016     REQUIRE_THROWS(sut.get<ParameterSvc>());
0017     /*
0018     try {
0019         sut.get<ParameterSvc>();
0020         REQUIRE(0 == 1); // Never gets here because it throws
0021     }
0022     catch (JException ex) {
0023         std::cout << ex << std::endl;
0024     }
0025     */
0026 }
0027 
0028 TEST_CASE("JServiceLocator chicken-and-egg tests") {
0029 
0030     JServiceLocator sl;
0031 
0032     // PHASE 1: jana.cc sets up params and logger services, which literally everything else needs
0033 
0034     auto parameterSvc = std::make_shared<ParameterSvc>();
0035     parameterSvc->set("JANA:LogLevel", "DEBUG");   // Eventually set from program args or config file
0036     sl.provide(parameterSvc);     // Any errors parsing parameters are sent to the UI, not the logger
0037 
0038     auto loggerSvc_throwaway = std::make_shared<LoggerSvc>();
0039     sl.provide(loggerSvc_throwaway);
0040     // LoggerSvc has not yet obtained its loglevel from parameterSvc
0041     REQUIRE(loggerSvc_throwaway->level == "INFO");
0042 
0043     // We need a logger ASAP so we can log failed plugin loading, etc
0044     // sl.get() will call logger.finalize(), which will call parameterSvc.acquire_services().
0045     // logger can get<>() the parameterSvc for the first time inside acquire_services()
0046     auto loggingSvc = sl.get<LoggerSvc>();
0047     REQUIRE(loggingSvc->level == "DEBUG");
0048 
0049     // PHASE 2: jana.cc registers other 'internal' services such as JApplication, JThreadManager, etc
0050     // We call JApplication::acquire_services() before plugin loading, where we pull in all of the other services
0051     // we need and make JApplication usable by others
0052 
0053 
0054     // PHASE 3: We call JApplication::loadPlugins(), which dlopens a bunch of plugins, each of which
0055     // has an InitPlugin() function which does something like:
0056 
0057     auto magFieldSvc = std::make_shared<MagneticFieldSvc>();
0058     sl.provide(magFieldSvc);
0059     REQUIRE(parameterSvc->get("EIC:MagneticFieldDatabaseURL") == "");  // MagneticFieldSvc doesn't have its params yet
0060 
0061 
0062     // PHASE 5: Once all plugins are loaded and all Services are provided, we wire them all up _before_ any
0063     // processing starts. This involves JServiceLocator calling acquire_services() on everything
0064     // MagneticFieldService retrieves its database URL or sets a default which the user can see.
0065     sl.wire_everything();
0066     REQUIRE(parameterSvc->get("EIC:MagneticFieldDatabaseURL") == "mysql://127.0.0.1");
0067 
0068     // PHASE 6: Everything is ready, we can do whatever we want.
0069     // If the user specified --listconfigs, then we print all configs. This will include the
0070     // EIC:MagneticFieldServiceURL parameter
0071 
0072     auto magneticFieldSvc = sl.get<MagneticFieldSvc>();
0073     REQUIRE(magneticFieldSvc->connect() == true);
0074 
0075 }
0076 
0077 struct OmniService : public JService {
0078 
0079     Service<JParameterManager> parman {this};
0080     Parameter<int> bucket_count {this, "bucket_count", 5, "Some integer representing a bucket count"};
0081     std::atomic_int init_call_count {0};
0082 
0083     void Init() override {
0084         LOG_INFO(GetLogger()) << "Calling OmniService::Init" << LOG_END;
0085         REQUIRE(parman->GetParameterValue<int>("bucket_count") == 22);
0086         REQUIRE(bucket_count() == 22);
0087         REQUIRE(init_call_count == 0);
0088         init_call_count++;
0089     }
0090 };
0091 
0092 TEST_CASE("JService Omni interface") {
0093     JApplication app;
0094     app.SetParameterValue("bucket_count", 22);
0095     app.ProvideService(std::make_shared<OmniService>());
0096     app.Initialize();
0097     auto sut = app.GetService<OmniService>();
0098     REQUIRE(sut->GetStatus() == JService::Status::Initialized);
0099     REQUIRE(sut->bucket_count() == 22);
0100 
0101     // Fetch again to make sure Init() is only called once
0102     sut = app.GetService<OmniService>();
0103     LOG << "Retrieved service " << sut << LOG_END; // Just in case the optimizer tries to get rid of this
0104 }
0105