fmq_unit_tests: Detect leaked FDs more efficiently

Instead of looping through the max number of allowed FDs +1, we now
check the number of FDs opened by the test process before and after
creating/destroying a number of queues.

Test: atest fmq_unit_tests
Bug: 343829026
Change-Id: I9fe29e418b2acafd3a12b1add96ea412e3eaa120
diff --git a/tests/fmq_unit_tests.cpp b/tests/fmq_unit_tests.cpp
index 622fcfb..7abe74d 100644
--- a/tests/fmq_unit_tests.cpp
+++ b/tests/fmq_unit_tests.cpp
@@ -25,6 +25,7 @@
 #include <sys/resource.h>
 #include <atomic>
 #include <cstdlib>
+#include <filesystem>
 #include <sstream>
 #include <thread>
 
@@ -374,20 +375,26 @@
     close(ashmemFd);
 }
 
-// If this test fails and we do leak FDs, the next test will cause a crash
+long numFds() {
+    return std::distance(std::filesystem::directory_iterator("/proc/self/fd"),
+                         std::filesystem::directory_iterator{});
+}
+
 TEST_F(AidlOnlyBadQueueConfig, LookForLeakedFds) {
+    // create/destroy a large number of queues that if we were leaking FDs
+    // we could detect it by looking at the number of FDs opened by the this
+    // test process.
+    constexpr uint32_t kNumQueues = 100;
     const size_t kPageSize = getpagesize();
     size_t numElementsInQueue = SIZE_MAX / sizeof(uint32_t) - kPageSize - 1;
-    struct rlimit rlim;
-    ASSERT_EQ(getrlimit(RLIMIT_NOFILE, &rlim), 0);
-    for (int i = 0; i <= rlim.rlim_cur + 1; i++) {
+    long numFdsBefore = numFds();
+    for (int i = 0; i < kNumQueues; i++) {
         android::AidlMessageQueue<uint32_t, SynchronizedReadWrite> fmq(numElementsInQueue);
         ASSERT_FALSE(fmq.isValid());
     }
-    // try to get another FD
-    int fd = ashmem_create_region("test", 100);
-    ASSERT_NE(fd, -1);
-    close(fd);
+    long numFdsAfter = numFds();
+    EXPECT_LT(numFdsAfter, kNumQueues);
+    EXPECT_EQ(numFdsAfter, numFdsBefore);
 }
 
 TEST_F(Hidl2AidlOperation, ConvertDescriptorsSync) {