Back to home page

Project CMSSW displayed by LXR

 
 

    


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

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