/** * Copyright © 2024 IBM Corporation * * 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 "temporary_subdirectory.hpp" #include #include #include #include #include using namespace phosphor::power::util; namespace fs = std::filesystem; TEST(TemporarySubDirectoryTests, DefaultConstructor) { TemporarySubDirectory subdirectory{}; fs::path path = subdirectory.getPath(); EXPECT_FALSE(path.empty()); EXPECT_TRUE(fs::exists(path)); EXPECT_TRUE(fs::is_directory(path)); fs::path parentDir = path.parent_path(); EXPECT_EQ(parentDir, "/tmp"); std::string baseName = path.filename(); EXPECT_TRUE(baseName.starts_with("phosphor-power-")); } TEST(TemporarySubDirectoryTests, MoveConstructor) { // Create first object and verify subdirectory exists TemporarySubDirectory subdirectory1{}; EXPECT_FALSE(subdirectory1.getPath().empty()); EXPECT_TRUE(fs::exists(subdirectory1.getPath())); // Save path to subdirectory fs::path path = subdirectory1.getPath(); // Create second object by moving first object TemporarySubDirectory subdirectory2{std::move(subdirectory1)}; // Verify first object now has an empty path EXPECT_TRUE(subdirectory1.getPath().empty()); // Verify second object now owns same subdirectory and subdirectory exists EXPECT_EQ(subdirectory2.getPath(), path); EXPECT_TRUE(fs::exists(subdirectory2.getPath())); } TEST(TemporarySubDirectoryTests, MoveAssignmentOperator) { // Test where works: object is moved { // Create first object and verify subdirectory exists TemporarySubDirectory subdirectory1{}; EXPECT_FALSE(subdirectory1.getPath().empty()); EXPECT_TRUE(fs::exists(subdirectory1.getPath())); // Save path to first subdirectory fs::path path1 = subdirectory1.getPath(); // Create second object and verify subdirectory exists TemporarySubDirectory subdirectory2{}; EXPECT_FALSE(subdirectory2.getPath().empty()); EXPECT_TRUE(fs::exists(subdirectory2.getPath())); // Save path to second subdirectory fs::path path2 = subdirectory2.getPath(); // Verify temporary subdirectories are different EXPECT_NE(path1, path2); // Move first object into the second subdirectory2 = std::move(subdirectory1); // Verify first object now has an empty path EXPECT_TRUE(subdirectory1.getPath().empty()); // Verify second object now owns first subdirectory and subdirectory // exists EXPECT_EQ(subdirectory2.getPath(), path1); EXPECT_TRUE(fs::exists(path1)); // Verify second subdirectory was deleted EXPECT_FALSE(fs::exists(path2)); } // Test where does nothing: object moved into itself { // Create object and verify subdirectory exists TemporarySubDirectory subdirectory{}; EXPECT_FALSE(subdirectory.getPath().empty()); EXPECT_TRUE(fs::exists(subdirectory.getPath())); // Save path to subdirectory fs::path path = subdirectory.getPath(); // Try to move object into itself; should do nothing subdirectory = static_cast(subdirectory); // Verify object still owns same subdirectory and subdirectory exists EXPECT_EQ(subdirectory.getPath(), path); EXPECT_TRUE(fs::exists(path)); } // Test where fails: Cannot delete subdirectory { // Create first object and verify subdirectory exists TemporarySubDirectory subdirectory1{}; EXPECT_FALSE(subdirectory1.getPath().empty()); EXPECT_TRUE(fs::exists(subdirectory1.getPath())); // Save path to first subdirectory fs::path path1 = subdirectory1.getPath(); // Create second object and verify subdirectory exists TemporarySubDirectory subdirectory2{}; EXPECT_FALSE(subdirectory2.getPath().empty()); EXPECT_TRUE(fs::exists(subdirectory2.getPath())); // Save path to second subdirectory fs::path path2 = subdirectory2.getPath(); // Verify temporary subdirectories are different EXPECT_NE(path1, path2); // Change second subdirectory to unreadable so it cannot be removed fs::permissions(path2, fs::perms::none); try { // Try to move first object into the second; should throw exception subdirectory2 = std::move(subdirectory1); ADD_FAILURE() << "Should not have reached this line."; } catch (const std::exception& e) { // This is expected. Exception message will vary. } // Change second subdirectory to readable/writable so it can be removed fs::permissions(path2, fs::perms::owner_all); // Verify first object has not changed and first subdirectory exists EXPECT_EQ(subdirectory1.getPath(), path1); EXPECT_TRUE(fs::exists(path1)); // Verify second object has not changed and second subdirectory exists EXPECT_EQ(subdirectory2.getPath(), path2); EXPECT_TRUE(fs::exists(path2)); } } TEST(TemporarySubDirectoryTests, Destructor) { // Test where works: Subdirectory is deleted { fs::path path{}; { TemporarySubDirectory subdirectory{}; path = subdirectory.getPath(); EXPECT_TRUE(fs::exists(path)); } EXPECT_FALSE(fs::exists(path)); } // Test where works: Subdirectory was already deleted { fs::path path{}; { TemporarySubDirectory subdirectory{}; path = subdirectory.getPath(); EXPECT_TRUE(fs::exists(path)); subdirectory.remove(); EXPECT_FALSE(fs::exists(path)); } EXPECT_FALSE(fs::exists(path)); } // Test where fails: Cannot delete subdirectory: No exception thrown { fs::path path{}; try { TemporarySubDirectory subdirectory{}; path = subdirectory.getPath(); EXPECT_TRUE(fs::exists(path)); // Change subdirectory to unreadable so it cannot be removed fs::permissions(path, fs::perms::none); } catch (...) { ADD_FAILURE() << "Should not have caught exception."; } // Change subdirectory to readable/writable so it can be removed fs::permissions(path, fs::perms::owner_all); // Subdirectory should still exist EXPECT_TRUE(fs::exists(path)); // Delete subdirectory fs::remove_all(path); } } TEST(TemporarySubDirectoryTests, Remove) { // Test where works { // Create object and verify subdirectory exists TemporarySubDirectory subdirectory{}; EXPECT_FALSE(subdirectory.getPath().empty()); EXPECT_TRUE(fs::exists(subdirectory.getPath())); // Save path to subdirectory fs::path path = subdirectory.getPath(); // Delete subdirectory subdirectory.remove(); // Verify path is cleared and subdirectory does not exist EXPECT_TRUE(subdirectory.getPath().empty()); EXPECT_FALSE(fs::exists(path)); // Delete subdirectory again; should do nothing subdirectory.remove(); EXPECT_TRUE(subdirectory.getPath().empty()); EXPECT_FALSE(fs::exists(path)); } // Test where fails { // Create object and verify subdirectory exists TemporarySubDirectory subdirectory{}; EXPECT_FALSE(subdirectory.getPath().empty()); EXPECT_TRUE(fs::exists(subdirectory.getPath())); // Save path to subdirectory fs::path path = subdirectory.getPath(); // Change subdirectory to unreadable so it cannot be removed fs::permissions(path, fs::perms::none); try { // Try to delete subdirectory; should fail with exception subdirectory.remove(); ADD_FAILURE() << "Should not have reached this line."; } catch (const std::exception& e) { // This is expected. Exception message will vary. } // Change subdirectory to readable/writable so it can be deleted by // destructor fs::permissions(path, fs::perms::owner_all); } } TEST(TemporarySubDirectoryTests, GetPath) { TemporarySubDirectory subdirectory{}; EXPECT_FALSE(subdirectory.getPath().empty()); EXPECT_EQ(subdirectory.getPath().parent_path(), "/tmp"); EXPECT_TRUE(fs::exists(subdirectory.getPath())); }