homework-jianmu/source/os/test/osTests.cpp

348 lines
11 KiB
C++

/*
* 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>
#include <iostream>
#include <inttypes.h>
#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 <windows.h>
#else
#include <arpa/inet.h>
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);
//int ret = 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);
(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