Skip to content

Commit

Permalink
exit normally in aborts predicate
Browse files Browse the repository at this point in the history
When testing that a closure calls `abort`, exit normally in the child
process if the test closure returns successfully. Previously, the child
process would call `_Exit` in order to terminate without flushing to
stdout. However, this also prevents gcov from writing coverage metrics
of the child process as this routine is registered with `atexit`.

This commit updates the abort predicate to send a flush command to the
printer before calling fork. The child process silences the printer
before invoking the test closure and exits normally if needed.

Change-Id: I0164e5752b4967ecad87c7fb7eee6622b847ab4b
  • Loading branch information
oliverlee committed Dec 24, 2023
1 parent 1f3faf2 commit f4a27ed
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 4 deletions.
18 changes: 18 additions & 0 deletions .github/coverage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
coverage:
status:
project:
default:
# basic
target: auto
threshold: 0%
base: auto
flags:
- unit
paths:
- "src"
# advanced settings
branches:
- master
if_ci_failed: error #success, failure, error, ignore
informational: false
only_pulls: false
28 changes: 24 additions & 4 deletions src/aborts.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

#include "src/cfg.hpp"

#include <cstdlib>
#include <cstring>
#include <optional>
Expand All @@ -10,7 +12,8 @@

namespace skytest {

inline constexpr struct
namespace detail {
struct aborts_fn
{
struct return_type
{
Expand Down Expand Up @@ -38,23 +41,40 @@ inline constexpr struct
}
};

template <class F>
struct do_flush
{
friend auto& operator<<(std::ostream& os, do_flush)
{
os.flush();
return os;
}
};

template <class F, class Override = override>
constexpr auto operator()(F&& f) const -> return_type
{
cfg<Override>.printer_ << do_flush{};

const auto pid = ::fork();
if (pid == -1) {
return {};
}

if (pid == 0) {
cfg<Override>.silence();

std::forward<F>(f)();
std::_Exit(EXIT_SUCCESS);

// NOLINTNEXTLINE(concurrency-mt-unsafe)
std::exit(EXIT_SUCCESS);
}

auto status = int{};
::wait(&status);
return {status};
}
} aborts{};
};
} // namespace detail
inline constexpr auto aborts = detail::aborts_fn{};

} // namespace skytest
12 changes: 12 additions & 0 deletions src/runner.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,20 @@
#include <type_traits>

namespace skytest {
namespace detail {
struct aborts_fn;
}

template <class Printer>
class runner
{
mutable Printer printer_;
mutable summary summary_{};
mutable bool silent_ = false;

friend struct ::skytest::detail::aborts_fn;

auto silence() const { silent_ = true; }

public:
template <
Expand All @@ -25,6 +33,10 @@ class runner

~runner()
{
if (silent_) {
return;
}

printer_ << summary_;

// NOLINTNEXTLINE(concurrency-mt-unsafe)
Expand Down

0 comments on commit f4a27ed

Please sign in to comment.