TDengine/source/os/test/osTests.cpp

856 lines
25 KiB
C++
Raw Permalink Normal View History

/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <gtest/gtest.h>
2023-11-21 08:31:31 +00:00
#include <inttypes.h>
2025-02-24 02:59:49 +00:00
#include <iostream>
2026-03-17 07:52:05 +00:00
#include <cstring>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wwrite-strings"
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wsign-compare"
#pragma GCC diagnostic ignored "-Wsign-compare"
#pragma GCC diagnostic ignored "-Wformat"
#pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
#pragma GCC diagnostic ignored "-Wpointer-arith"
#include "os.h"
#include "tlog.h"
2023-11-21 08:31:31 +00:00
#ifdef WINDOWS
#include <windows.h>
#else
#include <arpa/inet.h>
2025-02-24 02:59:49 +00:00
TEST(osTest, locale) {
char *ret = taosCharsetReplace(NULL);
EXPECT_EQ(ret, nullptr);
ret = taosCharsetReplace("utf8");
EXPECT_NE(ret, nullptr);
ret = taosCharsetReplace("utf-8");
EXPECT_NE(ret, nullptr);
taosGetSystemLocale(NULL, "");
taosGetSystemLocale("", NULL);
}
TEST(osTest, memory) {
2026-03-17 07:52:05 +00:00
// Test taosMemoryDbgInit
int32_t ret = taosMemoryDbgInit();
#if defined(LINUX) && !defined(_ALPINE) && !defined(TD_ASTRA)
2025-02-24 02:59:49 +00:00
EXPECT_EQ(ret, 0);
2026-03-17 07:52:05 +00:00
#else
EXPECT_NE(ret, 0);
#endif
2025-02-24 02:59:49 +00:00
2026-03-17 07:52:05 +00:00
// Test taosMemoryDbgInitRestore
ret = taosMemoryDbgInitRestore();
#if defined(LINUX) && !defined(_ALPINE) && !defined(TD_ASTRA)
EXPECT_EQ(ret, 0);
#else
EXPECT_NE(ret, 0);
#endif
// Test taosMemSize with NULL
2025-02-24 02:59:49 +00:00
int64_t ret64 = taosMemSize(NULL);
EXPECT_EQ(ret64, 0);
2026-03-17 07:52:05 +00:00
// Test basic memory allocation and free
void *ptr1 = taosMemMalloc(1024);
ASSERT_NE(ptr1, nullptr);
ret64 = taosMemSize(ptr1);
#if defined(WINDOWS) || defined(_TD_DARWIN_64) || !defined(TD_ASTRA)
EXPECT_GT(ret64, 0);
#endif
taosMemFree(ptr1);
// Test taosMemCalloc
void *ptr2 = taosMemCalloc(10, 100);
ASSERT_NE(ptr2, nullptr);
taosMemFree(ptr2);
// Test taosMemRealloc
void *ptr3 = taosMemMalloc(512);
ASSERT_NE(ptr3, nullptr);
void *ptr4 = taosMemRealloc(ptr3, 1024);
ASSERT_NE(ptr4, nullptr);
taosMemFree(ptr4);
// Test taosMemRealloc with NULL (should behave like malloc)
void *ptr5 = taosMemRealloc(NULL, 256);
ASSERT_NE(ptr5, nullptr);
taosMemFree(ptr5);
// Test taosStrdupi
const char *testStr = "Hello TDengine";
char *ptr6 = (char*)taosMemMalloc(strlen(testStr) + 1);
ASSERT_NE(ptr6, nullptr);
strcpy(ptr6, testStr);
char *dupStr = taosStrdupi(ptr6);
ASSERT_NE(dupStr, nullptr);
EXPECT_STREQ(dupStr, testStr);
taosMemFree(dupStr);
taosMemFree(ptr6);
// Test taosMemTrim with NULL trimed parameter
ret = taosMemTrim(0, NULL);
EXPECT_EQ(ret, TSDB_CODE_SUCCESS);
// Test taosMemTrim with trimed parameter
bool trimed = false;
ret = taosMemTrim(0, &trimed);
EXPECT_EQ(ret, TSDB_CODE_SUCCESS);
// Test taosMemMallocAlign
#if defined(LINUX) && !defined(USE_TD_MEMORY)
void *alignedPtr = taosMemMallocAlign(16, 1024);
ASSERT_NE(alignedPtr, nullptr);
// Check alignment
EXPECT_EQ((uintptr_t)alignedPtr % 16, 0);
taosMemFree(alignedPtr);
// Test large alignment
void *alignedPtr2 = taosMemMallocAlign(256, 2048);
ASSERT_NE(alignedPtr2, nullptr);
EXPECT_EQ((uintptr_t)alignedPtr2 % 256, 0);
taosMemFree(alignedPtr2);
#else
// On non-Linux or USE_TD_MEMORY, should return NULL or fallback to malloc
void *alignedPtr3 = taosMemMallocAlign(16, 1024);
#ifdef USE_TD_MEMORY
EXPECT_EQ(alignedPtr3, nullptr);
#else
if (alignedPtr3 != nullptr) {
taosMemFree(alignedPtr3);
}
#endif
#endif
// Test edge cases
void *zero_alloc = taosMemMalloc(0);
if (zero_alloc != nullptr) {
taosMemFree(zero_alloc);
}
void *zero_calloc = taosMemCalloc(0, 100);
if (zero_calloc != nullptr) {
taosMemFree(zero_calloc);
}
void *zero_calloc2 = taosMemCalloc(100, 0);
if (zero_calloc2 != nullptr) {
taosMemFree(zero_calloc2);
}
// Test free NULL (should not crash)
taosMemFree(NULL);
2025-02-24 02:59:49 +00:00
}
2026-03-17 07:52:05 +00:00
TEST(osTest, rand) {
// Test taosSeedRand and taosRand
taosSeedRand(12345);
uint32_t r1 = taosRand();
EXPECT_GT(r1, 0);
taosSeedRand(12345);
uint32_t r2 = taosRand();
EXPECT_EQ(r1, r2); // Same seed should produce same result
// Test taosRandR (thread-safe random)
uint32_t seed = 54321;
uint32_t r3 = taosRandR(&seed);
EXPECT_GT(r3, 0);
uint32_t seed2 = 54321;
uint32_t r4 = taosRandR(&seed2);
EXPECT_EQ(r3, r4); // Same seed should produce same result
// Test taosSafeRand
uint32_t safeRand1 = taosSafeRand();
uint32_t safeRand2 = taosSafeRand();
// Safe random should produce different values (with high probability)
// We just check they are valid
EXPECT_GE(safeRand1, 0);
EXPECT_GE(safeRand2, 0);
// Test taosSafeRandBytes
uint8_t bytes[32] = {0};
taosSafeRandBytes(bytes, 32);
// Check that at least some bytes are non-zero (with very high probability)
bool hasNonZero = false;
for (int i = 0; i < 32; i++) {
if (bytes[i] != 0) {
hasNonZero = true;
break;
}
}
EXPECT_TRUE(hasNonZero);
// Test with different sizes
uint8_t bytes2[1] = {0};
taosSafeRandBytes(bytes2, 1);
uint8_t bytes3[128] = {0};
taosSafeRandBytes(bytes3, 128);
// Test taosRandStr
char str1[64] = {0};
taosRandStr(str1, 63);
EXPECT_EQ(strlen(str1), 63);
// Verify characters are from the expected set
const char* validChars = "abcdefghijklmnopqrstuvwxyz0123456789-_.";
for (size_t i = 0; i < strlen(str1); i++) {
EXPECT_NE(strchr(validChars, str1[i]), nullptr);
}
// Test with different sizes
char str2[10] = {0};
taosRandStr(str2, 5);
EXPECT_EQ(strlen(str2), 5);
// Test taosRandStr2
char str3[128] = {0};
taosRandStr2(str3, 100);
EXPECT_EQ(strlen(str3), 100);
// Verify characters are from the expected set
const char* validChars2 = "abcdefghijklmnopqrstuvwxyz0123456789@";
for (size_t i = 0; i < strlen(str3); i++) {
EXPECT_NE(strchr(validChars2, str3[i]), nullptr);
}
// Test with different sizes
char str4[20] = {0};
taosRandStr2(str4, 10);
EXPECT_EQ(strlen(str4), 10);
// Test edge case: size 1
char str5[2] = {0};
taosRandStr2(str5, 1);
EXPECT_EQ(strlen(str5), 1);
2025-02-24 02:59:49 +00:00
}
TEST(osTest, socket2) {
int32_t ret32 = taosCloseSocket(NULL);
EXPECT_NE(ret32, 0);
ret32 = taosSetSockOpt(NULL, 0, 0, NULL, 0);
EXPECT_NE(ret32, 0);
#if defined(LINUX)
struct in_addr ipInt;
ipInt.s_addr = htonl(0x7F000001);
char buf[128] = {0};
taosInetNtop(ipInt, buf, 32);
#endif
ret32 = taosGetIpv4FromFqdn("localhost", NULL);
EXPECT_NE(ret32, 0);
uint32_t ip = 0;
ret32 = taosGetIpv4FromFqdn(NULL, &ip);
EXPECT_NE(ret32, 0);
taosInetNtoa(NULL, ip);
ret32 = taosInetAddr(NULL);
EXPECT_EQ(ret32, 0);
ret32 = taosWinSocketInit();
EXPECT_EQ(ret32, 0);
}
TEST(osTest, time2) {
int32_t code = 0;
taosGetLocalTimezoneOffset(&code);
2025-02-24 02:59:49 +00:00
char buf[12] = {0};
char fmt[12] = {0};
void *retptr = taosStrpTime(NULL, fmt, NULL);
EXPECT_EQ(retptr, nullptr);
retptr = taosStrpTime(buf, NULL, NULL);
EXPECT_EQ(retptr, nullptr);
size_t ret = taosStrfTime(NULL, 0, fmt, NULL);
EXPECT_EQ(ret, 0);
ret = taosStrfTime(buf, 0, NULL, NULL);
EXPECT_EQ(ret, 0);
time_t tp = {0};
struct tm *retptr2 = taosGmTimeR(&tp, NULL);
EXPECT_EQ(retptr2, nullptr);
retptr2 = taosGmTimeR(NULL, NULL);
EXPECT_EQ(retptr2, nullptr);
time_t rett = taosTimeGm(NULL);
EXPECT_EQ(rett, -1);
timezone_t tz = {0};
retptr2 = taosLocalTime(&tp, NULL, NULL, 0, tz);
EXPECT_EQ(retptr2, nullptr);
retptr2 = taosLocalTime(NULL, NULL, NULL, 0, tz);
EXPECT_EQ(retptr2, nullptr);
}
TEST(osTest, system) {
#if defined(LINUX)
taosSetConsoleEcho(false);
taosSetConsoleEcho(true);
taosGetOldTerminalMode();
taosCloseCmd(NULL);
TdCmdPtr ptr = taosOpenCmd(NULL);
EXPECT_EQ(ptr, nullptr);
taosCloseCmd(&ptr);
2026-03-17 05:49:08 +00:00
// ptr = taosOpenCmd("echo 'hello world'");
// ASSERT_NE(ptr, nullptr);
// char buf[256] = {0};
// int64_t ret64 = taosGetsCmd(NULL, 0, NULL);
// EXPECT_LE(ret64, 0);
// ret64 = taosGetsCmd(ptr, 0, NULL);
// EXPECT_LE(ret64, 0);
// ret64 = taosGetsCmd(ptr, 255, buf);
// EXPECT_GT(ret64, 0);
// taosCloseCmd(&ptr);
// ptr = taosOpenCmd("echoxxx 'hello world'");
// ASSERT_NE(ptr, nullptr);
// ret64 = taosGetsCmd(ptr, 255, buf);
// EXPECT_LE(ret64, 0);
// taosCloseCmd(&ptr);
// ret64 = taosGetLineCmd(NULL, NULL);
// EXPECT_LE(ret64, 0);
// ret64 = taosGetLineCmd(ptr, NULL);
// EXPECT_LE(ret64, 0);
// ptr = taosOpenCmd("echo 'hello world'");
// ASSERT_NE(ptr, nullptr);
// char *ptrBuf = NULL;
// ret64 = taosGetLineCmd(ptr, &ptrBuf);
// EXPECT_GE(ret64, 0);
// taosCloseCmd(&ptr);
// ptr = taosOpenCmd("echoxxx 'hello world'");
// ASSERT_NE(ptr, nullptr);
// ret64 = taosGetLineCmd(ptr, &ptrBuf);
// EXPECT_LE(ret64, 0);
// taosCloseCmd(&ptr);
// int32_t ret32 = taosEOFCmd(NULL);
// EXPECT_EQ(ret32, 0);
2025-02-24 02:59:49 +00:00
#endif
}
TEST(osTest, sysinfo) {
#if defined(LINUX)
int32_t ret32 = 0;
ret32 = taosGetEmail(NULL, 0);
EXPECT_NE(ret32, 0);
ret32 = taosGetOsReleaseName(NULL, NULL, NULL, 0);
EXPECT_NE(ret32, 0);
char buf[128] = {0};
float numOfCores = 0;
ret32 = taosGetCpuInfo(buf, 0, NULL);
EXPECT_NE(ret32, 0);
ret32 = taosGetCpuInfo(NULL, 0, &numOfCores);
EXPECT_NE(ret32, 0);
ret32 = taosGetCpuCores(NULL, false);
EXPECT_NE(ret32, 0);
ret32 = taosGetTotalMemory(NULL);
EXPECT_NE(ret32, 0);
ret32 = taosGetProcMemory(NULL);
EXPECT_NE(ret32, 0);
ret32 = taosGetSysMemory(NULL, NULL, NULL);
2025-02-24 02:59:49 +00:00
EXPECT_NE(ret32, 0);
ret32 = taosGetDiskSize(buf, NULL);
EXPECT_NE(ret32, 0);
SDiskSize disksize = {0};
ret32 = taosGetDiskSize(NULL, &disksize);
EXPECT_NE(ret32, 0);
int64_t tmp = 0;
ret32 = taosGetProcIO(NULL, NULL, NULL, NULL);
EXPECT_NE(ret32, 0);
ret32 = taosGetProcIO(&tmp, NULL, NULL, NULL);
EXPECT_NE(ret32, 0);
ret32 = taosGetProcIO(&tmp, &tmp, NULL, NULL);
EXPECT_NE(ret32, 0);
ret32 = taosGetProcIO(&tmp, &tmp, &tmp, NULL);
EXPECT_NE(ret32, 0);
ret32 = taosGetProcIODelta(NULL, NULL, NULL, NULL);
EXPECT_NE(ret32, 0);
ret32 = taosGetProcIODelta(&tmp, NULL, NULL, NULL);
EXPECT_NE(ret32, 0);
ret32 = taosGetProcIODelta(&tmp, &tmp, NULL, NULL);
EXPECT_NE(ret32, 0);
ret32 = taosGetProcIODelta(&tmp, &tmp, &tmp, NULL);
EXPECT_NE(ret32, 0);
taosGetProcIODelta(NULL, NULL, NULL, NULL);
taosGetProcIODelta(&tmp, &tmp, &tmp, &tmp);
ret32 = taosGetCardInfo(NULL, NULL);
EXPECT_NE(ret32, 0);
ret32 = taosGetCardInfo(&tmp, NULL);
EXPECT_NE(ret32, 0);
ret32 = taosGetCardInfoDelta(NULL, NULL);
EXPECT_NE(ret32, 0);
ret32 = taosGetCardInfoDelta(&tmp, NULL);
EXPECT_NE(ret32, 0);
taosGetCardInfoDelta(NULL, NULL);
taosGetCardInfoDelta(&tmp, &tmp);
ret32 = taosGetSystemUUIDLimit36(NULL, 0);
EXPECT_NE(ret32, 0);
ret32 = taosGetSystemUUIDLen(NULL, 0);
EXPECT_NE(ret32, 0);
ret32 = taosGetSystemUUIDLen(buf, -1);
EXPECT_NE(ret32, 0);
taosSetCoreDump(false);
ret32 = taosGetlocalhostname(NULL, 0);
EXPECT_NE(ret32, 0);
#endif
}
TEST(osTest, osFQDNSuccess) {
2024-10-09 02:29:47 +00:00
char fqdn[TD_FQDN_LEN];
char ipString[INET_ADDRSTRLEN];
int code = taosGetFqdn(fqdn);
2024-07-24 08:37:54 +00:00
uint32_t ipv4 = 0;
code = taosGetIpv4FromFqdn(fqdn, &ipv4);
ASSERT_NE(ipv4, 0xffffffff);
struct in_addr addr;
addr.s_addr = htonl(ipv4);
2024-07-26 09:38:02 +00:00
(void)snprintf(ipString, INET_ADDRSTRLEN, "%u.%u.%u.%u", (unsigned int)(addr.s_addr >> 24) & 0xFF,
2025-02-24 02:59:49 +00:00
(unsigned int)(addr.s_addr >> 16) & 0xFF, (unsigned int)(addr.s_addr >> 8) & 0xFF,
(unsigned int)(addr.s_addr) & 0xFF);
2024-07-26 09:38:02 +00:00
(void)printf("fqdn:%s ip:%s\n", fqdn, ipString);
}
TEST(osTest, osFQDNFailed) {
char fqdn[1024] = "fqdn_test_not_found";
char ipString[24];
2024-07-24 08:37:54 +00:00
uint32_t ipv4 = 0;
2025-02-24 02:59:49 +00:00
int32_t code = taosGetIpv4FromFqdn(fqdn, &ipv4);
2024-07-24 10:48:18 +00:00
ASSERT_NE(code, 0);
terrno = TSDB_CODE_RPC_FQDN_ERROR;
2024-07-26 09:38:02 +00:00
(void)printf("fqdn:%s transfer to ip failed!\n", fqdn);
}
2023-11-21 08:31:31 +00:00
#endif // WINDOWS
TEST(osTest, osSystem) {
const char *flags = "UTL FATAL ";
ELogLevel level = DEBUG_FATAL;
int32_t dflag = 255; // tsLogEmbedded ? 255 : uDebugFlag
2023-01-04 08:07:30 +00:00
taosPrintTrace(flags, level, dflag, 0);
const int sysLen = 64;
char osSysName[sysLen];
2023-07-14 05:27:19 +00:00
int ret = taosGetOsReleaseName(osSysName, NULL, NULL, sysLen);
2024-07-26 09:38:02 +00:00
(void)printf("os system name:%s\n", osSysName);
ASSERT_EQ(ret, 0);
}
void fileOperateOnFree(void *param) {
2025-02-24 02:59:49 +00:00
char *fname = (char *)param;
TdFilePtr pFile = taosOpenFile(fname, TD_FILE_CREATE | TD_FILE_WRITE);
2024-07-26 09:38:02 +00:00
(void)printf("On free thread open file\n");
ASSERT_NE(pFile, nullptr);
int ret = taosLockFile(pFile);
2024-07-26 09:38:02 +00:00
(void)printf("On free thread lock file ret:%d\n", ret);
ASSERT_EQ(ret, 0);
ret = taosUnLockFile(pFile);
2024-07-26 09:38:02 +00:00
(void)printf("On free thread unlock file ret:%d\n", ret);
ASSERT_EQ(ret, 0);
ret = taosCloseFile(&pFile);
ASSERT_EQ(ret, 0);
2024-07-26 09:38:02 +00:00
(void)printf("On free thread close file ret:%d\n", ret);
}
void *fileOperateOnFreeThread(void *param) {
fileOperateOnFree(param);
return NULL;
}
void fileOperateOnBusy(void *param) {
2025-02-24 02:59:49 +00:00
char *fname = (char *)param;
TdFilePtr pFile = taosOpenFile(fname, TD_FILE_CREATE | TD_FILE_WRITE);
2024-07-26 09:38:02 +00:00
(void)printf("On busy thread open file\n");
2023-11-21 08:31:31 +00:00
if (pFile == NULL) return;
// ASSERT_NE(pFile, nullptr);
int ret = taosLockFile(pFile);
2024-07-26 09:38:02 +00:00
(void)printf("On busy thread lock file ret:%d\n", ret);
ASSERT_NE(ret, 0);
ret = taosUnLockFile(pFile);
2024-07-26 09:38:02 +00:00
(void)printf("On busy thread unlock file ret:%d\n", ret);
ret = taosCloseFile(&pFile);
2024-07-26 09:38:02 +00:00
(void)printf("On busy thread close file ret:%d\n", ret);
ASSERT_EQ(ret, 0);
}
void *fileOperateOnBusyThread(void *param) {
fileOperateOnBusy(param);
return NULL;
}
TEST(osTest, osFile) {
char *fname = "./osfiletest1.txt";
TdFilePtr pOutFD = taosCreateFile(fname, TD_FILE_WRITE | TD_FILE_CREATE | TD_FILE_TRUNC);
ASSERT_NE(pOutFD, nullptr);
2024-07-26 09:38:02 +00:00
(void)printf("create file success\n");
(void)taosCloseFile(&pOutFD);
2024-07-26 09:38:02 +00:00
(void)taosCloseFile(&pOutFD);
TdFilePtr pFile = taosOpenFile(fname, TD_FILE_CREATE | TD_FILE_WRITE);
2024-07-26 09:38:02 +00:00
(void)printf("open file\n");
ASSERT_NE(pFile, nullptr);
int ret = taosLockFile(pFile);
2024-07-26 09:38:02 +00:00
(void)printf("lock file ret:%d\n", ret);
ASSERT_EQ(ret, 0);
TdThreadAttr thattr;
2024-07-26 09:38:02 +00:00
(void)taosThreadAttrInit(&thattr);
TdThread thread1, thread2;
2024-07-26 09:38:02 +00:00
(void)taosThreadCreate(&(thread1), &thattr, fileOperateOnBusyThread, (void *)fname);
(void)taosThreadAttrDestroy(&thattr);
2024-07-26 09:38:02 +00:00
(void)taosThreadJoin(thread1, NULL);
taosThreadClear(&thread1);
ret = taosUnLockFile(pFile);
2024-07-26 09:38:02 +00:00
(void)printf("unlock file ret:%d\n", ret);
ASSERT_EQ(ret, 0);
ret = taosCloseFile(&pFile);
2024-07-26 09:38:02 +00:00
(void)printf("close file ret:%d\n", ret);
ASSERT_EQ(ret, 0);
2024-07-26 09:38:02 +00:00
(void)taosThreadCreate(&(thread2), &thattr, fileOperateOnFreeThread, (void *)fname);
(void)taosThreadAttrDestroy(&thattr);
2024-07-26 09:38:02 +00:00
(void)taosThreadJoin(thread2, NULL);
taosThreadClear(&thread2);
2025-03-03 02:40:16 +00:00
taosRemoveFile(fname);
2025-02-24 02:59:49 +00:00
// ASSERT_EQ(ret, 0);
// printf("remove file success");
}
2023-11-21 08:31:31 +00:00
#ifndef OSFILE_PERFORMANCE_TEST
#define MAX_WORDS 100
#define MAX_WORD_LENGTH 20
#define MAX_TEST_FILE_SIZE 100000
#define TESTTIMES 1000
char *getRandomWord() {
2025-02-24 02:59:49 +00:00
static char words[][MAX_WORD_LENGTH] = {"Lorem",
"ipsum",
"dolor",
"sit",
"amet",
"consectetur",
"adipiscing",
"elit",
"sed",
"do",
"eiusmod",
"tempor",
"incididunt",
"ut",
"labore",
"et",
"dolore",
"magna",
"aliqua",
"Ut",
"enim",
"ad",
"minim",
"veniam",
"quis",
"nostrud",
"exercitation",
"ullamco",
"Why",
"do",
"programmers",
"prefer",
"using",
"dark",
"mode?",
"Because",
"light",
"attracts",
"bugs",
"and",
"they",
"want",
"to",
"code",
"in",
"peace,",
"like",
"a",
"ninja",
"in",
"the",
"shadows."
"aliqua",
"Ut",
"enim",
"ad",
"minim",
"veniam",
"quis",
"nostrud",
"exercitation",
"ullamco",
"laboris",
"nisi",
"ut",
"aliquip",
"ex",
"ea",
"commodo",
"consequat",
"Duis",
"aute",
"irure",
"dolor",
"in",
"reprehenderit",
"in",
"voluptate",
"velit",
"esse",
"cillum",
"dolore",
"eu",
"fugiat",
"nulla",
"pariatur",
"Excepteur",
"sint",
"occaecat",
"cupidatat",
"non",
"proident",
"sunt",
"in",
"culpa",
"qui",
"officia",
"deserunt",
"mollit",
"anim",
"id",
"est",
"laborum"};
2023-11-21 08:31:31 +00:00
return words[taosRand() % MAX_WORDS];
}
int64_t fillBufferWithRandomWords(char *buffer, int64_t maxBufferSize) {
int64_t len = 0;
while (len < maxBufferSize) {
2025-02-24 02:59:49 +00:00
char *word = getRandomWord();
2023-11-21 08:31:31 +00:00
size_t wordLen = strlen(word);
if (len + wordLen + 1 < maxBufferSize) {
2024-07-26 09:38:02 +00:00
(void)strcat(buffer, word);
(void)strcat(buffer, " ");
2023-11-21 08:31:31 +00:00
len += wordLen + 1;
} else {
break;
}
}
return len;
}
int64_t calculateAverage(int64_t arr[], int size) {
int64_t sum = 0;
for (int i = 0; i < size; i++) {
sum += arr[i];
}
return sum / size;
}
int64_t calculateMax(int64_t arr[], int size) {
int64_t max = arr[0];
for (int i = 1; i < size; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
int64_t calculateMin(int64_t arr[], int size) {
int64_t min = arr[0];
for (int i = 1; i < size; i++) {
if (arr[i] < min) {
min = arr[i];
}
}
return min;
}
TEST(osTest, osFilePerformance) {
2024-07-26 09:38:02 +00:00
(void)printf("os file performance testting...\n");
2023-11-21 08:31:31 +00:00
int64_t WriteFileCost;
int64_t ReadFileCost;
int64_t OpenForWriteCloseFileCost;
int64_t OpenForReadCloseFileCost;
2025-02-24 02:59:49 +00:00
char *buffer;
char *writeBuffer = (char *)taosMemoryCalloc(1, MAX_TEST_FILE_SIZE);
char *readBuffer = (char *)taosMemoryCalloc(1, MAX_TEST_FILE_SIZE);
2023-11-21 08:31:31 +00:00
int64_t size = fillBufferWithRandomWords(writeBuffer, MAX_TEST_FILE_SIZE);
2025-02-24 02:59:49 +00:00
char *fname = "./osFilePerformanceTest.txt";
2023-11-21 08:31:31 +00:00
TdFilePtr pOutFD = taosCreateFile(fname, TD_FILE_WRITE | TD_FILE_CREATE | TD_FILE_TRUNC);
ASSERT_NE(pOutFD, nullptr);
2024-07-26 09:38:02 +00:00
(void)taosCloseFile(&pOutFD);
2023-11-21 08:31:31 +00:00
2024-07-26 09:38:02 +00:00
(void)printf("os file performance start write...\n");
2023-11-21 08:31:31 +00:00
int64_t t1 = taosGetTimestampUs();
for (int i = 0; i < TESTTIMES; ++i) {
TdFilePtr pFile = taosOpenFile(fname, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_WRITE_THROUGH);
ASSERT_NE(pFile, nullptr);
2024-07-26 09:38:02 +00:00
(void)taosWriteFile(pFile, writeBuffer, size);
(void)taosFsyncFile(pFile);
(void)taosCloseFile(&pFile);
2023-11-21 08:31:31 +00:00
}
int64_t t2 = taosGetTimestampUs();
WriteFileCost = t2 - t1;
2024-07-26 09:38:02 +00:00
(void)printf("os file performance start read...\n");
2023-11-21 08:31:31 +00:00
for (int i = 0; i < TESTTIMES; ++i) {
TdFilePtr pFile = taosOpenFile(fname, TD_FILE_READ);
ASSERT_NE(pFile, nullptr);
2024-07-26 09:38:02 +00:00
(void)taosReadFile(pFile, readBuffer, size);
(void)taosCloseFile(&pFile);
2023-11-21 08:31:31 +00:00
int readLine = strlen(readBuffer);
ASSERT_EQ(size, readLine);
}
int64_t t3 = taosGetTimestampUs();
ReadFileCost = t3 - t2;
2024-07-26 09:38:02 +00:00
(void)printf("os file performance start open1...\n");
2023-11-21 08:31:31 +00:00
for (int i = 0; i < TESTTIMES; ++i) {
TdFilePtr pFile = taosOpenFile(fname, TD_FILE_CREATE | TD_FILE_WRITE);
ASSERT_NE(pFile, nullptr);
2024-07-26 09:38:02 +00:00
(void)taosCloseFile(&pFile);
2023-11-21 08:31:31 +00:00
}
int64_t t4 = taosGetTimestampUs();
OpenForWriteCloseFileCost = t4 - t3;
2024-07-26 09:38:02 +00:00
(void)printf("os file performance start open2...\n");
2023-11-21 08:31:31 +00:00
for (int i = 0; i < TESTTIMES; ++i) {
TdFilePtr pFile = taosOpenFile(fname, TD_FILE_CREATE | TD_FILE_READ);
ASSERT_NE(pFile, nullptr);
2024-07-26 09:38:02 +00:00
(void)taosCloseFile(&pFile);
2023-11-21 08:31:31 +00:00
}
int64_t t5 = taosGetTimestampUs();
OpenForReadCloseFileCost = t5 - t4;
#ifdef WINDOWS
printf("os file performance start window native...\n");
for (int i = 0; i < TESTTIMES; ++i) {
HANDLE hFile = CreateFile(fname, // 文件名
GENERIC_WRITE, // 写权限
FILE_SHARE_READ, // 不共享
NULL, // 默认安全描述符
OPEN_ALWAYS, // 打开已存在的文件
FILE_FLAG_WRITE_THROUGH, // 文件标志,可以根据实际需求调整
NULL // 模板文件句柄,对于创建新文件不需要
);
if (hFile == INVALID_HANDLE_VALUE) {
printf("Error opening file\n");
break;
}
// 写入数据
DWORD bytesWritten;
if (!WriteFile(hFile, writeBuffer, size, &bytesWritten, NULL)) {
// 处理错误
printf("Error writing to file\n");
CloseHandle(hFile);
break;
}
// 关闭文件
CloseHandle(hFile);
}
int64_t t6 = taosGetTimestampUs();
int64_t nativeWritCost = t6 - t5;
printf("Test Write file using native API %d times, cost: %" PRId64 "us\n", TESTTIMES, nativeWritCost);
#endif // WINDOWS
taosMemoryFree(writeBuffer);
taosMemoryFree(readBuffer);
2025-03-03 02:40:16 +00:00
taosRemoveFile(fname);
2024-07-26 09:38:02 +00:00
(void)printf("Test Write file %d times, cost: %" PRId64 "us\n", TESTTIMES, WriteFileCost);
(void)printf("Test Read file %d times, cost: %" PRId64 "us\n", TESTTIMES, ReadFileCost);
(void)printf("Test OpenForWrite & Close file %d times, cost: %" PRId64 "us\n", TESTTIMES, OpenForWriteCloseFileCost);
(void)printf("Test OpenForRead & Close file %d times, cost: %" PRId64 "us\n", TESTTIMES, OpenForReadCloseFileCost);
2023-11-21 08:31:31 +00:00
}
2025-02-24 02:59:49 +00:00
#endif // OSFILE_PERFORMANCE_TEST
2023-11-21 08:31:31 +00:00
#pragma GCC diagnostic pop