• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

taosdata / TDengine / #4905

29 Dec 2025 02:08PM UTC coverage: 65.423% (-0.3%) from 65.734%
#4905

push

travis-ci

web-flow
enh: sign connect request (#34067)

23 of 29 new or added lines in 4 files covered. (79.31%)

11614 existing lines in 186 files now uncovered.

193476 of 295730 relevant lines covered (65.42%)

115752566.53 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

77.52
/source/client/src/clientMsgHandler.c
1
/*
2
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
3
 *
4
 * This program is free software: you can use, redistribute, and/or modify
5
 * it under the terms of the GNU Affero General Public License, version 3
6
 * or later ("AGPL"), as published by the Free Software Foundation.
7
 *
8
 * This program is distributed in the hope that it will be useful, but WITHOUT
9
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
 * FITNESS FOR A PARTICULAR PURPOSE.
11
 *
12
 * You should have received a copy of the GNU Affero General Public License
13
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14
 */
15

16
#include "catalog.h"
17
#include "clientInt.h"
18
#include "clientLog.h"
19
#include "clientMonitor.h"
20
#include "cmdnodes.h"
21
#include "command.h"
22
#include "os.h"
23
#include "query.h"
24
#include "systable.h"
25
#include "tdatablock.h"
26
#include "tdef.h"
27
#include "tglobal.h"
28
#include "tmsg.h"
29
#include "tname.h"
30
#include "tversion.h"
31

32
extern SClientHbMgr clientHbMgr;
33

34
static void setErrno(SRequestObj* pRequest, int32_t code) {
3,938,794✔
35
  pRequest->code = code;
3,938,794✔
36
  terrno = code;
3,938,794✔
37
}
3,938,794✔
38

39
int32_t genericRspCallback(void* param, SDataBuf* pMsg, int32_t code) {
2,929,766✔
40
  SRequestObj* pRequest = param;
2,929,766✔
41
  setErrno(pRequest, code);
2,929,766✔
42

43
  if (NEED_CLIENT_RM_TBLMETA_REQ(pRequest->type)) {
2,929,766✔
44
    if (removeMeta(pRequest->pTscObj, pRequest->targetTableList, IS_VIEW_REQUEST(pRequest->type)) != 0) {
797,878✔
45
      tscError("failed to remove meta data for table");
×
46
    }
47
  }
48

49
  taosMemoryFree(pMsg->pEpSet);
2,929,766✔
50
  taosMemoryFree(pMsg->pData);
2,929,766✔
51
  if (pRequest->body.queryFp != NULL) {
2,929,766✔
52
    doRequestCallback(pRequest, code);
2,928,136✔
53
  } else {
54
    if (tsem_post(&pRequest->body.rspSem) != 0) {
1,630✔
55
      tscError("failed to post semaphore");
×
56
    }
57
  }
58
  return code;
2,929,766✔
59
}
60

61
int32_t processConnectRsp(void* param, SDataBuf* pMsg, int32_t code) {
2,062,552✔
62
  SRequestObj* pRequest = acquireRequest(*(int64_t*)param);
2,062,552✔
63
  if (NULL == pRequest) {
2,062,552✔
64
    goto EXIT;
×
65
  }
66

67
  if (code != TSDB_CODE_SUCCESS) {
2,062,552✔
68
    goto End;
8,275✔
69
  }
70

71
  STscObj* pTscObj = pRequest->pTscObj;
2,054,277✔
72

73
  if (NULL == pTscObj->pAppInfo) {
2,054,277✔
74
    code = TSDB_CODE_TSC_DISCONNECTED;
×
75
    goto End;
×
76
  }
77

78
  if (pTscObj->connType == CONN_TYPE__AUTH_TEST) {
2,054,277✔
79
    // auth test connection, no need to process connect rsp
80
    goto End;
×
81
  }
82

83
  SConnectRsp connectRsp = {0};
2,054,277✔
84
  if (tDeserializeSConnectRsp(pMsg->pData, pMsg->len, &connectRsp) != 0) {
2,054,277✔
85
    code = TSDB_CODE_TSC_INVALID_VERSION;
×
86
    goto End;
×
87
  }
88

89
  if ((code = taosCheckVersionCompatibleFromStr(td_version, connectRsp.sVer, 3)) != 0) {
2,054,236✔
90
    tscError("version not compatible. client version:%s, server version:%s", td_version, connectRsp.sVer);
×
91
    goto End;
×
92
  }
93

94
  int32_t now = taosGetTimestampSec();
2,054,075✔
95
  int32_t delta = abs(now - connectRsp.svrTimestamp);
2,054,075✔
96
  if (delta > tsTimestampDeltaLimit) {
2,054,075✔
UNCOV
97
    code = TSDB_CODE_TIME_UNSYNCED;
×
UNCOV
98
    tscError("time diff:%ds is too big", delta);
×
99
    goto End;
×
100
  }
101

102
  if (connectRsp.epSet.numOfEps == 0) {
2,054,277✔
103
    code = TSDB_CODE_APP_ERROR;
×
104
    goto End;
×
105
  }
106

107
  int    updateEpSet = 1;
2,054,277✔
108
  SEpSet srcEpSet = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
2,054,277✔
109
  if (connectRsp.dnodeNum == 1) {
2,054,236✔
110
    SEpSet dstEpSet = connectRsp.epSet;
1,889,333✔
111
    if (srcEpSet.numOfEps == 1) {
1,889,374✔
112
      if (rpcSetDefaultAddr(pTscObj->pAppInfo->pTransporter, srcEpSet.eps[srcEpSet.inUse].fqdn,
1,037,535✔
113
                            dstEpSet.eps[dstEpSet.inUse].fqdn) != 0) {
1,037,549✔
114
        tscError("failed to set default addr for rpc");
×
115
      }
116
      updateEpSet = 0;
1,037,751✔
117
    }
118
  }
119
  if (updateEpSet == 1 && !isEpsetEqual(&srcEpSet, &connectRsp.epSet)) {
2,054,041✔
120
    SEpSet corEpSet = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
884,158✔
121

122
    SEpSet* pOrig = &corEpSet;
884,130✔
123
    SEp*    pOrigEp = &pOrig->eps[pOrig->inUse];
884,130✔
124
    SEp*    pNewEp = &connectRsp.epSet.eps[connectRsp.epSet.inUse];
884,130✔
125
    tscDebug("mnode epset updated from %d/%d=>%s:%d to %d/%d=>%s:%d in connRsp", pOrig->inUse, pOrig->numOfEps,
884,130✔
126
             pOrigEp->fqdn, pOrigEp->port, connectRsp.epSet.inUse, connectRsp.epSet.numOfEps, pNewEp->fqdn,
127
             pNewEp->port);
128
    updateEpSet_s(&pTscObj->pAppInfo->mgmtEp, &connectRsp.epSet);
884,130✔
129
  }
130

131
  for (int32_t i = 0; i < connectRsp.epSet.numOfEps; ++i) {
4,147,923✔
132
    tscDebug("QID:0x%" PRIx64 ", epSet.fqdn[%d]:%s port:%d, conn:0x%" PRIx64, pRequest->requestId, i,
2,095,983✔
133
             connectRsp.epSet.eps[i].fqdn, connectRsp.epSet.eps[i].port, pTscObj->id);
134
  }
135

136
  pTscObj->sysInfo = connectRsp.sysInfo;
2,051,940✔
137
  pTscObj->connId = connectRsp.connId;
2,054,006✔
138
  pTscObj->acctId = connectRsp.acctId;
2,053,209✔
139
  if (pTscObj->user[0] == 0) {
2,053,020✔
140
    tstrncpy(pTscObj->user, connectRsp.user, tListLen(pTscObj->user));
30✔
141
    tstrncpy(pTscObj->tokenName, connectRsp.tokenName, tListLen(pTscObj->tokenName));
30✔
142
  } else {
143
    pTscObj->tokenName[0] = 0;
2,052,877✔
144
  }
145
  tstrncpy(pTscObj->sVer, connectRsp.sVer, tListLen(pTscObj->sVer));
2,052,657✔
146
  tstrncpy(pTscObj->sDetailVer, connectRsp.sDetailVer, tListLen(pTscObj->sDetailVer));
2,053,476✔
147

148
  // update the appInstInfo
149
  pTscObj->pAppInfo->clusterId = connectRsp.clusterId;
2,053,695✔
150
  pTscObj->pAppInfo->serverCfg.monitorParas = connectRsp.monitorParas;
2,052,766✔
151
  pTscObj->pAppInfo->serverCfg.enableAuditDelete = connectRsp.enableAuditDelete;
2,053,784✔
152
  pTscObj->pAppInfo->serverCfg.enableAuditSelect = connectRsp.enableAuditSelect;
2,053,410✔
153
  pTscObj->pAppInfo->serverCfg.enableAuditInsert = connectRsp.enableAuditInsert;
2,053,354✔
154
  pTscObj->pAppInfo->serverCfg.auditLevel = connectRsp.auditLevel;
2,051,509✔
155
  tscDebug("monitor paras from connect rsp, clusterId:0x%" PRIx64 ", threshold:%d scope:%d",
2,052,724✔
156
           connectRsp.clusterId, connectRsp.monitorParas.tsSlowLogThreshold, connectRsp.monitorParas.tsSlowLogScope);
157
  lastClusterId = connectRsp.clusterId;
2,052,724✔
158

159
  pTscObj->connType = connectRsp.connType;
2,052,724✔
160
  pTscObj->passInfo.ver = connectRsp.passVer;
2,051,071✔
161
  pTscObj->authVer = connectRsp.authVer;
2,052,000✔
162
  pTscObj->whiteListInfo.ver = connectRsp.whiteListVer;
2,051,212✔
163
  pTscObj->userId = connectRsp.userId;
2,053,268✔
164

165
  if (taosHashGet(appInfo.pInstMapByClusterId, &connectRsp.clusterId, LONG_BYTES) == NULL) {
2,051,637✔
166
    if (taosHashPut(appInfo.pInstMapByClusterId, &connectRsp.clusterId, LONG_BYTES, &pTscObj->pAppInfo,
1,157,659✔
167
                    POINTER_BYTES) != 0) {
UNCOV
168
      tscError("failed to put appInfo into appInfo.pInstMapByClusterId");
×
169
    } else {
170
#ifdef USE_MONITOR
171
      MonitorSlowLogData data = {0};
1,157,659✔
172
      data.clusterId = pTscObj->pAppInfo->clusterId;
1,157,659✔
173
      data.type = SLOW_LOG_READ_BEGINNIG;
1,157,659✔
174
      (void)monitorPutData2MonitorQueue(data);  // ignore
1,157,659✔
175
      monitorClientSlowQueryInit(connectRsp.clusterId);
1,157,659✔
176
      monitorClientSQLReqInit(connectRsp.clusterId);
1,157,659✔
177
#endif
178
    }
179
  }
180

181
  (void)taosThreadMutexLock(&clientHbMgr.lock);
2,053,668✔
182
  SAppHbMgr* pAppHbMgr = taosArrayGetP(clientHbMgr.appHbMgrs, pTscObj->appHbMgrIdx);
2,054,277✔
183
  if (pAppHbMgr) {
2,054,277✔
184
    if (hbRegisterConn(pAppHbMgr, pTscObj->id, pTscObj->user, pTscObj->tokenName, connectRsp.clusterId, connectRsp.connType) != 0) {
2,054,277✔
UNCOV
185
      tscError("QID:0x%" PRIx64 ", failed to register conn to hbMgr", pRequest->requestId);
×
186
    }
187
  } else {
188
    (void)taosThreadMutexUnlock(&clientHbMgr.lock);
×
189
    code = TSDB_CODE_TSC_DISCONNECTED;
×
UNCOV
190
    goto End;
×
191
  }
192
  (void)taosThreadMutexUnlock(&clientHbMgr.lock);
2,054,277✔
193

194
  tscDebug("QID:0x%" PRIx64 ", clusterId:0x%" PRIx64 ", totalConn:%" PRId64, pRequest->requestId, connectRsp.clusterId,
2,054,277✔
195
           pTscObj->pAppInfo->numOfConns);
196

197
End:
2,042,686✔
198
  if (code != 0) {
2,062,552✔
199
    setErrno(pRequest, code);
8,275✔
200
  }
201
  if (tsem_post(&pRequest->body.rspSem) != 0) {
2,062,552✔
UNCOV
202
    tscError("failed to post semaphore");
×
203
  }
204

205
  if (pRequest) {
2,062,552✔
206
    (void)releaseRequest(pRequest->self);
2,062,552✔
207
  }
208

209
EXIT:
2,020,041✔
210
  taosMemoryFree(param);
2,062,552✔
211
  taosMemoryFree(pMsg->pEpSet);
2,062,552✔
212
  taosMemoryFree(pMsg->pData);
2,062,552✔
213
  return code;
2,062,552✔
214
}
215

216
SMsgSendInfo* buildMsgInfoImpl(SRequestObj* pRequest) {
14,126,166✔
217
  SMsgSendInfo* pMsgSendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
14,126,166✔
218
  if (pMsgSendInfo == NULL) return pMsgSendInfo;
14,126,152✔
219
  pMsgSendInfo->requestObjRefId = pRequest->self;
14,126,152✔
220
  pMsgSendInfo->requestId = pRequest->requestId;
14,126,416✔
221
  pMsgSendInfo->param = pRequest;
14,126,249✔
222
  pMsgSendInfo->msgType = pRequest->type;
14,126,152✔
223
  pMsgSendInfo->target.type = TARGET_TYPE_MNODE;
14,125,959✔
224

225
  pMsgSendInfo->msgInfo = pRequest->body.requestMsg;
14,125,695✔
226
  pMsgSendInfo->fp = getMsgRspHandle(pRequest->type);
14,126,126✔
227
  return pMsgSendInfo;
14,126,513✔
228
}
229

230
int32_t processCreateDbRsp(void* param, SDataBuf* pMsg, int32_t code) {
1,220,781✔
231
  // todo rsp with the vnode id list
232
  SRequestObj* pRequest = param;
1,220,781✔
233
  taosMemoryFree(pMsg->pData);
1,220,781✔
234
  taosMemoryFree(pMsg->pEpSet);
1,220,781✔
235
  if (code != TSDB_CODE_SUCCESS) {
1,220,781✔
236
    setErrno(pRequest, code);
23,680✔
237
  } else {
238
    struct SCatalog* pCatalog = NULL;
1,197,101✔
239
    code = catalogGetHandle(pRequest->pTscObj->pAppInfo->clusterId, &pCatalog);
1,197,101✔
240
    if (TSDB_CODE_SUCCESS == code) {
1,197,101✔
241
      STscObj* pTscObj = pRequest->pTscObj;
1,197,101✔
242

243
      SRequestConnInfo conn = {.pTrans = pTscObj->pAppInfo->pTransporter,
1,197,101✔
244
                               .requestId = pRequest->requestId,
1,197,101✔
245
                               .requestObjRefId = pRequest->self,
1,197,101✔
246
                               .mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp)};
1,197,101✔
247
      char             dbFName[TSDB_DB_FNAME_LEN];
1,183,057✔
248
      (void)snprintf(dbFName, sizeof(dbFName) - 1, "%d.%s", pTscObj->acctId, TSDB_INFORMATION_SCHEMA_DB);
1,197,101✔
249
      if (catalogRefreshDBVgInfo(pCatalog, &conn, dbFName) != 0) {
1,197,101✔
UNCOV
250
        tscError("QID:0x%" PRIx64 ", failed to refresh db vg info", pRequest->requestId);
×
251
      }
252
      (void)snprintf(dbFName, sizeof(dbFName) - 1, "%d.%s", pTscObj->acctId, TSDB_PERFORMANCE_SCHEMA_DB);
1,197,101✔
253
      if (catalogRefreshDBVgInfo(pCatalog, &conn, dbFName) != 0) {
1,197,101✔
UNCOV
254
        tscError("QID:0x%" PRIx64 ", failed to refresh db vg info", pRequest->requestId);
×
255
      }
256
    }
257
  }
258

259
  if (pRequest->body.queryFp) {
1,220,781✔
260
    doRequestCallback(pRequest, code);
1,220,781✔
261
  } else {
262
    if (tsem_post(&pRequest->body.rspSem) != 0) {
×
UNCOV
263
      tscError("failed to post semaphore");
×
264
    }
265
  }
266
  return code;
1,220,781✔
267
}
268

269
int32_t processUseDbRsp(void* param, SDataBuf* pMsg, int32_t code) {
1,975,451✔
270
  SRequestObj* pRequest = param;
1,975,451✔
271
  if (TSDB_CODE_MND_DB_NOT_EXIST == code || TSDB_CODE_MND_DB_IN_CREATING == code ||
1,975,451✔
272
      TSDB_CODE_MND_DB_IN_DROPPING == code) {
273
    SUseDbRsp usedbRsp = {0};
1,583✔
274
    if (tDeserializeSUseDbRsp(pMsg->pData, pMsg->len, &usedbRsp) != 0) {
1,583✔
275
      tscError("QID:0x%" PRIx64 ", deserialize SUseDbRsp failed", pRequest->requestId);
1,583✔
276
    }
277
    struct SCatalog* pCatalog = NULL;
1,583✔
278

279
    if (usedbRsp.vgVersion >= 0) {  // cached in local
1,583✔
280
      int64_t clusterId = pRequest->pTscObj->pAppInfo->clusterId;
1,583✔
281
      int32_t code1 = catalogGetHandle(clusterId, &pCatalog);
1,583✔
282
      if (code1 != TSDB_CODE_SUCCESS) {
1,583✔
UNCOV
283
        tscWarn("QID:0x%" PRIx64 ", catalogGetHandle failed, clusterId:0x%" PRIx64 ", error:%s", pRequest->requestId, clusterId,
×
284
                tstrerror(code1));
285
      } else {
286
        if (catalogRemoveDB(pCatalog, usedbRsp.db, usedbRsp.uid) != 0) {
1,583✔
UNCOV
287
          tscError("QID:0x%" PRIx64 ", catalogRemoveDB failed, db:%s, uid:%" PRId64, pRequest->requestId, usedbRsp.db,
×
288
                   usedbRsp.uid);
289
        }
290
      }
291
    }
292
    tFreeSUsedbRsp(&usedbRsp);
1,583✔
293
  }
294

295
  if (code != TSDB_CODE_SUCCESS) {
1,975,451✔
296
    taosMemoryFree(pMsg->pData);
1,583✔
297
    taosMemoryFree(pMsg->pEpSet);
1,583✔
298
    setErrno(pRequest, code);
1,583✔
299

300
    if (pRequest->body.queryFp != NULL) {
1,583✔
301
      doRequestCallback(pRequest, pRequest->code);
1,583✔
302

303
    } else {
304
      if (tsem_post(&pRequest->body.rspSem) != 0) {
×
UNCOV
305
        tscError("failed to post semaphore");
×
306
      }
307
    }
308

309
    return code;
1,583✔
310
  }
311

312
  SUseDbRsp usedbRsp = {0};
1,973,868✔
313
  if (tDeserializeSUseDbRsp(pMsg->pData, pMsg->len, &usedbRsp) != 0) {
1,973,868✔
UNCOV
314
    tscError("QID:0x%" PRIx64 ", deserialize SUseDbRsp failed", pRequest->requestId);
×
315
  }
316

317
  if (strlen(usedbRsp.db) == 0) {
1,973,868✔
318
    taosMemoryFree(pMsg->pData);
×
UNCOV
319
    taosMemoryFree(pMsg->pEpSet);
×
320

321
    if (usedbRsp.errCode != 0) {
×
UNCOV
322
      return usedbRsp.errCode;
×
323
    } else {
UNCOV
324
      return TSDB_CODE_APP_ERROR;
×
325
    }
326
  }
327

328
  tscTrace("db:%s, usedbRsp received, numOfVgroups:%d", usedbRsp.db, usedbRsp.vgNum);
1,973,868✔
329
  for (int32_t i = 0; i < usedbRsp.vgNum; ++i) {
4,108,314✔
330
    SVgroupInfo* pInfo = taosArrayGet(usedbRsp.pVgroupInfos, i);
2,134,446✔
331
    if (pInfo == NULL) {
2,134,446✔
UNCOV
332
      continue;
×
333
    }
334
    tscTrace("vgId:%d, numOfEps:%d inUse:%d ", pInfo->vgId, pInfo->epSet.numOfEps, pInfo->epSet.inUse);
2,134,446✔
335
    for (int32_t j = 0; j < pInfo->epSet.numOfEps; ++j) {
4,429,948✔
336
      tscTrace("vgId:%d, index:%d epset:%s:%u", pInfo->vgId, j, pInfo->epSet.eps[j].fqdn, pInfo->epSet.eps[j].port);
2,295,502✔
337
    }
338
  }
339

340
  SName name = {0};
1,973,868✔
341
  if (tNameFromString(&name, usedbRsp.db, T_NAME_ACCT | T_NAME_DB) != TSDB_CODE_SUCCESS) {
1,973,868✔
UNCOV
342
    tscError("QID:0x%" PRIx64 ", failed to parse db name:%s", pRequest->requestId, usedbRsp.db);
×
343
  }
344

345
  SUseDbOutput output = {0};
1,973,868✔
346
  code = queryBuildUseDbOutput(&output, &usedbRsp);
1,973,868✔
347
  if (code != 0) {
1,973,854✔
348
    terrno = code;
×
UNCOV
349
    if (output.dbVgroup) taosHashCleanup(output.dbVgroup->vgHash);
×
350

UNCOV
351
    tscError("QID:0x%" PRIx64 ", failed to build use db output since %s", pRequest->requestId, terrstr());
×
352
  } else if (output.dbVgroup && output.dbVgroup->vgHash) {
1,973,854✔
353
    struct SCatalog* pCatalog = NULL;
994,464✔
354

355
    int32_t code1 = catalogGetHandle(pRequest->pTscObj->pAppInfo->clusterId, &pCatalog);
994,464✔
356
    if (code1 != TSDB_CODE_SUCCESS) {
994,464✔
UNCOV
357
      tscWarn("catalogGetHandle failed, clusterId:0x%" PRIx64 ", error:%s", pRequest->pTscObj->pAppInfo->clusterId,
×
358
              tstrerror(code1));
359
    } else {
360
      if (catalogUpdateDBVgInfo(pCatalog, output.db, output.dbId, output.dbVgroup) != 0) {
994,464✔
UNCOV
361
        tscError("QID:0x%" PRIx64 ", failed to update db vg info, db:%s, dbId:%" PRId64, pRequest->requestId, output.db,
×
362
                 output.dbId);
363
      }
364
      output.dbVgroup = NULL;
994,464✔
365
    }
366
  }
367

368
  taosMemoryFreeClear(output.dbVgroup);
1,973,868✔
369
  tFreeSUsedbRsp(&usedbRsp);
1,973,868✔
370

371
  char db[TSDB_DB_NAME_LEN] = {0};
1,973,854✔
372
  if (tNameGetDbName(&name, db) != TSDB_CODE_SUCCESS) {
1,973,854✔
UNCOV
373
    tscError("QID:0x%" PRIx64 ", failed to get db name since %s", pRequest->requestId, tstrerror(code));
×
374
  }
375

376
  setConnectionDB(pRequest->pTscObj, db);
1,973,868✔
377

378
  taosMemoryFree(pMsg->pData);
1,973,868✔
379
  taosMemoryFree(pMsg->pEpSet);
1,973,868✔
380

381
  if (pRequest->body.queryFp != NULL) {
1,973,868✔
382
    doRequestCallback(pRequest, pRequest->code);
1,973,868✔
383
  } else {
384
    if (tsem_post(&pRequest->body.rspSem) != 0) {
×
UNCOV
385
      tscError("failed to post semaphore");
×
386
    }
387
  }
388
  return 0;
1,973,868✔
389
}
390

391
int32_t processCreateSTableRsp(void* param, SDataBuf* pMsg, int32_t code) {
1,621,858✔
392
  if (pMsg == NULL) {
1,621,858✔
393
    tscError("processCreateSTableRsp: invalid input param, pMsg is NULL");
×
UNCOV
394
    return TSDB_CODE_TSC_INVALID_INPUT;
×
395
  }
396
  if (param == NULL) {
1,621,858✔
397
    taosMemoryFree(pMsg->pEpSet);
×
398
    taosMemoryFree(pMsg->pData);
×
399
    tscError("processCreateSTableRsp: invalid input param, param is NULL");
×
UNCOV
400
    return TSDB_CODE_TSC_INVALID_INPUT;
×
401
  }
402

403
  SRequestObj* pRequest = param;
1,621,858✔
404

405
  if (code != TSDB_CODE_SUCCESS) {
1,621,858✔
406
    setErrno(pRequest, code);
9,910✔
407
  } else {
408
    SMCreateStbRsp createRsp = {0};
1,611,948✔
409
    SDecoder       coder = {0};
1,611,948✔
410
    tDecoderInit(&coder, pMsg->pData, pMsg->len);
1,611,948✔
411
    if (pMsg->len > 0) {
1,611,948✔
412
      code = tDecodeSMCreateStbRsp(&coder, &createRsp);  // pMsg->len == 0
1,594,139✔
413
      if (code != TSDB_CODE_SUCCESS) {
1,594,139✔
UNCOV
414
        setErrno(pRequest, code);
×
415
      }
416
    }
417
    tDecoderClear(&coder);
1,611,948✔
418

419
    pRequest->body.resInfo.execRes.msgType = TDMT_MND_CREATE_STB;
1,611,948✔
420
    pRequest->body.resInfo.execRes.res = createRsp.pMeta;
1,611,948✔
421
  }
422

423
  taosMemoryFree(pMsg->pEpSet);
1,621,858✔
424
  taosMemoryFree(pMsg->pData);
1,621,858✔
425

426
  if (pRequest->body.queryFp != NULL) {
1,621,858✔
427
    SExecResult* pRes = &pRequest->body.resInfo.execRes;
1,237,719✔
428

429
    if (code == TSDB_CODE_SUCCESS) {
1,237,719✔
430
      SCatalog* pCatalog = NULL;
1,233,891✔
431
      int32_t   ret = catalogGetHandle(pRequest->pTscObj->pAppInfo->clusterId, &pCatalog);
1,233,891✔
432
      if (pRes->res != NULL) {
1,233,891✔
433
        ret = handleCreateTbExecRes(pRes->res, pCatalog);
1,231,012✔
434
      }
435

436
      if (ret != TSDB_CODE_SUCCESS) {
1,233,891✔
UNCOV
437
        code = ret;
×
438
      }
439
    }
440

441
    doRequestCallback(pRequest, code);
1,237,719✔
442
  } else {
443
    if (tsem_post(&pRequest->body.rspSem) != 0) {
384,139✔
UNCOV
444
      tscError("failed to post semaphore");
×
445
    }
446
  }
447
  return code;
1,621,858✔
448
}
449

450
int32_t processDropDbRsp(void* param, SDataBuf* pMsg, int32_t code) {
1,050,193✔
451
  SRequestObj* pRequest = param;
1,050,193✔
452
  if (code != TSDB_CODE_SUCCESS) {
1,050,193✔
453
    setErrno(pRequest, code);
6,763✔
454
  } else {
455
    SDropDbRsp dropdbRsp = {0};
1,043,430✔
456
    if (tDeserializeSDropDbRsp(pMsg->pData, pMsg->len, &dropdbRsp) != 0) {
1,043,430✔
UNCOV
457
      tscError("QID:0x%" PRIx64 ", deserialize SDropDbRsp failed", pRequest->requestId);
×
458
    }
459
    struct SCatalog* pCatalog = NULL;
1,043,430✔
460
    code = catalogGetHandle(pRequest->pTscObj->pAppInfo->clusterId, &pCatalog);
1,043,430✔
461
    if (TSDB_CODE_SUCCESS == code) {
1,043,430✔
462
      if (catalogRemoveDB(pCatalog, dropdbRsp.db, dropdbRsp.uid) != 0) {
1,043,430✔
UNCOV
463
        tscError("QID:0x%" PRIx64 ", failed to remove db:%s", pRequest->requestId, dropdbRsp.db);
×
464
      }
465
      STscObj* pTscObj = pRequest->pTscObj;
1,043,430✔
466

467
      SRequestConnInfo conn = {.pTrans = pTscObj->pAppInfo->pTransporter,
1,043,430✔
468
                               .requestId = pRequest->requestId,
1,043,430✔
469
                               .requestObjRefId = pRequest->self,
1,043,430✔
470
                               .mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp)};
1,043,430✔
471
      char             dbFName[TSDB_DB_FNAME_LEN] = {0};
1,043,430✔
472
      (void)snprintf(dbFName, sizeof(dbFName) - 1, "%d.%s", pTscObj->acctId, TSDB_INFORMATION_SCHEMA_DB);
1,043,430✔
473
      if (catalogRefreshDBVgInfo(pCatalog, &conn, dbFName) != TSDB_CODE_SUCCESS) {
1,043,430✔
UNCOV
474
        tscError("QID:0x%" PRIx64 ", failed to refresh db vg info, db:%s", pRequest->requestId, dbFName);
×
475
      }
476
      (void)snprintf(dbFName, sizeof(dbFName) - 1, "%d.%s", pTscObj->acctId, TSDB_PERFORMANCE_SCHEMA_DB);
1,043,430✔
477
      if (catalogRefreshDBVgInfo(pCatalog, &conn, dbFName) != 0) {
1,043,430✔
UNCOV
478
        tscError("QID:0x%" PRIx64 ", failed to refresh db vg info, db:%s", pRequest->requestId, dbFName);
×
479
      }
480
    }
481
  }
482

483
  taosMemoryFree(pMsg->pData);
1,050,193✔
484
  taosMemoryFree(pMsg->pEpSet);
1,050,193✔
485

486
  if (pRequest->body.queryFp != NULL) {
1,050,193✔
487
    doRequestCallback(pRequest, code);
1,050,193✔
488
  } else {
489
    if (tsem_post(&pRequest->body.rspSem) != 0) {
×
UNCOV
490
      tscError("failed to post semaphore");
×
491
    }
492
  }
493
  return code;
1,050,193✔
494
}
495

496
int32_t processAlterStbRsp(void* param, SDataBuf* pMsg, int32_t code) {
5,268,042✔
497
  SRequestObj* pRequest = param;
5,268,042✔
498
  if (code != TSDB_CODE_SUCCESS) {
5,268,042✔
499
    setErrno(pRequest, code);
950,428✔
500
  } else {
501
    SMAlterStbRsp alterRsp = {0};
4,317,614✔
502
    SDecoder      coder = {0};
4,317,614✔
503
    tDecoderInit(&coder, pMsg->pData, pMsg->len);
4,317,614✔
504
    if (pMsg->len > 0) {
4,317,614✔
505
      code = tDecodeSMAlterStbRsp(&coder, &alterRsp);  // pMsg->len == 0
4,294,925✔
506
      if (code != TSDB_CODE_SUCCESS) {
4,294,925✔
UNCOV
507
        setErrno(pRequest, code);
×
508
      }
509
    }
510
    tDecoderClear(&coder);
4,317,614✔
511

512
    pRequest->body.resInfo.execRes.msgType = TDMT_MND_ALTER_STB;
4,317,614✔
513
    pRequest->body.resInfo.execRes.res = alterRsp.pMeta;
4,317,614✔
514
  }
515

516
  taosMemoryFree(pMsg->pData);
5,268,042✔
517
  taosMemoryFree(pMsg->pEpSet);
5,268,042✔
518

519
  if (pRequest->body.queryFp != NULL) {
5,268,042✔
520
    SExecResult* pRes = &pRequest->body.resInfo.execRes;
5,268,042✔
521

522
    if (code == TSDB_CODE_SUCCESS) {
5,268,042✔
523
      SCatalog* pCatalog = NULL;
4,317,614✔
524
      int32_t   ret = catalogGetHandle(pRequest->pTscObj->pAppInfo->clusterId, &pCatalog);
4,317,614✔
525
      if (pRes->res != NULL) {
4,317,614✔
526
        ret = handleAlterTbExecRes(pRes->res, pCatalog);
4,294,925✔
527
      }
528

529
      if (ret != TSDB_CODE_SUCCESS) {
4,317,614✔
UNCOV
530
        code = ret;
×
531
      }
532
    }
533

534
    doRequestCallback(pRequest, code);
5,268,042✔
535
  } else {
536
    if (tsem_post(&pRequest->body.rspSem) != 0) {
×
UNCOV
537
      tscError("failed to post semaphore");
×
538
    }
539
  }
540
  return code;
5,268,042✔
541
}
542

543
static int32_t buildShowVariablesBlock(SArray* pVars, SSDataBlock** block) {
8,621✔
544
  int32_t      code = 0;
8,621✔
545
  int32_t      line = 0;
8,621✔
546
  SSDataBlock* pBlock = taosMemoryCalloc(1, sizeof(SSDataBlock));
8,621✔
547
  TSDB_CHECK_NULL(pBlock, code, line, END, terrno);
8,621✔
548
  pBlock->info.hasVarCol = true;
8,621✔
549

550
  pBlock->pDataBlock = taosArrayInit(SHOW_VARIABLES_RESULT_COLS, sizeof(SColumnInfoData));
8,621✔
551
  TSDB_CHECK_NULL(pBlock->pDataBlock, code, line, END, terrno);
8,621✔
552
  SColumnInfoData infoData = {0};
8,621✔
553
  infoData.info.type = TSDB_DATA_TYPE_VARCHAR;
8,621✔
554
  infoData.info.bytes = SHOW_VARIABLES_RESULT_FIELD1_LEN;
8,621✔
555
  TSDB_CHECK_NULL(taosArrayPush(pBlock->pDataBlock, &infoData), code, line, END, terrno);
17,242✔
556

557
  infoData.info.type = TSDB_DATA_TYPE_VARCHAR;
8,621✔
558
  infoData.info.bytes = SHOW_VARIABLES_RESULT_FIELD2_LEN;
8,621✔
559
  TSDB_CHECK_NULL(taosArrayPush(pBlock->pDataBlock, &infoData), code, line, END, terrno);
17,242✔
560

561
  infoData.info.type = TSDB_DATA_TYPE_VARCHAR;
8,621✔
562
  infoData.info.bytes = SHOW_VARIABLES_RESULT_FIELD3_LEN;
8,621✔
563
  TSDB_CHECK_NULL(taosArrayPush(pBlock->pDataBlock, &infoData), code, line, END, terrno);
17,242✔
564

565
  infoData.info.type = TSDB_DATA_TYPE_VARCHAR;
8,621✔
566
  infoData.info.bytes = SHOW_VARIABLES_RESULT_FIELD4_LEN;
8,621✔
567
  TSDB_CHECK_NULL(taosArrayPush(pBlock->pDataBlock, &infoData), code, line, END, terrno);
17,242✔
568

569
  infoData.info.type = TSDB_DATA_TYPE_VARCHAR;
8,621✔
570
  infoData.info.bytes = SHOW_VARIABLES_RESULT_FIELD5_LEN;
8,621✔
571
  TSDB_CHECK_NULL(taosArrayPush(pBlock->pDataBlock, &infoData), code, line, END, terrno);
17,242✔
572

573
  int32_t numOfCfg = taosArrayGetSize(pVars);
8,621✔
574
  code = blockDataEnsureCapacity(pBlock, numOfCfg);
8,621✔
575
  TSDB_CHECK_CODE(code, line, END);
8,621✔
576

577
  for (int32_t i = 0, c = 0; i < numOfCfg; ++i, c = 0) {
827,338✔
578
    SVariablesInfo* pInfo = taosArrayGet(pVars, i);
818,717✔
579
    TSDB_CHECK_NULL(pInfo, code, line, END, terrno);
818,717✔
580

581
    char name[TSDB_CONFIG_OPTION_LEN + VARSTR_HEADER_SIZE] = {0};
818,717✔
582
    STR_WITH_MAXSIZE_TO_VARSTR(name, pInfo->name, TSDB_CONFIG_OPTION_LEN + VARSTR_HEADER_SIZE);
818,717✔
583
    SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, c++);
818,717✔
584
    TSDB_CHECK_NULL(pColInfo, code, line, END, terrno);
818,717✔
585
    code = colDataSetVal(pColInfo, i, name, false);
818,717✔
586
    TSDB_CHECK_CODE(code, line, END);
818,717✔
587

588
    char value[TSDB_CONFIG_VALUE_LEN + VARSTR_HEADER_SIZE] = {0};
818,717✔
589
    STR_WITH_MAXSIZE_TO_VARSTR(value, pInfo->value, TSDB_CONFIG_VALUE_LEN + VARSTR_HEADER_SIZE);
818,717✔
590
    pColInfo = taosArrayGet(pBlock->pDataBlock, c++);
818,717✔
591
    TSDB_CHECK_NULL(pColInfo, code, line, END, terrno);
818,717✔
592
    code = colDataSetVal(pColInfo, i, value, false);
818,717✔
593
    TSDB_CHECK_CODE(code, line, END);
818,717✔
594

595
    char scope[TSDB_CONFIG_SCOPE_LEN + VARSTR_HEADER_SIZE] = {0};
818,717✔
596
    STR_WITH_MAXSIZE_TO_VARSTR(scope, pInfo->scope, TSDB_CONFIG_SCOPE_LEN + VARSTR_HEADER_SIZE);
818,717✔
597
    pColInfo = taosArrayGet(pBlock->pDataBlock, c++);
818,717✔
598
    TSDB_CHECK_NULL(pColInfo, code, line, END, terrno);
818,717✔
599
    code = colDataSetVal(pColInfo, i, scope, false);
818,717✔
600
    TSDB_CHECK_CODE(code, line, END);
818,717✔
601

602
    char category[TSDB_CONFIG_CATEGORY_LEN + VARSTR_HEADER_SIZE] = {0};
818,717✔
603
    STR_WITH_MAXSIZE_TO_VARSTR(category, pInfo->category, TSDB_CONFIG_CATEGORY_LEN + VARSTR_HEADER_SIZE);
818,717✔
604
    pColInfo = taosArrayGet(pBlock->pDataBlock, c++);
818,717✔
605
    TSDB_CHECK_NULL(pColInfo, code, line, END, terrno);
818,717✔
606
    code = colDataSetVal(pColInfo, i, category, false);
818,717✔
607
    TSDB_CHECK_CODE(code, line, END);
818,717✔
608

609
    char info[TSDB_CONFIG_INFO_LEN + VARSTR_HEADER_SIZE] = {0};
818,717✔
610
    STR_WITH_MAXSIZE_TO_VARSTR(info, pInfo->info, TSDB_CONFIG_INFO_LEN + VARSTR_HEADER_SIZE);
818,717✔
611
    pColInfo = taosArrayGet(pBlock->pDataBlock, c++);
818,717✔
612
    TSDB_CHECK_NULL(pColInfo, code, line, END, terrno);
818,717✔
613
    code = colDataSetVal(pColInfo, i, info, false);
818,717✔
614
    TSDB_CHECK_CODE(code, line, END);
818,717✔
615
  }
616

617
  pBlock->info.rows = numOfCfg;
8,621✔
618

619
  *block = pBlock;
8,621✔
620
  return code;
8,621✔
621

622
END:
×
623
  taosArrayDestroy(pBlock->pDataBlock);
×
624
  taosMemoryFree(pBlock);
×
UNCOV
625
  return code;
×
626
}
627

628
static int32_t buildShowVariablesRsp(SArray* pVars, SRetrieveTableRsp** pRsp) {
8,621✔
629
  SSDataBlock* pBlock = NULL;
8,621✔
630
  int32_t      code = buildShowVariablesBlock(pVars, &pBlock);
8,621✔
631
  if (code) {
8,621✔
UNCOV
632
    return code;
×
633
  }
634

635
  size_t dataEncodeBufSize = blockGetEncodeSize(pBlock);
8,621✔
636
  size_t rspSize = sizeof(SRetrieveTableRsp) + dataEncodeBufSize + PAYLOAD_PREFIX_LEN;
8,621✔
637
  *pRsp = taosMemoryCalloc(1, rspSize);
8,621✔
638
  if (NULL == *pRsp) {
8,621✔
639
    code = terrno;
×
UNCOV
640
    goto _exit;
×
641
  }
642

643
  (*pRsp)->useconds = 0;
8,621✔
644
  (*pRsp)->completed = 1;
8,621✔
645
  (*pRsp)->precision = 0;
8,621✔
646
  (*pRsp)->compressed = 0;
8,621✔
647

648
  (*pRsp)->numOfRows = htobe64((int64_t)pBlock->info.rows);
8,621✔
649
  (*pRsp)->numOfCols = htonl(SHOW_VARIABLES_RESULT_COLS);
8,621✔
650

651
  int32_t len = 0;
8,621✔
652
  if ((*pRsp)->numOfRows > 0) {
8,621✔
653
    len = blockEncode(pBlock, (*pRsp)->data + PAYLOAD_PREFIX_LEN, dataEncodeBufSize, SHOW_VARIABLES_RESULT_COLS);
8,117✔
654
    if (len < 0) {
8,117✔
655
      uError("buildShowVariablesRsp error, len:%d", len);
×
656
      code = terrno;
×
UNCOV
657
      goto _exit;
×
658
    }
659
    SET_PAYLOAD_LEN((*pRsp)->data, len, len);
8,117✔
660

661
    int32_t payloadLen = len + PAYLOAD_PREFIX_LEN;
8,117✔
662
    (*pRsp)->payloadLen = htonl(payloadLen);
8,117✔
663
    (*pRsp)->compLen = htonl(payloadLen);
8,117✔
664

665
    if (payloadLen != rspSize - sizeof(SRetrieveTableRsp)) {
8,117✔
UNCOV
666
      uError("buildShowVariablesRsp error, len:%d != rspSize - sizeof(SRetrieveTableRsp):%" PRIu64, len,
×
667
             (uint64_t)(rspSize - sizeof(SRetrieveTableRsp)));
668
      code = TSDB_CODE_TSC_INVALID_INPUT;
×
UNCOV
669
      goto _exit;
×
670
    }
671
  }
672

673
  blockDataDestroy(pBlock);
8,621✔
674
  pBlock = NULL;
8,621✔
675

676
  return TSDB_CODE_SUCCESS;
8,621✔
677
_exit:
×
678
  if (*pRsp) {
×
679
    taosMemoryFree(*pRsp);
×
UNCOV
680
    *pRsp = NULL;
×
681
  }
682
  if (pBlock) {
×
683
    blockDataDestroy(pBlock);
×
UNCOV
684
    pBlock = NULL;
×
685
  }
UNCOV
686
  return code;
×
687
}
688

689
int32_t processShowVariablesRsp(void* param, SDataBuf* pMsg, int32_t code) {
8,621✔
690
  SRequestObj* pRequest = param;
8,621✔
691
  if (code != TSDB_CODE_SUCCESS) {
8,621✔
UNCOV
692
    setErrno(pRequest, code);
×
693
  } else {
694
    SShowVariablesRsp  rsp = {0};
8,621✔
695
    SRetrieveTableRsp* pRes = NULL;
8,621✔
696
    code = tDeserializeSShowVariablesRsp(pMsg->pData, pMsg->len, &rsp);
8,621✔
697
    if (TSDB_CODE_SUCCESS == code) {
8,621✔
698
      code = buildShowVariablesRsp(rsp.variables, &pRes);
8,621✔
699
    }
700
    if (TSDB_CODE_SUCCESS == code) {
8,621✔
701
      code = setQueryResultFromRsp(&pRequest->body.resInfo, pRes, false, pRequest->stmtBindVersion > 0);
8,621✔
702
    }
703

704
    if (code != 0) {
8,621✔
705
      pRequest->body.resInfo.pRspMsg = NULL;
×
UNCOV
706
      taosMemoryFree(pRes);
×
707
    }
708
    tFreeSShowVariablesRsp(&rsp);
8,621✔
709
  }
710

711
  taosMemoryFree(pMsg->pData);
8,621✔
712
  taosMemoryFree(pMsg->pEpSet);
8,621✔
713

714
  if (pRequest->body.queryFp != NULL) {
8,621✔
715
    doRequestCallback(pRequest, code);
8,621✔
716
  } else {
717
    if (tsem_post(&pRequest->body.rspSem) != 0) {
×
UNCOV
718
      tscError("failed to post semaphore");
×
719
    }
720
  }
721
  return code;
8,621✔
722
}
723

724
static int32_t buildCompactDbBlock(SCompactDbRsp* pRsp, SSDataBlock** block) {
43,171✔
725
  int32_t      code = 0;
43,171✔
726
  int32_t      line = 0;
43,171✔
727
  SSDataBlock* pBlock = taosMemoryCalloc(1, sizeof(SSDataBlock));
43,171✔
728
  TSDB_CHECK_NULL(pBlock, code, line, END, terrno);
43,171✔
729
  pBlock->info.hasVarCol = true;
43,171✔
730

731
  pBlock->pDataBlock = taosArrayInit(COMPACT_DB_RESULT_COLS, sizeof(SColumnInfoData));
43,171✔
732
  TSDB_CHECK_NULL(pBlock->pDataBlock, code, line, END, terrno);
43,171✔
733
  SColumnInfoData infoData = {0};
43,171✔
734
  infoData.info.type = TSDB_DATA_TYPE_VARCHAR;
43,171✔
735
  infoData.info.bytes = COMPACT_DB_RESULT_FIELD1_LEN;
43,171✔
736
  TSDB_CHECK_NULL(taosArrayPush(pBlock->pDataBlock, &infoData), code, line, END, terrno);
86,342✔
737

738
  infoData.info.type = TSDB_DATA_TYPE_INT;
43,171✔
739
  infoData.info.bytes = tDataTypes[TSDB_DATA_TYPE_INT].bytes;
43,171✔
740
  TSDB_CHECK_NULL(taosArrayPush(pBlock->pDataBlock, &infoData), code, line, END, terrno);
86,342✔
741

742
  infoData.info.type = TSDB_DATA_TYPE_VARCHAR;
43,171✔
743
  infoData.info.bytes = COMPACT_DB_RESULT_FIELD3_LEN;
43,171✔
744
  TSDB_CHECK_NULL(taosArrayPush(pBlock->pDataBlock, &infoData), code, line, END, terrno);
86,342✔
745

746
  code = blockDataEnsureCapacity(pBlock, 1);
43,171✔
747
  TSDB_CHECK_CODE(code, line, END);
43,171✔
748

749
  SColumnInfoData* pResultCol = taosArrayGet(pBlock->pDataBlock, 0);
43,171✔
750
  TSDB_CHECK_NULL(pResultCol, code, line, END, terrno);
43,171✔
751
  SColumnInfoData* pIdCol = taosArrayGet(pBlock->pDataBlock, 1);
43,171✔
752
  TSDB_CHECK_NULL(pIdCol, code, line, END, terrno);
43,171✔
753
  SColumnInfoData* pReasonCol = taosArrayGet(pBlock->pDataBlock, 2);
43,171✔
754
  TSDB_CHECK_NULL(pReasonCol, code, line, END, terrno);
43,171✔
755

756
  char result[COMPACT_DB_RESULT_FIELD1_LEN] = {0};
43,171✔
757
  char reason[COMPACT_DB_RESULT_FIELD3_LEN] = {0};
43,171✔
758
  if (pRsp->bAccepted) {
43,171✔
759
    STR_TO_VARSTR(result, "accepted");
43,171✔
760
    code = colDataSetVal(pResultCol, 0, result, false);
43,171✔
761
    TSDB_CHECK_CODE(code, line, END);
43,171✔
762
    code = colDataSetVal(pIdCol, 0, (void*)&pRsp->compactId, false);
43,171✔
763
    TSDB_CHECK_CODE(code, line, END);
43,171✔
764
    STR_TO_VARSTR(reason, "success");
43,171✔
765
    code = colDataSetVal(pReasonCol, 0, reason, false);
43,171✔
766
    TSDB_CHECK_CODE(code, line, END);
43,171✔
767
  } else {
768
    STR_TO_VARSTR(result, "rejected");
×
769
    code = colDataSetVal(pResultCol, 0, result, false);
×
UNCOV
770
    TSDB_CHECK_CODE(code, line, END);
×
771
    colDataSetNULL(pIdCol, 0);
772
    STR_TO_VARSTR(reason, "compaction is ongoing");
×
773
    code = colDataSetVal(pReasonCol, 0, reason, false);
×
UNCOV
774
    TSDB_CHECK_CODE(code, line, END);
×
775
  }
776
  pBlock->info.rows = 1;
43,171✔
777

778
  *block = pBlock;
43,171✔
779

780
  return TSDB_CODE_SUCCESS;
43,171✔
781
END:
×
782
  taosMemoryFree(pBlock);
×
783
  taosArrayDestroy(pBlock->pDataBlock);
×
UNCOV
784
  return code;
×
785
}
786

787
static int32_t buildRetriveTableRspForCompactDb(SCompactDbRsp* pCompactDb, SRetrieveTableRsp** pRsp) {
43,171✔
788
  SSDataBlock* pBlock = NULL;
43,171✔
789
  int32_t      code = buildCompactDbBlock(pCompactDb, &pBlock);
43,171✔
790
  if (code) {
43,171✔
UNCOV
791
    return code;
×
792
  }
793

794
  size_t dataEncodeBufSize = blockGetEncodeSize(pBlock);
43,171✔
795
  size_t rspSize = sizeof(SRetrieveTableRsp) + dataEncodeBufSize + PAYLOAD_PREFIX_LEN;
43,171✔
796
  *pRsp = taosMemoryCalloc(1, rspSize);
43,171✔
797
  if (NULL == *pRsp) {
43,171✔
798
    code = terrno;
×
UNCOV
799
    goto _exit;
×
800
  }
801

802
  (*pRsp)->useconds = 0;
43,171✔
803
  (*pRsp)->completed = 1;
43,171✔
804
  (*pRsp)->precision = 0;
43,171✔
805
  (*pRsp)->compressed = 0;
43,171✔
806
  (*pRsp)->compLen = 0;
43,171✔
807
  (*pRsp)->payloadLen = 0;
43,171✔
808
  (*pRsp)->numOfRows = htobe64((int64_t)pBlock->info.rows);
43,171✔
809
  (*pRsp)->numOfCols = htonl(COMPACT_DB_RESULT_COLS);
43,171✔
810

811
  int32_t len = blockEncode(pBlock, (*pRsp)->data + PAYLOAD_PREFIX_LEN, dataEncodeBufSize, COMPACT_DB_RESULT_COLS);
43,171✔
812
  if (len < 0) {
43,171✔
813
    uError("buildRetriveTableRspForCompactDb error, len:%d", len);
×
814
    code = terrno;
×
UNCOV
815
    goto _exit;
×
816
  }
817
  blockDataDestroy(pBlock);
43,171✔
818

819
  SET_PAYLOAD_LEN((*pRsp)->data, len, len);
43,171✔
820

821
  int32_t payloadLen = len + PAYLOAD_PREFIX_LEN;
43,171✔
822
  (*pRsp)->payloadLen = htonl(payloadLen);
43,171✔
823
  (*pRsp)->compLen = htonl(payloadLen);
43,171✔
824

825
  if (payloadLen != rspSize - sizeof(SRetrieveTableRsp)) {
43,171✔
UNCOV
826
    uError("buildRetriveTableRspForCompactDb error, len:%d != rspSize - sizeof(SRetrieveTableRsp):%" PRIu64, len,
×
827
           (uint64_t)(rspSize - sizeof(SRetrieveTableRsp)));
828
    code = TSDB_CODE_TSC_INVALID_INPUT;
×
UNCOV
829
    goto _exit;
×
830
  }
831

832
  return TSDB_CODE_SUCCESS;
43,171✔
833
_exit:
×
834
  if (*pRsp) {
×
835
    taosMemoryFree(*pRsp);
×
UNCOV
836
    *pRsp = NULL;
×
837
  }
838
  if (pBlock) {
×
839
    blockDataDestroy(pBlock);
×
UNCOV
840
    pBlock = NULL;
×
841
  }
UNCOV
842
  return code;
×
843
}
844

845
int32_t processCompactDbRsp(void* param, SDataBuf* pMsg, int32_t code) {
29,706✔
846
  SRequestObj* pRequest = param;
29,706✔
847
  if (code != TSDB_CODE_SUCCESS) {
29,706✔
848
    setErrno(pRequest, code);
1,744✔
849
  } else {
850
    SCompactDbRsp      rsp = {0};
27,962✔
851
    SRetrieveTableRsp* pRes = NULL;
27,962✔
852
    code = tDeserializeSCompactDbRsp(pMsg->pData, pMsg->len, &rsp);
27,962✔
853
    if (TSDB_CODE_SUCCESS == code) {
27,962✔
854
      code = buildRetriveTableRspForCompactDb(&rsp, &pRes);
27,962✔
855
    }
856
    if (TSDB_CODE_SUCCESS == code) {
27,962✔
857
      code = setQueryResultFromRsp(&pRequest->body.resInfo, pRes, false, pRequest->stmtBindVersion > 0);
27,962✔
858
    }
859

860
    if (code != 0) {
27,962✔
861
      pRequest->body.resInfo.pRspMsg = NULL;
×
UNCOV
862
      taosMemoryFree(pRes);
×
863
    }
864
  }
865

866
  taosMemoryFree(pMsg->pData);
29,706✔
867
  taosMemoryFree(pMsg->pEpSet);
29,706✔
868

869
  if (pRequest->body.queryFp != NULL) {
29,706✔
870
    pRequest->body.queryFp(((SSyncQueryParam*)pRequest->body.interParam)->userParam, pRequest, code);
29,706✔
871
  } else {
872
    if (tsem_post(&pRequest->body.rspSem) != 0) {
×
UNCOV
873
      tscError("failed to post semaphore");
×
874
    }
875
  }
876
  return code;
29,706✔
877
}
878

879
static int32_t buildScanDbBlock(SScanDbRsp* pRsp, SSDataBlock** block) {
240✔
880
  int32_t      code = 0;
240✔
881
  int32_t      line = 0;
240✔
882
  SSDataBlock* pBlock = taosMemoryCalloc(1, sizeof(SSDataBlock));
240✔
883
  TSDB_CHECK_NULL(pBlock, code, line, END, terrno);
240✔
884
  pBlock->info.hasVarCol = true;
240✔
885

886
  pBlock->pDataBlock = taosArrayInit(SCAN_DB_RESULT_COLS, sizeof(SColumnInfoData));
240✔
887
  TSDB_CHECK_NULL(pBlock->pDataBlock, code, line, END, terrno);
240✔
888
  SColumnInfoData infoData = {0};
240✔
889
  infoData.info.type = TSDB_DATA_TYPE_VARCHAR;
240✔
890
  infoData.info.bytes = SCAN_DB_RESULT_FIELD1_LEN;
240✔
891
  TSDB_CHECK_NULL(taosArrayPush(pBlock->pDataBlock, &infoData), code, line, END, terrno);
480✔
892

893
  infoData.info.type = TSDB_DATA_TYPE_INT;
240✔
894
  infoData.info.bytes = tDataTypes[TSDB_DATA_TYPE_INT].bytes;
240✔
895
  TSDB_CHECK_NULL(taosArrayPush(pBlock->pDataBlock, &infoData), code, line, END, terrno);
480✔
896

897
  infoData.info.type = TSDB_DATA_TYPE_VARCHAR;
240✔
898
  infoData.info.bytes = SCAN_DB_RESULT_FIELD3_LEN;
240✔
899
  TSDB_CHECK_NULL(taosArrayPush(pBlock->pDataBlock, &infoData), code, line, END, terrno);
480✔
900

901
  code = blockDataEnsureCapacity(pBlock, 1);
240✔
902
  TSDB_CHECK_CODE(code, line, END);
240✔
903

904
  SColumnInfoData* pResultCol = taosArrayGet(pBlock->pDataBlock, 0);
240✔
905
  TSDB_CHECK_NULL(pResultCol, code, line, END, terrno);
240✔
906
  SColumnInfoData* pIdCol = taosArrayGet(pBlock->pDataBlock, 1);
240✔
907
  TSDB_CHECK_NULL(pIdCol, code, line, END, terrno);
240✔
908
  SColumnInfoData* pReasonCol = taosArrayGet(pBlock->pDataBlock, 2);
240✔
909
  TSDB_CHECK_NULL(pReasonCol, code, line, END, terrno);
240✔
910

911
  char result[SCAN_DB_RESULT_FIELD1_LEN] = {0};
240✔
912
  char reason[SCAN_DB_RESULT_FIELD3_LEN] = {0};
240✔
913
  if (pRsp->bAccepted) {
240✔
914
    STR_TO_VARSTR(result, "accepted");
240✔
915
    code = colDataSetVal(pResultCol, 0, result, false);
240✔
916
    TSDB_CHECK_CODE(code, line, END);
240✔
917
    code = colDataSetVal(pIdCol, 0, (void*)&pRsp->scanId, false);
240✔
918
    TSDB_CHECK_CODE(code, line, END);
240✔
919
    STR_TO_VARSTR(reason, "success");
240✔
920
    code = colDataSetVal(pReasonCol, 0, reason, false);
240✔
921
    TSDB_CHECK_CODE(code, line, END);
240✔
922
  } else {
923
    STR_TO_VARSTR(result, "rejected");
×
924
    code = colDataSetVal(pResultCol, 0, result, false);
×
UNCOV
925
    TSDB_CHECK_CODE(code, line, END);
×
926
    colDataSetNULL(pIdCol, 0);
927
    STR_TO_VARSTR(reason, "scan is ongoing");
×
928
    code = colDataSetVal(pReasonCol, 0, reason, false);
×
UNCOV
929
    TSDB_CHECK_CODE(code, line, END);
×
930
  }
931
  pBlock->info.rows = 1;
240✔
932

933
  *block = pBlock;
240✔
934

935
  return TSDB_CODE_SUCCESS;
240✔
936
END:
×
937
  taosMemoryFree(pBlock);
×
938
  taosArrayDestroy(pBlock->pDataBlock);
×
UNCOV
939
  return code;
×
940
}
941

942
static int32_t buildRetriveTableRspForScanDb(SScanDbRsp* pScanDb, SRetrieveTableRsp** pRsp) {
240✔
943
  SSDataBlock* pBlock = NULL;
240✔
944
  int32_t      code = buildScanDbBlock(pScanDb, &pBlock);
240✔
945
  if (code) {
240✔
UNCOV
946
    return code;
×
947
  }
948

949
  size_t dataEncodeBufSize = blockGetEncodeSize(pBlock);
240✔
950
  size_t rspSize = sizeof(SRetrieveTableRsp) + dataEncodeBufSize + PAYLOAD_PREFIX_LEN;
240✔
951
  *pRsp = taosMemoryCalloc(1, rspSize);
240✔
952
  if (NULL == *pRsp) {
240✔
953
    code = terrno;
×
UNCOV
954
    goto _exit;
×
955
  }
956

957
  (*pRsp)->useconds = 0;
240✔
958
  (*pRsp)->completed = 1;
240✔
959
  (*pRsp)->precision = 0;
240✔
960
  (*pRsp)->compressed = 0;
240✔
961
  (*pRsp)->compLen = 0;
240✔
962
  (*pRsp)->payloadLen = 0;
240✔
963
  (*pRsp)->numOfRows = htobe64((int64_t)pBlock->info.rows);
240✔
964
  (*pRsp)->numOfCols = htonl(SCAN_DB_RESULT_COLS);
240✔
965

966
  int32_t len = blockEncode(pBlock, (*pRsp)->data + PAYLOAD_PREFIX_LEN, dataEncodeBufSize, SCAN_DB_RESULT_COLS);
240✔
967
  if (len < 0) {
240✔
968
    uError("%s error, len:%d", __func__, len);
×
969
    code = terrno;
×
UNCOV
970
    goto _exit;
×
971
  }
972
  blockDataDestroy(pBlock);
240✔
973

974
  SET_PAYLOAD_LEN((*pRsp)->data, len, len);
240✔
975

976
  int32_t payloadLen = len + PAYLOAD_PREFIX_LEN;
240✔
977
  (*pRsp)->payloadLen = htonl(payloadLen);
240✔
978
  (*pRsp)->compLen = htonl(payloadLen);
240✔
979

980
  if (payloadLen != rspSize - sizeof(SRetrieveTableRsp)) {
240✔
UNCOV
981
    uError("%s error, len:%d != rspSize - sizeof(SRetrieveTableRsp):%" PRIu64, __func__, len,
×
982
           (uint64_t)(rspSize - sizeof(SRetrieveTableRsp)));
983
    code = TSDB_CODE_TSC_INVALID_INPUT;
×
UNCOV
984
    goto _exit;
×
985
  }
986

987
  return TSDB_CODE_SUCCESS;
240✔
988
_exit:
×
989
  if (*pRsp) {
×
990
    taosMemoryFree(*pRsp);
×
UNCOV
991
    *pRsp = NULL;
×
992
  }
993
  if (pBlock) {
×
994
    blockDataDestroy(pBlock);
×
UNCOV
995
    pBlock = NULL;
×
996
  }
UNCOV
997
  return code;
×
998
}
999

1000
static int32_t processScanDbRsp(void* param, SDataBuf* pMsg, int32_t code) {
360✔
1001
  SRequestObj* pRequest = param;
360✔
1002
  if (code != TSDB_CODE_SUCCESS) {
360✔
1003
    setErrno(pRequest, code);
120✔
1004
  } else {
1005
    SScanDbRsp         rsp = {0};
240✔
1006
    SRetrieveTableRsp* pRes = NULL;
240✔
1007
    code = tDeserializeSScanDbRsp(pMsg->pData, pMsg->len, &rsp);
240✔
1008
    if (TSDB_CODE_SUCCESS == code) {
240✔
1009
      code = buildRetriveTableRspForScanDb(&rsp, &pRes);
240✔
1010
    }
1011
    if (TSDB_CODE_SUCCESS == code) {
240✔
1012
      code = setQueryResultFromRsp(&pRequest->body.resInfo, pRes, false, pRequest->stmtBindVersion > 0);
240✔
1013
    }
1014

1015
    if (code != 0) {
240✔
1016
      pRequest->body.resInfo.pRspMsg = NULL;
×
UNCOV
1017
      taosMemoryFree(pRes);
×
1018
    }
1019
  }
1020

1021
  taosMemoryFree(pMsg->pData);
360✔
1022
  taosMemoryFree(pMsg->pEpSet);
360✔
1023

1024
  if (pRequest->body.queryFp != NULL) {
360✔
1025
    pRequest->body.queryFp(((SSyncQueryParam*)pRequest->body.interParam)->userParam, pRequest, code);
360✔
1026
  } else {
1027
    if (tsem_post(&pRequest->body.rspSem) != 0) {
×
UNCOV
1028
      tscError("failed to post semaphore");
×
1029
    }
1030
  }
1031
  return code;
360✔
1032
}
1033

1034
int32_t processTrimDbRsp(void* param, SDataBuf* pMsg, int32_t code) {
21,734✔
1035
  SRequestObj* pRequest = param;
21,734✔
1036
  if (code != TSDB_CODE_SUCCESS) {
21,734✔
1037
    setErrno(pRequest, code);
6,525✔
1038
  } else {
1039
    STrimDbRsp         rsp = {0};
15,209✔
1040
    SRetrieveTableRsp* pRes = NULL;
15,209✔
1041
    code = tDeserializeSCompactDbRsp(pMsg->pData, pMsg->len, (SCompactDbRsp*)&rsp);
15,209✔
1042
    if (TSDB_CODE_SUCCESS == code) {
15,209✔
1043
      code = buildRetriveTableRspForCompactDb(&rsp, &pRes);
15,209✔
1044
    }
1045
    if (TSDB_CODE_SUCCESS == code) {
15,209✔
1046
      code = setQueryResultFromRsp(&pRequest->body.resInfo, pRes, false, pRequest->stmtBindVersion > 0);
15,209✔
1047
    }
1048

1049
    if (code != 0) {
15,209✔
1050
      pRequest->body.resInfo.pRspMsg = NULL;
×
UNCOV
1051
      taosMemoryFree(pRes);
×
1052
    }
1053
  }
1054

1055
  taosMemoryFree(pMsg->pData);
21,734✔
1056
  taosMemoryFree(pMsg->pEpSet);
21,734✔
1057

1058
  if (pRequest->body.queryFp != NULL) {
21,734✔
1059
    pRequest->body.queryFp(((SSyncQueryParam*)pRequest->body.interParam)->userParam, pRequest, code);
21,734✔
1060
  } else {
1061
    if (tsem_post(&pRequest->body.rspSem) != 0) {
×
UNCOV
1062
      tscError("failed to post semaphore");
×
1063
    }
1064
  }
1065
  return code;
21,734✔
1066
}
1067

1068
static int32_t buildCreateTokenBlock(SCreateTokenRsp* pRsp, SSDataBlock** block) {
15✔
1069
  int32_t      code = 0;
15✔
1070
  int32_t      line = 0;
15✔
1071
  SSDataBlock* pBlock = taosMemoryCalloc(CREATE_USER_TOKEN_RESULT_COLS, sizeof(SSDataBlock));
15✔
1072
  TSDB_CHECK_NULL(pBlock, code, line, END, terrno);
15✔
1073
  pBlock->info.hasVarCol = true;
15✔
1074

1075
  pBlock->pDataBlock = taosArrayInit(1, sizeof(SColumnInfoData));
15✔
1076
  TSDB_CHECK_NULL(pBlock->pDataBlock, code, line, END, terrno);
15✔
1077
  SColumnInfoData infoData = {0};
15✔
1078
  infoData.info.type = TSDB_DATA_TYPE_VARCHAR;
15✔
1079
  infoData.info.bytes = CREATE_USER_TOKEN_RESULT_FIELD1_LEN;
15✔
1080
  TSDB_CHECK_NULL(taosArrayPush(pBlock->pDataBlock, &infoData), code, line, END, terrno);
30✔
1081

1082
  code = blockDataEnsureCapacity(pBlock, 1);
15✔
1083
  TSDB_CHECK_CODE(code, line, END);
15✔
1084

1085
  SColumnInfoData* pResultCol = taosArrayGet(pBlock->pDataBlock, 0);
15✔
1086
  TSDB_CHECK_NULL(pResultCol, code, line, END, terrno);
15✔
1087

1088
  char result[128 + 64] = {0};
15✔
1089
  STR_TO_VARSTR(result, pRsp->token);
15✔
1090
  code = colDataSetVal(pResultCol, 0, result, false);
15✔
1091
  TSDB_CHECK_CODE(code, line, END);
15✔
1092

1093
  pBlock->info.rows = 1;
15✔
1094

1095
  *block = pBlock;
15✔
1096
  return TSDB_CODE_SUCCESS;
15✔
1097

1098
END:
×
1099
  taosMemoryFree(pBlock);
×
1100
  taosArrayDestroy(pBlock->pDataBlock);
×
UNCOV
1101
  return code;
×
1102
}
1103

1104
static int32_t buildTableRspForCreateToken(SCreateTokenRsp* pResp, SRetrieveTableRsp** pRsp) {
15✔
1105
  SSDataBlock* pBlock = NULL;
15✔
1106
  int32_t      code = buildCreateTokenBlock(pResp, &pBlock);
15✔
1107
  if (code) {
15✔
UNCOV
1108
    return code;
×
1109
  }
1110

1111
  size_t dataEncodeBufSize = blockGetEncodeSize(pBlock);
15✔
1112
  size_t rspSize = sizeof(SRetrieveTableRsp) + dataEncodeBufSize + PAYLOAD_PREFIX_LEN;
15✔
1113
  *pRsp = taosMemoryCalloc(1, rspSize);
15✔
1114
  if (NULL == *pRsp) {
15✔
1115
    code = terrno;
×
UNCOV
1116
    goto _exit;
×
1117
  }
1118

1119
  (*pRsp)->useconds = 0;
15✔
1120
  (*pRsp)->completed = 1;
15✔
1121
  (*pRsp)->precision = 0;
15✔
1122
  (*pRsp)->compressed = 0;
15✔
1123

1124
  (*pRsp)->numOfRows = htobe64((int64_t)pBlock->info.rows);
15✔
1125
  (*pRsp)->numOfCols = htonl(CREATE_USER_TOKEN_RESULT_COLS);
15✔
1126

1127
  int32_t len =
1128
      blockEncode(pBlock, (*pRsp)->data + PAYLOAD_PREFIX_LEN, dataEncodeBufSize, CREATE_USER_TOKEN_RESULT_COLS);
15✔
1129
  if (len < 0) {
15✔
1130
    uError("buildTableRspFroCreateToken error, len:%d", len);
×
1131
    code = terrno;
×
UNCOV
1132
    goto _exit;
×
1133
  }
1134

1135
  blockDataDestroy(pBlock);
15✔
1136
  SET_PAYLOAD_LEN((*pRsp)->data, len, len);
15✔
1137

1138
  int32_t payloadLen = len + PAYLOAD_PREFIX_LEN;
15✔
1139
  (*pRsp)->payloadLen = htonl(payloadLen);
15✔
1140
  (*pRsp)->compLen = htonl(payloadLen);
15✔
1141

1142
  if (payloadLen != rspSize - sizeof(SRetrieveTableRsp)) {
15✔
UNCOV
1143
    uError("buildTableRspFroCreateToken error, len:%d != rspSize - sizeof(SRetrieveTableRsp):%" PRIu64, len,
×
1144
           (uint64_t)(rspSize - sizeof(SRetrieveTableRsp)));
1145
    code = TSDB_CODE_TSC_INVALID_INPUT;
×
UNCOV
1146
    goto _exit;
×
1147
  }
1148
  return TSDB_CODE_SUCCESS;
15✔
1149

1150
_exit:
×
1151
  if (*pRsp) {
×
1152
    taosMemoryFree(*pRsp);
×
UNCOV
1153
    *pRsp = NULL;
×
1154
  }
1155
  if (pBlock) {
×
1156
    blockDataDestroy(pBlock);
×
UNCOV
1157
    pBlock = NULL;
×
1158
  }
UNCOV
1159
  return code;
×
1160
}
1161

1162
int32_t processCreateTokenRsp(void* param, SDataBuf* pMsg, int32_t code) {
15✔
1163
  SRequestObj* pRequest = param;
15✔
1164
  if (code != TSDB_CODE_SUCCESS) {
15✔
UNCOV
1165
    setErrno(pRequest, code);
×
1166
  } else {
1167
    SCreateTokenRsp    rsp = {0};
15✔
1168
    SRetrieveTableRsp* pRes = NULL;
15✔
1169
    code = tDeserializeSCreateTokenResp(pMsg->pData, pMsg->len, &rsp);
15✔
1170
    if (TSDB_CODE_SUCCESS == code) {
15✔
1171
      code = buildTableRspForCreateToken(&rsp, &pRes);
15✔
1172
    }
1173
    if (TSDB_CODE_SUCCESS == code) {
15✔
1174
      code = setQueryResultFromRsp(&pRequest->body.resInfo, pRes, false, pRequest->stmtBindVersion > 0);
15✔
1175
    }
1176

1177
    if (code != 0) {
15✔
1178
      pRequest->body.resInfo.pRspMsg = NULL;
×
UNCOV
1179
      taosMemoryFree(pRes);
×
1180
    }
1181
  }
1182

1183
  taosMemoryFree(pMsg->pData);
15✔
1184
  taosMemoryFree(pMsg->pEpSet);
15✔
1185

1186
  if (pRequest->body.queryFp != NULL) {
15✔
1187
    pRequest->body.queryFp(((SSyncQueryParam*)pRequest->body.interParam)->userParam, pRequest, code);
15✔
1188
  } else if (tsem_post(&pRequest->body.rspSem) != 0) {
×
UNCOV
1189
    tscError("failed to post semaphore");
×
1190
  }
1191
  return code;
15✔
1192
}
1193

1194
__async_send_cb_fn_t getMsgRspHandle(int32_t msgType) {
16,188,718✔
1195
  switch (msgType) {
16,188,718✔
1196
    case TDMT_MND_CONNECT:
2,062,552✔
1197
      return processConnectRsp;
2,062,552✔
1198
    case TDMT_MND_CREATE_DB:
1,220,781✔
1199
      return processCreateDbRsp;
1,220,781✔
1200
    case TDMT_MND_USE_DB:
1,974,772✔
1201
      return processUseDbRsp;
1,974,772✔
1202
    case TDMT_MND_CREATE_STB:
1,621,858✔
1203
      return processCreateSTableRsp;
1,621,858✔
1204
    case TDMT_MND_DROP_DB:
1,050,096✔
1205
      return processDropDbRsp;
1,050,096✔
1206
    case TDMT_MND_ALTER_STB:
5,268,042✔
1207
      return processAlterStbRsp;
5,268,042✔
1208
    case TDMT_MND_SHOW_VARIABLES:
8,621✔
1209
      return processShowVariablesRsp;
8,621✔
1210
    case TDMT_MND_COMPACT_DB:
29,706✔
1211
      return processCompactDbRsp;
29,706✔
1212
    case TDMT_MND_TRIM_DB:
21,734✔
1213
      return processTrimDbRsp;
21,734✔
1214
    case TDMT_MND_SCAN_DB:
360✔
1215
      return processScanDbRsp;
360✔
1216
    case TDMT_MND_CREATE_TOKEN:
15✔
1217
      return processCreateTokenRsp;
15✔
1218

1219
    default:
2,930,181✔
1220
      return genericRspCallback;
2,930,181✔
1221
  }
1222
}
1223

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc