blob: 0b0188fe32c1f11154d21be7d5cc6f3381520dd7 [file] [log] [blame]
/**
* 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 <filesystem>
#include <fstream>
#include <string>
#include <utility>
#include <gtest/gtest.h>
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<TemporarySubDirectory&&>(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()));
}