TDengine/source/dnode/mnode/impl/test/xnode/xnodeSimpleTest.cpp
guichuan zhang 2c62466aa0
feat(taosx): support distributed taosx (#34126)
* feat: add xnode syntax

* refactor(xnode): reduce function complexity

* chore: add lost xnode.h file

* feat(xnode): create xnode task

* chore: fix double free error

* add xnoded

* start xnoded as subprocess

* complete xnode task feature

* complete show xnode jobs feature

* complete with option feature

* complete alter xnode job feature

* complete alter xnode task feature

* complete user pass feature

* clean code

* modify status type as char

* fix leader ep null

* fix start task req null

* fix pass id for status

* support timeout msg

* drop xnode task relative jobs

* clean code

* wip

* chore: add test cases for xnode

* chore: fix 3.0 merge changes

* fix drain core dump and create task core dump

* add password check

* retrieve xnode status from xnoded

* pass integer as double to cjson

* add some debug log

* add some job log

* fix start task lock

* do not handle http response

* fix coredump drop xnode task by name

* support start/stop/drop task by name

* remove mock xnoded

* support unix socket

* kill pre-xnoded before start

* support dnode close xnoded

* test(xnode): add unit test cases for xnode

* rebalance support where clause

* fix some test issue

* unformat http post content json string

* add xnode zh doc

* modify drain description

* remove job create/stop/drop operation

* support rebalance all without where condition

* support alter task by name

* add NULL param for mndCheckOperPrivilege

* add xnode txnode module for libmnode.a

* code clean

* change parser len to 4096

* clean code

* chore: try to fix gtest/gtest.h not found

* chore: fix markdown files

* chore: fix markdown in zh

* chore: fix enum issue and add ci

* chore: fix test case problem

* chore: fix pKeyVal overflow

* chore: rename to 排空节点

* chore: external cmake remove parallel

* chore: add DEP_ext_gtest for xnode test

* chore: fix gtest errors

* chore: remove gtest pthread lib

* chore: fix data type not match

* chore: fix some lint errors

* chore: fix void unlink

* chore: fix return with null pointer check

* chore: fix pointer double free and xnodeMemoryTest strncpy null

* chore: fix xnode encode action invalid datelen

* chore: remove TD_LINUX condition

* chore: use PRIu64 denote long long

* chore: fix task parser NULL and allow no with clause

* fix(xnode): fix windows build error

* chore: fix windows curl error

* chore: fix test case ins_tables relative error

* chore: fix memory leak

* docs: update taosx docs

* chore: update taosx docs

* chore: add role priviledge table

* chore: fix error code doc

* chore: fix test_xnode.py

* chore: fix doc typo

* fix: ci error while run test_user_privilege_sysinfo.py

---------

Co-authored-by: Linhe Huo <linhehuo@gmail.com>
Co-authored-by: huohong <sallyhuo@taosdata.com>
Co-authored-by: Simon Guan <guanshengliang@qq.com>
2026-01-01 14:51:03 +08:00

306 lines
7.9 KiB
C++

/**
* @file xnodeSimpleTest.cpp
* @brief Simplified XNode encode/decode test without complex dependencies
* @version 1.0
* @date 2025-12-25
*/
#include <gtest/gtest.h>
#include <cstdlib>
#include <cstring>
// Minimal mock for SDB functions
typedef struct SSdbRaw {
int8_t sver;
int32_t dataLen;
char data[4096];
} SSdbRaw;
typedef struct SSdbRow {
char data[1024];
} SSdbRow;
// Mock SDB functions
SSdbRaw* sdbAllocRaw(int type, int version, int dataLen) {
SSdbRaw* pRaw = (SSdbRaw*)malloc(sizeof(SSdbRaw));
memset(pRaw, 0, sizeof(SSdbRaw));
pRaw->sver = version;
return pRaw;
}
void sdbFreeRaw(SSdbRaw* pRaw) {
if (pRaw) free(pRaw);
}
SSdbRow* sdbAllocRow(int size) {
SSdbRow* pRow = (SSdbRow*)malloc(sizeof(SSdbRow));
memset(pRow, 0, sizeof(SSdbRow));
return pRow;
}
void* sdbGetRowObj(SSdbRow* pRow) { return pRow ? pRow->data : nullptr; }
int sdbSetRawInt32(SSdbRaw* pRaw, int pos, int32_t val) {
if (pos + 4 <= 4096) {
memcpy(pRaw->data + pos, &val, 4);
return 0;
}
return -1;
}
int sdbSetRawInt64(SSdbRaw* pRaw, int pos, int64_t val) {
if (pos + 8 <= 4096) {
memcpy(pRaw->data + pos, &val, 8);
return 0;
}
return -1;
}
int sdbSetRawBinary(SSdbRaw* pRaw, int pos, const void* data, int len) {
if (pos + len <= 4096) {
memcpy(pRaw->data + pos, data, len);
return 0;
}
return -1;
}
int sdbSetRawDataLen(SSdbRaw* pRaw, int len) {
pRaw->dataLen = len;
return 0;
}
int sdbGetRawSoftVer(SSdbRaw* pRaw, int8_t* ver) {
*ver = pRaw->sver;
return 0;
}
int sdbGetRawInt32(SSdbRaw* pRaw, int pos, int32_t* val) {
if (pos + 4 <= pRaw->dataLen) {
memcpy(val, pRaw->data + pos, 4);
return 0;
}
return -1;
}
int sdbGetRawInt64(SSdbRaw* pRaw, int pos, int64_t* val) {
if (pos + 8 <= pRaw->dataLen) {
memcpy(val, pRaw->data + pos, 8);
return 0;
}
return -1;
}
int sdbGetRawBinary(SSdbRaw* pRaw, int pos, void* data, int len) {
if (pos + len <= pRaw->dataLen) {
memcpy(data, pRaw->data + pos, len);
return 0;
}
return -1;
}
// Test structure
typedef struct SXnodeObj {
int32_t id;
int32_t urlLen;
char* url;
int32_t statusLen;
char* status;
int64_t createTime;
int64_t updateTime;
} SXnodeObj;
class XnodeSimpleTest : public ::testing::Test {
protected:
void SetUp() override {}
void TearDown() override {}
};
TEST_F(XnodeSimpleTest, BasicEncodeDecodeTest) {
// Create test object
SXnodeObj obj = {0};
obj.id = 1;
obj.urlLen = 12;
obj.url = (char*)malloc(obj.urlLen);
strcpy(obj.url, "node1:6050");
obj.statusLen = 7;
obj.status = (char*)malloc(obj.statusLen);
strcpy(obj.status, "online");
obj.createTime = 1234567890;
obj.updateTime = 1234567900;
// Encode
SSdbRaw* pRaw = sdbAllocRaw(1, 1, 256);
ASSERT_NE(pRaw, nullptr);
int32_t dataPos = 0;
EXPECT_EQ(sdbSetRawInt32(pRaw, dataPos, obj.id), 0);
dataPos += 4;
EXPECT_EQ(sdbSetRawInt32(pRaw, dataPos, obj.urlLen), 0);
dataPos += 4;
EXPECT_EQ(sdbSetRawBinary(pRaw, dataPos, obj.url, obj.urlLen), 0);
dataPos += obj.urlLen;
EXPECT_EQ(sdbSetRawInt32(pRaw, dataPos, obj.statusLen), 0);
dataPos += 4;
EXPECT_EQ(sdbSetRawBinary(pRaw, dataPos, obj.status, obj.statusLen), 0);
dataPos += obj.statusLen;
EXPECT_EQ(sdbSetRawInt64(pRaw, dataPos, obj.createTime), 0);
dataPos += 8;
EXPECT_EQ(sdbSetRawInt64(pRaw, dataPos, obj.updateTime), 0);
dataPos += 8;
EXPECT_EQ(sdbSetRawDataLen(pRaw, dataPos), 0);
// Decode
int8_t sver = 0;
EXPECT_EQ(sdbGetRawSoftVer(pRaw, &sver), 0);
EXPECT_EQ(sver, 1);
SSdbRow* pRow = sdbAllocRow(sizeof(SXnodeObj));
ASSERT_NE(pRow, nullptr);
SXnodeObj* pDecoded = (SXnodeObj*)sdbGetRowObj(pRow);
ASSERT_NE(pDecoded, nullptr);
memset(pDecoded, 0, sizeof(SXnodeObj));
dataPos = 0;
EXPECT_EQ(sdbGetRawInt32(pRaw, dataPos, &pDecoded->id), 0);
dataPos += 4;
EXPECT_EQ(sdbGetRawInt32(pRaw, dataPos, &pDecoded->urlLen), 0);
dataPos += 4;
pDecoded->url = (char*)malloc(pDecoded->urlLen);
EXPECT_EQ(sdbGetRawBinary(pRaw, dataPos, pDecoded->url, pDecoded->urlLen), 0);
dataPos += pDecoded->urlLen;
EXPECT_EQ(sdbGetRawInt32(pRaw, dataPos, &pDecoded->statusLen), 0);
dataPos += 4;
pDecoded->status = (char*)malloc(pDecoded->statusLen);
EXPECT_EQ(sdbGetRawBinary(pRaw, dataPos, pDecoded->status, pDecoded->statusLen), 0);
dataPos += pDecoded->statusLen;
EXPECT_EQ(sdbGetRawInt64(pRaw, dataPos, &pDecoded->createTime), 0);
dataPos += 8;
EXPECT_EQ(sdbGetRawInt64(pRaw, dataPos, &pDecoded->updateTime), 0);
// Verify
EXPECT_EQ(obj.id, pDecoded->id);
EXPECT_EQ(obj.urlLen, pDecoded->urlLen);
EXPECT_EQ(obj.statusLen, pDecoded->statusLen);
EXPECT_STREQ(obj.url, pDecoded->url);
EXPECT_STREQ(obj.status, pDecoded->status);
EXPECT_EQ(obj.createTime, pDecoded->createTime);
EXPECT_EQ(obj.updateTime, pDecoded->updateTime);
// Cleanup
free(obj.url);
free(obj.status);
free(pDecoded->url);
free(pDecoded->status);
free(pRow);
sdbFreeRaw(pRaw);
}
TEST_F(XnodeSimpleTest, EmptyFieldsTest) {
SXnodeObj obj = {0};
obj.id = 2;
obj.urlLen = 0;
obj.url = nullptr;
obj.statusLen = 0;
obj.status = nullptr;
obj.createTime = 9876543210;
obj.updateTime = 9876543220;
SSdbRaw* pRaw = sdbAllocRaw(1, 1, 128);
ASSERT_NE(pRaw, nullptr);
int32_t dataPos = 0;
sdbSetRawInt32(pRaw, dataPos, obj.id);
dataPos += 4;
sdbSetRawInt32(pRaw, dataPos, obj.urlLen);
dataPos += 4;
sdbSetRawInt32(pRaw, dataPos, obj.statusLen);
dataPos += 4;
sdbSetRawInt64(pRaw, dataPos, obj.createTime);
dataPos += 8;
sdbSetRawInt64(pRaw, dataPos, obj.updateTime);
dataPos += 8;
sdbSetRawDataLen(pRaw, dataPos);
// Decode
SSdbRow* pRow = sdbAllocRow(sizeof(SXnodeObj));
SXnodeObj* pDecoded = (SXnodeObj*)sdbGetRowObj(pRow);
memset(pDecoded, 0, sizeof(SXnodeObj));
dataPos = 0;
sdbGetRawInt32(pRaw, dataPos, &pDecoded->id);
dataPos += 4;
sdbGetRawInt32(pRaw, dataPos, &pDecoded->urlLen);
dataPos += 4;
sdbGetRawInt32(pRaw, dataPos, &pDecoded->statusLen);
dataPos += 4;
sdbGetRawInt64(pRaw, dataPos, &pDecoded->createTime);
dataPos += 8;
sdbGetRawInt64(pRaw, dataPos, &pDecoded->updateTime);
// Verify
EXPECT_EQ(obj.id, pDecoded->id);
EXPECT_EQ(0, pDecoded->urlLen);
EXPECT_EQ(0, pDecoded->statusLen);
EXPECT_EQ(obj.createTime, pDecoded->createTime);
EXPECT_EQ(obj.updateTime, pDecoded->updateTime);
free(pRow);
sdbFreeRaw(pRaw);
}
TEST_F(XnodeSimpleTest, MultipleObjectsTest) {
for (int i = 0; i < 10; i++) {
SXnodeObj obj = {0};
obj.id = i;
obj.urlLen = 15;
obj.url = (char*)malloc(obj.urlLen);
snprintf(obj.url, obj.urlLen, "node%d:6050", i);
obj.createTime = 1000000 + i;
obj.updateTime = 2000000 + i;
SSdbRaw* pRaw = sdbAllocRaw(1, 1, 256);
int32_t dataPos = 0;
sdbSetRawInt32(pRaw, dataPos, obj.id);
dataPos += 4;
sdbSetRawInt32(pRaw, dataPos, obj.urlLen);
dataPos += 4;
sdbSetRawBinary(pRaw, dataPos, obj.url, obj.urlLen);
dataPos += obj.urlLen;
sdbSetRawInt64(pRaw, dataPos, obj.createTime);
dataPos += 8;
sdbSetRawInt64(pRaw, dataPos, obj.updateTime);
dataPos += 8;
sdbSetRawDataLen(pRaw, dataPos);
// Decode and verify
SSdbRow* pRow = sdbAllocRow(sizeof(SXnodeObj));
SXnodeObj* pDecoded = (SXnodeObj*)sdbGetRowObj(pRow);
memset(pDecoded, 0, sizeof(SXnodeObj));
dataPos = 0;
sdbGetRawInt32(pRaw, dataPos, &pDecoded->id);
dataPos += 4;
sdbGetRawInt32(pRaw, dataPos, &pDecoded->urlLen);
dataPos += 4;
pDecoded->url = (char*)malloc(pDecoded->urlLen);
sdbGetRawBinary(pRaw, dataPos, pDecoded->url, pDecoded->urlLen);
dataPos += pDecoded->urlLen;
sdbGetRawInt64(pRaw, dataPos, &pDecoded->createTime);
dataPos += 8;
sdbGetRawInt64(pRaw, dataPos, &pDecoded->updateTime);
EXPECT_EQ(i, pDecoded->id);
EXPECT_EQ(obj.createTime, pDecoded->createTime);
EXPECT_EQ(obj.updateTime, pDecoded->updateTime);
free(obj.url);
free(pDecoded->url);
free(pRow);
sdbFreeRaw(pRaw);
}
}