[libc-commits] [libc] [llvm] [libc] Convert readv, writev, and read_write tests to use pipes (PR #210725)
Pavel Labath via libc-commits
libc-commits at lists.llvm.org
Fri Jul 24 00:18:12 PDT 2026
https://github.com/labath updated https://github.com/llvm/llvm-project/pull/210725
>From 311c0d33276963be285fe4105c85135f80bb0a2c Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Mon, 20 Jul 2026 13:58:24 +0000
Subject: [PATCH 1/2] [libc] Convert readv, writev, and read_write tests to use
pipes
Using a pipe avoids races between "hermetic" and "unit" versions of the same
test and avoids leaving filesystem artifacts around if the test fails.
If I'm successful, we won't have the worry about the first problem anymore, but
I think it's still a nice cleanup.
Assisted by Gemini.
---
libc/test/src/sys/uio/CMakeLists.txt | 7 +++--
libc/test/src/sys/uio/readv_test.cpp | 21 ++++++---------
libc/test/src/sys/uio/writev_test.cpp | 23 +++++++++-------
libc/test/src/unistd/CMakeLists.txt | 5 +---
libc/test/src/unistd/read_write_test.cpp | 26 +++++--------------
.../libc/test/src/unistd/BUILD.bazel | 5 +---
6 files changed, 34 insertions(+), 53 deletions(-)
diff --git a/libc/test/src/sys/uio/CMakeLists.txt b/libc/test/src/sys/uio/CMakeLists.txt
index 7ba02be5d1cc4..7ae4810e9aaae 100644
--- a/libc/test/src/sys/uio/CMakeLists.txt
+++ b/libc/test/src/sys/uio/CMakeLists.txt
@@ -10,10 +10,10 @@ add_libc_unittest(
libc.hdr.types.struct_iovec
libc.src.__support.common
libc.src.errno.errno
- libc.src.fcntl.open
libc.src.sys.uio.writev
libc.src.unistd.close
- libc.src.unistd.unlink
+ libc.src.unistd.pipe
+ libc.src.unistd.read
libc.test.UnitTest.ErrnoSetterMatcher
)
@@ -27,10 +27,9 @@ add_libc_unittest(
libc.hdr.types.struct_iovec
libc.src.__support.common
libc.src.errno.errno
- libc.src.fcntl.open
libc.src.sys.uio.readv
libc.src.unistd.close
- libc.src.unistd.unlink
+ libc.src.unistd.pipe
libc.src.unistd.write
libc.test.UnitTest.ErrnoSetterMatcher
)
diff --git a/libc/test/src/sys/uio/readv_test.cpp b/libc/test/src/sys/uio/readv_test.cpp
index 7cbaa3397d887..b25afc9754688 100644
--- a/libc/test/src/sys/uio/readv_test.cpp
+++ b/libc/test/src/sys/uio/readv_test.cpp
@@ -7,10 +7,9 @@
//===----------------------------------------------------------------------===//
#include "hdr/types/struct_iovec.h"
-#include "src/fcntl/open.h"
#include "src/sys/uio/readv.h"
#include "src/unistd/close.h"
-#include "src/unistd/unlink.h"
+#include "src/unistd/pipe.h"
#include "src/unistd/write.h"
#include "test/UnitTest/ErrnoSetterMatcher.h"
#include "test/UnitTest/Test.h"
@@ -18,16 +17,14 @@
using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
TEST(LlvmLibcSysUioReadvTest, SmokeTest) {
- const char *filename = "./LlvmLibcSysUioReadvTest";
- int fd = LIBC_NAMESPACE::open(filename, O_WRONLY | O_CREAT, 0644);
- ASSERT_THAT(fd, returns(GT(0)).with_errno(EQ(0)));
+ int pipefd[2];
+ ASSERT_THAT(LIBC_NAMESPACE::pipe(pipefd), Succeeds());
+
const char data[] = "Hello, World!\n";
- ASSERT_THAT(LIBC_NAMESPACE::write(fd, data, sizeof(data)),
+ ASSERT_THAT(LIBC_NAMESPACE::write(pipefd[1], data, sizeof(data)),
returns(EQ(sizeof(data))).with_errno(EQ(0)));
- ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds());
+ ASSERT_THAT(LIBC_NAMESPACE::close(pipefd[1]), Succeeds());
- fd = LIBC_NAMESPACE::open(filename, O_RDONLY);
- ASSERT_THAT(fd, returns(GT(0)).with_errno(EQ(0)));
char buf0[2];
char buf1[3];
struct iovec iov[2];
@@ -35,9 +32,7 @@ TEST(LlvmLibcSysUioReadvTest, SmokeTest) {
iov[0].iov_len = 1;
iov[1].iov_base = buf1;
iov[1].iov_len = 2;
- ASSERT_THAT(LIBC_NAMESPACE::readv(fd, iov, 2),
+ ASSERT_THAT(LIBC_NAMESPACE::readv(pipefd[0], iov, 2),
returns(EQ(ssize_t(3))).with_errno(EQ(0)));
- ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds());
- ASSERT_THAT(LIBC_NAMESPACE::unlink(filename),
- returns(EQ(ssize_t(0))).with_errno(EQ(0)));
+ ASSERT_THAT(LIBC_NAMESPACE::close(pipefd[0]), Succeeds());
}
diff --git a/libc/test/src/sys/uio/writev_test.cpp b/libc/test/src/sys/uio/writev_test.cpp
index 69db0de47141c..bf6b04fee0bda 100644
--- a/libc/test/src/sys/uio/writev_test.cpp
+++ b/libc/test/src/sys/uio/writev_test.cpp
@@ -7,28 +7,33 @@
//===----------------------------------------------------------------------===//
#include "hdr/types/struct_iovec.h"
-#include "src/fcntl/open.h"
#include "src/sys/uio/writev.h"
#include "src/unistd/close.h"
-#include "src/unistd/unlink.h"
+#include "src/unistd/pipe.h"
+#include "src/unistd/read.h"
#include "test/UnitTest/ErrnoSetterMatcher.h"
#include "test/UnitTest/Test.h"
using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
TEST(LlvmLibcSysUioWritevTest, SmokeTest) {
- const char *filename = "./LlvmLibcSysUioWritevTest";
- int fd = LIBC_NAMESPACE::open(filename, O_WRONLY | O_CREAT, 0644);
- ASSERT_THAT(fd, returns(GT(0)).with_errno(EQ(0)));
+ int pipefd[2];
+ ASSERT_THAT(LIBC_NAMESPACE::pipe(pipefd), Succeeds());
+
const char *data = "Hello, World!\n";
struct iovec iov[2];
iov[0].iov_base = const_cast<char *>(data);
iov[0].iov_len = 7;
iov[1].iov_base = const_cast<char *>(data + 7);
iov[1].iov_len = 8;
- ASSERT_THAT(LIBC_NAMESPACE::writev(fd, iov, 2),
+ ASSERT_THAT(LIBC_NAMESPACE::writev(pipefd[1], iov, 2),
+ returns(EQ(ssize_t(15))).with_errno(EQ(0)));
+ ASSERT_THAT(LIBC_NAMESPACE::close(pipefd[1]), Succeeds());
+
+ char buf[16];
+ ASSERT_THAT(LIBC_NAMESPACE::read(pipefd[0], buf, 15),
returns(EQ(ssize_t(15))).with_errno(EQ(0)));
- ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds());
- ASSERT_THAT(LIBC_NAMESPACE::unlink(filename),
- returns(EQ(ssize_t(0))).with_errno(EQ(0)));
+ buf[15] = '\0';
+ EXPECT_STREQ(buf, data);
+ ASSERT_THAT(LIBC_NAMESPACE::close(pipefd[0]), Succeeds());
}
diff --git a/libc/test/src/unistd/CMakeLists.txt b/libc/test/src/unistd/CMakeLists.txt
index 070c25f24e61a..93f8888dee19b 100644
--- a/libc/test/src/unistd/CMakeLists.txt
+++ b/libc/test/src/unistd/CMakeLists.txt
@@ -237,15 +237,12 @@ add_libc_unittest(
SRCS
read_write_test.cpp
DEPENDS
- libc.hdr.sys_stat_macros
libc.include.unistd
libc.src.errno.errno
- libc.src.fcntl.open
libc.src.unistd.close
- libc.src.unistd.fsync
+ libc.src.unistd.pipe
libc.src.unistd.read
libc.src.unistd.write
- libc.src.stdio.remove
libc.test.UnitTest.ErrnoCheckingTest
libc.test.UnitTest.ErrnoSetterMatcher
)
diff --git a/libc/test/src/unistd/read_write_test.cpp b/libc/test/src/unistd/read_write_test.cpp
index 17cd4f6ce8b44..7b700154d2f30 100644
--- a/libc/test/src/unistd/read_write_test.cpp
+++ b/libc/test/src/unistd/read_write_test.cpp
@@ -6,11 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#include "hdr/sys_stat_macros.h"
-#include "src/fcntl/open.h"
-#include "src/stdio/remove.h"
#include "src/unistd/close.h"
-#include "src/unistd/fsync.h"
+#include "src/unistd/pipe.h"
#include "src/unistd/read.h"
#include "src/unistd/write.h"
#include "test/UnitTest/ErrnoCheckingTest.h"
@@ -21,29 +18,20 @@ using LlvmLibcUniStd = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
TEST_F(LlvmLibcUniStd, WriteAndReadBackTest) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- constexpr const char *FILENAME = "__unistd_read_write.test";
- auto TEST_FILE = libc_make_test_file_path(FILENAME);
+ int pipefd[2];
+ ASSERT_THAT(LIBC_NAMESPACE::pipe(pipefd), Succeeds(0));
- int write_fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
- ASSERT_ERRNO_SUCCESS();
- ASSERT_GT(write_fd, 0);
constexpr const char HELLO[] = "hello";
constexpr ssize_t HELLO_SIZE = sizeof(HELLO);
- ASSERT_THAT(LIBC_NAMESPACE::write(write_fd, HELLO, HELLO_SIZE),
+ ASSERT_THAT(LIBC_NAMESPACE::write(pipefd[1], HELLO, HELLO_SIZE),
Succeeds(HELLO_SIZE));
- ASSERT_THAT(LIBC_NAMESPACE::fsync(write_fd), Succeeds(0));
- ASSERT_THAT(LIBC_NAMESPACE::close(write_fd), Succeeds(0));
+ ASSERT_THAT(LIBC_NAMESPACE::close(pipefd[1]), Succeeds(0));
- int read_fd = LIBC_NAMESPACE::open(TEST_FILE, O_RDONLY);
- ASSERT_ERRNO_SUCCESS();
- ASSERT_GT(read_fd, 0);
char read_buf[10];
- ASSERT_THAT(LIBC_NAMESPACE::read(read_fd, read_buf, HELLO_SIZE),
+ ASSERT_THAT(LIBC_NAMESPACE::read(pipefd[0], read_buf, HELLO_SIZE),
Succeeds(HELLO_SIZE));
EXPECT_STREQ(read_buf, HELLO);
- ASSERT_THAT(LIBC_NAMESPACE::close(read_fd), Succeeds(0));
-
- ASSERT_THAT(LIBC_NAMESPACE::remove(TEST_FILE), Succeeds(0));
+ ASSERT_THAT(LIBC_NAMESPACE::close(pipefd[0]), Succeeds(0));
}
TEST_F(LlvmLibcUniStd, WriteFails) {
diff --git a/utils/bazel/llvm-project-overlay/libc/test/src/unistd/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/test/src/unistd/BUILD.bazel
index 54006159cee10..6507820ea5679 100644
--- a/utils/bazel/llvm-project-overlay/libc/test/src/unistd/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/test/src/unistd/BUILD.bazel
@@ -107,11 +107,8 @@ libc_test(
srcs = ["read_write_test.cpp"],
deps = [
"//libc:close",
- "//libc:fsync",
- "//libc:hdr_sys_stat_macros",
- "//libc:open",
+ "//libc:pipe",
"//libc:read",
- "//libc:remove",
"//libc:write",
],
)
>From 2876ea9e5b4be3352f318ccd2108448fa449dcd4 Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Mon, 20 Jul 2026 14:12:46 +0000
Subject: [PATCH 2/2] also make them hermetic
---
libc/test/src/sys/uio/CMakeLists.txt | 4 ++--
libc/test/src/unistd/CMakeLists.txt | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/libc/test/src/sys/uio/CMakeLists.txt b/libc/test/src/sys/uio/CMakeLists.txt
index 7ae4810e9aaae..9d8beec1fe5be 100644
--- a/libc/test/src/sys/uio/CMakeLists.txt
+++ b/libc/test/src/sys/uio/CMakeLists.txt
@@ -1,6 +1,6 @@
add_custom_target(libc_sys_uio_unittests)
-add_libc_unittest(
+add_libc_test(
writev_test
SUITE
libc_sys_uio_unittests
@@ -17,7 +17,7 @@ add_libc_unittest(
libc.test.UnitTest.ErrnoSetterMatcher
)
-add_libc_unittest(
+add_libc_test(
readv_test
SUITE
libc_sys_uio_unittests
diff --git a/libc/test/src/unistd/CMakeLists.txt b/libc/test/src/unistd/CMakeLists.txt
index 93f8888dee19b..a25e3a29af95c 100644
--- a/libc/test/src/unistd/CMakeLists.txt
+++ b/libc/test/src/unistd/CMakeLists.txt
@@ -230,7 +230,7 @@ add_libc_unittest(
libc.test.UnitTest.ErrnoSetterMatcher
)
-add_libc_unittest(
+add_libc_test(
read_write_test
SUITE
libc_unistd_unittests
More information about the libc-commits
mailing list