summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--test/syscalls/linux/madvise.cc12
-rw-r--r--test/syscalls/linux/pty.cc11
-rw-r--r--test/syscalls/linux/shm.cc8
-rw-r--r--test/util/logging.cc8
-rw-r--r--test/util/logging.h39
-rw-r--r--test/util/multiprocess_util.h3
-rw-r--r--test/util/posix_error.cc2
-rw-r--r--test/util/posix_error.h14
8 files changed, 68 insertions, 29 deletions
diff --git a/test/syscalls/linux/madvise.cc b/test/syscalls/linux/madvise.cc
index 5a1973f60..6e714b12c 100644
--- a/test/syscalls/linux/madvise.cc
+++ b/test/syscalls/linux/madvise.cc
@@ -179,9 +179,9 @@ TEST(MadviseDontforkTest, DontforkShared) {
// First page is mapped in child and modifications are visible to parent
// via the shared mapping.
TEST_CHECK(IsMapped(ms1.addr()));
- ExpectAllMappingBytes(ms1, 2);
+ CheckAllMappingBytes(ms1, 2);
memset(ms1.ptr(), 1, kPageSize);
- ExpectAllMappingBytes(ms1, 1);
+ CheckAllMappingBytes(ms1, 1);
// Second page must not be mapped in child.
TEST_CHECK(!IsMapped(ms2.addr()));
@@ -222,9 +222,9 @@ TEST(MadviseDontforkTest, DontforkAnonPrivate) {
// page. The mapping is private so the modifications are not visible to
// the parent.
TEST_CHECK(IsMapped(mp1.addr()));
- ExpectAllMappingBytes(mp1, 1);
+ CheckAllMappingBytes(mp1, 1);
memset(mp1.ptr(), 11, kPageSize);
- ExpectAllMappingBytes(mp1, 11);
+ CheckAllMappingBytes(mp1, 11);
// Verify second page is not mapped.
TEST_CHECK(!IsMapped(mp2.addr()));
@@ -233,9 +233,9 @@ TEST(MadviseDontforkTest, DontforkAnonPrivate) {
// page. The mapping is private so the modifications are not visible to
// the parent.
TEST_CHECK(IsMapped(mp3.addr()));
- ExpectAllMappingBytes(mp3, 3);
+ CheckAllMappingBytes(mp3, 3);
memset(mp3.ptr(), 13, kPageSize);
- ExpectAllMappingBytes(mp3, 13);
+ CheckAllMappingBytes(mp3, 13);
};
EXPECT_THAT(InForkedProcess(rest), IsPosixErrorOkAndHolds(0));
diff --git a/test/syscalls/linux/pty.cc b/test/syscalls/linux/pty.cc
index 0b174e2be..85ff258df 100644
--- a/test/syscalls/linux/pty.cc
+++ b/test/syscalls/linux/pty.cc
@@ -1338,6 +1338,7 @@ TEST_F(JobControlTest, SetTTYDifferentSession) {
TEST_PCHECK(waitpid(grandchild, &gcwstatus, 0) == grandchild);
TEST_PCHECK(gcwstatus == 0);
});
+ ASSERT_NO_ERRNO(res);
}
TEST_F(JobControlTest, ReleaseTTY) {
@@ -1515,7 +1516,8 @@ TEST_F(JobControlTest, GetForegroundProcessGroupNonControlling) {
// - creates a child process in a new process group
// - sets that child as the foreground process group
// - kills its child and sets itself as the foreground process group.
-TEST_F(JobControlTest, SetForegroundProcessGroup) {
+// TODO(gvisor.dev/issue/5357): Fix and enable.
+TEST_F(JobControlTest, DISABLED_SetForegroundProcessGroup) {
auto res = RunInChild([=]() {
TEST_PCHECK(!ioctl(replica_.get(), TIOCSCTTY, 0));
@@ -1557,6 +1559,7 @@ TEST_F(JobControlTest, SetForegroundProcessGroup) {
TEST_PCHECK(pgid = getpgid(0) == 0);
TEST_PCHECK(!tcsetpgrp(replica_.get(), pgid));
});
+ ASSERT_NO_ERRNO(res);
}
TEST_F(JobControlTest, SetForegroundProcessGroupWrongTTY) {
@@ -1576,8 +1579,9 @@ TEST_F(JobControlTest, SetForegroundProcessGroupNegPgid) {
ASSERT_NO_ERRNO(ret);
}
-TEST_F(JobControlTest, SetForegroundProcessGroupEmptyProcessGroup) {
- auto ret = RunInChild([=]() {
+// TODO(gvisor.dev/issue/5357): Fix and enable.
+TEST_F(JobControlTest, DISABLED_SetForegroundProcessGroupEmptyProcessGroup) {
+ auto res = RunInChild([=]() {
TEST_PCHECK(!ioctl(replica_.get(), TIOCSCTTY, 0));
// Create a new process, put it in a new process group, make that group the
@@ -1595,6 +1599,7 @@ TEST_F(JobControlTest, SetForegroundProcessGroupEmptyProcessGroup) {
TEST_PCHECK(ioctl(replica_.get(), TIOCSPGRP, &grandchild) != 0 &&
errno == ESRCH);
});
+ ASSERT_NO_ERRNO(res);
}
TEST_F(JobControlTest, SetForegroundProcessGroupDifferentSession) {
diff --git a/test/syscalls/linux/shm.cc b/test/syscalls/linux/shm.cc
index 6aabd79e7..baf794152 100644
--- a/test/syscalls/linux/shm.cc
+++ b/test/syscalls/linux/shm.cc
@@ -372,18 +372,18 @@ TEST(ShmDeathTest, SegmentNotAccessibleAfterDetach) {
SetupGvisorDeathTest();
const auto rest = [&] {
- ShmSegment shm = ASSERT_NO_ERRNO_AND_VALUE(
+ ShmSegment shm = TEST_CHECK_NO_ERRNO_AND_VALUE(
Shmget(IPC_PRIVATE, kAllocSize, IPC_CREAT | 0777));
- char* addr = ASSERT_NO_ERRNO_AND_VALUE(Shmat(shm.id(), nullptr, 0));
+ char* addr = TEST_CHECK_NO_ERRNO_AND_VALUE(Shmat(shm.id(), nullptr, 0));
// Mark the segment as destroyed so it's automatically cleaned up when we
// crash below. We can't rely on the standard cleanup since the destructor
// will not run after the SIGSEGV. Note that this doesn't destroy the
// segment immediately since we're still attached to it.
- ASSERT_NO_ERRNO(shm.Rmid());
+ TEST_CHECK_NO_ERRNO(shm.Rmid());
addr[0] = 'x';
- ASSERT_NO_ERRNO(Shmdt(addr));
+ TEST_CHECK_NO_ERRNO(Shmdt(addr));
// This access should cause a SIGSEGV.
addr[0] = 'x';
diff --git a/test/util/logging.cc b/test/util/logging.cc
index 5d5e76c46..5fadb076b 100644
--- a/test/util/logging.cc
+++ b/test/util/logging.cc
@@ -69,9 +69,7 @@ int WriteNumber(int fd, uint32_t val) {
} // namespace
void CheckFailure(const char* cond, size_t cond_size, const char* msg,
- size_t msg_size, bool include_errno) {
- int saved_errno = errno;
-
+ size_t msg_size, int errno_value) {
constexpr char kCheckFailure[] = "Check failed: ";
Write(2, kCheckFailure, sizeof(kCheckFailure) - 1);
Write(2, cond, cond_size);
@@ -81,10 +79,10 @@ void CheckFailure(const char* cond, size_t cond_size, const char* msg,
Write(2, msg, msg_size);
}
- if (include_errno) {
+ if (errno_value != 0) {
constexpr char kErrnoMessage[] = " (errno ";
Write(2, kErrnoMessage, sizeof(kErrnoMessage) - 1);
- WriteNumber(2, saved_errno);
+ WriteNumber(2, errno_value);
Write(2, ")", 1);
}
diff --git a/test/util/logging.h b/test/util/logging.h
index 589166fab..9d224ea05 100644
--- a/test/util/logging.h
+++ b/test/util/logging.h
@@ -21,7 +21,7 @@ namespace gvisor {
namespace testing {
void CheckFailure(const char* cond, size_t cond_size, const char* msg,
- size_t msg_size, bool include_errno);
+ size_t msg_size, int errno_value);
// If cond is false, aborts the current process.
//
@@ -30,7 +30,7 @@ void CheckFailure(const char* cond, size_t cond_size, const char* msg,
do { \
if (!(cond)) { \
::gvisor::testing::CheckFailure(#cond, sizeof(#cond) - 1, nullptr, \
- 0, false); \
+ 0, 0); \
} \
} while (0)
@@ -41,7 +41,7 @@ void CheckFailure(const char* cond, size_t cond_size, const char* msg,
do { \
if (!(cond)) { \
::gvisor::testing::CheckFailure(#cond, sizeof(#cond) - 1, msg, \
- sizeof(msg) - 1, false); \
+ sizeof(msg) - 1, 0); \
} \
} while (0)
@@ -52,7 +52,7 @@ void CheckFailure(const char* cond, size_t cond_size, const char* msg,
do { \
if (!(cond)) { \
::gvisor::testing::CheckFailure(#cond, sizeof(#cond) - 1, nullptr, \
- 0, true); \
+ 0, errno); \
} \
} while (0)
@@ -63,10 +63,39 @@ void CheckFailure(const char* cond, size_t cond_size, const char* msg,
do { \
if (!(cond)) { \
::gvisor::testing::CheckFailure(#cond, sizeof(#cond) - 1, msg, \
- sizeof(msg) - 1, true); \
+ sizeof(msg) - 1, errno); \
} \
} while (0)
+// expr must return PosixErrorOr<T>. The current process is aborted if
+// !PosixError<T>.ok().
+//
+// This macro is async-signal-safe.
+#define TEST_CHECK_NO_ERRNO(expr) \
+ ({ \
+ auto _expr_result = (expr); \
+ if (!_expr_result.ok()) { \
+ ::gvisor::testing::CheckFailure( \
+ #expr, sizeof(#expr) - 1, nullptr, 0, \
+ _expr_result.error().errno_value()); \
+ } \
+ })
+
+// expr must return PosixErrorOr<T>. The current process is aborted if
+// !PosixError<T>.ok(). Otherwise, PosixErrorOr<T> value is returned.
+//
+// This macro is async-signal-safe.
+#define TEST_CHECK_NO_ERRNO_AND_VALUE(expr) \
+ ({ \
+ auto _expr_result = (expr); \
+ if (!_expr_result.ok()) { \
+ ::gvisor::testing::CheckFailure( \
+ #expr, sizeof(#expr) - 1, nullptr, 0, \
+ _expr_result.error().errno_value()); \
+ } \
+ std::move(_expr_result).ValueOrDie(); \
+ })
+
} // namespace testing
} // namespace gvisor
diff --git a/test/util/multiprocess_util.h b/test/util/multiprocess_util.h
index 2f3bf4a6f..840fde4ee 100644
--- a/test/util/multiprocess_util.h
+++ b/test/util/multiprocess_util.h
@@ -123,7 +123,8 @@ inline PosixErrorOr<Cleanup> ForkAndExecveat(int32_t dirfd,
// Calls fn in a forked subprocess and returns the exit status of the
// subprocess.
//
-// fn must be async-signal-safe.
+// fn must be async-signal-safe. Use of ASSERT/EXPECT functions is prohibited.
+// Use TEST_CHECK variants instead.
PosixErrorOr<int> InForkedProcess(const std::function<void()>& fn);
} // namespace testing
diff --git a/test/util/posix_error.cc b/test/util/posix_error.cc
index deed0c05b..8522e4c81 100644
--- a/test/util/posix_error.cc
+++ b/test/util/posix_error.cc
@@ -50,7 +50,7 @@ std::string PosixError::ToString() const {
ret = absl::StrCat("PosixError(errno=", errno_, " ", res, ")");
#endif
- if (!msg_.empty()) {
+ if (strnlen(msg_, sizeof(msg_)) > 0) {
ret.append(" ");
ret.append(msg_);
}
diff --git a/test/util/posix_error.h b/test/util/posix_error.h
index b634a7f78..27557ad44 100644
--- a/test/util/posix_error.h
+++ b/test/util/posix_error.h
@@ -26,12 +26,18 @@
namespace gvisor {
namespace testing {
+// PosixError must be async-signal-safe.
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(int errno_value, std::string_view msg) : errno_(errno_value) {
+ // Check that `msg` will fit, leaving room for '\0' at the end.
+ TEST_CHECK(msg.size() < sizeof(msg_));
+ msg.copy(msg_, msg.size());
+ }
PosixError(PosixError&& other) = default;
PosixError& operator=(PosixError&& other) = default;
@@ -45,7 +51,7 @@ class ABSL_MUST_USE_RESULT PosixError {
const PosixError& error() const { return *this; }
int errno_value() const { return errno_; }
- std::string message() const { return msg_; }
+ const char* message() const { return msg_; }
// ToString produces a full string representation of this posix error
// including the printable representation of the errno and the error message.
@@ -58,7 +64,7 @@ class ABSL_MUST_USE_RESULT PosixError {
private:
int errno_ = 0;
- std::string msg_;
+ char msg_[1024] = {};
};
template <typename T>