Files
Sunshine/tests/unit/test_config.cpp
T

152 lines
5.5 KiB
C++

/**
* @file tests/unit/test_config.cpp
* @brief Tests for Sunshine configuration persistence helpers.
*/
// test includes
#include "../tests_common.h"
// standard includes
#include <array>
#include <filesystem>
#include <string>
#include <utility>
// local includes
#include <src/config.h>
#include <src/file_handler.h>
using namespace std::literals;
TEST(ConfigDefaultsTest, UsesAutomaticGamepadSelection) {
EXPECT_EQ(config::input.gamepad, "auto");
}
using NvencPresetNameParam = std::pair<int, std::string_view>;
/**
* @brief Parameterized coverage for FFmpeg's symbolic NVENC preset names.
*/
struct NvencPresetNameTest: testing::TestWithParam<NvencPresetNameParam> {};
TEST_P(NvencPresetNameTest, UsesStableSymbolicName) {
const auto &[quality_preset, expected] = GetParam();
EXPECT_EQ(expected, config::nv::ffmpeg_preset_from_quality(quality_preset));
}
INSTANTIATE_TEST_SUITE_P(
NvencQualityPresets,
NvencPresetNameTest,
testing::Values(
NvencPresetNameParam {1, "p1"sv},
NvencPresetNameParam {2, "p2"sv},
NvencPresetNameParam {3, "p3"sv},
NvencPresetNameParam {4, "p4"sv},
NvencPresetNameParam {5, "p5"sv},
NvencPresetNameParam {6, "p6"sv},
NvencPresetNameParam {7, "p7"sv}
)
);
namespace {
/**
* @brief Fixture that redirects configuration persistence to a temporary file.
*/
class ConfigPersistenceTest: public testing::Test {
protected:
/**
* @brief Preserve the active config path and prepare an empty temporary path.
*/
void SetUp() override {
original_config_file_ = config::sunshine.config_file;
original_gamepad_driver_ = config::input.gamepad_driver;
original_gamepad_ = config::input.gamepad;
original_apps_file_ = config::stream.file_apps;
config_file_ = std::filesystem::temp_directory_path() / "sunshine_test_config_persistence.conf"; // NOSONAR(cpp:S5443): safe for tests
std::filesystem::remove(config_file_);
config::sunshine.config_file = config_file_.string();
config::input.gamepad_driver.clear();
}
/**
* @brief Remove the temporary file and restore the active config path.
*/
void TearDown() override {
config::sunshine.config_file = std::move(original_config_file_);
config::input.gamepad_driver = std::move(original_gamepad_driver_);
config::input.gamepad = std::move(original_gamepad_);
config::stream.file_apps = std::move(original_apps_file_);
std::filesystem::remove(config_file_.parent_path() / "sunshine_test_config_apps.json");
std::filesystem::remove(config_file_);
}
/**
* @brief Get the temporary configuration file used by the test.
*
* @return Temporary configuration file path.
*/
const std::filesystem::path &config_file() const {
return config_file_;
}
private:
std::filesystem::path config_file_; ///< Temporary configuration file used by the test.
std::string original_config_file_; ///< Active configuration path restored after each test.
std::string original_gamepad_driver_; ///< Gamepad driver preference restored after each test.
std::string original_gamepad_; ///< Gamepad profile restored after each test.
std::string original_apps_file_; ///< Applications file path restored after each test.
};
} // namespace
TEST_F(ConfigPersistenceTest, AppendsMissingOptionWithoutReplacingExistingText) {
ASSERT_EQ(file_handler::write_file(config_file().string().c_str(), "# retained comment"), 0);
EXPECT_TRUE(config::persist_config_option_if_missing("gamepad_driver", "all"));
EXPECT_EQ(
file_handler::read_file(config_file().string().c_str()),
"# retained comment\ngamepad_driver = all\n"
);
EXPECT_FALSE(config::persist_config_option_if_missing("gamepad_driver", "virtualhid"));
EXPECT_EQ(
file_handler::read_file(config_file().string().c_str()),
"# retained comment\ngamepad_driver = all\n"
);
}
TEST_F(ConfigPersistenceTest, DoesNotReplaceAnExistingOption) {
ASSERT_EQ(file_handler::write_file(config_file().string().c_str(), "gamepad_driver = vigembus\n"), 0);
EXPECT_FALSE(config::persist_config_option_if_missing("gamepad_driver", "all"));
EXPECT_EQ(file_handler::read_file(config_file().string().c_str()), "gamepad_driver = vigembus\n");
}
TEST_F(ConfigPersistenceTest, SelectsAllDriversOnlyForLicensedUsersWithoutAPreference) {
EXPECT_FALSE(config::select_all_gamepad_drivers_if_licensed(false));
EXPECT_TRUE(config::input.gamepad_driver.empty());
EXPECT_TRUE(file_handler::read_file(config_file().string().c_str()).empty());
EXPECT_TRUE(config::select_all_gamepad_drivers_if_licensed(true));
EXPECT_EQ(config::input.gamepad_driver, config::GAMEPAD_DRIVER_ALL);
EXPECT_EQ(file_handler::read_file(config_file().string().c_str()), "gamepad_driver = all\n");
EXPECT_FALSE(config::select_all_gamepad_drivers_if_licensed(true));
EXPECT_EQ(file_handler::read_file(config_file().string().c_str()), "gamepad_driver = all\n");
}
TEST_F(ConfigPersistenceTest, AcceptsAllGamepadProfilesAcrossRepeatedConfigurationChanges) {
const auto apps_file = config_file().parent_path() / "sunshine_test_config_apps.json";
ASSERT_EQ(file_handler::write_file(apps_file.string().c_str(), "{}"), 0);
config::stream.file_apps = apps_file.string();
constexpr std::array profiles {"generic"sv, "x360"sv, "xone"sv, "xseries"sv, "ds4"sv, "ds5"sv, "switch"sv};
for (const auto profile : profiles) {
config::input.gamepad = "auto";
config::apply_config_for_test(std::string {"gamepad = "} + std::string {profile} + "\n");
EXPECT_EQ(config::input.gamepad, profile);
}
}