Skip to content

Commit

Permalink
Merge branch 'DOR-450_utests_silence_stderr' into 'master'
Browse files Browse the repository at this point in the history
DOR-450 "Utests silence stderr"

Closes DOR-450

See merge request machine-learning/dorado!742
  • Loading branch information
tijyojwad committed Dec 1, 2023
2 parents b0767a6 + 1038c81 commit d871eb1
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 9 deletions.
21 changes: 18 additions & 3 deletions tests/IndexFileAccessTest.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "alignment/IndexFileAccess.h"

#include "StreamUtils.h"
#include "TestUtils.h"
#include "alignment/Minimap2Index.h"

Expand All @@ -9,6 +10,8 @@

#define TEST_GROUP "[alignment::IndexFileAccess]"

using namespace ont::test_utils::streams;

namespace {

const std::string& valid_reference_file() {
Expand All @@ -29,6 +32,15 @@ const dorado::alignment::Minimap2Options& invalid_options() {
}();
return result;
}

dorado::alignment::IndexLoadResult load_index_no_stderr(
dorado::alignment::IndexFileAccess& cut,
const std::string& file,
const dorado::alignment::Minimap2Options& options) {
SuppressStderr no_stderr{};
return cut.load_index(file, options, 1);
}

} // namespace

namespace dorado::alignment::index_file_access {
Expand All @@ -47,7 +59,7 @@ TEST_CASE(TEST_GROUP " load_index with invalid file return reference_file_not_fo
TEST_CASE(TEST_GROUP " load_index with invalid options returns validation_error", TEST_GROUP) {
IndexFileAccess cut{};

REQUIRE(cut.load_index(valid_reference_file(), invalid_options(), 1) ==
REQUIRE(load_index_no_stderr(cut, valid_reference_file(), invalid_options()) ==
IndexLoadResult::validation_error);
}

Expand All @@ -67,7 +79,7 @@ SCENARIO(TEST_GROUP " Load and retrieve index files", TEST_GROUP) {
}

GIVEN("load_index called with valid file but invalid options") {
cut.load_index(valid_reference_file(), invalid_options(), 1);
load_index_no_stderr(cut, valid_reference_file(), invalid_options());
THEN("is_index_loaded returns false") {
REQUIRE_FALSE(cut.is_index_loaded(valid_reference_file(), invalid_options()));
}
Expand Down Expand Up @@ -163,7 +175,10 @@ SCENARIO(TEST_GROUP " Load and retrieve index files", TEST_GROUP) {
}

TEST_CASE(TEST_GROUP " validate_options with invalid options returns false", TEST_GROUP) {
REQUIRE_FALSE(validate_options(invalid_options()));
bool result{};
SuppressStderr::invoke([&result] { result = validate_options(invalid_options()); });

REQUIRE_FALSE(result);
}

TEST_CASE(TEST_GROUP " validate_options with default options returns true", TEST_GROUP) {
Expand Down
23 changes: 17 additions & 6 deletions tests/Minimap2IndexTest.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "alignment/Minimap2Index.h"

#include "StreamUtils.h"
#include "TestUtils.h"

#include <catch2/catch.hpp>
Expand All @@ -8,6 +9,8 @@

#define TEST_GROUP "[alignment::Minimap2Index]"

using namespace ont::test_utils::streams;

namespace {

class Minimap2IndexTestFixture {
Expand Down Expand Up @@ -68,12 +71,15 @@ TEST_CASE(TEST_GROUP " initialise() with invalid options returns false", TEST_GR
auto invalid_options{dflt_options};
invalid_options.bandwidth = invalid_options.bandwidth_long + 1;

REQUIRE_FALSE(cut.initialise(invalid_options));
bool result{};
SuppressStderr::invoke(
[&result, &invalid_options, &cut] { result = cut.initialise(invalid_options); });

REQUIRE_FALSE(result);
}

TEST_CASE_METHOD(Minimap2IndexTestFixture,
TEST_GROUP
" load() without invalid reference file returns reference_file_not_found",
TEST_GROUP " load() with invalid reference file returns reference_file_not_found",
TEST_GROUP) {
REQUIRE(cut.load("some_reference_file", 1) == IndexLoadResult::reference_file_not_found);
}
Expand All @@ -85,14 +91,19 @@ TEST_CASE_METHOD(Minimap2IndexTestFixture,
}

TEST_CASE_METHOD(Minimap2IndexTestFixture,
TEST_GROUP
" create_compatible_index() with invalid mapping options returns non-null",
TEST_GROUP " create_compatible_index() with invalid mapping options returns null",
TEST_GROUP) {
cut.load(reference_file, 1);
Minimap2Options invalid_compatible_options{dflt_options};
invalid_compatible_options.bandwidth = invalid_compatible_options.bandwidth_long + 1;

REQUIRE(cut.create_compatible_index(invalid_compatible_options) == nullptr);
std::shared_ptr<Minimap2Index> compatible_index{};
{
SuppressStderr suppressed{};
compatible_index = cut.create_compatible_index(invalid_compatible_options);
}

REQUIRE(compatible_index == nullptr);
}

TEST_CASE_METHOD(Minimap2IndexTestFixture,
Expand Down
77 changes: 77 additions & 0 deletions tests/StreamUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#ifdef _WIN32
#include <io.h>
#define NULL_DEVICE "NUL:"
#define Close _close
#define Dup _dup
#define Dup2 _dup2
#define Fileno _fileno
#else
#include <unistd.h>
#define NULL_DEVICE "/dev/null"
#define Close close
#define Dup dup
#define Dup2 dup2
#define Fileno fileno
#endif

#include <stdio.h>

#include <functional>

namespace ont::test_utils::streams {

namespace details {
template <class T>
void ignore(const T &) {}
} // namespace details

inline int suppress_stderr() {
fflush(stderr);
int fd = Dup(Fileno(stderr));
auto old_stream = freopen(NULL_DEVICE, "w", stderr);
details::ignore(old_stream);
return fd;
}

inline void restore_stderr(int fd) {
fflush(stderr);
auto dup_result = Dup2(fd, Fileno(stderr));
details::ignore(dup_result);
Close(fd);
}

inline int suppress_stdout() {
fflush(stdout);
int fd = Dup(Fileno(stdout));
auto old_stream = freopen(NULL_DEVICE, "w", stdout);
details::ignore(old_stream);
return fd;
}

inline void restore_stdout(int fd) {
fflush(stdout);
auto dup_result = Dup2(fd, Fileno(stdout));
details::ignore(dup_result);
Close(fd);
}

/// <summary>
/// RAII helper to provide scoped stderr suppression
/// </summary>
class [[nodiscard]] SuppressStderr final {
const int m_fd;

public:
SuppressStderr() : m_fd(suppress_stderr()) {}
~SuppressStderr() { restore_stderr(m_fd); }

/// <summary>
/// Invoke a function with stderr suppressed
/// </summary>
static void invoke(std::function<void()> func) {
SuppressStderr suppression{};
func();
}
};

} // namespace ont::test_utils::streams

0 comments on commit d871eb1

Please sign in to comment.