Back to home page

Project CMSSW displayed by LXR

 
 

    


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

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