Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-12-24 02:18:47

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