Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-05-23 03:13:16

0001 
0002 // Test code for the ParameterSetDescription and ParameterDescription
0003 // classes.
0004 
0005 #include "catch.hpp"
0006 
0007 #include "DataFormats/Provenance/interface/EventID.h"
0008 #include "DataFormats/Provenance/interface/LuminosityBlockID.h"
0009 #include "FWCore/ParameterSet/interface/AllowedLabelsDescription.h"
0010 #include "FWCore/ParameterSet/interface/IfExistsDescription.h"
0011 #include "FWCore/Utilities/interface/FileInPath.h"
0012 #include "FWCore/ParameterSet/interface/ParameterDescriptionBase.h"
0013 #include "FWCore/ParameterSet/interface/ParameterDescriptionNode.h"
0014 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0015 #include "FWCore/ParameterSet/interface/ParameterWildcardWithSpecifics.h"
0016 #include "FWCore/ParameterSet/interface/allowedValues.h"
0017 #include "FWCore/ParameterSet/interface/PluginDescription.h"
0018 #include "FWCore/ParameterSet/interface/ValidatedPluginMacros.h"
0019 #include "FWCore/ParameterSet/interface/ValidatedPluginFactoryMacros.h"
0020 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0021 #include "FWCore/PluginManager/interface/PluginManager.h"
0022 #include "FWCore/PluginManager/interface/standard.h"
0023 #include "FWCore/Utilities/interface/EDMException.h"
0024 #include "FWCore/Utilities/interface/Exception.h"
0025 #include "FWCore/Utilities/interface/InputTag.h"
0026 
0027 #include <cassert>
0028 #include <iostream>
0029 #include <string>
0030 #include <vector>
0031 
0032 namespace testParameterSetDescription {
0033 
0034   void testDesc(edm::ParameterDescriptionNode const& node,
0035                 edm::ParameterSetDescription const& psetDesc,
0036                 edm::ParameterSet& pset,
0037                 bool exists,
0038                 bool validates) {
0039     CHECK(node.exists(pset) == exists);
0040     CHECK(node.partiallyExists(pset) == exists);
0041     CHECK(node.howManyXORSubNodesExist(pset) == (exists ? 1 : 0));
0042     if (validates) {
0043       psetDesc.validate(pset);
0044     } else {
0045       REQUIRE_THROWS_AS(psetDesc.validate(pset), edm::Exception);
0046     }
0047   }
0048 
0049   struct TestPluginBase {
0050     virtual ~TestPluginBase() = default;
0051   };
0052 
0053   struct ATestPlugin : public TestPluginBase {
0054     static void fillPSetDescription(edm::ParameterSetDescription& iPS) { iPS.add<int>("anInt", 5); }
0055   };
0056 
0057   struct BTestPlugin : public TestPluginBase {
0058     static void fillPSetDescription(edm::ParameterSetDescription& iPS) { iPS.add<double>("aDouble", 0.5); }
0059   };
0060 
0061   using TestPluginFactory = edmplugin::PluginFactory<testParameterSetDescription::TestPluginBase*()>;
0062 
0063 }  // namespace testParameterSetDescription
0064 
0065 using TestPluginFactory = testParameterSetDescription::TestPluginFactory;
0066 
0067 using testParameterSetDescription::testDesc;
0068 
0069 TEST_CASE("test ParameterSetDescription", "[ParameterSetDescription]") {
0070   SECTION("testWildcards") {
0071     using Catch::Matchers::Equals;
0072     {
0073       edm::ParameterSetDescription set;
0074       edm::ParameterWildcard<int> w("*", edm::RequireZeroOrMore, true);
0075       set.addNode(w);
0076       edm::ParameterSet pset;
0077       testDesc(w, set, pset, true, true);
0078       pset.addParameter<int>("x", 1);
0079       testDesc(w, set, pset, true, true);
0080       pset.addParameter<int>("y", 1);
0081       testDesc(w, set, pset, true, true);
0082       pset.addParameter<unsigned>("z", 1);
0083       testDesc(w, set, pset, true, false);
0084 
0085       SECTION("cfi generation") {
0086         std::ostringstream os;
0087         bool startWithComma = false;
0088         bool wroteSomething = false;
0089         edm::CfiOptions ops = edm::cfi::Typed{};
0090         w.writeCfi(os, false, startWithComma, 0, ops, wroteSomething);
0091 
0092         REQUIRE_THAT(os.str(), Equals("\nallowAnyLabel_ = cms.required.int32"));
0093       }
0094     }
0095 
0096     {
0097       edm::ParameterSetDescription set;
0098       edm::ParameterWildcard<unsigned> w("*", edm::RequireExactlyOne, false);
0099       set.addNode(w);
0100       edm::ParameterSet pset;
0101       testDesc(w, set, pset, false, false);
0102       pset.addUntrackedParameter<unsigned>("x", 1);
0103       testDesc(w, set, pset, true, true);
0104       pset.addUntrackedParameter<unsigned>("y", 1);
0105       testDesc(w, set, pset, false, false);
0106 
0107       SECTION("cfi generation") {
0108         std::ostringstream os;
0109         bool startWithComma = false;
0110         bool wroteSomething = false;
0111         edm::CfiOptions ops = edm::cfi::Typed{};
0112 
0113         w.writeCfi(os, false, startWithComma, 0, ops, wroteSomething);
0114 
0115         REQUIRE_THAT(os.str(), Equals("\nallowAnyLabel_ = cms.required.untracked.uint32"));
0116       }
0117     }
0118 
0119     {
0120       edm::ParameterSetDescription set;
0121       edm::ParameterWildcard<unsigned> w("*", edm::RequireExactlyOne, false);
0122       set.addOptionalNode(w, false);
0123       edm::ParameterSet pset;
0124       testDesc(w, set, pset, false, true);
0125       pset.addUntrackedParameter<unsigned>("x", 1);
0126       testDesc(w, set, pset, true, true);
0127       pset.addUntrackedParameter<unsigned>("y", 1);
0128       testDesc(w, set, pset, false, false);
0129     }
0130 
0131     {
0132       edm::ParameterSetDescription set;
0133       edm::ParameterWildcard<unsigned> w("*", edm::RequireAtLeastOne, false);
0134       set.addOptionalNode(w, false);
0135       edm::ParameterSet pset;
0136       testDesc(w, set, pset, false, true);
0137       pset.addUntrackedParameter<unsigned>("x", 1);
0138       testDesc(w, set, pset, true, true);
0139       pset.addUntrackedParameter<unsigned>("y", 1);
0140       testDesc(w, set, pset, true, true);
0141     }
0142 
0143     {
0144       edm::ParameterSetDescription set;
0145       edm::ParameterWildcard<double> w("*", edm::RequireAtLeastOne, true);
0146       set.addNode(w);
0147       edm::ParameterSet pset;
0148       testDesc(w, set, pset, false, false);
0149       pset.addParameter<double>("x", 1);
0150       testDesc(w, set, pset, true, true);
0151       pset.addParameter<double>("y", 1);
0152       testDesc(w, set, pset, true, true);
0153 
0154       SECTION("cfi generation") {
0155         std::ostringstream os;
0156         bool startWithComma = false;
0157         bool wroteSomething = false;
0158         edm::CfiOptions ops = edm::cfi::Typed{};
0159 
0160         w.writeCfi(os, false, startWithComma, 0, ops, wroteSomething);
0161 
0162         REQUIRE_THAT(os.str(), Equals("\nallowAnyLabel_ = cms.required.double"));
0163       }
0164     }
0165 
0166     {
0167       edm::ParameterSetDescription set;
0168       edm::ParameterWildcard<double> w("*", edm::RequireAtLeastOne, true);
0169       set.addNode(w);
0170       set.add<int>("testTypeChecking1", 11);
0171       REQUIRE_THROWS_AS(set.add<double>("testTypeChecking2", 11.0), edm::Exception);
0172     }
0173 
0174     REQUIRE_THROWS_AS(edm::ParameterWildcard<int>("a*", edm::RequireZeroOrMore, true), edm::Exception);
0175 
0176     edm::ParameterSet nestedPset;
0177     nestedPset.addUntrackedParameter<unsigned>("n1", 1);
0178 
0179     {
0180       edm::ParameterSetDescription set;
0181       edm::ParameterWildcard<edm::ParameterSetDescription> w("*", edm::RequireZeroOrMore, true);
0182       set.addNode(w);
0183       edm::ParameterSet pset;
0184       testDesc(w, set, pset, true, true);
0185       pset.addParameter<edm::ParameterSet>("nested1", nestedPset);
0186       testDesc(w, set, pset, true, true);
0187       pset.addParameter<edm::ParameterSet>("nested2", nestedPset);
0188       testDesc(w, set, pset, true, true);
0189 
0190       SECTION("cfi generation") {
0191         std::ostringstream os;
0192         bool startWithComma = false;
0193         bool wroteSomething = false;
0194         edm::CfiOptions ops = edm::cfi::Typed{};
0195         w.writeCfi(os, false, startWithComma, 0, ops, wroteSomething);
0196 
0197         REQUIRE_THAT(os.str(), Equals("\nallowAnyLabel_ = cms.required.PSetTemplate()"));
0198       }
0199     }
0200 
0201     {
0202       edm::ParameterSetDescription set;
0203       edm::ParameterWildcard<edm::ParameterSetDescription> w(std::string("*"), edm::RequireZeroOrMore, true);
0204       set.addNode(w);
0205       edm::ParameterSet pset;
0206       testDesc(w, set, pset, true, true);
0207       pset.addParameter<edm::ParameterSet>("nested1", nestedPset);
0208       testDesc(w, set, pset, true, true);
0209       pset.addParameter<edm::ParameterSet>("nested2", nestedPset);
0210       testDesc(w, set, pset, true, true);
0211     }
0212 
0213     {
0214       edm::ParameterSetDescription set;
0215       edm::ParameterWildcard<edm::ParameterSetDescription> w(
0216           "*", edm::RequireZeroOrMore, true, edm::ParameterSetDescription());
0217       set.addNode(w);
0218       edm::ParameterSet pset;
0219       testDesc(w, set, pset, true, true);
0220       pset.addParameter<edm::ParameterSet>("nested1", nestedPset);
0221       testDesc(w, set, pset, true, false);
0222       pset.addParameter<edm::ParameterSet>("nested2", nestedPset);
0223       testDesc(w, set, pset, true, false);
0224     }
0225 
0226     edm::ParameterSetDescription nestedDesc;
0227     nestedDesc.addUntracked<unsigned>("n1", 1);
0228 
0229     {
0230       edm::ParameterSetDescription set;
0231       edm::ParameterWildcard<edm::ParameterSetDescription> w("*", edm::RequireZeroOrMore, true, nestedDesc);
0232       set.addNode(w);
0233       edm::ParameterSet pset;
0234       testDesc(w, set, pset, true, true);
0235       pset.addParameter<edm::ParameterSet>("nested1", nestedPset);
0236       testDesc(w, set, pset, true, true);
0237       pset.addParameter<edm::ParameterSet>("nested2", nestedPset);
0238       testDesc(w, set, pset, true, true);
0239 
0240       SECTION("cfi generation") {
0241         std::ostringstream os;
0242         bool startWithComma = false;
0243         bool wroteSomething = false;
0244         edm::CfiOptions ops = edm::cfi::Typed{};
0245         w.writeCfi(os, false, startWithComma, 0, ops, wroteSomething);
0246 
0247         REQUIRE_THAT(os.str(),
0248                      Equals("\nallowAnyLabel_ = cms.required.PSetTemplate(\n  n1 = cms.untracked.uint32(1)\n)"));
0249       }
0250     }
0251 
0252     {
0253       edm::ParameterSetDescription set;
0254       edm::ParameterWildcard<edm::ParameterSetDescription> w(
0255           std::string("*"), edm::RequireExactlyOne, true, nestedDesc);
0256       set.addNode(w);
0257       edm::ParameterSet pset;
0258       testDesc(w, set, pset, false, false);
0259       pset.addParameter<edm::ParameterSet>("nested1", nestedPset);
0260       testDesc(w, set, pset, true, true);
0261       pset.addParameter<edm::ParameterSet>("nested2", nestedPset);
0262       testDesc(w, set, pset, false, false);
0263     }
0264 
0265     {
0266       edm::ParameterSetDescription set;
0267       edm::ParameterWildcard<edm::ParameterSetDescription> w("*", edm::RequireAtLeastOne, true, nestedDesc);
0268       set.addNode(w);
0269       edm::ParameterSet pset;
0270       testDesc(w, set, pset, false, false);
0271       pset.addParameter<edm::ParameterSet>("nested1", nestedPset);
0272       testDesc(w, set, pset, true, true);
0273       pset.addParameter<edm::ParameterSet>("nested2", nestedPset);
0274       testDesc(w, set, pset, true, true);
0275     }
0276 
0277     std::vector<edm::ParameterSet> nestedVPset;
0278     edm::ParameterSet vectorElement;
0279     vectorElement.addUntrackedParameter<unsigned>("n11", 1);
0280     nestedVPset.push_back(vectorElement);
0281     nestedVPset.push_back(vectorElement);
0282 
0283     {
0284       edm::ParameterSetDescription set;
0285       edm::ParameterWildcard<std::vector<edm::ParameterSet>> w("*", edm::RequireZeroOrMore, true);
0286       set.addNode(w);
0287       edm::ParameterSet pset;
0288       testDesc(w, set, pset, true, true);
0289       pset.addParameter<std::vector<edm::ParameterSet>>("nested1", nestedVPset);
0290       testDesc(w, set, pset, true, true);
0291       pset.addParameter<std::vector<edm::ParameterSet>>("nested2", nestedVPset);
0292       testDesc(w, set, pset, true, true);
0293       SECTION("cfi generation") {
0294         std::ostringstream os;
0295         bool startWithComma = false;
0296         bool wroteSomething = false;
0297         edm::CfiOptions ops = edm::cfi::Typed{};
0298         w.writeCfi(os, false, startWithComma, 0, ops, wroteSomething);
0299 
0300         REQUIRE_THAT(os.str(), Equals("\nallowAnyLabel_ = cms.required.VPSet"));
0301       }
0302     }
0303 
0304     {
0305       edm::ParameterSetDescription set;
0306       edm::ParameterWildcard<std::vector<edm::ParameterSet>> w(std::string("*"), edm::RequireZeroOrMore, true);
0307       set.addNode(w);
0308       edm::ParameterSet pset;
0309       testDesc(w, set, pset, true, true);
0310       pset.addParameter<std::vector<edm::ParameterSet>>("nested1", nestedVPset);
0311       testDesc(w, set, pset, true, true);
0312       pset.addParameter<std::vector<edm::ParameterSet>>("nested2", nestedVPset);
0313       testDesc(w, set, pset, true, true);
0314     }
0315 
0316     {
0317       edm::ParameterSetDescription set;
0318       edm::ParameterWildcard<std::vector<edm::ParameterSet>> w(
0319           "*", edm::RequireZeroOrMore, true, edm::ParameterSetDescription());
0320       set.addNode(w);
0321       edm::ParameterSet pset;
0322       testDesc(w, set, pset, true, true);
0323       pset.addParameter<std::vector<edm::ParameterSet>>("nested1", nestedVPset);
0324       testDesc(w, set, pset, true, false);
0325       pset.addParameter<std::vector<edm::ParameterSet>>("nested2", nestedVPset);
0326       testDesc(w, set, pset, true, false);
0327     }
0328 
0329     edm::ParameterSetDescription descElement;
0330     descElement.addUntracked<unsigned>("n11", 1);
0331     {
0332       edm::ParameterSetDescription set;
0333       edm::ParameterWildcard<std::vector<edm::ParameterSet>> w("*", edm::RequireZeroOrMore, true, descElement);
0334       set.addNode(w);
0335       edm::ParameterSet pset;
0336       testDesc(w, set, pset, true, true);
0337       pset.addParameter<std::vector<edm::ParameterSet>>("nested1", nestedVPset);
0338       testDesc(w, set, pset, true, true);
0339       pset.addParameter<std::vector<edm::ParameterSet>>("nested2", nestedVPset);
0340       testDesc(w, set, pset, true, true);
0341     }
0342 
0343     {
0344       edm::ParameterSetDescription set;
0345       edm::ParameterWildcard<std::vector<edm::ParameterSet>> w(
0346           std::string("*"), edm::RequireExactlyOne, true, descElement);
0347       set.addNode(w);
0348       edm::ParameterSet pset;
0349       testDesc(w, set, pset, false, false);
0350       pset.addParameter<std::vector<edm::ParameterSet>>("nested1", nestedVPset);
0351       testDesc(w, set, pset, true, true);
0352       pset.addParameter<std::vector<edm::ParameterSet>>("nested2", nestedVPset);
0353       testDesc(w, set, pset, false, false);
0354     }
0355 
0356     {
0357       edm::ParameterSetDescription set;
0358       edm::ParameterWildcard<std::vector<edm::ParameterSet>> w("*", edm::RequireAtLeastOne, true, descElement);
0359       set.addNode(w);
0360       edm::ParameterSet pset;
0361       testDesc(w, set, pset, false, false);
0362       pset.addParameter<std::vector<edm::ParameterSet>>("nested1", nestedVPset);
0363       testDesc(w, set, pset, true, true);
0364       pset.addParameter<std::vector<edm::ParameterSet>>("nested2", nestedVPset);
0365       testDesc(w, set, pset, true, true);
0366     }
0367   }
0368 
0369   SECTION("testWildcardWithExceptions") {
0370     {
0371       edm::ParameterSetDescription set;
0372 
0373       edm::ParameterSetDescription wild;
0374       wild.addUntracked<unsigned>("n11", 1);
0375 
0376       edm::ParameterSetDescription except_;
0377       except_.addUntracked<double>("f", 3.14);
0378       std::map<std::string, edm::ParameterSetDescription> excptions = {{"special", except_}};
0379       edm::ParameterWildcardWithSpecifics w("*", edm::RequireZeroOrMore, true, wild, std::move(excptions));
0380       set.addNode(w);
0381       edm::ParameterSet pset;
0382       testDesc(w, set, pset, true, true);
0383       edm::ParameterSet nested1;
0384       nested1.addUntrackedParameter<unsigned>("n11", 3);
0385       pset.addParameter<edm::ParameterSet>("nested1", nested1);
0386       testDesc(w, set, pset, true, true);
0387       edm::ParameterSet special;
0388       special.addUntrackedParameter<double>("f", 5);
0389       pset.addParameter<edm::ParameterSet>("special", special);
0390       testDesc(w, set, pset, true, true);
0391     }
0392 
0393     {
0394       edm::ParameterSetDescription set;
0395 
0396       edm::ParameterSetDescription wild;
0397       wild.add<unsigned>("n11", 1);
0398 
0399       edm::ParameterSetDescription except_;
0400       except_.add<double>("f", 3.14);
0401       std::map<std::string, edm::ParameterSetDescription> excptions = {{"special", except_}};
0402       edm::ParameterWildcardWithSpecifics w("*", edm::RequireZeroOrMore, true, wild, std::move(excptions));
0403       set.addNode(w);
0404       edm::ParameterSet pset;
0405       testDesc(w, set, pset, true, true);
0406       edm::ParameterSet nested1;
0407       nested1.addParameter<unsigned>("n11", 3);
0408       pset.addParameter<edm::ParameterSet>("nested1", nested1);
0409       testDesc(w, set, pset, true, true);
0410       edm::ParameterSet special;
0411       special.addParameter<double>("f", 5);
0412       pset.addParameter<edm::ParameterSet>("special", special);
0413       testDesc(w, set, pset, true, true);
0414     }
0415   }
0416 
0417   // ---------------------------------------------------------------------------------
0418 
0419   SECTION("testAllowedValues") {
0420     // Duplicate case values not allowed
0421     edm::ParameterSetDescription psetDesc;
0422     psetDesc.ifValue(edm::ParameterDescription<std::string>("sswitch", "a", true),
0423                      edm::allowedValues<std::string>("a", "h", "z"));
0424   }
0425 
0426   SECTION("testSwitch") {
0427     // Duplicate case values not allowed
0428     edm::ParameterSetDescription psetDesc;
0429     REQUIRE_THROWS_AS(psetDesc.ifValue(edm::ParameterDescription<int>("oiswitch", 1, true),
0430                                        0 >> edm::ParameterDescription<int>("oivalue", 100, true) or
0431                                            1 >> (edm::ParameterDescription<double>("oivalue1", 101.0, true) and
0432                                                  edm::ParameterDescription<double>("oivalue2", 101.0, true)) or
0433                                            1 >> edm::ParameterDescription<std::string>("oivalue", "102", true)),
0434                       edm::Exception);
0435 
0436     // Types used in case parameters cannot duplicate type already used in a wildcard
0437     edm::ParameterSetDescription psetDesc1;
0438     edm::ParameterWildcard<double> w("*", edm::RequireAtLeastOne, true);
0439     psetDesc1.addNode(w);
0440 
0441     REQUIRE_THROWS_AS(psetDesc1.ifValue(edm::ParameterDescription<int>("oiswitch", 1, true),
0442                                         0 >> edm::ParameterDescription<int>("oivalue", 100, true) or
0443                                             1 >> (edm::ParameterDescription<double>("oivalue1", 101.0, true) and
0444                                                   edm::ParameterDescription<double>("oivalue2", 101.0, true)) or
0445                                             2 >> edm::ParameterDescription<std::string>("oivalue", "102", true)),
0446                       edm::Exception);
0447 
0448     // Types used in the switch parameter cannot duplicate type already used in a wildcard
0449     edm::ParameterSetDescription psetDesc2;
0450     edm::ParameterWildcard<int> w1("*", edm::RequireAtLeastOne, true);
0451     psetDesc2.addNode(w1);
0452 
0453     REQUIRE_THROWS_AS(psetDesc2.ifValue(edm::ParameterDescription<int>("aswitch", 1, true),
0454                                         1 >> (edm::ParameterDescription<unsigned>("avalue1", 101, true) and
0455                                               edm::ParameterDescription<unsigned>("avalue2", 101, true)) or
0456                                             2 >> edm::ParameterDescription<std::string>("avalue", "102", true)),
0457                       edm::Exception);
0458 
0459     // Type used in the switch parameter cannot duplicate type in a case wildcard
0460     edm::ParameterSetDescription psetDesc3;
0461     REQUIRE_THROWS_AS(psetDesc3.ifValue(edm::ParameterDescription<int>("xswitch", 1, true),
0462                                         0 >> edm::ParameterWildcard<int>("*", edm::RequireAtLeastOne, true) or
0463                                             1 >> (edm::ParameterDescription<double>("xvalue1", 101.0, true) and
0464                                                   edm::ParameterDescription<double>("xvalue2", 101.0, true))),
0465                       edm::Exception);
0466 
0467     // Type used in a parameter cannot duplicate type in a case wildcard
0468     edm::ParameterSetDescription psetDesc4;
0469     psetDesc4.add<unsigned>("testunsigned", 1U);
0470     REQUIRE_THROWS_AS(psetDesc4.ifValue(edm::ParameterDescription<int>("xswitch", 1, true),
0471                                         0 >> edm::ParameterWildcard<unsigned>("*", edm::RequireAtLeastOne, true) or
0472                                             1 >> (edm::ParameterDescription<double>("xvalue1", 101.0, true) and
0473                                                   edm::ParameterDescription<double>("xvalue2", 101.0, true))),
0474                       edm::Exception);
0475 
0476     // No problem is wildcard type and parameter type are the same for different cases.
0477     edm::ParameterSetDescription psetDesc5;
0478     psetDesc5.ifValue(edm::ParameterDescription<int>("uswitch", 1, true),
0479                       0 >> edm::ParameterWildcard<unsigned>("*", edm::RequireAtLeastOne, true) or
0480                           1 >> (edm::ParameterDescription<unsigned>("uvalue1", 101, true) and
0481                                 edm::ParameterDescription<unsigned>("uvalue2", 101, true)));
0482 
0483     // The switch parameter label cannot be the same as a label that already exists
0484     edm::ParameterSetDescription psetDesc6;
0485     psetDesc6.add<unsigned>("xswitch", 1U);
0486     REQUIRE_THROWS_AS(psetDesc6.ifValue(edm::ParameterDescription<int>("xswitch", 1, true),
0487                                         0 >> edm::ParameterWildcard<double>("*", edm::RequireAtLeastOne, true) or
0488                                             1 >> (edm::ParameterDescription<double>("xvalue1", 101.0, true) and
0489                                                   edm::ParameterDescription<double>("xvalue2", 101.0, true))),
0490                       edm::Exception);
0491 
0492     // Case labels cannot be the same as a label that already exists
0493     edm::ParameterSetDescription psetDesc7;
0494     psetDesc7.add<unsigned>("xvalue1", 1U);
0495     REQUIRE_THROWS_AS(psetDesc7.ifValue(edm::ParameterDescription<int>("xswitch", 1, true),
0496                                         0 >> edm::ParameterWildcard<double>("*", edm::RequireAtLeastOne, true) or
0497                                             1 >> (edm::ParameterDescription<double>("xvalue1", 101.0, true) and
0498                                                   edm::ParameterDescription<double>("xvalue2", 101.0, true))),
0499                       edm::Exception);
0500 
0501     // Case labels cannot be the same as a switch label
0502     edm::ParameterSetDescription psetDesc8;
0503     REQUIRE_THROWS_AS(psetDesc8.ifValue(edm::ParameterDescription<int>("xswitch", 1, true),
0504                                         0 >> edm::ParameterWildcard<double>("*", edm::RequireAtLeastOne, true) or
0505                                             1 >> (edm::ParameterDescription<double>("xswitch", 101.0, true) and
0506                                                   edm::ParameterDescription<double>("xvalue2", 101.0, true))),
0507                       edm::Exception);
0508 
0509     // Parameter set switch value must be one of the defined cases
0510     edm::ParameterSetDescription psetDesc9;
0511 
0512     psetDesc9.ifValue(edm::ParameterDescription<int>("xswitch", 1, true),
0513                       0 >> edm::ParameterWildcard<double>("*", edm::RequireAtLeastOne, true) or
0514                           1 >> (edm::ParameterDescription<double>("xvalue1", 101.0, true) and
0515                                 edm::ParameterDescription<double>("xvalue2", 101.0, true)));
0516     edm::ParameterSet pset;
0517     pset.addParameter<int>("xswitch", 5);
0518     REQUIRE_THROWS_AS(psetDesc9.validate(pset), edm::Exception);
0519 
0520     edm::ParameterSwitch<int> pswitch(edm::ParameterDescription<int>("xswitch", 1, true),
0521                                       0 >> edm::ParameterWildcard<double>("*", edm::RequireAtLeastOne, true) or
0522                                           1 >> (edm::ParameterDescription<double>("xvalue1", 101.0, true) and
0523                                                 edm::ParameterDescription<double>("xvalue2", 101.0, true)));
0524     edm::ParameterSetDescription psetDesc10;
0525     psetDesc10.addNode(pswitch);
0526     edm::ParameterSet pset10;
0527     testDesc(pswitch, psetDesc10, pset10, false, true);
0528     pset10.addParameter<int>("xswitch", 1);
0529     testDesc(pswitch, psetDesc10, pset10, true, true);
0530   }
0531 
0532   // ---------------------------------------------------------------------------------
0533 
0534   SECTION("testXor") {
0535     edm::ParameterSetDescription psetDesc1;
0536     std::unique_ptr<edm::ParameterDescriptionNode> node1(
0537         edm::ParameterDescription<double>("x1", 101.0, true) xor
0538         (edm::ParameterDescription<double>("x1", 101.0, true) and
0539          edm::ParameterDescription<double>("x2", 101.0, true)) xor
0540         edm::ParameterDescription<double>("x1", 101.0, true) xor
0541         (edm::ParameterDescription<double>("x1", 101.0, true) or edm::ParameterDescription<double>("x2", 101.0, true)));
0542 
0543     edm::ParameterSet pset1;
0544 
0545     edm::ParameterSet pset2;
0546     pset2.addParameter("x1", 11.0);
0547     pset2.addParameter("x2", 12.0);
0548 
0549     CHECK(node1->exists(pset1) == false);
0550     CHECK(node1->partiallyExists(pset1) == false);
0551     CHECK(node1->howManyXORSubNodesExist(pset1) == 0);
0552 
0553     CHECK(node1->exists(pset2) == false);
0554     CHECK(node1->partiallyExists(pset2) == false);
0555     CHECK(node1->howManyXORSubNodesExist(pset2) == 4);
0556 
0557     // 0 of the options existing should fail validation
0558     psetDesc1.addNode(std::move(node1));
0559     REQUIRE_THROWS_AS(psetDesc1.validate(pset1), edm::Exception);
0560 
0561     // More than one of the options existing should also fail
0562     REQUIRE_THROWS_AS(psetDesc1.validate(pset2), edm::Exception);
0563 
0564     // One of the labels cannot already exist in the description
0565     edm::ParameterSetDescription psetDesc2;
0566     psetDesc2.add<unsigned>("xvalue1", 1U);
0567     std::unique_ptr<edm::ParameterDescriptionNode> node2(edm::ParameterDescription<double>("x1", 101.0, true) xor
0568                                                          (edm::ParameterDescription<double>("x1", 101.0, true) and
0569                                                           edm::ParameterDescription<double>("x2", 101.0, true)) xor
0570                                                          edm::ParameterDescription<double>("x1", 101.0, true) xor
0571                                                          (edm::ParameterDescription<double>("xvalue1", 101.0, true) or
0572                                                           edm::ParameterDescription<double>("x2", 101.0, true)));
0573     REQUIRE_THROWS_AS(psetDesc2.addNode(std::move(node2)), edm::Exception);
0574 
0575     // One of the labels cannot already exist in the description, other order
0576     edm::ParameterSetDescription psetDesc3;
0577     std::unique_ptr<edm::ParameterDescriptionNode> node3(edm::ParameterDescription<double>("x1", 101.0, true) xor
0578                                                          (edm::ParameterDescription<double>("x1", 101.0, true) and
0579                                                           edm::ParameterDescription<double>("x2", 101.0, true)) xor
0580                                                          edm::ParameterDescription<double>("x1", 101.0, true) xor
0581                                                          (edm::ParameterDescription<double>("xvalue1", 101.0, true) or
0582                                                           edm::ParameterDescription<double>("x2", 101.0, true)));
0583     psetDesc3.addNode(std::move(node3));
0584     REQUIRE_THROWS_AS(psetDesc3.add<unsigned>("xvalue1", 1U), edm::Exception);
0585 
0586     // A parameter cannot use the same type as a wildcard
0587     edm::ParameterSetDescription psetDesc4;
0588     std::unique_ptr<edm::ParameterDescriptionNode> node4(
0589         edm::ParameterDescription<double>("x1", 101.0, true) xor
0590         (edm::ParameterDescription<double>("x1", 101.0, true) and
0591          edm::ParameterDescription<unsigned>("x2", 101, true)) xor
0592         edm::ParameterDescription<double>("x1", 101.0, true) xor
0593         (edm::ParameterDescription<double>("x1", 101.0, true) or edm::ParameterDescription<double>("x2", 101.0, true)));
0594     psetDesc4.addNode(std::move(node4));
0595 
0596     edm::ParameterWildcard<unsigned> w4("*", edm::RequireAtLeastOne, true);
0597     REQUIRE_THROWS_AS(psetDesc4.addNode(w4), edm::Exception);
0598 
0599     // A parameter cannot use the same type as a wildcard
0600     edm::ParameterSetDescription psetDesc5;
0601     std::unique_ptr<edm::ParameterDescriptionNode> node5(
0602         edm::ParameterDescription<double>("x1", 101.0, true) xor
0603         (edm::ParameterDescription<double>("x1", 101.0, true) and
0604          edm::ParameterWildcard<unsigned>("*", edm::RequireAtLeastOne, true)) xor
0605         edm::ParameterDescription<double>("x1", 101.0, true) xor
0606         (edm::ParameterDescription<double>("x1", 101.0, true) or
0607          edm::ParameterWildcard<unsigned>("*", edm::RequireAtLeastOne, true)));
0608     psetDesc5.addNode(std::move(node5));
0609 
0610     edm::ParameterDescription<unsigned> n5("z5", edm::RequireAtLeastOne, true);
0611     REQUIRE_THROWS_AS(psetDesc5.addNode(n5), edm::Exception);
0612   }
0613 
0614   // ---------------------------------------------------------------------------------
0615 
0616   SECTION("testOr") {
0617     edm::ParameterSetDescription psetDesc1;
0618     std::unique_ptr<edm::ParameterDescriptionNode> node1(edm::ParameterDescription<double>("x1", 101.0, true) or
0619                                                          (edm::ParameterDescription<double>("x2", 101.0, true) and
0620                                                           edm::ParameterDescription<double>("x3", 101.0, true)) or
0621                                                          edm::ParameterDescription<double>("x4", 101.0, true) or
0622                                                          (edm::ParameterDescription<double>("x5", 101.0, true) xor
0623                                                           edm::ParameterDescription<double>("x6", 101.0, true)));
0624 
0625     edm::ParameterSet pset1;
0626 
0627     edm::ParameterSet pset2;
0628     pset2.addParameter("x1", 11.0);
0629     pset2.addParameter("x2", 12.0);
0630     pset2.addParameter("x3", 13.0);
0631     pset2.addParameter("x4", 14.0);
0632     pset2.addParameter("x5", 15.0);
0633 
0634     CHECK(node1->exists(pset1) == false);
0635     CHECK(node1->partiallyExists(pset1) == false);
0636     CHECK(node1->howManyXORSubNodesExist(pset1) == 0);
0637 
0638     CHECK(node1->exists(pset2) == true);
0639     CHECK(node1->partiallyExists(pset2) == true);
0640     CHECK(node1->howManyXORSubNodesExist(pset2) == 1);
0641 
0642     // 0 of the options existing should fail validation
0643     psetDesc1.addNode(std::move(node1));
0644     psetDesc1.validate(pset1);
0645 
0646     // More than one of the options existing should succeed
0647     psetDesc1.validate(pset2);
0648 
0649     // One of the labels cannot already exist in the description
0650     edm::ParameterSetDescription psetDesc2;
0651     psetDesc2.add<unsigned>("x1", 1U);
0652     std::unique_ptr<edm::ParameterDescriptionNode> node2(edm::ParameterDescription<double>("x1", 101.0, true) or
0653                                                          (edm::ParameterDescription<double>("x2", 101.0, true) and
0654                                                           edm::ParameterDescription<double>("x3", 101.0, true)) or
0655                                                          edm::ParameterDescription<double>("x4", 101.0, true));
0656     REQUIRE_THROWS_AS(psetDesc2.addNode(std::move(node2)), edm::Exception);
0657 
0658     // One of the labels cannot already exist in the description, other order
0659     edm::ParameterSetDescription psetDesc3;
0660     std::unique_ptr<edm::ParameterDescriptionNode> node3(edm::ParameterDescription<double>("x1", 101.0, true) or
0661                                                          (edm::ParameterDescription<double>("x2", 101.0, true) and
0662                                                           edm::ParameterDescription<double>("x3", 101.0, true)) or
0663                                                          edm::ParameterDescription<double>("x4", 101.0, true));
0664     psetDesc3.addNode(std::move(node3));
0665 
0666     REQUIRE_THROWS_AS(psetDesc3.add<unsigned>("x1", 1U), edm::Exception);
0667 
0668     // Put the duplicate labels in different nodes of the "or" expression
0669     edm::ParameterSetDescription psetDesc4;
0670     std::unique_ptr<edm::ParameterDescriptionNode> node4(edm::ParameterDescription<double>("x1", 101.0, true) or
0671                                                          (edm::ParameterDescription<double>("x2", 101.0, true) and
0672                                                           edm::ParameterDescription<double>("x3", 101.0, true)) or
0673                                                          edm::ParameterDescription<double>("x1", 101.0, true));
0674     REQUIRE_THROWS_AS(psetDesc4.addNode(std::move(node4)), edm::Exception);
0675 
0676     // A type used in a wildcard should not be the same as a type
0677     // used for another parameter
0678     edm::ParameterSetDescription psetDesc5;
0679     std::unique_ptr<edm::ParameterDescriptionNode> node5(
0680         edm::ParameterWildcard<double>("*", edm::RequireAtLeastOne, true) or
0681         (edm::ParameterDescription<double>("x2", 101.0, true) and
0682          edm::ParameterDescription<unsigned>("x3", 101U, true)) or
0683         edm::ParameterDescription<unsigned>("x1", 101U, true));
0684     REQUIRE_THROWS_AS(psetDesc5.addNode(std::move(node5)), edm::Exception);
0685 
0686     // A type used in a wildcard should not be the same as a type
0687     // used for another parameter node
0688     edm::ParameterSetDescription psetDesc6;
0689     psetDesc6.add<double>("x0", 1.0);
0690     std::unique_ptr<edm::ParameterDescriptionNode> node6(
0691         edm::ParameterWildcard<double>("*", edm::RequireAtLeastOne, true) or
0692         (edm::ParameterDescription<unsigned>("x2", 101U, true) and
0693          edm::ParameterDescription<unsigned>("x3", 101U, true)) or
0694         edm::ParameterDescription<unsigned>("x1", 101U, true));
0695     REQUIRE_THROWS_AS(psetDesc6.addNode(std::move(node6)), edm::Exception);
0696 
0697     // A type used in a wildcard should not be the same as a type
0698     // used for another parameter node
0699     edm::ParameterSetDescription psetDesc7;
0700     psetDesc7.addWildcard<double>("*");
0701     std::unique_ptr<edm::ParameterDescriptionNode> node7(edm::ParameterDescription<double>("x0", 1.0, true) or
0702                                                          (edm::ParameterDescription<unsigned>("x2", 101U, true) and
0703                                                           edm::ParameterDescription<unsigned>("x3", 101U, true)) or
0704                                                          edm::ParameterDescription<unsigned>("x1", 101U, true));
0705     REQUIRE_THROWS_AS(psetDesc7.addNode(std::move(node7)), edm::Exception);
0706   }
0707 
0708   // ---------------------------------------------------------------------------------
0709 
0710   SECTION("testAnd") {
0711     edm::ParameterSetDescription psetDesc1;
0712     std::unique_ptr<edm::ParameterDescriptionNode> node1(edm::ParameterDescription<double>("x1", 101.0, true) and
0713                                                          (edm::ParameterDescription<double>("x2", 101.0, true) or
0714                                                           edm::ParameterDescription<double>("x3", 101.0, true)) and
0715                                                          edm::ParameterDescription<double>("x4", 101.0, true) and
0716                                                          (edm::ParameterDescription<double>("x5", 101.0, true) xor
0717                                                           edm::ParameterDescription<double>("x6", 101.0, true)));
0718 
0719     edm::ParameterSet pset1;
0720 
0721     edm::ParameterSet pset2;
0722     pset2.addParameter("x1", 11.0);
0723     pset2.addParameter("x2", 12.0);
0724     pset2.addParameter("x3", 13.0);
0725     pset2.addParameter("x4", 14.0);
0726     pset2.addParameter("x5", 15.0);
0727 
0728     edm::ParameterSet pset3;
0729     pset3.addParameter("x3", 13.0);
0730 
0731     CHECK(node1->exists(pset1) == false);
0732     CHECK(node1->partiallyExists(pset1) == false);
0733     CHECK(node1->howManyXORSubNodesExist(pset1) == 0);
0734 
0735     CHECK(node1->exists(pset2) == true);
0736     CHECK(node1->partiallyExists(pset2) == true);
0737     CHECK(node1->howManyXORSubNodesExist(pset2) == 1);
0738 
0739     CHECK(node1->exists(pset3) == false);
0740     CHECK(node1->partiallyExists(pset3) == true);
0741     CHECK(node1->howManyXORSubNodesExist(pset3) == 0);
0742 
0743     psetDesc1.addNode(std::move(node1));
0744     psetDesc1.validate(pset1);
0745     psetDesc1.validate(pset2);
0746     psetDesc1.validate(pset3);
0747 
0748     // One of the labels cannot already exist in the description
0749     edm::ParameterSetDescription psetDesc2;
0750     psetDesc2.add<unsigned>("x1", 1U);
0751     std::unique_ptr<edm::ParameterDescriptionNode> node2(edm::ParameterDescription<double>("x1", 101.0, true) and
0752                                                          (edm::ParameterDescription<double>("x2", 101.0, true) or
0753                                                           edm::ParameterDescription<double>("x3", 101.0, true)) and
0754                                                          edm::ParameterDescription<double>("x4", 101.0, true));
0755     REQUIRE_THROWS_AS(psetDesc2.addNode(std::move(node2)), edm::Exception);
0756 
0757     // One of the labels cannot already exist in the description, other order
0758     edm::ParameterSetDescription psetDesc3;
0759     std::unique_ptr<edm::ParameterDescriptionNode> node3(edm::ParameterDescription<double>("x1", 101.0, true) and
0760                                                          (edm::ParameterDescription<double>("x2", 101.0, true) or
0761                                                           edm::ParameterDescription<double>("x3", 101.0, true)) and
0762                                                          edm::ParameterDescription<double>("x4", 101.0, true));
0763     psetDesc3.addNode(std::move(node3));
0764 
0765     REQUIRE_THROWS_AS(psetDesc3.add<unsigned>("x1", 1U), edm::Exception);
0766 
0767     // Put the duplicate labels in different nodes of the "and" expression
0768     edm::ParameterSetDescription psetDesc4;
0769     std::unique_ptr<edm::ParameterDescriptionNode> node4(edm::ParameterDescription<double>("x1", 101.0, true) and
0770                                                          (edm::ParameterDescription<double>("x2", 101.0, true) or
0771                                                           edm::ParameterDescription<double>("x3", 101.0, true)) and
0772                                                          edm::ParameterDescription<double>("x1", 101.0, true));
0773     REQUIRE_THROWS_AS(psetDesc4.addNode(std::move(node4)), edm::Exception);
0774 
0775     // A type used in a wildcard should not be the same as a type
0776     // used for another parameter
0777     edm::ParameterSetDescription psetDesc5;
0778     std::unique_ptr<edm::ParameterDescriptionNode> node5(
0779         edm::ParameterWildcard<double>("*", edm::RequireAtLeastOne, true) and
0780         (edm::ParameterDescription<double>("x2", 101.0, true) or
0781          edm::ParameterDescription<unsigned>("x3", 101U, true)) and
0782         edm::ParameterDescription<unsigned>("x1", 101U, true));
0783     REQUIRE_THROWS_AS(psetDesc5.addNode(std::move(node5)), edm::Exception);
0784 
0785     // A type used in a wildcard should not be the same as a type
0786     // used for another parameter node
0787     edm::ParameterSetDescription psetDesc6;
0788     psetDesc6.add<double>("x0", 1.0);
0789     std::unique_ptr<edm::ParameterDescriptionNode> node6(
0790         edm::ParameterWildcard<double>("*", edm::RequireAtLeastOne, true) and
0791         (edm::ParameterDescription<unsigned>("x2", 101U, true) or
0792          edm::ParameterDescription<unsigned>("x3", 101U, true)) and
0793         edm::ParameterDescription<unsigned>("x1", 101U, true));
0794     REQUIRE_THROWS_AS(psetDesc6.addNode(std::move(node6)), edm::Exception);
0795 
0796     // A type used in a wildcard should not be the same as a type
0797     // used for another parameter node
0798     edm::ParameterSetDescription psetDesc7;
0799     psetDesc7.addWildcard<double>("*");
0800     std::unique_ptr<edm::ParameterDescriptionNode> node7(edm::ParameterDescription<double>("x0", 1.0, true) and
0801                                                          (edm::ParameterDescription<unsigned>("x2", 101U, true) or
0802                                                           edm::ParameterDescription<unsigned>("x3", 101U, true)) and
0803                                                          edm::ParameterDescription<unsigned>("x1", 101U, true));
0804     REQUIRE_THROWS_AS(psetDesc7.addNode(std::move(node7)), edm::Exception);
0805   }
0806 
0807   // ---------------------------------------------------------------------------------
0808 
0809   SECTION("testIfExists") {
0810     edm::ParameterSetDescription psetDesc1;
0811     std::unique_ptr<edm::ParameterDescriptionNode> node1(
0812         std::make_unique<edm::IfExistsDescription>(edm::ParameterDescription<double>("x1", 101.0, true),
0813                                                    (edm::ParameterDescription<double>("x2", 101.0, true) and
0814                                                     edm::ParameterDescription<double>("x3", 101.0, true))));
0815 
0816     std::unique_ptr<edm::ParameterDescriptionNode> node1a(std::make_unique<edm::IfExistsDescription>(
0817         (edm::ParameterDescription<double>("x2", 101.0, true) and edm::ParameterDescription<double>("x3", 101.0, true)),
0818         edm::ParameterDescription<double>("x1", 101.0, true)));
0819 
0820     std::unique_ptr<edm::ParameterDescriptionNode> node1b(std::make_unique<edm::IfExistsDescription>(
0821         (edm::ParameterDescription<double>("x1", 101.0, true) xor edm::ParameterDescription<int>("x1", 101, true)),
0822         (edm::ParameterDescription<double>("x2", 101.0, true) and
0823          edm::ParameterDescription<double>("x3", 101.0, true))));
0824 
0825     edm::ParameterSet pset1;
0826 
0827     edm::ParameterSet pset2;
0828     pset2.addParameter("x1", 11.0);
0829     pset2.addParameter("x2", 12.0);
0830     pset2.addParameter("x3", 13.0);
0831 
0832     edm::ParameterSet pset3;
0833     pset3.addParameter("x1", 14.0);
0834 
0835     edm::ParameterSet pset4;
0836     pset4.addParameter("x2", 15.0);
0837     pset4.addParameter("x3", 16.0);
0838 
0839     CHECK(node1->exists(pset1) == true);
0840     CHECK(node1->partiallyExists(pset1) == true);
0841     CHECK(node1->howManyXORSubNodesExist(pset1) == 1);
0842     CHECK(node1a->exists(pset1) == true);
0843     CHECK(node1b->exists(pset1) == true);
0844 
0845     CHECK(node1->exists(pset2) == true);
0846     CHECK(node1->partiallyExists(pset2) == true);
0847     CHECK(node1->howManyXORSubNodesExist(pset2) == 1);
0848     CHECK(node1a->exists(pset2) == true);
0849     CHECK(node1b->exists(pset2) == true);
0850 
0851     CHECK(node1->exists(pset3) == false);
0852     CHECK(node1->partiallyExists(pset3) == false);
0853     CHECK(node1->howManyXORSubNodesExist(pset3) == 0);
0854     CHECK(node1a->exists(pset3) == false);
0855     CHECK(node1b->exists(pset3) == false);
0856 
0857     CHECK(node1->exists(pset4) == false);
0858     CHECK(node1->partiallyExists(pset4) == false);
0859     CHECK(node1->howManyXORSubNodesExist(pset4) == 0);
0860     CHECK(node1a->exists(pset4) == false);
0861     CHECK(node1b->exists(pset4) == false);
0862 
0863     psetDesc1.addNode(std::move(node1));
0864     psetDesc1.validate(pset1);
0865     psetDesc1.validate(pset2);
0866     psetDesc1.validate(pset3);
0867     psetDesc1.validate(pset3);
0868 
0869     // One of the labels cannot already exist in the description
0870     edm::ParameterSetDescription psetDesc2;
0871     psetDesc2.add<unsigned>("x1", 1U);
0872     std::unique_ptr<edm::ParameterDescriptionNode> node2(
0873         std::make_unique<edm::IfExistsDescription>(edm::ParameterDescription<double>("x1", 101.0, true),
0874                                                    (edm::ParameterDescription<double>("x2", 101.0, true) and
0875                                                     edm::ParameterDescription<double>("x3", 101.0, true))));
0876 
0877     REQUIRE_THROWS_AS(psetDesc2.addNode(std::move(node2)), edm::Exception);
0878 
0879     // One of the labels cannot already exist in the description, other order
0880     edm::ParameterSetDescription psetDesc3;
0881     std::unique_ptr<edm::ParameterDescriptionNode> node3(
0882         std::make_unique<edm::IfExistsDescription>(edm::ParameterDescription<double>("x1", 101.0, true),
0883                                                    (edm::ParameterDescription<double>("x2", 101.0, true) and
0884                                                     edm::ParameterDescription<double>("x3", 101.0, true))));
0885     psetDesc3.addNode(std::move(node3));
0886 
0887     REQUIRE_THROWS_AS(psetDesc3.add<unsigned>("x1", 1U), edm::Exception);
0888 
0889     // Put the duplicate labels in different nodes of the "and" expression
0890     edm::ParameterSetDescription psetDesc4;
0891     std::unique_ptr<edm::ParameterDescriptionNode> node4(
0892         std::make_unique<edm::IfExistsDescription>(edm::ParameterDescription<double>("x1", 101.0, true),
0893                                                    (edm::ParameterDescription<double>("x2", 101.0, true) and
0894                                                     edm::ParameterDescription<double>("x1", 101.0, true))));
0895     REQUIRE_THROWS_AS(psetDesc4.addNode(std::move(node4)), edm::Exception);
0896 
0897     // A type used in a wildcard should not be the same as a type
0898     // used for another parameter
0899     edm::ParameterSetDescription psetDesc5;
0900     std::unique_ptr<edm::ParameterDescriptionNode> node5(std::make_unique<edm::IfExistsDescription>(
0901         edm::ParameterDescription<double>("x1", 101.0, true),
0902         (edm::ParameterDescription<unsigned>("x2", 101U, true) and
0903          edm::ParameterWildcard<double>("*", edm::RequireAtLeastOne, true))));
0904     REQUIRE_THROWS_AS(psetDesc5.addNode(std::move(node5)), edm::Exception);
0905 
0906     // A type used in a wildcard should not be the same as a type
0907     // used for another parameter node
0908     edm::ParameterSetDescription psetDesc6;
0909     psetDesc6.add<double>("x0", 1.0);
0910     std::unique_ptr<edm::ParameterDescriptionNode> node6(
0911         std::make_unique<edm::IfExistsDescription>(edm::ParameterWildcard<double>("*", edm::RequireAtLeastOne, true),
0912                                                    (edm::ParameterDescription<unsigned>("x2", 101U, true) and
0913                                                     edm::ParameterDescription<unsigned>("x3", 102U, true))));
0914     REQUIRE_THROWS_AS(psetDesc6.addNode(std::move(node6)), edm::Exception);
0915 
0916     // A type used in a wildcard should not be the same as a type
0917     // used for another parameter node
0918     edm::ParameterSetDescription psetDesc7;
0919     psetDesc7.addWildcard<double>("*");
0920     std::unique_ptr<edm::ParameterDescriptionNode> node7(
0921         std::make_unique<edm::IfExistsDescription>(edm::ParameterDescription<double>("x1", 11.0, true),
0922                                                    (edm::ParameterDescription<unsigned>("x2", 101U, true) and
0923                                                     edm::ParameterDescription<unsigned>("x3", 102U, true))));
0924     REQUIRE_THROWS_AS(psetDesc7.addNode(std::move(node7)), edm::Exception);
0925   }
0926 
0927   // ---------------------------------------------------------------------------------
0928 
0929   SECTION("testAllowedLabels") {
0930     {
0931       std::unique_ptr<edm::ParameterDescriptionNode> node(
0932           std::make_unique<edm::AllowedLabelsDescription<int>>("allowedLabels", true));
0933 
0934       const edm::ParameterSet emptyPset;
0935 
0936       edm::ParameterSet pset;
0937       std::vector<std::string> labels;
0938       pset.addParameter<std::vector<std::string>>("allowedLabels", labels);
0939 
0940       CHECK(node->exists(emptyPset) == false);
0941       CHECK(node->partiallyExists(emptyPset) == false);
0942       CHECK(node->howManyXORSubNodesExist(emptyPset) == 0);
0943 
0944       CHECK(node->exists(pset) == true);
0945       CHECK(node->partiallyExists(pset) == true);
0946       CHECK(node->howManyXORSubNodesExist(pset) == 1);
0947     }
0948 
0949     {
0950       // One of the labels cannot already exist in the description
0951       edm::ParameterSetDescription psetDesc;
0952       psetDesc.add<unsigned>("x1", 1U);
0953       std::unique_ptr<edm::ParameterDescriptionNode> node(
0954           std::make_unique<edm::AllowedLabelsDescription<int>>("x1", true));
0955 
0956       REQUIRE_THROWS_AS(psetDesc.addNode(std::move(node)), edm::Exception);
0957     }
0958 
0959     {
0960       // A type used in a wildcard should not be the same as a type
0961       // used for another parameter node
0962       edm::ParameterSetDescription psetDesc;
0963       psetDesc.addWildcard<std::vector<std::string>>("*");
0964       std::unique_ptr<edm::ParameterDescriptionNode> node(
0965           std::make_unique<edm::AllowedLabelsDescription<int>>("x1", true));
0966       REQUIRE_THROWS_AS(psetDesc.addNode(std::move(node)), edm::Exception);
0967     }
0968     {
0969       edm::ParameterSet pset;
0970       edm::ParameterSet nestedPset;
0971       nestedPset.addParameter<int>("x", 1);
0972       pset.addParameter<edm::ParameterSet>("nestedPset", nestedPset);
0973 
0974       {
0975         edm::ParameterSetDescription psetDesc;
0976         psetDesc.labelsFrom<edm::ParameterSetDescription>("allowedLabelsA");
0977 
0978         // nestedPset is an illegal parameter
0979         REQUIRE_THROWS_AS(psetDesc.validate(pset), edm::Exception);
0980 
0981         std::vector<std::string> labels;
0982         labels.push_back(std::string("nestedPset"));
0983         pset.addParameter<std::vector<std::string>>("allowedLabelsA", labels);
0984 
0985         // Now nestedPset should be an allowed parameter
0986         psetDesc.validate(pset);
0987       }
0988 
0989       // Above it did not validate the contents of the nested ParameterSet
0990       // because a description was not passed to the labelsFrom function.
0991 
0992       {
0993         edm::ParameterSetDescription psetDesc;
0994         psetDesc.labelsFrom<edm::ParameterSetDescription>("allowedLabelsA", edm::ParameterSetDescription());
0995         // Now it should fail because the description says the nested ParameterSet
0996         // should be empty, but it has parameter "x"
0997         REQUIRE_THROWS_AS(psetDesc.validate(pset), edm::Exception);
0998       }
0999 
1000       // Now include "x" in the description and it should once again pass validation
1001       edm::ParameterSetDescription nestedPsetDesc;
1002       nestedPsetDesc.add<int>("x", 1);
1003 
1004       {
1005         edm::ParameterSetDescription psetDesc;
1006         psetDesc.labelsFrom<edm::ParameterSetDescription>("allowedLabelsA", nestedPsetDesc);
1007         psetDesc.validate(pset);
1008       }
1009       // Minor variations, repeat with a string argument
1010       {
1011         edm::ParameterSetDescription psetDesc;
1012         psetDesc.labelsFrom<edm::ParameterSetDescription>(std::string("allowedLabelsA"));
1013         psetDesc.validate(pset);
1014       }
1015       {
1016         edm::ParameterSetDescription psetDesc;
1017         psetDesc.labelsFrom<edm::ParameterSetDescription>(std::string("allowedLabelsA"),
1018                                                           edm::ParameterSetDescription());
1019         REQUIRE_THROWS_AS(psetDesc.validate(pset), edm::Exception);
1020       }
1021       {
1022         edm::ParameterSetDescription psetDesc;
1023         psetDesc.labelsFrom<edm::ParameterSetDescription>(std::string("allowedLabelsA"), nestedPsetDesc);
1024         psetDesc.validate(pset);
1025       }
1026     }
1027     // Now repeat what was done above with the variations
1028     // necessary to test the vector<ParameterSet> case
1029     {
1030       edm::ParameterSet pset;
1031 
1032       edm::ParameterSet elementOfVPset;
1033       elementOfVPset.addParameter<int>("y", 1);
1034       std::vector<edm::ParameterSet> vpset;
1035       vpset.push_back(elementOfVPset);
1036       vpset.push_back(elementOfVPset);
1037 
1038       pset.addParameter<std::vector<edm::ParameterSet>>("nestedVPSet", vpset);
1039 
1040       {
1041         edm::ParameterSetDescription psetDesc;
1042         psetDesc.labelsFrom<std::vector<edm::ParameterSet>>("allowedLabelsC");
1043 
1044         // nestedVPSet is an illegal parameter
1045         REQUIRE_THROWS_AS(psetDesc.validate(pset), edm::Exception);
1046 
1047         std::vector<std::string> labels;
1048         labels.push_back(std::string("nestedVPSet"));
1049         pset.addParameter<std::vector<std::string>>("allowedLabelsC", labels);
1050 
1051         // Now nestedVPSet should be an allowed parameter
1052         psetDesc.validate(pset);
1053       }
1054       // Above it did not validate the contents of the nested vector<ParameterSet>
1055       // because a description was not passed to the labelsFrom function.
1056 
1057       {
1058         edm::ParameterSetDescription psetDesc;
1059         psetDesc.labelsFrom<std::vector<edm::ParameterSet>>("allowedLabelsC", edm::ParameterSetDescription());
1060         // Now it should fail because the description says the contained vector<ParameterSet>
1061         // should have empty ParameterSets, but the ParameterSets have parameter "y"
1062         REQUIRE_THROWS_AS(psetDesc.validate(pset), edm::Exception);
1063       }
1064 
1065       // Now include "y" in the description and it should once again pass validation
1066       edm::ParameterSetDescription nestedPSetDesc;
1067       nestedPSetDesc.add<int>("y", 1);
1068 
1069       {
1070         edm::ParameterSetDescription psetDesc;
1071         psetDesc.labelsFrom<std::vector<edm::ParameterSet>>("allowedLabelsC", nestedPSetDesc);
1072         psetDesc.validate(pset);
1073       }
1074 
1075       // Minor variations, repeat with a string argument
1076       {
1077         edm::ParameterSetDescription psetDesc;
1078         psetDesc.labelsFrom<std::vector<edm::ParameterSet>>(std::string("allowedLabelsC"));
1079         psetDesc.validate(pset);
1080       }
1081       {
1082         edm::ParameterSetDescription psetDesc;
1083         psetDesc.labelsFrom<std::vector<edm::ParameterSet>>(std::string("allowedLabelsC"),
1084                                                             edm::ParameterSetDescription());
1085         REQUIRE_THROWS_AS(psetDesc.validate(pset), edm::Exception);
1086       }
1087       {
1088         edm::ParameterSetDescription psetDesc;
1089         psetDesc.labelsFrom<std::vector<edm::ParameterSet>>(std::string("allowedLabelsC"), nestedPSetDesc);
1090         psetDesc.validate(pset);
1091       }
1092     }
1093   }
1094   // ---------------------------------------------------------------------------------
1095 
1096   SECTION("testNoDefault") {
1097     edm::ParameterSetDescription psetDesc;
1098     psetDesc.add<int>("x");
1099     edm::ParameterSet pset;
1100 
1101     REQUIRE_THROWS_AS(psetDesc.validate(pset), edm::Exception);
1102 
1103     pset.addParameter<int>("x", 1);
1104     psetDesc.validate(pset);
1105 
1106     psetDesc.addVPSet("y", edm::ParameterSetDescription());
1107     REQUIRE_THROWS_AS(psetDesc.validate(pset), edm::Exception);
1108   }
1109 
1110   // ---------------------------------------------------------------------------------
1111 
1112   SECTION("testWrongTrackiness") {
1113     edm::ParameterSet pset1;
1114     pset1.addParameter<int>("test1", 1);
1115 
1116     edm::ParameterSetDescription psetDesc1;
1117     psetDesc1.addUntracked<int>("test1", 1);
1118     REQUIRE_THROWS_AS(psetDesc1.validate(pset1), edm::Exception);
1119 
1120     edm::ParameterSet pset2;
1121     pset2.addParameter<edm::ParameterSet>("test2", edm::ParameterSet());
1122 
1123     edm::ParameterSetDescription psetDesc2;
1124     psetDesc2.addUntracked<edm::ParameterSetDescription>("test2", edm::ParameterSetDescription());
1125     REQUIRE_THROWS_AS(psetDesc2.validate(pset2), edm::Exception);
1126 
1127     edm::ParameterSet pset3;
1128     pset3.addParameter<std::vector<edm::ParameterSet>>("test3", std::vector<edm::ParameterSet>());
1129 
1130     edm::ParameterSetDescription psetDesc3;
1131     psetDesc3.addVPSetUntracked("test3", edm::ParameterSetDescription());
1132     REQUIRE_THROWS_AS(psetDesc3.validate(pset3), edm::Exception);
1133   }
1134 
1135   // ---------------------------------------------------------------------------------
1136 
1137   SECTION("testWrongType") {
1138     edm::ParameterSet pset1;
1139     pset1.addParameter<unsigned int>("test1", 1);
1140 
1141     edm::ParameterSetDescription psetDesc1;
1142     psetDesc1.add<int>("test1", 1);
1143     REQUIRE_THROWS_AS(psetDesc1.validate(pset1), edm::Exception);
1144 
1145     edm::ParameterSet pset2;
1146     pset2.addParameter<int>("test2", 1);
1147 
1148     edm::ParameterSetDescription psetDesc2;
1149     psetDesc2.add<edm::ParameterSetDescription>("test2", edm::ParameterSetDescription());
1150     REQUIRE_THROWS_AS(psetDesc2.validate(pset2), edm::Exception);
1151 
1152     edm::ParameterSet pset3;
1153     pset3.addParameter<int>("test3", 1);
1154 
1155     edm::ParameterSetDescription psetDesc3;
1156     psetDesc3.addVPSetUntracked("test3", edm::ParameterSetDescription());
1157     REQUIRE_THROWS_AS(psetDesc3.validate(pset3), edm::Exception);
1158   }
1159 
1160   // ---------------------------------------------------------------------------------
1161 
1162   SECTION("testPlugin") {
1163     static std::once_flag flag;
1164     std::call_once(flag, []() { edmplugin::PluginManager::configure(edmplugin::standard::config()); });
1165     {
1166       edm::ParameterSetDescription desc;
1167       desc.addNode(edm::PluginDescription<TestPluginFactory>("type", true));
1168 
1169       edm::ParameterSet pset1;
1170       pset1.addParameter<std::string>("type", "ATestPlugin");
1171       pset1.addParameter<int>("anInt", 3);
1172 
1173       desc.validate(pset1);
1174     }
1175 
1176     {
1177       edm::ParameterSetDescription desc;
1178       desc.addNode(edm::PluginDescription<TestPluginFactory>("type", true));
1179 
1180       edm::ParameterSet pset1;
1181       pset1.addParameter<std::string>("type", "BTestPlugin");
1182       pset1.addParameter<double>("aDouble", 0.2);
1183 
1184       desc.validate(pset1);
1185     }
1186 
1187     {
1188       //add defaults
1189       edm::ParameterSetDescription desc;
1190       desc.addNode(edm::PluginDescription<TestPluginFactory>("type", true));
1191 
1192       edm::ParameterSet pset1;
1193       pset1.addParameter<std::string>("type", "ATestPlugin");
1194       desc.validate(pset1);
1195       CHECK(pset1.getParameter<int>("anInt") == 5);
1196     }
1197 
1198     {
1199       //add defaults
1200       edm::ParameterSetDescription desc;
1201       desc.addNode(edm::PluginDescription<TestPluginFactory>("type", "ATestPlugin", true));
1202 
1203       edm::ParameterSet pset1;
1204       desc.validate(pset1);
1205       CHECK(pset1.getParameter<int>("anInt") == 5);
1206       CHECK(pset1.getParameter<std::string>("type") == "ATestPlugin");
1207     }
1208 
1209     {
1210       //an additional parameter
1211       edm::ParameterSetDescription desc;
1212       desc.addNode(edm::PluginDescription<TestPluginFactory>("type", true));
1213 
1214       edm::ParameterSet pset1;
1215       pset1.addParameter<std::string>("type", "ATestPlugin");
1216       pset1.addParameter<int>("anInt", 3);
1217       pset1.addParameter<int>("NotRight", 3);
1218 
1219       REQUIRE_THROWS_AS(desc.validate(pset1), edm::Exception);
1220     }
1221 
1222     SECTION("wildcard") {
1223       //embedded with wildcard
1224       edm::ParameterSetDescription desc;
1225       desc.addNode(edm::PluginDescription<TestPluginFactory>("type", true));
1226       edm::ParameterWildcard<edm::ParameterSetDescription> w("*", edm::RequireExactlyOne, true, desc);
1227 
1228       edm::ParameterSetDescription top;
1229       top.addNode(w);
1230 
1231       edm::ParameterSet pset1;
1232       pset1.addParameter<std::string>("type", "ATestPlugin");
1233 
1234       edm::ParameterSet psetTop;
1235       psetTop.addParameter<edm::ParameterSet>("foo", pset1);
1236 
1237       top.validate(psetTop);
1238     }
1239 
1240     {
1241       //missing type
1242       edm::ParameterSetDescription desc;
1243       desc.addNode(edm::PluginDescription<TestPluginFactory>("type", true));
1244 
1245       edm::ParameterSet pset1;
1246       pset1.addParameter<int>("anInt", 3);
1247 
1248       REQUIRE_THROWS_AS(desc.validate(pset1), edm::Exception);
1249     }
1250 
1251     {
1252       //a non-existent type
1253       edm::ParameterSetDescription desc;
1254       desc.addNode(edm::PluginDescription<TestPluginFactory>("type", true));
1255 
1256       edm::ParameterSet pset1;
1257       pset1.addParameter<std::string>("type", "ZTestPlugin");
1258 
1259       REQUIRE_THROWS_AS(desc.validate(pset1), cms::Exception);
1260     }
1261   }
1262 
1263   SECTION("VPSet with defaults") {
1264     edm::ParameterSetDescription psetDesc;
1265 
1266     std::vector<edm::ParameterSet> defaults{1};
1267     {
1268       auto& d = defaults.front();
1269       edm::ParameterSetDescription templte;
1270 
1271       templte.add<int>("i");
1272       d.addParameter<int>("i", 1);
1273 
1274       templte.add<std::vector<int>>("vi");
1275       d.addParameter<std::vector<int>>("vi", std::vector<int>({1}));
1276 
1277       templte.add<unsigned int>("ui");
1278       d.addParameter<unsigned int>("ui", 1);
1279 
1280       templte.add<std::vector<unsigned int>>("vui");
1281       d.addParameter<std::vector<unsigned int>>("vui", std::vector<unsigned int>({1}));
1282 
1283       templte.add<long long>("l");
1284       d.addParameter<long long>("l", 1);
1285 
1286       templte.add<std::vector<long long>>("vl");
1287       d.addParameter<std::vector<long long>>("vl", std::vector<long long>({1}));
1288 
1289       templte.add<unsigned long long>("ul");
1290       d.addParameter<unsigned long long>("ul", 1);
1291 
1292       templte.add<std::vector<unsigned long long>>("vul");
1293       d.addParameter<std::vector<unsigned long long>>("vul", std::vector<unsigned long long>({1}));
1294 
1295       templte.add<bool>("b");
1296       d.addParameter<bool>("b", true);
1297 
1298       templte.add<double>("d");
1299       d.addParameter<double>("d", 1.0);
1300 
1301       templte.add<std::vector<double>>("vd");
1302       d.addParameter<std::vector<double>>("vd", std::vector<double>({1.0}));
1303 
1304       templte.add<std::string>("s");
1305       d.addParameter<std::string>("s", "a");
1306 
1307       templte.add<std::vector<std::string>>("vs");
1308       d.addParameter<std::vector<std::string>>("vs", std::vector<std::string>({"a"}));
1309 
1310       templte.add<edm::InputTag>("t");
1311       d.addParameter<edm::InputTag>("t", edm::InputTag("foo"));
1312 
1313       templte.add<std::vector<edm::InputTag>>("vt");
1314       d.addParameter<std::vector<edm::InputTag>>("vt", std::vector<edm::InputTag>({edm::InputTag("foo")}));
1315 
1316       templte.add<edm::ESInputTag>("et");
1317       d.addParameter<edm::ESInputTag>("et", edm::ESInputTag(":foo"));
1318 
1319       templte.add<std::vector<edm::ESInputTag>>("vet");
1320       d.addParameter<std::vector<edm::ESInputTag>>("vet", std::vector<edm::ESInputTag>({edm::ESInputTag(":foo")}));
1321 
1322       edm::FileInPath::disableFileLookup();
1323       templte.add<edm::FileInPath>("f");
1324       d.addParameter<edm::FileInPath>("f", edm::FileInPath());
1325 
1326       templte.add<edm::EventID>("e");
1327       d.addParameter<edm::EventID>("e", edm::EventID(1, 2, 3));
1328 
1329       templte.add<std::vector<edm::EventID>>("ve");
1330       d.addParameter<std::vector<edm::EventID>>("ve", std::vector<edm::EventID>({edm::EventID(1, 2, 3)}));
1331 
1332       templte.add<edm::LuminosityBlockID>("L");
1333       d.addParameter<edm::LuminosityBlockID>("L", edm::LuminosityBlockID(1, 2));
1334 
1335       templte.add<std::vector<edm::LuminosityBlockID>>("vL");
1336       d.addParameter<std::vector<edm::LuminosityBlockID>>(
1337           "vL", std::vector<edm::LuminosityBlockID>({edm::LuminosityBlockID(1, 2)}));
1338 
1339       templte.add<edm::EventRange>("er");
1340       d.addParameter<edm::EventRange>("er", edm::EventRange(1, 2, 3, 4, 5, 6));
1341 
1342       templte.add<std::vector<edm::EventRange>>("ver");
1343       d.addParameter<std::vector<edm::EventRange>>("ver",
1344                                                    std::vector<edm::EventRange>({edm::EventRange(1, 2, 3, 4, 5, 6)}));
1345 
1346       templte.add<edm::LuminosityBlockRange>("Lr");
1347       d.addParameter<edm::LuminosityBlockRange>("Lr", edm::LuminosityBlockRange(1, 2, 3, 4));
1348 
1349       templte.add<std::vector<edm::LuminosityBlockRange>>("vLr");
1350       d.addParameter<std::vector<edm::LuminosityBlockRange>>(
1351           "vLr", std::vector<edm::LuminosityBlockRange>({edm::LuminosityBlockRange(1, 2, 3, 4)}));
1352 
1353       templte.add<edm::ParameterSetDescription>("p", edm::ParameterSetDescription());
1354       d.addParameter<edm::ParameterSet>("p", edm::ParameterSet());
1355 
1356       templte.addVPSet("vp", edm::ParameterSetDescription());
1357       d.addParameter<std::vector<edm::ParameterSet>>("vp", std::vector<edm::ParameterSet>());
1358 
1359       psetDesc.addVPSet("vp", templte, defaults);
1360     }
1361     SECTION("writeCfi full") {
1362       edm::ParameterSet test;
1363       test.addParameter("vp", defaults);
1364       psetDesc.validate(test);
1365 
1366       std::ostringstream s;
1367       edm::CfiOptions fullOps = edm::cfi::Typed{};
1368       psetDesc.writeCfi(s, false, 0, fullOps);
1369       std::string expected = R"-(
1370 vp = cms.VPSet(
1371   cms.PSet(
1372     L = cms.LuminosityBlockID(1, 2),
1373     Lr = cms.LuminosityBlockRange('1:2-3:4'),
1374     b = cms.bool(True),
1375     d = cms.double(1),
1376     e = cms.EventID(1, 2, 3),
1377     er = cms.EventRange('1:2:3-4:5:6'),
1378     et = cms.ESInputTag('', 'foo'),
1379     f = cms.FileInPath(''),
1380     i = cms.int32(1),
1381     l = cms.int64(1),
1382     s = cms.string('a'),
1383     t = cms.InputTag('foo'),
1384     ui = cms.uint32(1),
1385     ul = cms.uint64(1),
1386     vL = cms.VLuminosityBlockID('1:2'),
1387     vLr = cms.VLuminosityBlockRange('1:2-3:4'),
1388     vd = cms.vdouble(1),
1389     ve = cms.VEventID('1:2:3'),
1390     ver = cms.VEventRange('1:2:3-4:5:6'),
1391     vet = cms.VESInputTag(':foo'),
1392     vi = cms.vint32(1),
1393     vl = cms.vint64(1),
1394     vs = cms.vstring('a'),
1395     vt = cms.VInputTag('foo'),
1396     vui = cms.vuint32(1),
1397     vul = cms.vuint64(1),
1398     p = cms.PSet(),
1399     vp = cms.VPSet(
1400     )
1401   )
1402 )
1403 )-";
1404 
1405       CHECK(expected == s.str());
1406     }
1407     SECTION("writeCfi Untyped") {
1408       edm::ParameterSet test;
1409       test.addParameter("vp", defaults);
1410       psetDesc.validate(test);
1411 
1412       std::ostringstream s;
1413       edm::CfiOptions fullOps = edm::cfi::Untyped{edm::cfi::Paths{}};
1414       psetDesc.writeCfi(s, false, 0, fullOps);
1415       std::string expected = R"-(
1416 vp = [
1417   cms.PSet(
1418     L = cms.LuminosityBlockID(1, 2),
1419     Lr = cms.LuminosityBlockRange('1:2-3:4'),
1420     b = cms.bool(True),
1421     d = cms.double(1),
1422     e = cms.EventID(1, 2, 3),
1423     er = cms.EventRange('1:2:3-4:5:6'),
1424     et = cms.ESInputTag('', 'foo'),
1425     f = cms.FileInPath(''),
1426     i = cms.int32(1),
1427     l = cms.int64(1),
1428     s = cms.string('a'),
1429     t = cms.InputTag('foo'),
1430     ui = cms.uint32(1),
1431     ul = cms.uint64(1),
1432     vL = cms.VLuminosityBlockID('1:2'),
1433     vLr = cms.VLuminosityBlockRange('1:2-3:4'),
1434     vd = cms.vdouble(1),
1435     ve = cms.VEventID('1:2:3'),
1436     ver = cms.VEventRange('1:2:3-4:5:6'),
1437     vet = cms.VESInputTag(':foo'),
1438     vi = cms.vint32(1),
1439     vl = cms.vint64(1),
1440     vs = cms.vstring('a'),
1441     vt = cms.VInputTag('foo'),
1442     vui = cms.vuint32(1),
1443     vul = cms.vuint64(1),
1444     p = cms.PSet(),
1445     vp = cms.VPSet(
1446     )
1447   )
1448 ]
1449 )-";
1450 
1451       CHECK(expected == s.str());
1452     }
1453   }
1454 
1455   SECTION("PSet with default") {
1456     edm::ParameterSetDescription psetDesc;
1457 
1458     {
1459       edm::ParameterSetDescription templte;
1460 
1461       templte.add<int>("i", 1);
1462       templte.add<std::vector<int>>("vi", std::vector<int>({1}));
1463       templte.add<unsigned int>("ui", 1);
1464       templte.add<std::vector<unsigned int>>("vui", std::vector<unsigned int>({1}));
1465       templte.add<long long>("l", 1);
1466       templte.add<std::vector<long long>>("vl", std::vector<long long>({1}));
1467       templte.add<unsigned long long>("ul", 1);
1468       templte.add<std::vector<unsigned long long>>("vul", std::vector<unsigned long long>({1}));
1469       templte.add<bool>("b", true);
1470       templte.add<double>("d", 1.0);
1471       templte.add<std::vector<double>>("vd", std::vector<double>({1.0}));
1472       templte.add<std::string>("s", "a");
1473       templte.add<std::vector<std::string>>("vs", std::vector<std::string>({"a"}));
1474       templte.add<edm::InputTag>("t", edm::InputTag("foo"));
1475       templte.add<std::vector<edm::InputTag>>("vt", std::vector<edm::InputTag>({edm::InputTag("foo")}));
1476       templte.add<edm::ESInputTag>("et", edm::ESInputTag(":foo"));
1477       templte.add<std::vector<edm::ESInputTag>>("vet", std::vector<edm::ESInputTag>({edm::ESInputTag(":foo")}));
1478       edm::FileInPath::disableFileLookup();
1479       templte.add<edm::FileInPath>("f", edm::FileInPath());
1480       templte.add<edm::EventID>("e", edm::EventID(1, 2, 3));
1481       templte.add<std::vector<edm::EventID>>("ve", std::vector<edm::EventID>({edm::EventID(1, 2, 3)}));
1482       templte.add<edm::LuminosityBlockID>("L", edm::LuminosityBlockID(1, 2));
1483       templte.add<std::vector<edm::LuminosityBlockID>>(
1484           "vL", std::vector<edm::LuminosityBlockID>({edm::LuminosityBlockID(1, 2)}));
1485       templte.add<edm::EventRange>("er", edm::EventRange(1, 2, 3, 4, 5, 6));
1486       templte.add<std::vector<edm::EventRange>>("ver",
1487                                                 std::vector<edm::EventRange>({edm::EventRange(1, 2, 3, 4, 5, 6)}));
1488       templte.add<edm::LuminosityBlockRange>("Lr", edm::LuminosityBlockRange(1, 2, 3, 4));
1489       templte.add<std::vector<edm::LuminosityBlockRange>>(
1490           "vLr", std::vector<edm::LuminosityBlockRange>({edm::LuminosityBlockRange(1, 2, 3, 4)}));
1491       templte.add<edm::ParameterSetDescription>("p", edm::ParameterSetDescription());
1492       templte.addVPSet("vp", edm::ParameterSetDescription(), std::vector<edm::ParameterSet>());
1493       psetDesc.add<edm::ParameterSetDescription>("p", templte);
1494     }
1495     SECTION("writeCfi full") {
1496       edm::ParameterSet test;
1497       test.addParameter("p", edm::ParameterSet());
1498       psetDesc.validate(test);
1499 
1500       std::ostringstream s;
1501       edm::CfiOptions fullOps = edm::cfi::Typed{};
1502       psetDesc.writeCfi(s, false, 0, fullOps);
1503       std::string expected = R"-(
1504 p = cms.PSet(
1505   i = cms.int32(1),
1506   vi = cms.vint32(1),
1507   ui = cms.uint32(1),
1508   vui = cms.vuint32(1),
1509   l = cms.int64(1),
1510   vl = cms.vint64(1),
1511   ul = cms.uint64(1),
1512   vul = cms.vuint64(1),
1513   b = cms.bool(True),
1514   d = cms.double(1),
1515   vd = cms.vdouble(1),
1516   s = cms.string('a'),
1517   vs = cms.vstring('a'),
1518   t = cms.InputTag('foo'),
1519   vt = cms.VInputTag('foo'),
1520   et = cms.ESInputTag('', 'foo'),
1521   vet = cms.VESInputTag(':foo'),
1522   f = cms.FileInPath(''),
1523   e = cms.EventID(1, 2, 3),
1524   ve = cms.VEventID('1:2:3'),
1525   L = cms.LuminosityBlockID(1, 2),
1526   vL = cms.VLuminosityBlockID('1:2'),
1527   er = cms.EventRange('1:2:3-4:5:6'),
1528   ver = cms.VEventRange('1:2:3-4:5:6'),
1529   Lr = cms.LuminosityBlockRange('1:2-3:4'),
1530   vLr = cms.VLuminosityBlockRange('1:2-3:4'),
1531   p = cms.PSet(),
1532   vp = cms.VPSet(
1533   )
1534 )
1535 )-";
1536 
1537       CHECK(expected == s.str());
1538     }
1539     SECTION("writeCfi Untyped") {
1540       std::ostringstream s;
1541       edm::CfiOptions fullOps = edm::cfi::Untyped{edm::cfi::Paths{}};
1542       psetDesc.writeCfi(s, false, 0, fullOps);
1543       std::string expected = R"-(
1544 p = dict(
1545   i = 1,
1546   vi = [1],
1547   ui = 1,
1548   vui = [1],
1549   l = 1,
1550   vl = [1],
1551   ul = 1,
1552   vul = [1],
1553   b = True,
1554   d = 1,
1555   vd = [1],
1556   s = 'a',
1557   vs = ['a'],
1558   t = ('foo'),
1559   vt = ['foo'],
1560   et = ('', 'foo'),
1561   vet = [':foo'],
1562   f = '',
1563   e = (1, 2, 3),
1564   ve = ['1:2:3'],
1565   L = (1, 2),
1566   vL = ['1:2'],
1567   er = ('1:2:3-4:5:6'),
1568   ver = ['1:2:3-4:5:6'],
1569   Lr = ('1:2-3:4'),
1570   vLr = ['1:2-3:4'],
1571   p = dict(),
1572   vp = [
1573   ]
1574 )
1575 )-";
1576 
1577       CHECK(expected == s.str());
1578     }
1579   }
1580 
1581   SECTION("setAllowAnything") {
1582     edm::ParameterSetDescription psetDesc;
1583     CHECK(!psetDesc.anythingAllowed());
1584     CHECK(!psetDesc.isUnknown());
1585     CHECK(psetDesc.begin() == psetDesc.end());
1586 
1587     edm::ParameterSet params;
1588     psetDesc.validate(params);
1589 
1590     params.addParameter<std::string>("testname", std::string("testvalue"));
1591 
1592     // Expect this to throw, parameter not in description
1593     REQUIRE_THROWS_AS(psetDesc.validate(params), edm::Exception);
1594 
1595     psetDesc.setAllowAnything();
1596     CHECK(psetDesc.anythingAllowed());
1597 
1598     psetDesc.validate(params);
1599 
1600     psetDesc.add<int>("testInt", 11);
1601     psetDesc.validate(params);
1602     CHECK(params.exists("testInt"));
1603   }
1604 
1605   SECTION("unknown") {
1606     edm::ParameterSetDescription psetDesc;
1607 
1608     edm::ParameterSet params;
1609     params.addParameter<std::string>("testname", std::string("testvalue"));
1610     psetDesc.setUnknown();
1611     CHECK(psetDesc.isUnknown());
1612 
1613     psetDesc.validate(params);
1614   }
1615 
1616   SECTION("FileInPath") {
1617     // Test this type separately because I do not know how to
1618     // add an entry into a ParameterSet without FileInPath pointing
1619     // at a real file.
1620     edm::ParameterSetDescription psetDesc;
1621     edm::ParameterDescriptionBase* par = psetDesc.add<edm::FileInPath>("fileInPath", edm::FileInPath());
1622     CHECK(par->type() == edm::k_FileInPath);
1623     CHECK(edm::parameterTypeEnumToString(par->type()) == std::string("FileInPath"));
1624   }
1625 
1626   SECTION("main") {
1627     edm::ParameterSetDescription psetDesc;
1628     edm::ParameterSet pset;
1629 
1630     psetDesc.reserve(2);
1631 
1632     int a = 1;
1633     edm::ParameterDescriptionBase* par = psetDesc.add<int>(std::string("ivalue"), a);
1634     CHECK(par->exists(pset) == false);
1635     CHECK(par->partiallyExists(pset) == false);
1636     CHECK(par->howManyXORSubNodesExist(pset) == 0);
1637     pset.addParameter<int>("ivalue", a);
1638     CHECK(par != 0);
1639     CHECK(par->label() == std::string("ivalue"));
1640     CHECK(par->type() == edm::k_int32);
1641     CHECK(par->isTracked() == true);
1642     CHECK(edm::parameterTypeEnumToString(par->type()) == std::string("int32"));
1643     CHECK(par->exists(pset) == true);
1644     CHECK(par->partiallyExists(pset) == true);
1645     CHECK(par->howManyXORSubNodesExist(pset) == 1);
1646 
1647     edm::ParameterSet psetWrongTrackiness;
1648     psetWrongTrackiness.addUntrackedParameter("ivalue", a);
1649     REQUIRE_THROWS_AS(psetDesc.validate(psetWrongTrackiness), edm::Exception);
1650 
1651     edm::ParameterSet psetWrongType;
1652     psetWrongType.addUntrackedParameter("ivalue", 1U);
1653     REQUIRE_THROWS_AS(psetDesc.validate(psetWrongType), edm::Exception);
1654 
1655     edm::ParameterSetDescription::const_iterator parIter = psetDesc.begin();
1656     CHECK(parIter->node().operator->() == par);
1657 
1658     unsigned b = 2;
1659     par = psetDesc.add<unsigned>("uvalue", b);
1660     pset.addParameter<unsigned>("uvalue", b);
1661     CHECK(par != 0);
1662     CHECK(par->label() == std::string("uvalue"));
1663     CHECK(par->type() == edm::k_uint32);
1664     CHECK(par->isTracked() == true);
1665     CHECK(edm::parameterTypeEnumToString(par->type()) == std::string("uint32"));
1666 
1667     parIter = psetDesc.begin();
1668     ++parIter;
1669     CHECK(parIter->node().operator->() == par);
1670 
1671     long long c = 3;
1672     par = psetDesc.addUntracked<long long>(std::string("i64value"), c);
1673     pset.addUntrackedParameter<long long>("i64value", c);
1674     CHECK(par != 0);
1675     CHECK(par->label() == std::string("i64value"));
1676     CHECK(par->type() == edm::k_int64);
1677     CHECK(par->isTracked() == false);
1678     CHECK(edm::parameterTypeEnumToString(par->type()) == std::string("int64"));
1679 
1680     unsigned long long d = 4;
1681     par = psetDesc.addUntracked<unsigned long long>("u64value", d);
1682     pset.addUntrackedParameter<unsigned long long>("u64value", d);
1683     CHECK(par != 0);
1684     CHECK(par->label() == std::string("u64value"));
1685     CHECK(par->type() == edm::k_uint64);
1686     CHECK(par->isTracked() == false);
1687     CHECK(edm::parameterTypeEnumToString(par->type()) == std::string("uint64"));
1688 
1689     double e = 5;
1690     par = psetDesc.addOptional<double>(std::string("dvalue"), e);
1691     pset.addParameter<double>("dvalue", e);
1692     CHECK(par != 0);
1693     CHECK(par->label() == std::string("dvalue"));
1694     CHECK(par->type() == edm::k_double);
1695     CHECK(par->isTracked() == true);
1696     CHECK(edm::parameterTypeEnumToString(par->type()) == std::string("double"));
1697 
1698     bool f = true;
1699     par = psetDesc.addOptional<bool>("bvalue", f);
1700     pset.addParameter<bool>("bvalue", f);
1701     CHECK(par != 0);
1702     CHECK(par->label() == std::string("bvalue"));
1703     CHECK(par->type() == edm::k_bool);
1704     CHECK(par->isTracked() == true);
1705     CHECK(edm::parameterTypeEnumToString(par->type()) == std::string("bool"));
1706 
1707     std::string g;
1708     par = psetDesc.addOptionalUntracked<std::string>(std::string("svalue"), g);
1709     pset.addUntrackedParameter<std::string>("svalue", g);
1710     CHECK(par != 0);
1711     CHECK(par->label() == std::string("svalue"));
1712     CHECK(par->type() == edm::k_stringRaw);
1713     CHECK(par->isTracked() == false);
1714     CHECK(edm::parameterTypeEnumToString(par->type()) == std::string("string"));
1715 
1716     edm::EventID h;
1717     par = psetDesc.addOptionalUntracked<edm::EventID>("evalue", h);
1718     pset.addUntrackedParameter<edm::EventID>("evalue", h);
1719     CHECK(par != 0);
1720     CHECK(par->label() == std::string("evalue"));
1721     CHECK(par->type() == edm::k_EventID);
1722     CHECK(par->isTracked() == false);
1723     CHECK(edm::parameterTypeEnumToString(par->type()) == std::string("EventID"));
1724 
1725     edm::LuminosityBlockID i;
1726     par = psetDesc.add<edm::LuminosityBlockID>("lvalue", i);
1727     pset.addParameter<edm::LuminosityBlockID>("lvalue", i);
1728     CHECK(par->type() == edm::k_LuminosityBlockID);
1729     CHECK(edm::parameterTypeEnumToString(par->type()) == std::string("LuminosityBlockID"));
1730 
1731     edm::InputTag j;
1732     par = psetDesc.add<edm::InputTag>("input", j);
1733     pset.addParameter<edm::InputTag>("input", j);
1734     CHECK(par->type() == edm::k_InputTag);
1735     CHECK(edm::parameterTypeEnumToString(par->type()) == std::string("InputTag"));
1736 
1737     edm::ESInputTag k;
1738     par = psetDesc.add<edm::ESInputTag>("esinput", k);
1739     pset.addParameter<edm::ESInputTag>("esinput", k);
1740     CHECK(par->type() == edm::k_ESInputTag);
1741     CHECK(edm::parameterTypeEnumToString(par->type()) == std::string("ESInputTag"));
1742 
1743     std::vector<int> v1;
1744     par = psetDesc.add<std::vector<int>>("v1", v1);
1745     pset.addParameter<std::vector<int>>("v1", v1);
1746     CHECK(par->type() == edm::k_vint32);
1747     CHECK(edm::parameterTypeEnumToString(par->type()) == std::string("vint32"));
1748 
1749     std::vector<unsigned> v2;
1750     par = psetDesc.add<std::vector<unsigned>>("v2", v2);
1751     pset.addParameter<std::vector<unsigned>>("v2", v2);
1752     CHECK(par->type() == edm::k_vuint32);
1753     CHECK(edm::parameterTypeEnumToString(par->type()) == std::string("vuint32"));
1754 
1755     std::vector<long long> v3;
1756     par = psetDesc.add<std::vector<long long>>("v3", v3);
1757     pset.addParameter<std::vector<long long>>("v3", v3);
1758     CHECK(par->type() == edm::k_vint64);
1759     CHECK(edm::parameterTypeEnumToString(par->type()) == std::string("vint64"));
1760 
1761     std::vector<unsigned long long> v4;
1762     par = psetDesc.add<std::vector<unsigned long long>>("v4", v4);
1763     pset.addParameter<std::vector<unsigned long long>>("v4", v4);
1764     CHECK(par->type() == edm::k_vuint64);
1765     CHECK(edm::parameterTypeEnumToString(par->type()) == std::string("vuint64"));
1766 
1767     std::vector<double> v5;
1768     par = psetDesc.add<std::vector<double>>("v5", v5);
1769     pset.addParameter<std::vector<double>>("v5", v5);
1770     CHECK(par->type() == edm::k_vdouble);
1771     CHECK(edm::parameterTypeEnumToString(par->type()) == std::string("vdouble"));
1772 
1773     std::vector<std::string> v6;
1774     par = psetDesc.add<std::vector<std::string>>("v6", v6);
1775     pset.addParameter<std::vector<std::string>>("v6", v6);
1776     CHECK(par->type() == edm::k_vstringRaw);
1777     CHECK(edm::parameterTypeEnumToString(par->type()) == std::string("vstring"));
1778 
1779     std::vector<edm::EventID> v7;
1780     par = psetDesc.add<std::vector<edm::EventID>>("v7", v7);
1781     pset.addParameter<std::vector<edm::EventID>>("v7", v7);
1782     CHECK(par->type() == edm::k_VEventID);
1783     CHECK(edm::parameterTypeEnumToString(par->type()) == std::string("VEventID"));
1784 
1785     std::vector<edm::LuminosityBlockID> v8;
1786     par = psetDesc.add<std::vector<edm::LuminosityBlockID>>("v8", v8);
1787     pset.addParameter<std::vector<edm::LuminosityBlockID>>("v8", v8);
1788     CHECK(par->type() == edm::k_VLuminosityBlockID);
1789     CHECK(edm::parameterTypeEnumToString(par->type()) == std::string("VLuminosityBlockID"));
1790 
1791     std::vector<edm::InputTag> v9;
1792     par = psetDesc.add<std::vector<edm::InputTag>>("v9", v9);
1793     pset.addParameter<std::vector<edm::InputTag>>("v9", v9);
1794     CHECK(par->type() == edm::k_VInputTag);
1795     CHECK(edm::parameterTypeEnumToString(par->type()) == std::string("VInputTag"));
1796 
1797     std::vector<edm::ESInputTag> v11;
1798     par = psetDesc.add<std::vector<edm::ESInputTag>>("v11", v11);
1799     pset.addParameter<std::vector<edm::ESInputTag>>("v11", v11);
1800     CHECK(par->type() == edm::k_VESInputTag);
1801     CHECK(edm::parameterTypeEnumToString(par->type()) == std::string("VESInputTag"));
1802 
1803     edm::ParameterSetDescription m;
1804     par = psetDesc.add<edm::ParameterSetDescription>("psetDesc", m);
1805     CHECK(par->exists(pset) == false);
1806     CHECK(par->partiallyExists(pset) == false);
1807     CHECK(par->howManyXORSubNodesExist(pset) == 0);
1808     edm::ParameterSet p1;
1809     pset.addParameter<edm::ParameterSet>("psetDesc", p1);
1810     CHECK(par->type() == edm::k_PSet);
1811     CHECK(edm::parameterTypeEnumToString(par->type()) == std::string("PSet"));
1812     CHECK(par->exists(pset) == true);
1813     CHECK(par->partiallyExists(pset) == true);
1814     CHECK(par->howManyXORSubNodesExist(pset) == 1);
1815 
1816     edm::ParameterSetDescription v10;
1817     par = psetDesc.addVPSet("psetVectorDesc", v10);
1818     CHECK(par->exists(pset) == false);
1819     CHECK(par->partiallyExists(pset) == false);
1820     CHECK(par->howManyXORSubNodesExist(pset) == 0);
1821     std::vector<edm::ParameterSet> vp1;
1822     pset.addParameter<std::vector<edm::ParameterSet>>("psetVectorDesc", vp1);
1823     CHECK(par->type() == edm::k_VPSet);
1824     CHECK(edm::parameterTypeEnumToString(par->type()) == std::string("VPSet"));
1825     CHECK(par->exists(pset) == true);
1826     CHECK(par->partiallyExists(pset) == true);
1827     CHECK(par->howManyXORSubNodesExist(pset) == 1);
1828 
1829     psetDesc.validate(pset);
1830 
1831     // Add a ParameterSetDescription nested in a ParameterSetDescription nested in
1832     // a vector in the top level ParameterSetDescription to see if the nesting is
1833     // working properly.
1834 
1835     edm::ParameterSet nest2;
1836     nest2.addParameter<int>("intLevel2a", 1);
1837     nest2.addUntrackedParameter<int>("intLevel2b", 1);
1838     nest2.addParameter<int>("intLevel2e", 1);
1839     nest2.addUntrackedParameter<int>("intLevel2f", 1);
1840 
1841     edm::ParameterSet nest1;
1842     nest1.addParameter<int>("intLevel1a", 1);
1843     nest1.addParameter<edm::ParameterSet>("nestLevel1b", nest2);
1844 
1845     std::vector<edm::ParameterSet> vPset;
1846     vPset.push_back(edm::ParameterSet());
1847     vPset.push_back(nest1);
1848 
1849     pset.addUntrackedParameter<std::vector<edm::ParameterSet>>("nestLevel0", vPset);
1850 
1851     std::vector<edm::ParameterSetDescription> testDescriptions;
1852     testDescriptions.push_back(psetDesc);
1853     testDescriptions.push_back(psetDesc);
1854     testDescriptions.push_back(psetDesc);
1855 
1856     for (int ii = 0; ii < 3; ++ii) {
1857       edm::ParameterSetDescription nestLevel2;
1858 
1859       // for the first test do not put a parameter in the description
1860       // so there will be an extra parameter in the ParameterSet and
1861       // validation should fail.
1862       if (ii > 0)
1863         nestLevel2.add<int>("intLevel2a", 1);
1864 
1865       // for the next test validation should pass
1866 
1867       // For the last test add an extra required parameter in the
1868       // description that is not in the ParameterSet.
1869       if (ii == 2)
1870         nestLevel2.add<int>("intLevel2extra", 11);
1871 
1872       nestLevel2.addUntracked<int>("intLevel2b", 1);
1873       nestLevel2.addOptional<int>("intLevel2c", 1);
1874       nestLevel2.addOptionalUntracked<int>("intLevel2d", 1);
1875       nestLevel2.addOptional<int>("intLevel2e", 1);
1876       nestLevel2.addOptionalUntracked<int>("intLevel2f", 1);
1877 
1878       edm::ParameterSetDescription nestLevel1;
1879       nestLevel1.add<int>("intLevel1a", 1);
1880       nestLevel1.add<edm::ParameterSetDescription>("nestLevel1b", nestLevel2);
1881 
1882       testDescriptions[ii].addVPSetUntracked("nestLevel0", nestLevel1);
1883     }
1884 
1885     // Now run the validation and make sure we get the expected results
1886     REQUIRE_THROWS_AS(testDescriptions[0].validate(pset), edm::Exception);
1887 
1888     // This one should pass validation with no exception
1889     testDescriptions[1].validate(pset);
1890 
1891     // This validation should also pass and it should insert
1892     // the missing parameter into the ParameterSet
1893     testDescriptions[2].validate(pset);
1894 
1895     std::vector<edm::ParameterSet> const& vpset = pset.getUntrackedParameterSetVector("nestLevel0");
1896     edm::ParameterSet const& psetInPset = vpset[1].getParameterSet("nestLevel1b");
1897     CHECK(psetInPset.getParameter<int>("intLevel2extra") == 11);
1898 
1899     // One more iteration, this time the purpose is to
1900     // test the parameterSetDescription accessors.
1901     edm::ParameterSetDescription nestLevel2;
1902     par = nestLevel2.add<int>("intLevel2a", 1);
1903     par->setComment("testComment");
1904     CHECK(par->parameterSetDescription() == 0);
1905     edm::ParameterDescriptionBase const& constParRef = *par;
1906     CHECK(constParRef.parameterSetDescription() == 0);
1907 
1908     nestLevel2.addUntracked<int>("intLevel2b", 1);
1909     nestLevel2.addOptional<int>("intLevel2c", 1);
1910     nestLevel2.addOptionalUntracked<int>("intLevel2d", 1);
1911     nestLevel2.addOptional<int>("intLevel2e", 1);
1912     nestLevel2.addOptionalUntracked<int>("intLevel2f", 1);
1913     nestLevel2.setAllowAnything();
1914 
1915     edm::ParameterSetDescription nestLevel1;
1916     par = nestLevel1.add<int>("intLevel1a", 1);
1917     par->setComment("testComment1");
1918     par = nestLevel1.add<edm::ParameterSetDescription>("nestLevel1b", nestLevel2);
1919     CHECK(par->parameterSetDescription() != 0);
1920     CHECK(par->parameterSetDescription()->begin()->node()->comment() == std::string("testComment"));
1921     edm::ParameterDescriptionBase const& constParRef2 = *par;
1922     CHECK(constParRef2.parameterSetDescription() != 0);
1923     CHECK(constParRef2.parameterSetDescription()->begin()->node()->comment() == std::string("testComment"));
1924 
1925     CHECK(par->parameterSetDescription()->anythingAllowed() == true);
1926     CHECK(constParRef2.parameterSetDescription()->anythingAllowed() == true);
1927 
1928     par = psetDesc.addVPSetUntracked("nestLevel0", nestLevel1);
1929     CHECK(par->parameterSetDescription() != 0);
1930     CHECK(par->parameterSetDescription()->begin()->node()->comment() == std::string("testComment1"));
1931     edm::ParameterDescriptionBase const& constParRef3 = *par;
1932     CHECK(constParRef3.parameterSetDescription() != 0);
1933     CHECK(constParRef3.parameterSetDescription()->begin()->node()->comment() == std::string("testComment1"));
1934 
1935     psetDesc.validate(pset);
1936   }
1937 }  // namespace testParameterSetDescription
1938 
1939 EDM_REGISTER_VALIDATED_PLUGINFACTORY(TestPluginFactory, "TestPluginFWCoreParameterSet");
1940 
1941 DEFINE_EDM_VALIDATED_PLUGIN(TestPluginFactory, testParameterSetDescription::ATestPlugin, "ATestPlugin");
1942 DEFINE_EDM_VALIDATED_PLUGIN(TestPluginFactory, testParameterSetDescription::BTestPlugin, "BTestPlugin");