Skip to content

Commit

Permalink
Adding exception catcher around system::run
Browse files Browse the repository at this point in the history
  • Loading branch information
janweinstock committed Oct 9, 2023
1 parent 4644bf4 commit 5aeecd3
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 16 deletions.
42 changes: 27 additions & 15 deletions src/vcml/core/system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,21 +73,33 @@ int system::run() {

broker::report_unused();
tlm::tlm_global_quantum::instance().set(quantum);
if (session >= 0) {
vcml::debugging::vspserver vspsession(session);
vspsession.echo(session_debug);
vspsession.start();
} else if (duration != sc_core::SC_ZERO_TIME) {
log_info("starting simulation until %s using %s quantum",
duration.get().to_string().c_str(),
quantum.get().to_string().c_str());
sc_core::sc_start();
log_info("simulation stopped");
} else {
log_info("starting infinite simulation using %s quantum",
quantum.get().to_string().c_str());
sc_core::sc_start();
log_info("simulation stopped");

try {
if (session >= 0) {
vcml::debugging::vspserver vspsession(session);
vspsession.echo(session_debug);
vspsession.start();
} else if (duration != sc_core::SC_ZERO_TIME) {
log_info("starting simulation until %s using %s quantum",
duration.get().to_string().c_str(),
quantum.get().to_string().c_str());
sc_core::sc_start();
log_info("simulation stopped");
} else {
log_info("starting infinite simulation using %s quantum",
quantum.get().to_string().c_str());
sc_core::sc_start();
log_info("simulation stopped");
}
} catch (sc_report& rep) {
log_error("%s", rep.what());
return EXIT_FAILURE;
} catch (std::exception& ex) {
log_error("Caught c++ exception: %s", ex.what());
return EXIT_FAILURE;
} catch (...) {
log_error("Caught unknown exception");
return EXIT_FAILURE;
}

return EXIT_SUCCESS;
Expand Down
3 changes: 2 additions & 1 deletion test/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ core_test("tracing")
core_test("async_timer")
core_test("memory")
core_test("disk")
core_tesT("model")
core_test("model")
core_test("system")

if(LUA_FOUND)
core_test("lua")
Expand Down
40 changes: 40 additions & 0 deletions test/core/system.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/******************************************************************************
* *
* Copyright (C) 2023 MachineWare GmbH *
* All Rights Reserved *
* *
* This is work is licensed under the terms described in the LICENSE file *
* found in the root directory of this source tree. *
* *
******************************************************************************/

#include "testing.h"

class harness : public vcml::system
{
public:
mwr::publishers::terminal term;
mock_publisher pub;

harness(const sc_module_name& nm): vcml::system(nm), term(), pub() {
SC_HAS_PROCESS(harness);
SC_METHOD(test_method);
pub.expect(LOG_INFO, "starting infinite simulation");
}

virtual ~harness() = default;

void test_method() {
pub.expect(LOG_ERROR, "wait() is only allowed in SC_THREADs");
wait(SC_ZERO_TIME);
}
};

TEST(system, exceptions) {
// restore default handler, otherwise reports will count as a failure
auto handler = ::sc_core::sc_report_handler::default_handler;
::sc_core::sc_report_handler::set_handler(handler);

harness test("harness");
EXPECT_EQ(test.run(), EXIT_FAILURE);
}
23 changes: 23 additions & 0 deletions test/testing.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,29 @@ using namespace ::vcml;
#define EXPECT_SUCCESS(fn) EXPECT_TRUE(vcml::success(fn))
#define EXPECT_FAILURE(fn) EXPECT_TRUE(vcml::failure(fn))

MATCHER_P2(match_log, lvl, txt, "Matches a log message on level and text") {
if (arg.level != lvl)
return false;

for (const string& line : arg.lines)
if (line.find(txt) != std::string::npos)
return true;

return false;
}

class mock_publisher : public mwr::publisher
{
public:
mock_publisher(): mwr::publisher(LOG_ERROR, LOG_DEBUG) {}
mock_publisher(log_level min, log_level max): mwr::publisher(min, max) {}
MOCK_METHOD(void, publish, (const mwr::logmsg&), (override));

void expect(log_level lvl, const string& message) {
EXPECT_CALL(*this, publish(match_log(lvl, message)));
}
};

class test_base : public component
{
private:
Expand Down

0 comments on commit 5aeecd3

Please sign in to comment.