/* * 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 . */ #include #include #include #include #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" #ifdef WINDOWS #include #else #include 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) { // Test taosMemoryDbgInit int32_t ret = taosMemoryDbgInit(); #if defined(LINUX) && !defined(_ALPINE) && !defined(TD_ASTRA) EXPECT_EQ(ret, 0); #else EXPECT_NE(ret, 0); #endif // 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 int64_t ret64 = taosMemSize(NULL); EXPECT_EQ(ret64, 0); // 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); } 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); } 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); 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); // 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); #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); 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) { char fqdn[TD_FQDN_LEN]; char ipString[INET_ADDRSTRLEN]; int code = taosGetFqdn(fqdn); uint32_t ipv4 = 0; code = taosGetIpv4FromFqdn(fqdn, &ipv4); ASSERT_NE(ipv4, 0xffffffff); struct in_addr addr; addr.s_addr = htonl(ipv4); (void)snprintf(ipString, INET_ADDRSTRLEN, "%u.%u.%u.%u", (unsigned int)(addr.s_addr >> 24) & 0xFF, (unsigned int)(addr.s_addr >> 16) & 0xFF, (unsigned int)(addr.s_addr >> 8) & 0xFF, (unsigned int)(addr.s_addr) & 0xFF); (void)printf("fqdn:%s ip:%s\n", fqdn, ipString); } TEST(osTest, osFQDNFailed) { char fqdn[1024] = "fqdn_test_not_found"; char ipString[24]; uint32_t ipv4 = 0; int32_t code = taosGetIpv4FromFqdn(fqdn, &ipv4); ASSERT_NE(code, 0); terrno = TSDB_CODE_RPC_FQDN_ERROR; (void)printf("fqdn:%s transfer to ip failed!\n", fqdn); } #endif // WINDOWS TEST(osTest, osSystem) { const char *flags = "UTL FATAL "; ELogLevel level = DEBUG_FATAL; int32_t dflag = 255; // tsLogEmbedded ? 255 : uDebugFlag taosPrintTrace(flags, level, dflag, 0); const int sysLen = 64; char osSysName[sysLen]; int ret = taosGetOsReleaseName(osSysName, NULL, NULL, sysLen); (void)printf("os system name:%s\n", osSysName); ASSERT_EQ(ret, 0); } void fileOperateOnFree(void *param) { char *fname = (char *)param; TdFilePtr pFile = taosOpenFile(fname, TD_FILE_CREATE | TD_FILE_WRITE); (void)printf("On free thread open file\n"); ASSERT_NE(pFile, nullptr); int ret = taosLockFile(pFile); (void)printf("On free thread lock file ret:%d\n", ret); ASSERT_EQ(ret, 0); ret = taosUnLockFile(pFile); (void)printf("On free thread unlock file ret:%d\n", ret); ASSERT_EQ(ret, 0); ret = taosCloseFile(&pFile); ASSERT_EQ(ret, 0); (void)printf("On free thread close file ret:%d\n", ret); } void *fileOperateOnFreeThread(void *param) { fileOperateOnFree(param); return NULL; } void fileOperateOnBusy(void *param) { char *fname = (char *)param; TdFilePtr pFile = taosOpenFile(fname, TD_FILE_CREATE | TD_FILE_WRITE); (void)printf("On busy thread open file\n"); if (pFile == NULL) return; // ASSERT_NE(pFile, nullptr); int ret = taosLockFile(pFile); (void)printf("On busy thread lock file ret:%d\n", ret); ASSERT_NE(ret, 0); ret = taosUnLockFile(pFile); (void)printf("On busy thread unlock file ret:%d\n", ret); ret = taosCloseFile(&pFile); (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); (void)printf("create file success\n"); (void)taosCloseFile(&pOutFD); (void)taosCloseFile(&pOutFD); TdFilePtr pFile = taosOpenFile(fname, TD_FILE_CREATE | TD_FILE_WRITE); (void)printf("open file\n"); ASSERT_NE(pFile, nullptr); int ret = taosLockFile(pFile); (void)printf("lock file ret:%d\n", ret); ASSERT_EQ(ret, 0); TdThreadAttr thattr; (void)taosThreadAttrInit(&thattr); TdThread thread1, thread2; (void)taosThreadCreate(&(thread1), &thattr, fileOperateOnBusyThread, (void *)fname); (void)taosThreadAttrDestroy(&thattr); (void)taosThreadJoin(thread1, NULL); taosThreadClear(&thread1); ret = taosUnLockFile(pFile); (void)printf("unlock file ret:%d\n", ret); ASSERT_EQ(ret, 0); ret = taosCloseFile(&pFile); (void)printf("close file ret:%d\n", ret); ASSERT_EQ(ret, 0); (void)taosThreadCreate(&(thread2), &thattr, fileOperateOnFreeThread, (void *)fname); (void)taosThreadAttrDestroy(&thattr); (void)taosThreadJoin(thread2, NULL); taosThreadClear(&thread2); taosRemoveFile(fname); // ASSERT_EQ(ret, 0); // printf("remove file success"); } #ifndef OSFILE_PERFORMANCE_TEST #define MAX_WORDS 100 #define MAX_WORD_LENGTH 20 #define MAX_TEST_FILE_SIZE 100000 #define TESTTIMES 1000 char *getRandomWord() { 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"}; return words[taosRand() % MAX_WORDS]; } int64_t fillBufferWithRandomWords(char *buffer, int64_t maxBufferSize) { int64_t len = 0; while (len < maxBufferSize) { char *word = getRandomWord(); size_t wordLen = strlen(word); if (len + wordLen + 1 < maxBufferSize) { (void)strcat(buffer, word); (void)strcat(buffer, " "); 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) { (void)printf("os file performance testting...\n"); int64_t WriteFileCost; int64_t ReadFileCost; int64_t OpenForWriteCloseFileCost; int64_t OpenForReadCloseFileCost; char *buffer; char *writeBuffer = (char *)taosMemoryCalloc(1, MAX_TEST_FILE_SIZE); char *readBuffer = (char *)taosMemoryCalloc(1, MAX_TEST_FILE_SIZE); int64_t size = fillBufferWithRandomWords(writeBuffer, MAX_TEST_FILE_SIZE); char *fname = "./osFilePerformanceTest.txt"; TdFilePtr pOutFD = taosCreateFile(fname, TD_FILE_WRITE | TD_FILE_CREATE | TD_FILE_TRUNC); ASSERT_NE(pOutFD, nullptr); (void)taosCloseFile(&pOutFD); (void)printf("os file performance start write...\n"); 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); (void)taosWriteFile(pFile, writeBuffer, size); (void)taosFsyncFile(pFile); (void)taosCloseFile(&pFile); } int64_t t2 = taosGetTimestampUs(); WriteFileCost = t2 - t1; (void)printf("os file performance start read...\n"); for (int i = 0; i < TESTTIMES; ++i) { TdFilePtr pFile = taosOpenFile(fname, TD_FILE_READ); ASSERT_NE(pFile, nullptr); (void)taosReadFile(pFile, readBuffer, size); (void)taosCloseFile(&pFile); int readLine = strlen(readBuffer); ASSERT_EQ(size, readLine); } int64_t t3 = taosGetTimestampUs(); ReadFileCost = t3 - t2; (void)printf("os file performance start open1...\n"); for (int i = 0; i < TESTTIMES; ++i) { TdFilePtr pFile = taosOpenFile(fname, TD_FILE_CREATE | TD_FILE_WRITE); ASSERT_NE(pFile, nullptr); (void)taosCloseFile(&pFile); } int64_t t4 = taosGetTimestampUs(); OpenForWriteCloseFileCost = t4 - t3; (void)printf("os file performance start open2...\n"); for (int i = 0; i < TESTTIMES; ++i) { TdFilePtr pFile = taosOpenFile(fname, TD_FILE_CREATE | TD_FILE_READ); ASSERT_NE(pFile, nullptr); (void)taosCloseFile(&pFile); } 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); taosRemoveFile(fname); (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); } #endif // OSFILE_PERFORMANCE_TEST #pragma GCC diagnostic pop