diff --git a/include/common/tglobal.h b/include/common/tglobal.h index c9d4e0f616dd..f1ff2efb8ad1 100644 --- a/include/common/tglobal.h +++ b/include/common/tglobal.h @@ -414,6 +414,13 @@ extern int32_t tsAuthReqHBInterval; extern char tsAuthReqUrl[]; extern bool tsSessionControl; +// cls +extern bool tsClsEnabled; +extern char tsClsUrl[]; +extern char tsClsLicenseId[]; +extern int32_t tsClsRefreshInterval; +extern int32_t gGrantClsPreRefreshInterval; + int32_t taosCreateLog(const char *logname, int32_t logFileNum, const char *cfgDir, const char **envCmd, const char *envFile, char *apolloUrl, SArray *pArgs, bool tsc); int32_t taosReadDataFolder(const char *cfgDir, const char **envCmd, const char *envFile, char *apolloUrl, diff --git a/include/common/tmsgdef.h b/include/common/tmsgdef.h index 31bd5ad4e4eb..bdc8b3fe76d6 100644 --- a/include/common/tmsgdef.h +++ b/include/common/tmsgdef.h @@ -491,6 +491,7 @@ TD_DEF_MSG_TYPE(TDMT_MND_KILL_TRIM, "kill-trim", SKillRetentionReq, NULL) TD_DEF_MSG_TYPE(TDMT_MND_ALTER_RSMA, "alter-rsma", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_AUTH_HB_TIMER, "auth-hb-tmr", NULL, NULL) + TD_DEF_MSG_TYPE(TDMT_MND_CLS_HB_TIMER, "cls-hb-tmr", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_AUTH_CHECK, "auth-check", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_REGISTER_INSTANCE, "register-instance", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_LIST_INSTANCES, "list-instances", NULL, NULL) diff --git a/include/util/tdef.h b/include/util/tdef.h index c51c3ad5d66f..96078bf3cb23 100644 --- a/include/util/tdef.h +++ b/include/util/tdef.h @@ -467,6 +467,8 @@ typedef enum { #define TSDB_CLUSTER_VALUE_LEN 1000 #define TSDB_GRANT_LOG_COL_LEN 15600 +#define TSDB_GRANT_CLS_RESP_LEN (32*1024) + #define TSDB_ACTIVE_KEY_LEN 109 #define TSDB_CONN_ACTIVE_KEY_LEN 255 diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index 6accc2d1a6bd..f81f4ac8c057 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -34,6 +34,14 @@ // GRANT_CFG_DECLARE; +#ifdef TD_ENTERPRISE +static bool taosIsClsDerivedRefreshInterval(int32_t interval); +static int32_t taosCheckClsRefreshIntervalValue(int32_t interval, ECfgSrcType stype); +static void taosBackupClsRefreshInterval(int32_t interval); +static int32_t taosSetClsDerivedRefreshInterval(int32_t interval); +static int32_t taosHandleClsEnabledChange(bool enabled); +#endif + SConfig *tsCfg = NULL; // cluster char tsFirst[TSDB_EP_LEN] = {0}; @@ -118,6 +126,11 @@ bool tsAuthReq = 0; int32_t tsAuthReqInterval = 2592000; int32_t tsAuthReqHBInterval = 5; char tsAuthReqUrl[TSDB_FQDN_LEN] = {0}; +bool tsClsEnabled = 0; +char tsClsUrl[TSDB_FQDN_LEN] = {0}; +char tsClsLicenseId[TSDB_FQDN_LEN] = {0}; +int32_t tsClsRefreshInterval = 3600; +int32_t gGrantClsPreRefreshInterval = 3600; #endif int32_t tsNumOfQueryThreads = 0; @@ -1143,6 +1156,10 @@ static int32_t taosAddServerCfg(SConfig *pCfg) { TAOS_CHECK_RETURN(cfgAddBool(pCfg, "authReq", tsAuthReq, CFG_SCOPE_SERVER, CFG_DYN_SERVER, CFG_CATEGORY_GLOBAL, CFG_PRIV_SYSTEM)); TAOS_CHECK_RETURN(cfgAddInt32(pCfg, "authReqInterval", tsAuthReqInterval, 1, 86400 * 30, CFG_SCOPE_SERVER, CFG_DYN_SERVER, CFG_CATEGORY_GLOBAL, CFG_PRIV_SYSTEM)); TAOS_CHECK_RETURN(cfgAddString(pCfg, "authReqUrl", tsAuthReqUrl, CFG_SCOPE_SERVER, CFG_DYN_SERVER, CFG_CATEGORY_GLOBAL, CFG_PRIV_SYSTEM)); + TAOS_CHECK_RETURN(cfgAddBool(pCfg, "clsEnabled", tsClsEnabled, CFG_SCOPE_SERVER, CFG_DYN_SERVER, CFG_CATEGORY_GLOBAL, CFG_PRIV_SYSTEM)); + TAOS_CHECK_RETURN(cfgAddString(pCfg, "clsUrl", tsClsUrl, CFG_SCOPE_SERVER, CFG_DYN_SERVER, CFG_CATEGORY_GLOBAL, CFG_PRIV_SYSTEM)); + TAOS_CHECK_RETURN(cfgAddString(pCfg, "clsLicenseId", tsClsLicenseId, CFG_SCOPE_SERVER, CFG_DYN_SERVER, CFG_CATEGORY_GLOBAL, CFG_PRIV_SYSTEM)); + TAOS_CHECK_RETURN(cfgAddInt32(pCfg, "clsRefreshInterval", tsClsRefreshInterval, 10, 86400, CFG_SCOPE_SERVER, CFG_DYN_SERVER, CFG_CATEGORY_GLOBAL, CFG_PRIV_SYSTEM)); #endif // clang-format on @@ -1819,6 +1836,21 @@ static int32_t taosSetServerCfg(SConfig *pCfg) { TAOS_CHECK_GET_CFG_ITEM(pCfg, pItem, "authReqUrl"); TAOS_CHECK_RETURN(taosCheckCfgStrValueLen(pItem->name, pItem->str, TSDB_FQDN_LEN)); tstrncpy(tsAuthReqUrl, pItem->str, TSDB_FQDN_LEN); + + TAOS_CHECK_GET_CFG_ITEM(pCfg, pItem, "clsRefreshInterval"); + TAOS_CHECK_RETURN(taosCheckClsRefreshIntervalValue(pItem->i32, pItem->stype)); + tsClsRefreshInterval = pItem->i32; + + TAOS_CHECK_GET_CFG_ITEM(pCfg, pItem, "clsUrl"); + TAOS_CHECK_RETURN(taosCheckCfgStrValueLen(pItem->name, pItem->str, TSDB_FQDN_LEN)); + tstrncpy(tsClsUrl, pItem->str, TSDB_FQDN_LEN); + + TAOS_CHECK_GET_CFG_ITEM(pCfg, pItem, "clsLicenseId"); + TAOS_CHECK_RETURN(taosCheckCfgStrValueLen(pItem->name, pItem->str, TSDB_FQDN_LEN)); + tstrncpy(tsClsLicenseId, pItem->str, TSDB_FQDN_LEN); + + TAOS_CHECK_GET_CFG_ITEM(pCfg, pItem, "clsEnabled"); + TAOS_CHECK_RETURN(taosHandleClsEnabledChange(pItem->bval)); #endif TAOS_CHECK_GET_CFG_ITEM(pCfg, pItem, "retentionSpeedLimitMB"); @@ -2381,6 +2413,45 @@ static int32_t cfgInitWrapper(SConfig **pCfg) { TAOS_RETURN(TSDB_CODE_SUCCESS); } +#ifdef TD_ENTERPRISE +static bool taosIsClsDerivedRefreshInterval(int32_t interval) { return interval == 1 || interval == 2; } + +static int32_t taosCheckClsRefreshIntervalValue(int32_t interval, ECfgSrcType stype) { + bool isAlterSource = (stype == CFG_STYPE_ALTER_CLIENT_CMD || stype == CFG_STYPE_ALTER_SERVER_CMD); + + if ((interval >= 10 && interval <= 86400) || (!isAlterSource && taosIsClsDerivedRefreshInterval(interval))) { + TAOS_RETURN(TSDB_CODE_SUCCESS); + } + + uError("cfg:clsRefreshInterval, value:%d out of range[10, 86400]", interval); + TAOS_RETURN(TSDB_CODE_OUT_OF_RANGE); +} + +static void taosBackupClsRefreshInterval(int32_t interval) { + if (!taosIsClsDerivedRefreshInterval(interval)) { + gGrantClsPreRefreshInterval = interval; + } +} + +static int32_t taosSetClsDerivedRefreshInterval(int32_t interval) { + tsClsRefreshInterval = interval; + TAOS_RETURN(TSDB_CODE_SUCCESS); +} + +static int32_t taosHandleClsEnabledChange(bool enabled) { + bool oldEnabled = tsClsEnabled; + + tsClsEnabled = enabled; + if (oldEnabled == enabled) { + TAOS_RETURN(TSDB_CODE_SUCCESS); + } + + taosBackupClsRefreshInterval(tsClsRefreshInterval); + TAOS_CHECK_RETURN(taosSetClsDerivedRefreshInterval(enabled ? 2 : 1)); + TAOS_RETURN(TSDB_CODE_SUCCESS); +} +#endif + int32_t setAllConfigs(SConfig *pCfg) { int32_t code = 0; int32_t lino = -1; @@ -2921,6 +2992,25 @@ static int32_t taosCfgDynamicOptionsForServer(SConfig *pCfg, const char *name) { tstrncpy(tsAuthReqUrl, pItem->str, TSDB_FQDN_LEN); goto _exit; } + if (strcasecmp(name, "clsEnabled") == 0) { + TAOS_CHECK_GOTO(taosHandleClsEnabledChange(pItem->bval), &lino, _exit); + goto _exit; + } + if (strcasecmp(name, "clsUrl") == 0) { + TAOS_CHECK_GOTO(taosCheckCfgStrValueLen(pItem->name, pItem->str, TSDB_FQDN_LEN), &lino, _exit); + tstrncpy(tsClsUrl, pItem->str, TSDB_FQDN_LEN); + goto _exit; + } + if (strcasecmp(name, "clsLicenseId") == 0) { + TAOS_CHECK_GOTO(taosCheckCfgStrValueLen(pItem->name, pItem->str, TSDB_FQDN_LEN), &lino, _exit); + tstrncpy(tsClsLicenseId, pItem->str, TSDB_FQDN_LEN); + goto _exit; + } + if (strcasecmp(name, "clsRefreshInterval") == 0) { + TAOS_CHECK_GOTO(taosCheckClsRefreshIntervalValue(pItem->i32, pItem->stype), &lino, _exit); + tsClsRefreshInterval = pItem->i32; + goto _exit; + } #endif if (strcasecmp(name, "minReservedMemorySize") == 0) { diff --git a/source/common/test/commonTests.cpp b/source/common/test/commonTests.cpp index b02a6c3551d3..880728a5543f 100644 --- a/source/common/test/commonTests.cpp +++ b/source/common/test/commonTests.cpp @@ -20,9 +20,35 @@ #include "tanalytics.h" #include "tglobal.h" +#ifdef TD_ENTERPRISE namespace { -// +class ClsConfigDynamicTest : public ::testing::Test { + protected: + void SetUp() override { + taosCleanupCfg(); + tsClsEnabled = false; + tsClsRefreshInterval = 3600; + gGrantClsPreRefreshInterval = 3600; + ASSERT_EQ(cfgInit(&tsCfg), TSDB_CODE_SUCCESS); + ASSERT_EQ(cfgAddBool(tsCfg, "clsEnabled", tsClsEnabled, CFG_SCOPE_SERVER, CFG_DYN_SERVER, CFG_CATEGORY_GLOBAL, + CFG_PRIV_SYSTEM), + TSDB_CODE_SUCCESS); + ASSERT_EQ(cfgAddInt32(tsCfg, "clsRefreshInterval", tsClsRefreshInterval, 1, 86400, CFG_SCOPE_SERVER, + CFG_DYN_SERVER, CFG_CATEGORY_GLOBAL, CFG_PRIV_SYSTEM), + TSDB_CODE_SUCCESS); + } + + void TearDown() override { taosCleanupCfg(); } + + void applyServerConfig(const char *name, const char *value, ECfgSrcType stype = CFG_STYPE_ALTER_SERVER_CMD) { + SConfig *pCfg = taosGetCfg(); + ASSERT_NE(pCfg, nullptr); + ASSERT_EQ(cfgSetItem(pCfg, name, value, stype, true), TSDB_CODE_SUCCESS); + ASSERT_EQ(taosCfgDynamicOptions(pCfg, name, true), TSDB_CODE_SUCCESS); + } +}; } // namespace +#endif int main(int argc, char** argv) { testing::InitGoogleTest(&argc, argv); @@ -238,6 +264,39 @@ TEST(testCase, toInteger_test) { ASSERT_EQ(ret, -1); } +#ifdef TD_ENTERPRISE +TEST_F(ClsConfigDynamicTest, clsEnabledTransitionKeepsLastExplicitRefreshInterval) { + ASSERT_EQ(tsClsEnabled, false); + ASSERT_EQ(tsClsRefreshInterval, 3600); + + applyServerConfig("clsRefreshInterval", "30"); + ASSERT_EQ(tsClsRefreshInterval, 30); + + applyServerConfig("clsEnabled", "1"); + ASSERT_EQ(tsClsEnabled, true); + ASSERT_EQ(gGrantClsPreRefreshInterval, 30); + ASSERT_EQ(tsClsRefreshInterval, 2); + + applyServerConfig("clsEnabled", "0"); + ASSERT_EQ(tsClsEnabled, false); + ASSERT_EQ(gGrantClsPreRefreshInterval, 30); + ASSERT_EQ(tsClsRefreshInterval, 1); + + applyServerConfig("clsEnabled", "1"); + ASSERT_EQ(tsClsEnabled, true); + ASSERT_EQ(gGrantClsPreRefreshInterval, 30); + ASSERT_EQ(tsClsRefreshInterval, 2); + + applyServerConfig("clsRefreshInterval", "40"); + ASSERT_EQ(tsClsRefreshInterval, 40); + + applyServerConfig("clsEnabled", "0"); + ASSERT_EQ(tsClsEnabled, false); + ASSERT_EQ(gGrantClsPreRefreshInterval, 40); + ASSERT_EQ(tsClsRefreshInterval, 1); +} +#endif + TEST(testCase, dmRepairDefaultsToNoWalRepair) { ASSERT_FALSE(dmRepairNeedWalRepair(123)); } diff --git a/source/dnode/mnode/impl/inc/mndDef.h b/source/dnode/mnode/impl/inc/mndDef.h index a09473cdd814..d5dcebfe8798 100644 --- a/source/dnode/mnode/impl/inc/mndDef.h +++ b/source/dnode/mnode/impl/inc/mndDef.h @@ -1472,6 +1472,17 @@ typedef struct { SRWLatch lock; } SGrantLogObj; +typedef struct { + int32_t id; + int32_t clsRespLen; + char* clsResp; + bool isValid; + int32_t extendLen; + char* extend; + int64_t updateTime; + SRWLatch lock; +} SGrantClsObj; + #ifdef __cplusplus } #endif diff --git a/source/dnode/mnode/impl/src/mndConfig.c b/source/dnode/mnode/impl/src/mndConfig.c index 7cb4609091af..b104c2eedb56 100644 --- a/source/dnode/mnode/impl/src/mndConfig.c +++ b/source/dnode/mnode/impl/src/mndConfig.c @@ -22,8 +22,9 @@ #include "mndSync.h" #include "mndTrans.h" #include "mndUser.h" -#include "tutil.h" #include "tcompare.h" +#include "tunit.h" +#include "tutil.h" #define CFG_VER_NUMBER 1 #define CFG_RESERVE_SIZE 63 @@ -63,6 +64,31 @@ int32_t mndSetCreateConfigCommitLogs(STrans *pTrans, SConfigObj *obj); int32_t mndSetDeleteConfigCommitLogs(STrans *pTrans, SConfigObj *item); int32_t mndSetCreateConfigPrepareLogs(STrans *pTrans, SConfigObj *obj); +static void mndNormalizeAlterConfigValue(const char *name, char *value, int32_t valueLen) { +#ifdef TD_ENTERPRISE + if (strcasecmp(name, "clsRefreshInterval") != 0) { + return; + } + + int32_t interval = 0; + if (taosStrHumanToInt32(value, &interval) != TSDB_CODE_SUCCESS) { + return; + } + + if (interval < 10) { + interval = 10; + } else if (interval > 86400) { + interval = 86400; + } + + (void)snprintf(value, valueLen, "%d", interval); +#else + (void)name; + (void)value; + (void)valueLen; +#endif +} + int32_t mndInitConfig(SMnode *pMnode) { int32_t code = 0; SSdbTable table = {.sdbType = SDB_CFG, @@ -833,6 +859,8 @@ static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) { updateWhiteList = 1; } + mndNormalizeAlterConfigValue(dcfgReq.config, dcfgReq.value, sizeof(dcfgReq.value)); + CfgAlterType alterType = (cfgReq.dnodeId == 0 || cfgReq.dnodeId == -1) ? CFG_ALTER_ALL_DNODES : CFG_ALTER_DNODE; TAOS_CHECK_GOTO(cfgCheckRangeForDynUpdate(taosGetCfg(), dcfgReq.config, dcfgReq.value, true, alterType), &lino, _err_out); diff --git a/source/dnode/mnode/impl/src/mndMain.c b/source/dnode/mnode/impl/src/mndMain.c index 9296afe128b3..1d9944afe003 100644 --- a/source/dnode/mnode/impl/src/mndMain.c +++ b/source/dnode/mnode/impl/src/mndMain.c @@ -286,6 +286,18 @@ static void mndPullupAuth(SMnode *pMnode) { } } +static void mndPullupCls(SMnode *pMnode) { + mTrace("pullup cls msg"); + int32_t contLen = 0; + void *pReq = mndBuildTimerMsg(&contLen); + if (pReq != NULL) { + SRpcMsg rpcMsg = {.msgType = TDMT_MND_CLS_HB_TIMER, .pCont = pReq, .contLen = contLen, .info.notFreeAhandle = 1, .info.ahandle = 0}; + if (tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, &rpcMsg) < 0) { + mError("failed to put into write-queue since %s, line:%d", terrstr(), __LINE__); + } + } +} + static void mndIncreaseUpTime(SMnode *pMnode) { mTrace("increate uptime"); int32_t contLen = 0; @@ -409,6 +421,9 @@ static int32_t minCronTime() { min = TMIN(min, telemInt); min = TMIN(min, tsGrantHBInterval); min = TMIN(min, tsUptimeInterval); +#ifdef TD_ENTERPRISE + if (tsClsEnabled) min = TMIN(min, tsClsRefreshInterval); +#endif return min <= 1 ? 2 : min; } @@ -455,6 +470,9 @@ void mndDoTimerPullupTask(SMnode *pMnode, int64_t sec) { mndPullupAuth(pMnode); } } + if (sec % tsClsRefreshInterval == 0) { + mndPullupCls(pMnode); + } #endif if (sec % tsTransPullupInterval == 0) { mndPullupTrans(pMnode); @@ -1101,7 +1119,8 @@ static int32_t mndCheckMnodeState(SRpcMsg *pMsg) { pMsg->msgType == TDMT_MND_SSMIGRATE_DB_TIMER || pMsg->msgType == TDMT_MND_ARB_HEARTBEAT_TIMER || pMsg->msgType == TDMT_MND_ARB_CHECK_SYNC_TIMER || pMsg->msgType == TDMT_MND_CHECK_STREAM_TIMER || pMsg->msgType == TDMT_MND_UPDATE_SSMIGRATE_PROGRESS_TIMER || pMsg->msgType == TDMT_MND_SCAN_TIMER || - pMsg->msgType == TDMT_MND_QUERY_TRIM_TIMER || pMsg->msgType == TDMT_MND_AUTH_HB_TIMER) { + pMsg->msgType == TDMT_MND_QUERY_TRIM_TIMER || pMsg->msgType == TDMT_MND_AUTH_HB_TIMER || + pMsg->msgType == TDMT_MND_CLS_HB_TIMER) { mTrace("timer not process since mnode restored:%d stopped:%d, sync restored:%d role:%s ", pMnode->restored, pMnode->stopped, state.restored, syncStr(state.state)); TAOS_RETURN(code); diff --git a/source/dnode/mnode/sdb/inc/sdb.h b/source/dnode/mnode/sdb/inc/sdb.h index 0b8d9b514492..28256d8e2b4b 100644 --- a/source/dnode/mnode/sdb/inc/sdb.h +++ b/source/dnode/mnode/sdb/inc/sdb.h @@ -190,7 +190,8 @@ typedef enum { SDB_XNODE_JOB = 45, SDB_XNODE_USER_PASS = 46, SDB_SECURITY_POLICY = 47, - SDB_MAX = 48 + SDB_GRANT_CLS = 48, + SDB_MAX = 49 } ESdbType; typedef struct SSdbRaw { diff --git a/source/util/src/tconfig.c b/source/util/src/tconfig.c index ceb2034bdadb..aa7bcfafaf15 100644 --- a/source/util/src/tconfig.c +++ b/source/util/src/tconfig.c @@ -1721,4 +1721,4 @@ void cfgDestroyIter(SConfigIter *pIter) { } SArray *taosGetLocalCfg(SConfig *pCfg) { return pCfg->localArray; } -SArray *taosGetGlobalCfg(SConfig *pCfg) { return pCfg->globalArray; } \ No newline at end of file +SArray *taosGetGlobalCfg(SConfig *pCfg) { return pCfg->globalArray; } diff --git a/source/util/test/cfgTest.cpp b/source/util/test/cfgTest.cpp index ca106b60043c..db227575df6f 100644 --- a/source/util/test/cfgTest.cpp +++ b/source/util/test/cfgTest.cpp @@ -226,6 +226,49 @@ TEST_F(CfgTest, initWithArray) { ASSERT_EQ(code, TSDB_CODE_SUCCESS); } +TEST_F(CfgTest, clsRefreshIntervalAlterRange) { + SConfig *pConfig = NULL; + int32_t code = cfgInit(&pConfig); + SConfigItem *pItem = NULL; + + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + ASSERT_NE(pConfig, nullptr); + + ASSERT_EQ(cfgAddInt32(pConfig, "clsRefreshInterval", 3600, 10, 86400, CFG_SCOPE_SERVER, CFG_DYN_SERVER, + CFG_CATEGORY_GLOBAL, CFG_PRIV_SYSTEM), + TSDB_CODE_SUCCESS); + + EXPECT_EQ(cfgCheckRangeForDynUpdate(pConfig, "clsRefreshInterval", "9", true, CFG_ALTER_LOCAL), + TSDB_CODE_OUT_OF_RANGE); + EXPECT_EQ(cfgCheckRangeForDynUpdate(pConfig, "clsRefreshInterval", "10", true, CFG_ALTER_LOCAL), TSDB_CODE_SUCCESS); + EXPECT_EQ(cfgCheckRangeForDynUpdate(pConfig, "clsRefreshInterval", "86400", true, CFG_ALTER_ALL_DNODES), + TSDB_CODE_SUCCESS); + EXPECT_EQ(cfgCheckRangeForDynUpdate(pConfig, "clsRefreshInterval", "86401", true, CFG_ALTER_ALL_DNODES), + TSDB_CODE_OUT_OF_RANGE); + + pItem = cfgGetItem(pConfig, "clsRefreshInterval"); + ASSERT_NE(pItem, nullptr); + EXPECT_EQ(pItem->i32, 3600); + + ASSERT_EQ(cfgSetItem(pConfig, "clsRefreshInterval", "9", CFG_STYPE_ALTER_CLIENT_CMD, true), TSDB_CODE_OUT_OF_RANGE); + EXPECT_EQ(pItem->i32, 3600); + + ASSERT_EQ(cfgSetItem(pConfig, "clsRefreshInterval", "10", CFG_STYPE_ALTER_CLIENT_CMD, true), TSDB_CODE_SUCCESS); + EXPECT_EQ(pItem->i32, 10); + + ASSERT_EQ(cfgGetAndSetItem(pConfig, &pItem, "clsRefreshInterval", "86401", CFG_STYPE_ALTER_SERVER_CMD, true), + TSDB_CODE_OUT_OF_RANGE); + ASSERT_NE(pItem, nullptr); + EXPECT_EQ(pItem->i32, 10); + + ASSERT_EQ(cfgGetAndSetItem(pConfig, &pItem, "clsRefreshInterval", "86400", CFG_STYPE_ALTER_SERVER_CMD, true), + TSDB_CODE_SUCCESS); + ASSERT_NE(pItem, nullptr); + EXPECT_EQ(pItem->i32, 86400); + + cfgCleanup(pConfig); +} + TEST_F(CfgTest, cfgDumpItemCategory) { SConfig *pConfig = NULL; int32_t code = cfgInit(&pConfig); @@ -530,4 +573,4 @@ TEST_F(CfgTest, configSyncSameContent) { taosArrayDestroy(itemsToDelete); cfgCleanup(pGlobalConfig); cfgCleanup(pSdbConfig); -} \ No newline at end of file +}