diff --git a/src/examples/SubeventCUDAExample/SubeventCUDAExample.cu b/src/examples/SubeventCUDAExample/SubeventCUDAExample.cu index 731d30276..6718e647a 100644 --- a/src/examples/SubeventCUDAExample/SubeventCUDAExample.cu +++ b/src/examples/SubeventCUDAExample/SubeventCUDAExample.cu @@ -128,10 +128,8 @@ int main() { &subevents_out); auto merge_arrow = new JMergeArrow("merge", &processor, &subevents_out, &events_out); - auto parms = new JParameterManager; - // Some params need to be present BEFORE JApplication is constructed, e.g. log levels are lost - // parms->SetParameter("log:debug", "JWorker,JScheduler,JArrowProcessingController,JEventProcessorArrow"); - JApplication app(parms); + JApplication app; + app.SetParameterValue("log:info", "JWorker,JScheduler,JArrowProcessingController,JEventProcessorArrow"); app.SetTimeoutEnabled(false); app.SetTicker(false); diff --git a/src/examples/SubeventExample/SubeventExample.cc b/src/examples/SubeventExample/SubeventExample.cc index 27385a6c7..0417a83f7 100644 --- a/src/examples/SubeventExample/SubeventExample.cc +++ b/src/examples/SubeventExample/SubeventExample.cc @@ -88,10 +88,8 @@ int main() { auto subprocess_arrow = new JSubeventArrow("subprocess", &processor, &subevents_in, &subevents_out); auto merge_arrow = new JMergeArrow("merge", &processor, &subevents_out, &events_out); - auto parms = new JParameterManager; - // Some params need to be present BEFORE JApplication is constructed, e.g. log levels are lost - // parms->SetParameter("log:debug", "JWorker,JScheduler,JArrowProcessingController,JEventProcessorArrow"); - JApplication app(parms); + JApplication app; + app.SetParameterValue("log:info", "JWorker,JScheduler,JArrowProcessingController,JEventProcessorArrow"); app.SetTimeoutEnabled(false); app.SetTicker(false); diff --git a/src/examples/UnitTestingExample/SimpleClusterFactoryTests.cc b/src/examples/UnitTestingExample/SimpleClusterFactoryTests.cc index 2c413dfbe..d7ca22701 100644 --- a/src/examples/UnitTestingExample/SimpleClusterFactoryTests.cc +++ b/src/examples/UnitTestingExample/SimpleClusterFactoryTests.cc @@ -10,15 +10,11 @@ TEST_CASE("SimpleClusterFactoryTests") { - // Turn off all unnecessary loggers and turn on the loggers in the factory being tested. - // Note this needs to happen BEFORE creating the JApplication. - auto params = new JParameterManager; - params->SetParameter("log:debug", "SimpleClusterFactory"); - params->SetParameter("log:off", "JApplication,JParameterManager,JArrowProcessingController,JArrow"); - // We need to fire up the JApplication so that our Factory can access all of its JServices. // However, for unit testing, we don't need (or want!) to set up an event source or actually call JApplication::Run(). - JApplication app(params); + JApplication app; + app.SetParameterValue("log:debug", "SimpleClusterFactory"); + app.SetParameterValue("log:off", "JApplication,JParameterManager,JArrowProcessingController,JArrow"); // Add any plugins you need here // app.AddPlugin("myPlugin"); app.Initialize(); // Load the plugins @@ -75,4 +71,4 @@ TEST_CASE("SimpleClusterFactoryTests") { REQUIRE(true == true); } -} \ No newline at end of file +} diff --git a/src/libraries/JANA/JApplication.cc b/src/libraries/JANA/JApplication.cc index 71638c33f..5e719eed3 100644 --- a/src/libraries/JANA/JApplication.cc +++ b/src/libraries/JANA/JApplication.cc @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -16,46 +17,34 @@ JApplication *japp = nullptr; -JApplication::JApplication(JLogger::Level verbosity) { - m_service_locator = new JServiceLocator; - m_params = std::make_shared(); - m_params->SetParameter("log:global", verbosity); - m_service_locator->provide(m_params); - ProvideService(m_params); - ProvideService(std::make_shared()); - ProvideService(std::make_shared()); - ProvideService(std::make_shared()); - ProvideService(std::make_shared()); - ProvideService(std::make_shared()); - - m_plugin_loader = m_service_locator->get(); - m_component_manager = m_service_locator->get(); - m_logger = m_service_locator->get()->get_logger("JApplication"); - m_logger.show_classname = false; -} JApplication::JApplication(JParameterManager* params) { + // We set up some very essential services here, but note + // that they won't have been initialized yet. We need them now + // so that they can passively receive components, plugin names, parameter values, etc. + // These passive operations don't require any parameters, services, or + // logging output, so they don't need to be initialized until later. + // They will be fully initialized in JApplication::Initialize(). + // Only then they will be exposed to the user through the service locator. + if (params == nullptr) { m_params = std::make_shared(); } else { m_params = std::shared_ptr(params); } - + m_component_manager = std::make_shared(); + m_plugin_loader = std::make_shared(); m_service_locator = new JServiceLocator; + ProvideService(m_params); + ProvideService(m_component_manager); + ProvideService(m_plugin_loader); ProvideService(std::make_shared()); - ProvideService(std::make_shared()); - ProvideService(std::make_shared()); ProvideService(std::make_shared()); ProvideService(std::make_shared()); - m_plugin_loader = m_service_locator->get(); - m_component_manager = m_service_locator->get(); - - m_logger = m_service_locator->get()->get_logger("JApplication"); - m_logger.show_classname = false; } @@ -107,28 +96,36 @@ void JApplication::Add(JEventUnfolder* unfolder) { } -// Controlling processing - void JApplication::Initialize() { /// Initialize the application in preparation for data processing. - /// This is called by the Run method so users will usually not - /// need to call this directly. + /// This is called by the Run method so users will usually not need to call this directly. // Only run this once if (m_initialized) return; - // Obtain final values of parameters and loggers - m_plugin_loader->InitPhase2(); - m_component_manager->InitPhase2(); - m_logger = m_service_locator->get()->get_logger("JApplication"); + // Now that all parameters, components, plugin names, etc have been set, + // we can expose our builtin services to the user via GetService() + m_services_available = true; + + // We trigger initialization + auto logging_service = m_service_locator->get(); + auto component_manager = m_service_locator->get(); + auto plugin_loader = m_service_locator->get(); + auto topology_builder = m_service_locator->get(); + + // Set logger on JApplication itself + m_logger = logging_service->get_logger("JApplication"); m_logger.show_classname = false; // Attach all plugins - m_plugin_loader->attach_plugins(m_component_manager.get()); + plugin_loader->attach_plugins(component_manager.get()); // Resolve all event sources now that all plugins have been loaded - m_component_manager->resolve_event_sources(); + component_manager->resolve_event_sources(); + + // Give all components a JApplication pointer and a logger + component_manager->configure_components(); // Set desired nthreads. We parse the 'nthreads' parameter two different ways for backwards compatibility. m_desired_nthreads = 1; @@ -150,16 +147,15 @@ void JApplication::Initialize() { LOG_WARN(m_logger) << "Unrecognized engine choice! Falling back to jana:engine=0" << LOG_END; } */ - std::shared_ptr topology_builder = m_service_locator->get(); auto topology = topology_builder->get_or_create(); + ProvideService(std::make_shared(topology)); - auto japc = std::make_shared(topology); - m_service_locator->provide(japc); // Make concrete class available via SL m_processing_controller = m_service_locator->get(); // Get deps from SL - m_service_locator->provide(m_processing_controller); // Make abstract class available via SL + ProvideService(m_processing_controller); // Make abstract class available via SL m_processing_controller->initialize(); m_initialized = true; + // This needs to be at the end so that m_initialized==false while InitPlugin() is being called } /// @brief Run the application, launching 1 or more threads to do the work. diff --git a/src/libraries/JANA/JApplication.h b/src/libraries/JANA/JApplication.h index 59a09c85e..72dbd4259 100644 --- a/src/libraries/JANA/JApplication.h +++ b/src/libraries/JANA/JApplication.h @@ -18,6 +18,9 @@ T JApplication::GetParameterValue(std::string name) { /// A convenience method which delegates to JParameterManager template JParameter* JApplication::SetParameterValue(std::string name, T val) { + if (m_initialized) { + throw JException("SetParameterValue() must be called before Initialize(), as otherwise the parameter value won't be used!"); + } return m_params->SetParameter(name, val); } @@ -39,12 +42,22 @@ JParameter* JApplication::GetParameter(std::string name, T& result) { /// A convenience method which delegates to JServiceLocator template std::shared_ptr JApplication::GetService() { + if (!m_services_available) { + LOG_WARN(m_logger) << "GetService() called before Initialize(): Any parameter values set after this point won't be used!" << LOG_END; + // Eventually, GetService() could trigger Initialize() just like Run() does. + // In order to make this happen, JTopologyBuilder needs modification. + // The blockers are SubeventExample, TopologyTests, SubeventTests + //throw JException("Application needs initialization before services become available"); + } return m_service_locator->get(); } /// A convenience method which delegates to JServiceLocator template void JApplication::ProvideService(std::shared_ptr service) { + if (m_initialized) { + throw JException("Services need to be provided before JApplication::Initialize(), or inside InitPlugin()"); + } service->SetApplication(this); m_service_locator->provide(service); } diff --git a/src/libraries/JANA/JApplicationFwd.h b/src/libraries/JANA/JApplicationFwd.h index 2d251264a..082311180 100644 --- a/src/libraries/JANA/JApplicationFwd.h +++ b/src/libraries/JANA/JApplicationFwd.h @@ -146,6 +146,7 @@ class JApplication { bool m_draining_queues = false; bool m_skip_join = false; std::atomic_bool m_initialized {false}; + std::atomic_bool m_services_available {false}; bool m_ticker_on = true; bool m_timeout_on = true; bool m_extended_report = false; diff --git a/src/libraries/JANA/Omni/JComponent.h b/src/libraries/JANA/Omni/JComponent.h index 18cdcbce6..b37ab587e 100644 --- a/src/libraries/JANA/Omni/JComponent.h +++ b/src/libraries/JANA/Omni/JComponent.h @@ -91,9 +91,19 @@ class JComponent::Service : public JComponent::ServiceBase { } ServiceT& operator()() { + if (m_data == nullptr) { + throw JException("Attempted to access a Service which hasn't been attached to this Component yet!"); + } return *m_data; } + ServiceT* operator->() { + if (m_data == nullptr) { + throw JException("Attempted to access a Service which hasn't been attached to this Component yet!"); + } + return m_data.get(); + } + protected: void Init(JApplication* app) { diff --git a/src/libraries/JANA/Services/JComponentManager.cc b/src/libraries/JANA/Services/JComponentManager.cc index 548e03656..d9b34939c 100644 --- a/src/libraries/JANA/Services/JComponentManager.cc +++ b/src/libraries/JANA/Services/JComponentManager.cc @@ -30,15 +30,13 @@ JComponentManager::~JComponentManager() { } } -void JComponentManager::InitPhase2() { +void JComponentManager::Init() { - // We don't set these in Init() because Init() gets called by the JApplication constructor and we want to give the user a chance to - // set them manually before they call JApplication::Init(). - m_params().SetDefaultParameter("event_source_type", m_user_evt_src_typename, "Manually specifies which JEventSource should open the input file"); - m_params().SetDefaultParameter("record_call_stack", m_enable_call_graph_recording, "Records a trace of who called each factory. Reduces performance but necessary for plugins such as janadot."); - m_params().SetDefaultParameter("jana:nevents", m_nevents, "Max number of events that sources can emit"); - m_params().SetDefaultParameter("jana:nskip", m_nskip, "Number of events that sources should skip before starting emitting"); - m_params().FilterParameters(m_default_tags, "DEFTAG:"); + m_params->SetDefaultParameter("event_source_type", m_user_evt_src_typename, "Manually specifies which JEventSource should open the input file"); + m_params->SetDefaultParameter("record_call_stack", m_enable_call_graph_recording, "Records a trace of who called each factory. Reduces performance but necessary for plugins such as janadot."); + m_params->SetDefaultParameter("jana:nevents", m_nevents, "Max number of events that sources can emit"); + m_params->SetDefaultParameter("jana:nskip", m_nskip, "Number of events that sources should skip before starting emitting"); + m_params->FilterParameters(m_default_tags, "DEFTAG:"); // Look for factories to auto-activate // Right now AutoActivator parameter won't show up in parameters list. Reconsider this. @@ -47,6 +45,29 @@ void JComponentManager::InitPhase2() { } } +void JComponentManager::configure_components() { + for (auto* src : m_evt_srces) { + src->SetApplication(GetApplication()); + src->SetLogger(m_logging->get_logger(src->GetLoggerName())); + } + for (auto* proc : m_evt_procs) { + proc->SetApplication(GetApplication()); + proc->SetLogger(m_logging->get_logger(proc->GetLoggerName())); + } + for (auto* fac_gen : m_fac_gens) { + fac_gen->SetApplication(GetApplication()); + //fac_gen->SetLogger(m_logging->get_logger(fac_gen->GetLoggerName())); + } + for (auto* src_gen : m_src_gens) { + src_gen->SetJApplication(GetApplication()); + //src_gen->SetLogger(m_logging->get_logger(src_gen->GetLoggerName())); + } + for (auto* unfolder : m_unfolders) { + unfolder->SetApplication(GetApplication()); + unfolder->SetLogger(m_logging->get_logger(unfolder->GetLoggerName())); + } +} + void JComponentManager::next_plugin(std::string plugin_name) { // We defer resolving event sources until we have finished loading all plugins m_current_plugin_name = plugin_name; @@ -58,36 +79,26 @@ void JComponentManager::add(std::string event_source_name) { void JComponentManager::add(JEventSourceGenerator *source_generator) { source_generator->SetPluginName(m_current_plugin_name); - source_generator->SetJApplication(GetApplication()); - // source_generator->SetLogger(m_logging().get_logger(source_generator->GetLoggerName())); m_src_gens.push_back(source_generator); } void JComponentManager::add(JFactoryGenerator *factory_generator) { factory_generator->SetPluginName(m_current_plugin_name); - factory_generator->SetApplication(GetApplication()); - // factory_generator->SetLogger(m_logging().get_logger(factory_generator->GetLoggerName())); m_fac_gens.push_back(factory_generator); } void JComponentManager::add(JEventSource *event_source) { event_source->SetPluginName(m_current_plugin_name); - event_source->SetApplication(GetApplication()); - event_source->SetLogger(m_logging().get_logger(event_source->GetLoggerName())); m_evt_srces.push_back(event_source); } void JComponentManager::add(JEventProcessor *processor) { processor->SetPluginName(m_current_plugin_name); - processor->SetApplication(GetApplication()); - processor->SetLogger(m_logging().get_logger(processor->GetLoggerName())); m_evt_procs.push_back(processor); } void JComponentManager::add(JEventUnfolder* unfolder) { unfolder->SetPluginName(m_current_plugin_name); - unfolder->SetApplication(GetApplication()); - unfolder->SetLogger(m_logging().get_logger(unfolder->GetLoggerName())); m_unfolders.push_back(unfolder); } @@ -99,6 +110,7 @@ void JComponentManager::configure_event(JEvent& event) { } + void JComponentManager::resolve_event_sources() { m_user_evt_src_gen = resolve_user_event_source_generator(); diff --git a/src/libraries/JANA/Services/JComponentManager.h b/src/libraries/JANA/Services/JComponentManager.h index ff5c4b6f5..bd42b94ad 100644 --- a/src/libraries/JANA/Services/JComponentManager.h +++ b/src/libraries/JANA/Services/JComponentManager.h @@ -20,7 +20,7 @@ class JComponentManager : public JService { explicit JComponentManager(); ~JComponentManager() override; - void InitPhase2(); + void Init() override; void next_plugin(std::string plugin_name); @@ -31,6 +31,7 @@ class JComponentManager : public JService { void add(JEventProcessor* processor); void add(JEventUnfolder* unfolder); + void configure_components(); void resolve_event_sources(); JEventSourceGenerator* resolve_user_event_source_generator() const; JEventSourceGenerator* resolve_event_source(std::string source_name) const; diff --git a/src/libraries/JANA/Services/JLoggingService.cc b/src/libraries/JANA/Services/JLoggingService.cc index 4e9283d40..69645e792 100644 --- a/src/libraries/JANA/Services/JLoggingService.cc +++ b/src/libraries/JANA/Services/JLoggingService.cc @@ -30,8 +30,11 @@ inline void JParameterManager::Parse(const std::string& in, JLogger::Level& out) else if (std::strcmp(token.c_str(), "fatal") == 0) { out = JLogger::Level::FATAL; } + else if (std::strcmp(token.c_str(), "off") == 0) { + out = JLogger::Level::OFF; + } else { - throw JException("Unable to parse log level: '%s'. Options are: TRACE, DEBUG, INFO, WARN, ERROR, FATAL", in.c_str()); + throw JException("Unable to parse log level: '%s'. Options are: TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF", in.c_str()); } } diff --git a/src/libraries/JANA/Services/JPluginLoader.cc b/src/libraries/JANA/Services/JPluginLoader.cc index ed5fe08f3..eee7c5eee 100644 --- a/src/libraries/JANA/Services/JPluginLoader.cc +++ b/src/libraries/JANA/Services/JPluginLoader.cc @@ -14,12 +14,12 @@ class JApplication; -void JPluginLoader::InitPhase2() { +void JPluginLoader::Init() { - m_params().SetDefaultParameter("plugins", m_plugins_to_include, "Comma-separated list of plugins to load."); - m_params().SetDefaultParameter("plugins_to_ignore", m_plugins_to_exclude, "Comma-separated list of plugins to NOT load, even if they are specified in 'plugins'."); - m_params().SetDefaultParameter("jana:plugin_path", m_plugin_paths_str, "Colon-separated list of paths to search for plugins"); - m_params().SetDefaultParameter("jana:debug_plugin_loading", m_verbose, "Trace the plugin search path and display any loading errors"); + m_params->SetDefaultParameter("plugins", m_plugins_to_include, "Comma-separated list of plugins to load."); + m_params->SetDefaultParameter("plugins_to_ignore", m_plugins_to_exclude, "Comma-separated list of plugins to NOT load, even if they are specified in 'plugins'."); + m_params->SetDefaultParameter("jana:plugin_path", m_plugin_paths_str, "Colon-separated list of paths to search for plugins"); + m_params->SetDefaultParameter("jana:debug_plugin_loading", m_verbose, "Trace the plugin search path and display any loading errors"); if (m_verbose) { // The jana:debug_plugin_loading parameter is kept around for backwards compatibility diff --git a/src/libraries/JANA/Services/JPluginLoader.h b/src/libraries/JANA/Services/JPluginLoader.h index ddd46a200..7078a6206 100644 --- a/src/libraries/JANA/Services/JPluginLoader.h +++ b/src/libraries/JANA/Services/JPluginLoader.h @@ -22,7 +22,7 @@ class JPluginLoader : public JService { JPluginLoader(); ~JPluginLoader() override; - void InitPhase2(); + void Init() override; void add_plugin(std::string plugin_name); void add_plugin_path(std::string path); diff --git a/src/programs/unit_tests/JEventProcessorSequentialTests.cc b/src/programs/unit_tests/JEventProcessorSequentialTests.cc index 8fe702bb8..f971fbc4c 100644 --- a/src/programs/unit_tests/JEventProcessorSequentialTests.cc +++ b/src/programs/unit_tests/JEventProcessorSequentialTests.cc @@ -50,14 +50,14 @@ struct MyRootProcessor : public JEventProcessorSequentialRoot { TEST_CASE("JEventProcessorSequentialRootTests") { - JParameterManager *params = new JParameterManager; - // params->SetParameter("log:trace", "JScheduler,JArrow,JArrowProcessingController"); - JApplication app(params); + JApplication app; app.Add(new DummySource); app.SetParameterValue("nthreads", 4); app.SetParameterValue("jana:nevents", 4); app.SetParameterValue("jana:event_source_chunksize", 1); app.SetParameterValue("jana:event_processor_chunksize", 1); + app.SetParameterValue("log:global", "OFF"); + app.SetParameterValue("log:warn", "JScheduler,JArrow,JArrowProcessingController"); auto proc = new MyRootProcessor; app.Add(proc); app.Run(true); @@ -137,14 +137,14 @@ struct MySeqProcessor : public JEventProcessorSequential { TEST_CASE("JEventProcessorSequentialTests") { - JParameterManager *params = new JParameterManager; - // params->SetParameter("log:trace", "JScheduler,JArrow,JArrowProcessingController"); - JApplication app(params); + JApplication app; app.Add(new DummySource); app.SetParameterValue("nthreads", 4); app.SetParameterValue("jana:nevents", 4); app.SetParameterValue("jana:event_source_chunksize", 1); app.SetParameterValue("jana:event_processor_chunksize", 1); + app.SetParameterValue("log:global", "OFF"); + app.SetParameterValue("log:warn", "JScheduler,JArrow,JArrowProcessingController"); auto proc = new MySeqProcessor; app.Add(proc); app.Run(true); diff --git a/src/programs/unit_tests/JMultiFactoryTests.cc b/src/programs/unit_tests/JMultiFactoryTests.cc index 8a00652c3..8cc5402e5 100644 --- a/src/programs/unit_tests/JMultiFactoryTests.cc +++ b/src/programs/unit_tests/JMultiFactoryTests.cc @@ -79,6 +79,7 @@ TEST_CASE("MultiFactoryTests") { SECTION("Multifactories work with JFactoryGeneratorT") { app.Add(new JFactoryGeneratorT()); + app.Initialize(); auto jcm = app.GetService(); auto event = std::make_shared(&app); jcm->configure_event(*event); @@ -89,6 +90,7 @@ TEST_CASE("MultiFactoryTests") { SECTION("Test that multifactory Process() is only called once") { app.Add(new JFactoryGeneratorT()); + app.Initialize(); auto jcm = app.GetService(); auto event = std::make_shared(&app); jcm->configure_event(*event); diff --git a/src/programs/unit_tests/JServiceLocatorTests.cc b/src/programs/unit_tests/JServiceLocatorTests.cc index 329e9685b..41f00b369 100644 --- a/src/programs/unit_tests/JServiceLocatorTests.cc +++ b/src/programs/unit_tests/JServiceLocatorTests.cc @@ -81,7 +81,7 @@ struct OmniService : public JService { void Init() override { LOG_INFO(GetLogger()) << "Calling OmniService::Init" << LOG_END; - REQUIRE(parman().GetParameterValue("bucket_count") == 22); + REQUIRE(parman->GetParameterValue("bucket_count") == 22); REQUIRE(bucket_count() == 22); } }; diff --git a/src/programs/unit_tests/MultiLevelTopologyTests.cc b/src/programs/unit_tests/MultiLevelTopologyTests.cc index dfefe17dc..650c8b561 100644 --- a/src/programs/unit_tests/MultiLevelTopologyTests.cc +++ b/src/programs/unit_tests/MultiLevelTopologyTests.cc @@ -432,10 +432,9 @@ TEST_CASE("MultiLevelTopologyBuilderTests") { TEST_CASE("TimeslicesTests") { - auto parms = new JParameterManager; - parms->SetParameter("log:trace", "JScheduler,JArrow,JArrowProcessingController"); - parms->SetParameter("jana:nevents", "5"); - JApplication app(parms); + JApplication app; + app.SetParameterValue("log:info", "JScheduler,JArrow,JArrowProcessingController"); + app.SetParameterValue("jana:nevents", "5"); app.Add(new MyTimesliceSource); app.Add(new MyTimesliceUnfolder); diff --git a/src/programs/unit_tests/NEventNSkipTests.cc b/src/programs/unit_tests/NEventNSkipTests.cc index 36cbdbc1d..160c4e19f 100644 --- a/src/programs/unit_tests/NEventNSkipTests.cc +++ b/src/programs/unit_tests/NEventNSkipTests.cc @@ -77,9 +77,8 @@ TEST_CASE("NEventNSkipTests") { } TEST_CASE("JEventSourceArrow with multiple JEventSources") { - JParameterManager* params = new JParameterManager; - params->SetParameter("log:debug","JArrow,JArrowProcessingController"); - JApplication app(params); + JApplication app; + app.SetParameterValue("log:info","JArrow,JArrowProcessingController"); auto source1 = new NEventNSkipBoundedSource(); auto source2 = new NEventNSkipBoundedSource(); auto source3 = new NEventNSkipBoundedSource(); diff --git a/src/programs/unit_tests/ScaleTests.cc b/src/programs/unit_tests/ScaleTests.cc index e8e4c0381..3ddffe149 100644 --- a/src/programs/unit_tests/ScaleTests.cc +++ b/src/programs/unit_tests/ScaleTests.cc @@ -8,10 +8,10 @@ TEST_CASE("NThreads") { - auto parms = new JParameterManager; - // parms->SetParameter("log:debug","JScheduler,JArrowProcessingController,JWorker,JArrow"); - parms->SetParameter("jana:nevents",3); - JApplication app(parms); + JApplication app; + app.SetParameterValue("jana:nevents",3); + app.SetParameterValue("log:global", "OFF"); + app.SetParameterValue("log:warn", "JScheduler,JArrow,JWorker,JArrowProcessingController"); app.Add(new scaletest::DummySource); SECTION("If nthreads not provided, default to 1") { @@ -37,12 +37,12 @@ TEST_CASE("NThreads") { } TEST_CASE("ScaleNWorkerUpdate") { - auto params = new JParameterManager(); - // params->SetParameter("log:debug", "JWorker,JArrowTopology,JScheduler,JArrow"); - JApplication app(params); + JApplication app; + app.SetParameterValue("nthreads",4); + app.SetParameterValue("log:global", "OFF"); + app.SetParameterValue("log:warn", "JScheduler,JArrow,JWorker,JArrowProcessingController"); app.Add(new scaletest::DummySource); app.Add(new scaletest::DummyProcessor); - app.SetParameterValue("nthreads", 4); app.Run(false); auto threads = app.GetNThreads(); REQUIRE(threads == 4); @@ -64,10 +64,9 @@ TEST_CASE("ScaleNWorkerUpdate") { TEST_CASE("ScaleThroughputImprovement", "[.][performance]") { - auto parms = new JParameterManager; - // parms->SetParameter("log:debug","JArrowProcessingController,JWorker,JArrow"); - // parms->SetParameter("log:info","JScheduler"); - JApplication app(parms); + JApplication app; + app.SetParameterValue("log:global", "INFO"); + // app.SetParameterValue("log:warn", "JScheduler,JArrow,JWorker,JArrowProcessingController"); app.SetTicker(false); app.Add(new scaletest::DummySource); app.Add(new scaletest::DummyProcessor); diff --git a/src/programs/unit_tests/SubeventTests.cc b/src/programs/unit_tests/SubeventTests.cc index 7e4f44a72..c4b1608af 100644 --- a/src/programs/unit_tests/SubeventTests.cc +++ b/src/programs/unit_tests/SubeventTests.cc @@ -169,10 +169,8 @@ TEST_CASE("Basic subevent arrow functionality") { SECTION("Execute subevent arrows end-to-end using same example as in JSubeventMailbox") { - auto parms = new JParameterManager; - // Some params need to be present BEFORE JApplication is constructed, e.g. log levels are lost - parms->SetParameter("log:trace", "JWorker,JScheduler,JArrow,JArrowProcessingController,JEventProcessorArrow"); - JApplication app(parms); + JApplication app; + app.SetParameterValue("log:info", "JWorker,JScheduler,JArrow,JArrowProcessingController,JEventProcessorArrow"); app.SetTimeoutEnabled(false); app.SetTicker(false); diff --git a/src/programs/unit_tests/TerminationTests.cc b/src/programs/unit_tests/TerminationTests.cc index 1a4974624..06133bbd3 100644 --- a/src/programs/unit_tests/TerminationTests.cc +++ b/src/programs/unit_tests/TerminationTests.cc @@ -14,29 +14,26 @@ TEST_CASE("TerminationTests") { - auto parms = new JParameterManager; - // parms->SetParameter("log:debug","JScheduler,JArrowProcessingController,JWorker,JArrow"); - JApplication app(parms); + JApplication app; + app.SetParameterValue("log:global", "OFF"); auto processor = new CountingProcessor(); app.Add(processor); app.SetParameterValue("jana:extended_report", 0); - SECTION("Arrow engine, manual termination") { + SECTION("Manual termination") { - app.SetParameterValue("jana:engine", 0); auto source = new UnboundedSource(); app.Add(source); app.Run(false); - std::this_thread::sleep_for(std::chrono::milliseconds(50)); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); app.Stop(true); REQUIRE(source->event_count > 0); REQUIRE(processor->finish_call_count == 1); REQUIRE(app.GetNEventsProcessed() == source->event_count); } - SECTION("Arrow engine, self termination") { + SECTION("Self termination") { - app.SetParameterValue("jana:engine", 0); auto source = new BoundedSource(); app.Add(source); app.Run(true); @@ -46,47 +43,14 @@ TEST_CASE("TerminationTests") { REQUIRE(app.GetNEventsProcessed() == source->event_count); } - SECTION("Arrow engine, interrupted during JEventSource::Open()") { + SECTION("Interrupted during JEventSource::Open()") { - // TODO: This test is kind of useless now that JEventSource::Open is called from - // JEventSourceArrow::execute rather than JEventSourceArrow::initialize(). - // What we really want is an Arrow that has an initialize() that we override. - // However to do that, we need to extend JESA and create a custom topology. - app.SetParameterValue("jana:engine", 0); auto source = new InterruptedSource(); app.Add(source); app.Run(true); - REQUIRE(processor->processed_count == 1); // TODO: Was 0, should become zero again REQUIRE(processor->finish_call_count == 1); - // Stop() tells JApplication to finish Initialize() but not to proceed with Run(). - // If we had called Quit() instead, it would have exited Initialize() immediately and ended the program. - REQUIRE(app.GetNEventsProcessed() == source->GetEventCount()); - } - - SECTION("Debug engine, self-termination") { - - app.SetParameterValue("jana:engine", 1); - auto source = new BoundedSource(); - app.Add(source); - app.Run(true); - REQUIRE(source->event_count == 10); - REQUIRE(processor->processed_count == 10); - REQUIRE(processor->finish_call_count == 1); - REQUIRE(app.GetNEventsProcessed() == source->event_count); - } - - SECTION("Debug engine, manual termination") { - - app.SetParameterValue("jana:engine", 1); - auto source = new UnboundedSource(); - app.Add(source); - app.Run(false); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - app.Stop(true); - REQUIRE(source->event_count > 0); - REQUIRE(app.GetNEventsProcessed() == source->event_count); - REQUIRE(processor->finish_call_count == 1); + // We don't know how many events will emit before Stop() request propagates } }; diff --git a/src/programs/unit_tests/UnfoldTests.cc b/src/programs/unit_tests/UnfoldTests.cc index 699feea62..fe31c174b 100644 --- a/src/programs/unit_tests/UnfoldTests.cc +++ b/src/programs/unit_tests/UnfoldTests.cc @@ -43,6 +43,7 @@ struct TestUnfolder : public JEventUnfolder { TEST_CASE("UnfoldTests_Basic") { JApplication app; + app.Initialize(); auto jcm = app.GetService(); JEventPool parent_pool {jcm, 5, 1, true, JEventLevel::Timeslice}; // size=5, locations=1, limit_total_events_in_flight=true @@ -83,7 +84,9 @@ TEST_CASE("UnfoldTests_Basic") { TEST_CASE("FoldArrowTests") { JApplication app; + app.Initialize(); auto jcm = app.GetService(); + // We only use these to obtain preconfigured JEvents JEventPool parent_pool {jcm, 5, 1, true, JEventLevel::Timeslice}; // size=5, locations=1, limit_total_events_in_flight=true diff --git a/src/programs/unit_tests/UserExceptionTests.cc b/src/programs/unit_tests/UserExceptionTests.cc index cae310584..4593ef781 100644 --- a/src/programs/unit_tests/UserExceptionTests.cc +++ b/src/programs/unit_tests/UserExceptionTests.cc @@ -9,87 +9,40 @@ TEST_CASE("UserExceptionTests") { - auto parms = new JParameterManager; - //parms->SetParameter("log:debug","JApplication,JScheduler,JArrowProcessingController,JWorker,JArrow"); - JApplication app(parms); + JApplication app; + app.SetParameterValue("log:debug","JApplication,JScheduler,JArrowProcessingController,JWorker,JArrow"); app.SetParameterValue("jana:extended_report", 0); - SECTION("JEventSource::Open() excepts, debug engine") { + SECTION("JEventSource::Open() excepts") { - app.SetParameterValue("jana:engine", 1); app.Add(new FlakySource(true, false)); app.Add(new FlakyProcessor(false, false, false)); REQUIRE_THROWS(app.Run(true)); } - SECTION("JEventSource::GetEvent() excepts, debug engine") { + SECTION("JEventSource::GetEvent() excepts") { - app.SetParameterValue("jana:engine", 1); - app.Add(new FlakySource(false, true)); - app.Add(new FlakyProcessor(false, false, false)); - REQUIRE_THROWS(app.Run(true)); - } - - - SECTION("JEventProcessor::Init() excepts, debug engine") { - - app.SetParameterValue("jana:engine", 1); - app.Add(new FlakySource(false, false)); - app.Add(new FlakyProcessor(true, false, false)); - REQUIRE_THROWS(app.Run(true)); - } - - SECTION("JEventProcessor::Process() excepts, debug engine") { - - app.SetParameterValue("jana:engine", 1); - app.Add(new FlakySource(false, false)); - app.Add(new FlakyProcessor(false, true, false)); - REQUIRE_THROWS(app.Run(true)); - } - - SECTION("JEventProcessor::Finish() excepts, debug engine") { - - app.SetParameterValue("jana:engine", 1); - app.Add(new FlakySource(false, false)); - app.Add(new FlakyProcessor(false, false, true)); - REQUIRE_THROWS(app.Run(true)); - } - - SECTION("JEventSource::Open() excepts, default engine") { - - app.SetParameterValue("jana:engine", 0); - app.Add(new FlakySource(true, false)); - app.Add(new FlakyProcessor(false, false, false)); - REQUIRE_THROWS(app.Run(true)); - } - - SECTION("JEventSource::GetEvent() excepts, default engine") { - - app.SetParameterValue("jana:engine", 0); app.Add(new FlakySource(false, true)); app.Add(new FlakyProcessor(false, false, false)); REQUIRE_THROWS(app.Run(true)); } - SECTION("JEventProcessor::Init() excepts, default engine") { + SECTION("JEventProcessor::Init() excepts") { - app.SetParameterValue("jana:engine", 0); app.Add(new FlakySource(false, false)); app.Add(new FlakyProcessor(true, false, false)); REQUIRE_THROWS(app.Run(true)); } - SECTION("JEventProcessor::Process() excepts, default engine") { + SECTION("JEventProcessor::Process() excepts") { - app.SetParameterValue("jana:engine", 0); app.Add(new FlakySource(false, false)); app.Add(new FlakyProcessor(false, true, false)); REQUIRE_THROWS(app.Run(true)); } - SECTION("JEventProcessor::Finish() excepts, default engine") { + SECTION("JEventProcessor::Finish() excepts") { - app.SetParameterValue("jana:engine", 0); app.Add(new FlakySource(false, false)); app.Add(new FlakyProcessor(false, false, true)); REQUIRE_THROWS(app.Run(true));