* Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
*
* 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.
*/
* Description: Perform unit tests on functions in the flags.cpp file.
*/
#include <cstdint>
#include <string>
#include <gtest/gtest.h>
#include "ut/common.h"
#include "datasystem/common/log/log.h"
#include "datasystem/worker/worker_update_flag_check.h"
#include "datasystem/common/util/gflag/flags.h"
DS_DEFINE_string(worker_address, "", "");
DS_DECLARE_int32(heartbeat_interval_ms);
DS_DECLARE_bool(log_compress);
DS_DECLARE_uint32(arena_per_tenant);
DS_DECLARE_uint32(log_async_queue_size);
DS_DECLARE_uint32(max_log_file_num);
DS_DECLARE_int32(logbufsecs);
DS_DECLARE_bool(log_monitor);
namespace datasystem {
namespace ut {
class FlagsTest : public CommonTest {};
TEST_F(FlagsTest, TestTrimSpace)
{
Flags flag;
std::string command1 = " -FlagName=Value ";
flag.TrimSpace(command1);
EXPECT_EQ(command1, "-FlagName=Value");
std::string command2 = " -FlagName = Value ";
flag.TrimSpace(command2);
EXPECT_EQ(command2, "-FlagName = Value");
}
TEST_F(FlagsTest, TestSplitArgument)
{
Flags flag;
std::string command1 = "--heartbeat_interval_ms=Value";
std::pair<std::string, std::string> kv1;
EXPECT_TRUE(flag.SplitArgument(command1.c_str(), kv1));
EXPECT_EQ(kv1.first, "heartbeat_interval_ms");
EXPECT_EQ(kv1.second, "Value");
std::string command2 = "--heartbeat_interval_ms = Value";
std::pair<std::string, std::string> kv2;
EXPECT_FALSE(flag.SplitArgument(command2.c_str(), kv2));
EXPECT_NE(kv2.first, "heartbeat_interval_ms");
EXPECT_NE(kv2.second, "Value");
std::string command3 = "-xx=Value";
std::pair<std::string, std::string> kv3;
EXPECT_FALSE(flag.SplitArgument(command3.c_str(), kv3));
EXPECT_NE(kv3.first, "xx");
EXPECT_NE(kv3.second, "Value");
}
TEST_F(FlagsTest, TestUpdateFlagParameter)
{
Flags flag;
std::unordered_map<std::string, std::string> flagMap{ { "v", "3" },
{ "max_log_file_num", "20" },
{ "logbufsecs", "15" } };
flag.UpdateFlagParameter(flagMap);
EXPECT_EQ(FLAGS_v, 3);
EXPECT_EQ(FLAGS_max_log_file_num, 20ul);
EXPECT_EQ(FLAGS_logbufsecs, 15);
}
TEST_F(FlagsTest, TestValidateFlagName)
{
Flags flag;
EXPECT_FALSE(flag.ValidateFlagName("logbufsecs"));
EXPECT_TRUE(flag.ValidateFlagName("log_compress"));
EXPECT_TRUE(flag.ValidateFlagName("minloglevel"));
EXPECT_TRUE(flag.ValidateFlagName("log_monitor"));
}
TEST_F(FlagsTest, TestFindFirstSeparator)
{
Flags flag;
std::string context1 = " -flagName=value\r\n ";
auto index1 = flag.FindFirstSeparator(context1);
EXPECT_EQ(index1, 0);
std::string context2 = "-flagName=value\r\n ";
auto index2 = flag.FindFirstSeparator(context2);
EXPECT_EQ(index2, 15);
std::string context3 = "-flagName=value\n ";
auto index3 = flag.FindFirstSeparator(context3);
EXPECT_EQ(index3, 15);
std::string context4 = "-flagName=value";
auto index4 = flag.FindFirstSeparator(context3);
EXPECT_EQ(index4, 15);
std::string context5 = "-flagName=value\t";
auto index5 = flag.FindFirstSeparator(context5);
EXPECT_EQ(index5, 15);
}
TEST_F(FlagsTest, TestProcessOptions)
{
Flags flag;
std::string fileContext =
"-heartbeat_interval_ms=10\n--v=3\r\n-log_async_queue_size=4096\r-log_compress=false\t-max_log_file_num=22 "
"-arena_per_tenant=30";
auto flagMap = flag.ProcessOptions(fileContext);
flag.UpdateFlagParameter(flagMap);
EXPECT_EQ(FLAGS_heartbeat_interval_ms, 10);
EXPECT_EQ(FLAGS_v, 3);
EXPECT_EQ(FLAGS_log_async_queue_size, static_cast<uint32_t>(4096));
EXPECT_FALSE(FLAGS_log_compress);
EXPECT_EQ(FLAGS_max_log_file_num, static_cast<uint32_t>(22));
EXPECT_EQ(FLAGS_arena_per_tenant, static_cast<uint32_t>(30));
}
TEST_F(FlagsTest, TestProcessOptionsUpdatesRuntimeLogControlFlags)
{
auto oldMinLogLevel = FLAGS_minloglevel;
auto oldLogMonitor = FLAGS_log_monitor;
FLAGS_minloglevel = 0;
FLAGS_log_monitor = true;
Flags flag;
auto flagMap = flag.ProcessOptions("-minloglevel=2\n-log_monitor=false");
EXPECT_EQ(flagMap.count("minloglevel"), 1ul);
EXPECT_EQ(flagMap.count("log_monitor"), 1ul);
flag.UpdateFlagParameter(flagMap);
EXPECT_EQ(FLAGS_minloglevel, 2);
EXPECT_FALSE(FLAGS_log_monitor);
FLAGS_minloglevel = oldMinLogLevel;
FLAGS_log_monitor = oldLogMonitor;
}
TEST_F(FlagsTest, TestWorkerFlagValidateSpecial)
{
std::string flagName = "node_dead_timeout_s";
std::string newVal = "50";
EXPECT_TRUE(WorkerFlagValidateSpecial(flagName, newVal));
flagName = "heartbeat_interval_ms";
newVal = "70000";
EXPECT_TRUE(WorkerFlagValidateSpecial(flagName, newVal));
}
}
}