* Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
* ubs-virt-ovs is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include "test_config_module.h"
#include <filesystem>
#include <fstream>
#include "config_manager.h"
#include "config_module.h"
using namespace virt::ovs::config;
namespace ovs::ut {
void TestConfigModule::SetUp() {}
void TestConfigModule::TearDown()
{
GlobalMockObject::verify();
GlobalMockObject::reset();
}
TEST_F(TestConfigModule, IsValidNumber)
{
EXPECT_TRUE(IsValidNumber("123", false));
EXPECT_FALSE(IsValidNumber("-123", false));
EXPECT_TRUE(IsValidNumber("-123.45", true));
EXPECT_FALSE(IsValidNumber("abc", false));
}
TEST_F(TestConfigModule, TrimConf)
{
auto [sec, key, val] = TrimConf(" sec ", " key ", " val ");
EXPECT_EQ(sec, "sec");
EXPECT_EQ(key, "key");
EXPECT_EQ(val, "val");
}
TEST_F(TestConfigModule, GetConf_Types)
{
auto &mgr = ConfigManager::GetInstance();
mgr.configMap["type_sec"]["uint_key"] = "42";
mgr.configMap["type_sec"]["ulong_key"] = "10000000000";
mgr.configMap["type_sec"]["float_key"] = "3.14";
mgr.configMap["type_sec"]["str_key"] = "hello";
mgr.configMap["type_sec"]["bool_key"] = "true";
ConfigModule mod;
uint32_t uval;
EXPECT_EQ(mod.GetConf("type_sec", "uint_key", uval), ConfigCode::OK);
EXPECT_EQ(uval, 42u);
uint64_t ulval;
EXPECT_EQ(mod.GetConf("type_sec", "ulong_key", ulval), ConfigCode::OK);
EXPECT_EQ(ulval, 10000000000ULL);
float fval;
EXPECT_EQ(mod.GetConf("type_sec", "float_key", fval), ConfigCode::OK);
EXPECT_FLOAT_EQ(fval, 3.14f);
std::string sval;
EXPECT_EQ(mod.GetConf("type_sec", "str_key", sval), ConfigCode::OK);
EXPECT_EQ(sval, "hello");
bool bval;
EXPECT_EQ(mod.GetConf("type_sec", "bool_key", bval), ConfigCode::OK);
EXPECT_TRUE(bval);
}
TEST_F(TestConfigModule, GetConf_InvalidType)
{
ConfigModule mod;
int unsupported;
EXPECT_EQ(mod.GetConf("type_sec", "any", unsupported), ConfigCode::VALUE_TYPE_NOT_SUPPORTED);
}
TEST_F(TestConfigModule, GetBoolConf_False)
{
auto &mgr = ConfigManager::GetInstance();
mgr.configMap["bool_sec"]["flag"] = "false";
ConfigModule mod;
bool val = true;
EXPECT_EQ(mod.GetConf("bool_sec", "flag", val), ConfigCode::OK);
EXPECT_FALSE(val);
}
TEST_F(TestConfigModule, GetBoolConf_Invalid)
{
auto &mgr = ConfigManager::GetInstance();
mgr.configMap["bool_sec"]["flag"] = "not_a_bool";
ConfigModule mod;
bool val = false;
EXPECT_EQ(mod.GetConf("bool_sec", "flag", val), ConfigCode::CONFIG_VALUE_INVALID);
}
TEST_F(TestConfigModule, GetUIntConf_InvalidNumber)
{
auto &mgr = ConfigManager::GetInstance();
mgr.configMap["num_sec"]["bad"] = "not_a_number";
ConfigModule mod;
uint32_t val = 0;
EXPECT_EQ(mod.GetConf("num_sec", "bad", val), ConfigCode::CONFIG_VALUE_INVALID);
}
TEST_F(TestConfigModule, GetFloatConf_InvalidNumber)
{
auto &mgr = ConfigManager::GetInstance();
mgr.configMap["num_sec"]["bad_float"] = "xyz";
ConfigModule mod;
float val = 0.0f;
EXPECT_EQ(mod.GetConf("num_sec", "bad_float", val), ConfigCode::CONFIG_VALUE_INVALID);
}
TEST_F(TestConfigModule, GetUIntConf_NegativeNumber)
{
auto &mgr = ConfigManager::GetInstance();
mgr.configMap["num_sec"]["neg"] = "-5";
ConfigModule mod;
uint32_t val = 0;
EXPECT_NE(mod.GetConf("num_sec", "neg", val), ConfigCode::OK);
}
TEST_F(TestConfigModule, IsValidNumber_MoreCases)
{
EXPECT_TRUE(IsValidNumber("0", false));
EXPECT_TRUE(IsValidNumber("1", false));
EXPECT_FALSE(IsValidNumber("01", false));
EXPECT_TRUE(IsValidNumber("3.0", true));
EXPECT_TRUE(IsValidNumber(".5", true));
EXPECT_TRUE(IsValidNumber("0.5", true));
EXPECT_TRUE(IsValidNumber("-0.5", true));
}
TEST_F(TestConfigModule, GetUIntConf_Overflow)
{
auto &mgr = ConfigManager::GetInstance();
mgr.configMap["num_sec"]["overflow32"] = "5000000000";
ConfigModule mod;
uint32_t val = 0;
EXPECT_EQ(mod.GetConf("num_sec", "overflow32", val), ConfigCode::CONFIG_ARGUMENT_INVALID);
}
TEST_F(TestConfigModule, GetUIntConf_OutOfRange)
{
auto &mgr = ConfigManager::GetInstance();
mgr.configMap["num_sec"]["huge"] = "999999999999999999999";
ConfigModule mod;
uint32_t val = 0;
EXPECT_EQ(mod.GetConf("num_sec", "huge", val), ConfigCode::CONFIG_OUT_OF_RANGE);
}
TEST_F(TestConfigModule, GetULongConf_InvalidNumber)
{
auto &mgr = ConfigManager::GetInstance();
mgr.configMap["num_sec"]["bad_ulong"] = "not_a_number";
ConfigModule mod;
uint64_t val = 0;
EXPECT_EQ(mod.GetConf("num_sec", "bad_ulong", val), ConfigCode::CONFIG_VALUE_INVALID);
}
TEST_F(TestConfigModule, GetStringConf_SectionNotFound)
{
ConfigModule mod;
std::string val;
EXPECT_EQ(mod.GetConf("nonexistent_sec_xyz", "any", val), ConfigCode::SECTION_NOT_EXIST);
}
TEST_F(TestConfigModule, GetStringConf_KeyNotFound)
{
auto &mgr = ConfigManager::GetInstance();
mgr.configMap["str_sec2"]["existing_key"] = "val";
mgr.configMap["str_sec2"].erase("no_key");
ConfigModule mod;
std::string val;
EXPECT_EQ(mod.GetConf("str_sec2", "no_key", val), ConfigCode::CONFIG_KEY_NOT_EXIST);
}
TEST_F(TestConfigModule, ConfigModule_Init)
{
ConfigModule mod;
auto ret = mod.Init("/nonexistent_config_dir");
EXPECT_NE(ret, ConfigCode::OK);
}
TEST_F(TestConfigModule, GetFloatConf_OutOfRange)
{
auto &mgr = ConfigManager::GetInstance();
std::string hugeFloat(400, '9');
hugeFloat += ".9";
mgr.configMap["num_sec"]["big_float"] = hugeFloat;
ConfigModule mod;
float val = 0.0f;
auto ret = mod.GetConf("num_sec", "big_float", val);
EXPECT_NE(ret, ConfigCode::OK);
}
TEST_F(TestConfigModule, GetUIntConf_SuccessZero)
{
auto &mgr = ConfigManager::GetInstance();
mgr.configMap["num_sec"]["zero"] = "0";
ConfigModule mod;
uint32_t val = 99;
EXPECT_EQ(mod.GetConf("num_sec", "zero", val), ConfigCode::OK);
EXPECT_EQ(val, 0u);
}
TEST_F(TestConfigModule, ConfigModule_InitSuccess)
{
std::filesystem::create_directory("test_cfg_mod_dir");
std::ofstream out("test_cfg_mod_dir/test.conf");
out << "[sec]\nkey=val\n";
out.close();
ConfigModule mod;
auto ret = mod.Init("test_cfg_mod_dir");
EXPECT_EQ(ret, ConfigCode::OK);
std::string val;
EXPECT_EQ(mod.GetConf("sec", "key", val), ConfigCode::OK);
EXPECT_EQ(val, "val");
std::filesystem::remove_all("test_cfg_mod_dir");
}
}