Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-10-07 04:59:32

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