Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:12:40

0001 #define CATCH_CONFIG_MAIN
0002 #include "catch.hpp"
0003 
0004 #include "DataFormats/TestObjects/interface/ToyProducts.h"
0005 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0006 #include "FWCore/ParameterSetReader/interface/ParameterSetReader.h"
0007 #include "FWCore/TestProcessor/interface/TestProcessor.h"
0008 
0009 #include <iostream>
0010 
0011 static constexpr auto s_tag = "[SwitchProducer]";
0012 
0013 namespace {
0014   std::string makeConfig(bool test2Enabled,
0015                          const std::string& test1,
0016                          const std::string& test2,
0017                          const std::string& otherprod = "",
0018                          const std::string& othername = "") {
0019     std::string otherline;
0020     std::string othertask;
0021     if (not otherprod.empty()) {
0022       otherline = "process." + othername + " = " + otherprod + "\n";
0023       othertask = ", cms.Task(process." + othername + ")";
0024     }
0025 
0026     return std::string{
0027                R"_(from FWCore.TestProcessor.TestProcess import *
0028 import FWCore.ParameterSet.Config as cms
0029 
0030 class SwitchProducerTest(cms.SwitchProducer):
0031     def __init__(self, **kargs):
0032         super(SwitchProducerTest,self).__init__(
0033             dict(
0034                 test1 = lambda accelerators: (True, -10),
0035                 test2 = lambda accelerators: ()_"} +
0036            (test2Enabled ? "True" : "False") + ", -9)\n" +
0037            R"_(            ), **kargs)
0038 process = TestProcess()
0039 )_" + otherline +
0040            R"_(process.s = SwitchProducerTest(
0041    test1 = )_" +
0042            test1 + ",\n" + "   test2 = " + test2 + "\n" + ")\n" + "process.moduleToTest(process.s" + othertask + ")\n";
0043   }
0044 }  // namespace
0045 
0046 TEST_CASE("Configuration", s_tag) {
0047   const std::string test1{"cms.EDProducer('IntProducer', ivalue = cms.int32(1))"};
0048   const std::string test2{"cms.EDProducer('ManyIntProducer', ivalue = cms.int32(2), values = cms.VPSet())"};
0049 
0050   const std::string baseConfig = makeConfig(true, test1, test2);
0051   const std::string baseConfigTest2Disabled = makeConfig(false, test1, test2);
0052 
0053   SECTION("Configuration hash is not changed") {
0054     std::unique_ptr<edm::ParameterSet> pset, psetTest2Disabled;
0055     edm::makeParameterSets(baseConfig, pset);
0056     edm::makeParameterSets(baseConfigTest2Disabled, psetTest2Disabled);
0057     pset->registerIt();
0058     psetTest2Disabled->registerIt();
0059     REQUIRE(pset->id() == psetTest2Disabled->id());
0060   }
0061 
0062   edm::test::TestProcessor::Config config{baseConfig};
0063   edm::test::TestProcessor::Config configTest2Disabled{baseConfigTest2Disabled};
0064 
0065   SECTION("Base configuration is OK") { REQUIRE_NOTHROW(edm::test::TestProcessor(config)); }
0066 
0067   SECTION("No event data") {
0068     edm::test::TestProcessor tester(config);
0069     REQUIRE_NOTHROW(tester.test());
0070   }
0071 
0072   SECTION("beginJob and endJob only") {
0073     edm::test::TestProcessor tester(config);
0074     REQUIRE_NOTHROW(tester.testBeginAndEndJobOnly());
0075   }
0076 
0077   SECTION("Run with no LuminosityBlocks") {
0078     edm::test::TestProcessor tester(config);
0079     REQUIRE_NOTHROW(tester.testRunWithNoLuminosityBlocks());
0080   }
0081 
0082   SECTION("LuminosityBlock with no Events") {
0083     edm::test::TestProcessor tester(config);
0084     REQUIRE_NOTHROW(tester.testLuminosityBlockWithNoEvents());
0085   }
0086 
0087   SECTION("Test2 enabled") {
0088     edm::test::TestProcessor tester(config);
0089     auto event = tester.test();
0090     REQUIRE(event.get<edmtest::IntProduct>()->value == 2);
0091   }
0092 
0093   SECTION("Test2 disabled") {
0094     edm::test::TestProcessor tester(configTest2Disabled);
0095     auto event = tester.test();
0096     REQUIRE(event.get<edmtest::IntProduct>()->value == 1);
0097   }
0098 }
0099 
0100 TEST_CASE("Configuration with EDAlias", s_tag) {
0101   const std::string otherprod{"cms.EDProducer('ManyIntProducer', ivalue = cms.int32(2), values = cms.VPSet())"};
0102   const std::string othername{"intprod"};
0103 
0104   const std::string test1{"cms.EDProducer('IntProducer', ivalue = cms.int32(1))"};
0105   const std::string test2{"cms.EDAlias(intprod = cms.VPSet(cms.PSet(type = cms.string('edmtestIntProduct'))))"};
0106 
0107   const std::string baseConfig = makeConfig(true, test1, test2, otherprod, othername);
0108   const std::string baseConfigTest2Disabled = makeConfig(false, test1, test2, otherprod, othername);
0109 
0110   SECTION("Configuration hash is not changed") {
0111     std::unique_ptr<edm::ParameterSet> pset, psetTest2Disabled;
0112     edm::makeParameterSets(baseConfig, pset);
0113     edm::makeParameterSets(baseConfigTest2Disabled, psetTest2Disabled);
0114     pset->registerIt();
0115     psetTest2Disabled->registerIt();
0116     REQUIRE(pset->id() == psetTest2Disabled->id());
0117   }
0118 
0119   edm::test::TestProcessor::Config config{baseConfig};
0120   edm::test::TestProcessor::Config configTest2Disabled{baseConfigTest2Disabled};
0121 
0122   SECTION("Base configuration is OK") { REQUIRE_NOTHROW(edm::test::TestProcessor(config)); }
0123 
0124   SECTION("No event data") {
0125     edm::test::TestProcessor tester(config);
0126     REQUIRE_NOTHROW(tester.test());
0127   }
0128 
0129   SECTION("beginJob and endJob only") {
0130     edm::test::TestProcessor tester(config);
0131     REQUIRE_NOTHROW(tester.testBeginAndEndJobOnly());
0132   }
0133 
0134   SECTION("Run with no LuminosityBlocks") {
0135     edm::test::TestProcessor tester(config);
0136     REQUIRE_NOTHROW(tester.testRunWithNoLuminosityBlocks());
0137   }
0138 
0139   SECTION("LuminosityBlock with no Events") {
0140     edm::test::TestProcessor tester(config);
0141     REQUIRE_NOTHROW(tester.testLuminosityBlockWithNoEvents());
0142   }
0143 
0144   SECTION("Test2 enabled") {
0145     edm::test::TestProcessor tester(config);
0146     auto event = tester.test();
0147     REQUIRE(event.get<edmtest::IntProduct>()->value == 2);
0148   }
0149 
0150   SECTION("Test2 disabled") {
0151     edm::test::TestProcessor tester(configTest2Disabled);
0152     auto event = tester.test();
0153     REQUIRE(event.get<edmtest::IntProduct>()->value == 1);
0154   }
0155 }
0156 
0157 TEST_CASE("Configuration with many branches", s_tag) {
0158   const std::string test1{
0159       R"_(cms.EDProducer('ManyIntProducer', ivalue = cms.int32(1), values = cms.VPSet(cms.PSet(instance=cms.string('foo'),value=cms.int32(11)),
0160                                                                                        cms.PSet(instance=cms.string('bar'),value=cms.int32(21)))))_"};
0161   const std::string test2{
0162       R"_(cms.EDProducer('ManyIntProducer', ivalue = cms.int32(2), values = cms.VPSet(cms.PSet(instance=cms.string('foo'),value=cms.int32(12)),
0163                                                                                        cms.PSet(instance=cms.string('bar'),value=cms.int32(22)))))_"};
0164 
0165   const std::string baseConfig = makeConfig(true, test1, test2);
0166   const std::string baseConfigTest2Disabled = makeConfig(false, test1, test2);
0167 
0168   edm::test::TestProcessor::Config config{baseConfig};
0169   edm::test::TestProcessor::Config configTest2Disabled{baseConfigTest2Disabled};
0170 
0171   SECTION("Test2 enabled") {
0172     edm::test::TestProcessor tester(config);
0173     auto event = tester.test();
0174     REQUIRE(event.get<edmtest::IntProduct>()->value == 2);
0175     REQUIRE(event.get<edmtest::IntProduct>("foo")->value == 12);
0176     REQUIRE(event.get<edmtest::IntProduct>("bar")->value == 22);
0177   }
0178 
0179   SECTION("Test2 disabled") {
0180     edm::test::TestProcessor tester(configTest2Disabled);
0181     auto event = tester.test();
0182     REQUIRE(event.get<edmtest::IntProduct>()->value == 1);
0183     REQUIRE(event.get<edmtest::IntProduct>("foo")->value == 11);
0184     REQUIRE(event.get<edmtest::IntProduct>("bar")->value == 21);
0185   }
0186 }
0187 
0188 TEST_CASE("Configuration with many branches with EDAlias", s_tag) {
0189   const std::string otherprod{
0190       R"_(cms.EDProducer('ManyIntProducer', ivalue = cms.int32(2), values = cms.VPSet(cms.PSet(instance=cms.string('foo'),value=cms.int32(12)),
0191                                                                                        cms.PSet(instance=cms.string('bar'),value=cms.int32(22))))
0192 )_"};
0193   const std::string othername{"intprod"};
0194 
0195   const std::string test1{
0196       R"_(cms.EDProducer('ManyIntProducer', ivalue = cms.int32(1), values = cms.VPSet(cms.PSet(instance=cms.string('foo'),value=cms.int32(11)),
0197                                                                                        cms.PSet(instance=cms.string('bar'),value=cms.int32(21)))))_"};
0198   const std::string test2{
0199       R"_(cms.EDAlias(intprod = cms.VPSet(cms.PSet(type = cms.string('edmtestIntProduct'), fromProductInstance = cms.string(''), toProductInstance = cms.string('')),
0200                                                               cms.PSet(type = cms.string('edmtestIntProduct'), fromProductInstance = cms.string('foo'), toProductInstance = cms.string('foo')),
0201                                                               cms.PSet(type = cms.string('edmtestIntProduct'), fromProductInstance = cms.string('bar'), toProductInstance = cms.string('bar')))))_"};
0202 
0203   const std::string baseConfig = makeConfig(true, test1, test2, otherprod, othername);
0204   const std::string baseConfigTest2Disabled = makeConfig(false, test1, test2, otherprod, othername);
0205 
0206   edm::test::TestProcessor::Config config{baseConfig};
0207   edm::test::TestProcessor::Config configTest2Disabled{baseConfigTest2Disabled};
0208 
0209   SECTION("Test2 enabled") {
0210     edm::test::TestProcessor tester(config);
0211     auto event = tester.test();
0212     REQUIRE(event.get<edmtest::IntProduct>()->value == 2);
0213     REQUIRE(event.get<edmtest::IntProduct>("foo")->value == 12);
0214     REQUIRE(event.get<edmtest::IntProduct>("bar")->value == 22);
0215   }
0216 
0217   SECTION("Test2 disabled") {
0218     edm::test::TestProcessor tester(configTest2Disabled);
0219     auto event = tester.test();
0220     REQUIRE(event.get<edmtest::IntProduct>()->value == 1);
0221     REQUIRE(event.get<edmtest::IntProduct>("foo")->value == 11);
0222     REQUIRE(event.get<edmtest::IntProduct>("bar")->value == 21);
0223   }
0224 }
0225 
0226 TEST_CASE("Configuration with different branches", s_tag) {
0227   const std::string test1{"cms.EDProducer('ManyIntProducer', ivalue = cms.int32(1), values = cms.VPSet())"};
0228   const std::string test2{
0229       "cms.EDProducer('ManyIntProducer', ivalue = cms.int32(2), values = "
0230       "cms.VPSet(cms.PSet(instance=cms.string('foo'),value=cms.int32(3))))"};
0231 
0232   const std::string baseConfig1 = makeConfig(true, test1, test2);
0233   const std::string baseConfig2 = makeConfig(false, test1, test2);
0234 
0235   SECTION("Different branches are not allowed") {
0236     edm::test::TestProcessor::Config config1{baseConfig1};
0237     REQUIRE_THROWS_WITH(
0238         edm::test::TestProcessor(config1),
0239         Catch::Contains("that does not produce a product") && Catch::Contains("that is produced by the chosen case") &&
0240             Catch::Contains("Products for case s@test1") && Catch::Contains("Products for case s@test2") &&
0241             Catch::Contains("edmtestIntProduct \n") && Catch::Contains("edmtestIntProduct foo"));
0242 
0243     edm::test::TestProcessor::Config config2{baseConfig2};
0244     REQUIRE_THROWS_WITH(
0245         edm::test::TestProcessor(config2),
0246         Catch::Contains("with a product") && Catch::Contains("that is not produced by the chosen case") &&
0247             Catch::Contains("Products for case s@test1") && Catch::Contains("Products for case s@test2") &&
0248             Catch::Contains("edmtestIntProduct \n") && Catch::Contains("edmtestIntProduct foo"));
0249   }
0250 }
0251 
0252 TEST_CASE("Configuration with different transient branches", s_tag) {
0253   const std::string test1{"cms.EDProducer('ManyIntProducer', ivalue = cms.int32(1), values = cms.VPSet())"};
0254   const std::string test2{
0255       "cms.EDProducer('ManyIntProducer', ivalue = cms.int32(2), transientValues = "
0256       "cms.VPSet(cms.PSet(instance=cms.string('foo'),value=cms.int32(3))))"};
0257 
0258   const std::string baseConfig1 = makeConfig(true, test1, test2);
0259   const std::string baseConfig2 = makeConfig(false, test1, test2);
0260 
0261   SECTION("Different transient branches are allowed") {
0262     edm::test::TestProcessor::Config config1{baseConfig1};
0263     edm::test::TestProcessor testProcessor1{config1};
0264     auto event1 = testProcessor1.test();
0265     REQUIRE(event1.get<edmtest::IntProduct>()->value == 2);
0266 
0267     // It would be better if the next line of executable code would
0268     // throw an exception, but that is not the current expected behavior.
0269     // It would be nice to have all cases of a SwitchProducer fail if
0270     // any case fails on a "get" (but it is intentional and desirable
0271     // that it does not fail only because a  case declares it produces
0272     // different transient products). We decided it was not worth the
0273     // effort and complexity to implement this behavior (at least not yet).
0274     REQUIRE(event1.get<edmtest::TransientIntProduct>("foo")->value == 3);
0275 
0276     edm::test::TestProcessor::Config config2{baseConfig2};
0277     edm::test::TestProcessor testProcessor2{config2};
0278     auto event2 = testProcessor2.test();
0279     REQUIRE(event2.get<edmtest::IntProduct>()->value == 1);
0280     REQUIRE_THROWS(event2.get<edmtest::TransientIntProduct>()->value == 3);
0281   }
0282 }
0283 
0284 TEST_CASE("Configuration with different branches with EDAlias", s_tag) {
0285   const std::string otherprod{
0286       "cms.EDProducer('ManyIntProducer', ivalue = cms.int32(2), values = "
0287       "cms.VPSet(cms.PSet(instance=cms.string('foo'),value=cms.int32(3))))"};
0288   const std::string othername{"intprod"};
0289 
0290   const std::string test1{"cms.EDProducer('ManyIntProducer', ivalue = cms.int32(1), values = cms.VPSet())"};
0291   const std::string test2{
0292       R"_(cms.EDAlias(intprod = cms.VPSet(cms.PSet(type = cms.string('edmtestIntProduct'), fromProductInstance = cms.string(''), toProductInstance = cms.string('')),
0293                                                               cms.PSet(type = cms.string('edmtestIntProduct'), fromProductInstance = cms.string('foo'), toProductInstance = cms.string('foo')))))_"};
0294 
0295   const std::string baseConfig1 = makeConfig(true, test1, test2, otherprod, othername);
0296   const std::string baseConfig2 = makeConfig(false, test1, test2, otherprod, othername);
0297 
0298   SECTION("Different branches are not allowed") {
0299     edm::test::TestProcessor::Config config1{baseConfig1};
0300     REQUIRE_THROWS_WITH(
0301         edm::test::TestProcessor(config1),
0302         Catch::Contains("that does not produce a product") && Catch::Contains("that is produced by the chosen case") &&
0303             Catch::Contains("Products for case s@test1") && Catch::Contains("Products for case s@test2") &&
0304             Catch::Contains("edmtestIntProduct \n") && Catch::Contains("edmtestIntProduct foo"));
0305 
0306     edm::test::TestProcessor::Config config2{baseConfig2};
0307     REQUIRE_THROWS_WITH(
0308         edm::test::TestProcessor(config2),
0309         Catch::Contains("with a product") && Catch::Contains("that is not produced by the chosen case") &&
0310             Catch::Contains("Products for case s@test1") && Catch::Contains("Products for case s@test2") &&
0311             Catch::Contains("edmtestIntProduct \n") && Catch::Contains("edmtestIntProduct foo"));
0312   }
0313 }
0314 
0315 TEST_CASE("Configuration with lumi and run", s_tag) {
0316   const std::string test1{"cms.EDProducer('ThingProducer', nThings = cms.int32(10))"};
0317   const std::string test2{"cms.EDProducer('ThingProducer', nThings = cms.int32(20))"};
0318   const std::string baseConfig = makeConfig(true, test1, test2);
0319 
0320   edm::test::TestProcessor::Config config{baseConfig};
0321 
0322   SECTION("Lumi and run products are not supported") {
0323     REQUIRE_THROWS_WITH(edm::test::TestProcessor(config),
0324                         Catch::Contains("SwitchProducer does not support non-event branches"));
0325   }
0326 };
0327 
0328 TEST_CASE("Configuration with ROOT branch alias", s_tag) {
0329   const std::string test1{
0330       "cms.EDProducer('ManyIntProducer', ivalue = cms.int32(1), values = "
0331       "cms.VPSet(cms.PSet(instance=cms.string('foo'),value=cms.int32(3))))"};
0332   const std::string test2{
0333       "cms.EDProducer('ManyIntProducer', ivalue = cms.int32(2), values = "
0334       "cms.VPSet(cms.PSet(instance=cms.string('foo'),value=cms.int32(4),branchAlias=cms.string('bar'))))"};
0335 
0336   const std::string baseConfig1 = makeConfig(true, test1, test2);
0337   const std::string baseConfig2 = makeConfig(false, test1, test2);
0338 
0339   SECTION("ROOT branch aliases are not supported for the chosen case") {
0340     edm::test::TestProcessor::Config config{baseConfig1};
0341     REQUIRE_THROWS_WITH(edm::test::TestProcessor(config),
0342                         Catch::Contains("SwitchProducer does not support ROOT branch aliases"));
0343   }
0344 
0345   SECTION("ROOT branch aliases are not supported for the non-chosen case") {
0346     edm::test::TestProcessor::Config config{baseConfig2};
0347     REQUIRE_THROWS_WITH(edm::test::TestProcessor(config),
0348                         Catch::Contains("SwitchProducer does not support ROOT branch aliases"));
0349   }
0350 }