Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-08-30 04:05:53

0001 /*
0002  *  esproducer_t.cppunit.cc
0003  *  EDMProto
0004  *
0005  *  Created by Chris Jones on 4/8/05.
0006  *  Changed by Viji Sundararajan on 28-Jun-05
0007  */
0008 #include <iostream>
0009 #include "cppunit/extensions/HelperMacros.h"
0010 #include "FWCore/Framework/interface/EDConsumerBase.h"
0011 #include "FWCore/Framework/interface/ESProducer.h"
0012 #include "FWCore/Framework/test/DummyData.h"
0013 #include "FWCore/Framework/test/Dummy2Record.h"
0014 #include "FWCore/Framework/test/DummyRecord.h"
0015 #include "FWCore/Framework/test/DummyFinder.h"
0016 #include "FWCore/Framework/test/DepOn2Record.h"
0017 #include "FWCore/Framework/test/DepRecord.h"
0018 #include "FWCore/Framework/interface/DataProxy.h"
0019 #include "FWCore/Framework/interface/EventSetup.h"
0020 #include "FWCore/Framework/interface/EventSetupProvider.h"
0021 #include "FWCore/Framework/interface/EventSetupRecordKey.h"
0022 #include "FWCore/Framework/src/SynchronousEventSetupsController.h"
0023 #include "FWCore/Framework/interface/es_Label.h"
0024 #include "FWCore/Framework/interface/ESHandle.h"
0025 #include "FWCore/Framework/interface/ESProducts.h"
0026 #include "FWCore/Framework/interface/ESRecordsToProxyIndices.h"
0027 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0028 #include "FWCore/ServiceRegistry/interface/ActivityRegistry.h"
0029 #include "FWCore/Utilities/interface/do_nothing_deleter.h"
0030 #include "FWCore/Utilities/interface/Exception.h"
0031 #include "FWCore/Concurrency/interface/ThreadsController.h"
0032 #include "FWCore/Concurrency/interface/FinalWaitingTask.h"
0033 
0034 #include <memory>
0035 #include <optional>
0036 
0037 using edm::eventsetup::test::DummyData;
0038 using namespace edm::eventsetup;
0039 using edm::ESProducer;
0040 using edm::EventSetupRecordIntervalFinder;
0041 
0042 namespace {
0043   edm::ParameterSet createDummyPset() {
0044     edm::ParameterSet pset;
0045     std::vector<std::string> emptyVStrings;
0046     pset.addParameter<std::vector<std::string>>("@all_esprefers", emptyVStrings);
0047     pset.addParameter<std::vector<std::string>>("@all_essources", emptyVStrings);
0048     pset.addParameter<std::vector<std::string>>("@all_esmodules", emptyVStrings);
0049     return pset;
0050   }
0051   edm::ActivityRegistry activityRegistry;
0052 
0053   struct DummyDataConsumerBase : public edm::EDConsumerBase {
0054     void prefetch(edm::EventSetupImpl const& iImpl) const {
0055       auto const& recs = this->esGetTokenRecordIndicesVector(edm::Transition::Event);
0056       auto const& proxies = this->esGetTokenIndicesVector(edm::Transition::Event);
0057       for (size_t i = 0; i != proxies.size(); ++i) {
0058         auto rec = iImpl.findImpl(recs[i]);
0059         if (rec) {
0060           oneapi::tbb::task_group group;
0061           edm::FinalWaitingTask waitTask{group};
0062           rec->prefetchAsync(
0063               edm::WaitingTaskHolder(group, &waitTask), proxies[i], &iImpl, edm::ServiceToken{}, edm::ESParentContext{});
0064           waitTask.wait();
0065         }
0066       }
0067     }
0068   };
0069 
0070   template <typename Record>
0071   struct DummyDataConsumer : public DummyDataConsumerBase {
0072     DummyDataConsumer() : m_token{esConsumes()} {}
0073     edm::ESGetToken<DummyData, Record> m_token;
0074   };
0075 
0076   struct DummyDataConsumer2 : public DummyDataConsumerBase {
0077     DummyDataConsumer2(edm::ESInputTag const& tag1, edm::ESInputTag const& tag2, edm::ESInputTag const& tag3)
0078         : m_token1{esConsumes(tag1)}, m_token2{esConsumes(tag2)}, m_token3{esConsumes(tag3)} {}
0079     edm::ESGetToken<DummyData, DummyRecord> m_token1;
0080     edm::ESGetToken<DummyData, DummyRecord> m_token2;
0081     edm::ESGetToken<DummyData, DummyRecord> m_token3;
0082   };
0083 }  // namespace
0084 
0085 class testEsproducer : public CppUnit::TestFixture {
0086   CPPUNIT_TEST_SUITE(testEsproducer);
0087 
0088   CPPUNIT_TEST(registerTest);
0089   CPPUNIT_TEST(getFromTest);
0090   CPPUNIT_TEST(getFromLambdaTest);
0091   CPPUNIT_TEST(getfromShareTest);
0092   CPPUNIT_TEST(getfromUniqueTest);
0093   CPPUNIT_TEST(getfromOptionalTest);
0094   CPPUNIT_TEST(decoratorTest);
0095   CPPUNIT_TEST(dependsOnTest);
0096   CPPUNIT_TEST(labelTest);
0097   CPPUNIT_TEST_EXCEPTION(failMultipleRegistration, cms::Exception);
0098   CPPUNIT_TEST(forceCacheClearTest);
0099   CPPUNIT_TEST(dataProxyProviderTest);
0100 
0101   CPPUNIT_TEST_SUITE_END();
0102 
0103 public:
0104   void setUp() { m_scheduler = std::make_unique<edm::ThreadsController>(1); }
0105   void tearDown() {}
0106 
0107   void registerTest();
0108   void getFromTest();
0109   void getFromLambdaTest();
0110   void getfromShareTest();
0111   void getfromUniqueTest();
0112   void getfromOptionalTest();
0113   void decoratorTest();
0114   void dependsOnTest();
0115   void labelTest();
0116   void failMultipleRegistration();
0117   void forceCacheClearTest();
0118   void dataProxyProviderTest();
0119 
0120 private:
0121   edm::propagate_const<std::unique_ptr<edm::ThreadsController>> m_scheduler;
0122 
0123   class Test1Producer : public ESProducer {
0124   public:
0125     Test1Producer() { setWhatProduced(this); }
0126     std::shared_ptr<DummyData> produce(const DummyRecord& /*iRecord*/) {
0127       ++data_.value_;
0128       return std::shared_ptr<DummyData>(&data_, edm::do_nothing_deleter{});
0129     }
0130 
0131   private:
0132     DummyData data_{0};
0133   };
0134 
0135   class LambdaProducer : public ESProducer {
0136   public:
0137     LambdaProducer() {
0138       setWhatProduced([data_ = DummyData()](const DummyRecord& /*iRecord*/) mutable {
0139         ++data_.value_;
0140         return std::shared_ptr<DummyData>(&data_, edm::do_nothing_deleter{});
0141       });
0142     }
0143   };
0144 
0145   class OptionalProducer : public ESProducer {
0146   public:
0147     OptionalProducer() { setWhatProduced(this); }
0148     std::optional<DummyData> produce(const DummyRecord& /*iRecord*/) {
0149       ++data_.value_;
0150       return data_;
0151     }
0152 
0153   private:
0154     DummyData data_{0};
0155   };
0156 
0157   class MultiRegisterProducer : public ESProducer {
0158   public:
0159     MultiRegisterProducer() {
0160       setWhatProduced(this);
0161       setWhatProduced(this);
0162     }
0163     std::shared_ptr<DummyData> produce(const DummyRecord& /*iRecord*/) {
0164       return std::shared_ptr<DummyData>(&data_, edm::do_nothing_deleter{});
0165     }
0166 
0167   private:
0168     DummyData data_{0};
0169   };
0170 
0171   class ShareProducer : public ESProducer {
0172   public:
0173     ShareProducer() { setWhatProduced(this); }
0174     std::shared_ptr<DummyData> produce(const DummyRecord& /*iRecord*/) {
0175       ++ptr_->value_;
0176       return ptr_;
0177     }
0178 
0179   private:
0180     std::shared_ptr<DummyData> ptr_{std::make_shared<DummyData>(0)};
0181   };
0182 
0183   class UniqueProducer : public ESProducer {
0184   public:
0185     UniqueProducer() { setWhatProduced(this); }
0186     std::unique_ptr<DummyData> produce(const DummyRecord&) {
0187       ++data_.value_;
0188       return std::make_unique<DummyData>(data_);
0189     }
0190 
0191   private:
0192     DummyData data_;
0193   };
0194 
0195   class LabelledProducer : public ESProducer {
0196   public:
0197     enum { kFi, kFum };
0198     typedef edm::ESProducts<edm::es::L<DummyData, kFi>, edm::es::L<DummyData, kFum>> ReturnProducts;
0199     LabelledProducer() {
0200       setWhatProduced(this, &LabelledProducer::produceMore, edm::es::label("fi", kFi)("fum", kFum));
0201       setWhatProduced(this, "foo");
0202     }
0203 
0204     std::shared_ptr<DummyData> produce(const DummyRecord& /*iRecord*/) {
0205       ++ptr_->value_;
0206       return ptr_;
0207     }
0208 
0209     ReturnProducts produceMore(const DummyRecord&) {
0210       using edm::es::L;
0211       using namespace edm;
0212       ++fi_->value_;
0213 
0214       L<DummyData, kFum> fum(std::make_shared<DummyData>());
0215       fum->value_ = fi_->value_;
0216 
0217       return edm::es::products(fum, es::l<kFi>(fi_));
0218     }
0219 
0220   private:
0221     std::shared_ptr<DummyData> ptr_{std::make_shared<DummyData>(0)};
0222     std::shared_ptr<DummyData> fi_{std::make_shared<DummyData>(0)};
0223   };
0224 };
0225 
0226 ///registration of the test so that the runner can find it
0227 CPPUNIT_TEST_SUITE_REGISTRATION(testEsproducer);
0228 
0229 void testEsproducer::registerTest() {
0230   Test1Producer testProd;
0231   EventSetupRecordKey dummyRecordKey = EventSetupRecordKey::makeKey<DummyRecord>();
0232   EventSetupRecordKey depRecordKey = EventSetupRecordKey::makeKey<DepRecord>();
0233   testProd.createKeyedProxies(dummyRecordKey, 1);
0234   CPPUNIT_ASSERT(testProd.isUsingRecord(dummyRecordKey));
0235   CPPUNIT_ASSERT(!testProd.isUsingRecord(depRecordKey));
0236   const DataProxyProvider::KeyedProxies& keyedProxies = testProd.keyedProxies(dummyRecordKey);
0237 
0238   CPPUNIT_ASSERT(keyedProxies.size() == 1);
0239 }
0240 
0241 void testEsproducer::getFromTest() {
0242   SynchronousEventSetupsController controller;
0243   edm::ParameterSet pset = createDummyPset();
0244   EventSetupProvider& provider = *controller.makeProvider(pset, &activityRegistry);
0245 
0246   // This manner of adding directly to the EventSetupProvider should work OK in tests
0247   // unless there are multiple EventSetupProviders (the case with SubProcesses).
0248   // Then there would be addition work to do to get things setup properly for the
0249   // functions that check for module sharing between EventSetupProviders.
0250   provider.add(std::make_shared<Test1Producer>());
0251 
0252   auto pFinder = std::make_shared<DummyFinder>();
0253   provider.add(std::shared_ptr<EventSetupRecordIntervalFinder>(pFinder));
0254 
0255   edm::ESParentContext parentC;
0256   for (int iTime = 1; iTime != 6; ++iTime) {
0257     const edm::Timestamp time(iTime);
0258     pFinder->setInterval(edm::ValidityInterval(edm::IOVSyncValue(time), edm::IOVSyncValue(time)));
0259     controller.eventSetupForInstance(edm::IOVSyncValue(time));
0260     DummyDataConsumer<DummyRecord> consumer;
0261     consumer.updateLookup(provider.recordsToProxyIndices());
0262     consumer.prefetch(provider.eventSetupImpl());
0263     const edm::EventSetup eventSetup(provider.eventSetupImpl(),
0264                                      static_cast<unsigned int>(edm::Transition::Event),
0265                                      consumer.esGetTokenIndices(edm::Transition::Event),
0266                                      parentC);
0267     edm::ESHandle<DummyData> pDummy = eventSetup.getHandle(consumer.m_token);
0268     CPPUNIT_ASSERT(0 != pDummy.product());
0269     CPPUNIT_ASSERT(iTime == pDummy->value_);
0270   }
0271 }
0272 
0273 void testEsproducer::getFromLambdaTest() {
0274   SynchronousEventSetupsController controller;
0275   edm::ParameterSet pset = createDummyPset();
0276   EventSetupProvider& provider = *controller.makeProvider(pset, &activityRegistry);
0277 
0278   provider.add(std::make_shared<LambdaProducer>());
0279 
0280   auto pFinder = std::make_shared<DummyFinder>();
0281   provider.add(std::shared_ptr<EventSetupRecordIntervalFinder>(pFinder));
0282 
0283   edm::ESParentContext parentC;
0284   for (int iTime = 1; iTime != 6; ++iTime) {
0285     const edm::Timestamp time(iTime);
0286     pFinder->setInterval(edm::ValidityInterval(edm::IOVSyncValue(time), edm::IOVSyncValue(time)));
0287     controller.eventSetupForInstance(edm::IOVSyncValue(time));
0288     DummyDataConsumer<DummyRecord> consumer;
0289     consumer.updateLookup(provider.recordsToProxyIndices());
0290     consumer.prefetch(provider.eventSetupImpl());
0291     const edm::EventSetup eventSetup(provider.eventSetupImpl(),
0292                                      static_cast<unsigned int>(edm::Transition::Event),
0293                                      consumer.esGetTokenIndices(edm::Transition::Event),
0294                                      parentC);
0295     edm::ESHandle<DummyData> pDummy = eventSetup.getHandle(consumer.m_token);
0296     CPPUNIT_ASSERT(0 != pDummy.product());
0297     CPPUNIT_ASSERT(iTime == pDummy->value_);
0298   }
0299 }
0300 
0301 void testEsproducer::getfromShareTest() {
0302   SynchronousEventSetupsController controller;
0303   edm::ParameterSet pset = createDummyPset();
0304   EventSetupProvider& provider = *controller.makeProvider(pset, &activityRegistry);
0305 
0306   std::shared_ptr<DataProxyProvider> pProxyProv = std::make_shared<ShareProducer>();
0307   provider.add(pProxyProv);
0308 
0309   auto pFinder = std::make_shared<DummyFinder>();
0310   provider.add(std::shared_ptr<EventSetupRecordIntervalFinder>(pFinder));
0311 
0312   edm::ESParentContext parentC;
0313   for (int iTime = 1; iTime != 6; ++iTime) {
0314     const edm::Timestamp time(iTime);
0315     pFinder->setInterval(edm::ValidityInterval(edm::IOVSyncValue(time), edm::IOVSyncValue(time)));
0316     controller.eventSetupForInstance(edm::IOVSyncValue(time));
0317     DummyDataConsumer<DummyRecord> consumer;
0318     consumer.updateLookup(provider.recordsToProxyIndices());
0319     consumer.prefetch(provider.eventSetupImpl());
0320     const edm::EventSetup eventSetup(provider.eventSetupImpl(),
0321                                      static_cast<unsigned int>(edm::Transition::Event),
0322                                      consumer.esGetTokenIndices(edm::Transition::Event),
0323                                      parentC);
0324     edm::ESHandle<DummyData> pDummy = eventSetup.getHandle(consumer.m_token);
0325     CPPUNIT_ASSERT(0 != pDummy.product());
0326     CPPUNIT_ASSERT(iTime == pDummy->value_);
0327   }
0328 }
0329 
0330 void testEsproducer::getfromUniqueTest() {
0331   SynchronousEventSetupsController controller;
0332   edm::ParameterSet pset = createDummyPset();
0333   EventSetupProvider& provider = *controller.makeProvider(pset, &activityRegistry);
0334 
0335   std::shared_ptr<DataProxyProvider> pProxyProv = std::make_shared<UniqueProducer>();
0336   provider.add(pProxyProv);
0337 
0338   auto pFinder = std::make_shared<DummyFinder>();
0339   provider.add(std::shared_ptr<EventSetupRecordIntervalFinder>(pFinder));
0340 
0341   edm::ESParentContext parentC;
0342   for (int iTime = 1; iTime != 6; ++iTime) {
0343     const edm::Timestamp time(iTime);
0344     pFinder->setInterval(edm::ValidityInterval(edm::IOVSyncValue(time), edm::IOVSyncValue(time)));
0345     controller.eventSetupForInstance(edm::IOVSyncValue(time));
0346     DummyDataConsumer<DummyRecord> consumer;
0347     consumer.updateLookup(provider.recordsToProxyIndices());
0348     consumer.prefetch(provider.eventSetupImpl());
0349     const edm::EventSetup eventSetup(provider.eventSetupImpl(),
0350                                      static_cast<unsigned int>(edm::Transition::Event),
0351                                      consumer.esGetTokenIndices(edm::Transition::Event),
0352                                      parentC);
0353     edm::ESHandle<DummyData> pDummy = eventSetup.getHandle(consumer.m_token);
0354     CPPUNIT_ASSERT(0 != pDummy.product());
0355     CPPUNIT_ASSERT(iTime == pDummy->value_);
0356   }
0357 }
0358 
0359 void testEsproducer::getfromOptionalTest() {
0360   SynchronousEventSetupsController controller;
0361   edm::ParameterSet pset = createDummyPset();
0362   EventSetupProvider& provider = *controller.makeProvider(pset, &activityRegistry);
0363 
0364   provider.add(std::make_shared<OptionalProducer>());
0365 
0366   auto pFinder = std::make_shared<DummyFinder>();
0367   provider.add(std::shared_ptr<EventSetupRecordIntervalFinder>(pFinder));
0368 
0369   edm::ESParentContext parentC;
0370   for (int iTime = 1; iTime != 6; ++iTime) {
0371     const edm::Timestamp time(iTime);
0372     pFinder->setInterval(edm::ValidityInterval(edm::IOVSyncValue(time), edm::IOVSyncValue(time)));
0373     controller.eventSetupForInstance(edm::IOVSyncValue(time));
0374     DummyDataConsumer<DummyRecord> consumer;
0375     consumer.updateLookup(provider.recordsToProxyIndices());
0376     consumer.prefetch(provider.eventSetupImpl());
0377     const edm::EventSetup eventSetup(provider.eventSetupImpl(),
0378                                      static_cast<unsigned int>(edm::Transition::Event),
0379                                      consumer.esGetTokenIndices(edm::Transition::Event),
0380                                      parentC);
0381     edm::ESHandle<DummyData> pDummy = eventSetup.getHandle(consumer.m_token);
0382     CPPUNIT_ASSERT(0 != pDummy.product());
0383     CPPUNIT_ASSERT(iTime == pDummy->value_);
0384   }
0385 }
0386 
0387 void testEsproducer::labelTest() {
0388   try {
0389     SynchronousEventSetupsController controller;
0390     edm::ParameterSet pset = createDummyPset();
0391     EventSetupProvider& provider = *controller.makeProvider(pset, &activityRegistry);
0392 
0393     std::shared_ptr<DataProxyProvider> pProxyProv = std::make_shared<LabelledProducer>();
0394     provider.add(pProxyProv);
0395 
0396     auto pFinder = std::make_shared<DummyFinder>();
0397     provider.add(std::shared_ptr<EventSetupRecordIntervalFinder>(pFinder));
0398 
0399     edm::ESParentContext parentC;
0400     for (int iTime = 1; iTime != 6; ++iTime) {
0401       const edm::Timestamp time(iTime);
0402       pFinder->setInterval(edm::ValidityInterval(edm::IOVSyncValue(time), edm::IOVSyncValue(time)));
0403       controller.eventSetupForInstance(edm::IOVSyncValue(time));
0404       DummyDataConsumer2 consumer(edm::ESInputTag("", "foo"), edm::ESInputTag("", "fi"), edm::ESInputTag("", "fum"));
0405       consumer.updateLookup(provider.recordsToProxyIndices());
0406       consumer.prefetch(provider.eventSetupImpl());
0407       const edm::EventSetup eventSetup(provider.eventSetupImpl(),
0408                                        static_cast<unsigned int>(edm::Transition::Event),
0409                                        consumer.esGetTokenIndices(edm::Transition::Event),
0410                                        parentC);
0411 
0412       edm::ESHandle<DummyData> pDummy = eventSetup.getHandle(consumer.m_token1);
0413       CPPUNIT_ASSERT(0 != pDummy.product());
0414       CPPUNIT_ASSERT(iTime == pDummy->value_);
0415 
0416       pDummy = eventSetup.getHandle(consumer.m_token2);
0417       CPPUNIT_ASSERT(0 != pDummy.product());
0418       CPPUNIT_ASSERT(iTime == pDummy->value_);
0419 
0420       pDummy = eventSetup.getHandle(consumer.m_token3);
0421       CPPUNIT_ASSERT(0 != pDummy.product());
0422       CPPUNIT_ASSERT(iTime == pDummy->value_);
0423     }
0424   } catch (const cms::Exception& iException) {
0425     std::cout << "caught exception " << iException.explainSelf() << std::endl;
0426     throw;
0427   }
0428 }
0429 
0430 struct TestDecorator {
0431   static int s_pre;
0432   static int s_post;
0433 
0434   void pre(const DummyRecord&) { ++s_pre; }
0435 
0436   void post(const DummyRecord&) { ++s_post; }
0437 };
0438 
0439 int TestDecorator::s_pre = 0;
0440 int TestDecorator::s_post = 0;
0441 
0442 class DecoratorProducer : public ESProducer {
0443 public:
0444   DecoratorProducer() { setWhatProduced(this, TestDecorator{}); }
0445   std::shared_ptr<DummyData> produce(const DummyRecord& /*iRecord*/) {
0446     ++ptr_->value_;
0447     return ptr_;
0448   }
0449 
0450 private:
0451   std::shared_ptr<DummyData> ptr_{std::make_shared<DummyData>(0)};
0452 };
0453 
0454 void testEsproducer::decoratorTest() {
0455   SynchronousEventSetupsController controller;
0456   edm::ParameterSet pset = createDummyPset();
0457   EventSetupProvider& provider = *controller.makeProvider(pset, &activityRegistry);
0458 
0459   provider.add(std::make_shared<DecoratorProducer>());
0460 
0461   auto pFinder = std::make_shared<DummyFinder>();
0462   provider.add(std::shared_ptr<EventSetupRecordIntervalFinder>(pFinder));
0463 
0464   edm::ESParentContext parentC;
0465   for (int iTime = 1; iTime != 6; ++iTime) {
0466     const edm::Timestamp time(iTime);
0467     pFinder->setInterval(edm::ValidityInterval(edm::IOVSyncValue(time), edm::IOVSyncValue(time)));
0468     controller.eventSetupForInstance(edm::IOVSyncValue(time));
0469     DummyDataConsumer<DummyRecord> consumer;
0470     consumer.updateLookup(provider.recordsToProxyIndices());
0471 
0472     CPPUNIT_ASSERT(iTime - 1 == TestDecorator::s_pre);
0473     CPPUNIT_ASSERT(iTime - 1 == TestDecorator::s_post);
0474     consumer.prefetch(provider.eventSetupImpl());
0475     const edm::EventSetup eventSetup(provider.eventSetupImpl(),
0476                                      static_cast<unsigned int>(edm::Transition::Event),
0477                                      consumer.esGetTokenIndices(edm::Transition::Event),
0478                                      parentC);
0479     edm::ESHandle<DummyData> pDummy = eventSetup.getHandle(consumer.m_token);
0480     CPPUNIT_ASSERT(0 != pDummy.product());
0481     CPPUNIT_ASSERT(iTime == TestDecorator::s_pre);
0482     CPPUNIT_ASSERT(iTime == TestDecorator::s_post);
0483     CPPUNIT_ASSERT(iTime == pDummy->value_);
0484   }
0485 }
0486 
0487 class DepProducer : public ESProducer {
0488 public:
0489   DepProducer() {
0490     setWhatProduced(this,
0491                     dependsOn(&DepProducer::callWhenDummyChanges,
0492                               &DepProducer::callWhenDummyChanges2,
0493                               &DepProducer::callWhenDummyChanges3));
0494   }
0495   std::shared_ptr<DummyData> produce(const DepRecord& /*iRecord*/) { return ptr_; }
0496   void callWhenDummyChanges(const DummyRecord&) { ++ptr_->value_; }
0497   void callWhenDummyChanges2(const DummyRecord&) { ++ptr_->value_; }
0498   void callWhenDummyChanges3(const DummyRecord&) { ++ptr_->value_; }
0499 
0500 private:
0501   std::shared_ptr<DummyData> ptr_{std::make_shared<DummyData>(0)};
0502 };
0503 
0504 void testEsproducer::dependsOnTest() {
0505   SynchronousEventSetupsController controller;
0506   edm::ParameterSet pset = createDummyPset();
0507   EventSetupProvider& provider = *controller.makeProvider(pset, &activityRegistry);
0508 
0509   provider.add(std::make_shared<DepProducer>());
0510 
0511   auto pFinder = std::make_shared<DummyFinder>();
0512   provider.add(std::shared_ptr<EventSetupRecordIntervalFinder>(pFinder));
0513 
0514   edm::ESParentContext parentC;
0515   for (int iTime = 1; iTime != 6; ++iTime) {
0516     const edm::Timestamp time(iTime);
0517     pFinder->setInterval(edm::ValidityInterval(edm::IOVSyncValue(time), edm::IOVSyncValue(time)));
0518     controller.eventSetupForInstance(edm::IOVSyncValue(time));
0519     DummyDataConsumer<DepRecord> consumer;
0520     consumer.updateLookup(provider.recordsToProxyIndices());
0521     consumer.prefetch(provider.eventSetupImpl());
0522     const edm::EventSetup eventSetup(provider.eventSetupImpl(),
0523                                      static_cast<unsigned int>(edm::Transition::Event),
0524                                      consumer.esGetTokenIndices(edm::Transition::Event),
0525                                      parentC);
0526     edm::ESHandle<DummyData> pDummy = eventSetup.getHandle(consumer.m_token);
0527     CPPUNIT_ASSERT(0 != pDummy.product());
0528     CPPUNIT_ASSERT(3 * iTime == pDummy->value_);
0529   }
0530 }
0531 
0532 void testEsproducer::failMultipleRegistration() { MultiRegisterProducer dummy; }
0533 
0534 void testEsproducer::forceCacheClearTest() {
0535   SynchronousEventSetupsController controller;
0536   edm::ParameterSet pset = createDummyPset();
0537   EventSetupProvider& provider = *controller.makeProvider(pset, &activityRegistry);
0538 
0539   provider.add(std::make_shared<Test1Producer>());
0540 
0541   auto pFinder = std::make_shared<DummyFinder>();
0542   provider.add(std::shared_ptr<EventSetupRecordIntervalFinder>(pFinder));
0543 
0544   const edm::Timestamp time(1);
0545   pFinder->setInterval(edm::ValidityInterval(edm::IOVSyncValue(time), edm::IOVSyncValue(time)));
0546   controller.eventSetupForInstance(edm::IOVSyncValue(time));
0547   {
0548     DummyDataConsumer<DummyRecord> consumer;
0549     consumer.updateLookup(provider.recordsToProxyIndices());
0550     consumer.prefetch(provider.eventSetupImpl());
0551     edm::ESParentContext parentC;
0552     const edm::EventSetup eventSetup(provider.eventSetupImpl(),
0553                                      static_cast<unsigned int>(edm::Transition::Event),
0554                                      consumer.esGetTokenIndices(edm::Transition::Event),
0555                                      parentC);
0556     edm::ESHandle<DummyData> pDummy = eventSetup.getHandle(consumer.m_token);
0557     CPPUNIT_ASSERT(0 != pDummy.product());
0558     CPPUNIT_ASSERT(1 == pDummy->value_);
0559   }
0560   provider.forceCacheClear();
0561   controller.eventSetupForInstance(edm::IOVSyncValue(time));
0562   {
0563     DummyDataConsumer<DummyRecord> consumer;
0564     consumer.updateLookup(provider.recordsToProxyIndices());
0565     consumer.prefetch(provider.eventSetupImpl());
0566     edm::ESParentContext parentC;
0567     const edm::EventSetup eventSetup2(provider.eventSetupImpl(),
0568                                       static_cast<unsigned int>(edm::Transition::Event),
0569                                       consumer.esGetTokenIndices(edm::Transition::Event),
0570                                       parentC);
0571     edm::ESHandle<DummyData> pDummy = eventSetup2.getHandle(consumer.m_token);
0572     CPPUNIT_ASSERT(0 != pDummy.product());
0573     CPPUNIT_ASSERT(2 == pDummy->value_);
0574   }
0575 }
0576 
0577 namespace {
0578   class TestDataProxyProvider : public DataProxyProvider {
0579   public:
0580     TestDataProxyProvider();
0581 
0582     class TestProxy : public DataProxy {
0583     public:
0584       void prefetchAsyncImpl(edm::WaitingTaskHolder,
0585                              EventSetupRecordImpl const&,
0586                              DataKey const&,
0587                              edm::EventSetupImpl const*,
0588                              edm::ServiceToken const&,
0589                              edm::ESParentContext const&) override {}
0590       void invalidateCache() override {}
0591       void const* getAfterPrefetchImpl() const override { return nullptr; }
0592     };
0593 
0594     DataKey dataKeyDummy_0_;
0595     DataKey dataKeyDummy2_0_;
0596     DataKey dataKeyDummy2_1_;
0597     DataKey dataKeyDummy2_2_;
0598     DataKey dataKeyDep_0_;
0599     DataKey dataKeyDep_1_;
0600     std::shared_ptr<TestProxy> proxyDummy_0_0_;
0601     std::shared_ptr<TestProxy> proxyDummy_0_1_;
0602     std::shared_ptr<TestProxy> proxyDummy_0_2_;
0603     std::shared_ptr<TestProxy> proxyDummy2_0_0_;
0604     std::shared_ptr<TestProxy> proxyDummy2_1_0_;
0605     std::shared_ptr<TestProxy> proxyDummy2_2_0_;
0606     std::shared_ptr<TestProxy> proxyDep_0_0_;
0607     std::shared_ptr<TestProxy> proxyDep_0_1_;
0608     std::shared_ptr<TestProxy> proxyDep_1_0_;
0609     std::shared_ptr<TestProxy> proxyDep_1_1_;
0610 
0611   private:
0612     KeyedProxiesVector registerProxies(const EventSetupRecordKey& recordKey, unsigned int iovIndex) override {
0613       KeyedProxiesVector keyedProxiesVector;
0614       if (recordKey == EventSetupRecordKey::makeKey<DummyRecord>()) {
0615         if (iovIndex == 0) {
0616           keyedProxiesVector.emplace_back(dataKeyDummy_0_, proxyDummy_0_0_);
0617         } else if (iovIndex == 1) {
0618           keyedProxiesVector.emplace_back(dataKeyDummy_0_, proxyDummy_0_1_);
0619         } else if (iovIndex == 2) {
0620           keyedProxiesVector.emplace_back(dataKeyDummy_0_, proxyDummy_0_2_);
0621         }
0622       } else if (recordKey == EventSetupRecordKey::makeKey<Dummy2Record>()) {
0623         keyedProxiesVector.emplace_back(dataKeyDummy2_0_, proxyDummy2_0_0_);
0624         keyedProxiesVector.emplace_back(dataKeyDummy2_1_, proxyDummy2_1_0_);
0625         keyedProxiesVector.emplace_back(dataKeyDummy2_2_, proxyDummy2_2_0_);
0626       } else if (recordKey == EventSetupRecordKey::makeKey<DepRecord>()) {
0627         if (iovIndex == 0) {
0628           keyedProxiesVector.emplace_back(dataKeyDep_0_, proxyDep_0_0_);
0629           keyedProxiesVector.emplace_back(dataKeyDep_1_, proxyDep_1_0_);
0630         } else if (iovIndex == 1) {
0631           keyedProxiesVector.emplace_back(dataKeyDep_0_, proxyDep_0_1_);
0632           keyedProxiesVector.emplace_back(dataKeyDep_1_, proxyDep_1_1_);
0633         }
0634       }
0635       return keyedProxiesVector;
0636     }
0637   };
0638 
0639   TestDataProxyProvider::TestDataProxyProvider()
0640       : dataKeyDummy_0_(DataKey::makeTypeTag<DummyData>(), "Dummy_0"),
0641         dataKeyDummy2_0_(DataKey::makeTypeTag<DummyData>(), "Dummy2_0"),
0642         dataKeyDummy2_1_(DataKey::makeTypeTag<DummyData>(), "Dummy2_1"),
0643         dataKeyDummy2_2_(DataKey::makeTypeTag<DummyData>(), "Dummy2_2"),
0644         dataKeyDep_0_(DataKey::makeTypeTag<DummyData>(), "Dep_0"),
0645         dataKeyDep_1_(DataKey::makeTypeTag<DummyData>(), "Dep_1"),
0646         proxyDummy_0_0_(std::make_shared<TestProxy>()),
0647         proxyDummy_0_1_(std::make_shared<TestProxy>()),
0648         proxyDummy_0_2_(std::make_shared<TestProxy>()),
0649         proxyDummy2_0_0_(std::make_shared<TestProxy>()),
0650         proxyDummy2_1_0_(std::make_shared<TestProxy>()),
0651         proxyDummy2_2_0_(std::make_shared<TestProxy>()),
0652         proxyDep_0_0_(std::make_shared<TestProxy>()),
0653         proxyDep_0_1_(std::make_shared<TestProxy>()),
0654         proxyDep_1_0_(std::make_shared<TestProxy>()),
0655         proxyDep_1_1_(std::make_shared<TestProxy>()) {
0656     usingRecord<DummyRecord>();
0657     usingRecord<Dummy2Record>();
0658     usingRecord<DepRecord>();
0659     usingRecord<DepOn2Record>();
0660     usingRecord<DummyRecord>();
0661     usingRecord<Dummy2Record>();
0662     usingRecord<DepRecord>();
0663     usingRecord<DepOn2Record>();
0664   }
0665 }  // namespace
0666 
0667 void testEsproducer::dataProxyProviderTest() {
0668   TestDataProxyProvider dataProxyProvider;
0669   EventSetupRecordKey dummyRecordKey = EventSetupRecordKey::makeKey<DummyRecord>();
0670   EventSetupRecordKey dummy2RecordKey = EventSetupRecordKey::makeKey<Dummy2Record>();
0671   EventSetupRecordKey depRecordKey = EventSetupRecordKey::makeKey<DepRecord>();
0672   EventSetupRecordKey depOn2RecordKey = EventSetupRecordKey::makeKey<DepOn2Record>();
0673   unsigned int nConcurrentIOVs = 3;
0674   dataProxyProvider.createKeyedProxies(dummyRecordKey, nConcurrentIOVs);
0675   CPPUNIT_ASSERT(dataProxyProvider.isUsingRecord(dummyRecordKey));
0676   CPPUNIT_ASSERT(dataProxyProvider.isUsingRecord(dummy2RecordKey));
0677   CPPUNIT_ASSERT(dataProxyProvider.isUsingRecord(depRecordKey));
0678   CPPUNIT_ASSERT(dataProxyProvider.isUsingRecord(depOn2RecordKey));
0679 
0680   std::set<EventSetupRecordKey> expectedKeys;
0681   expectedKeys.insert(dummyRecordKey);
0682   expectedKeys.insert(dummy2RecordKey);
0683   expectedKeys.insert(depRecordKey);
0684   expectedKeys.insert(depOn2RecordKey);
0685 
0686   auto keys = dataProxyProvider.usingRecords();
0687   CPPUNIT_ASSERT(keys == expectedKeys);
0688 
0689   keys.clear();
0690   dataProxyProvider.fillRecordsNotAllowingConcurrentIOVs(keys);
0691   expectedKeys.clear();
0692   expectedKeys.insert(dummy2RecordKey);
0693   CPPUNIT_ASSERT(keys == expectedKeys);
0694 
0695   nConcurrentIOVs = 1;
0696   dataProxyProvider.createKeyedProxies(dummy2RecordKey, nConcurrentIOVs);
0697   nConcurrentIOVs = 2;
0698   dataProxyProvider.createKeyedProxies(depRecordKey, nConcurrentIOVs);
0699   nConcurrentIOVs = 4;
0700   dataProxyProvider.createKeyedProxies(depOn2RecordKey, nConcurrentIOVs);
0701 
0702   DataProxyProvider::KeyedProxies& keyedProxies0 = dataProxyProvider.keyedProxies(dummyRecordKey, 0);
0703   CPPUNIT_ASSERT(keyedProxies0.recordKey() == dummyRecordKey);
0704   CPPUNIT_ASSERT(keyedProxies0.size() == 1);
0705   {
0706     auto it = keyedProxies0.begin();
0707     auto itEnd = keyedProxies0.end();
0708     CPPUNIT_ASSERT(it.dataKey() == dataProxyProvider.dataKeyDummy_0_);
0709     CPPUNIT_ASSERT(it.dataProxy() == dataProxyProvider.proxyDummy_0_0_.get());
0710     CPPUNIT_ASSERT(it != itEnd);
0711     ++it;
0712     CPPUNIT_ASSERT(!(it != itEnd));
0713   }
0714   DataProxyProvider::KeyedProxies& keyedProxies1 = dataProxyProvider.keyedProxies(dummyRecordKey, 1);
0715   CPPUNIT_ASSERT(keyedProxies1.recordKey() == dummyRecordKey);
0716   CPPUNIT_ASSERT(keyedProxies1.size() == 1);
0717   {
0718     auto it = keyedProxies1.begin();
0719     auto itEnd = keyedProxies1.end();
0720     CPPUNIT_ASSERT(it.dataKey() == dataProxyProvider.dataKeyDummy_0_);
0721     CPPUNIT_ASSERT(it.dataProxy() == dataProxyProvider.proxyDummy_0_1_.get());
0722     CPPUNIT_ASSERT(it != itEnd);
0723     ++it;
0724     CPPUNIT_ASSERT(!(it != itEnd));
0725   }
0726   DataProxyProvider::KeyedProxies& keyedProxies2 = dataProxyProvider.keyedProxies(dummyRecordKey, 2);
0727   CPPUNIT_ASSERT(keyedProxies2.recordKey() == dummyRecordKey);
0728   CPPUNIT_ASSERT(keyedProxies2.size() == 1);
0729   {
0730     auto it = keyedProxies2.begin();
0731     auto itEnd = keyedProxies2.end();
0732     CPPUNIT_ASSERT(it.dataKey() == dataProxyProvider.dataKeyDummy_0_);
0733     CPPUNIT_ASSERT(it.dataProxy() == dataProxyProvider.proxyDummy_0_2_.get());
0734     CPPUNIT_ASSERT(it != itEnd);
0735     ++it;
0736     CPPUNIT_ASSERT(!(it != itEnd));
0737   }
0738   DataProxyProvider::KeyedProxies& keyedProxies3 = dataProxyProvider.keyedProxies(dummy2RecordKey, 0);
0739   CPPUNIT_ASSERT(keyedProxies3.recordKey() == dummy2RecordKey);
0740   CPPUNIT_ASSERT(keyedProxies3.size() == 3);
0741   {
0742     auto it = keyedProxies3.begin();
0743     auto itEnd = keyedProxies3.end();
0744     CPPUNIT_ASSERT(it.dataKey() == dataProxyProvider.dataKeyDummy2_0_);
0745     CPPUNIT_ASSERT(it.dataProxy() == dataProxyProvider.proxyDummy2_0_0_.get());
0746     CPPUNIT_ASSERT(it != itEnd);
0747     ++it;
0748     CPPUNIT_ASSERT(it.dataKey() == dataProxyProvider.dataKeyDummy2_1_);
0749     CPPUNIT_ASSERT(it.dataProxy() == dataProxyProvider.proxyDummy2_1_0_.get());
0750     CPPUNIT_ASSERT(it != itEnd);
0751     ++it;
0752     CPPUNIT_ASSERT(it.dataKey() == dataProxyProvider.dataKeyDummy2_2_);
0753     CPPUNIT_ASSERT(it.dataProxy() == dataProxyProvider.proxyDummy2_2_0_.get());
0754     CPPUNIT_ASSERT(it != itEnd);
0755     ++it;
0756     CPPUNIT_ASSERT(!(it != itEnd));
0757   }
0758   DataProxyProvider::KeyedProxies& keyedProxies4 = dataProxyProvider.keyedProxies(depRecordKey, 0);
0759   CPPUNIT_ASSERT(keyedProxies4.recordKey() == depRecordKey);
0760   CPPUNIT_ASSERT(keyedProxies4.size() == 2);
0761   {
0762     auto it = keyedProxies4.begin();
0763     auto itEnd = keyedProxies4.end();
0764     CPPUNIT_ASSERT(it.dataKey() == dataProxyProvider.dataKeyDep_0_);
0765     CPPUNIT_ASSERT(it.dataProxy() == dataProxyProvider.proxyDep_0_0_.get());
0766     CPPUNIT_ASSERT(it != itEnd);
0767     ++it;
0768     CPPUNIT_ASSERT(it.dataKey() == dataProxyProvider.dataKeyDep_1_);
0769     CPPUNIT_ASSERT(it.dataProxy() == dataProxyProvider.proxyDep_1_0_.get());
0770     CPPUNIT_ASSERT(it != itEnd);
0771     ++it;
0772     CPPUNIT_ASSERT(!(it != itEnd));
0773   }
0774   DataProxyProvider::KeyedProxies& keyedProxies5 = dataProxyProvider.keyedProxies(depRecordKey, 1);
0775   CPPUNIT_ASSERT(keyedProxies5.recordKey() == depRecordKey);
0776   CPPUNIT_ASSERT(keyedProxies5.size() == 2);
0777   {
0778     auto it = keyedProxies5.begin();
0779     auto itEnd = keyedProxies5.end();
0780     CPPUNIT_ASSERT(it.dataKey() == dataProxyProvider.dataKeyDep_0_);
0781     CPPUNIT_ASSERT(it.dataProxy() == dataProxyProvider.proxyDep_0_1_.get());
0782     CPPUNIT_ASSERT(it != itEnd);
0783     ++it;
0784     CPPUNIT_ASSERT(it.dataKey() == dataProxyProvider.dataKeyDep_1_);
0785     CPPUNIT_ASSERT(it.dataProxy() == dataProxyProvider.proxyDep_1_1_.get());
0786     CPPUNIT_ASSERT(it != itEnd);
0787     ++it;
0788     CPPUNIT_ASSERT(!(it != itEnd));
0789   }
0790   DataProxyProvider::KeyedProxies& keyedProxies6 = dataProxyProvider.keyedProxies(depOn2RecordKey, 0);
0791   CPPUNIT_ASSERT(keyedProxies6.recordKey() == depOn2RecordKey);
0792   CPPUNIT_ASSERT(keyedProxies6.size() == 0);
0793   {
0794     auto it = keyedProxies6.begin();
0795     auto itEnd = keyedProxies6.end();
0796     CPPUNIT_ASSERT(!(it != itEnd));
0797   }
0798   DataProxyProvider::KeyedProxies& keyedProxies7 = dataProxyProvider.keyedProxies(depOn2RecordKey, 1);
0799   CPPUNIT_ASSERT(keyedProxies7.recordKey() == depOn2RecordKey);
0800   CPPUNIT_ASSERT(keyedProxies7.size() == 0);
0801   {
0802     auto it = keyedProxies7.begin();
0803     auto itEnd = keyedProxies7.end();
0804     CPPUNIT_ASSERT(!(it != itEnd));
0805   }
0806   DataProxyProvider::KeyedProxies& keyedProxies8 = dataProxyProvider.keyedProxies(depOn2RecordKey, 2);
0807   CPPUNIT_ASSERT(keyedProxies8.recordKey() == depOn2RecordKey);
0808   CPPUNIT_ASSERT(keyedProxies8.size() == 0);
0809   {
0810     auto it = keyedProxies8.begin();
0811     auto itEnd = keyedProxies8.end();
0812     CPPUNIT_ASSERT(!(it != itEnd));
0813   }
0814   DataProxyProvider::KeyedProxies& keyedProxies9 = dataProxyProvider.keyedProxies(depOn2RecordKey, 3);
0815   CPPUNIT_ASSERT(keyedProxies9.recordKey() == depOn2RecordKey);
0816   CPPUNIT_ASSERT(keyedProxies9.size() == 0);
0817   {
0818     auto it = keyedProxies9.begin();
0819     auto itEnd = keyedProxies9.end();
0820     CPPUNIT_ASSERT(!(it != itEnd));
0821   }
0822 
0823   CPPUNIT_ASSERT(keyedProxies4.contains(dataProxyProvider.dataKeyDep_0_));
0824   CPPUNIT_ASSERT(keyedProxies4.contains(dataProxyProvider.dataKeyDep_1_));
0825   CPPUNIT_ASSERT(!keyedProxies4.contains(dataProxyProvider.dataKeyDummy_0_));
0826 
0827   DataProxyProvider::KeyedProxies keyedProxies10(nullptr, 0);
0828   CPPUNIT_ASSERT(keyedProxies10.unInitialized());
0829   CPPUNIT_ASSERT(!keyedProxies0.unInitialized());
0830 }