Test exceptions thrown in user code

This commit is contained in:
Dennis Klein 2018-10-09 20:46:23 +02:00 committed by Dennis Klein
parent bde12f58b2
commit e39316c866
6 changed files with 166 additions and 6 deletions

View File

@ -111,12 +111,10 @@ auto DeviceRunner::RunWithExceptionHandlers() -> int
try {
return Run();
} catch (std::exception& e) {
LOG(error) << "Unhandled exception reached the top of main: " << e.what()
<< ", application will now exit";
LOG(error) << "Uncaught exception reached the top of DeviceRunner: " << e.what();
return 1;
} catch (...) {
LOG(error) << "Non-exception instance being thrown. Please make sure you use "
"std::runtime_exception() instead. Application will now exit.";
LOG(error) << "Uncaught exception reached the top of DeviceRunner.";
return 1;
}
}

View File

@ -56,12 +56,12 @@ int main(int argc, char* argv[])
}
catch (std::exception& e)
{
LOG(error) << "Unhandled exception reached the top of main: " << e.what() << ", application will now exit";
LOG(error) << "Uncaught exception reached the top of main: " << e.what();
return 1;
}
catch (...)
{
LOG(error) << "Non-exception instance being thrown. Please make sure you use std::runtime_exception() instead. Application will now exit.";
LOG(error) << "Uncaught exception reached the top of main.";
return 1;
}
}

View File

@ -27,6 +27,7 @@ add_testhelper(runTestDevice
helper/devices/TestSub.cxx
helper/devices/TestTransferTimeout.cxx
helper/devices/TestWaitFor.cxx
helper/devices/TestExceptions.cxx
LINKS FairMQ
)
@ -95,6 +96,7 @@ add_testsuite(FairMQ.Device
device/_device_version.cxx
device/_device_config.cxx
device/_waitfor.cxx
device/_exceptions.cxx
LINKS FairMQ
DEPENDS testhelper_runTestDevice

View File

@ -0,0 +1,71 @@
/********************************************************************************
* Copyright (C) 2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
#include "runner.h"
#include <gtest/gtest.h>
#include <boost/process.hpp>
#include <fairmq/Tools.h>
#include <string>
#include <thread>
#include <iostream>
namespace
{
using namespace std;
using namespace fair::mq::test;
using namespace fair::mq::tools;
void RunExceptionIn(const std::string& state)
{
size_t session{fair::mq::tools::UuidHash()};
execute_result result{"", 100};
thread device_thread([&]() {
stringstream cmd;
cmd << runTestDevice
<< " --id exceptions_" << state << "_"
<< " --control static"
<< " --session " << session
<< " --color false";
result = execute(cmd.str(), "[EXCEPTION IN " + state + "]");
});
device_thread.join();
ASSERT_NE(std::string::npos, result.console_out.find("exception in " + state + "()"));
exit(result.exit_code);
}
TEST(Exceptions, InInit) { EXPECT_EXIT(RunExceptionIn("Init"), ::testing::ExitedWithCode(1), ""); }
TEST(Exceptions, InInitTask)
{
EXPECT_EXIT(RunExceptionIn("InitTask"), ::testing::ExitedWithCode(1), "");
}
TEST(Exceptions, InPreRun)
{
EXPECT_EXIT(RunExceptionIn("PreRun"), ::testing::ExitedWithCode(1), "");
}
TEST(Exceptions, InRun) { EXPECT_EXIT(RunExceptionIn("Run"), ::testing::ExitedWithCode(1), ""); }
TEST(Exceptions, InPostRun)
{
EXPECT_EXIT(RunExceptionIn("PostRun"), ::testing::ExitedWithCode(1), "");
}
TEST(Exceptions, InResetTask)
{
EXPECT_EXIT(RunExceptionIn("ResetTask"), ::testing::ExitedWithCode(1), "");
}
TEST(Exceptions, InReset)
{
EXPECT_EXIT(RunExceptionIn("Reset"), ::testing::ExitedWithCode(1), "");
}
} // namespace

View File

@ -0,0 +1,84 @@
/********************************************************************************
* Copyright (C) 2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
#include <FairMQDevice.h>
#include <FairMQLogger.h>
#include <iostream>
#include <stdexcept>
namespace fair
{
namespace mq
{
namespace test
{
class TestExceptions : public FairMQDevice
{
public:
auto Init() -> void override
{
std::string state("Init");
if (std::string::npos != GetId().find("_" + state + "_")) {
throw std::runtime_error("exception in " + state + "()");
}
}
auto InitTask() -> void override
{
std::string state("InitTask");
if (std::string::npos != GetId().find("_" + state + "_")) {
throw std::runtime_error("exception in " + state + "()");
}
}
auto PreRun() -> void override
{
std::string state("PreRun");
if (std::string::npos != GetId().find("_" + state + "_")) {
throw std::runtime_error("exception in " + state + "()");
}
}
auto Run() -> void override
{
std::string state("Run");
if (std::string::npos != GetId().find("_" + state + "_")) {
throw std::runtime_error("exception in " + state + "()");
}
}
auto PostRun() -> void override
{
std::string state("PostRun");
if (std::string::npos != GetId().find("_" + state + "_")) {
throw std::runtime_error("exception in " + state + "()");
}
}
auto ResetTask() -> void override
{
std::string state("ResetTask");
if (std::string::npos != GetId().find("_" + state + "_")) {
throw std::runtime_error("exception in " + state + "()");
}
}
auto Reset() -> void override
{
std::string state("Reset");
if (std::string::npos != GetId().find("_" + state + "_")) {
throw std::runtime_error("exception in " + state + "()");
}
}
};
} // namespace test
} // namespace mq
} // namespace fair

View File

@ -18,6 +18,7 @@
#include "devices/TestSub.cxx"
#include "devices/TestTransferTimeout.cxx"
#include "devices/TestWaitFor.cxx"
#include "devices/TestExceptions.cxx"
#include <runFairMQDevice.h>
@ -87,6 +88,10 @@ auto getDevice(const FairMQProgOptions& config) -> FairMQDevicePtr
{
return new TestWaitFor;
}
else if (0 == id.find("exceptions_"))
{
return new TestExceptions;
}
else
{
cerr << "Don't know id '" << id << "'" << endl;