Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:12:26

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