add cfg value check

This commit is contained in:
wangjiaming0909 2024-04-10 16:48:02 +08:00
parent 083c07f6a6
commit 8a5532dd88
6 changed files with 163 additions and 78 deletions

View File

@ -22,10 +22,10 @@
extern "C" {
#endif
int64_t taosStrHumanToInt64(const char* str);
int32_t taosStrHumanToInt64(const char* str, int64_t* out);
void taosInt64ToHumanStr(int64_t val, char* outStr);
int32_t taosStrHumanToInt32(const char* str);
int32_t taosStrHumanToInt32(const char* str, int32_t* out);
void taosInt32ToHumanStr(int32_t val, char* outStr);
#ifdef __cplusplus

View File

@ -56,6 +56,8 @@ void taosIpPort2String(uint32_t ip, uint16_t port, char *str);
void *tmemmem(const char *haystack, int hlen, const char *needle, int nlen);
int32_t parseCfgReal(const char* str, double* out);
static FORCE_INLINE void taosEncryptPass(uint8_t *inBuf, size_t inLen, char *target) {
T_MD5_CTX context;
tMD5Init(&context);

View File

@ -174,7 +174,9 @@ static int32_t cfgSetBool(SConfigItem *pItem, const char *value, ECfgSrcType sty
}
static int32_t cfgSetInt32(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
int32_t ival = taosStrHumanToInt32(value);
int32_t ival;
int32_t code = taosStrHumanToInt32(value, &ival);
if (code != TSDB_CODE_SUCCESS) return code;
if (ival < pItem->imin || ival > pItem->imax) {
uError("cfg:%s, type:%s src:%s value:%d out of range[%" PRId64 ", %" PRId64 "]", pItem->name,
cfgDtypeStr(pItem->dtype), cfgStypeStr(stype), ival, pItem->imin, pItem->imax);
@ -188,7 +190,9 @@ static int32_t cfgSetInt32(SConfigItem *pItem, const char *value, ECfgSrcType st
}
static int32_t cfgSetInt64(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
int64_t ival = taosStrHumanToInt64(value);
int64_t ival;
int32_t code = taosStrHumanToInt64(value, &ival);
if (code != TSDB_CODE_SUCCESS) return code;
if (ival < pItem->imin || ival > pItem->imax) {
uError("cfg:%s, type:%s src:%s value:%" PRId64 " out of range[%" PRId64 ", %" PRId64 "]", pItem->name,
cfgDtypeStr(pItem->dtype), cfgStypeStr(stype), ival, pItem->imin, pItem->imax);
@ -202,15 +206,16 @@ static int32_t cfgSetInt64(SConfigItem *pItem, const char *value, ECfgSrcType st
}
static int32_t cfgSetFloat(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
float fval = (float)atof(value);
if (fval < pItem->fmin || fval > pItem->fmax) {
double dval;
int32_t code = parseCfgReal(value, &dval);
if (dval < pItem->fmin || dval > pItem->fmax) {
uError("cfg:%s, type:%s src:%s value:%f out of range[%f, %f]", pItem->name, cfgDtypeStr(pItem->dtype),
cfgStypeStr(stype), fval, pItem->fmin, pItem->fmax);
cfgStypeStr(stype), dval, pItem->fmin, pItem->fmax);
terrno = TSDB_CODE_OUT_OF_RANGE;
return -1;
}
pItem->fval = fval;
pItem->fval = (float)dval;
pItem->stype = stype;
return 0;
}
@ -408,7 +413,9 @@ int32_t cfgCheckRangeForDynUpdate(SConfig *pCfg, const char *name, const char *p
}
} break;
case CFG_DTYPE_INT32: {
int32_t ival = (int32_t)taosStrHumanToInt32(pVal);
int32_t ival;
int32_t code = (int32_t)taosStrHumanToInt32(pVal, &ival);
if (code != TSDB_CODE_SUCCESS) return code;
if (ival < pItem->imin || ival > pItem->imax) {
uError("cfg:%s, type:%s value:%d out of range[%" PRId64 ", %" PRId64 "]", pItem->name,
cfgDtypeStr(pItem->dtype), ival, pItem->imin, pItem->imax);
@ -417,7 +424,9 @@ int32_t cfgCheckRangeForDynUpdate(SConfig *pCfg, const char *name, const char *p
}
} break;
case CFG_DTYPE_INT64: {
int64_t ival = (int64_t)taosStrHumanToInt64(pVal);
int64_t ival;
int32_t code = taosStrHumanToInt64(pVal, &ival);
if (code != TSDB_CODE_SUCCESS) return code;
if (ival < pItem->imin || ival > pItem->imax) {
uError("cfg:%s, type:%s value:%" PRId64 " out of range[%" PRId64 ", %" PRId64 "]", pItem->name,
cfgDtypeStr(pItem->dtype), ival, pItem->imin, pItem->imax);
@ -427,9 +436,11 @@ int32_t cfgCheckRangeForDynUpdate(SConfig *pCfg, const char *name, const char *p
} break;
case CFG_DTYPE_FLOAT:
case CFG_DTYPE_DOUBLE: {
float fval = (float)atof(pVal);
if (fval < pItem->fmin || fval > pItem->fmax) {
uError("cfg:%s, type:%s value:%f out of range[%f, %f]", pItem->name, cfgDtypeStr(pItem->dtype), fval,
double dval;
int32_t code = parseCfgReal(pVal, &dval);
if (code != TSDB_CODE_SUCCESS) return code;
if (dval < pItem->fmin || dval > pItem->fmax) {
uError("cfg:%s, type:%s value:%f out of range[%f, %f]", pItem->name, cfgDtypeStr(pItem->dtype), dval,
pItem->fmin, pItem->fmax);
terrno = TSDB_CODE_OUT_OF_RANGE;
return -1;

View File

@ -23,45 +23,74 @@
#define UNIT_ONE_PEBIBYTE (UNIT_ONE_TEBIBYTE * UNIT_SIZE_CONVERT_FACTOR)
#define UNIT_ONE_EXBIBYTE (UNIT_ONE_PEBIBYTE * UNIT_SIZE_CONVERT_FACTOR)
int64_t taosStrHumanToInt64(const char* str) {
size_t sLen = strlen(str);
if (sLen < 2) return atoll(str);
int64_t val = 0;
char* strNoUnit = NULL;
char unit = str[sLen - 1];
if ((unit == 'P') || (unit == 'p')) {
strNoUnit = taosMemoryCalloc(sLen, 1);
memcpy(strNoUnit, str, sLen - 1);
val = atof(strNoUnit) * UNIT_ONE_PEBIBYTE;
} else if ((unit == 'T') || (unit == 't')) {
strNoUnit = taosMemoryCalloc(sLen, 1);
memcpy(strNoUnit, str, sLen - 1);
val = atof(strNoUnit) * UNIT_ONE_TEBIBYTE;
} else if ((unit == 'G') || (unit == 'g')) {
strNoUnit = taosMemoryCalloc(sLen, 1);
memcpy(strNoUnit, str, sLen - 1);
val = atof(strNoUnit) * UNIT_ONE_GIBIBYTE;
} else if ((unit == 'M') || (unit == 'm')) {
strNoUnit = taosMemoryCalloc(sLen, 1);
memcpy(strNoUnit, str, sLen - 1);
val = atof(strNoUnit) * UNIT_ONE_MEBIBYTE;
} else if ((unit == 'K') || (unit == 'k')) {
strNoUnit = taosMemoryCalloc(sLen, 1);
memcpy(strNoUnit, str, sLen - 1);
val = atof(strNoUnit) * UNIT_ONE_KIBIBYTE;
} else {
val = atoll(str);
static int32_t parseCfgIntWithUnit(const char* str, double *res) {
double val, temp = INT64_MAX;
char* endPtr;
errno = 0;
val = taosStr2Int64(str, &endPtr, 0);
if (*endPtr == '.' || errno == ERANGE) {
errno = 0;
val = taosStr2Double(str, &endPtr);
}
if (endPtr == str || errno == ERANGE || isnan(val)) {
terrno = TSDB_CODE_INVALID_CFG_VALUE;
return -1;
}
while (isspace((unsigned char)*endPtr)) endPtr++;
uint64_t factor = 1;
if (*endPtr != '\0') {
switch (*endPtr) {
case 'P':
case 'p': {
temp /= UNIT_ONE_PEBIBYTE;
factor = UNIT_ONE_PEBIBYTE;
} break;
case 'T':
case 't': {
temp /= UNIT_ONE_TEBIBYTE;
factor = UNIT_ONE_TEBIBYTE;
} break;
case 'G':
case 'g': {
temp /= UNIT_ONE_GIBIBYTE;
factor = UNIT_ONE_GIBIBYTE;
} break;
case 'M':
case 'm': {
temp /= UNIT_ONE_MEBIBYTE;
factor = UNIT_ONE_MEBIBYTE;
} break;
case 'K':
case 'k': {
temp /= UNIT_ONE_KIBIBYTE;
factor = UNIT_ONE_KIBIBYTE;
} break;
default:
terrno = TSDB_CODE_INVALID_CFG_VALUE;
return -1;
}
if ((val > 0 && val > temp) || (val < 0 && val < -temp)) {
terrno = TSDB_CODE_OUT_OF_RANGE;
return -1;
}
endPtr++;
val *= factor;
}
while (isspace((unsigned char)*endPtr)) endPtr++;
if (*endPtr) {
terrno = TSDB_CODE_INVALID_CFG_VALUE;
return -1;
}
val = rint(val);
*res = val;
return TSDB_CODE_SUCCESS;
}
taosMemoryFree(strNoUnit);
return val;
int32_t taosStrHumanToInt64(const char* str, int64_t *out) {
double res;
int32_t code = parseCfgIntWithUnit(str, &res);
if (code == TSDB_CODE_SUCCESS) *out = (int64_t)res;
return code;
}
#ifdef BUILD_NO_CALL
@ -83,35 +112,17 @@ void taosInt64ToHumanStr(int64_t val, char* outStr) {
}
#endif
int32_t taosStrHumanToInt32(const char* str) {
size_t sLen = strlen(str);
if (sLen < 2) return atoll(str);
int32_t val = 0;
char* strNoUnit = NULL;
char unit = str[sLen - 1];
if ((unit == 'G') || (unit == 'g')) {
strNoUnit = taosMemoryCalloc(sLen, 1);
memcpy(strNoUnit, str, sLen - 1);
val = atof(strNoUnit) * UNIT_ONE_GIBIBYTE;
} else if ((unit == 'M') || (unit == 'm')) {
strNoUnit = taosMemoryCalloc(sLen, 1);
memcpy(strNoUnit, str, sLen - 1);
val = atof(strNoUnit) * UNIT_ONE_MEBIBYTE;
} else if ((unit == 'K') || (unit == 'k')) {
strNoUnit = taosMemoryCalloc(sLen, 1);
memcpy(strNoUnit, str, sLen - 1);
val = atof(strNoUnit) * UNIT_ONE_KIBIBYTE;
} else {
val = atoll(str);
int32_t taosStrHumanToInt32(const char* str, int32_t* out) {
double res;
int32_t code = parseCfgIntWithUnit(str, &res);
if (code == TSDB_CODE_SUCCESS) {
if (res < INT32_MIN || res > INT32_MAX) {
terrno = TSDB_CODE_OUT_OF_RANGE;
return -1;
}
*out = (int32_t)res;
}
taosMemoryFree(strNoUnit);
return val;
return code;
}
#ifdef BUILD_NO_CALL

View File

@ -496,3 +496,21 @@ size_t twcsncspn(const TdUcs4 *wcs, size_t size, const TdUcs4 *reject, size_t rs
return index;
}
int32_t parseCfgReal(const char* str, double* out) {
double val;
char *endPtr;
errno = 0;
val = taosStr2Double(str, &endPtr);
if (str == endPtr || errno == ERANGE || isnan(val)) {
terrno = TSDB_CODE_INVALID_CFG_VALUE;
return -1;
}
while(isspace((unsigned char)*endPtr)) endPtr++;
if (*endPtr != '\0') {
terrno = TSDB_CODE_INVALID_CFG_VALUE;
return -1;
}
*out = val;
return TSDB_CODE_SUCCESS;
}

View File

@ -240,6 +240,49 @@ class TDTestCase:
self.show_create_sysdb_sql()
self.show_create_systb_sql()
self.show_column_name()
self.test_show_variables()
def get_variable(self, name: str, local: bool = True):
if local:
sql = 'show local variables'
else:
sql = f'select `value` from information_schema.ins_dnode_variables where name like "{name}"'
tdSql.query(sql, queryTimes=1)
res = tdSql.queryResult
if local:
for row in res:
if row[0] == name:
return row[1]
else:
if len(res) > 0:
return res[0][0]
raise Exception(f"variable {name} not found")
def test_show_variables(self):
epsion = 0.0000001
var = 'minimalTmpDirGB'
expect_val: float = 10.11
sql = f'ALTER LOCAL "{var}" "{expect_val}"'
tdSql.execute(sql)
val: float = float(self.get_variable(var))
if val != expect_val:
tdLog.exit(f'failed to set local {var} to {expect_val} actually {val}')
error_vals = ['a', '10a', '', '1.100r', '1.12 r']
for error_val in error_vals:
tdSql.error(f'ALTER LOCAL "{var}" "{error_val}"')
var = 'supportVnodes'
expect_val = 1240 ## 1.211111 * 1024
sql = f'ALTER DNODE 1 "{var}" "1.211111k"'
tdSql.execute(sql, queryTimes=1)
val = int(self.get_variable(var, False))
if val != expect_val:
tdLog.exit(f'failed to set dnode {var} to {expect_val} actually {val}')
error_vals = ['a', '10a', '', '1.100r', '1.12 r', '5k']
for error_val in error_vals:
tdSql.error(f'ALTER DNODE 1 "{var}" "{error_val}"')
def stop(self):
tdSql.close()