File indexing completed on 2024-04-06 12:03:56
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 "Utilities/Testing/interface/CppUnit_testdriver.icpp"
0007
0008 #include "cppunit/extensions/HelperMacros.h"
0009
0010 #include <iostream>
0011 #include <string>
0012 #include <utility>
0013
0014 #include <thread>
0015 #include <atomic>
0016
0017 class TestRef : public CppUnit::TestFixture {
0018 CPPUNIT_TEST_SUITE(TestRef);
0019 CPPUNIT_TEST(default_ctor);
0020
0021 CPPUNIT_TEST(nondefault_ctor);
0022
0023 CPPUNIT_TEST(using_wrong_productid);
0024 CPPUNIT_TEST(threading);
0025 CPPUNIT_TEST_SUITE_END();
0026
0027 public:
0028 typedef std::vector<int> product1_t;
0029 typedef std::map<std::string, int> product2_t;
0030
0031 typedef edm::Ref<product1_t> ref1_t;
0032
0033
0034 TestRef() {}
0035 ~TestRef() {}
0036 void setUp() {}
0037 void tearDown() {}
0038
0039 void default_ctor();
0040
0041 void default_ctor_with_active_getter();
0042 void nondefault_ctor();
0043
0044 void using_wrong_productid();
0045 void threading();
0046
0047 private:
0048 };
0049
0050 CPPUNIT_TEST_SUITE_REGISTRATION(TestRef);
0051
0052 void TestRef::default_ctor() {
0053 ref1_t default_ref;
0054 CPPUNIT_ASSERT(default_ref.isNull());
0055 CPPUNIT_ASSERT(default_ref.isNonnull() == false);
0056 CPPUNIT_ASSERT(!default_ref);
0057 CPPUNIT_ASSERT(default_ref.productGetter() == 0);
0058 CPPUNIT_ASSERT(default_ref.id().isValid() == false);
0059 CPPUNIT_ASSERT(default_ref.isAvailable() == false);
0060 }
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072 void TestRef::nondefault_ctor() {
0073 SimpleEDProductGetter getter;
0074
0075 edm::ProductID id(1, 201U);
0076 CPPUNIT_ASSERT(id.isValid());
0077
0078 auto prod = std::make_unique<product1_t>();
0079 prod->push_back(1);
0080 prod->push_back(2);
0081 getter.addProduct(id, std::move(prod));
0082
0083 ref1_t ref0(id, 0, &getter);
0084 CPPUNIT_ASSERT(ref0.isNull() == false);
0085 CPPUNIT_ASSERT(ref0.isNonnull());
0086 CPPUNIT_ASSERT(!!ref0);
0087 CPPUNIT_ASSERT(ref0.productGetter() == &getter);
0088 CPPUNIT_ASSERT(ref0.id().isValid());
0089 CPPUNIT_ASSERT(ref0.isAvailable() == true);
0090 CPPUNIT_ASSERT(*ref0 == 1);
0091
0092 ref1_t ref1(id, 1, &getter);
0093 CPPUNIT_ASSERT(ref1.isNonnull());
0094 CPPUNIT_ASSERT(ref1.isAvailable() == true);
0095 CPPUNIT_ASSERT(*ref1 == 2);
0096
0097
0098
0099
0100 }
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128 void TestRef::using_wrong_productid() {
0129 SimpleEDProductGetter getter;
0130
0131 edm::ProductID id(1, 1U);
0132 CPPUNIT_ASSERT(id.isValid());
0133
0134 auto prod = std::make_unique<product1_t>();
0135 prod->push_back(1);
0136 prod->push_back(2);
0137 getter.addProduct(id, std::move(prod));
0138
0139 edm::ProductID wrong_id(1, 100U);
0140 CPPUNIT_ASSERT(wrong_id.isValid());
0141
0142 ref1_t ref(wrong_id, 0, &getter);
0143 CPPUNIT_ASSERT_THROW(*ref, edm::Exception);
0144 CPPUNIT_ASSERT_THROW(ref.operator->(), edm::Exception);
0145 }
0146
0147 namespace {
0148 constexpr int kNThreads = 8;
0149 std::atomic<int> s_threadsStarting{kNThreads};
0150 }
0151 void TestRef::threading() {
0152 SimpleEDProductGetter getter;
0153
0154 edm::ProductID id(1, 1U);
0155 CPPUNIT_ASSERT(id.isValid());
0156
0157 auto prod = std::make_unique<product1_t>();
0158 prod->push_back(1);
0159 prod->push_back(2);
0160 getter.addProduct(id, std::move(prod));
0161
0162 ref1_t ref0(id, 0, &getter);
0163 ref1_t ref1(id, 1, &getter);
0164
0165 std::vector<std::thread> threads;
0166 std::vector<std::exception_ptr> excepPtrs(kNThreads, std::exception_ptr{});
0167
0168 for (unsigned int i = 0; i < kNThreads; ++i) {
0169 threads.emplace_back([&ref0, &ref1, i, &excepPtrs]() {
0170 --s_threadsStarting;
0171 while (0 != s_threadsStarting) {
0172 }
0173 try {
0174 CPPUNIT_ASSERT(*ref0 == 1);
0175 CPPUNIT_ASSERT(*ref1 == 2);
0176 } catch (...) {
0177 excepPtrs[i] = std::current_exception();
0178 }
0179 });
0180 }
0181 for (auto& t : threads) {
0182 t.join();
0183 }
0184
0185 for (auto& e : excepPtrs) {
0186 if (e) {
0187 std::rethrow_exception(e);
0188 }
0189 }
0190 }