Add temp file and FD support to TemporaryFileHandle

This commit adds file descriptor and temporary file management to
DuplicatableFileHandle, removing the redundant test-only
TemporaryFileHandle utility.

Changes:
- Add file descriptor constructor and setFd() method
- Add temporary file constructor with string_view content
- Add filePath member and automatic cleanup in destructor
- Add configurable temp-dir meson option (default: /tmp/bmcweb)
- Remove include/file_test_utilities.hpp
- Update all tests to use DuplicatableFileHandle
- Rename stringPath to filePath

These features will be used by the multipart parser to stream
large uploads to temporary files instead of keeping them in memory,
and by the update service to pass file descriptors over D-Bus.

Change-Id: I982f5928d453f9f0c13d91c3525006134ddc87b3
Signed-off-by: Rajeev Ranjan <ranjan.rajeev1609@gmail.com>
diff --git a/test/http/http2_connection_test.cpp b/test/http/http2_connection_test.cpp
index a6bc81c..3648892 100644
--- a/test/http/http2_connection_test.cpp
+++ b/test/http/http2_connection_test.cpp
@@ -9,7 +9,7 @@
 #include "test_stream.hpp"
 
 #include <nghttp2/nghttp2.h>
-#include <unistd.h>
+#include <sys/types.h>
 
 #include <boost/asio/buffer.hpp>
 #include <boost/asio/io_context.hpp>
diff --git a/test/http/http_body_test.cpp b/test/http/http_body_test.cpp
index 889161c..b96fd2c 100644
--- a/test/http/http_body_test.cpp
+++ b/test/http/http_body_test.cpp
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: Apache-2.0
 // SPDX-FileCopyrightText: Copyright OpenBMC Authors
-#include "file_test_utilities.hpp"
+#include "duplicatable_file_handle.hpp"
 #include "http_body.hpp"
 
 #include <boost/beast/core/file_base.hpp>
@@ -70,9 +70,9 @@
 TEST(HttpHttpBodyValueType, MoveFile)
 {
     HttpBody::value_type value(EncodingType::Base64, CompressionType::Raw);
-    TemporaryFileHandle temporaryFile("teststring");
+    DuplicatableFileHandle temporaryFile("teststring");
     boost::system::error_code ec;
-    value.open(temporaryFile.stringPath.c_str(), boost::beast::file_mode::read,
+    value.open(temporaryFile.filePath.c_str(), boost::beast::file_mode::read,
                ec);
     ASSERT_FALSE(ec);
     // Move constructor
@@ -95,9 +95,9 @@
 TEST(HttpHttpBodyValueType, MoveOperatorFile)
 {
     HttpBody::value_type value(EncodingType::Base64, CompressionType::Raw);
-    TemporaryFileHandle temporaryFile("teststring");
+    DuplicatableFileHandle temporaryFile("teststring");
     boost::system::error_code ec;
-    value.open(temporaryFile.stringPath.c_str(), boost::beast::file_mode::read,
+    value.open(temporaryFile.filePath.c_str(), boost::beast::file_mode::read,
                ec);
     ASSERT_FALSE(ec);
     // Move constructor
@@ -119,9 +119,9 @@
 TEST(HttpFileBodyValueType, SetFd)
 {
     HttpBody::value_type value(EncodingType::Base64, CompressionType::Raw);
-    TemporaryFileHandle temporaryFile("teststring");
+    DuplicatableFileHandle temporaryFile("teststring");
     boost::system::error_code ec;
-    FILE* r = fopen(temporaryFile.stringPath.c_str(), "r");
+    FILE* r = fopen(temporaryFile.filePath.c_str(), "r");
     ASSERT_NE(r, nullptr);
     value.setFd(fileno(r), ec);
     ASSERT_FALSE(ec);
diff --git a/test/http/http_response_test.cpp b/test/http/http_response_test.cpp
index 536415e..69eb637 100644
--- a/test/http/http_response_test.cpp
+++ b/test/http/http_response_test.cpp
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: Apache-2.0
 // SPDX-FileCopyrightText: Copyright OpenBMC Authors
-#include "file_test_utilities.hpp"
+#include "duplicatable_file_handle.hpp"
 #include "http/http_body.hpp"
 #include "http/http_response.hpp"
 #include "utility.hpp"
@@ -86,8 +86,8 @@
 {
     Response res;
     addHeaders(res);
-    TemporaryFileHandle temporaryFile("sample text");
-    res.openFile(temporaryFile.stringPath);
+    DuplicatableFileHandle temporaryFile("sample text");
+    res.openFile(temporaryFile.filePath);
 
     verifyHeaders(res);
 }
@@ -95,8 +95,9 @@
 {
     Response res;
     addHeaders(res);
-    TemporaryFileHandle temporaryFile("sample text");
-    FILE* fd = fopen(temporaryFile.stringPath.c_str(), "r+");
+    DuplicatableFileHandle temporaryFile("sample text");
+    FILE* fd = fopen(temporaryFile.filePath.c_str(), "r+");
+    ASSERT_NE(fd, nullptr);
     res.openFd(fileno(fd));
     verifyHeaders(res);
     fclose(fd);
@@ -106,8 +107,8 @@
 {
     Response res;
     addHeaders(res);
-    TemporaryFileHandle temporaryFile("sample text");
-    FILE* fd = fopen(temporaryFile.stringPath.c_str(), "r");
+    DuplicatableFileHandle temporaryFile("sample text");
+    FILE* fd = fopen(temporaryFile.filePath.c_str(), "r");
     ASSERT_NE(fd, nullptr);
     res.openFd(fileno(fd), bmcweb::EncodingType::Base64);
     verifyHeaders(res);
@@ -118,8 +119,8 @@
 {
     Response res;
     addHeaders(res);
-    TemporaryFileHandle temporaryFile("sample text");
-    res.openFile(temporaryFile.stringPath);
+    DuplicatableFileHandle temporaryFile("sample text");
+    res.openFile(temporaryFile.filePath);
 
     verifyHeaders(res);
     res.write("body text");
@@ -149,21 +150,23 @@
 {
     Response res;
     std::string data = "sample text";
-    TemporaryFileHandle temporaryFile(data);
-    FILE* f = fopen(temporaryFile.stringPath.c_str(), "r+");
+    DuplicatableFileHandle temporaryFile(data);
+    FILE* f = fopen(temporaryFile.filePath.c_str(), "r+");
+    ASSERT_NE(f, nullptr);
     res.openFd(fileno(f), bmcweb::EncodingType::Base64);
     EXPECT_EQ(getData(res.response), "c2FtcGxlIHRleHQ=");
+    fclose(f);
 }
 
 TEST(HttpResponse, Base64HttpBodyWriterLarge)
 {
     Response res;
     std::string data = generateBigdata();
-    TemporaryFileHandle temporaryFile(data);
+    DuplicatableFileHandle temporaryFile(data);
 
     boost::beast::file_posix file;
     boost::system::error_code ec;
-    file.open(temporaryFile.stringPath.c_str(), boost::beast::file_mode::read,
+    file.open(temporaryFile.filePath.c_str(), boost::beast::file_mode::read,
               ec);
     EXPECT_EQ(ec.value(), 0);
     res.openFd(file.native_handle(), bmcweb::EncodingType::Base64);
@@ -174,11 +177,11 @@
 {
     Response res;
     std::string data = generateBigdata();
-    TemporaryFileHandle temporaryFile(data);
+    DuplicatableFileHandle temporaryFile(data);
 
     boost::beast::file_posix file;
     boost::system::error_code ec;
-    file.open(temporaryFile.stringPath.c_str(), boost::beast::file_mode::read,
+    file.open(temporaryFile.filePath.c_str(), boost::beast::file_mode::read,
               ec);
     EXPECT_EQ(ec.value(), 0);
     res.openFd(file.native_handle());