/* * Copyright (c) 2019 TAOS Data, Inc. * * This program is free software: you can use, redistribute, and/or modify * it under the terms of the GNU Affero General Public License, version 3 * or later ("AGPL"), as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ #define _DEFAULT_SOURCE #include "simInt.h" void simLogSql(char *sql, bool useSharp) { static TdFilePtr pFile = NULL; char filename[256]; sprintf(filename, "%s/sim.sql", simScriptDir); if (pFile == NULL) { // fp = fopen(filename, "w"); pFile = taosOpenFile(filename, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC | TD_FILE_STREAM); if (pFile == NULL) { fprintf(stderr, "ERROR: failed to open file: %s\n", filename); return; } } if (useSharp) { taosFprintfFile(pFile, "# %s;\n", sql); } else { taosFprintfFile(pFile, "%s;\n", sql); } taosFsyncFile(pFile); } char *simParseArbitratorName(char *varName) { static char hostName[140]; #ifdef WINDOWS taosGetFqdn(hostName); sprintf(&hostName[strlen(hostName)], ":%d", 8000); #else sprintf(hostName, "%s:%d", "localhost", 8000); #endif return hostName; } char *simParseHostName(char *varName) { static char hostName[140]; #ifdef WINDOWS hostName[0] = '\"'; taosGetFqdn(&hostName[1]); int strEndIndex = strlen(hostName); hostName[strEndIndex] = '\"'; hostName[strEndIndex + 1] = '\0'; #else sprintf(hostName, "%s", "localhost"); #endif return hostName; } static void simFindFirstNum(const char *begin, int32_t beginLen, int32_t *num) { if (beginLen <= 5) { *num = 0; } else { *num = atoi(begin + 5); } } static void simFindSecondNum(const char *begin, int32_t beginLen, int32_t *num) { const char *number = strstr(begin, "]["); if (number == NULL) { *num = 0; } else { *num = atoi(number + 2); } } static void simFindFirstKeyVal(const char *begin, int32_t beginLen, char *key, int32_t keyLen) { key[0] = 0; for (int32_t i = 5; i < beginLen && i - 5 < keyLen; ++i) { if (begin[i] != 0 && begin[i] != ']' && begin[i] != ')') { key[i - 5] = begin[i]; } } } static void simFindSecondKeyNum(const char *begin, int32_t beginLen, int32_t *num) { const char *number = strstr(begin, ")["); if (number == NULL) { *num = 0; } else { *num = atoi(number + 2); } } char *simGetVariable(SScript *script, char *varName, int32_t varLen) { if (strncmp(varName, "hostname", 8) == 0) { return simParseHostName(varName); } if (strncmp(varName, "arbitrator", 10) == 0) { return simParseArbitratorName(varName); } if (strncmp(varName, "error", varLen) == 0) return script->error; if (strncmp(varName, "rows", varLen) == 0) return script->rows; if (strncmp(varName, "system_exit", varLen) == 0) return script->system_exit_code; if (strncmp(varName, "system_content", varLen) == 0) return script->system_ret_content; if (strncmp(varName, "data", 4) == 0) { if (varLen < 6) { return "null"; } int32_t row = 0; int32_t col = 0; char keyVal[1024] = {0}; int32_t keyLen = 1024; if (varName[4] == '[') { // $data[0][1] simFindFirstNum(varName, varLen, &row); simFindSecondNum(varName, varLen, &col); if (row < 0 || row >= MAX_QUERY_ROW_NUM) { return "null"; } if (col < 0 || col >= MAX_QUERY_COL_NUM) { return "null"; } simDebug("script:%s, data[%d][%d]=%s", script->fileName, row, col, script->data[row][col]); return script->data[row][col]; } else if (varName[4] == '(') { // $data(db)[0] simFindFirstKeyVal(varName, varLen, keyVal, keyLen); simFindSecondKeyNum(varName, varLen, &col); for (int32_t i = 0; i < MAX_QUERY_ROW_NUM; ++i) { if (strncmp(keyVal, script->data[i][0], keyLen) == 0) { simDebug("script:%s, keyName:%s, keyValue:%s", script->fileName, script->data[i][0], script->data[i][col]); return script->data[i][col]; } } } else if (varName[5] == '_') { // data2_db int32_t col = varName[4] - '0'; if (col < 0 || col >= MAX_QUERY_COL_NUM) { return "null"; } char *keyName; int32_t keyLen; paGetToken(varName + 6, &keyName, &keyLen); for (int32_t i = 0; i < MAX_QUERY_ROW_NUM; ++i) { if (strncmp(keyName, script->data[i][0], keyLen) == 0) { simDebug("script:%s, keyName:%s, keyValue:%s", script->fileName, script->data[i][0], script->data[i][col]); return script->data[i][col]; } } return "null"; } else if (varName[6] == '_') { // data21_db int32_t col = (varName[4] - '0') * 10 + (varName[5] - '0'); if (col < 0 || col >= MAX_QUERY_COL_NUM) { return "null"; } char *keyName; int32_t keyLen; paGetToken(varName + 7, &keyName, &keyLen); for (int32_t i = 0; i < MAX_QUERY_ROW_NUM; ++i) { if (strncmp(keyName, script->data[i][0], keyLen) == 0) { simTrace("script:%s, keyName:%s, keyValue:%s", script->fileName, script->data[i][0], script->data[i][col]); return script->data[i][col]; } } return "null"; } else { // $data00 int32_t row = varName[4] - '0'; int32_t col = varName[5] - '0'; if (row < 0 || row >= MAX_QUERY_ROW_NUM) { return "null"; } if (col < 0 || col >= MAX_QUERY_COL_NUM) { return "null"; } simDebug("script:%s, data[%d][%d]=%s", script->fileName, row, col, script->data[row][col]); return script->data[row][col]; } return "null"; } for (int32_t i = 0; i < script->varLen; ++i) { SVariable *var = &script->variables[i]; if (var->varNameLen != varLen) { continue; } if (strncmp(varName, var->varName, varLen) == 0) { return var->varValue; } } if (script->varLen >= MAX_VAR_LEN) { simError("script:%s, too many varialbes:%d", script->fileName, script->varLen); exit(0); } SVariable *var = &script->variables[script->varLen]; script->varLen++; strncpy(var->varName, varName, varLen); var->varNameLen = varLen; var->varValue[0] = 0; return var->varValue; } int32_t simExecuteExpression(SScript *script, char *exp) { char *op1 = NULL; char *op2 = NULL; char *var1 = NULL; char *var2 = NULL; char *var3 = NULL; char *rest = NULL; int32_t op1Len = 0; int32_t op2Len = 0; int32_t var1Len = 0; int32_t var2Len = 0; int32_t var3Len = 0; int32_t val0 = 0; int32_t val1 = 0; char t0[2048] = {0}; char t1[2048] = {0}; char t2[2048] = {0}; char t3[2048] = {0}; int32_t result = 0; rest = paGetToken(exp, &var1, &var1Len); rest = paGetToken(rest, &op1, &op1Len); rest = paGetToken(rest, &var2, &var2Len); rest = paGetToken(rest, &op2, &op2Len); if (var1[0] == '$') strcpy(t0, simGetVariable(script, var1 + 1, var1Len - 1)); else { memcpy(t0, var1, var1Len); t0[var1Len] = 0; } if (var2[0] == '$') { tstrncpy(t1, simGetVariable(script, var2 + 1, var2Len - 1), sizeof(t1)); } else { memcpy(t1, var2, var2Len); t1[var2Len] = 0; } if (op2Len != 0) { rest = paGetToken(rest, &var3, &var3Len); if (var3[0] == '$') tstrncpy(t2, simGetVariable(script, var3 + 1, var3Len - 1), sizeof(t2)); else { memcpy(t2, var3, var3Len); t2[var3Len] = 0; } int64_t t1l = atoll(t1); int64_t t2l = atoll(t2); if (op2[0] == '+') { sprintf(t3, "%" PRId64, t1l + t2l); } else if (op2[0] == '-') { sprintf(t3, "%" PRId64, t1l - t2l); } else if (op2[0] == '*') { sprintf(t3, "%" PRId64, t1l * t2l); } else if (op2[0] == '/') { if (t2l == 0) { sprintf(t3, "%" PRId64, INT64_MAX); } else { sprintf(t3, "%" PRId64, t1l / t2l); } } else if (op2[0] == '.') { sprintf(t3, "%s%s", t1, t2); } } else { tstrncpy(t3, t1, sizeof(t3)); } result = 0; if (op1Len == 1) { if (op1[0] == '=') { strcpy(simGetVariable(script, var1 + 1, var1Len - 1), t3); } else if (op1[0] == '<') { val0 = atoi(t0); val1 = atoi(t3); if (val0 >= val1) result = -1; } else if (op1[0] == '>') { val0 = atoi(t0); val1 = atoi(t3); if (val0 <= val1) result = -1; } } else { if (op1[0] == '=' && op1[1] == '=') { if (strcmp(t0, t3) != 0) result = -1; } else if (op1[0] == '!' && op1[1] == '=') { if (strcmp(t0, t3) == 0) result = -1; } else if (op1[0] == '<' && op1[1] == '=') { val0 = atoi(t0); val1 = atoi(t3); if (val0 > val1) result = -1; } else if (op1[0] == '>' && op1[1] == '=') { val0 = atoi(t0); val1 = atoi(t3); if (val0 < val1) result = -1; } } return result; } bool simExecuteExpCmd(SScript *script, char *option) { simExecuteExpression(script, option); script->linePos++; return true; } bool simExecuteTestCmd(SScript *script, char *option) { int32_t result; result = simExecuteExpression(script, option); if (result >= 0) script->linePos++; else script->linePos = script->lines[script->linePos].jump; return true; } bool simExecuteGotoCmd(SScript *script, char *option) { script->linePos = script->lines[script->linePos].jump; return true; } bool simExecuteRunCmd(SScript *script, char *option) { char *fileName = option; if (fileName == NULL || strlen(fileName) == 0) { sprintf(script->error, "lineNum:%d. script file is null", script->lines[script->linePos].lineNum); return false; } SScript *newScript = simParseScript(option); if (newScript == NULL) { sprintf(script->error, "lineNum:%d. parse file:%s error", script->lines[script->linePos].lineNum, fileName); return false; } simInfo("script:%s, start to execute", newScript->fileName); newScript->type = SIM_SCRIPT_TYPE_MAIN; simScriptPos++; simScriptList[simScriptPos] = newScript; script->linePos++; return true; } bool simExecuteRunBackCmd(SScript *script, char *option) { char *fileName = option; if (fileName == NULL || strlen(fileName) == 0) { sprintf(script->error, "lineNum:%d. script file is null", script->lines[script->linePos].lineNum); return false; } SScript *newScript = simParseScript(option); if (newScript == NULL) { sprintf(script->error, "lineNum:%d. parse file:%s error", script->lines[script->linePos].lineNum, fileName); return false; } newScript->type = SIM_SCRIPT_TYPE_BACKGROUND; script->bgScripts[script->bgScriptLen++] = newScript; simInfo("script:%s, start to execute in background,", newScript->fileName); if (taosThreadCreate(&newScript->bgPid, NULL, simExecuteScript, (void *)newScript) != 0) { sprintf(script->error, "lineNum:%d. create background thread failed", script->lines[script->linePos].lineNum); return false; } else { simDebug("script:%s, background thread:0x%08" PRIx64 " is created", newScript->fileName, taosGetPthreadId(newScript->bgPid)); } script->linePos++; return true; } bool simReplaceStr(char *buf, char *src, char *dst) { bool replaced = false; char *begin = strstr(buf, src); if (begin != NULL) { int32_t srcLen = (int32_t)strlen(src); int32_t dstLen = (int32_t)strlen(dst); int32_t interval = (dstLen - srcLen); int32_t remainLen = (int32_t)strlen(buf); char *end = buf + remainLen; *(end + interval) = 0; for (char *p = end; p >= begin; p--) { *(p + interval) = *p; } memcpy(begin, dst, dstLen); replaced = true; } simInfo("system cmd is %s", buf); return replaced; } bool simExecuteSystemCmd(SScript *script, char *option) { char buf[4096] = {0}; bool replaced = false; #ifndef WINDOWS sprintf(buf, "cd %s; ", simScriptDir); simVisuallizeOption(script, option, buf + strlen(buf)); #else sprintf(buf, "%s", simScriptDir); simVisuallizeOption(script, option, buf + strlen(buf)); simReplaceStr(buf, ".sh", ".bat"); #endif if (useMultiProcess) { simReplaceStr(buf, "deploy.sh", "deploy.sh -m"); } if (useValgrind) { replaced = simReplaceStr(buf, "exec.sh", "exec.sh -v"); } simLogSql(buf, true); int32_t code = system(buf); int32_t repeatTimes = 0; while (code < 0) { simError("script:%s, failed to execute %s , code %d, errno:%d %s, repeatTimes:%d", script->fileName, buf, code, errno, strerror(errno), repeatTimes); taosMsleep(1000); taosDflSignal(SIGCHLD); if (repeatTimes++ >= 10) { exit(0); } } sprintf(script->system_exit_code, "%d", code); script->linePos++; if (replaced && strstr(buf, "start") != NULL) { simInfo("====> startup is slow in valgrind mode, so sleep 5 seconds after exec.sh -s start"); taosMsleep(5000); } return true; } void simStoreSystemContentResult(SScript *script, char *filename) { memset(script->system_ret_content, 0, MAX_SYSTEM_RESULT_LEN); TdFilePtr pFile; // if ((fd = fopen(filename, "r")) != NULL) { if ((pFile = taosOpenFile(filename, TD_FILE_READ)) != NULL) { taosReadFile(pFile, script->system_ret_content, MAX_SYSTEM_RESULT_LEN - 1); int32_t len = strlen(script->system_ret_content); for (int32_t i = 0; i < len; ++i) { if (script->system_ret_content[i] == '\n' || script->system_ret_content[i] == '\r') { script->system_ret_content[i] = 0; } } taosCloseFile(&pFile); char rmCmd[MAX_FILE_NAME_LEN] = {0}; sprintf(rmCmd, "rm -f %s", filename); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-result" system(rmCmd); #pragma GCC diagnostic pop } } bool simExecuteSystemContentCmd(SScript *script, char *option) { char buf[4096] = {0}; char buf1[4096 + 512] = {0}; char filename[400] = {0}; sprintf(filename, "%s" TD_DIRSEP "%s.tmp", simScriptDir, script->fileName); #ifdef WINDOWS sprintf(buf, "cd %s && ", simScriptDir); simVisuallizeOption(script, option, buf + strlen(buf)); sprintf(buf1, "%s > %s 2>nul", buf, filename); #else sprintf(buf, "cd %s; ", simScriptDir); simVisuallizeOption(script, option, buf + strlen(buf)); sprintf(buf1, "%s > %s 2>/dev/null", buf, filename); #endif sprintf(script->system_exit_code, "%d", system(buf1)); simStoreSystemContentResult(script, filename); script->linePos++; return true; } bool simExecutePrintCmd(SScript *script, char *rest) { char buf[65536]; simVisuallizeOption(script, rest, buf); rest = buf; simInfo("script:%s, %s", script->fileName, rest); script->linePos++; return true; } bool simExecuteSleepCmd(SScript *script, char *option) { int32_t delta; char buf[1024]; simVisuallizeOption(script, option, buf); option = buf; delta = atoi(option); if (delta <= 0) delta = 5; simInfo("script:%s, sleep %dms begin", script->fileName, delta); taosMsleep(delta); simInfo("script:%s, sleep %dms finished", script->fileName, delta); char sleepStr[32] = {0}; sprintf(sleepStr, "sleep %d", delta); simLogSql(sleepStr, true); script->linePos++; return true; } bool simExecuteReturnCmd(SScript *script, char *option) { char buf[1024]; simVisuallizeOption(script, option, buf); option = buf; int32_t ret = 1; if (option && option[0] != 0) ret = atoi(option); if (ret < 0) { sprintf(script->error, "lineNum:%d. error return %s", script->lines[script->linePos].lineNum, option); return false; } else { simInfo("script:%s, return cmd execute with:%d", script->fileName, ret); script->linePos = script->numOfLines; } script->linePos++; return true; } void simVisuallizeOption(SScript *script, char *src, char *dst) { char *var, *token, *value; int32_t dstLen, srcLen, tokenLen; dst[0] = 0, dstLen = 0; while (1) { var = strchr(src, '$'); if (var == NULL) break; if (var && ((var - src - 1) > 0) && *(var - 1) == '\\') { srcLen = (int32_t)(var - src - 1); memcpy(dst + dstLen, src, srcLen); dstLen += srcLen; src = var; break; } srcLen = (int32_t)(var - src); memcpy(dst + dstLen, src, srcLen); dstLen += srcLen; src = paGetToken(var + 1, &token, &tokenLen); value = simGetVariable(script, token, tokenLen); strcpy(dst + dstLen, value); dstLen += (int32_t)strlen(value); } strcpy(dst + dstLen, src); } void simCloseNativeConnect(SScript *script) { if (script->taos == NULL) return; simDebug("script:%s, taos:%p closed", script->fileName, script->taos); taos_close(script->taos); script->taos = NULL; } void simCloseTaosdConnect(SScript *script) { simCloseNativeConnect(script); } bool simCreateNativeConnect(SScript *script, char *user, char *pass) { simCloseTaosdConnect(script); void *taos = NULL; for (int32_t attempt = 0; attempt < 10; ++attempt) { if (abortExecution) { script->killed = true; return false; } taos = taos_connect(NULL, user, pass, NULL, 0); if (taos == NULL) { simDebug("script:%s, user:%s connect taosd failed:%s, attempt:%d", script->fileName, user, taos_errstr(NULL), attempt); taosMsleep(1000); } else { simDebug("script:%s, user:%s connect taosd successed, attempt:%d", script->fileName, user, attempt); break; } } if (taos == NULL) { sprintf(script->error, "lineNum:%d. connect taosd failed:%s", script->lines[script->linePos].lineNum, taos_errstr(NULL)); return false; } script->taos = taos; simDebug("script:%s, connect taosd successed, taos:%p", script->fileName, taos); return true; } bool simCreateTaosdConnect(SScript *script, char *rest) { char *user = TSDB_DEFAULT_USER; char *token; int32_t tokenLen; rest = paGetToken(rest, &token, &tokenLen); rest = paGetToken(rest, &token, &tokenLen); if (tokenLen != 0) { user = token; } return simCreateNativeConnect(script, user, TSDB_DEFAULT_PASS); } bool simExecuteNativeSqlCommand(SScript *script, char *rest, bool isSlow) { char timeStr[80] = {0}; time_t tt; struct tm tp; SCmdLine *line = &script->lines[script->linePos]; int32_t ret = -1; TAOS_RES *pSql = NULL; for (int32_t attempt = 0; attempt < 10; ++attempt) { if (abortExecution) { script->killed = true; return false; } simLogSql(rest, false); pSql = taos_query(script->taos, rest); ret = taos_errno(pSql); if (ret == TSDB_CODE_MND_STB_ALREADY_EXIST || ret == TSDB_CODE_MND_DB_ALREADY_EXIST) { simDebug("script:%s, taos:%p, %s success, ret:%d:%s", script->fileName, script->taos, rest, ret & 0XFFFF, tstrerror(ret)); ret = 0; break; } else if (ret != 0) { simDebug("script:%s, taos:%p, %s failed, ret:%d:%s, error:%s", script->fileName, script->taos, rest, ret & 0XFFFF, tstrerror(ret), taos_errstr(pSql)); if (line->errorJump == SQL_JUMP_TRUE) { script->linePos = line->jump; taos_free_result(pSql); return true; } taosMsleep(1000); } else { break; } taos_free_result(pSql); } if (ret) { sprintf(script->error, "lineNum:%d. sql:%s failed, ret:%d:%s", line->lineNum, rest, ret & 0XFFFF, tstrerror(ret)); return false; } int32_t numOfRows = 0; int32_t num_fields = taos_field_count(pSql); if (num_fields != 0) { if (pSql == NULL) { simDebug("script:%s, taos:%p, %s failed, result is null", script->fileName, script->taos, rest); if (line->errorJump == SQL_JUMP_TRUE) { script->linePos = line->jump; return true; } sprintf(script->error, "lineNum:%d. result set null, sql:%s", line->lineNum, rest); return false; } TAOS_ROW row; while ((row = taos_fetch_row(pSql))) { if (numOfRows < MAX_QUERY_ROW_NUM) { TAOS_FIELD *fields = taos_fetch_fields(pSql); int32_t *length = taos_fetch_lengths(pSql); for (int32_t i = 0; i < num_fields; i++) { char *value = NULL; if (i < MAX_QUERY_COL_NUM) { value = script->data[numOfRows][i]; } if (value == NULL) { continue; } if (row[i] == 0) { strcpy(value, TSDB_DATA_NULL_STR); continue; } switch (fields[i].type) { case TSDB_DATA_TYPE_BOOL: sprintf(value, "%s", ((((int32_t)(*((char *)row[i]))) == 1) ? "1" : "0")); break; case TSDB_DATA_TYPE_TINYINT: sprintf(value, "%d", *((int8_t *)row[i])); break; case TSDB_DATA_TYPE_UTINYINT: sprintf(value, "%u", *((uint8_t *)row[i])); break; case TSDB_DATA_TYPE_SMALLINT: sprintf(value, "%d", *((int16_t *)row[i])); break; case TSDB_DATA_TYPE_USMALLINT: sprintf(value, "%u", *((uint16_t *)row[i])); break; case TSDB_DATA_TYPE_INT: sprintf(value, "%d", *((int32_t *)row[i])); break; case TSDB_DATA_TYPE_UINT: sprintf(value, "%u", *((uint32_t *)row[i])); break; case TSDB_DATA_TYPE_BIGINT: sprintf(value, "%" PRId64, *((int64_t *)row[i])); break; case TSDB_DATA_TYPE_UBIGINT: sprintf(value, "%" PRIu64, *((uint64_t *)row[i])); break; case TSDB_DATA_TYPE_FLOAT: sprintf(value, "%.5f", GET_FLOAT_VAL(row[i])); break; case TSDB_DATA_TYPE_DOUBLE: sprintf(value, "%.9lf", GET_DOUBLE_VAL(row[i])); break; case TSDB_DATA_TYPE_BINARY: case TSDB_DATA_TYPE_NCHAR: if (length[i] < 0 || length[i] > 1 << 20) { fprintf(stderr, "Invalid length(%d) of BINARY or NCHAR\n", length[i]); exit(-1); } memset(value, 0, MAX_QUERY_VALUE_LEN); memcpy(value, row[i], length[i]); value[length[i]] = 0; // snprintf(value, fields[i].bytes, "%s", (char *)row[i]); break; case TSDB_DATA_TYPE_TIMESTAMP: { int32_t precision = taos_result_precision(pSql); if (precision == TSDB_TIME_PRECISION_MILLI) { tt = (*(int64_t *)row[i]) / 1000; } else if (precision == TSDB_TIME_PRECISION_MICRO) { tt = (*(int64_t *)row[i]) / 1000000; } else { tt = (*(int64_t *)row[i]) / 1000000000; } taosLocalTime(&tt, &tp); strftime(timeStr, 64, "%y-%m-%d %H:%M:%S", &tp); if (precision == TSDB_TIME_PRECISION_MILLI) { sprintf(value, "%s.%03d", timeStr, (int32_t)(*((int64_t *)row[i]) % 1000)); } else if (precision == TSDB_TIME_PRECISION_MICRO) { sprintf(value, "%s.%06d", timeStr, (int32_t)(*((int64_t *)row[i]) % 1000000)); } else { sprintf(value, "%s.%09d", timeStr, (int32_t)(*((int64_t *)row[i]) % 1000000000)); } break; } default: break; } // end of switch } // end of for } // end of if numOfRows++; if (isSlow && numOfRows % 100 == 0) { taosMsleep(200); } if (numOfRows > 2000000000) { simError("script:%s, too many rows return from query", script->fileName); break; } } } else { numOfRows = taos_affected_rows(pSql); } taos_free_result(pSql); sprintf(script->rows, "%d", numOfRows); script->linePos++; return true; } bool simExecuteSqlImpCmd(SScript *script, char *rest, bool isSlow) { char buf[3000]; SCmdLine *line = &script->lines[script->linePos]; simVisuallizeOption(script, rest, buf); rest = buf; simDebug("script:%s, exec:%s", script->fileName, rest); strcpy(script->rows, "-1"); for (int32_t row = 0; row < MAX_QUERY_ROW_NUM; ++row) { for (int32_t col = 0; col < MAX_QUERY_COL_NUM; ++col) { strcpy(script->data[row][col], "null"); } } if (strncmp(rest, "connect", 7) == 0) { if (!simCreateTaosdConnect(script, rest)) { return false; } script->linePos++; return true; } if (script->taos == NULL) { if (!simCreateTaosdConnect(script, "connect root")) { if (line->errorJump == SQL_JUMP_TRUE) { script->linePos = line->jump; return true; } return false; } } if (strncmp(rest, "close", 5) == 0) { simCloseTaosdConnect(script); script->linePos++; return true; } return simExecuteNativeSqlCommand(script, rest, isSlow); } bool simExecuteSqlCmd(SScript *script, char *rest) { bool isSlow = false; return simExecuteSqlImpCmd(script, rest, isSlow); } bool simExecuteSqlSlowCmd(SScript *script, char *rest) { bool isSlow = true; return simExecuteSqlImpCmd(script, rest, isSlow); } bool simExecuteRestfulCmd(SScript *script, char *rest) { TdFilePtr pFile = NULL; char filename[256]; sprintf(filename, "%s/tmp.sql", simScriptDir); // fp = fopen(filename, "w"); pFile = taosOpenFile(filename, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC | TD_FILE_STREAM); if (pFile == NULL) { fprintf(stderr, "ERROR: failed to open file: %s\n", filename); return false; } char db[64] = {0}; char tb[64] = {0}; char gzip[32] = {0}; int32_t ts; int32_t times; sscanf(rest, "%s %s %d %d %s", db, tb, &ts, ×, gzip); taosFprintfFile(pFile, "insert into %s.%s values ", db, tb); for (int32_t i = 0; i < times; ++i) { taosFprintfFile(pFile, "(%d000, %d)", ts + i, ts); } taosFprintfFile(pFile, " \n"); taosFsyncFile(pFile); taosCloseFile(&pFile); char cmd[1024] = {0}; if (strcmp(gzip, "gzip") == 0) { sprintf(cmd, "curl -H 'Authorization: Taosd /KfeAzX/f9na8qdtNZmtONryp201ma04bEl8LcvLUd7a8qdtNZmtONryp201ma04' --header " "--compressed --data-ascii @%s 127.0.0.1:7111/rest/sql", filename); } else { sprintf(cmd, "curl -H 'Authorization: Taosd /KfeAzX/f9na8qdtNZmtONryp201ma04bEl8LcvLUd7a8qdtNZmtONryp201ma04' --header " "'Transfer-Encoding: chunked' --data-ascii @%s 127.0.0.1:7111/rest/sql", filename); } return simExecuteSystemCmd(script, cmd); } bool simExecuteSqlErrorCmd(SScript *script, char *rest) { char buf[3000]; SCmdLine *line = &script->lines[script->linePos]; simVisuallizeOption(script, rest, buf); rest = buf; simDebug("script:%s, exec:%s", script->fileName, rest); strcpy(script->rows, "-1"); for (int32_t row = 0; row < MAX_QUERY_ROW_NUM; ++row) { for (int32_t col = 0; col < MAX_QUERY_COL_NUM; ++col) { strcpy(script->data[row][col], "null"); } } if (strncmp(rest, "connect", 7) == 0) { if (!simCreateTaosdConnect(script, rest)) { return false; } script->linePos++; return true; } if (script->taos == NULL) { if (!simCreateTaosdConnect(script, "connect root")) { if (line->errorJump == SQL_JUMP_TRUE) { script->linePos = line->jump; return true; } return false; } } if (strncmp(rest, "close", 5) == 0) { simCloseTaosdConnect(script); script->linePos++; return true; } TAOS_RES *pSql = taos_query(script->taos, rest); int32_t ret = taos_errno(pSql); taos_free_result(pSql); if (ret != TSDB_CODE_SUCCESS) { simDebug("script:%s, taos:%p, %s execute, expect failed, so success, ret:%d:%s", script->fileName, script->taos, rest, ret & 0XFFFF, tstrerror(ret)); script->linePos++; return true; } sprintf(script->error, "lineNum:%d. sql:%s expect failed, but success, ret:%d:%s", line->lineNum, rest, ret & 0XFFFF, tstrerror(ret)); return false; } bool simExecuteLineInsertCmd(SScript *script, char *rest) { char buf[TSDB_MAX_BINARY_LEN] = {0}; simVisuallizeOption(script, rest, buf); rest = buf; SCmdLine *line = &script->lines[script->linePos]; simInfo("script:%s, %s", script->fileName, rest); simLogSql(buf, true); char *lines[] = {rest}; #if 0 int32_t ret = taos_insert_lines(script->taos, lines, 1); if (ret == TSDB_CODE_SUCCESS) { simDebug("script:%s, taos:%p, %s executed. success.", script->fileName, script->taos, rest); script->linePos++; return true; } else { sprintf(script->error, "lineNum: %d. line: %s failed, ret:%d:%s", line->lineNum, rest, ret & 0XFFFF, tstrerror(ret)); return false; } #else simDebug("script:%s, taos:%p, %s executed. success.", script->fileName, script->taos, rest); script->linePos++; return true; #endif } bool simExecuteLineInsertErrorCmd(SScript *script, char *rest) { char buf[TSDB_MAX_BINARY_LEN]; simVisuallizeOption(script, rest, buf); rest = buf; SCmdLine *line = &script->lines[script->linePos]; simInfo("script:%s, %s", script->fileName, rest); simLogSql(buf, true); char *lines[] = {rest}; #if 0 int32_t ret = taos_insert_lines(script->taos, lines, 1); #else int32_t ret = 0; #endif if (ret == TSDB_CODE_SUCCESS) { sprintf(script->error, "script:%s, taos:%p, %s executed. expect failed, but success.", script->fileName, script->taos, rest); script->linePos++; return false; } else { simDebug("lineNum: %d. line: %s failed, ret:%d:%s. Expect failed, so success", line->lineNum, rest, ret & 0XFFFF, tstrerror(ret)); return true; } }