Repository: llvm/llvm-project
Pull request #132067: [libc] Migrate unistd tests to use ErrnoCheckingTest.
Author: login: vonosmas
Labels: name: libc
name: bazel
description: "Peripheral" support tier build system: utils/bazel
Created: 2025-03-19T17:32:14Z | Merged: 2025-03-19T20:29:53Z

Use ErrnoCheckingTest harness added in d039af33096c0a83b03475a240d5e281e2271c44 for all unistd tests that verify errno values. Stop explicitly setting it to zero in test code, as harness does it.

It also verifies that the errno is zero at the end of each test case, so update the ASSERT_ERRNO_EQ and ASSERT_ERRNO_FAILURE macro to clear out its value after the verification (similar to how ErrnoSetterMatcher does).

Update the CMake and Bazel rules for those tests. In the latter case, remove commented out tests that are currently unsupported in Bazel, since they get stale quickly.


Diff:
diff --git a/libc/test/UnitTest/Test.h b/libc/test/UnitTest/Test.h
index c7729606000c4..95d48f40914ed 100644
--- a/libc/test/UnitTest/Test.h
+++ b/libc/test/UnitTest/Test.h
@@ -41,10 +41,16 @@
 // they all provide.
 
 #define ASSERT_ERRNO_EQ(VAL)                                                   \
-  ASSERT_EQ(VAL, static_cast<int>(LIBC_NAMESPACE::libc_errno))
+  do {                                                                         \
+    ASSERT_EQ(VAL, static_cast<int>(LIBC_NAMESPACE::libc_errno));              \
+    LIBC_NAMESPACE::libc_errno = 0;                                            \
+  } while (0)
 #define ASSERT_ERRNO_SUCCESS()                                                 \
   ASSERT_EQ(0, static_cast<int>(LIBC_NAMESPACE::libc_errno))
 #define ASSERT_ERRNO_FAILURE()                                                 \
-  ASSERT_NE(0, static_cast<int>(LIBC_NAMESPACE::libc_errno))
+  do {                                                                         \
+    ASSERT_NE(0, static_cast<int>(LIBC_NAMESPACE::libc_errno));                \
+    LIBC_NAMESPACE::libc_errno = 0;                                            \
+  } while (0)
 
 #endif // LLVM_LIBC_TEST_UNITTEST_TEST_H
diff --git a/libc/test/src/unistd/CMakeLists.txt b/libc/test/src/unistd/CMakeLists.txt
index c31a03d4b27a5..9aec6150af0ec 100644
--- a/libc/test/src/unistd/CMakeLists.txt
+++ b/libc/test/src/unistd/CMakeLists.txt
@@ -15,6 +15,8 @@ add_libc_unittest(
     libc.src.unistd.access
     libc.src.unistd.close
     libc.src.unistd.unlink
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_unittest(
@@ -30,6 +32,7 @@ add_libc_unittest(
     libc.src.unistd.chdir
     libc.src.unistd.close
     libc.src.fcntl.open
+    libc.test.UnitTest.ErrnoCheckingTest
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
@@ -48,6 +51,7 @@ add_libc_unittest(
     libc.src.unistd.read
     libc.src.unistd.unlink
     libc.src.unistd.write
+    libc.test.UnitTest.ErrnoCheckingTest
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
@@ -66,6 +70,7 @@ add_libc_unittest(
     libc.src.unistd.read
     libc.src.unistd.unlink
     libc.src.unistd.write
+    libc.test.UnitTest.ErrnoCheckingTest
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
@@ -84,6 +89,7 @@ add_libc_unittest(
     libc.src.unistd.read
     libc.src.unistd.unlink
     libc.src.unistd.write
+    libc.test.UnitTest.ErrnoCheckingTest
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
@@ -99,6 +105,7 @@ add_libc_unittest(
     libc.src.fcntl.open
     libc.src.unistd.fchdir
     libc.src.unistd.close
+    libc.test.UnitTest.ErrnoCheckingTest
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
@@ -118,6 +125,8 @@ add_libc_unittest(
     libc.src.unistd.unlink
     libc.src.unistd.write
     libc.src.__support.CPP.string_view
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_unittest(
@@ -136,6 +145,7 @@ add_libc_unittest(
     libc.src.unistd.pwrite
     libc.src.unistd.unlink
     libc.src.unistd.write
+    libc.test.UnitTest.ErrnoCheckingTest
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
@@ -154,6 +164,7 @@ add_libc_unittest(
     libc.src.unistd.read
     libc.src.unistd.write
     libc.src.stdio.remove
+    libc.test.UnitTest.ErrnoCheckingTest
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
@@ -170,6 +181,8 @@ add_libc_unittest(
     libc.src.unistd.close
     libc.src.unistd.link
     libc.src.unistd.unlink
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_unittest(
@@ -185,6 +198,8 @@ add_libc_unittest(
     libc.src.unistd.close
     libc.src.unistd.linkat
     libc.src.unistd.unlink
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_unittest(
@@ -200,6 +215,7 @@ add_libc_unittest(
     libc.src.unistd.close
     libc.src.unistd.lseek
     libc.src.unistd.read
+    libc.test.UnitTest.ErrnoCheckingTest
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
@@ -214,6 +230,7 @@ add_libc_unittest(
     libc.src.errno.errno
     libc.src.unistd.close
     libc.src.unistd.pipe
+    libc.test.UnitTest.ErrnoCheckingTest
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
@@ -228,6 +245,7 @@ add_libc_unittest(
     libc.src.errno.errno
     libc.src.unistd.close
     libc.src.unistd.pipe2
+    libc.test.UnitTest.ErrnoCheckingTest
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
@@ -242,6 +260,8 @@ add_libc_unittest(
     libc.src.errno.errno
     libc.src.sys.stat.mkdir
     libc.src.unistd.rmdir
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_unittest(
@@ -268,6 +288,8 @@ add_libc_unittest(
     libc.src.unistd.symlink
     libc.src.unistd.unlink
     libc.src.__support.CPP.string_view
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_unittest(
@@ -285,6 +307,8 @@ add_libc_unittest(
     libc.src.unistd.symlink
     libc.src.unistd.unlink
     libc.src.__support.CPP.string_view
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_unittest(
@@ -310,6 +334,8 @@ add_libc_unittest(
     libc.src.unistd.close
     libc.src.unistd.symlink
     libc.src.unistd.unlink
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_unittest(
@@ -325,6 +351,8 @@ add_libc_unittest(
     libc.src.unistd.close
     libc.src.unistd.symlinkat
     libc.src.unistd.unlink
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_unittest(
@@ -343,6 +371,8 @@ add_libc_unittest(
     libc.src.unistd.unlink
     libc.src.unistd.write
     libc.src.__support.CPP.string_view
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_unittest(
@@ -374,6 +404,8 @@ add_libc_unittest(
     libc.src.fcntl.openat
     libc.src.unistd.close
     libc.src.unistd.unlinkat
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_unittest(
@@ -404,6 +436,8 @@ add_libc_unittest(
     getsid_test.cpp
   DEPENDS
     libc.src.unistd.getsid
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_unittest(
@@ -427,6 +461,8 @@ add_libc_unittest(
     libc.src.fcntl.open
     libc.src.unistd.close
     libc.src.errno.errno
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_unittest(
@@ -451,6 +487,7 @@ add_libc_unittest(
     libc.include.sys_syscall
     libc.src.errno.errno
     libc.src.unistd.__llvm_libc_syscall
+    libc.test.UnitTest.ErrnoCheckingTest
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
@@ -479,6 +516,8 @@ add_libc_unittest(
     libc.src.unistd.fpathconf
     libc.src.fcntl.open
     libc.src.unistd.close
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_unittest(
@@ -494,6 +533,8 @@ add_libc_unittest(
     libc.src.unistd.pathconf
     libc.src.fcntl.open
     libc.src.unistd.close
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_test(
@@ -519,6 +560,7 @@ add_libc_test(
   DEPENDS
     libc.src.unistd.getentropy
     libc.src.errno.errno
+    libc.test.UnitTest.ErrnoCheckingTest
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
diff --git a/libc/test/src/unistd/access_test.cpp b/libc/test/src/unistd/access_test.cpp
index 0643b2b992a5c..693f15c767e5e 100644
--- a/libc/test/src/unistd/access_test.cpp
+++ b/libc/test/src/unistd/access_test.cpp
@@ -6,21 +6,23 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/errno/libc_errno.h"
 #include "src/fcntl/open.h"
 #include "src/unistd/access.h"
 #include "src/unistd/close.h"
 #include "src/unistd/unlink.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 #include <sys/stat.h>
 #include <unistd.h>
 
-TEST(LlvmLibcAccessTest, CreateAndTest) {
+using LlvmLibcAccessTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcAccessTest, CreateAndTest) {
   // The test strategy is to repeatedly create a file in different modes and
   // test that it is accessable in those modes but not in others.
-  LIBC_NAMESPACE::libc_errno = 0;
+  using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
   constexpr const char *FILENAME = "access.test";
   auto TEST_FILE = libc_make_test_file_path(FILENAME);
@@ -29,30 +31,23 @@ TEST(LlvmLibcAccessTest, CreateAndTest) {
   ASSERT_GT(fd, 0);
   ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
 
-  ASSERT_EQ(LIBC_NAMESPACE::access(TEST_FILE, F_OK), 0);
-  ASSERT_ERRNO_SUCCESS();
-  ASSERT_EQ(LIBC_NAMESPACE::access(TEST_FILE, X_OK | W_OK | R_OK), 0);
-  ASSERT_ERRNO_SUCCESS();
+  ASSERT_THAT(LIBC_NAMESPACE::access(TEST_FILE, F_OK), Succeeds(0));
+  ASSERT_THAT(LIBC_NAMESPACE::access(TEST_FILE, X_OK | W_OK | R_OK),
+              Succeeds(0));
   ASSERT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE), Succeeds(0));
 
   fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IXUSR);
   ASSERT_ERRNO_SUCCESS();
   ASSERT_GT(fd, 0);
   ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
-  ASSERT_EQ(LIBC_NAMESPACE::access(TEST_FILE, F_OK), 0);
-  ASSERT_ERRNO_SUCCESS();
-  ASSERT_EQ(LIBC_NAMESPACE::access(TEST_FILE, X_OK), 0);
-  ASSERT_ERRNO_SUCCESS();
-  ASSERT_EQ(LIBC_NAMESPACE::access(TEST_FILE, R_OK), -1);
-  ASSERT_ERRNO_EQ(EACCES);
-  LIBC_NAMESPACE::libc_errno = 0;
-  ASSERT_EQ(LIBC_NAMESPACE::access(TEST_FILE, W_OK), -1);
-  ASSERT_ERRNO_EQ(EACCES);
-  LIBC_NAMESPACE::libc_errno = 0;
+  ASSERT_THAT(LIBC_NAMESPACE::access(TEST_FILE, F_OK), Succeeds(0));
+  ASSERT_THAT(LIBC_NAMESPACE::access(TEST_FILE, X_OK), Succeeds(0));
+  ASSERT_THAT(LIBC_NAMESPACE::access(TEST_FILE, R_OK), Fails(EACCES));
+  ASSERT_THAT(LIBC_NAMESPACE::access(TEST_FILE, W_OK), Fails(EACCES));
   ASSERT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE), Succeeds(0));
 }
 
-TEST(LlvmLibcAccessTest, AccessNonExistentFile) {
+TEST_F(LlvmLibcAccessTest, AccessNonExistentFile) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
   ASSERT_THAT(LIBC_NAMESPACE::access("testdata/non-existent-file", F_OK),
               Fails(ENOENT));
diff --git a/libc/test/src/unistd/chdir_test.cpp b/libc/test/src/unistd/chdir_test.cpp
index e1bdcd77119f7..ac5217bbd2461 100644
--- a/libc/test/src/unistd/chdir_test.cpp
+++ b/libc/test/src/unistd/chdir_test.cpp
@@ -6,16 +6,18 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/errno/libc_errno.h"
 #include "src/fcntl/open.h"
 #include "src/unistd/chdir.h"
 #include "src/unistd/close.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 #include "hdr/fcntl_macros.h"
 
-TEST(LlvmLibcChdirTest, ChangeAndOpen) {
+using LlvmLibcChdirTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcChdirTest, ChangeAndOpen) {
   // The idea of this test is that we will first open an existing test file
   // without changing the directory to make sure it exists. Next, we change
   // directory and open the same file to make sure that the "chdir" operation
@@ -27,7 +29,6 @@ TEST(LlvmLibcChdirTest, ChangeAndOpen) {
   auto TEST_FILE = libc_make_test_file_path(FILENAME2);
   constexpr const char *FILENAME3 = "chdir.test";
   auto TEST_FILE_BASE = libc_make_test_file_path(FILENAME3);
-  LIBC_NAMESPACE::libc_errno = 0;
 
   int fd = LIBC_NAMESPACE::open(TEST_FILE, O_PATH);
   ASSERT_GT(fd, 0);
@@ -41,9 +42,7 @@ TEST(LlvmLibcChdirTest, ChangeAndOpen) {
   ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
 }
 
-TEST(LlvmLibcChdirTest, ChangeToNonExistentDir) {
-  LIBC_NAMESPACE::libc_errno = 0;
+TEST_F(LlvmLibcChdirTest, ChangeToNonExistentDir) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
   ASSERT_THAT(LIBC_NAMESPACE::chdir("non-existent-dir"), Fails(ENOENT));
-  LIBC_NAMESPACE::libc_errno = 0;
 }
diff --git a/libc/test/src/unistd/dup2_test.cpp b/libc/test/src/unistd/dup2_test.cpp
index 2b2b3f3eef9a8..f6d546def33ec 100644
--- a/libc/test/src/unistd/dup2_test.cpp
+++ b/libc/test/src/unistd/dup2_test.cpp
@@ -6,21 +6,22 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/errno/libc_errno.h"
 #include "src/fcntl/open.h"
 #include "src/unistd/close.h"
 #include "src/unistd/dup2.h"
 #include "src/unistd/read.h"
 #include "src/unistd/unlink.h"
 #include "src/unistd/write.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 #include <sys/stat.h>
 
-TEST(LlvmLibcdupTest, ReadAndWriteViaDup) {
+using LlvmLibcdupTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcdupTest, ReadAndWriteViaDup) {
   constexpr int DUPFD = 0xD0;
-  LIBC_NAMESPACE::libc_errno = 0;
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
   constexpr const char *FILENAME = "dup2.test";
   auto TEST_FILE = libc_make_test_file_path(FILENAME);
@@ -59,7 +60,7 @@ TEST(LlvmLibcdupTest, ReadAndWriteViaDup) {
   ASSERT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE), Succeeds(0));
 }
 
-TEST(LlvmLibcdupTest, DupBadFD) {
+TEST_F(LlvmLibcdupTest, DupBadFD) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
   ASSERT_THAT(LIBC_NAMESPACE::dup2(-1, 123), Fails(EBADF));
 }
diff --git a/libc/test/src/unistd/dup3_test.cpp b/libc/test/src/unistd/dup3_test.cpp
index 7b1c8e0e25190..598940b1c456d 100644
--- a/libc/test/src/unistd/dup3_test.cpp
+++ b/libc/test/src/unistd/dup3_test.cpp
@@ -6,26 +6,27 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/errno/libc_errno.h"
 #include "src/fcntl/open.h"
 #include "src/unistd/close.h"
 #include "src/unistd/dup3.h"
 #include "src/unistd/read.h"
 #include "src/unistd/unlink.h"
 #include "src/unistd/write.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 #include <sys/stat.h>
 
+using LlvmLibcdupTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
 // The tests here are exactly the same as those of dup2. We only test the
 // plumbing of the dup3 syscall and not the dup3 functionality itself as it is
 // a simple syscall wrapper. Testing dup3 functionality is beyond the scope of
 // this test.
 
-TEST(LlvmLibcdupTest, ReadAndWriteViaDup) {
+TEST_F(LlvmLibcdupTest, ReadAndWriteViaDup) {
   constexpr int DUPFD = 0xD0;
-  LIBC_NAMESPACE::libc_errno = 0;
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
   constexpr const char *FILENAME = "dup3.test";
@@ -65,7 +66,7 @@ TEST(LlvmLibcdupTest, ReadAndWriteViaDup) {
   ASSERT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE), Succeeds(0));
 }
 
-TEST(LlvmLibcdupTest, DupBadFD) {
+TEST_F(LlvmLibcdupTest, DupBadFD) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
   ASSERT_THAT(LIBC_NAMESPACE::dup3(-1, 123, 0), Fails(EBADF));
 }
diff --git a/libc/test/src/unistd/dup_test.cpp b/libc/test/src/unistd/dup_test.cpp
index c7bf877142102..8e0b662c3961b 100644
--- a/libc/test/src/unistd/dup_test.cpp
+++ b/libc/test/src/unistd/dup_test.cpp
@@ -6,20 +6,21 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/errno/libc_errno.h"
 #include "src/fcntl/open.h"
 #include "src/unistd/close.h"
 #include "src/unistd/dup.h"
 #include "src/unistd/read.h"
 #include "src/unistd/unlink.h"
 #include "src/unistd/write.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 #include <sys/stat.h>
 
-TEST(LlvmLibcdupTest, ReadAndWriteViaDup) {
-  LIBC_NAMESPACE::libc_errno = 0;
+using LlvmLibcdupTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcdupTest, ReadAndWriteViaDup) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
   constexpr const char *FILENAME = "dup.test";
   auto TEST_FILE = libc_make_test_file_path(FILENAME);
@@ -55,7 +56,7 @@ TEST(LlvmLibcdupTest, ReadAndWriteViaDup) {
   ASSERT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE), Succeeds(0));
 }
 
-TEST(LlvmLibcdupTest, DupBadFD) {
+TEST_F(LlvmLibcdupTest, DupBadFD) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
   ASSERT_THAT(LIBC_NAMESPACE::dup(-1), Fails(EBADF));
 }
diff --git a/libc/test/src/unistd/fchdir_test.cpp b/libc/test/src/unistd/fchdir_test.cpp
index 0e39fde17c67b..add56484a8e85 100644
--- a/libc/test/src/unistd/fchdir_test.cpp
+++ b/libc/test/src/unistd/fchdir_test.cpp
@@ -6,16 +6,18 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/errno/libc_errno.h"
 #include "src/fcntl/open.h"
 #include "src/unistd/close.h"
 #include "src/unistd/fchdir.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 #include "hdr/fcntl_macros.h"
 
-TEST(LlvmLibcChdirTest, ChangeAndOpen) {
+using LlvmLibcChdirTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcChdirTest, ChangeAndOpen) {
   // The idea of this test is that we will first open an existing test file
   // without changing the directory to make sure it exists. Next, we change
   // directory and open the same file to make sure that the "fchdir" operation
@@ -27,7 +29,6 @@ TEST(LlvmLibcChdirTest, ChangeAndOpen) {
   auto TEST_FILE = libc_make_test_file_path(FILENAME2);
   constexpr const char *FILENAME3 = "fchdir.test";
   auto TEST_FILE_BASE = libc_make_test_file_path(FILENAME3);
-  LIBC_NAMESPACE::libc_errno = 0;
 
   int dir_fd = LIBC_NAMESPACE::open(TEST_DIR, O_DIRECTORY);
   ASSERT_GT(dir_fd, 0);
@@ -45,10 +46,7 @@ TEST(LlvmLibcChdirTest, ChangeAndOpen) {
   ASSERT_THAT(LIBC_NAMESPACE::close(dir_fd), Succeeds(0));
 }
 
-TEST(LlvmLibcChdirTest, ChangeToNonExistentDir) {
-  using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
-  LIBC_NAMESPACE::libc_errno = 0;
+TEST_F(LlvmLibcChdirTest, ChangeToNonExistentDir) {
   ASSERT_EQ(LIBC_NAMESPACE::fchdir(0), -1);
   ASSERT_ERRNO_FAILURE();
-  LIBC_NAMESPACE::libc_errno = 0;
 }
diff --git a/libc/test/src/unistd/fpathconf_test.cpp b/libc/test/src/unistd/fpathconf_test.cpp
index fe63e5e085973..3cba7ec5c66a8 100644
--- a/libc/test/src/unistd/fpathconf_test.cpp
+++ b/libc/test/src/unistd/fpathconf_test.cpp
@@ -12,19 +12,24 @@
 #include "src/fcntl/open.h"
 #include "src/unistd/close.h"
 #include "src/unistd/fpathconf.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
+using LlvmLibcFpathconfTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
 
-TEST(LlvmLibcPipeTest, SmokeTest) {
+TEST_F(LlvmLibcFpathconfTest, SmokeTest) {
   constexpr const char *FILENAME = "fpathconf.test";
   auto TEST_FILE = libc_make_test_file_path(FILENAME);
   int fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
+  ASSERT_ERRNO_SUCCESS();
+  ASSERT_GT(fd, 0);
+
   EXPECT_EQ(LIBC_NAMESPACE::fpathconf(fd, _PC_SYNC_IO), -1l);
   EXPECT_EQ(LIBC_NAMESPACE::fpathconf(fd, _PC_PATH_MAX),
             static_cast<long>(_POSIX_PATH_MAX));
-  LIBC_NAMESPACE::close(fd);
+  ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
 }
 
 // TODO: Functionality tests
diff --git a/libc/test/src/unistd/ftruncate_test.cpp b/libc/test/src/unistd/ftruncate_test.cpp
index 2fe4002692a87..c50a07f15f1e0 100644
--- a/libc/test/src/unistd/ftruncate_test.cpp
+++ b/libc/test/src/unistd/ftruncate_test.cpp
@@ -7,21 +7,22 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/__support/CPP/string_view.h"
-#include "src/errno/libc_errno.h"
 #include "src/fcntl/open.h"
 #include "src/unistd/close.h"
 #include "src/unistd/ftruncate.h"
 #include "src/unistd/read.h"
 #include "src/unistd/unlink.h"
 #include "src/unistd/write.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 #include <sys/stat.h>
 
 namespace cpp = LIBC_NAMESPACE::cpp;
+using LlvmLibcFtruncateTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
 
-TEST(LlvmLibcFtruncateTest, CreateAndTruncate) {
+TEST_F(LlvmLibcFtruncateTest, CreateAndTruncate) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
   constexpr const char *FILENAME = "ftruncate.test";
   auto TEST_FILE = libc_make_test_file_path(FILENAME);
@@ -34,7 +35,6 @@ TEST(LlvmLibcFtruncateTest, CreateAndTruncate) {
   //   2. Read it to make sure what was written is actually in the file.
   //   3. Truncate to 1 byte.
   //   4. Try to read more than 1 byte and fail.
-  LIBC_NAMESPACE::libc_errno = 0;
   int fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
   ASSERT_ERRNO_SUCCESS();
   ASSERT_GT(fd, 0);
@@ -67,7 +67,7 @@ TEST(LlvmLibcFtruncateTest, CreateAndTruncate) {
   ASSERT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE), Succeeds(0));
 }
 
-TEST(LlvmLibcFtruncateTest, TruncateBadFD) {
+TEST_F(LlvmLibcFtruncateTest, TruncateBadFD) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
   ASSERT_THAT(LIBC_NAMESPACE::ftruncate(0, off_t(1)), Fails(EINVAL));
 }
diff --git a/libc/test/src/unistd/getentropy_test.cpp b/libc/test/src/unistd/getentropy_test.cpp
index f7329ae419327..a4177560432d5 100644
--- a/libc/test/src/unistd/getentropy_test.cpp
+++ b/libc/test/src/unistd/getentropy_test.cpp
@@ -8,21 +8,23 @@
 
 #include "hdr/errno_macros.h"
 #include "src/unistd/getentropy.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
+using LlvmLibcUnistdGetEntropyTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
 
-TEST(LlvmLibcUnistdGetEntropyTest, LengthTooLong) {
+TEST_F(LlvmLibcUnistdGetEntropyTest, LengthTooLong) {
   char buf[1024];
   ASSERT_THAT(LIBC_NAMESPACE::getentropy(buf, 257), Fails(EIO));
 }
 
-TEST(LlvmLibcUnistdGetEntropyTest, SmokeTest) {
+TEST_F(LlvmLibcUnistdGetEntropyTest, SmokeTest) {
   char buf[256];
   ASSERT_THAT(LIBC_NAMESPACE::getentropy(buf, 256), Succeeds());
 }
 
-TEST(LlvmLibcUnistdGetEntropyTest, OtherError) {
+TEST_F(LlvmLibcUnistdGetEntropyTest, OtherError) {
   ASSERT_THAT(LIBC_NAMESPACE::getentropy(nullptr, 1), Fails(EIO));
 }
diff --git a/libc/test/src/unistd/getsid_test.cpp b/libc/test/src/unistd/getsid_test.cpp
index b3e8d54b14dcb..e9973487c9f27 100644
--- a/libc/test/src/unistd/getsid_test.cpp
+++ b/libc/test/src/unistd/getsid_test.cpp
@@ -6,11 +6,13 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/errno/libc_errno.h"
 #include "src/unistd/getsid.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/Test.h"
 
-TEST(LlvmLibcGetPidTest, GetCurrSID) {
+using LlvmLibcGetSidTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcGetSidTest, GetCurrSID) {
   pid_t sid = LIBC_NAMESPACE::getsid(0);
   ASSERT_NE(sid, -1);
   ASSERT_ERRNO_SUCCESS();
diff --git a/libc/test/src/unistd/isatty_test.cpp b/libc/test/src/unistd/isatty_test.cpp
index c20eead46c060..63a0bf7e059b0 100644
--- a/libc/test/src/unistd/isatty_test.cpp
+++ b/libc/test/src/unistd/isatty_test.cpp
@@ -6,10 +6,10 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/errno/libc_errno.h"
 #include "src/fcntl/open.h"
 #include "src/unistd/close.h"
 #include "src/unistd/isatty.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
@@ -17,11 +17,11 @@
 
 using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
 using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
+using LlvmLibcIsATTYTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
 
-TEST(LlvmLibcIsATTYTest, StdInOutTests) {
+TEST_F(LlvmLibcIsATTYTest, StdInOutTests) {
   // If stdin is connected to a terminal, assume that all of the standard i/o
   // fds are.
-  LIBC_NAMESPACE::libc_errno = 0;
   if (LIBC_NAMESPACE::isatty(0)) {
     EXPECT_THAT(LIBC_NAMESPACE::isatty(0), Succeeds(1)); // stdin
     EXPECT_THAT(LIBC_NAMESPACE::isatty(1), Succeeds(1)); // stdout
@@ -33,27 +33,26 @@ TEST(LlvmLibcIsATTYTest, StdInOutTests) {
   }
 }
 
-TEST(LlvmLibcIsATTYTest, BadFdTest) {
-  LIBC_NAMESPACE::libc_errno = 0;
+TEST_F(LlvmLibcIsATTYTest, BadFdTest) {
   EXPECT_THAT(LIBC_NAMESPACE::isatty(-1), Fails(EBADF, 0)); // invalid fd
 }
 
-TEST(LlvmLibcIsATTYTest, DevTTYTest) {
+TEST_F(LlvmLibcIsATTYTest, DevTTYTest) {
   constexpr const char *FILENAME = "/dev/tty";
   auto TTY_FILE = libc_make_test_file_path(FILENAME);
-  LIBC_NAMESPACE::libc_errno = 0;
   int fd = LIBC_NAMESPACE::open(TTY_FILE, O_RDONLY);
   if (fd > 0) {
     ASSERT_ERRNO_SUCCESS();
     EXPECT_THAT(LIBC_NAMESPACE::isatty(fd), Succeeds(1));
     ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
+  } else {
+    ASSERT_ERRNO_FAILURE();
   }
 }
 
-TEST(LlvmLibcIsATTYTest, FileTest) {
+TEST_F(LlvmLibcIsATTYTest, FileTest) {
   constexpr const char *FILENAME = "isatty.test";
   auto TEST_FILE = libc_make_test_file_path(FILENAME);
-  LIBC_NAMESPACE::libc_errno = 0;
   int fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
   ASSERT_ERRNO_SUCCESS();
   ASSERT_GT(fd, 0);
diff --git a/libc/test/src/unistd/link_test.cpp b/libc/test/src/unistd/link_test.cpp
index 3f1af2ec63f57..e91edd55e67ca 100644
--- a/libc/test/src/unistd/link_test.cpp
+++ b/libc/test/src/unistd/link_test.cpp
@@ -6,17 +6,19 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/errno/libc_errno.h"
 #include "src/fcntl/open.h"
 #include "src/unistd/close.h"
 #include "src/unistd/link.h"
 #include "src/unistd/unlink.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 #include <sys/stat.h>
 
-TEST(LlvmLibcLinkTest, CreateAndUnlink) {
+using LlvmLibcLinkTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcLinkTest, CreateAndUnlink) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
   constexpr const char *FILENAME = "link.test";
   auto TEST_FILE = libc_make_test_file_path(FILENAME);
@@ -28,7 +30,6 @@ TEST(LlvmLibcLinkTest, CreateAndUnlink) {
   //   2. Create a link to that file.
   //   3. Open the link to check that the link was created.
   //   4. Cleanup the file and its link.
-  LIBC_NAMESPACE::libc_errno = 0;
   int write_fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
   ASSERT_ERRNO_SUCCESS();
   ASSERT_GT(write_fd, 0);
@@ -44,7 +45,7 @@ TEST(LlvmLibcLinkTest, CreateAndUnlink) {
   ASSERT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE_LINK), Succeeds(0));
 }
 
-TEST(LlvmLibcLinkTest, LinkToNonExistentFile) {
+TEST_F(LlvmLibcLinkTest, LinkToNonExistentFile) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
   ASSERT_THAT(LIBC_NAMESPACE::link("non-existent-file", "bad-link"),
               Fails(ENOENT));
diff --git a/libc/test/src/unistd/linkat_test.cpp b/libc/test/src/unistd/linkat_test.cpp
index c6e4575604289..1d8290832b027 100644
--- a/libc/test/src/unistd/linkat_test.cpp
+++ b/libc/test/src/unistd/linkat_test.cpp
@@ -6,17 +6,19 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/errno/libc_errno.h"
 #include "src/fcntl/open.h"
 #include "src/unistd/close.h"
 #include "src/unistd/linkat.h"
 #include "src/unistd/unlink.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 #include <sys/stat.h>
 
-TEST(LlvmLibcLinkatTest, CreateAndUnlink) {
+using LlvmLibcLinkatTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcLinkatTest, CreateAndUnlink) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
   constexpr const char *FILENAME = "testdata";
   auto TEST_DIR = libc_make_test_file_path(FILENAME);
@@ -34,7 +36,6 @@ TEST(LlvmLibcLinkatTest, CreateAndUnlink) {
   //   2. Create a link to that file.
   //   3. Open the link to check that the link was created.
   //   4. Cleanup the file and its link.
-  LIBC_NAMESPACE::libc_errno = 0;
   int write_fd =
       LIBC_NAMESPACE::open(TEST_FILE_PATH, O_WRONLY | O_CREAT, S_IRWXU);
   ASSERT_ERRNO_SUCCESS();
@@ -56,7 +57,7 @@ TEST(LlvmLibcLinkatTest, CreateAndUnlink) {
   ASSERT_THAT(LIBC_NAMESPACE::close(dir_fd), Succeeds(0));
 }
 
-TEST(LlvmLibcLinkatTest, LinkToNonExistentFile) {
+TEST_F(LlvmLibcLinkatTest, LinkToNonExistentFile) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
   ASSERT_THAT(LIBC_NAMESPACE::linkat(AT_FDCWD, "testdata/non-existent-file",
                                      AT_FDCWD, "testdata/bad-link", 0),
diff --git a/libc/test/src/unistd/lseek_test.cpp b/libc/test/src/unistd/lseek_test.cpp
index 7a147f2b83a31..66268ca5ff11a 100644
--- a/libc/test/src/unistd/lseek_test.cpp
+++ b/libc/test/src/unistd/lseek_test.cpp
@@ -6,17 +6,19 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/errno/libc_errno.h"
 #include "src/fcntl/open.h"
 #include "src/unistd/close.h"
 #include "src/unistd/lseek.h"
 #include "src/unistd/read.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 #include <unistd.h>
 
-TEST(LlvmLibcUniStd, LseekTest) {
+using LlvmLibcUniStd = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcUniStd, LseekTest) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
   constexpr const char *FILENAME = "testdata/lseek.test";
   auto TEST_FILE = libc_make_test_file_path(FILENAME);
@@ -50,7 +52,7 @@ TEST(LlvmLibcUniStd, LseekTest) {
   ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
 }
 
-TEST(LlvmLibcUniStd, LseekFailsTest) {
+TEST_F(LlvmLibcUniStd, LseekFailsTest) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
   constexpr const char *FILENAME = "testdata/lseek.test";
diff --git a/libc/test/src/unistd/pathconf_test.cpp b/libc/test/src/unistd/pathconf_test.cpp
index 3dc4b2c6027cb..5529774ac253a 100644
--- a/libc/test/src/unistd/pathconf_test.cpp
+++ b/libc/test/src/unistd/pathconf_test.cpp
@@ -12,19 +12,24 @@
 #include "src/fcntl/open.h"
 #include "src/unistd/close.h"
 #include "src/unistd/pathconf.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
+using LlvmLibcPathconfTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
 
-TEST(LlvmLibcPipeTest, SmokeTest) {
+TEST_F(LlvmLibcPathconfTest, SmokeTest) {
   constexpr const char *FILENAME = "pathconf.test";
   auto TEST_FILE = libc_make_test_file_path(FILENAME);
   int fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
+  ASSERT_ERRNO_SUCCESS();
+  ASSERT_GT(fd, 0);
+
   EXPECT_EQ(LIBC_NAMESPACE::pathconf(FILENAME, _PC_SYNC_IO), -1l);
   EXPECT_EQ(LIBC_NAMESPACE::pathconf(FILENAME, _PC_PATH_MAX),
             static_cast<long>(_POSIX_PATH_MAX));
-  LIBC_NAMESPACE::close(fd);
+  ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
 }
 
 // TODO: Functionality tests
diff --git a/libc/test/src/unistd/pipe2_test.cpp b/libc/test/src/unistd/pipe2_test.cpp
index 795ec784e81cb..db35c34aa6817 100644
--- a/libc/test/src/unistd/pipe2_test.cpp
+++ b/libc/test/src/unistd/pipe2_test.cpp
@@ -5,23 +5,24 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-#include "src/errno/libc_errno.h"
 #include "src/unistd/close.h"
 #include "src/unistd/pipe2.h"
 
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
+using LlvmLibcPipe2Test = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
 
-TEST(LlvmLibcPipe2Test, SmokeTest) {
+TEST_F(LlvmLibcPipe2Test, SucceedsSmokeTest) {
   int pipefd[2];
   ASSERT_THAT(LIBC_NAMESPACE::pipe2(pipefd, 0), Succeeds());
   ASSERT_THAT(LIBC_NAMESPACE::close(pipefd[0]), Succeeds());
   ASSERT_THAT(LIBC_NAMESPACE::close(pipefd[1]), Succeeds());
 }
 
-TEST(LlvmLibcPipe2ErrTest, SmokeTest) {
+TEST_F(LlvmLibcPipe2Test, FailsSmokeTest) {
   int pipefd[2];
   ASSERT_THAT(LIBC_NAMESPACE::pipe2(pipefd, -1), Fails(EINVAL));
   ASSERT_THAT(LIBC_NAMESPACE::pipe2(nullptr, 0), Fails(EFAULT));
diff --git a/libc/test/src/unistd/pipe_test.cpp b/libc/test/src/unistd/pipe_test.cpp
index 9c633dea1dba5..9c6d9f661b20c 100644
--- a/libc/test/src/unistd/pipe_test.cpp
+++ b/libc/test/src/unistd/pipe_test.cpp
@@ -8,12 +8,14 @@
 #include "src/unistd/close.h"
 #include "src/unistd/pipe.h"
 
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
+using LlvmLibcPipeTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
 
-TEST(LlvmLibcPipeTest, SmokeTest) {
+TEST_F(LlvmLibcPipeTest, SmokeTest) {
 
   int pipefd[2];
 
diff --git a/libc/test/src/unistd/pread_pwrite_test.cpp b/libc/test/src/unistd/pread_pwrite_test.cpp
index 397a0da1327a5..7cbac04b60a95 100644
--- a/libc/test/src/unistd/pread_pwrite_test.cpp
+++ b/libc/test/src/unistd/pread_pwrite_test.cpp
@@ -6,7 +6,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/errno/libc_errno.h"
 #include "src/fcntl/open.h"
 #include "src/unistd/close.h"
 #include "src/unistd/fsync.h"
@@ -14,12 +13,15 @@
 #include "src/unistd/pwrite.h"
 #include "src/unistd/unlink.h"
 #include "src/unistd/write.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 #include <sys/stat.h>
 
-TEST(LlvmLibcUniStd, PWriteAndPReadBackTest) {
+using LlvmLibcUniStd = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcUniStd, PWriteAndPReadBackTest) {
   // The strategy here is that we first create a file and write to it. Next,
   // we open that file again and write at an offset. Finally, we open the
   // file again and pread at an offset and make sure that only expected data
@@ -65,12 +67,12 @@ TEST(LlvmLibcUniStd, PWriteAndPReadBackTest) {
   ASSERT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE), Succeeds(0));
 }
 
-TEST(LlvmLibcUniStd, PWriteFails) {
+TEST_F(LlvmLibcUniStd, PWriteFails) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
   EXPECT_THAT(LIBC_NAMESPACE::pwrite(-1, "", 1, 0), Fails<ssize_t>(EBADF));
 }
 
-TEST(LlvmLibcUniStd, PReadFails) {
+TEST_F(LlvmLibcUniStd, PReadFails) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
   EXPECT_THAT(LIBC_NAMESPACE::pread(-1, nullptr, 1, 0), Fails<ssize_t>(EBADF));
 }
diff --git a/libc/test/src/unistd/read_write_test.cpp b/libc/test/src/unistd/read_write_test.cpp
index ba3aeff02042d..8952e6083f97d 100644
--- a/libc/test/src/unistd/read_write_test.cpp
+++ b/libc/test/src/unistd/read_write_test.cpp
@@ -6,19 +6,21 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/errno/libc_errno.h"
 #include "src/fcntl/open.h"
 #include "src/stdio/remove.h"
 #include "src/unistd/close.h"
 #include "src/unistd/fsync.h"
 #include "src/unistd/read.h"
 #include "src/unistd/write.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 #include <sys/stat.h>
 
-TEST(LlvmLibcUniStd, WriteAndReadBackTest) {
+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);
@@ -45,7 +47,7 @@ TEST(LlvmLibcUniStd, WriteAndReadBackTest) {
   ASSERT_THAT(LIBC_NAMESPACE::remove(TEST_FILE), Succeeds(0));
 }
 
-TEST(LlvmLibcUniStd, WriteFails) {
+TEST_F(LlvmLibcUniStd, WriteFails) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
 
   EXPECT_THAT(LIBC_NAMESPACE::write(-1, "", 1), Fails<ssize_t>(EBADF));
@@ -53,7 +55,7 @@ TEST(LlvmLibcUniStd, WriteFails) {
               Fails<ssize_t>(EFAULT));
 }
 
-TEST(LlvmLibcUniStd, ReadFails) {
+TEST_F(LlvmLibcUniStd, ReadFails) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
 
   EXPECT_THAT(LIBC_NAMESPACE::read(-1, nullptr, 1), Fails<ssize_t>(EBADF));
diff --git a/libc/test/src/unistd/readlink_test.cpp b/libc/test/src/unistd/readlink_test.cpp
index ffc05000a2e61..25c58a51e5b5e 100644
--- a/libc/test/src/unistd/readlink_test.cpp
+++ b/libc/test/src/unistd/readlink_test.cpp
@@ -7,23 +7,23 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/__support/CPP/string_view.h"
-#include "src/errno/libc_errno.h"
 #include "src/string/string_utils.h"
 #include "src/unistd/readlink.h"
 #include "src/unistd/symlink.h"
 #include "src/unistd/unlink.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 namespace cpp = LIBC_NAMESPACE::cpp;
+using LlvmLibcReadlinkTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
 
-TEST(LlvmLibcReadlinkTest, CreateAndUnlink) {
+TEST_F(LlvmLibcReadlinkTest, CreateAndUnlink) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
   constexpr const char *FILENAME = "readlink_test_file";
   auto LINK_VAL = libc_make_test_file_path(FILENAME);
   constexpr const char *FILENAME2 = "readlink_test_file.link";
   auto LINK = libc_make_test_file_path(FILENAME2);
-  LIBC_NAMESPACE::libc_errno = 0;
 
   // The test strategy is as follows:
   //   1. Create a symlink with value LINK_VAL.
@@ -40,7 +40,7 @@ TEST(LlvmLibcReadlinkTest, CreateAndUnlink) {
   ASSERT_THAT(LIBC_NAMESPACE::unlink(LINK), Succeeds(0));
 }
 
-TEST(LlvmLibcReadlinkTest, ReadlinkInNonExistentPath) {
+TEST_F(LlvmLibcReadlinkTest, ReadlinkInNonExistentPath) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
   constexpr auto LEN = 8;
   char buf[LEN];
diff --git a/libc/test/src/unistd/readlinkat_test.cpp b/libc/test/src/unistd/readlinkat_test.cpp
index a62fde5a0ac54..e2e71883f716e 100644
--- a/libc/test/src/unistd/readlinkat_test.cpp
+++ b/libc/test/src/unistd/readlinkat_test.cpp
@@ -7,25 +7,25 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/__support/CPP/string_view.h"
-#include "src/errno/libc_errno.h"
 #include "src/string/string_utils.h"
 #include "src/unistd/readlinkat.h"
 #include "src/unistd/symlink.h"
 #include "src/unistd/unlink.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 #include "hdr/fcntl_macros.h"
 
 namespace cpp = LIBC_NAMESPACE::cpp;
+using LlvmLibcReadlinkatTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
 
-TEST(LlvmLibcReadlinkatTest, CreateAndUnlink) {
+TEST_F(LlvmLibcReadlinkatTest, CreateAndUnlink) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
   constexpr const char *FILENAME = "readlinkat_test_file";
   auto LINK_VAL = libc_make_test_file_path(FILENAME);
   constexpr const char *FILENAME2 = "readlinkat_test_file.link";
   auto LINK = libc_make_test_file_path(FILENAME2);
-  LIBC_NAMESPACE::libc_errno = 0;
 
   // The test strategy is as follows:
   //   1. Create a symlink with value LINK_VAL.
@@ -42,7 +42,7 @@ TEST(LlvmLibcReadlinkatTest, CreateAndUnlink) {
   ASSERT_THAT(LIBC_NAMESPACE::unlink(LINK), Succeeds(0));
 }
 
-TEST(LlvmLibcReadlinkatTest, ReadlinkInNonExistentPath) {
+TEST_F(LlvmLibcReadlinkatTest, ReadlinkInNonExistentPath) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
   constexpr auto LEN = 8;
   char buf[LEN];
diff --git a/libc/test/src/unistd/rmdir_test.cpp b/libc/test/src/unistd/rmdir_test.cpp
index 4f4cd94c5cf0b..860cf1ce87ddb 100644
--- a/libc/test/src/unistd/rmdir_test.cpp
+++ b/libc/test/src/unistd/rmdir_test.cpp
@@ -6,15 +6,17 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/errno/libc_errno.h"
 #include "src/sys/stat/mkdir.h"
 #include "src/unistd/rmdir.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 #include "hdr/fcntl_macros.h"
 
-TEST(LlvmLibcRmdirTest, CreateAndRemove) {
+using LlvmLibcRmdirTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcRmdirTest, CreateAndRemove) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
   constexpr const char *FILENAME = "rmdir.testdir";
   auto TEST_DIR = libc_make_test_file_path(FILENAME);
@@ -22,7 +24,7 @@ TEST(LlvmLibcRmdirTest, CreateAndRemove) {
   ASSERT_THAT(LIBC_NAMESPACE::rmdir(TEST_DIR), Succeeds(0));
 }
 
-TEST(LlvmLibcRmdirTest, RemoveNonExistentDir) {
+TEST_F(LlvmLibcRmdirTest, RemoveNonExistentDir) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
   ASSERT_THAT(LIBC_NAMESPACE::rmdir("non-existent-dir"), Fails(ENOENT));
 }
diff --git a/libc/test/src/unistd/symlink_test.cpp b/libc/test/src/unistd/symlink_test.cpp
index 9e8b81c38269b..1cc90becb5fd3 100644
--- a/libc/test/src/unistd/symlink_test.cpp
+++ b/libc/test/src/unistd/symlink_test.cpp
@@ -6,17 +6,19 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/errno/libc_errno.h"
 #include "src/fcntl/open.h"
 #include "src/unistd/close.h"
 #include "src/unistd/symlink.h"
 #include "src/unistd/unlink.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 #include <sys/stat.h>
 
-TEST(LlvmLibcSymlinkTest, CreateAndUnlink) {
+using LlvmLibcSymlinkTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcSymlinkTest, CreateAndUnlink) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
   constexpr const char *FILENAME = "symlink.test";
   auto TEST_FILE_BASE = libc_make_test_file_path(FILENAME);
@@ -30,7 +32,6 @@ TEST(LlvmLibcSymlinkTest, CreateAndUnlink) {
   //   2. Create a symlink to that file.
   //   3. Open the symlink to check that the symlink was created.
   //   4. Cleanup the file and its symlink.
-  LIBC_NAMESPACE::libc_errno = 0;
   int write_fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
   ASSERT_ERRNO_SUCCESS();
   ASSERT_GT(write_fd, 0);
@@ -48,7 +49,7 @@ TEST(LlvmLibcSymlinkTest, CreateAndUnlink) {
   ASSERT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE_LINK), Succeeds(0));
 }
 
-TEST(LlvmLibcSymlinkTest, SymlinkInNonExistentPath) {
+TEST_F(LlvmLibcSymlinkTest, SymlinkInNonExistentPath) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
   ASSERT_THAT(LIBC_NAMESPACE::symlink("non-existent-dir/non-existent-file",
                                       "non-existent-dir/bad-symlink"),
diff --git a/libc/test/src/unistd/symlinkat_test.cpp b/libc/test/src/unistd/symlinkat_test.cpp
index b6588a988b797..85970be6e2286 100644
--- a/libc/test/src/unistd/symlinkat_test.cpp
+++ b/libc/test/src/unistd/symlinkat_test.cpp
@@ -6,17 +6,19 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/errno/libc_errno.h"
 #include "src/fcntl/open.h"
 #include "src/unistd/close.h"
 #include "src/unistd/symlinkat.h"
 #include "src/unistd/unlink.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 #include <sys/stat.h>
 
-TEST(LlvmLibcSymlinkatTest, CreateAndUnlink) {
+using LlvmLibcSymlinkatTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcSymlinkatTest, CreateAndUnlink) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
   constexpr const char *FILENAME = "testdata";
   auto TEST_DIR = libc_make_test_file_path(FILENAME);
@@ -34,7 +36,6 @@ TEST(LlvmLibcSymlinkatTest, CreateAndUnlink) {
   //   2. Create a link to that file.
   //   3. Open the link to check that the link was created.
   //   4. Cleanup the file and its link.
-  LIBC_NAMESPACE::libc_errno = 0;
   int write_fd =
       LIBC_NAMESPACE::open(TEST_FILE_PATH, O_WRONLY | O_CREAT, S_IRWXU);
   ASSERT_ERRNO_SUCCESS();
@@ -55,7 +56,7 @@ TEST(LlvmLibcSymlinkatTest, CreateAndUnlink) {
   ASSERT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE_PATH), Succeeds(0));
 }
 
-TEST(LlvmLibcSymlinkatTest, SymlinkInNonExistentPath) {
+TEST_F(LlvmLibcSymlinkatTest, SymlinkInNonExistentPath) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
   ASSERT_THAT(LIBC_NAMESPACE::symlinkat("non-existent-dir/non-existent-file",
                                         AT_FDCWD, "non-existent-dir/bad-link"),
diff --git a/libc/test/src/unistd/syscall_test.cpp b/libc/test/src/unistd/syscall_test.cpp
index b5a775a9a672c..85caef297cab3 100644
--- a/libc/test/src/unistd/syscall_test.cpp
+++ b/libc/test/src/unistd/syscall_test.cpp
@@ -6,8 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/errno/libc_errno.h"
 #include "src/unistd/syscall.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
@@ -17,6 +17,7 @@
 #include <unistd.h>
 
 using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
+using LlvmLibcSyscallTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
 
 // We only do a smoke test here. Actual functionality tests are
 // done by the unit tests of the syscall wrappers like mmap.
@@ -26,14 +27,12 @@ using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
 // set up the arguments properly. We still need to specify the namespace though
 // because the macro generates a call to the actual internal function
 // (__llvm_libc_syscall) which is inside the namespace.
-TEST(LlvmLibcSyscallTest, TrivialCall) {
-  LIBC_NAMESPACE::libc_errno = 0;
-
+TEST_F(LlvmLibcSyscallTest, TrivialCall) {
   ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_gettid), 0l);
   ASSERT_ERRNO_SUCCESS();
 }
 
-TEST(LlvmLibcSyscallTest, SymlinkCreateDestroy) {
+TEST_F(LlvmLibcSyscallTest, SymlinkCreateDestroy) {
   constexpr const char LINK_VAL[] = "syscall_readlink_test_value";
   constexpr const char LINK[] = "testdata/syscall_readlink.test.link";
 
@@ -68,7 +67,7 @@ TEST(LlvmLibcSyscallTest, SymlinkCreateDestroy) {
   ASSERT_ERRNO_SUCCESS();
 }
 
-TEST(LlvmLibcSyscallTest, FileReadWrite) {
+TEST_F(LlvmLibcSyscallTest, FileReadWrite) {
   constexpr const char HELLO[] = "hello";
   constexpr int HELLO_SIZE = sizeof(HELLO);
 
@@ -97,7 +96,7 @@ TEST(LlvmLibcSyscallTest, FileReadWrite) {
   ASSERT_ERRNO_SUCCESS();
 }
 
-TEST(LlvmLibcSyscallTest, FileLinkCreateDestroy) {
+TEST_F(LlvmLibcSyscallTest, FileLinkCreateDestroy) {
   constexpr const char *TEST_DIR = "testdata";
   constexpr const char *TEST_FILE = "syscall_linkat.test";
   constexpr const char *TEST_FILE_PATH = "testdata/syscall_linkat.test";
diff --git a/libc/test/src/unistd/truncate_test.cpp b/libc/test/src/unistd/truncate_test.cpp
index 261dd63d2afc4..0af3b63e66871 100644
--- a/libc/test/src/unistd/truncate_test.cpp
+++ b/libc/test/src/unistd/truncate_test.cpp
@@ -7,13 +7,13 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/__support/CPP/string_view.h"
-#include "src/errno/libc_errno.h"
 #include "src/fcntl/open.h"
 #include "src/unistd/close.h"
 #include "src/unistd/read.h"
 #include "src/unistd/truncate.h"
 #include "src/unistd/unlink.h"
 #include "src/unistd/write.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
@@ -21,7 +21,9 @@
 
 namespace cpp = LIBC_NAMESPACE::cpp;
 
-TEST(LlvmLibcTruncateTest, CreateAndTruncate) {
+using LlvmLibcTruncateTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcTruncateTest, CreateAndTruncate) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
   constexpr const char *FILENAME = "truncate.test";
   auto TEST_FILE = libc_make_test_file_path(FILENAME);
@@ -34,7 +36,6 @@ TEST(LlvmLibcTruncateTest, CreateAndTruncate) {
   //   2. Read it to make sure what was written is actually in the file.
   //   3. Truncate to 1 byte.
   //   4. Try to read more than 1 byte and fail.
-  LIBC_NAMESPACE::libc_errno = 0;
   int fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
   ASSERT_ERRNO_SUCCESS();
   ASSERT_GT(fd, 0);
@@ -61,7 +62,7 @@ TEST(LlvmLibcTruncateTest, CreateAndTruncate) {
   ASSERT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE), Succeeds(0));
 }
 
-TEST(LlvmLibcTruncateTest, TruncateNonExistentFile) {
+TEST_F(LlvmLibcTruncateTest, TruncateNonExistentFile) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
   ASSERT_THAT(
       LIBC_NAMESPACE::truncate("non-existent-dir/non-existent-file", off_t(1)),
diff --git a/libc/test/src/unistd/unlinkat_test.cpp b/libc/test/src/unistd/unlinkat_test.cpp
index 2d64a996e6444..e862ad1142095 100644
--- a/libc/test/src/unistd/unlinkat_test.cpp
+++ b/libc/test/src/unistd/unlinkat_test.cpp
@@ -6,17 +6,19 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/errno/libc_errno.h"
 #include "src/fcntl/open.h"
 #include "src/fcntl/openat.h"
 #include "src/unistd/close.h"
 #include "src/unistd/unlinkat.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 #include <sys/stat.h>
 
-TEST(LlvmLibcUnlinkatTest, CreateAndDeleteTest) {
+using LlvmLibcUnlinkatTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcUnlinkatTest, CreateAndDeleteTest) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
   constexpr const char *FILENAME = "testdata";
   auto TEST_DIR = libc_make_test_file_path(FILENAME);
@@ -34,7 +36,7 @@ TEST(LlvmLibcUnlinkatTest, CreateAndDeleteTest) {
   ASSERT_THAT(LIBC_NAMESPACE::close(dir_fd), Succeeds(0));
 }
 
-TEST(LlvmLibcUnlinkatTest, UnlinkatNonExistentFile) {
+TEST_F(LlvmLibcUnlinkatTest, UnlinkatNonExistentFile) {
   constexpr const char *FILENAME = "testdata";
   auto TEST_DIR = libc_make_test_file_path(FILENAME);
   int dir_fd = LIBC_NAMESPACE::open(TEST_DIR, O_DIRECTORY);
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 0d6601633956f..62641889f9a72 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
@@ -19,18 +19,11 @@ libc_test(
         "//libc:close",
         "//libc:unlink",
     ],
+    deps = [
+        "//libc/test/UnitTest:errno_test_helpers",
+    ],
 )
 
-# libc_test(
-#     name = "chdir_test",
-#     srcs = ["chdir_test.cpp"],
-#     libc_function_deps = [
-#         "//libc:open",
-#         "//libc:chdir",
-#         "//libc:close",
-#     ],
-# )
-
 libc_test(
     name = "dup_test",
     srcs = ["dup_test.cpp"],
@@ -42,6 +35,9 @@ libc_test(
         "//libc:unlink",
         "//libc:write",
     ],
+    deps = [
+        "//libc/test/UnitTest:errno_test_helpers",
+    ],
 )
 
 libc_test(
@@ -55,6 +51,9 @@ libc_test(
         "//libc:unlink",
         "//libc:write",
     ],
+    deps = [
+        "//libc/test/UnitTest:errno_test_helpers",
+    ],
 )
 
 libc_test(
@@ -68,18 +67,11 @@ libc_test(
         "//libc:unlink",
         "//libc:write",
     ],
+    deps = [
+        "//libc/test/UnitTest:errno_test_helpers",
+    ],
 )
 
-# libc_test(
-#     name = "fchdir_test",
-#     srcs = ["fchdir_test.cpp"],
-#     libc_function_deps = [
-#         "//libc:open",
-#         "//libc:fchdir",
-#         "//libc:close",
-#     ],
-# )
-
 libc_test(
     name = "ftruncate_test",
     srcs = ["ftruncate_test.cpp"],
@@ -93,6 +85,7 @@ libc_test(
     ],
     deps = [
         "//libc:__support_cpp_string_view",
+        "//libc/test/UnitTest:errno_test_helpers",
     ],
 )
 
@@ -108,6 +101,9 @@ libc_test(
         "//libc:unlink",
         "//libc:write",
     ],
+    deps = [
+        "//libc/test/UnitTest:errno_test_helpers",
+    ],
 )
 
 libc_test(
@@ -121,6 +117,9 @@ libc_test(
         "//libc:write",
         "//libc:remove",
     ],
+    deps = [
+        "//libc/test/UnitTest:errno_test_helpers",
+    ],
 )
 
 libc_test(
@@ -132,39 +131,11 @@ libc_test(
         "//libc:link",
         "//libc:unlink",
     ],
+    deps = [
+        "//libc/test/UnitTest:errno_test_helpers",
+    ],
 )
 
-# libc_test(
-#     name = "linkat_test",
-#     srcs = ["linkat_test.cpp"],
-#     libc_function_deps = [
-#         "//libc:open",
-#         "//libc:close",
-#         "//libc:linkat",
-#         "//libc:unlink",
-#     ],
-# )
-
-# libc_test(
-#     name = "lseek_test",
-#     srcs = ["lseek_test.cpp"],
-#     libc_function_deps = [
-#         "//libc:open",
-#         "//libc:close",
-#         "//libc:lseek",
-#         "//libc:read",
-#     ],
-# )
-
-# libc_test(
-#     name = "rmdir_test",
-#     srcs = ["rmdir_test.cpp"],
-#     libc_function_deps = [
-#         "//libc:mkdir",
-#         "//libc:rmdir",
-#     ],
-# )
-
 libc_test(
     name = "swab_test",
     srcs = ["swab_test.cpp"],
@@ -176,32 +147,6 @@ libc_test(
     ],
 )
 
-# libc_test(
-#     name = "readlink_test",
-#     srcs = ["readlink_test.cpp"],
-#     libc_function_deps = [
-#         "//libc:readlink",
-#         "//libc:symlink",
-#         "//libc:unlink",
-#     ],
-#     deps = [
-#         "//libc:__support_cpp_string_view",
-#     ],
-# )
-
-# libc_test(
-#     name = "readlinkat_test",
-#     srcs = ["readlinkat_test.cpp"],
-#     libc_function_deps = [
-#         "//libc:readlinkat",
-#         "//libc:symlink",
-#         "//libc:unlink",
-#     ],
-#     deps = [
-#         "//libc:__support_cpp_string_view",
-#     ],
-# )
-
 libc_test(
     name = "symlink_test",
     srcs = ["symlink_test.cpp"],
@@ -211,19 +156,11 @@ libc_test(
         "//libc:symlink",
         "//libc:unlink",
     ],
+    deps = [
+        "//libc/test/UnitTest:errno_test_helpers",
+    ],
 )
 
-# libc_test(
-#     name = "symlinkat_test",
-#     srcs = ["symlinkat_test.cpp"],
-#     libc_function_deps = [
-#         "//libc:open",
-#         "//libc:close",
-#         "//libc:symlinkat",
-#         "//libc:unlink",
-#     ],
-# )
-
 libc_test(
     name = "truncate_test",
     srcs = ["truncate_test.cpp"],
@@ -237,6 +174,7 @@ libc_test(
     ],
     deps = [
         "//libc:__support_cpp_string_view",
+        "//libc/test/UnitTest:errno_test_helpers",
     ],
 )
 
@@ -253,17 +191,6 @@ libc_test(
     ],
 )
 
-# libc_test(
-#     name = "unlinkat_test",
-#     srcs = ["unlinkat_test.cpp"],
-#     libc_function_deps = [
-#         "//libc:open",
-#         "//libc:openat",
-#         "//libc:close",
-#         "//libc:unlinkat",
-#     ],
-# )
-
 libc_test(
     name = "getppid_test",
     srcs = ["getppid_test.cpp"],
@@ -288,6 +215,9 @@ libc_test(
         "//libc:open",
         "//libc:close",
     ],
+    deps = [
+        "//libc/test/UnitTest:errno_test_helpers",
+    ],
 )
 
 libc_test(
@@ -298,6 +228,8 @@ libc_test(
     ],
 )
 
+# TODO: add rules for functions modifying directories.
+
 #TODO: Enable once fullbuild is added to bazel, since this depends on a macro
 # definition in the public header
 


Reviews:
user: login: lntue
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-19T17:35:31Z
user: login: vonosmas
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-19T18:52:57Z
user: login: lntue
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-19T19:11:15Z

Review comments:
diff_hunk: @@ -41,10 +41,12 @@
 // they all provide.
 
 #define ASSERT_ERRNO_EQ(VAL)                                                   \
-  ASSERT_EQ(VAL, static_cast<int>(LIBC_NAMESPACE::libc_errno))
+  ASSERT_EQ(VAL, static_cast<int>(LIBC_NAMESPACE::libc_errno));                \
path: libc/test/UnitTest/Test.h
user: login: lntue
body: can you wrap them inside `do { } while (0)` instead?
created_at: 2025-03-19T17:35:31Z
author_association: CONTRIBUTOR
diff_hunk: @@ -41,10 +41,12 @@
 // they all provide.
 
 #define ASSERT_ERRNO_EQ(VAL)                                                   \
-  ASSERT_EQ(VAL, static_cast<int>(LIBC_NAMESPACE::libc_errno))
+  ASSERT_EQ(VAL, static_cast<int>(LIBC_NAMESPACE::libc_errno));                \
path: libc/test/UnitTest/Test.h
user: login: vonosmas
body: Done
created_at: 2025-03-19T18:52:57Z
author_association: CONTRIBUTOR

PR comments:
user: login: llvmbot
created_at: 2025-03-19T17:32:37Z
body: 
<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libc

Author: Alexey Samsonov (vonosmas)

<details>
<summary>Changes</summary>

Use ErrnoCheckingTest harness added in d039af33096c0a83b03475a240d5e281e2271c44 for all unistd tests that verify errno values. Stop explicitly setting it to zero in test code, as harness does it.

It also verifies that the errno is zero at the end of each test case, so update the ASSERT_ERRNO_EQ and ASSERT_ERRNO_FAILURE macro to clear out its value after the verification (similar to how ErrnoSetterMatcher does).

Update the CMake and Bazel rules for those tests. In the latter case, remove commented out tests that are currently unsupported in Bazel, since they get stale quickly.

---

Patch is 54.50 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/132067.diff


30 Files Affected:

- (modified) libc/test/UnitTest/Test.h (+4-2) 
- (modified) libc/test/src/unistd/CMakeLists.txt (+42) 
- (modified) libc/test/src/unistd/access_test.cpp (+13-18) 
- (modified) libc/test/src/unistd/chdir_test.cpp (+5-6) 
- (modified) libc/test/src/unistd/dup2_test.cpp (+5-4) 
- (modified) libc/test/src/unistd/dup3_test.cpp (+5-4) 
- (modified) libc/test/src/unistd/dup_test.cpp (+5-4) 
- (modified) libc/test/src/unistd/fchdir_test.cpp (+5-7) 
- (modified) libc/test/src/unistd/fpathconf_test.cpp (+7-2) 
- (modified) libc/test/src/unistd/ftruncate_test.cpp (+4-4) 
- (modified) libc/test/src/unistd/getentropy_test.cpp (+5-3) 
- (modified) libc/test/src/unistd/getsid_test.cpp (+4-2) 
- (modified) libc/test/src/unistd/isatty_test.cpp (+8-9) 
- (modified) libc/test/src/unistd/link_test.cpp (+5-4) 
- (modified) libc/test/src/unistd/linkat_test.cpp (+5-4) 
- (modified) libc/test/src/unistd/lseek_test.cpp (+5-3) 
- (modified) libc/test/src/unistd/pathconf_test.cpp (+7-2) 
- (modified) libc/test/src/unistd/pipe2_test.cpp (+4-3) 
- (modified) libc/test/src/unistd/pipe_test.cpp (+3-1) 
- (modified) libc/test/src/unistd/pread_pwrite_test.cpp (+6-4) 
- (modified) libc/test/src/unistd/read_write_test.cpp (+6-4) 
- (modified) libc/test/src/unistd/readlink_test.cpp (+4-4) 
- (modified) libc/test/src/unistd/readlinkat_test.cpp (+4-4) 
- (modified) libc/test/src/unistd/rmdir_test.cpp (+5-3) 
- (modified) libc/test/src/unistd/symlink_test.cpp (+5-4) 
- (modified) libc/test/src/unistd/symlinkat_test.cpp (+5-4) 
- (modified) libc/test/src/unistd/syscall_test.cpp (+6-7) 
- (modified) libc/test/src/unistd/truncate_test.cpp (+5-4) 
- (modified) libc/test/src/unistd/unlinkat_test.cpp (+5-3) 
- (modified) utils/bazel/llvm-project-overlay/libc/test/src/unistd/BUILD.bazel (+31-99) 


``````````diff
diff --git a/libc/test/UnitTest/Test.h b/libc/test/UnitTest/Test.h
index c7729606000c4..907ae1e59e511 100644
--- a/libc/test/UnitTest/Test.h
+++ b/libc/test/UnitTest/Test.h
@@ -41,10 +41,12 @@
 // they all provide.
 
 #define ASSERT_ERRNO_EQ(VAL)                                                   \
-  ASSERT_EQ(VAL, static_cast<int>(LIBC_NAMESPACE::libc_errno))
+  ASSERT_EQ(VAL, static_cast<int>(LIBC_NAMESPACE::libc_errno));                \
+  LIBC_NAMESPACE::libc_errno = 0
 #define ASSERT_ERRNO_SUCCESS()                                                 \
   ASSERT_EQ(0, static_cast<int>(LIBC_NAMESPACE::libc_errno))
 #define ASSERT_ERRNO_FAILURE()                                                 \
-  ASSERT_NE(0, static_cast<int>(LIBC_NAMESPACE::libc_errno))
+  ASSERT_NE(0, static_cast<int>(LIBC_NAMESPACE::libc_errno));                  \
+  LIBC_NAMESPACE::libc_errno = 0
 
 #endif // LLVM_LIBC_TEST_UNITTEST_TEST_H
diff --git a/libc/test/src/unistd/CMakeLists.txt b/libc/test/src/unistd/CMakeLists.txt
index c31a03d4b27a5..9aec6150af0ec 100644
--- a/libc/test/src/unistd/CMakeLists.txt
+++ b/libc/test/src/unistd/CMakeLists.txt
@@ -15,6 +15,8 @@ add_libc_unittest(
     libc.src.unistd.access
     libc.src.unistd.close
     libc.src.unistd.unlink
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_unittest(
@@ -30,6 +32,7 @@ add_libc_unittest(
     libc.src.unistd.chdir
     libc.src.unistd.close
     libc.src.fcntl.open
+    libc.test.UnitTest.ErrnoCheckingTest
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
@@ -48,6 +51,7 @@ add_libc_unittest(
     libc.src.unistd.read
     libc.src.unistd.unlink
     libc.src.unistd.write
+    libc.test.UnitTest.ErrnoCheckingTest
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
@@ -66,6 +70,7 @@ add_libc_unittest(
     libc.src.unistd.read
     libc.src.unistd.unlink
     libc.src.unistd.write
+    libc.test.UnitTest.ErrnoCheckingTest
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
@@ -84,6 +89,7 @@ add_libc_unittest(
     libc.src.unistd.read
     libc.src.unistd.unlink
     libc.src.unistd.write
+    libc.test.UnitTest.ErrnoCheckingTest
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
@@ -99,6 +105,7 @@ add_libc_unittest(
     libc.src.fcntl.open
     libc.src.unistd.fchdir
     libc.src.unistd.close
+    libc.test.UnitTest.ErrnoCheckingTest
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
@@ -118,6 +125,8 @@ add_libc_unittest(
     libc.src.unistd.unlink
     libc.src.unistd.write
     libc.src.__support.CPP.string_view
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_unittest(
@@ -136,6 +145,7 @@ add_libc_unittest(
     libc.src.unistd.pwrite
     libc.src.unistd.unlink
     libc.src.unistd.write
+    libc.test.UnitTest.ErrnoCheckingTest
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
@@ -154,6 +164,7 @@ add_libc_unittest(
     libc.src.unistd.read
     libc.src.unistd.write
     libc.src.stdio.remove
+    libc.test.UnitTest.ErrnoCheckingTest
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
@@ -170,6 +181,8 @@ add_libc_unittest(
     libc.src.unistd.close
     libc.src.unistd.link
     libc.src.unistd.unlink
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_unittest(
@@ -185,6 +198,8 @@ add_libc_unittest(
     libc.src.unistd.close
     libc.src.unistd.linkat
     libc.src.unistd.unlink
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_unittest(
@@ -200,6 +215,7 @@ add_libc_unittest(
     libc.src.unistd.close
     libc.src.unistd.lseek
     libc.src.unistd.read
+    libc.test.UnitTest.ErrnoCheckingTest
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
@@ -214,6 +230,7 @@ add_libc_unittest(
     libc.src.errno.errno
     libc.src.unistd.close
     libc.src.unistd.pipe
+    libc.test.UnitTest.ErrnoCheckingTest
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
@@ -228,6 +245,7 @@ add_libc_unittest(
     libc.src.errno.errno
     libc.src.unistd.close
     libc.src.unistd.pipe2
+    libc.test.UnitTest.ErrnoCheckingTest
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
@@ -242,6 +260,8 @@ add_libc_unittest(
     libc.src.errno.errno
     libc.src.sys.stat.mkdir
     libc.src.unistd.rmdir
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_unittest(
@@ -268,6 +288,8 @@ add_libc_unittest(
     libc.src.unistd.symlink
     libc.src.unistd.unlink
     libc.src.__support.CPP.string_view
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_unittest(
@@ -285,6 +307,8 @@ add_libc_unittest(
     libc.src.unistd.symlink
     libc.src.unistd.unlink
     libc.src.__support.CPP.string_view
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_unittest(
@@ -310,6 +334,8 @@ add_libc_unittest(
     libc.src.unistd.close
     libc.src.unistd.symlink
     libc.src.unistd.unlink
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_unittest(
@@ -325,6 +351,8 @@ add_libc_unittest(
     libc.src.unistd.close
     libc.src.unistd.symlinkat
     libc.src.unistd.unlink
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_unittest(
@@ -343,6 +371,8 @@ add_libc_unittest(
     libc.src.unistd.unlink
     libc.src.unistd.write
     libc.src.__support.CPP.string_view
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_unittest(
@@ -374,6 +404,8 @@ add_libc_unittest(
     libc.src.fcntl.openat
     libc.src.unistd.close
     libc.src.unistd.unlinkat
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_unittest(
@@ -404,6 +436,8 @@ add_libc_unittest(
     getsid_test.cpp
   DEPENDS
     libc.src.unistd.getsid
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_unittest(
@@ -427,6 +461,8 @@ add_libc_unittest(
     libc.src.fcntl.open
     libc.src.unistd.close
     libc.src.errno.errno
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_unittest(
@@ -451,6 +487,7 @@ add_libc_unittest(
     libc.include.sys_syscall
     libc.src.errno.errno
     libc.src.unistd.__llvm_libc_syscall
+    libc.test.UnitTest.ErrnoCheckingTest
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
@@ -479,6 +516,8 @@ add_libc_unittest(
     libc.src.unistd.fpathconf
     libc.src.fcntl.open
     libc.src.unistd.close
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_unittest(
@@ -494,6 +533,8 @@ add_libc_unittest(
     libc.src.unistd.pathconf
     libc.src.fcntl.open
     libc.src.unistd.close
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
 
 add_libc_test(
@@ -519,6 +560,7 @@ add_libc_test(
   DEPENDS
     libc.src.unistd.getentropy
     libc.src.errno.errno
+    libc.test.UnitTest.ErrnoCheckingTest
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
diff --git a/libc/test/src/unistd/access_test.cpp b/libc/test/src/unistd/access_test.cpp
index 0643b2b992a5c..375227fe348b8 100644
--- a/libc/test/src/unistd/access_test.cpp
+++ b/libc/test/src/unistd/access_test.cpp
@@ -6,22 +6,24 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/errno/libc_errno.h"
 #include "src/fcntl/open.h"
 #include "src/unistd/access.h"
 #include "src/unistd/close.h"
 #include "src/unistd/unlink.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 #include <sys/stat.h>
 #include <unistd.h>
 
-TEST(LlvmLibcAccessTest, CreateAndTest) {
+using LlvmLibcAccessTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcAccessTest, CreateAndTest) {
   // The test strategy is to repeatedly create a file in different modes and
   // test that it is accessable in those modes but not in others.
-  LIBC_NAMESPACE::libc_errno = 0;
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
+  using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
   constexpr const char *FILENAME = "access.test";
   auto TEST_FILE = libc_make_test_file_path(FILENAME);
   int fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
@@ -29,30 +31,23 @@ TEST(LlvmLibcAccessTest, CreateAndTest) {
   ASSERT_GT(fd, 0);
   ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
 
-  ASSERT_EQ(LIBC_NAMESPACE::access(TEST_FILE, F_OK), 0);
-  ASSERT_ERRNO_SUCCESS();
-  ASSERT_EQ(LIBC_NAMESPACE::access(TEST_FILE, X_OK | W_OK | R_OK), 0);
-  ASSERT_ERRNO_SUCCESS();
+  ASSERT_THAT(LIBC_NAMESPACE::access(TEST_FILE, F_OK), Succeeds(0));
+  ASSERT_THAT(LIBC_NAMESPACE::access(TEST_FILE, X_OK | W_OK | R_OK),
+              Succeeds(0));
   ASSERT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE), Succeeds(0));
 
   fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IXUSR);
   ASSERT_ERRNO_SUCCESS();
   ASSERT_GT(fd, 0);
   ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
-  ASSERT_EQ(LIBC_NAMESPACE::access(TEST_FILE, F_OK), 0);
-  ASSERT_ERRNO_SUCCESS();
-  ASSERT_EQ(LIBC_NAMESPACE::access(TEST_FILE, X_OK), 0);
-  ASSERT_ERRNO_SUCCESS();
-  ASSERT_EQ(LIBC_NAMESPACE::access(TEST_FILE, R_OK), -1);
-  ASSERT_ERRNO_EQ(EACCES);
-  LIBC_NAMESPACE::libc_errno = 0;
-  ASSERT_EQ(LIBC_NAMESPACE::access(TEST_FILE, W_OK), -1);
-  ASSERT_ERRNO_EQ(EACCES);
-  LIBC_NAMESPACE::libc_errno = 0;
+  ASSERT_THAT(LIBC_NAMESPACE::access(TEST_FILE, F_OK), Succeeds(0));
+  ASSERT_THAT(LIBC_NAMESPACE::access(TEST_FILE, X_OK), Succeeds(0));
+  ASSERT_THAT(LIBC_NAMESPACE::access(TEST_FILE, R_OK), Fails(EACCES));
+  ASSERT_THAT(LIBC_NAMESPACE::access(TEST_FILE, W_OK), Fails(EACCES));
   ASSERT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE), Succeeds(0));
 }
 
-TEST(LlvmLibcAccessTest, AccessNonExistentFile) {
+TEST_F(LlvmLibcAccessTest, AccessNonExistentFile) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
   ASSERT_THAT(LIBC_NAMESPACE::access("testdata/non-existent-file", F_OK),
               Fails(ENOENT));
diff --git a/libc/test/src/unistd/chdir_test.cpp b/libc/test/src/unistd/chdir_test.cpp
index e1bdcd77119f7..ac5217bbd2461 100644
--- a/libc/test/src/unistd/chdir_test.cpp
+++ b/libc/test/src/unistd/chdir_test.cpp
@@ -6,16 +6,18 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/errno/libc_errno.h"
 #include "src/fcntl/open.h"
 #include "src/unistd/chdir.h"
 #include "src/unistd/close.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 #include "hdr/fcntl_macros.h"
 
-TEST(LlvmLibcChdirTest, ChangeAndOpen) {
+using LlvmLibcChdirTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcChdirTest, ChangeAndOpen) {
   // The idea of this test is that we will first open an existing test file
   // without changing the directory to make sure it exists. Next, we change
   // directory and open the same file to make sure that the "chdir" operation
@@ -27,7 +29,6 @@ TEST(LlvmLibcChdirTest, ChangeAndOpen) {
   auto TEST_FILE = libc_make_test_file_path(FILENAME2);
   constexpr const char *FILENAME3 = "chdir.test";
   auto TEST_FILE_BASE = libc_make_test_file_path(FILENAME3);
-  LIBC_NAMESPACE::libc_errno = 0;
 
   int fd = LIBC_NAMESPACE::open(TEST_FILE, O_PATH);
   ASSERT_GT(fd, 0);
@@ -41,9 +42,7 @@ TEST(LlvmLibcChdirTest, ChangeAndOpen) {
   ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
 }
 
-TEST(LlvmLibcChdirTest, ChangeToNonExistentDir) {
-  LIBC_NAMESPACE::libc_errno = 0;
+TEST_F(LlvmLibcChdirTest, ChangeToNonExistentDir) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
   ASSERT_THAT(LIBC_NAMESPACE::chdir("non-existent-dir"), Fails(ENOENT));
-  LIBC_NAMESPACE::libc_errno = 0;
 }
diff --git a/libc/test/src/unistd/dup2_test.cpp b/libc/test/src/unistd/dup2_test.cpp
index 2b2b3f3eef9a8..f6d546def33ec 100644
--- a/libc/test/src/unistd/dup2_test.cpp
+++ b/libc/test/src/unistd/dup2_test.cpp
@@ -6,21 +6,22 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/errno/libc_errno.h"
 #include "src/fcntl/open.h"
 #include "src/unistd/close.h"
 #include "src/unistd/dup2.h"
 #include "src/unistd/read.h"
 #include "src/unistd/unlink.h"
 #include "src/unistd/write.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 #include <sys/stat.h>
 
-TEST(LlvmLibcdupTest, ReadAndWriteViaDup) {
+using LlvmLibcdupTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcdupTest, ReadAndWriteViaDup) {
   constexpr int DUPFD = 0xD0;
-  LIBC_NAMESPACE::libc_errno = 0;
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
   constexpr const char *FILENAME = "dup2.test";
   auto TEST_FILE = libc_make_test_file_path(FILENAME);
@@ -59,7 +60,7 @@ TEST(LlvmLibcdupTest, ReadAndWriteViaDup) {
   ASSERT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE), Succeeds(0));
 }
 
-TEST(LlvmLibcdupTest, DupBadFD) {
+TEST_F(LlvmLibcdupTest, DupBadFD) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
   ASSERT_THAT(LIBC_NAMESPACE::dup2(-1, 123), Fails(EBADF));
 }
diff --git a/libc/test/src/unistd/dup3_test.cpp b/libc/test/src/unistd/dup3_test.cpp
index 7b1c8e0e25190..598940b1c456d 100644
--- a/libc/test/src/unistd/dup3_test.cpp
+++ b/libc/test/src/unistd/dup3_test.cpp
@@ -6,26 +6,27 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/errno/libc_errno.h"
 #include "src/fcntl/open.h"
 #include "src/unistd/close.h"
 #include "src/unistd/dup3.h"
 #include "src/unistd/read.h"
 #include "src/unistd/unlink.h"
 #include "src/unistd/write.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 #include <sys/stat.h>
 
+using LlvmLibcdupTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
 // The tests here are exactly the same as those of dup2. We only test the
 // plumbing of the dup3 syscall and not the dup3 functionality itself as it is
 // a simple syscall wrapper. Testing dup3 functionality is beyond the scope of
 // this test.
 
-TEST(LlvmLibcdupTest, ReadAndWriteViaDup) {
+TEST_F(LlvmLibcdupTest, ReadAndWriteViaDup) {
   constexpr int DUPFD = 0xD0;
-  LIBC_NAMESPACE::libc_errno = 0;
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
   constexpr const char *FILENAME = "dup3.test";
@@ -65,7 +66,7 @@ TEST(LlvmLibcdupTest, ReadAndWriteViaDup) {
   ASSERT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE), Succeeds(0));
 }
 
-TEST(LlvmLibcdupTest, DupBadFD) {
+TEST_F(LlvmLibcdupTest, DupBadFD) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
   ASSERT_THAT(LIBC_NAMESPACE::dup3(-1, 123, 0), Fails(EBADF));
 }
diff --git a/libc/test/src/unistd/dup_test.cpp b/libc/test/src/unistd/dup_test.cpp
index c7bf877142102..8e0b662c3961b 100644
--- a/libc/test/src/unistd/dup_test.cpp
+++ b/libc/test/src/unistd/dup_test.cpp
@@ -6,20 +6,21 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/errno/libc_errno.h"
 #include "src/fcntl/open.h"
 #include "src/unistd/close.h"
 #include "src/unistd/dup.h"
 #include "src/unistd/read.h"
 #include "src/unistd/unlink.h"
 #include "src/unistd/write.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 #include <sys/stat.h>
 
-TEST(LlvmLibcdupTest, ReadAndWriteViaDup) {
-  LIBC_NAMESPACE::libc_errno = 0;
+using LlvmLibcdupTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcdupTest, ReadAndWriteViaDup) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
   constexpr const char *FILENAME = "dup.test";
   auto TEST_FILE = libc_make_test_file_path(FILENAME);
@@ -55,7 +56,7 @@ TEST(LlvmLibcdupTest, ReadAndWriteViaDup) {
   ASSERT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE), Succeeds(0));
 }
 
-TEST(LlvmLibcdupTest, DupBadFD) {
+TEST_F(LlvmLibcdupTest, DupBadFD) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
   ASSERT_THAT(LIBC_NAMESPACE::dup(-1), Fails(EBADF));
 }
diff --git a/libc/test/src/unistd/fchdir_test.cpp b/libc/test/src/unistd/fchdir_test.cpp
index 0e39fde17c67b..add56484a8e85 100644
--- a/libc/test/src/unistd/fchdir_test.cpp
+++ b/libc/test/src/unistd/fchdir_test.cpp
@@ -6,16 +6,18 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/errno/libc_errno.h"
 #include "src/fcntl/open.h"
 #include "src/unistd/close.h"
 #include "src/unistd/fchdir.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 #include "hdr/fcntl_macros.h"
 
-TEST(LlvmLibcChdirTest, ChangeAndOpen) {
+using LlvmLibcChdirTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcChdirTest, ChangeAndOpen) {
   // The idea of this test is that we will first open an existing test file
   // without changing the directory to make sure it exists. Next, we change
   // directory and open the same file to make sure that the "fchdir" operation
@@ -27,7 +29,6 @@ TEST(LlvmLibcChdirTest, ChangeAndOpen) {
   auto TEST_FILE = libc_make_test_file_path(FILENAME2);
   constexpr const char *FILENAME3 = "fchdir.test";
   auto TEST_FILE_BASE = libc_make_test_file_path(FILENAME3);
-  LIBC_NAMESPACE::libc_errno = 0;
 
   int dir_fd = LIBC_NAMESPACE::open(TEST_DIR, O_DIRECTORY);
   ASSERT_GT(dir_fd, 0);
@@ -45,10 +46,7 @@ TEST(LlvmLibcChdirTest, ChangeAndOpen) {
   ASSERT_THAT(LIBC_NAMESPACE::close(dir_fd), Succeeds(0));
 }
 
-TEST(LlvmLibcChdirTest, ChangeToNonExistentDir) {
-  using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
-  LIBC_NAMESPACE::libc_errno = 0;
+TEST_F(LlvmLibcChdirTest, ChangeToNonExistentDir) {
   ASSERT_EQ(LIBC_NAMESPACE::fchdir(0), -1);
   ASSERT_ERRNO_FAILURE();
-  LIBC_NAMESPACE::libc_errno = 0;
 }
diff --git a/libc/test/src/unistd/fpathconf_test.cpp b/libc/test/src/unistd/fpathconf_test.cpp
index fe63e5e085973..3cba7ec5c66a8 100644
--- a/libc/test/src/unistd/fpathconf_test.cpp
+++ b/libc/test/src/unistd/fpathconf_test.cpp
@@ -12,19 +12,24 @@
 #include "src/fcntl/open.h"
 #include "src/unistd/close.h"
 #include "src/unistd/fpathconf.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
+using LlvmLibcFpathconfTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
 
-TEST(LlvmLibcPipeTest, SmokeTest) {
+TEST_F(LlvmLibcFpathconfTest, SmokeTest) {
   constexpr const char *FILENAME = "fpathconf.test";
   auto TEST_FILE = libc_make_test_file_path(FILENAME);
   int fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
+  ASSERT_ERRNO_SUCCESS();
+  ASSERT_GT(fd, 0);
+
   EXPECT_EQ(LIBC_NAMESPACE::fpathconf(fd, _PC_SYNC_IO), -1l);
   EXPECT_EQ(LIBC_NAMESPACE::fpathconf(fd, _PC_PATH_MAX),
             static_cast<long>(_POSIX_PATH_MAX));
-  LIBC_NAMESPACE::close(fd);
+  ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
 }
 
 // TODO: Functionality tests
diff --git a/libc/test/src/unistd/ftruncate_test.cpp b/libc/test/src/unistd/ftruncate_test.cpp
index 2fe4002692a87..c50a07f15f1e0 100644
--- a/libc/test/src/unistd/ftruncate_test.cpp
+++ b/libc/test/src/unistd/ftruncate_test.cpp
@@ -7,21 +7,22 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/__support/CPP/string_view.h"
-#include "src/errno/libc_errno.h"
 #include "src/fcntl/open.h"
 #include "src/unistd/close.h"
 #include "src/unistd/ftruncate.h"
 #include "src/unistd/read.h"
 #include "src/unistd/unlink.h"
 #include "src/unistd/write.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 #include <sys/stat.h>
 
 namespace cpp = LIBC_NAMESPACE::cpp;
+using LlvmLibcFtruncateTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
 
-TEST(LlvmLibcFtruncateTest, CreateAndTruncate) {
+TEST_F(LlvmLibcFtruncateTest, CreateAndTruncate) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succe...
[truncated]

``````````

</details>

author_association: MEMBER
user: login: github-actions[bot]
created_at: 2025-03-19T17:35:45Z
body: <!--LLVM CODE FORMAT COMMENT: {clang-format}-->

:white_check_mark: With the latest revision this PR passed the C/C++ code formatter.
author_association: NONE