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
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
0031
0032
0033
0034
0035
0036
0037
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
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
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 }