Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-05-31 03:10:35

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