Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-07-24 02:01:38

0001 #include "catch.hpp"
0002 
0003 #include "FWCore/Framework/src/ScheduleBuilder.h"
0004 #include "FWCore/Framework/interface/global/EDProducer.h"
0005 #include "FWCore/Framework/interface/ModuleRegistry.h"
0006 #include "FWCore/Framework/interface/PreallocationConfiguration.h"
0007 #include "FWCore/Framework/interface/SignallingProductRegistryFiller.h"
0008 #include "FWCore/ServiceRegistry/interface/ActivityRegistry.h"
0009 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0010 #include "DataFormats/Provenance/interface/ProcessConfiguration.h"
0011 
0012 #include <vector>
0013 #include <string_view>
0014 namespace edm::test::sb {
0015   class SBIntProducer : public edm::global::EDProducer<> {
0016   public:
0017     explicit SBIntProducer(std::vector<edm::InputTag> const& iConsumes) {
0018       for (auto const& tag : iConsumes) {
0019         consumes<int>(tag);
0020       }
0021       produces<int>();
0022     }
0023     void produce(StreamID, edm::Event&, edm::EventSetup const&) const final {}
0024   };
0025 }  // namespace edm::test::sb
0026 
0027 namespace {
0028   struct ModuleInfo {
0029     std::string label_;
0030     std::string type_;
0031     std::string edmType_;
0032   };
0033   enum class EdmType { kProducer, kFilter, kAnalyzer, kSwitchProducer, kOutputModule };
0034 
0035   struct ConfigBuilder {
0036     void addModule(std::string const& iLabel, std::string const& iType, EdmType iEdmType) {
0037       ModuleInfo info = {.label_ = iLabel, .type_ = iType, .edmType_ = enumToName(iEdmType)};
0038       modules_.emplace_back(std::move(info));
0039     }
0040     std::string enumToName(EdmType iType) {
0041       switch (iType) {
0042         case EdmType::kProducer:
0043           return "EDProducer";
0044         case EdmType::kFilter:
0045           return "EDFilter";
0046         case EdmType::kAnalyzer:
0047           return "EDAnalyzer";
0048         case EdmType::kOutputModule:
0049           return "OutputModule";
0050         case EdmType::kSwitchProducer:
0051           return "SwitchProducer";
0052       }
0053       return "";
0054     }
0055     void addPath(std::string iName, std::vector<std::string> iModuleLabels) {
0056       paths_.emplace_back(std::move(iName), std::move(iModuleLabels));
0057     }
0058     void addEndPath(std::string iName, std::vector<std::string> iModuleLabels) {
0059       endpaths_.emplace_back(std::move(iName), std::move(iModuleLabels));
0060     }
0061     void addAllowedFilterOnEndPath(std::string iLabel) { allowedFiltersOnEndPaths_.emplace_back(std::move(iLabel)); }
0062 
0063     edm::ParameterSet buildConfig() {
0064       edm::ParameterSet config;
0065       config.addParameter<std::vector<std::string>>("@all_aliases", std::vector<std::string>());
0066       std::vector<std::string> pathNames;
0067       for (auto const& pathInfo : paths_) {
0068         pathNames.emplace_back(pathInfo.first);
0069         config.addParameter<std::vector<std::string>>(pathInfo.first, pathInfo.second);
0070       }
0071       for (auto const& pathInfo : endpaths_) {
0072         config.addParameter<std::vector<std::string>>(pathInfo.first, pathInfo.second);
0073       }
0074       edm::ParameterSet trigPaths;
0075       trigPaths.addParameter<std::vector<std::string>>("@trigger_paths", pathNames);
0076       config.addParameter<edm::ParameterSet>("@trigger_paths", trigPaths);
0077       std::vector<std::string> moduleLabels;
0078       moduleLabels.reserve(modules_.size());
0079       for (auto const& moduleInfo : modules_) {
0080         moduleLabels.emplace_back(moduleInfo.label_);
0081         edm::ParameterSet moduleConfig;
0082         moduleConfig.addParameter<std::string>("@module_type", moduleInfo.type_);
0083         moduleConfig.addParameter<std::string>("@module_edm_type", moduleInfo.edmType_);
0084         config.addParameter<edm::ParameterSet>(moduleInfo.label_, moduleConfig);
0085       }
0086       config.addParameter<std::vector<std::string>>("@all_modules", moduleLabels);
0087       config.addUntrackedParameter<std::vector<std::string>>("@filters_on_endpaths", allowedFiltersOnEndPaths_);
0088 
0089       return config;
0090     }
0091 
0092     std::vector<std::string> paths() {
0093       std::vector<std::string> ret;
0094       for (auto const& p : paths_) {
0095         ret.push_back(p.first);
0096       }
0097       return ret;
0098     }
0099 
0100     std::vector<std::string> endpaths() {
0101       std::vector<std::string> ret;
0102       for (auto const& p : endpaths_) {
0103         ret.push_back(p.first);
0104       }
0105       return ret;
0106     }
0107 
0108   private:
0109     std::vector<ModuleInfo> modules_;
0110     std::vector<std::pair<std::string, std::vector<std::string>>> paths_;
0111     std::vector<std::pair<std::string, std::vector<std::string>>> endpaths_;
0112     std::vector<std::string> allowedFiltersOnEndPaths_;
0113   };
0114 }  // namespace
0115 
0116 TEST_CASE("test edm::ScheduleBuilder", "[ScheduleBuilder]") {
0117   edm::HardwareResourcesDescription hardware;
0118   auto const processConfig = std::make_shared<edm::ProcessConfiguration const>("TEST", "CMSSW_X_Y_Z", hardware);
0119   edm::PreallocationConfiguration prealloc;
0120   SECTION("empty schedule") {
0121     edm::ModuleRegistry moduleRegistry;
0122     edm::SignallingProductRegistryFiller productRegistry;
0123     edm::ActivityRegistry activityRegistry;
0124 
0125     ConfigBuilder confBuilder;
0126     auto config = confBuilder.buildConfig();
0127     edm::ScheduleBuilder builder(moduleRegistry,
0128                                  config,
0129                                  confBuilder.paths(),
0130                                  confBuilder.endpaths(),
0131                                  prealloc,
0132                                  productRegistry,
0133                                  activityRegistry,
0134                                  processConfig);
0135 
0136     REQUIRE(builder.endpathNameAndModules_.empty());
0137     REQUIRE(builder.pathNameAndModules_.empty());
0138     REQUIRE(builder.allNeededModules_.empty());
0139     REQUIRE(builder.unscheduledModules_.empty());
0140     REQUIRE(builder.pathStatusInserters_.empty());
0141     REQUIRE(not builder.resultsInserter_);
0142   }
0143   SECTION("one module on path") {
0144     edm::SignallingProductRegistryFiller productRegistry;
0145     edm::ActivityRegistry activityRegistry;
0146 
0147     edm::ModuleRegistry moduleRegistry;
0148     edm::ParameterSet pset;
0149     pset.addParameter<std::string>("@module_type", "edm::test::sb::SBIntProducer");
0150     pset.addParameter<std::string>("@module_edm_type", "EDProducer");
0151     pset.registerIt();
0152 
0153     edm::ModuleDescription desc(
0154         pset.id(), "edm::test::sb::SBIntProducer", "prod1", processConfig.get(), edm::ModuleDescription::getUniqueID());
0155     moduleRegistry.makeExplicitModule<edm::test::sb::SBIntProducer>(desc,
0156                                                                     prealloc,
0157                                                                     &productRegistry,
0158                                                                     activityRegistry.preModuleConstructionSignal_,
0159                                                                     activityRegistry.postModuleConstructionSignal_,
0160                                                                     std::vector<edm::InputTag>());
0161 
0162     ConfigBuilder confBuilder;
0163     confBuilder.addModule("prod1", "edm::test::sb::SBIntProducer", EdmType::kProducer);
0164     confBuilder.addPath("p1", {{"prod1"}});
0165     auto config = confBuilder.buildConfig();
0166     edm::ScheduleBuilder builder(moduleRegistry,
0167                                  config,
0168                                  confBuilder.paths(),
0169                                  confBuilder.endpaths(),
0170                                  prealloc,
0171                                  productRegistry,
0172                                  activityRegistry,
0173                                  processConfig);
0174 
0175     REQUIRE(builder.endpathNameAndModules_.empty());
0176     REQUIRE(builder.pathNameAndModules_.size() == 1);
0177     REQUIRE(builder.pathNameAndModules_.front().first == "p1");
0178     REQUIRE(builder.pathNameAndModules_.front().second.size() == 1);
0179     auto moduleInfo = builder.pathNameAndModules_.front().second.front();
0180     REQUIRE(moduleInfo.description_->moduleLabel() == "prod1");
0181     REQUIRE(moduleInfo.description_->moduleName() == "edm::test::sb::SBIntProducer");
0182     REQUIRE(moduleInfo.action_ == edm::WorkerInPath::Normal);
0183     REQUIRE(moduleInfo.placeInPath_ == 0);
0184     REQUIRE(moduleInfo.runConcurrently_ == true);
0185     REQUIRE(builder.allNeededModules_.size() == 3);
0186     REQUIRE(std::find_if(builder.allNeededModules_.begin(), builder.allNeededModules_.end(), [&desc](auto const* el) {
0187               return *el == desc;
0188             }) != builder.allNeededModules_.end());
0189     REQUIRE(builder.unscheduledModules_.empty());
0190     REQUIRE(builder.pathStatusInserters_.size() == 1);
0191     REQUIRE(builder.endPathStatusInserters_.empty());
0192     REQUIRE(builder.resultsInserter_);
0193   }
0194 
0195   SECTION("one module on endpath") {
0196     //If there is only one endpath no end path status inserter is added to the system
0197     edm::SignallingProductRegistryFiller productRegistry;
0198     edm::ActivityRegistry activityRegistry;
0199 
0200     edm::ModuleRegistry moduleRegistry;
0201     edm::ParameterSet pset;
0202     pset.addParameter<std::string>("@module_type", "edm::test::sb::SBIntProducer");
0203     pset.addParameter<std::string>("@module_edm_type", "EDProducer");
0204     pset.registerIt();
0205 
0206     edm::ModuleDescription desc(
0207         pset.id(), "edm::test::sb::SBIntProducer", "prod1", processConfig.get(), edm::ModuleDescription::getUniqueID());
0208     moduleRegistry.makeExplicitModule<edm::test::sb::SBIntProducer>(desc,
0209                                                                     prealloc,
0210                                                                     &productRegistry,
0211                                                                     activityRegistry.preModuleConstructionSignal_,
0212                                                                     activityRegistry.postModuleConstructionSignal_,
0213                                                                     std::vector<edm::InputTag>());
0214 
0215     ConfigBuilder confBuilder;
0216     confBuilder.addModule("prod1", "edm::test::sb::SBIntProducer", EdmType::kProducer);
0217     confBuilder.addEndPath("e", {{"prod1"}});
0218     auto config = confBuilder.buildConfig();
0219     edm::ScheduleBuilder builder(moduleRegistry,
0220                                  config,
0221                                  confBuilder.paths(),
0222                                  confBuilder.endpaths(),
0223                                  prealloc,
0224                                  productRegistry,
0225                                  activityRegistry,
0226                                  processConfig);
0227 
0228     REQUIRE(builder.endpathNameAndModules_.size() == 1);
0229     REQUIRE(builder.endpathNameAndModules_.front().first == "e");
0230     REQUIRE(builder.endpathNameAndModules_.front().second.size() == 1);
0231     auto moduleInfo = builder.endpathNameAndModules_.front().second.front();
0232     REQUIRE(moduleInfo.description_->moduleLabel() == "prod1");
0233     REQUIRE(moduleInfo.description_->moduleName() == "edm::test::sb::SBIntProducer");
0234     REQUIRE(moduleInfo.action_ == edm::WorkerInPath::Normal);
0235     REQUIRE(moduleInfo.placeInPath_ == 0);
0236     REQUIRE(moduleInfo.runConcurrently_ == true);
0237     REQUIRE(builder.pathNameAndModules_.empty());
0238     REQUIRE(builder.allNeededModules_.size() == 1);
0239     REQUIRE(std::find_if(builder.allNeededModules_.begin(), builder.allNeededModules_.end(), [&desc](auto const* el) {
0240               return *el == desc;
0241             }) != builder.allNeededModules_.end());
0242     REQUIRE(builder.unscheduledModules_.empty());
0243     REQUIRE(builder.pathStatusInserters_.empty());
0244     REQUIRE(builder.endPathStatusInserters_.empty());
0245     REQUIRE(not builder.resultsInserter_);
0246   }
0247 }