Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-06-17 01:30:10

0001 #include "SimpleEDProductGetter.h"
0002 
0003 #include "DataFormats/Common/interface/EDProductGetter.h"
0004 #include "DataFormats/Common/interface/Ref.h"
0005 #include "FWCore/Utilities/interface/EDMException.h"
0006 #include "catch.hpp"
0007 
0008 #include <iostream>
0009 #include <string>
0010 #include <utility>
0011 #include <thread>
0012 #include <atomic>
0013 
0014 using product1_t = std::vector<int>;
0015 using product2_t = std::map<std::string, int>;
0016 using ref1_t = edm::Ref<product1_t>;
0017 // using ref2_t = edm::Ref<product2_t, int>;
0018 
0019 TEST_CASE("Ref tests", "[Ref]") {
0020   SECTION("default constructor") {
0021     ref1_t default_ref;
0022     REQUIRE(default_ref.isNull());
0023     REQUIRE(default_ref.isNonnull() == false);
0024     REQUIRE(!default_ref);
0025     REQUIRE(default_ref.productGetter() == 0);
0026     REQUIRE(default_ref.id().isValid() == false);
0027     REQUIRE(default_ref.isAvailable() == false);
0028   }
0029 
0030   // SECTION("default constructor with string key") {
0031   //   ref2_t default_ref;
0032   //   REQUIRE(default_ref.isNull());
0033   //   REQUIRE(default_ref.isNonnull()==false);
0034   //   REQUIRE(!default_ref);
0035   //   REQUIRE(default_ref.productGetter()==0);
0036   //   REQUIRE(default_ref.id().isValid()==false);
0037   //   REQUIRE(default_ref.id().isAvailable()==false);
0038   // }
0039 
0040   SECTION("non-default constructor") {
0041     SimpleEDProductGetter getter;
0042     edm::ProductID id(1, 201U);
0043     REQUIRE(id.isValid());
0044     auto prod = std::make_unique<product1_t>();
0045     prod->push_back(1);
0046     prod->push_back(2);
0047     getter.addProduct(id, std::move(prod));
0048 
0049     ref1_t ref0(id, 0, &getter);
0050     REQUIRE(ref0.isNull() == false);
0051     REQUIRE(ref0.isNonnull());
0052     REQUIRE(!!ref0);
0053     REQUIRE(ref0.productGetter() == &getter);
0054     REQUIRE(ref0.id().isValid());
0055     REQUIRE(ref0.isAvailable() == true);
0056     REQUIRE(*ref0 == 1);
0057 
0058     ref1_t ref1(id, 1, &getter);
0059     REQUIRE(ref1.isNonnull());
0060     REQUIRE(ref1.isAvailable() == true);
0061     REQUIRE(*ref1 == 2);
0062   }
0063 
0064   // SECTION("non-default constructor 2") {
0065   //   SimpleEDProductGetter getter;
0066   //   edm::EDProductGetter::Operate op(&getter);
0067   //   edm::ProductID id(1, 201U);
0068   //   REQUIRE(id.isValid());
0069   //   auto prod = std::make_unique<product2_t>();
0070   //   prod->insert(std::make_pair(std::string("a"), 1));
0071   //   prod->insert(std::make_pair(std::string("b"), 2));
0072   //   prod->insert(std::make_pair(std::string("c"), 3));
0073   //   getter.addProduct(id, prod);
0074   //   ref2_t refa(id, std::string("a"), &getter);
0075   //   REQUIRE(refa.isNull()==false);
0076   //   REQUIRE(refa.isNonnull());
0077   //   REQUIRE(!!refa);
0078   //   REQUIRE(refa.productGetter()==&getter);
0079   //   REQUIRE(refa.id().isValid());
0080   //   REQUIRE(*refa == 1);
0081   //   ref2_t refb(id, "b", &getter);
0082   //   REQUIRE(refb.isNonnull());
0083   //   REQUIRE(*refb == 2);
0084   // }
0085 
0086   SECTION("using wrong productid") {
0087     SimpleEDProductGetter getter;
0088     edm::ProductID id(1, 1U);
0089     REQUIRE(id.isValid());
0090     auto prod = std::make_unique<product1_t>();
0091     prod->push_back(1);
0092     prod->push_back(2);
0093     getter.addProduct(id, std::move(prod));
0094     edm::ProductID wrong_id(1, 100U);
0095     REQUIRE(wrong_id.isValid());
0096     ref1_t ref(wrong_id, 0, &getter);
0097     REQUIRE_THROWS_AS(*ref, edm::Exception);
0098     REQUIRE_THROWS_AS(ref.operator->(), edm::Exception);
0099   }
0100 
0101   SECTION("threading") {
0102     constexpr int kNThreads = 8;
0103     std::atomic<int> s_threadsStarting{kNThreads};
0104     SimpleEDProductGetter getter;
0105     edm::ProductID id(1, 1U);
0106     REQUIRE(id.isValid());
0107     auto prod = std::make_unique<product1_t>();
0108     prod->push_back(1);
0109     prod->push_back(2);
0110     getter.addProduct(id, std::move(prod));
0111     ref1_t ref0(id, 0, &getter);
0112     ref1_t ref1(id, 1, &getter);
0113     std::vector<std::thread> threads;
0114     std::vector<std::exception_ptr> excepPtrs(kNThreads, std::exception_ptr{});
0115     for (unsigned int i = 0; i < kNThreads; ++i) {
0116       threads.emplace_back([&ref0, &ref1, i, &excepPtrs, &s_threadsStarting]() {
0117         --s_threadsStarting;
0118         while (0 != s_threadsStarting) {
0119         }
0120         try {
0121           REQUIRE(*ref0 == 1);
0122           REQUIRE(*ref1 == 2);
0123         } catch (...) {
0124           excepPtrs[i] = std::current_exception();
0125         }
0126       });
0127     }
0128     for (auto& t : threads) {
0129       t.join();
0130     }
0131     for (auto& e : excepPtrs) {
0132       if (e) {
0133         std::rethrow_exception(e);
0134       }
0135     }
0136   }
0137 }