Skip to content

Commit c85a467

Browse files
authored
Merge pull request cms-sw#43068 from makortel/eshandleFailedFactory
Allow ESHandle be constructed from a whyFailedFactory of another ESHandle
2 parents 07a781e + 3912156 commit c85a467

File tree

3 files changed

+229
-3
lines changed

3 files changed

+229
-3
lines changed

FWCore/Framework/interface/ESHandle.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ namespace edm {
3737
: data_(iData), description_(desc) {}
3838

3939
///Used when the attempt to get the data failed
40-
ESHandleBase(std::shared_ptr<ESHandleExceptionFactory>&& iWhyFailed) : whyFailedFactory_(std::move(iWhyFailed)) {}
40+
ESHandleBase(std::shared_ptr<ESHandleExceptionFactory> iWhyFailed) : whyFailedFactory_(std::move(iWhyFailed)) {}
4141

4242
edm::eventsetup::ComponentDescription const* description() const;
4343

@@ -80,7 +80,7 @@ namespace edm {
8080
ESHandle() = default;
8181
ESHandle(T const* iData) : ESHandleBase(iData, nullptr) {}
8282
ESHandle(T const* iData, edm::eventsetup::ComponentDescription const* desc) : ESHandleBase(iData, desc) {}
83-
ESHandle(std::shared_ptr<ESHandleExceptionFactory>&&);
83+
ESHandle(std::shared_ptr<ESHandleExceptionFactory>);
8484

8585
// ---------- const member functions ---------------------
8686
T const* product() const { return static_cast<T const*>(productStorage()); }
@@ -93,7 +93,7 @@ namespace edm {
9393
};
9494

9595
template <class T>
96-
ESHandle<T>::ESHandle(std::shared_ptr<edm::ESHandleExceptionFactory>&& iWhyFailed)
96+
ESHandle<T>::ESHandle(std::shared_ptr<edm::ESHandleExceptionFactory> iWhyFailed)
9797
: ESHandleBase(std::move(iWhyFailed)) {}
9898

9999
// Free swap function

FWCore/Framework/test/BuildFile.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,11 @@
350350
<use name="FWCore/Framework"/>
351351
</bin>
352352

353+
<bin file="test_catch2_main.cc,test_catch2_ESHandle.cc" name="TestFWCoreFrameworkESHandle">
354+
<use name="catch2"/>
355+
<use name="FWCore/Framework"/>
356+
</bin>
357+
353358
<test name="testFWCoreFrameworkNonEventOrdering" command="test_non_event_ordering.sh"/>
354359
<test name="testFWCoreFramework1ThreadESPrefetch" command="run_test_1_thread_es_prefetching.sh"/>
355360
<test name="testFWCoreFrameworkModuleDeletion" command="run_module_delete_tests.sh"/>
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
#include "catch.hpp"
2+
3+
#include "FWCore/Framework/interface/ESHandle.h"
4+
#include "FWCore/Utilities/interface/EDMException.h"
5+
6+
namespace {
7+
class TestExceptionFactory : public edm::ESHandleExceptionFactory {
8+
public:
9+
std::exception_ptr make() const override { return std::make_exception_ptr(edm::Exception(edm::errors::OtherCMS)); }
10+
};
11+
} // namespace
12+
13+
TEST_CASE("test edm::ESHandle", "[ESHandle]") {
14+
SECTION("Default constructor") {
15+
edm::ESHandle<int> handle;
16+
REQUIRE(not handle.isValid());
17+
REQUIRE(not handle.failedToGet());
18+
REQUIRE_THROWS_AS(handle.description(), edm::Exception);
19+
REQUIRE(handle.product() == nullptr);
20+
}
21+
22+
SECTION("Valid construction") {
23+
int const value = 42;
24+
25+
SECTION("without ComponentDescription") {
26+
edm::ESHandle<int> handle(&value);
27+
REQUIRE(not handle.isValid());
28+
REQUIRE(not handle.failedToGet());
29+
REQUIRE_THROWS_AS(handle.description(), edm::Exception);
30+
REQUIRE(handle.product() != nullptr);
31+
REQUIRE(*handle == value);
32+
}
33+
34+
SECTION("Valid construction, with ComponentDescription") {
35+
edm::eventsetup::ComponentDescription const desc;
36+
edm::ESHandle<int> handle(&value, &desc);
37+
REQUIRE(handle.isValid());
38+
REQUIRE(not handle.failedToGet());
39+
REQUIRE(handle.description() == &desc);
40+
REQUIRE(handle.product() != nullptr);
41+
REQUIRE(*handle == value);
42+
}
43+
}
44+
45+
SECTION("Construction for a 'failure'") {
46+
SECTION("From temporary factory object") {
47+
edm::ESHandle<int> handle(std::make_shared<TestExceptionFactory>());
48+
REQUIRE(not handle.isValid());
49+
REQUIRE(handle.failedToGet());
50+
REQUIRE_THROWS_AS(handle.description(), edm::Exception);
51+
REQUIRE_THROWS_AS(handle.product(), edm::Exception);
52+
}
53+
54+
SECTION("From another factory object") {
55+
auto const factory = std::make_shared<TestExceptionFactory>();
56+
edm::ESHandle<int> handle(factory);
57+
REQUIRE(not handle.isValid());
58+
REQUIRE(handle.failedToGet());
59+
REQUIRE_THROWS_AS(handle.description(), edm::Exception);
60+
REQUIRE_THROWS_AS(handle.product(), edm::Exception);
61+
REQUIRE(handle.whyFailedFactory().get() == factory.get());
62+
}
63+
64+
SECTION("From another ESHandle") {
65+
auto const factory = std::make_shared<TestExceptionFactory>();
66+
edm::ESHandle<int> handleA(factory);
67+
edm::ESHandle<int> handle(handleA.whyFailedFactory());
68+
REQUIRE(not handle.isValid());
69+
REQUIRE(handle.failedToGet());
70+
REQUIRE_THROWS_AS(handle.description(), edm::Exception);
71+
REQUIRE_THROWS_AS(handle.product(), edm::Exception);
72+
REQUIRE(handle.whyFailedFactory().get() == factory.get());
73+
}
74+
}
75+
76+
SECTION("Copying") {
77+
int const valueA = 42;
78+
edm::eventsetup::ComponentDescription const descA;
79+
80+
SECTION("From valid ESHandle") {
81+
edm::ESHandle<int> const handleA(&valueA, &descA);
82+
83+
SECTION("Constructor") {
84+
edm::ESHandle<int> handleB(handleA);
85+
REQUIRE(handleA.isValid());
86+
REQUIRE(*handleA == valueA);
87+
REQUIRE(handleB.isValid());
88+
REQUIRE(*handleB == valueA);
89+
}
90+
91+
SECTION("Assignment") {
92+
edm::ESHandle<int> handleB;
93+
REQUIRE(not handleB.isValid());
94+
95+
handleB = handleA;
96+
REQUIRE(handleA.isValid());
97+
REQUIRE(*handleA == valueA);
98+
REQUIRE(handleB.isValid());
99+
REQUIRE(*handleB == valueA);
100+
}
101+
}
102+
103+
SECTION("From invalid ESHandle") {
104+
edm::ESHandle<int> const handleA(std::make_shared<TestExceptionFactory>());
105+
106+
SECTION("Constructor") {
107+
edm::ESHandle<int> handleB(handleA);
108+
REQUIRE(not handleA.isValid());
109+
REQUIRE(handleA.failedToGet());
110+
REQUIRE_THROWS_AS(handleA.description(), edm::Exception);
111+
REQUIRE_THROWS_AS(handleA.product(), edm::Exception);
112+
113+
REQUIRE(not handleB.isValid());
114+
REQUIRE(handleB.failedToGet());
115+
REQUIRE_THROWS_AS(handleB.description(), edm::Exception);
116+
REQUIRE_THROWS_AS(handleB.product(), edm::Exception);
117+
}
118+
119+
SECTION("Assignment") {
120+
edm::ESHandle<int> handleB(&valueA, &descA);
121+
REQUIRE(handleB.isValid());
122+
123+
handleB = handleA;
124+
REQUIRE(not handleA.isValid());
125+
REQUIRE(handleA.failedToGet());
126+
REQUIRE_THROWS_AS(handleA.description(), edm::Exception);
127+
REQUIRE_THROWS_AS(handleA.product(), edm::Exception);
128+
129+
REQUIRE(not handleB.isValid());
130+
REQUIRE(handleB.failedToGet());
131+
REQUIRE_THROWS_AS(handleB.description(), edm::Exception);
132+
REQUIRE_THROWS_AS(handleB.product(), edm::Exception);
133+
}
134+
}
135+
}
136+
137+
SECTION("Moving") {
138+
int const valueA = 42;
139+
edm::eventsetup::ComponentDescription const descA;
140+
141+
SECTION("From valid ESHandle") {
142+
edm::ESHandle<int> handleA(&valueA, &descA);
143+
144+
SECTION("Constructor") {
145+
edm::ESHandle<int> handleB(std::move(handleA));
146+
REQUIRE(handleB.isValid());
147+
REQUIRE(*handleB == valueA);
148+
}
149+
150+
SECTION("Assignment") {
151+
edm::ESHandle<int> handleB;
152+
REQUIRE(not handleB.isValid());
153+
154+
handleB = std::move(handleA);
155+
REQUIRE(handleB.isValid());
156+
REQUIRE(*handleB == valueA);
157+
}
158+
}
159+
160+
SECTION("From invalid ESHandle") {
161+
edm::ESHandle<int> handleA(std::make_shared<TestExceptionFactory>());
162+
163+
SECTION("Constructor") {
164+
edm::ESHandle<int> handleB(std::move(handleA));
165+
// this is pretty much the only feature that we can test on
166+
// the moved-from ESHandle that is guaranteed to change (to
167+
// test that move actually happens instead of copy)
168+
REQUIRE(not handleA.failedToGet());
169+
170+
REQUIRE(not handleB.isValid());
171+
REQUIRE(handleB.failedToGet());
172+
REQUIRE_THROWS_AS(handleB.description(), edm::Exception);
173+
REQUIRE_THROWS_AS(handleB.product(), edm::Exception);
174+
}
175+
176+
SECTION("Assignment") {
177+
edm::ESHandle<int> handleB(&valueA, &descA);
178+
REQUIRE(handleB.isValid());
179+
180+
handleB = std::move(handleA);
181+
// this is pretty much the only feature that we can test on
182+
// the moved-from ESHandle that is guaranteed to change (to
183+
// test that move actually happens instead of copy)
184+
REQUIRE(not handleA.failedToGet());
185+
186+
REQUIRE(not handleB.isValid());
187+
REQUIRE(handleB.failedToGet());
188+
REQUIRE_THROWS_AS(handleB.description(), edm::Exception);
189+
REQUIRE_THROWS_AS(handleB.product(), edm::Exception);
190+
}
191+
}
192+
}
193+
194+
SECTION("Swap") {
195+
int const valueA = 42;
196+
edm::eventsetup::ComponentDescription const descA;
197+
edm::ESHandle<int> handleA(&valueA, &descA);
198+
199+
SECTION("With value") {
200+
int const valueB = 3;
201+
edm::ESHandle<int> handleB(&valueB);
202+
203+
std::swap(handleA, handleB);
204+
REQUIRE(not handleA.isValid());
205+
REQUIRE(handleB.isValid());
206+
REQUIRE(*handleB == valueA);
207+
}
208+
209+
SECTION("With failure factory") {
210+
auto factory = std::make_shared<TestExceptionFactory>();
211+
edm::ESHandle<int> handleB(factory);
212+
213+
std::swap(handleA, handleB);
214+
REQUIRE(not handleA.isValid());
215+
REQUIRE(handleA.failedToGet());
216+
REQUIRE(handleA.whyFailedFactory().get() == factory.get());
217+
REQUIRE(handleB.isValid());
218+
REQUIRE(*handleB == valueA);
219+
}
220+
}
221+
}

0 commit comments

Comments
 (0)