Skip to content

Commit

Permalink
Allow ESHandle be constructed from a whyFailedFactory of another ESHa…
Browse files Browse the repository at this point in the history
…ndle
  • Loading branch information
makortel committed Oct 19, 2023
1 parent eb6caad commit 533e20d
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 3 deletions.
6 changes: 3 additions & 3 deletions FWCore/Framework/interface/ESHandle.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ namespace edm {
: data_(iData), description_(desc) {}

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

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

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

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

template <class T>
ESHandle<T>::ESHandle(std::shared_ptr<edm::ESHandleExceptionFactory>&& iWhyFailed)
ESHandle<T>::ESHandle(std::shared_ptr<edm::ESHandleExceptionFactory> iWhyFailed)
: ESHandleBase(std::move(iWhyFailed)) {}

// Free swap function
Expand Down
5 changes: 5 additions & 0 deletions FWCore/Framework/test/BuildFile.xml
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,11 @@
<use name="FWCore/Framework"/>
</bin>

<bin file="test_catch2_main.cc,test_catch2_ESHandle.cc" name="TestFWCoreFrameworkESHandle">
<use name="catch2"/>
<use name="FWCore/Framework"/>
</bin>

<test name="testFWCoreFrameworkNonEventOrdering" command="test_non_event_ordering.sh"/>
<test name="testFWCoreFramework1ThreadESPrefetch" command="run_test_1_thread_es_prefetching.sh"/>
<test name="testFWCoreFrameworkModuleDeletion" command="run_module_delete_tests.sh"/>
Expand Down
99 changes: 99 additions & 0 deletions FWCore/Framework/test/test_catch2_ESHandle.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#include "catch.hpp"

#include "FWCore/Framework/interface/ESHandle.h"
#include "FWCore/Utilities/interface/EDMException.h"

namespace {
class TestExceptionFactory : public edm::ESHandleExceptionFactory {
public:
std::exception_ptr make() const override { return std::make_exception_ptr(edm::Exception(edm::errors::OtherCMS)); }
};
} // namespace

TEST_CASE("test edm::ESHandle", "[ESHandle]") {
SECTION("Default constructor") {
edm::ESHandle<int> handle;
REQUIRE(not handle.isValid());
REQUIRE(not handle.failedToGet());
REQUIRE_THROWS_AS(handle.description(), edm::Exception);
REQUIRE(handle.product() == nullptr);
}

SECTION("Valid construction, without ComponentDescription") {
int const value = 42;
edm::ESHandle<int> handle(&value);
REQUIRE(not handle.isValid());
REQUIRE(not handle.failedToGet());
REQUIRE_THROWS_AS(handle.description(), edm::Exception);
REQUIRE(handle.product() != nullptr);
REQUIRE(*handle == value);
}

SECTION("Valid construction, with ComponentDescription") {
int const value = 42;
edm::eventsetup::ComponentDescription const desc;
edm::ESHandle<int> handle(&value, &desc);
REQUIRE(handle.isValid());
REQUIRE(not handle.failedToGet());
REQUIRE(handle.description() == &desc);
REQUIRE(handle.product() != nullptr);
REQUIRE(*handle == value);
}

SECTION("Failure construction from temporary") {
edm::ESHandle<int> handle(std::make_shared<TestExceptionFactory>());
REQUIRE(not handle.isValid());
REQUIRE(handle.failedToGet());
REQUIRE_THROWS_AS(handle.description(), edm::Exception);
REQUIRE_THROWS_AS(handle.product(), edm::Exception);
}

SECTION("Failure construction from object") {
auto const factory = std::make_shared<TestExceptionFactory>();
edm::ESHandle<int> handle(factory);
REQUIRE(not handle.isValid());
REQUIRE(handle.failedToGet());
REQUIRE_THROWS_AS(handle.description(), edm::Exception);
REQUIRE_THROWS_AS(handle.product(), edm::Exception);
REQUIRE(handle.whyFailedFactory().get() == factory.get());
}

SECTION("Failure construction from another ESHandle") {
auto const factory = std::make_shared<TestExceptionFactory>();
edm::ESHandle<int> handleA(factory);
edm::ESHandle<int> handle(handleA.whyFailedFactory());
REQUIRE(not handle.isValid());
REQUIRE(handle.failedToGet());
REQUIRE_THROWS_AS(handle.description(), edm::Exception);
REQUIRE_THROWS_AS(handle.product(), edm::Exception);
REQUIRE(handle.whyFailedFactory().get() == factory.get());
}

SECTION("Swap") {
int const valueA = 42;
edm::eventsetup::ComponentDescription const descA;
edm::ESHandle<int> handleA(&valueA, &descA);

SECTION("with value") {
int const valueB = 3;
edm::ESHandle<int> handleB(&valueB);

std::swap(handleA, handleB);
REQUIRE(not handleA.isValid());
REQUIRE(handleB.isValid());
REQUIRE(*handleB == valueA);
}

SECTION("with failure factory") {
auto factory = std::make_shared<TestExceptionFactory>();
edm::ESHandle<int> handleB(factory);

std::swap(handleA, handleB);
REQUIRE(not handleA.isValid());
REQUIRE(handleA.failedToGet());
REQUIRE(handleA.whyFailedFactory().get() == factory.get());
REQUIRE(handleB.isValid());
REQUIRE(*handleB == valueA);
}
}
}

0 comments on commit 533e20d

Please sign in to comment.