From b8345246dcc2121bcb6d1515a9341789de20199f Mon Sep 17 00:00:00 2001 From: Dominick Allen Date: Sun, 27 Oct 2024 09:04:05 -0500 Subject: First crack at file objects. --- test/test_file.cpp | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 test/test_file.cpp (limited to 'test/test_file.cpp') diff --git a/test/test_file.cpp b/test/test_file.cpp new file mode 100644 index 0000000..06e6bcc --- /dev/null +++ b/test/test_file.cpp @@ -0,0 +1,97 @@ +/* + * libfud + * Copyright 2024 Dominick Allen + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "fud_file.hpp" +#include "fud_string.hpp" +#include "test_common.hpp" + +#include "gtest/gtest.h" +#include +#include +#include +#include +#include + +namespace fud { + +TEST(FudFile, Basic) +{ + constexpr const char* testDirCName = "/tmp/fud_directory_test"; + const auto testDirName{String::makeFromCString(testDirCName).takeOkay()}; + ASSERT_TRUE(testDirName.utf8Valid()); + constexpr mode_t pathMode = 0777; + + ASSERT_EQ(removeRecursive(testDirName), FudStatus::Success); + + auto mkdirResult = mkdir(testDirName.c_str(), pathMode); + EXPECT_EQ(mkdirResult, 0); + if (mkdirResult != 0) { + ASSERT_EQ(removeRecursive(testDirName), FudStatus::Success); + return; + } + + String testName1{String::makeFromCStrings(testDirCName, "/", "test1").takeOkay()}; + String testName2{String::makeFromCStrings(testDirCName, "/", "test2").takeOkay()}; + + auto rmFile = [](const auto& filename) -> int { + auto result = unlink(filename.c_str()); + if (result == -1) { + if (errno == ENOENT) { + return 0; + } + } + return result; + }; + ASSERT_EQ(rmFile(testName1), 0); + ASSERT_EQ(rmFile(testName2), 0); + + auto fileResult{RegularFile::open(testName1.asView(), FileAccessMode::Read, OpenFlags{}, NullOpt)}; + EXPECT_EQ(fileResult.takeErrorOr(FudStatus::Success), FudStatus::NotFound); + + /* The irony of the ability for TOCTOU bugs to be present in the test does + * not escape me. */ + + auto createFile = [](const auto& filename) -> int { + constexpr int allPerms = 0777; + auto handleResult = open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, allPerms); + if (handleResult >= 0) { + close(handleResult); + } + return handleResult; + }; + ASSERT_GE(createFile(testName1), 0); + + fileResult = RegularFile::open(testName1.asView(), FileAccessMode::Read, OpenFlags{}, NullOpt); + ASSERT_TRUE(fileResult.isOkay()); + auto file{fileResult.takeOkay()}; + ASSERT_EQ(file.close(), FudStatus::Success); + + ASSERT_EQ(rmFile(testName1), 0); + ASSERT_GE(createFile(testName2), 0); + ASSERT_EQ(symlink(testName2.c_str(), testName1.c_str()), 0); + + fileResult = RegularFile::open(testName2.asView(), FileAccessMode::Read, OpenFlags{}, NullOpt); + ASSERT_TRUE(fileResult.isOkay()); + file = fileResult.takeOkay(); + ASSERT_EQ(file.close(), FudStatus::Success); + + fileResult = RegularFile::open(testName1.asView(), FileAccessMode::Read, OpenFlags{}, NullOpt); + ASSERT_TRUE(fileResult.isError()); + EXPECT_EQ(fileResult.getError(), FudStatus::Failure); +} + +} // namespace fud -- cgit v1.2.3