Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-11-26 03:07:50

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