2019-04-29 21:25:05 +00:00
|
|
|
// Copyright 2018 The gVisor Authors.
|
2018-12-10 22:41:40 +00:00
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
#ifndef GVISOR_TEST_UTIL_POSIX_ERROR_H_
|
|
|
|
#define GVISOR_TEST_UTIL_POSIX_ERROR_H_
|
|
|
|
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
#include "gmock/gmock.h"
|
|
|
|
#include "absl/base/attributes.h"
|
|
|
|
#include "absl/strings/string_view.h"
|
|
|
|
#include "absl/types/variant.h"
|
|
|
|
#include "test/util/logging.h"
|
|
|
|
|
|
|
|
namespace gvisor {
|
|
|
|
namespace testing {
|
|
|
|
|
|
|
|
class PosixErrorIsMatcherCommonImpl;
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
class PosixErrorOr;
|
|
|
|
|
|
|
|
class ABSL_MUST_USE_RESULT PosixError {
|
|
|
|
public:
|
|
|
|
PosixError() {}
|
|
|
|
explicit PosixError(int errno_value) : errno_(errno_value) {}
|
|
|
|
PosixError(int errno_value, std::string msg)
|
|
|
|
: errno_(errno_value), msg_(std::move(msg)) {}
|
|
|
|
|
|
|
|
PosixError(PosixError&& other) = default;
|
|
|
|
PosixError& operator=(PosixError&& other) = default;
|
|
|
|
PosixError(const PosixError&) = default;
|
|
|
|
PosixError& operator=(const PosixError&) = default;
|
|
|
|
|
|
|
|
bool ok() const { return errno_ == 0; }
|
|
|
|
|
|
|
|
// Returns a reference to *this to make matchers compatible with
|
|
|
|
// PosixErrorOr.
|
|
|
|
const PosixError& error() const { return *this; }
|
|
|
|
|
|
|
|
std::string error_message() const { return msg_; }
|
|
|
|
|
2019-06-28 22:28:24 +00:00
|
|
|
// ToString produces a full string representation of this posix error
|
2018-12-10 22:41:40 +00:00
|
|
|
// including the printable representation of the errno and the error message.
|
|
|
|
std::string ToString() const;
|
|
|
|
|
|
|
|
// Ignores any errors. This method does nothing except potentially suppress
|
|
|
|
// complaints from any tools that are checking that errors are not dropped on
|
|
|
|
// the floor.
|
|
|
|
void IgnoreError() const {}
|
|
|
|
|
|
|
|
private:
|
|
|
|
int errno_value() const { return errno_; }
|
|
|
|
int errno_ = 0;
|
|
|
|
std::string msg_;
|
|
|
|
|
|
|
|
friend class PosixErrorIsMatcherCommonImpl;
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
friend class PosixErrorOr;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
class ABSL_MUST_USE_RESULT PosixErrorOr {
|
|
|
|
public:
|
2019-02-26 23:46:39 +00:00
|
|
|
// A PosixErrorOr will check fail if it is constructed with NoError().
|
2018-12-18 20:15:22 +00:00
|
|
|
PosixErrorOr(const PosixError& error);
|
|
|
|
PosixErrorOr(const T& value);
|
|
|
|
PosixErrorOr(T&& value);
|
2018-12-10 22:41:40 +00:00
|
|
|
|
|
|
|
PosixErrorOr(PosixErrorOr&& other) = default;
|
|
|
|
PosixErrorOr& operator=(PosixErrorOr&& other) = default;
|
|
|
|
PosixErrorOr(const PosixErrorOr&) = default;
|
|
|
|
PosixErrorOr& operator=(const PosixErrorOr&) = default;
|
|
|
|
|
|
|
|
// Conversion copy/move constructor, T must be convertible from U.
|
|
|
|
template <typename U>
|
|
|
|
friend class PosixErrorOr;
|
|
|
|
|
|
|
|
template <typename U>
|
|
|
|
PosixErrorOr(PosixErrorOr<U> other);
|
|
|
|
|
|
|
|
template <typename U>
|
|
|
|
PosixErrorOr& operator=(PosixErrorOr<U> other);
|
|
|
|
|
|
|
|
// Return a reference to the error or NoError().
|
2019-04-25 21:11:32 +00:00
|
|
|
PosixError error() const;
|
2018-12-10 22:41:40 +00:00
|
|
|
|
|
|
|
// Returns this->error().error_message();
|
2019-04-25 21:11:32 +00:00
|
|
|
std::string error_message() const;
|
2018-12-10 22:41:40 +00:00
|
|
|
|
2019-02-26 23:46:39 +00:00
|
|
|
// Returns true if this PosixErrorOr contains some T.
|
2018-12-10 22:41:40 +00:00
|
|
|
bool ok() const;
|
|
|
|
|
|
|
|
// Returns a reference to our current value, or CHECK-fails if !this->ok().
|
2018-12-12 01:04:42 +00:00
|
|
|
const T& ValueOrDie() const&;
|
|
|
|
T& ValueOrDie() &;
|
|
|
|
const T&& ValueOrDie() const&&;
|
|
|
|
T&& ValueOrDie() &&;
|
2018-12-10 22:41:40 +00:00
|
|
|
|
|
|
|
// Ignores any errors. This method does nothing except potentially suppress
|
|
|
|
// complaints from any tools that are checking that errors are not dropped on
|
|
|
|
// the floor.
|
|
|
|
void IgnoreError() const {}
|
|
|
|
|
|
|
|
private:
|
2019-04-25 21:11:32 +00:00
|
|
|
int errno_value() const;
|
2018-12-10 22:41:40 +00:00
|
|
|
absl::variant<T, PosixError> value_;
|
|
|
|
|
|
|
|
friend class PosixErrorIsMatcherCommonImpl;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T>
|
2019-02-26 23:46:39 +00:00
|
|
|
PosixErrorOr<T>::PosixErrorOr(const PosixError& error) : value_(error) {
|
|
|
|
TEST_CHECK_MSG(
|
|
|
|
!error.ok(),
|
|
|
|
"Constructing PosixErrorOr with NoError, eg. errno 0 is not allowed.");
|
|
|
|
}
|
2018-12-10 22:41:40 +00:00
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
PosixErrorOr<T>::PosixErrorOr(const T& value) : value_(value) {}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
PosixErrorOr<T>::PosixErrorOr(T&& value) : value_(std::move(value)) {}
|
|
|
|
|
|
|
|
// Conversion copy/move constructor, T must be convertible from U.
|
|
|
|
template <typename T>
|
|
|
|
template <typename U>
|
|
|
|
inline PosixErrorOr<T>::PosixErrorOr(PosixErrorOr<U> other) {
|
|
|
|
if (absl::holds_alternative<U>(other.value_)) {
|
|
|
|
// T is convertible from U.
|
|
|
|
value_ = absl::get<U>(std::move(other.value_));
|
|
|
|
} else if (absl::holds_alternative<PosixError>(other.value_)) {
|
|
|
|
value_ = absl::get<PosixError>(std::move(other.value_));
|
|
|
|
} else {
|
|
|
|
TEST_CHECK_MSG(false, "PosixErrorOr does not contain PosixError or value");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
template <typename U>
|
|
|
|
inline PosixErrorOr<T>& PosixErrorOr<T>::operator=(PosixErrorOr<U> other) {
|
|
|
|
if (absl::holds_alternative<U>(other.value_)) {
|
|
|
|
// T is convertible from U.
|
|
|
|
value_ = absl::get<U>(std::move(other.value_));
|
|
|
|
} else if (absl::holds_alternative<PosixError>(other.value_)) {
|
|
|
|
value_ = absl::get<PosixError>(std::move(other.value_));
|
|
|
|
} else {
|
|
|
|
TEST_CHECK_MSG(false, "PosixErrorOr does not contain PosixError or value");
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
2019-04-25 21:11:32 +00:00
|
|
|
PosixError PosixErrorOr<T>::error() const {
|
2018-12-10 22:41:40 +00:00
|
|
|
if (!absl::holds_alternative<PosixError>(value_)) {
|
|
|
|
return PosixError();
|
|
|
|
}
|
|
|
|
return absl::get<PosixError>(value_);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
2019-04-25 21:11:32 +00:00
|
|
|
int PosixErrorOr<T>::errno_value() const {
|
2018-12-10 22:41:40 +00:00
|
|
|
return error().errno_value();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
2019-04-25 21:11:32 +00:00
|
|
|
std::string PosixErrorOr<T>::error_message() const {
|
2018-12-10 22:41:40 +00:00
|
|
|
return error().error_message();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
bool PosixErrorOr<T>::ok() const {
|
2019-02-26 23:46:39 +00:00
|
|
|
return absl::holds_alternative<T>(value_);
|
2018-12-10 22:41:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
2018-12-12 01:04:42 +00:00
|
|
|
const T& PosixErrorOr<T>::ValueOrDie() const& {
|
2018-12-10 22:41:40 +00:00
|
|
|
TEST_CHECK(absl::holds_alternative<T>(value_));
|
|
|
|
return absl::get<T>(value_);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
2018-12-12 01:04:42 +00:00
|
|
|
T& PosixErrorOr<T>::ValueOrDie() & {
|
2018-12-10 22:41:40 +00:00
|
|
|
TEST_CHECK(absl::holds_alternative<T>(value_));
|
|
|
|
return absl::get<T>(value_);
|
|
|
|
}
|
|
|
|
|
2018-12-12 01:04:42 +00:00
|
|
|
template <typename T>
|
|
|
|
const T&& PosixErrorOr<T>::ValueOrDie() const&& {
|
|
|
|
TEST_CHECK(absl::holds_alternative<T>(value_));
|
|
|
|
return std::move(absl::get<T>(value_));
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
T&& PosixErrorOr<T>::ValueOrDie() && {
|
|
|
|
TEST_CHECK(absl::holds_alternative<T>(value_));
|
|
|
|
return std::move(absl::get<T>(value_));
|
|
|
|
}
|
|
|
|
|
2018-12-10 22:41:40 +00:00
|
|
|
extern ::std::ostream& operator<<(::std::ostream& os, const PosixError& e);
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
::std::ostream& operator<<(::std::ostream& os, const PosixErrorOr<T>& e) {
|
|
|
|
os << e.error();
|
|
|
|
return os;
|
|
|
|
}
|
|
|
|
|
|
|
|
// NoError is a PosixError that represents a successful state, i.e. No Error.
|
|
|
|
inline PosixError NoError() { return PosixError(); }
|
|
|
|
|
|
|
|
// Monomorphic implementation of matcher IsPosixErrorOk() for a given type T.
|
|
|
|
// T can be PosixError, PosixErrorOr<>, or a reference to either of them.
|
|
|
|
template <typename T>
|
|
|
|
class MonoPosixErrorIsOkMatcherImpl : public ::testing::MatcherInterface<T> {
|
|
|
|
public:
|
|
|
|
void DescribeTo(std::ostream* os) const override { *os << "is OK"; }
|
|
|
|
void DescribeNegationTo(std::ostream* os) const override {
|
|
|
|
*os << "is not OK";
|
|
|
|
}
|
|
|
|
bool MatchAndExplain(T actual_value,
|
|
|
|
::testing::MatchResultListener*) const override {
|
|
|
|
return actual_value.ok();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Implements IsPosixErrorOkMatcher() as a polymorphic matcher.
|
|
|
|
class IsPosixErrorOkMatcher {
|
|
|
|
public:
|
|
|
|
template <typename T>
|
|
|
|
operator ::testing::Matcher<T>() const { // NOLINT
|
|
|
|
return MakeMatcher(new MonoPosixErrorIsOkMatcherImpl<T>());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Monomorphic implementation of a matcher for a PosixErrorOr.
|
|
|
|
template <typename PosixErrorOrType>
|
|
|
|
class IsPosixErrorOkAndHoldsMatcherImpl
|
|
|
|
: public ::testing::MatcherInterface<PosixErrorOrType> {
|
|
|
|
public:
|
|
|
|
using ValueType = typename std::remove_reference<decltype(
|
|
|
|
std::declval<PosixErrorOrType>().ValueOrDie())>::type;
|
|
|
|
|
|
|
|
template <typename InnerMatcher>
|
|
|
|
explicit IsPosixErrorOkAndHoldsMatcherImpl(InnerMatcher&& inner_matcher)
|
|
|
|
: inner_matcher_(::testing::SafeMatcherCast<const ValueType&>(
|
|
|
|
std::forward<InnerMatcher>(inner_matcher))) {}
|
|
|
|
|
|
|
|
void DescribeTo(std::ostream* os) const override {
|
|
|
|
*os << "is OK and has a value that ";
|
|
|
|
inner_matcher_.DescribeTo(os);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DescribeNegationTo(std::ostream* os) const override {
|
|
|
|
*os << "isn't OK or has a value that ";
|
|
|
|
inner_matcher_.DescribeNegationTo(os);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MatchAndExplain(
|
|
|
|
PosixErrorOrType actual_value,
|
|
|
|
::testing::MatchResultListener* listener) const override {
|
2019-02-26 23:46:39 +00:00
|
|
|
// We can't extract the value if it doesn't contain one.
|
2018-12-10 22:41:40 +00:00
|
|
|
if (!actual_value.ok()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
::testing::StringMatchResultListener inner_listener;
|
|
|
|
const bool matches = inner_matcher_.MatchAndExplain(
|
|
|
|
actual_value.ValueOrDie(), &inner_listener);
|
|
|
|
const std::string inner_explanation = inner_listener.str();
|
2019-02-26 23:46:39 +00:00
|
|
|
*listener << "has a value "
|
|
|
|
<< ::testing::PrintToString(actual_value.ValueOrDie());
|
|
|
|
|
2018-12-10 22:41:40 +00:00
|
|
|
if (!inner_explanation.empty()) {
|
2019-02-26 23:46:39 +00:00
|
|
|
*listener << " " << inner_explanation;
|
2018-12-10 22:41:40 +00:00
|
|
|
}
|
|
|
|
return matches;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
const ::testing::Matcher<const ValueType&> inner_matcher_;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Implements IsOkAndHolds() as a polymorphic matcher.
|
|
|
|
template <typename InnerMatcher>
|
|
|
|
class IsPosixErrorOkAndHoldsMatcher {
|
|
|
|
public:
|
|
|
|
explicit IsPosixErrorOkAndHoldsMatcher(InnerMatcher inner_matcher)
|
|
|
|
: inner_matcher_(std::move(inner_matcher)) {}
|
|
|
|
|
|
|
|
// Converts this polymorphic matcher to a monomorphic one of the given type.
|
|
|
|
// PosixErrorOrType can be either PosixErrorOr<T> or a reference to
|
|
|
|
// PosixErrorOr<T>.
|
|
|
|
template <typename PosixErrorOrType>
|
|
|
|
operator ::testing::Matcher<PosixErrorOrType>() const { // NOLINT
|
|
|
|
return ::testing::MakeMatcher(
|
|
|
|
new IsPosixErrorOkAndHoldsMatcherImpl<PosixErrorOrType>(
|
|
|
|
inner_matcher_));
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
const InnerMatcher inner_matcher_;
|
|
|
|
};
|
|
|
|
|
|
|
|
// PosixErrorIs() is a polymorphic matcher. This class is the common
|
|
|
|
// implementation of it shared by all types T where PosixErrorIs() can be
|
|
|
|
// used as a Matcher<T>.
|
|
|
|
class PosixErrorIsMatcherCommonImpl {
|
|
|
|
public:
|
|
|
|
PosixErrorIsMatcherCommonImpl(
|
|
|
|
::testing::Matcher<int> code_matcher,
|
|
|
|
::testing::Matcher<const std::string&> message_matcher)
|
|
|
|
: code_matcher_(std::move(code_matcher)),
|
|
|
|
message_matcher_(std::move(message_matcher)) {}
|
|
|
|
|
|
|
|
void DescribeTo(std::ostream* os) const;
|
|
|
|
|
|
|
|
void DescribeNegationTo(std::ostream* os) const;
|
|
|
|
|
|
|
|
bool MatchAndExplain(const PosixError& error,
|
|
|
|
::testing::MatchResultListener* result_listener) const;
|
|
|
|
|
2019-02-26 23:46:39 +00:00
|
|
|
template <typename T>
|
|
|
|
bool MatchAndExplain(const PosixErrorOr<T>& error_or,
|
|
|
|
::testing::MatchResultListener* result_listener) const {
|
|
|
|
if (error_or.ok()) {
|
|
|
|
*result_listener << "has a value "
|
|
|
|
<< ::testing::PrintToString(error_or.ValueOrDie());
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return MatchAndExplain(error_or.error(), result_listener);
|
|
|
|
}
|
|
|
|
|
2018-12-10 22:41:40 +00:00
|
|
|
private:
|
|
|
|
const ::testing::Matcher<int> code_matcher_;
|
|
|
|
const ::testing::Matcher<const std::string&> message_matcher_;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Monomorphic implementation of matcher PosixErrorIs() for a given type
|
|
|
|
// T. T can be PosixError, PosixErrorOr<>, or a reference to either of them.
|
|
|
|
template <typename T>
|
|
|
|
class MonoPosixErrorIsMatcherImpl : public ::testing::MatcherInterface<T> {
|
|
|
|
public:
|
|
|
|
explicit MonoPosixErrorIsMatcherImpl(
|
|
|
|
PosixErrorIsMatcherCommonImpl common_impl)
|
|
|
|
: common_impl_(std::move(common_impl)) {}
|
|
|
|
|
|
|
|
void DescribeTo(std::ostream* os) const override {
|
|
|
|
common_impl_.DescribeTo(os);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DescribeNegationTo(std::ostream* os) const override {
|
|
|
|
common_impl_.DescribeNegationTo(os);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MatchAndExplain(
|
|
|
|
T actual_value,
|
|
|
|
::testing::MatchResultListener* result_listener) const override {
|
2019-02-26 23:46:39 +00:00
|
|
|
return common_impl_.MatchAndExplain(actual_value, result_listener);
|
2018-12-10 22:41:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
PosixErrorIsMatcherCommonImpl common_impl_;
|
|
|
|
};
|
|
|
|
|
|
|
|
inline ::testing::Matcher<int> ToErrorCodeMatcher(
|
|
|
|
const ::testing::Matcher<int>& m) {
|
|
|
|
return m;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Implements PosixErrorIs() as a polymorphic matcher.
|
|
|
|
class PosixErrorIsMatcher {
|
|
|
|
public:
|
|
|
|
template <typename ErrorCodeMatcher>
|
|
|
|
PosixErrorIsMatcher(ErrorCodeMatcher&& code_matcher,
|
|
|
|
::testing::Matcher<const std::string&> message_matcher)
|
|
|
|
: common_impl_(
|
|
|
|
ToErrorCodeMatcher(std::forward<ErrorCodeMatcher>(code_matcher)),
|
|
|
|
std::move(message_matcher)) {}
|
|
|
|
|
|
|
|
// Converts this polymorphic matcher to a monomorphic matcher of the
|
|
|
|
// given type. T can be StatusOr<>, Status, or a reference to
|
|
|
|
// either of them.
|
|
|
|
template <typename T>
|
|
|
|
operator ::testing::Matcher<T>() const { // NOLINT
|
|
|
|
return MakeMatcher(new MonoPosixErrorIsMatcherImpl<T>(common_impl_));
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
const PosixErrorIsMatcherCommonImpl common_impl_;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Returns a gMock matcher that matches a PosixError or PosixErrorOr<> whose
|
|
|
|
// whose error code matches code_matcher, and whose error message matches
|
|
|
|
// message_matcher.
|
|
|
|
template <typename ErrorCodeMatcher>
|
|
|
|
PosixErrorIsMatcher PosixErrorIs(
|
|
|
|
ErrorCodeMatcher&& code_matcher,
|
|
|
|
::testing::Matcher<const std::string&> message_matcher) {
|
|
|
|
return PosixErrorIsMatcher(std::forward<ErrorCodeMatcher>(code_matcher),
|
|
|
|
std::move(message_matcher));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Returns a gMock matcher that matches a PosixErrorOr<> which is ok() and
|
|
|
|
// value matches the inner matcher.
|
|
|
|
template <typename InnerMatcher>
|
|
|
|
IsPosixErrorOkAndHoldsMatcher<typename std::decay<InnerMatcher>::type>
|
|
|
|
IsPosixErrorOkAndHolds(InnerMatcher&& inner_matcher) {
|
|
|
|
return IsPosixErrorOkAndHoldsMatcher<typename std::decay<InnerMatcher>::type>(
|
|
|
|
std::forward<InnerMatcher>(inner_matcher));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Internal helper for concatenating macro values.
|
|
|
|
#define POSIX_ERROR_IMPL_CONCAT_INNER_(x, y) x##y
|
|
|
|
#define POSIX_ERROR_IMPL_CONCAT_(x, y) POSIX_ERROR_IMPL_CONCAT_INNER_(x, y)
|
|
|
|
|
|
|
|
#define POSIX_ERROR_IMPL_ASSIGN_OR_RETURN_(posixerroror, lhs, rexpr) \
|
|
|
|
auto posixerroror = (rexpr); \
|
|
|
|
if (!posixerroror.ok()) { \
|
|
|
|
return (posixerroror.error()); \
|
|
|
|
} \
|
2018-12-12 01:04:42 +00:00
|
|
|
lhs = std::move(posixerroror).ValueOrDie()
|
2018-12-10 22:41:40 +00:00
|
|
|
|
|
|
|
#define EXPECT_NO_ERRNO(expression) \
|
|
|
|
EXPECT_THAT(expression, IsPosixErrorOkMatcher())
|
|
|
|
#define ASSERT_NO_ERRNO(expression) \
|
|
|
|
ASSERT_THAT(expression, IsPosixErrorOkMatcher())
|
|
|
|
|
|
|
|
#define ASSIGN_OR_RETURN_ERRNO(lhs, rexpr) \
|
|
|
|
POSIX_ERROR_IMPL_ASSIGN_OR_RETURN_( \
|
|
|
|
POSIX_ERROR_IMPL_CONCAT_(_status_or_value, __LINE__), lhs, rexpr)
|
|
|
|
|
|
|
|
#define RETURN_IF_ERRNO(s) \
|
|
|
|
do { \
|
2019-01-24 02:23:39 +00:00
|
|
|
if (!s.ok()) { \
|
|
|
|
return s; \
|
|
|
|
} \
|
2018-12-10 22:41:40 +00:00
|
|
|
} while (false);
|
|
|
|
|
|
|
|
#define ASSERT_NO_ERRNO_AND_VALUE(expr) \
|
|
|
|
({ \
|
|
|
|
auto _expr_result = (expr); \
|
|
|
|
ASSERT_NO_ERRNO(_expr_result); \
|
2018-12-12 01:04:42 +00:00
|
|
|
std::move(_expr_result).ValueOrDie(); \
|
2018-12-10 22:41:40 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
} // namespace testing
|
|
|
|
} // namespace gvisor
|
|
|
|
|
|
|
|
#endif // GVISOR_TEST_UTIL_POSIX_ERROR_H_
|