Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-07-16 00:28:33

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