// Copyright 2025 Huawei Cloud Computing Technology Co., Ltd. // // 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 "src/utils/cpp/tmp_dir.hpp" #include #include #include #include #include "catch2/catch_test_macros.hpp" #include "src/buildtool/file_system/file_system_manager.hpp" TEST_CASE("tmp_dir", "[tmp_dir]") { char const* const env_tmpdir = std::getenv("TEST_TMPDIR"); REQUIRE(env_tmpdir != nullptr); auto const test_tempdir = std::filesystem::path{std::string{env_tmpdir}} / ".test_build_root"; REQUIRE(FileSystemManager::CreateDirectory(test_tempdir)); SECTION("simple") { // Create a temp directory auto temp_dir = TmpDir::Create(test_tempdir / "test_dir"); REQUIRE(temp_dir != nullptr); // Create one more temp directory at the same location to ensure the // template gets populated, and a new directory gets created auto temp_dir_2 = TmpDir::Create(test_tempdir / "test_dir"); REQUIRE(temp_dir_2 != nullptr); std::filesystem::path const temp_dir_path = temp_dir->GetPath(); REQUIRE(FileSystemManager::Exists(temp_dir_path)); { auto temp_dir_clone = temp_dir; temp_dir = nullptr; REQUIRE(FileSystemManager::Exists(temp_dir_path)); } REQUIRE(not FileSystemManager::Exists(temp_dir_path)); std::filesystem::path const temp_dir_path_2 = temp_dir_2->GetPath(); REQUIRE(FileSystemManager::Exists(temp_dir_path_2)); { auto temp_dir_clone = temp_dir_2; temp_dir_2 = nullptr; REQUIRE(FileSystemManager::Exists(temp_dir_path_2)); } REQUIRE(not FileSystemManager::Exists(temp_dir_path_2)); } SECTION("nested directories") { auto parent_dir = TmpDir::Create(test_tempdir / "test_dir"); REQUIRE(parent_dir != nullptr); std::filesystem::path const parent = parent_dir->GetPath(); auto child_dir_1 = TmpDir::CreateNestedDirectory(parent_dir); REQUIRE(child_dir_1); std::filesystem::path const child_1 = child_dir_1->GetPath(); auto child_dir_2 = TmpDir::CreateNestedDirectory(parent_dir); REQUIRE(child_dir_2); std::filesystem::path const child_2 = child_dir_2->GetPath(); REQUIRE(FileSystemManager::Exists(parent)); REQUIRE(FileSystemManager::Exists(child_1)); REQUIRE(FileSystemManager::Exists(child_2)); // Kill the parent directory. child_1 and child_2 still retain // references to the parent object, so all folders should remain alive: parent_dir = nullptr; REQUIRE(FileSystemManager::Exists(parent)); REQUIRE(FileSystemManager::Exists(child_1)); REQUIRE(FileSystemManager::Exists(child_2)); // Kill child_1. child_1 dies, but child_2 retains a reference to the // parent directory, so parent and child_2 must be alive: child_dir_1 = nullptr; REQUIRE(FileSystemManager::Exists(parent)); REQUIRE(not FileSystemManager::Exists(child_1)); REQUIRE(FileSystemManager::Exists(child_2)); // Kill child_2. All directories should be destroyed: child_dir_2 = nullptr; REQUIRE(not FileSystemManager::Exists(parent)); REQUIRE(not FileSystemManager::Exists(child_1)); REQUIRE(not FileSystemManager::Exists(child_2)); } SECTION("temp files") { auto parent_dir = TmpDir::Create(test_tempdir / "test_dir"); REQUIRE(parent_dir != nullptr); std::filesystem::path const parent = parent_dir->GetPath(); auto file = TmpDir::CreateFile(parent_dir); REQUIRE(file != nullptr); std::filesystem::path const file_path = file->GetPath(); REQUIRE(FileSystemManager::Exists(parent)); REQUIRE(FileSystemManager::Exists(file_path)); // Kill the parent directory. File still retains a reference to the // parent object, so parent should remain alive: parent_dir = nullptr; REQUIRE(FileSystemManager::Exists(parent)); REQUIRE(FileSystemManager::Exists(file_path)); // Kill the file. Both the parent directory and the file should be // deleted: file = nullptr; REQUIRE(not FileSystemManager::Exists(parent)); REQUIRE(not FileSystemManager::Exists(file_path)); } }