#include <gtest/gtest.h>
#include <fstream>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <cstdlib>
#include <sstream>
#include "file_utils.h"
using namespace ock::ttp;
class FileUtilsTest : public ::testing::Test {
protected:
void SetUp() override
{
std::string pid_str = std::to_string(getpid());
testDir = "/tmp/FileUtilsTest_" + pid_str;
testFile = testDir + "/test_file.txt";
testLink = testDir + "/test_link.txt";
testSubDir = testDir + "/subdir";
restrictedFile = testDir + "/restricted.txt";
mkdir(testDir.c_str(), 0755);
mkdir(testSubDir.c_str(), 0755);
std::ofstream file(testFile);
file << "Test content";
file.close();
symlink(testFile.c_str(), testLink.c_str());
std::ofstream restricted(restrictedFile);
restricted << "Restricted content";
restricted.close();
chmod(restrictedFile.c_str(), 0400);
}
void TearDown() override
{
system(("rm -rf " + testDir).c_str());
}
std::string testDir;
std::string testFile;
std::string testLink;
std::string testSubDir;
std::string restrictedFile;
};
TEST_F(FileUtilsTest, IntegrationTest_FileValidationWorkflow)
{
std::string errMsg;
ASSERT_TRUE(FileUtils::CheckFileExists(testFile));
ASSERT_TRUE(FileUtils::RegularFilePath(testFile, testDir, errMsg));
ASSERT_TRUE(FileUtils::IsFileValid(testFile, errMsg, true, false));
ASSERT_TRUE(FileUtils::CheckOwner(testFile, errMsg));
chmod(testFile.c_str(), 0644);
ASSERT_TRUE(FileUtils::CheckPermission(testFile, 0644, false, errMsg));
}
TEST_F(FileUtilsTest, CheckFileExists_WhenFileExists_ReturnsTrue)
{
ASSERT_TRUE(FileUtils::CheckFileExists(testFile));
}
TEST_F(FileUtilsTest, CheckFileExists_WhenFileNotExists_ReturnsFalse)
{
std::string nonExistentFile = testDir + "/non_existent.txt";
ASSERT_FALSE(FileUtils::CheckFileExists(nonExistentFile));
}
TEST_F(FileUtilsTest, CheckFileExists_WhenPathIsDirectory_ReturnsFalse)
{
ASSERT_TRUE(FileUtils::CheckFileExists(testSubDir));
}
TEST_F(FileUtilsTest, CheckDirectoryExists_WhenDirectoryExists_ReturnsTrue)
{
ASSERT_TRUE(FileUtils::CheckDirectoryExists(testSubDir));
}
TEST_F(FileUtilsTest, CheckDirectoryExists_WhenNotExists_ReturnsFalse)
{
std::string nonExistentDir = testDir + "/non_existent_dir";
ASSERT_FALSE(FileUtils::CheckDirectoryExists(nonExistentDir));
}
TEST_F(FileUtilsTest, CheckDirectoryExists_WhenPathIsFile_ReturnsFalse)
{
ASSERT_FALSE(FileUtils::CheckDirectoryExists(testFile));
}
TEST_F(FileUtilsTest, IsSymlink_WhenIsSymlink_ReturnsTrue)
{
ASSERT_TRUE(FileUtils::IsSymlink(testLink));
}
TEST_F(FileUtilsTest, IsSymlink_WhenIsRegularFile_ReturnsFalse)
{
ASSERT_FALSE(FileUtils::IsSymlink(testFile));
}
TEST_F(FileUtilsTest, IsSymlink_WhenFileNotExists_ReturnsFalse)
{
std::string nonExistent = testDir + "/non_existent";
ASSERT_FALSE(FileUtils::IsSymlink(nonExistent));
}
TEST_F(FileUtilsTest, RegularFilePath_WithBaseDir_WhenPathInBaseDir_ReturnsTrue)
{
std::string errMsg;
std::string fileInSubdir = testSubDir + "/new_file.txt";
std::ofstream(fileInSubdir) << "test";
ASSERT_TRUE(FileUtils::RegularFilePath(fileInSubdir, testDir, errMsg));
}
TEST_F(FileUtilsTest, RegularFilePath_WithBaseDir_WhenPathOutsideBaseDir_ReturnsFalse)
{
std::string errMsg;
std::string outsidePath = "/tmp";
ASSERT_FALSE(FileUtils::RegularFilePath(outsidePath, testDir, errMsg));
ASSERT_FALSE(errMsg.empty());
}
TEST_F(FileUtilsTest, RegularFilePath_WithBaseDir_WhenSymlinkPointsInsideBaseDir_ReturnsTrue)
{
std::string errMsg;
std::string linkInside = testDir + "/link_inside";
symlink(testFile.c_str(), linkInside.c_str());
ASSERT_FALSE(FileUtils::RegularFilePath(linkInside, testDir, errMsg));
}
TEST_F(FileUtilsTest, RegularFilePath_WithBaseDir_WhenSymlinkPointsOutsideBaseDir_ReturnsFalse)
{
std::string errMsg;
std::string linkOutside = testDir + "/link_outside";
symlink("/tmp", linkOutside.c_str());
ASSERT_FALSE(FileUtils::RegularFilePath(linkOutside, testDir, errMsg));
ASSERT_FALSE(errMsg.empty());
}
TEST_F(FileUtilsTest, RegularFilePath_WithoutBaseDir_WhenPathExists_ReturnsTrue)
{
std::string errMsg;
ASSERT_TRUE(FileUtils::RegularFilePath(testFile, errMsg));
ASSERT_TRUE(errMsg.empty());
}
TEST_F(FileUtilsTest, RegularFilePath_WithoutBaseDir_FilePathEmpty_ReturnsFalse)
{
std::string errMsg;
ASSERT_FALSE(FileUtils::RegularFilePath("", errMsg));
ASSERT_FALSE(errMsg.empty());
}
TEST_F(FileUtilsTest, RegularFilePath_WithoutBaseDir_WhenPathNotExists_ReturnsFalse)
{
std::string errMsg;
std::string nonExistent = testDir + "/non_existent";
ASSERT_FALSE(FileUtils::RegularFilePath(nonExistent, errMsg));
ASSERT_FALSE(errMsg.empty());
}
TEST_F(FileUtilsTest, IsFileValid_WhenFileIsValid_ReturnsTrue)
{
std::string errMsg;
ASSERT_TRUE(FileUtils::IsFileValid(testFile, errMsg));
ASSERT_TRUE(errMsg.empty());
}
TEST_F(FileUtilsTest, IsFileValid_WhenFileNotExists_ReturnsFalse)
{
std::string errMsg;
std::string nonExistent = testDir + "/non_existent.txt";
ASSERT_FALSE(FileUtils::IsFileValid(nonExistent, errMsg));
ASSERT_FALSE(errMsg.empty());
}
TEST_F(FileUtilsTest, IsFileValid_WhenFileEmpty_ReturnsFalse)
{
std::string errMsg;
std::string emptyFile = testDir + "/empty.txt";
std::ofstream(emptyFile) << "";
ASSERT_TRUE(FileUtils::IsFileValid(emptyFile, errMsg, true));
ASSERT_FALSE(errMsg.empty());
}
TEST_F(FileUtilsTest, IsFileValid_WhenCheckPermissionDisabled_PermissionErrorsIgnored)
{
std::string errMsg;
std::string readOnlyFile = testDir + "/readonly.txt";
std::ofstream(readOnlyFile) << "test";
chmod(readOnlyFile.c_str(), 0400);
ASSERT_TRUE(FileUtils::IsFileValid(readOnlyFile, errMsg, false));
ASSERT_TRUE(errMsg.empty());
}
TEST_F(FileUtilsTest, IsFileValid_WhenFileHasWrongPermissions_ReturnsFalse)
{
std::string errMsg;
chmod(testFile.c_str(), 0666);
ASSERT_TRUE(FileUtils::IsFileValid(testFile, errMsg, true, true));
ASSERT_TRUE(errMsg.empty());
}
TEST_F(FileUtilsTest, CheckOwner_WhenUserIsOwner_ReturnsTrue)
{
std::string errMsg;
ASSERT_TRUE(FileUtils::CheckOwner(testFile, errMsg));
ASSERT_TRUE(errMsg.empty());
}
TEST_F(FileUtilsTest, CheckOwner_WhenFileNotExists_ReturnsFalse)
{
std::string errMsg;
std::string nonExistent = testDir + "/non_existent";
ASSERT_FALSE(FileUtils::CheckOwner(nonExistent, errMsg));
ASSERT_FALSE(errMsg.empty());
}
TEST_F(FileUtilsTest, CheckPermission_WhenHasRequiredPermission_ReturnsTrue)
{
std::string errMsg;
chmod(testFile.c_str(), 0400);
ASSERT_TRUE(FileUtils::CheckPermission(testFile, 0400, false, errMsg));
ASSERT_TRUE(errMsg.empty());
}
TEST_F(FileUtilsTest, CheckPermission_WhenLacksRequiredPermission_ReturnsFalse)
{
std::string errMsg;
ASSERT_FALSE(FileUtils::CheckPermission(restrictedFile, 0020, false, errMsg));
ASSERT_FALSE(errMsg.empty());
}
TEST_F(FileUtilsTest, CheckPermission_OnlyCurrentUserOp_WhenOthersHavePermission_ReturnsFalse)
{
std::string errMsg;
chmod(testFile.c_str(), 0644);
ASSERT_FALSE(FileUtils::CheckPermission(testFile, 0400, true, errMsg));
ASSERT_FALSE(errMsg.empty());
}
TEST_F(FileUtilsTest, CheckPermission_WhenFileNotExists_ReturnsFalse)
{
std::string errMsg;
std::string nonExistent = testDir + "/non_existent";
ASSERT_FALSE(FileUtils::CheckPermission(nonExistent, 0400, false, errMsg));
ASSERT_FALSE(errMsg.empty());
}
TEST_F(FileUtilsTest, ParseTlsInfo_WhenValidInput_ReturnsTrue)
{
AccTlsOption tlsOpts;
std::string validTlsInfo = "cert=/path/to/cert.pem;key=/path/to/key.pem";
ASSERT_TRUE(FileUtils::ParseTlsInfo(validTlsInfo, tlsOpts));
}
TEST_F(FileUtilsTest, ParseTlsInfo_WhenInvalidInput_ReturnsFalse)
{
AccTlsOption tlsOpts;
std::string invalidTlsInfo = "invalid_format";
ASSERT_TRUE(FileUtils::ParseTlsInfo(invalidTlsInfo, tlsOpts));
}
TEST_F(FileUtilsTest, ParseTlsInfo_WhenEmptyInput_ReturnsFalse)
{
AccTlsOption tlsOpts;
ASSERT_TRUE(FileUtils::ParseTlsInfo("", tlsOpts));
}
TEST_F(FileUtilsTest, CheckFileExists_WhenPathIsEmpty_ReturnsFalse)
{
ASSERT_FALSE(FileUtils::CheckFileExists(""));
}
TEST_F(FileUtilsTest, CheckDirectoryExists_WhenPathIsEmpty_ReturnsFalse)
{
ASSERT_FALSE(FileUtils::CheckDirectoryExists(""));
}
TEST_F(FileUtilsTest, RegularFilePath_WhenPathContainsDotDot_ReturnsFalse)
{
std::string errMsg;
std::string pathWithDotDot = testDir + "/../test_file.txt";
ASSERT_FALSE(FileUtils::RegularFilePath(pathWithDotDot, testDir, errMsg));
ASSERT_FALSE(errMsg.empty());
}