Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-04-30 22:24:11

0001 /*
0002  *  eventsetuprecord_t.cc
0003  *  EDMProto
0004  *
0005  *  Created by Chris Jones on 3/29/05.
0006  *  Changed by Viji on 06/07/2005
0007  */
0008 
0009 #include "cppunit/extensions/HelperMacros.h"
0010 
0011 #include "FWCore/Framework/interface/ESConsumesCollector.h"
0012 #include "FWCore/Framework/interface/ESRecordsToProductResolverIndices.h"
0013 #include "FWCore/Framework/interface/EventSetupRecord.h"
0014 #include "FWCore/Framework/interface/EventSetupRecordImpl.h"
0015 #include "FWCore/Framework/interface/EventSetupRecordImplementation.h"
0016 #include "FWCore/Framework/interface/EventSetupRecordKey.h"
0017 #include "FWCore/Framework/interface/EventSetupRecordProvider.h"
0018 #include "FWCore/Framework/interface/EventSetupImpl.h"
0019 #include "FWCore/Framework/interface/NoProductResolverException.h"
0020 #include "FWCore/Framework/interface/RecordDependencyRegister.h"
0021 #include "FWCore/Framework/interface/MakeDataException.h"
0022 #include "FWCore/Framework/interface/EDConsumerBase.h"
0023 
0024 #include "FWCore/Framework/interface/HCTypeTag.h"
0025 
0026 #include "FWCore/Framework/interface/ESProductResolverTemplate.h"
0027 #include "FWCore/Framework/interface/ESProductResolverProvider.h"
0028 #include "FWCore/Framework/interface/ESModuleProducesInfo.h"
0029 
0030 #include "FWCore/Framework/interface/ESHandle.h"
0031 #include "FWCore/Framework/interface/ESValidHandle.h"
0032 #include "FWCore/Framework/interface/ESTransientHandle.h"
0033 
0034 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0035 #include "FWCore/ServiceRegistry/interface/ActivityRegistry.h"
0036 #include "FWCore/ServiceRegistry/interface/ESParentContext.h"
0037 #include "FWCore/Concurrency/interface/FinalWaitingTask.h"
0038 #include "FWCore/Utilities/interface/ESIndices.h"
0039 
0040 #include <memory>
0041 #include "oneapi/tbb/task_arena.h"
0042 
0043 namespace {
0044   edm::ActivityRegistry activityRegistry;
0045 }
0046 
0047 using namespace edm;
0048 using namespace edm::eventsetup;
0049 namespace eventsetuprecord_t {
0050   class DummyRecord : public edm::eventsetup::EventSetupRecordImplementation<DummyRecord> {
0051   public:
0052   };
0053 }  // namespace eventsetuprecord_t
0054 //HCMethods<T, T, EventSetup, EventSetupRecordKey, EventSetupRecordKey::IdTag >
0055 HCTYPETAG_HELPER_METHODS(eventsetuprecord_t::DummyRecord)
0056 
0057 //create an instance of the factory
0058 static eventsetup::RecordDependencyRegister<eventsetuprecord_t::DummyRecord> const s_factory;
0059 
0060 namespace eventsetuprecord_t {
0061   class Dummy {};
0062 }  // namespace eventsetuprecord_t
0063 using eventsetuprecord_t::Dummy;
0064 using eventsetuprecord_t::DummyRecord;
0065 typedef edm::eventsetup::MakeDataException ExceptionType;
0066 
0067 class testEventsetupRecord : public CppUnit::TestFixture {
0068   CPPUNIT_TEST_SUITE(testEventsetupRecord);
0069 
0070   CPPUNIT_TEST(resolverTest);
0071   CPPUNIT_TEST(getHandleTest);
0072   CPPUNIT_TEST(getWithTokenTest);
0073   CPPUNIT_TEST(doGetTest);
0074   CPPUNIT_TEST(resolverResetTest);
0075   CPPUNIT_TEST(introspectionTest);
0076   CPPUNIT_TEST(transientTest);
0077 
0078   CPPUNIT_TEST_EXCEPTION(getNodataExpTest, NoProductResolverException);
0079   CPPUNIT_TEST_EXCEPTION(doGetExepTest, ExceptionType);
0080 
0081   CPPUNIT_TEST_SUITE_END();
0082 
0083 public:
0084   testEventsetupRecord();
0085   void setUp();
0086   void tearDown() {}
0087 
0088   void resolverTest();
0089   void getHandleTest();
0090   void getWithTokenTest();
0091   void doGetTest();
0092   void resolverResetTest();
0093   void introspectionTest();
0094   void transientTest();
0095 
0096   void getNodataExpTest();
0097   void doGetExepTest();
0098 
0099   EventSetupRecordKey dummyRecordKey_;
0100   oneapi::tbb::task_arena taskArena_;
0101   EventSetupImpl eventSetupImpl_;
0102 };
0103 
0104 ///registration of the test so that the runner can find it
0105 CPPUNIT_TEST_SUITE_REGISTRATION(testEventsetupRecord);
0106 
0107 HCTYPETAG_HELPER_METHODS(Dummy)
0108 
0109 class FailingDummyResolver : public eventsetup::ESProductResolverTemplate<DummyRecord, Dummy> {
0110 protected:
0111   const value_type* make(const record_type&, const DataKey&) final { return nullptr; }
0112   void const* getAfterPrefetchImpl() const final { return nullptr; }
0113 };
0114 
0115 class WorkingDummyResolver : public eventsetup::ESProductResolverTemplate<DummyRecord, Dummy> {
0116 public:
0117   WorkingDummyResolver(const Dummy* iDummy)
0118       : data_(iDummy), invalidateCalled_(false), invalidateTransientCalled_(false) {}
0119 
0120   bool invalidateCalled() const { return invalidateCalled_; }
0121 
0122   bool invalidateTransientCalled() const { return invalidateTransientCalled_; }
0123 
0124   void set(Dummy* iDummy) { data_ = iDummy; }
0125 
0126 protected:
0127   const value_type* make(const record_type&, const DataKey&) final {
0128     invalidateCalled_ = false;
0129     invalidateTransientCalled_ = false;
0130     return data_;
0131   }
0132   void invalidateCache() final {
0133     invalidateCalled_ = true;
0134     eventsetup::ESProductResolverTemplate<DummyRecord, Dummy>::invalidateCache();
0135   }
0136 
0137   void invalidateTransientCache() override {
0138     invalidateTransientCalled_ = true;
0139     //check default behavior
0140     eventsetup::ESProductResolverTemplate<DummyRecord, Dummy>::invalidateTransientCache();
0141   }
0142   void const* getAfterPrefetchImpl() const override { return data_; }
0143 
0144 private:
0145   const Dummy* data_;
0146   bool invalidateCalled_;
0147   bool invalidateTransientCalled_;
0148 };
0149 
0150 testEventsetupRecord::testEventsetupRecord() : taskArena_(1), eventSetupImpl_() {}
0151 void testEventsetupRecord::setUp() { dummyRecordKey_ = EventSetupRecordKey::makeKey<DummyRecord>(); }
0152 
0153 class WorkingDummyProvider : public edm::eventsetup::ESProductResolverProvider {
0154 public:
0155   WorkingDummyProvider(const edm::eventsetup::DataKey& iKey, std::shared_ptr<WorkingDummyResolver> iResolver)
0156       : m_key(iKey), m_resolver(iResolver) {
0157     usingRecord<DummyRecord>();
0158   }
0159 
0160   std::vector<edm::eventsetup::ESModuleProducesInfo> producesInfo() const override {
0161     return std::vector<edm::eventsetup::ESModuleProducesInfo>(
0162         1,
0163         edm::eventsetup::ESModuleProducesInfo(edm::eventsetup::EventSetupRecordKey::makeKey<DummyRecord>(), m_key, 0));
0164   }
0165 
0166 protected:
0167   KeyedResolversVector registerResolvers(const EventSetupRecordKey&, unsigned int /* iovIndex */) override {
0168     KeyedResolversVector keyedResolversVector;
0169     keyedResolversVector.emplace_back(m_key, m_resolver);
0170     return keyedResolversVector;
0171   }
0172 
0173 private:
0174   edm::eventsetup::DataKey m_key;
0175   std::shared_ptr<WorkingDummyResolver> m_resolver;
0176 };
0177 
0178 void testEventsetupRecord::resolverTest() {
0179   eventsetup::EventSetupRecordImpl dummyRecord{dummyRecordKey_, &activityRegistry};
0180 
0181   FailingDummyResolver dummyResolver;
0182 
0183   const DataKey dummyDataKey(DataKey::makeTypeTag<FailingDummyResolver::value_type>(), "");
0184 
0185   CPPUNIT_ASSERT(nullptr == dummyRecord.find(dummyDataKey));
0186 
0187   dummyRecord.add(dummyDataKey, &dummyResolver);
0188   CPPUNIT_ASSERT(&dummyResolver == dummyRecord.find(dummyDataKey));
0189 
0190   const DataKey dummyFredDataKey(DataKey::makeTypeTag<FailingDummyResolver::value_type>(), "fred");
0191   CPPUNIT_ASSERT(nullptr == dummyRecord.find(dummyFredDataKey));
0192 }
0193 
0194 namespace {
0195   struct DummyDataConsumer : public EDConsumerBase {
0196     explicit DummyDataConsumer(ESInputTag const& iTag) : m_token{esConsumes(iTag)} {}
0197 
0198     void prefetch(eventsetup::EventSetupRecordImpl const& iRec) const {
0199       auto const& resolvers = this->esGetTokenIndicesVector(edm::Transition::Event);
0200       for (size_t i = 0; i != resolvers.size(); ++i) {
0201         oneapi::tbb::task_group group;
0202         edm::FinalWaitingTask waitTask{group};
0203         edm::ServiceToken token;
0204         iRec.prefetchAsync(WaitingTaskHolder(group, &waitTask), resolvers[i], nullptr, token, edm::ESParentContext{});
0205         waitTask.wait();
0206       }
0207     }
0208 
0209     ESGetToken<Dummy, DummyRecord> m_token;
0210   };
0211 
0212   struct DummyDataConsumerGeneric : public EDConsumerBase {
0213     explicit DummyDataConsumerGeneric(DataKey const& iKey)
0214         : m_token{esConsumes<>(eventsetup::EventSetupRecordKey::makeKey<DummyRecord>(), iKey)} {}
0215 
0216     void prefetch(eventsetup::EventSetupRecordImpl const& iRec) const {
0217       auto const& resolvers = this->esGetTokenIndicesVector(edm::Transition::Event);
0218       for (size_t i = 0; i != resolvers.size(); ++i) {
0219         oneapi::tbb::task_group group;
0220         edm::FinalWaitingTask waitTask{group};
0221         edm::ServiceToken token;
0222         iRec.prefetchAsync(WaitingTaskHolder(group, &waitTask), resolvers[i], nullptr, token, edm::ESParentContext{});
0223         waitTask.wait();
0224       }
0225     }
0226 
0227     ESGetTokenGeneric m_token;
0228   };
0229 
0230 }  // namespace
0231 
0232 namespace {
0233   template <typename CONSUMER>
0234   struct SetupRecordT {
0235     eventsetup::EventSetupRecordImpl dummyRecordImpl;
0236     edm::EventSetupImpl& eventSetupImpl_;
0237     CONSUMER& consumer;
0238     //we need the DataKeys to stick around since references are being kept to them
0239     std::vector<std::pair<edm::eventsetup::DataKey, edm::eventsetup::ESProductResolver*>> resolvers;
0240     // same for ESParentContext
0241     ESParentContext pc_;
0242 
0243     SetupRecordT(CONSUMER& iConsumer,
0244                  EventSetupRecordKey const& iKey,
0245                  EventSetupImpl& iEventSetup,
0246                  ActivityRegistry* iRegistry,
0247                  std::vector<std::pair<edm::eventsetup::DataKey, edm::eventsetup::ESProductResolver*>> iResolvers)
0248         : dummyRecordImpl(iKey, iRegistry),
0249           eventSetupImpl_(iEventSetup),
0250           consumer(iConsumer),
0251           resolvers(std::move(iResolvers)) {
0252       for (auto const& d : resolvers) {
0253         dummyRecordImpl.add(d.first, d.second);
0254       }
0255 
0256       ESRecordsToProductResolverIndices resolverIndices({iKey});
0257       std::vector<DataKey> const& dataKeys = dummyRecordImpl.registeredDataKeys();
0258 
0259       (void)resolverIndices.dataKeysInRecord(0,
0260                                              iKey,
0261                                              dataKeys,
0262                                              dummyRecordImpl.componentsForRegisteredDataKeys(),
0263                                              dummyRecordImpl.produceMethodIDsForRegisteredDataKeys());
0264 
0265       iConsumer.updateLookup(resolverIndices);
0266       iConsumer.prefetch(dummyRecordImpl);
0267     }
0268 
0269     DummyRecord makeRecord() {
0270       DummyRecord ret;
0271       ret.setImpl(&dummyRecordImpl, 0, consumer.esGetTokenIndices(edm::Transition::Event), &eventSetupImpl_, &pc_);
0272       return ret;
0273     }
0274   };
0275   using SetupRecord = SetupRecordT<DummyDataConsumer>;
0276   using SetupGenericRecord = SetupRecordT<DummyDataConsumerGeneric>;
0277 }  // namespace
0278 
0279 void testEventsetupRecord::getHandleTest() {
0280   FailingDummyResolver dummyResolver;
0281 
0282   const DataKey dummyDataKey(DataKey::makeTypeTag<FailingDummyResolver::value_type>(), "");
0283 
0284   ESHandle<Dummy> dummyPtr;
0285   {
0286     DummyDataConsumer consumer{edm::ESInputTag("", "")};
0287 
0288     SetupRecord sr{consumer, dummyRecordKey_, eventSetupImpl_, &activityRegistry, {}};
0289     DummyRecord dummyRecord = sr.makeRecord();
0290 
0291     CPPUNIT_ASSERT(not dummyRecord.getHandle(consumer.m_token));
0292     dummyPtr = dummyRecord.getHandle(consumer.m_token);
0293     CPPUNIT_ASSERT(not dummyPtr.isValid());
0294     CPPUNIT_ASSERT(not dummyPtr);
0295     CPPUNIT_ASSERT(dummyPtr.failedToGet());
0296     CPPUNIT_ASSERT_THROW(*dummyPtr, NoProductResolverException);
0297     CPPUNIT_ASSERT_THROW(makeESValid(dummyPtr), cms::Exception);
0298   }
0299 
0300   {
0301     DummyDataConsumer consumer{edm::ESInputTag("", "")};
0302 
0303     SetupRecord sr{consumer, dummyRecordKey_, eventSetupImpl_, &activityRegistry, {{dummyDataKey, &dummyResolver}}};
0304 
0305     DummyRecord dummyRecord = sr.makeRecord();
0306     CPPUNIT_ASSERT_THROW(dummyRecord.getHandle(consumer.m_token), ExceptionType);
0307   }
0308   Dummy myDummy;
0309   WorkingDummyResolver workingResolver(&myDummy);
0310   ComponentDescription cd;
0311   cd.label_ = "";
0312   cd.type_ = "DummyProd";
0313   workingResolver.setProviderDescription(&cd);
0314 
0315   const DataKey workingDataKey(DataKey::makeTypeTag<WorkingDummyResolver::value_type>(), "working");
0316   {
0317     DummyDataConsumer consumer{edm::ESInputTag("", "working")};
0318     SetupRecord sr{consumer,
0319                    dummyRecordKey_,
0320                    eventSetupImpl_,
0321                    &activityRegistry,
0322                    {{dummyDataKey, &dummyResolver}, {workingDataKey, &workingResolver}}};
0323 
0324     DummyRecord dummyRecord = sr.makeRecord();
0325 
0326     dummyPtr = dummyRecord.getHandle(consumer.m_token);
0327     CPPUNIT_ASSERT(!dummyPtr.failedToGet());
0328     CPPUNIT_ASSERT(dummyPtr.isValid());
0329     CPPUNIT_ASSERT(dummyPtr);
0330 
0331     CPPUNIT_ASSERT(&(*dummyPtr) == &myDummy);
0332   }
0333   {
0334     DummyDataConsumer consumer{edm::ESInputTag("DummyProd", "working")};
0335     SetupRecord sr{consumer,
0336                    dummyRecordKey_,
0337                    eventSetupImpl_,
0338                    &activityRegistry,
0339                    {{dummyDataKey, &dummyResolver}, {workingDataKey, &workingResolver}}};
0340 
0341     DummyRecord dummyRecord = sr.makeRecord();
0342 
0343     dummyPtr = dummyRecord.getHandle(consumer.m_token);
0344     CPPUNIT_ASSERT(&(*dummyPtr) == &myDummy);
0345   }
0346   {
0347     DummyDataConsumer consumer{edm::ESInputTag("SmartProd", "working")};
0348     SetupRecord sr{consumer,
0349                    dummyRecordKey_,
0350                    eventSetupImpl_,
0351                    &activityRegistry,
0352                    {{dummyDataKey, &dummyResolver}, {workingDataKey, &workingResolver}}};
0353 
0354     DummyRecord dummyRecord = sr.makeRecord();
0355 
0356     CPPUNIT_ASSERT(not dummyRecord.getHandle(consumer.m_token));
0357     CPPUNIT_ASSERT_THROW(*dummyRecord.getHandle(consumer.m_token), cms::Exception);
0358   }
0359   //check if label is set
0360   cd.label_ = "foo";
0361   {
0362     DummyDataConsumer consumer{edm::ESInputTag("foo", "working")};
0363     SetupRecord sr{consumer,
0364                    dummyRecordKey_,
0365                    eventSetupImpl_,
0366                    &activityRegistry,
0367                    {{dummyDataKey, &dummyResolver}, {workingDataKey, &workingResolver}}};
0368 
0369     DummyRecord dummyRecord = sr.makeRecord();
0370 
0371     dummyPtr = dummyRecord.getHandle(consumer.m_token);
0372     CPPUNIT_ASSERT(&(*dummyPtr) == &myDummy);
0373   }
0374   {
0375     DummyDataConsumer consumer{edm::ESInputTag("DummyProd", "working")};
0376     SetupRecord sr{consumer,
0377                    dummyRecordKey_,
0378                    eventSetupImpl_,
0379                    &activityRegistry,
0380                    {{dummyDataKey, &dummyResolver}, {workingDataKey, &workingResolver}}};
0381 
0382     DummyRecord dummyRecord = sr.makeRecord();
0383 
0384     CPPUNIT_ASSERT(not dummyRecord.getHandle(consumer.m_token));
0385     CPPUNIT_ASSERT_THROW(*dummyRecord.getHandle(consumer.m_token), cms::Exception);
0386   }
0387 }
0388 
0389 void testEventsetupRecord::getWithTokenTest() {
0390   FailingDummyResolver dummyResolver;
0391 
0392   const DataKey dummyDataKey(DataKey::makeTypeTag<FailingDummyResolver::value_type>(), "");
0393 
0394   {
0395     DummyDataConsumer consumer{edm::ESInputTag("", "")};
0396 
0397     SetupRecord sr{consumer, dummyRecordKey_, eventSetupImpl_, &activityRegistry, {}};
0398 
0399     DummyRecord dummyRecord = sr.makeRecord();
0400 
0401     CPPUNIT_ASSERT_THROW(dummyRecord.get(consumer.m_token), NoProductResolverException);
0402   }
0403 
0404   {
0405     DummyDataConsumer consumer{edm::ESInputTag("", "")};
0406 
0407     SetupRecord sr{consumer, dummyRecordKey_, eventSetupImpl_, &activityRegistry, {{dummyDataKey, &dummyResolver}}};
0408 
0409     DummyRecord dummyRecord = sr.makeRecord();
0410     CPPUNIT_ASSERT_THROW(dummyRecord.get(consumer.m_token), ExceptionType);
0411   }
0412   Dummy myDummy;
0413   WorkingDummyResolver workingResolver(&myDummy);
0414   ComponentDescription cd;
0415   cd.label_ = "";
0416   cd.type_ = "DummyProd";
0417   workingResolver.setProviderDescription(&cd);
0418 
0419   const DataKey workingDataKey(DataKey::makeTypeTag<WorkingDummyResolver::value_type>(), "working");
0420   {
0421     DummyDataConsumer consumer{edm::ESInputTag("", "working")};
0422     SetupRecord sr{consumer,
0423                    dummyRecordKey_,
0424                    eventSetupImpl_,
0425                    &activityRegistry,
0426                    {{dummyDataKey, &dummyResolver}, {workingDataKey, &workingResolver}}};
0427 
0428     DummyRecord dummyRecord = sr.makeRecord();
0429     auto const& dummyData = dummyRecord.get(consumer.m_token);
0430 
0431     CPPUNIT_ASSERT(&dummyData == &myDummy);
0432   }
0433   {
0434     DummyDataConsumer consumer{edm::ESInputTag("DummyProd", "working")};
0435     SetupRecord sr{consumer,
0436                    dummyRecordKey_,
0437                    eventSetupImpl_,
0438                    &activityRegistry,
0439                    {{dummyDataKey, &dummyResolver}, {workingDataKey, &workingResolver}}};
0440 
0441     DummyRecord dummyRecord = sr.makeRecord();
0442     auto const& dummyData = dummyRecord.get(consumer.m_token);
0443     CPPUNIT_ASSERT(&dummyData == &myDummy);
0444   }
0445   {
0446     DummyDataConsumer consumer{edm::ESInputTag("SmartProd", "working")};
0447     SetupRecord sr{consumer,
0448                    dummyRecordKey_,
0449                    eventSetupImpl_,
0450                    &activityRegistry,
0451                    {{dummyDataKey, &dummyResolver}, {workingDataKey, &workingResolver}}};
0452 
0453     DummyRecord dummyRecord = sr.makeRecord();
0454     CPPUNIT_ASSERT_THROW(dummyRecord.get(consumer.m_token), cms::Exception);
0455   }
0456   //check if label is set
0457   cd.label_ = "foo";
0458   {
0459     DummyDataConsumer consumer{edm::ESInputTag("foo", "working")};
0460     SetupRecord sr{consumer,
0461                    dummyRecordKey_,
0462                    eventSetupImpl_,
0463                    &activityRegistry,
0464                    {{dummyDataKey, &dummyResolver}, {workingDataKey, &workingResolver}}};
0465 
0466     DummyRecord dummyRecord = sr.makeRecord();
0467     auto const& dummyData = dummyRecord.get(consumer.m_token);
0468     CPPUNIT_ASSERT(&dummyData == &myDummy);
0469   }
0470   {
0471     DummyDataConsumer consumer{edm::ESInputTag("DummyProd", "working")};
0472     SetupRecord sr{consumer,
0473                    dummyRecordKey_,
0474                    eventSetupImpl_,
0475                    &activityRegistry,
0476                    {{dummyDataKey, &dummyResolver}, {workingDataKey, &workingResolver}}};
0477 
0478     DummyRecord dummyRecord = sr.makeRecord();
0479     CPPUNIT_ASSERT_THROW(dummyRecord.get(consumer.m_token), cms::Exception);
0480   }
0481 }
0482 
0483 void testEventsetupRecord::getNodataExpTest() {
0484   const DataKey dummyDataKey(DataKey::makeTypeTag<FailingDummyResolver::value_type>(), "");
0485 
0486   edm::ESConsumesInfo consumesInfo;
0487   edm::ESConsumesCollectorT<DummyRecord> cc(&consumesInfo, static_cast<unsigned int>(edm::Transition::Event));
0488   auto token = cc.consumes<Dummy>();
0489   std::vector<edm::ESResolverIndex> getTokenIndices{ESResolverIndex::noResolverConfigured()};
0490 
0491   EventSetupRecordImpl recImpl(DummyRecord::keyForClass(), &activityRegistry);
0492   DummyRecord dummyRecord;
0493   ESParentContext pc;
0494   dummyRecord.setImpl(&recImpl, 0, getTokenIndices.data(), &eventSetupImpl_, &pc);
0495 
0496   ESHandle<Dummy> dummyPtr = dummyRecord.getHandle(token);
0497   *dummyPtr;
0498 }
0499 
0500 void testEventsetupRecord::doGetTest() {
0501   const DataKey dummyDataKey(DataKey::makeTypeTag<FailingDummyResolver::value_type>(), "");
0502 
0503   {
0504     DummyDataConsumerGeneric consumer{dummyDataKey};
0505 
0506     SetupGenericRecord sr{consumer, dummyRecordKey_, eventSetupImpl_, &activityRegistry, {}};
0507 
0508     DummyRecord dummyRecord = sr.makeRecord();
0509 
0510     CPPUNIT_ASSERT(!dummyRecord.doGet(consumer.m_token));
0511   }
0512 
0513   FailingDummyResolver dummyResolver;
0514 
0515   {
0516     DummyDataConsumerGeneric consumer{dummyDataKey};
0517 
0518     SetupGenericRecord sr{
0519         consumer, dummyRecordKey_, eventSetupImpl_, &activityRegistry, {{dummyDataKey, &dummyResolver}}};
0520 
0521     DummyRecord dummyRecord = sr.makeRecord();
0522     CPPUNIT_ASSERT_THROW(dummyRecord.doGet(consumer.m_token), ExceptionType);
0523   }
0524   Dummy myDummy;
0525   WorkingDummyResolver workingResolver(&myDummy);
0526 
0527   const DataKey workingDataKey(DataKey::makeTypeTag<WorkingDummyResolver::value_type>(), "working");
0528 
0529   {
0530     DummyDataConsumerGeneric consumer{workingDataKey};
0531 
0532     SetupGenericRecord sr{consumer,
0533                           dummyRecordKey_,
0534                           eventSetupImpl_,
0535                           &activityRegistry,
0536                           {{dummyDataKey, &dummyResolver}, {workingDataKey, &workingResolver}}};
0537 
0538     DummyRecord dummyRecord = sr.makeRecord();
0539     CPPUNIT_ASSERT(dummyRecord.doGet(consumer.m_token));
0540   }
0541 }
0542 
0543 namespace {
0544   ComponentDescription const* find(std::vector<DataKey> const& iKeys,
0545                                    std::vector<ComponentDescription const*> const& iComp,
0546                                    DataKey const& iKey) {
0547     return iComp[std::lower_bound(iKeys.begin(), iKeys.end(), iKey) - iKeys.begin()];
0548   }
0549 }  // namespace
0550 
0551 void testEventsetupRecord::introspectionTest() {
0552   eventsetup::EventSetupRecordImpl dummyRecordImpl{dummyRecordKey_, &activityRegistry};
0553   FailingDummyResolver dummyResolver;
0554 
0555   ComponentDescription cd1;
0556   cd1.label_ = "foo1";
0557   cd1.type_ = "DummyProd1";
0558   cd1.isSource_ = false;
0559   cd1.isLooper_ = false;
0560   dummyResolver.setProviderDescription(&cd1);
0561 
0562   const DataKey dummyDataKey(DataKey::makeTypeTag<FailingDummyResolver::value_type>(), "");
0563 
0564   std::vector<edm::eventsetup::DataKey> keys = dummyRecordImpl.registeredDataKeys();
0565   CPPUNIT_ASSERT(keys.empty());
0566 
0567   DummyRecord dummyRecord;
0568   ESParentContext pc;
0569   dummyRecord.setImpl(&dummyRecordImpl, 0, nullptr, &eventSetupImpl_, &pc);
0570 
0571   std::vector<ComponentDescription const*> esproducers;
0572   dummyRecordImpl.getESProducers(esproducers);
0573   CPPUNIT_ASSERT(esproducers.empty());
0574 
0575   std::vector<DataKey> referencedDataKeys = dummyRecordImpl.registeredDataKeys();
0576   auto referencedComponents = dummyRecordImpl.componentsForRegisteredDataKeys();
0577   CPPUNIT_ASSERT(referencedDataKeys.empty());
0578   CPPUNIT_ASSERT(referencedComponents.empty());
0579 
0580   dummyRecordImpl.add(dummyDataKey, &dummyResolver);
0581 
0582   dummyRecord.fillRegisteredDataKeys(keys);
0583   CPPUNIT_ASSERT(1 == keys.size());
0584 
0585   dummyRecordImpl.getESProducers(esproducers);
0586   CPPUNIT_ASSERT(esproducers.size() == 1);
0587   CPPUNIT_ASSERT(esproducers[0] == &cd1);
0588 
0589   referencedDataKeys = dummyRecordImpl.registeredDataKeys();
0590   referencedComponents = dummyRecordImpl.componentsForRegisteredDataKeys();
0591   CPPUNIT_ASSERT(referencedDataKeys.size() == 1);
0592   CPPUNIT_ASSERT(referencedComponents.size() == 1);
0593   CPPUNIT_ASSERT(referencedComponents[0] == &cd1);
0594   CPPUNIT_ASSERT(find(referencedDataKeys, referencedComponents, dummyDataKey) == &cd1);
0595 
0596   Dummy myDummy;
0597   WorkingDummyResolver workingResolver(&myDummy);
0598 
0599   ComponentDescription cd2;
0600   cd2.label_ = "foo2";
0601   cd2.type_ = "DummyProd2";
0602   cd2.isSource_ = true;
0603   cd2.isLooper_ = false;
0604   workingResolver.setProviderDescription(&cd2);
0605 
0606   const DataKey workingDataKey(DataKey::makeTypeTag<WorkingDummyResolver::value_type>(), "working");
0607 
0608   dummyRecordImpl.add(workingDataKey, &workingResolver);
0609 
0610   dummyRecord.fillRegisteredDataKeys(keys);
0611   CPPUNIT_ASSERT(2 == keys.size());
0612 
0613   dummyRecordImpl.getESProducers(esproducers);
0614   CPPUNIT_ASSERT(esproducers.size() == 1);
0615 
0616   referencedDataKeys = dummyRecordImpl.registeredDataKeys();
0617   referencedComponents = dummyRecordImpl.componentsForRegisteredDataKeys();
0618   CPPUNIT_ASSERT(referencedDataKeys.size() == 2);
0619   CPPUNIT_ASSERT(referencedComponents.size() == 2);
0620   CPPUNIT_ASSERT(find(referencedDataKeys, referencedComponents, workingDataKey) == &cd2);
0621 
0622   Dummy myDummy3;
0623   WorkingDummyResolver workingResolver3(&myDummy3);
0624 
0625   ComponentDescription cd3;
0626   cd3.label_ = "foo3";
0627   cd3.type_ = "DummyProd3";
0628   cd3.isSource_ = false;
0629   cd3.isLooper_ = true;
0630   workingResolver3.setProviderDescription(&cd3);
0631 
0632   const DataKey workingDataKey3(DataKey::makeTypeTag<WorkingDummyResolver::value_type>(), "working3");
0633 
0634   dummyRecordImpl.add(workingDataKey3, &workingResolver3);
0635 
0636   dummyRecordImpl.getESProducers(esproducers);
0637   CPPUNIT_ASSERT(esproducers.size() == 1);
0638 
0639   referencedDataKeys = dummyRecordImpl.registeredDataKeys();
0640   referencedComponents = dummyRecordImpl.componentsForRegisteredDataKeys();
0641   CPPUNIT_ASSERT(referencedDataKeys.size() == 3);
0642   CPPUNIT_ASSERT(referencedComponents.size() == 3);
0643   CPPUNIT_ASSERT(find(referencedDataKeys, referencedComponents, workingDataKey3) == &cd3);
0644 
0645   Dummy myDummy4;
0646   WorkingDummyResolver workingResolver4(&myDummy4);
0647 
0648   ComponentDescription cd4;
0649   cd4.label_ = "foo4";
0650   cd4.type_ = "DummyProd4";
0651   cd4.isSource_ = false;
0652   cd4.isLooper_ = false;
0653   workingResolver4.setProviderDescription(&cd4);
0654 
0655   const DataKey workingDataKey4(DataKey::makeTypeTag<WorkingDummyResolver::value_type>(), "working4");
0656 
0657   dummyRecordImpl.add(workingDataKey4, &workingResolver4);
0658 
0659   dummyRecordImpl.getESProducers(esproducers);
0660   CPPUNIT_ASSERT(esproducers.size() == 2);
0661   CPPUNIT_ASSERT(esproducers[1] == &cd4);
0662 
0663   referencedDataKeys = dummyRecordImpl.registeredDataKeys();
0664   referencedComponents = dummyRecordImpl.componentsForRegisteredDataKeys();
0665   CPPUNIT_ASSERT(referencedDataKeys.size() == 4);
0666   CPPUNIT_ASSERT(referencedComponents.size() == 4);
0667   CPPUNIT_ASSERT(find(referencedDataKeys, referencedComponents, workingDataKey4) == &cd4);
0668 
0669   dummyRecordImpl.clearResolvers();
0670   dummyRecord.fillRegisteredDataKeys(keys);
0671   CPPUNIT_ASSERT(0 == keys.size());
0672 }
0673 
0674 void testEventsetupRecord::doGetExepTest() {
0675   const DataKey dummyDataKey(DataKey::makeTypeTag<FailingDummyResolver::value_type>(), "");
0676   {
0677     DummyDataConsumerGeneric consumer{dummyDataKey};
0678 
0679     SetupGenericRecord sr{consumer, dummyRecordKey_, eventSetupImpl_, &activityRegistry, {}};
0680 
0681     DummyRecord dummyRecord = sr.makeRecord();
0682 
0683     CPPUNIT_ASSERT(!dummyRecord.doGet(consumer.m_token));
0684   }
0685 
0686   {
0687     FailingDummyResolver dummyResolver;
0688 
0689     const DataKey dummyDataKey(DataKey::makeTypeTag<FailingDummyResolver::value_type>(), "");
0690 
0691     DummyDataConsumerGeneric consumer{dummyDataKey};
0692 
0693     SetupGenericRecord sr{
0694         consumer, dummyRecordKey_, eventSetupImpl_, &activityRegistry, {{dummyDataKey, &dummyResolver}}};
0695 
0696     DummyRecord dummyRecord = sr.makeRecord();
0697 
0698     CPPUNIT_ASSERT(dummyRecord.doGet(consumer.m_token));
0699   }
0700 }
0701 
0702 void testEventsetupRecord::resolverResetTest() {
0703   auto dummyProvider = std::make_unique<EventSetupRecordProvider>(DummyRecord::keyForClass(), &activityRegistry);
0704 
0705   Dummy myDummy;
0706   std::shared_ptr<WorkingDummyResolver> workingResolver = std::make_shared<WorkingDummyResolver>(&myDummy);
0707 
0708   const DataKey workingDataKey(DataKey::makeTypeTag<WorkingDummyResolver::value_type>(), "");
0709   DummyDataConsumer consumer{edm::ESInputTag("", "")};
0710   SetupRecord sr{
0711       consumer, dummyRecordKey_, eventSetupImpl_, &activityRegistry, {{workingDataKey, workingResolver.get()}}};
0712   DummyRecord dummyRecord = sr.makeRecord();
0713 
0714   edm::ESConsumesInfo consumesInfo;
0715   edm::ESConsumesCollectorT<DummyRecord> cc(&consumesInfo, static_cast<unsigned int>(edm::Transition::Event));
0716   auto token = cc.consumes<Dummy>();
0717   std::vector<edm::ESResolverIndex> getTokenIndices{edm::ESResolverIndex(0)};
0718 
0719   std::shared_ptr<WorkingDummyProvider> wdProv =
0720       std::make_shared<WorkingDummyProvider>(workingDataKey, workingResolver);
0721   CPPUNIT_ASSERT(nullptr != wdProv.get());
0722   if (wdProv.get() == nullptr)
0723     return;  // To silence Coverity
0724   wdProv->createKeyedResolvers(DummyRecord::keyForClass(), 1);
0725   dummyProvider->add(wdProv);
0726 
0727   //this causes the resolvers to actually be placed in the Record
0728   edm::eventsetup::EventSetupRecordProvider::DataToPreferredProviderMap pref;
0729   dummyProvider->usePreferred(pref);
0730 
0731   edm::ESHandle<Dummy> hDummy = dummyRecord.getHandle(token);
0732 
0733   CPPUNIT_ASSERT(&myDummy == &(*hDummy));
0734 
0735   Dummy myDummy2;
0736   workingResolver->set(&myDummy2);
0737 
0738   //should not change
0739   hDummy = dummyRecord.getHandle(token);
0740   CPPUNIT_ASSERT(&myDummy == &(*hDummy));
0741   CPPUNIT_ASSERT(!workingResolver->invalidateCalled());
0742   CPPUNIT_ASSERT(!workingResolver->invalidateTransientCalled());
0743 
0744   dummyProvider->resetResolvers();
0745   CPPUNIT_ASSERT(workingResolver->invalidateCalled());
0746   CPPUNIT_ASSERT(workingResolver->invalidateTransientCalled());
0747   consumer.prefetch(sr.dummyRecordImpl);
0748   hDummy = dummyRecord.getHandle(token);
0749   CPPUNIT_ASSERT(&myDummy2 == &(*hDummy));
0750   CPPUNIT_ASSERT(!workingResolver->invalidateCalled());
0751   CPPUNIT_ASSERT(!workingResolver->invalidateTransientCalled());
0752 }
0753 
0754 void testEventsetupRecord::transientTest() {
0755   // NEEDS TO BE REWRITTEN WHEN WE FIX OR REMOVE THE TRANSIENT
0756   // PARTS OF THE EVENTSETUP CODE WHICH IS CURRENTLY DISABLED
0757 
0758   auto dummyProvider = std::make_unique<EventSetupRecordProvider>(DummyRecord::keyForClass(), &activityRegistry);
0759 
0760   Dummy myDummy;
0761   std::shared_ptr<WorkingDummyResolver> workingResolver = std::make_shared<WorkingDummyResolver>(&myDummy);
0762 
0763   const DataKey workingDataKey(DataKey::makeTypeTag<WorkingDummyResolver::value_type>(), "");
0764   DummyDataConsumer consumer{edm::ESInputTag("", "")};
0765   SetupRecord sr{
0766       consumer, dummyRecordKey_, eventSetupImpl_, &activityRegistry, {{workingDataKey, workingResolver.get()}}};
0767   DummyRecord dummyRecordNoConst = sr.makeRecord();
0768   EventSetupRecord const& dummyRecord = dummyRecordNoConst;
0769 
0770   edm::ESConsumesInfo consumesInfo;
0771   edm::ESConsumesCollectorT<DummyRecord> cc(&consumesInfo, static_cast<unsigned int>(edm::Transition::Event));
0772   auto token = cc.consumes<Dummy>();
0773   std::vector<edm::ESResolverIndex> getTokenIndices{edm::ESResolverIndex(0)};
0774 
0775   eventsetup::EventSetupRecordImpl& nonConstDummyRecordImpl = *const_cast<EventSetupRecordImpl*>(dummyRecord.impl_);
0776 
0777   std::shared_ptr<WorkingDummyProvider> wdProv =
0778       std::make_shared<WorkingDummyProvider>(workingDataKey, workingResolver);
0779   wdProv->createKeyedResolvers(DummyRecord::keyForClass(), 1);
0780   dummyProvider->add(wdProv);
0781 
0782   //this causes the resolvers to actually be placed in the Record
0783   edm::eventsetup::EventSetupRecordProvider::DataToPreferredProviderMap pref;
0784   dummyProvider->usePreferred(pref);
0785 
0786   //do a transient access to see if it clears properly
0787   edm::ESTransientHandle<Dummy> hTDummy;
0788   CPPUNIT_ASSERT(hTDummy.transientAccessOnly);
0789   hTDummy = dummyRecord.getHandleImpl<edm::ESTransientHandle>(token);
0790 
0791   CPPUNIT_ASSERT(&myDummy == &(*hTDummy));
0792   CPPUNIT_ASSERT(workingResolver->invalidateCalled() == false);
0793   CPPUNIT_ASSERT(workingResolver->invalidateTransientCalled() == false);
0794 
0795   nonConstDummyRecordImpl.resetIfTransientInResolvers();
0796   CPPUNIT_ASSERT(workingResolver->invalidateCalled());
0797   CPPUNIT_ASSERT(workingResolver->invalidateTransientCalled());
0798 
0799   Dummy myDummy2;
0800   workingResolver->set(&myDummy2);
0801 
0802   //do non-transient access to make sure nothing resets now
0803   consumer.prefetch(sr.dummyRecordImpl);
0804   edm::ESHandle<Dummy> hDummy = dummyRecord.getHandleImpl<edm::ESHandle>(token);
0805 
0806   hDummy = dummyRecord.getHandleImpl<edm::ESHandle>(token);
0807   CPPUNIT_ASSERT(&myDummy2 == &(*hDummy));
0808   nonConstDummyRecordImpl.resetIfTransientInResolvers();
0809   CPPUNIT_ASSERT(workingResolver->invalidateCalled() == false);
0810   CPPUNIT_ASSERT(workingResolver->invalidateTransientCalled() == false);
0811 
0812   //do another transient access which should not do a reset since we have a non-transient access outstanding
0813   consumer.prefetch(sr.dummyRecordImpl);
0814   hDummy = dummyRecord.getHandleImpl<edm::ESHandle>(token);
0815   hTDummy = dummyRecord.getHandleImpl<edm::ESTransientHandle>(token);
0816 
0817   nonConstDummyRecordImpl.resetIfTransientInResolvers();
0818   CPPUNIT_ASSERT(workingResolver->invalidateCalled() == false);
0819   CPPUNIT_ASSERT(workingResolver->invalidateTransientCalled() == false);
0820 
0821   //Ask for a transient then a non transient to be sure we don't have an ordering problem
0822   {
0823     dummyProvider->resetResolvers();
0824     Dummy myDummy3;
0825     workingResolver->set(&myDummy3);
0826 
0827     consumer.prefetch(sr.dummyRecordImpl);
0828     hDummy = dummyRecord.getHandleImpl<edm::ESHandle>(token);
0829     hTDummy = dummyRecord.getHandleImpl<edm::ESTransientHandle>(token);
0830 
0831     CPPUNIT_ASSERT(&myDummy3 == &(*hDummy));
0832     CPPUNIT_ASSERT(&myDummy3 == &(*hTDummy));
0833     nonConstDummyRecordImpl.resetIfTransientInResolvers();
0834     CPPUNIT_ASSERT(workingResolver->invalidateCalled() == false);
0835     CPPUNIT_ASSERT(workingResolver->invalidateTransientCalled() == false);
0836   }
0837 }