Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:13:03

0001 /*
0002  *  serviceregistry_t.cppunit.cc
0003  *  CMSSW
0004  *
0005  *  Created by Chris Jones on 9/7/05.
0006  *
0007  */
0008 
0009 #include "FWCore/ServiceRegistry/interface/ServiceRegistry.h"
0010 #include "FWCore/ServiceRegistry/interface/Service.h"
0011 #include "FWCore/ServiceRegistry/test/stubs/DummyService.h"
0012 
0013 #include <cppunit/extensions/HelperMacros.h>
0014 
0015 #include "FWCore/PluginManager/interface/ProblemTracker.h"
0016 
0017 #include <thread>
0018 
0019 #include <atomic>
0020 
0021 class testServiceRegistry : public CppUnit::TestFixture {
0022   CPPUNIT_TEST_SUITE(testServiceRegistry);
0023 
0024   CPPUNIT_TEST(loadTest);
0025   CPPUNIT_TEST(hierarchyTest);
0026   CPPUNIT_TEST(threadTest);
0027   CPPUNIT_TEST(externalServiceTest);
0028   CPPUNIT_TEST(saveConfigWithExternalTest);
0029 
0030   CPPUNIT_TEST_SUITE_END();
0031 
0032 public:
0033   void setUp() {}
0034   void tearDown() {}
0035 
0036   void loadTest();
0037   void hierarchyTest();
0038   void threadTest();
0039   void externalServiceTest();
0040   void saveConfigWithExternalTest();
0041 };
0042 
0043 ///registration of the test so that the runner can find it
0044 CPPUNIT_TEST_SUITE_REGISTRATION(testServiceRegistry);
0045 
0046 void testServiceRegistry::loadTest() {
0047   edm::AssertHandler ah;
0048 
0049   std::vector<edm::ParameterSet> pss;
0050 
0051   edm::ParameterSet ps;
0052   std::string typeName("DummyService");
0053   ps.addParameter("@service_type", typeName);
0054   int value = 2;
0055   ps.addParameter("value", value);
0056   pss.push_back(ps);
0057 
0058   edm::ServiceToken token(edm::ServiceRegistry::createSet(pss));
0059 
0060   edm::ServiceRegistry::Operate operate(token);
0061   edm::Service<testserviceregistry::DummyService> dummy;
0062   CPPUNIT_ASSERT(dummy);
0063   CPPUNIT_ASSERT(dummy.isAvailable());
0064   CPPUNIT_ASSERT(dummy->value() == 2);
0065 }
0066 
0067 namespace {
0068   struct DummyService {
0069     int value_;
0070   };
0071 }  // namespace
0072 
0073 void testServiceRegistry::externalServiceTest() {
0074   edm::AssertHandler ah;
0075 
0076   {
0077     auto dummyPtr = std::make_unique<DummyService>();
0078     dummyPtr->value_ = 2;
0079     edm::ServiceToken token(edm::ServiceRegistry::createContaining(std::move(dummyPtr)));
0080 
0081     {
0082       edm::ServiceRegistry::Operate operate(token);
0083       edm::Service<DummyService> dummy;
0084       CPPUNIT_ASSERT(dummy);
0085       CPPUNIT_ASSERT(dummy.isAvailable());
0086       CPPUNIT_ASSERT(dummy->value_ == 2);
0087     }
0088     {
0089       auto anotherDummyPtr = std::make_unique<DummyService>();
0090       anotherDummyPtr->value_ = 4;
0091 
0092       std::vector<edm::ParameterSet> pss;
0093 
0094       edm::ParameterSet ps;
0095       std::string typeName("DummyService");
0096       ps.addParameter("@service_type", typeName);
0097       int value = 3;
0098       ps.addParameter("value", value);
0099       pss.push_back(ps);
0100 
0101       edm::ServiceToken tokenFromConfig(edm::ServiceRegistry::createSet(pss));
0102       edm::ServiceToken anotherToken(edm::ServiceRegistry::createContaining(
0103           std::move(anotherDummyPtr), tokenFromConfig, edm::serviceregistry::kOverlapIsError));
0104 
0105       edm::ServiceRegistry::Operate operate(anotherToken);
0106       edm::Service<testserviceregistry::DummyService> dummy;
0107       CPPUNIT_ASSERT(dummy);
0108       CPPUNIT_ASSERT(dummy.isAvailable());
0109       CPPUNIT_ASSERT(dummy->value() == 3);
0110 
0111       edm::Service<DummyService> dummyNotFromConfig;
0112       CPPUNIT_ASSERT(dummyNotFromConfig);
0113       CPPUNIT_ASSERT(dummyNotFromConfig.isAvailable());
0114       CPPUNIT_ASSERT(dummyNotFromConfig->value_ == 4);
0115     }
0116   }
0117 
0118   {
0119     // This is very similar to the above test. Pass in a ServiceWrapper to createContaining instead
0120     // of a unique_ptr
0121     auto dummyPtr = std::make_unique<DummyService>();
0122     auto wrapper = std::make_shared<edm::serviceregistry::ServiceWrapper<DummyService> >(std::move(dummyPtr));
0123 
0124     wrapper->get().value_ = 2;
0125 
0126     {
0127       edm::ServiceToken token(edm::ServiceRegistry::createContaining(wrapper));
0128       edm::ServiceRegistry::Operate operate(token);
0129       edm::Service<DummyService> dummy;
0130       CPPUNIT_ASSERT(dummy);
0131       CPPUNIT_ASSERT(dummy.isAvailable());
0132       CPPUNIT_ASSERT(dummy->value_ == 2);
0133     }
0134   }
0135 }
0136 
0137 void testServiceRegistry::saveConfigWithExternalTest() {
0138   //In the HLT the PrescaleService is created once and then used again
0139   // even if a new EventProcessor is created.  However, the '@save_config' must
0140   // still be added to the Service's PSet even if that service is not created
0141   edm::AssertHandler ah;
0142 
0143   std::vector<edm::ParameterSet> pss;
0144 
0145   {
0146     edm::ParameterSet ps;
0147     std::string typeName("DummyStoreConfigService");
0148     ps.addParameter("@service_type", typeName);
0149     pss.push_back(ps);
0150   }
0151   edm::ServiceToken token(edm::ServiceRegistry::createSet(pss));
0152   CPPUNIT_ASSERT(pss[0].exists("@save_config"));
0153 
0154   pss.clear();
0155 
0156   {
0157     edm::ParameterSet ps;
0158     std::string typeName("DummyStoreConfigService");
0159     ps.addParameter("@service_type", typeName);
0160     pss.push_back(ps);
0161   }
0162 
0163   //create the services
0164   edm::ServiceToken token2(edm::ServiceRegistry::createSet(pss, token, edm::serviceregistry::kTokenOverrides));
0165 
0166   CPPUNIT_ASSERT(pss[0].exists("@save_config"));
0167 }
0168 
0169 void testServiceRegistry::hierarchyTest() {
0170   edm::AssertHandler ah;
0171 
0172   std::vector<edm::ParameterSet> pss;
0173   {
0174     edm::ParameterSet ps;
0175     std::string typeName("DummyService");
0176     ps.addParameter("@service_type", typeName);
0177     int value = 1;
0178     ps.addParameter("value", value);
0179     pss.push_back(ps);
0180   }
0181   edm::ServiceToken token1(edm::ServiceRegistry::createSet(pss));
0182 
0183   pss.clear();
0184   {
0185     edm::ParameterSet ps;
0186     std::string typeName("DummyService");
0187     ps.addParameter("@service_type", typeName);
0188     int value = 2;
0189     ps.addParameter("value", value);
0190     pss.push_back(ps);
0191   }
0192   edm::ServiceToken token2(edm::ServiceRegistry::createSet(pss));
0193 
0194   edm::ServiceRegistry::Operate operate1(token1);
0195   {
0196     edm::Service<testserviceregistry::DummyService> dummy;
0197     CPPUNIT_ASSERT(dummy->value() == 1);
0198   }
0199   {
0200     edm::ServiceRegistry::Operate operate2(token2);
0201     edm::Service<testserviceregistry::DummyService> dummy;
0202     CPPUNIT_ASSERT(dummy->value() == 2);
0203   }
0204   {
0205     edm::Service<testserviceregistry::DummyService> dummy;
0206     CPPUNIT_ASSERT(dummy->value() == 1);
0207   }
0208 }
0209 
0210 namespace {
0211   struct UniqueRegistry {
0212     UniqueRegistry(void* iReg) : otherRegistry_(iReg) {}
0213 
0214     void operator()() { isUnique_ = (otherRegistry_ != &(edm::ServiceRegistry::instance())); }
0215     void* otherRegistry_;
0216     static std::atomic<bool> isUnique_;
0217   };
0218   std::atomic<bool> UniqueRegistry::isUnique_{false};
0219 
0220   struct PassServices {
0221     PassServices(edm::ServiceToken iToken, bool& oSucceeded, bool& oCaughtException)
0222         : token_(iToken), success_(&oSucceeded), caught_(&oCaughtException) {
0223       *success_ = false;
0224       *caught_ = false;
0225     }
0226 
0227     void operator()() {
0228       try {
0229         edm::ServiceRegistry::Operate operate(token_);
0230         edm::Service<testserviceregistry::DummyService> dummy;
0231         *success_ = dummy->value() == 1;
0232       } catch (...) {
0233         *caught_ = true;
0234       }
0235     }
0236 
0237     edm::ServiceToken token_;
0238     bool* success_;
0239     bool* caught_;
0240   };
0241 }  // namespace
0242 
0243 void testServiceRegistry::threadTest() {
0244   UniqueRegistry::isUnique_ = false;
0245   void* serviceRegistry = &(edm::ServiceRegistry::instance());
0246   UniqueRegistry unique(serviceRegistry);
0247   std::thread testUniqueness(unique);
0248   testUniqueness.join();
0249   CPPUNIT_ASSERT(UniqueRegistry::isUnique_);
0250 
0251   edm::AssertHandler ah;
0252 
0253   std::vector<edm::ParameterSet> pss;
0254   {
0255     edm::ParameterSet ps;
0256     std::string typeName("DummyService");
0257     ps.addParameter("@service_type", typeName);
0258     int value = 1;
0259     ps.addParameter("value", value);
0260     pss.push_back(ps);
0261   }
0262   edm::ServiceToken token(edm::ServiceRegistry::createSet(pss));
0263 
0264   bool succeededToPassServices = false;
0265   bool exceptionWasThrown = false;
0266 
0267   PassServices passRun(token, succeededToPassServices, exceptionWasThrown);
0268   std::thread testPassing(passRun);
0269   testPassing.join();
0270   CPPUNIT_ASSERT(!exceptionWasThrown);
0271   CPPUNIT_ASSERT(succeededToPassServices);
0272 }
0273 #include <Utilities/Testing/interface/CppUnit_testdriver.icpp>