mirror of
https://github.com/thead-yocto-mirror/prd-utils
synced 2026-06-21 08:52:31 +02:00
Linux_SDK_V1.1.2
This commit is contained in:
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
!.gitignore
|
||||
*.o
|
||||
out_*
|
||||
buildout
|
||||
build
|
||||
output
|
||||
install.sh
|
||||
make.sh
|
||||
|
||||
34
CMakeLists.txt
Normal file
34
CMakeLists.txt
Normal file
@@ -0,0 +1,34 @@
|
||||
#
|
||||
# Copyright (C) 2023 Alibaba Group Holding Limited
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.5.1)
|
||||
project(prd_utils C)
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
|
||||
# Add fpic
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
# Board Selection
|
||||
if (${BOARD_NAME} MATCHES "light*")
|
||||
set(BOARD_NAME "light")
|
||||
include(cmake/board_light.cmake)
|
||||
else ()
|
||||
message(FATAL_ERROR, "No BOARD_NAME")
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -Wall -g")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined")
|
||||
|
||||
include(cmake/show_cmake_param.cmake)
|
||||
|
||||
|
||||
# Add include dirs for all sub modules
|
||||
include_directories(${PROJECT_BINARY_DIR})
|
||||
include_directories(${PROJECT_SOURCE_DIR}/include)
|
||||
|
||||
add_subdirectory(platform/${BOARD_NAME})
|
||||
add_subdirectory(utils)
|
||||
add_subdirectory(test)
|
||||
|
||||
install(FILES ${INSTALL_HEAD_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
36
README.en.md
36
README.en.md
@@ -1,36 +0,0 @@
|
||||
# prd-utils
|
||||
|
||||
#### Description
|
||||
product produce utilities
|
||||
|
||||
#### Software Architecture
|
||||
Software architecture description
|
||||
|
||||
#### Installation
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
|
||||
#### Instructions
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
|
||||
#### Contribution
|
||||
|
||||
1. Fork the repository
|
||||
2. Create Feat_xxx branch
|
||||
3. Commit your code
|
||||
4. Create Pull Request
|
||||
|
||||
|
||||
#### Gitee Feature
|
||||
|
||||
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
|
||||
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
|
||||
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
|
||||
4. The most valuable open source project [GVP](https://gitee.com/gvp)
|
||||
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
|
||||
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
||||
51
README.md
51
README.md
@@ -1,37 +1,20 @@
|
||||
# prd-utils
|
||||
# Comments
|
||||
This is utilities for product produce process, including:
|
||||
- utils for set/get/clean Key-Value
|
||||
|
||||
#### 介绍
|
||||
product produce utilities
|
||||
# How to get the code
|
||||
- git clone git@gitlab.alibaba-inc.com:thead-linux/prd_utils.git
|
||||
|
||||
#### 软件架构
|
||||
软件架构说明
|
||||
# How to build
|
||||
1. export PATH=riscv-toolchain-2.2.8/bin:$PATH
|
||||
2. mkdir build
|
||||
3. cd buildout
|
||||
4. cmake ../ -DBOARD_NAME="light" -DCMAKE_INSTALL_BINDIR=bin -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_INSTALL_INCLUDEDIR=include -DCMAKE_C_COMPILER=gcc
|
||||
5. make
|
||||
|
||||
|
||||
#### 安装教程
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
|
||||
#### 使用说明
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
|
||||
#### 参与贡献
|
||||
|
||||
1. Fork 本仓库
|
||||
2. 新建 Feat_xxx 分支
|
||||
3. 提交代码
|
||||
4. 新建 Pull Request
|
||||
|
||||
|
||||
#### 特技
|
||||
|
||||
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
|
||||
2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
|
||||
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
|
||||
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
|
||||
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
|
||||
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
||||
# Description of each directories
|
||||
- cmake/: The cmake files for build.
|
||||
- include/: The header files.
|
||||
- platform/: Different platform implementation code directories.
|
||||
- test/: The test cases.
|
||||
- utils/: The utils using in console.
|
||||
|
||||
6
cmake/board_light.cmake
Normal file
6
cmake/board_light.cmake
Normal file
@@ -0,0 +1,6 @@
|
||||
#
|
||||
# Copyright (C) 2023 Alibaba Group Holding Limited
|
||||
#
|
||||
|
||||
SET(CMAKE_C_COMPILER riscv64-linux-gcc)
|
||||
SET(CMAKE_CXX_COMPILER riscv64-linux-c++)
|
||||
11
cmake/custom_macros.cmake
Normal file
11
cmake/custom_macros.cmake
Normal file
@@ -0,0 +1,11 @@
|
||||
#
|
||||
# Copyright (C) 2023 Alibaba Group Holding Limited
|
||||
#
|
||||
|
||||
macro(BuildNormalProgram sourceName)
|
||||
set(TargetName ${sourceName})
|
||||
set(target_src ${sourceName}.c)
|
||||
add_executable(${TargetName} ${target_src})
|
||||
target_link_libraries(${TargetName} ${linkLibs})
|
||||
endmacro(BuildNormalProgram)
|
||||
|
||||
19
cmake/show_cmake_param.cmake
Normal file
19
cmake/show_cmake_param.cmake
Normal file
@@ -0,0 +1,19 @@
|
||||
#
|
||||
# Copyright (C) 2023 Alibaba Group Holding Limited
|
||||
#
|
||||
|
||||
message("")
|
||||
message("=== Show cmake system paramerters ===")
|
||||
message(STATUS "PROJECT_NAME = ${PROJECT_NAME}")
|
||||
message(STATUS "PROJECT_SOURCE_DIR = ${PROJECT_SOURCE_DIR}")
|
||||
message(STATUS "PROJECT_BINARY_DIR = ${PROJECT_BINARY_DIR}")
|
||||
message(STATUS "CMAKE_SOURCE_DIR = ${CMAKE_SOURCE_DIR}")
|
||||
message(STATUS "CMAKE_SYSTEM_PROCESSOR = ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
message(STATUS "CMAKE_SYSTEM = ${CMAKE_SYSTEM}")
|
||||
message(STATUS "CMAKE_C_COMPILER = ${CMAKE_C_COMPILER}")
|
||||
message(STATUS "CMAKE_C_FLAGS = ${CMAKE_C_FLAGS}")
|
||||
message(STATUS "CMAKE_SHARED_LINKER_FLAGS = ${CMAKE_SHARED_LINKER_FLAGS}")
|
||||
message(STATUS "BOARD_NAME = ${BOARD_NAME}")
|
||||
|
||||
message(STATUS "CMAKE_INSTALL_LIBDIR = ${CMAKE_INSTALL_LIBDIR}")
|
||||
message("")
|
||||
41
include/prd_utils_internal.h
Normal file
41
include/prd_utils_internal.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef PRD_UTILS_INTERNAL_H
|
||||
#define PRD_UTILS_INTERNAL_H
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#define MKTAG_NEGA(e) (-(e))
|
||||
|
||||
#define LOG_COLOR_RED_YELLO_BACK "\033[1;31;43m"
|
||||
#define LOG_COLOR_RED "\033[2;31;49m"
|
||||
#define LOG_COLOR_YELLOW "\033[2;33;49m"
|
||||
#define LOG_COLOR_GREEN "\033[2;32;49m"
|
||||
#define LOG_COLOR_BLUE "\033[2;34;49m"
|
||||
#define LOG_COLOR_GRAY "\033[1;30m"
|
||||
#define LOG_COLOR_WHITE "\033[1;47;49m"
|
||||
#define LOG_COLOR_RESET "\033[0m"
|
||||
|
||||
|
||||
#define PRD_UTILS_LOG(fmt, args...) \
|
||||
do {printf("[%s():%d] ",__FUNCTION__, __LINE__); printf(fmt,##args);} while(0)
|
||||
|
||||
#define PRD_UTILS_ASSERT(expr) \
|
||||
do { \
|
||||
if (!(expr)) { \
|
||||
printf(LOG_COLOR_RED \
|
||||
"\nASSERT failed at:\n"\
|
||||
" >File name: %s\n" \
|
||||
" >Function : %s\n" \
|
||||
" >Line No. : %d\n" \
|
||||
" >Condition: %s\n" \
|
||||
LOG_COLOR_RESET, \
|
||||
__FILE__,__FUNCTION__, __LINE__, #expr);\
|
||||
exit(-1); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
||||
#endif /* PRD_UTILS_INTERNAL_H */
|
||||
30
include/prd_utils_kv.h
Normal file
30
include/prd_utils_kv.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef PRD_UTILS_KV_H
|
||||
#define PRD_UTILS_KV_H
|
||||
|
||||
#define PRD_UTILS_KEY_MAX_LENGTH 64
|
||||
#define PRD_UTILS_VAL_MAX_LENGTH 256
|
||||
#define PRD_UTILS_KV_MAX_COUNT 128
|
||||
|
||||
#define PRD_UTILS_KEY_NAME_ETH_ADDR "ethaddr"
|
||||
#define PRD_UTILS_KEY_NAME_SN "sn"
|
||||
|
||||
typedef enum {
|
||||
PRD_UTILS_RESULT_OK = 0,
|
||||
PRD_UTILS_RESULT_KV_INPUT_INVALID = -1,
|
||||
PRD_UTILS_RESULT_KV_IO_FAILED = -2,
|
||||
PRD_UTILS_RESULT_KV_NOT_EXIST = -3,
|
||||
} prd_utils_result_e;
|
||||
|
||||
// Notice:
|
||||
// 1. input key CAN'T including space or other non-printable charater
|
||||
// 2. input value CAN'T including any non-printable charater
|
||||
|
||||
int prd_utils_get_kv(char *key, char **value);
|
||||
int prd_utils_set_kv(char *key, char *value);
|
||||
int prd_utils_clean_kv(char *key);
|
||||
|
||||
#endif /* PRD_UTILS_KV_H */
|
||||
20
platform/light/CMakeLists.txt
Normal file
20
platform/light/CMakeLists.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
#
|
||||
# Copyright (C) 2023 Alibaba Group Holding Limited
|
||||
#
|
||||
|
||||
# include
|
||||
INCLUDE_DIRECTORIES(./)
|
||||
|
||||
SET(LIBSOURCE
|
||||
prd_utils_kv_light.c
|
||||
uboot_env_params.c
|
||||
)
|
||||
|
||||
ADD_LIBRARY(prd_utils SHARED ${LIBSOURCE})
|
||||
|
||||
INSTALL(DIRECTORY ./include/. DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
INSTALL(TARGETS prd_utils
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
|
||||
53
platform/light/prd_utils_kv_light.c
Normal file
53
platform/light/prd_utils_kv_light.c
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <prd_utils_kv.h>
|
||||
#include <prd_utils_internal.h>
|
||||
|
||||
#include "uboot_env_params.h"
|
||||
|
||||
#define CHECK_KEY_VALID(key) \
|
||||
do { \
|
||||
if (key == NULL || strlen(key) >= PRD_UTILS_KEY_MAX_LENGTH) \
|
||||
{ \
|
||||
PRD_UTILS_LOG("key is NULL or key len > %d\n", PRD_UTILS_KEY_MAX_LENGTH); \
|
||||
return PRD_UTILS_RESULT_KV_INPUT_INVALID; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_VAL_VALID(val) \
|
||||
do { \
|
||||
if (val == NULL || strlen(val) >= PRD_UTILS_VAL_MAX_LENGTH) \
|
||||
{ \
|
||||
PRD_UTILS_LOG("val is NULL or val len > %d\n", PRD_UTILS_VAL_MAX_LENGTH); \
|
||||
return PRD_UTILS_RESULT_KV_INPUT_INVALID; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
int prd_utils_get_kv(char *key, char **value)
|
||||
{
|
||||
CHECK_KEY_VALID(key);
|
||||
|
||||
return light_uboot_get_env(key, value);
|
||||
}
|
||||
|
||||
int prd_utils_set_kv(char *key, char *value)
|
||||
{
|
||||
CHECK_KEY_VALID(key);
|
||||
CHECK_VAL_VALID(value);
|
||||
|
||||
return light_uboot_set_env(key, value);
|
||||
}
|
||||
|
||||
int prd_utils_clean_kv(char *key)
|
||||
{
|
||||
CHECK_KEY_VALID(key);
|
||||
|
||||
return light_uboot_clean_env(key);
|
||||
}
|
||||
|
||||
93
platform/light/uboot_env_params.c
Normal file
93
platform/light/uboot_env_params.c
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <prd_utils_kv.h>
|
||||
#include <prd_utils_internal.h>
|
||||
|
||||
#include "uboot_env_params.h"
|
||||
static char g_result[PRD_UTILS_VAL_MAX_LENGTH] = "";
|
||||
|
||||
static int execmd_fetch_result_string(const char *cmd, char *result)
|
||||
{
|
||||
char buffer[PRD_UTILS_VAL_MAX_LENGTH];
|
||||
|
||||
FILE *pipe = popen(cmd, "r");
|
||||
if (pipe == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
while(!feof(pipe))
|
||||
{
|
||||
if(fgets(buffer, PRD_UTILS_VAL_MAX_LENGTH, pipe))
|
||||
{
|
||||
strcat(result, buffer);
|
||||
if(strlen(result) >= PRD_UTILS_VAL_MAX_LENGTH)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pclose(pipe);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int light_uboot_get_env(const char *key, char **value)
|
||||
{
|
||||
char cmd[128 + PRD_UTILS_KEY_MAX_LENGTH] ="";
|
||||
memset(g_result, 0, sizeof(g_result));
|
||||
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
"fw_printenv | grep '%s=' | awk -F '=' '{print $2}' | tr -d '\n' '\r'", key);
|
||||
|
||||
if (execmd_fetch_result_string(cmd, g_result) == 0)
|
||||
{
|
||||
*value = g_result;
|
||||
if (strlen(*value) == 0)
|
||||
{
|
||||
//PRD_UTILS_LOG("light_uboot_get_env() failed, return enmpty value\n");
|
||||
return PRD_UTILS_RESULT_KV_NOT_EXIST;
|
||||
}
|
||||
|
||||
return PRD_UTILS_RESULT_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*value = NULL;
|
||||
//PRD_UTILS_LOG("light_uboot_get_env() failed\n");
|
||||
return PRD_UTILS_RESULT_KV_IO_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int light_uboot_set_env(const char *key, char *value)
|
||||
{
|
||||
char cmd[128 + PRD_UTILS_KEY_MAX_LENGTH + PRD_UTILS_VAL_MAX_LENGTH] ="";
|
||||
snprintf(cmd, sizeof(cmd), "fw_setenv %s '%s'", key, value);
|
||||
|
||||
if (system(cmd) != 0)
|
||||
{
|
||||
PRD_UTILS_LOG("execute cmd='%s' failed\n", cmd);
|
||||
return PRD_UTILS_RESULT_KV_IO_FAILED;
|
||||
}
|
||||
|
||||
return PRD_UTILS_RESULT_OK;
|
||||
}
|
||||
|
||||
int light_uboot_clean_env(const char *key)
|
||||
{
|
||||
char cmd[128 + PRD_UTILS_KEY_MAX_LENGTH] = "";
|
||||
snprintf(cmd, sizeof(cmd), "fw_setenv %s", key);
|
||||
|
||||
if (system(cmd) != 0)
|
||||
{
|
||||
PRD_UTILS_LOG("execute cmd='%s' failed\n", cmd);
|
||||
return PRD_UTILS_RESULT_KV_IO_FAILED;
|
||||
}
|
||||
|
||||
return PRD_UTILS_RESULT_OK;
|
||||
}
|
||||
|
||||
12
platform/light/uboot_env_params.h
Normal file
12
platform/light/uboot_env_params.h
Normal file
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef UBOOT_ENV_PARAMS_H
|
||||
#define UBOOT_ENV_PARAMS_H
|
||||
|
||||
int light_uboot_get_env(const char *key, char **value);
|
||||
int light_uboot_set_env(const char *key, char *value);
|
||||
int light_uboot_clean_env(const char *key);
|
||||
|
||||
#endif /* UBOOT_ENV_PARAMS_H */
|
||||
12
test/CMakeLists.txt
Normal file
12
test/CMakeLists.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
#
|
||||
# Copyright (C) 2023 Alibaba Group Holding Limited
|
||||
#
|
||||
|
||||
include(${PROJECT_SOURCE_DIR}/cmake/custom_macros.cmake)
|
||||
|
||||
# Config all parameters for test cases below
|
||||
set(linkLibs prd_utils)
|
||||
|
||||
# test factory param
|
||||
BuildNormalProgram(test_prd_utils_kv)
|
||||
|
||||
254
test/test_prd_utils_kv.c
Normal file
254
test/test_prd_utils_kv.c
Normal file
@@ -0,0 +1,254 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <prd_utils_kv.h>
|
||||
#include <prd_utils_internal.h>
|
||||
|
||||
#define KV_OP_MAX_DURATION 100 // unit: ms
|
||||
|
||||
static char test_key[] = "test_key";
|
||||
static char test_val[] = "test value with spaces";
|
||||
|
||||
static char max_length_key[PRD_UTILS_KEY_MAX_LENGTH] =
|
||||
"12345678901234567890123456789012345678901234567890" \
|
||||
"1234567890123";
|
||||
|
||||
static char max_length_val[PRD_UTILS_VAL_MAX_LENGTH] =
|
||||
"12345678901234567890123456789012345678901234567890" \
|
||||
"12345678901234567890123456789012345678901234567890" \
|
||||
"12345678901234567890123456789012345678901234567890" \
|
||||
"12345678901234567890123456789012345678901234567890" \
|
||||
"12345678901234567890123456789012345678901234567890" \
|
||||
"12345";
|
||||
|
||||
typedef struct test_performance_records
|
||||
{
|
||||
// unit: us
|
||||
int normal_set;
|
||||
int normal_get;
|
||||
int normal_clean;
|
||||
int max_len_set;
|
||||
int max_len_get;
|
||||
int max_len_clean;
|
||||
|
||||
// tmp values
|
||||
struct timeval tpstart;
|
||||
struct timeval tpend;
|
||||
} test_performance_records_t;
|
||||
|
||||
static test_performance_records_t perf_records;
|
||||
|
||||
#define GET_TIME_BEGIN() do { gettimeofday(&perf_records.tpstart, NULL); } while(0)
|
||||
#define GET_TIME_RECORD(target) do { gettimeofday(&perf_records.tpend, NULL); \
|
||||
target = 1000000 * (perf_records.tpend.tv_sec - perf_records.tpstart.tv_sec) \
|
||||
+ perf_records.tpend.tv_usec - perf_records.tpstart.tv_usec; \
|
||||
} while (0)
|
||||
|
||||
static int test_prd_utils_set_kv()
|
||||
{
|
||||
printf("Test: prd_utils_set_kv() start\n");
|
||||
|
||||
GET_TIME_BEGIN();
|
||||
PRD_UTILS_ASSERT(prd_utils_set_kv(test_key, test_val) == PRD_UTILS_RESULT_OK);
|
||||
GET_TIME_RECORD(perf_records.normal_set);
|
||||
|
||||
printf("Test: prd_utils_set_kv() pass\n\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_prd_utils_get_kv()
|
||||
{
|
||||
char *get_val;
|
||||
printf("Test: prd_utils_get_kv() start\n");
|
||||
|
||||
GET_TIME_BEGIN();
|
||||
PRD_UTILS_ASSERT(prd_utils_get_kv(test_key, &get_val) == PRD_UTILS_RESULT_OK);
|
||||
GET_TIME_RECORD(perf_records.normal_get);
|
||||
|
||||
PRD_UTILS_ASSERT(strncmp(test_val, get_val, PRD_UTILS_VAL_MAX_LENGTH) == 0);
|
||||
|
||||
printf("Test: prd_utils_get_kv() pass\n\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_prd_utils_clean_kv()
|
||||
{
|
||||
char *get_val;
|
||||
printf("Test: prd_utils_clean_kv() start\n");
|
||||
|
||||
GET_TIME_BEGIN();
|
||||
PRD_UTILS_ASSERT(prd_utils_clean_kv(test_key) == PRD_UTILS_RESULT_OK);
|
||||
GET_TIME_RECORD(perf_records.normal_clean);
|
||||
|
||||
PRD_UTILS_ASSERT(prd_utils_get_kv(test_key, &get_val) == PRD_UTILS_RESULT_KV_NOT_EXIST);
|
||||
|
||||
printf("Test: prd_utils_clean_kv() pass\n\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int test_prd_utils_max_kv_value_length()
|
||||
{
|
||||
char *get_val;
|
||||
printf("Test: max value length(%u) start\n", PRD_UTILS_VAL_MAX_LENGTH);
|
||||
|
||||
PRD_UTILS_ASSERT(strlen(max_length_val) == PRD_UTILS_VAL_MAX_LENGTH - 1);
|
||||
|
||||
PRD_UTILS_ASSERT(prd_utils_set_kv(test_key, max_length_val) == PRD_UTILS_RESULT_OK);
|
||||
PRD_UTILS_ASSERT(prd_utils_get_kv(test_key, &get_val) == PRD_UTILS_RESULT_OK);
|
||||
PRD_UTILS_ASSERT(strncmp(max_length_val, get_val, PRD_UTILS_VAL_MAX_LENGTH) == 0);
|
||||
|
||||
PRD_UTILS_ASSERT(prd_utils_clean_kv(test_key) == PRD_UTILS_RESULT_OK);
|
||||
PRD_UTILS_ASSERT(prd_utils_get_kv(test_key, &get_val) == PRD_UTILS_RESULT_KV_NOT_EXIST);
|
||||
|
||||
printf("Test: max value length(%u) pass\n\n", PRD_UTILS_VAL_MAX_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_prd_utils_max_kv_key_length()
|
||||
{
|
||||
char *get_val;
|
||||
printf("Test: max key length(%u) start\n", PRD_UTILS_KEY_MAX_LENGTH);
|
||||
|
||||
PRD_UTILS_ASSERT(strlen(max_length_key) == PRD_UTILS_KEY_MAX_LENGTH - 1);
|
||||
|
||||
PRD_UTILS_ASSERT(prd_utils_set_kv(max_length_key, test_val) == PRD_UTILS_RESULT_OK);
|
||||
PRD_UTILS_ASSERT(prd_utils_get_kv(max_length_key, &get_val) == PRD_UTILS_RESULT_OK);
|
||||
PRD_UTILS_ASSERT(strncmp(test_val, get_val, PRD_UTILS_VAL_MAX_LENGTH) == 0);
|
||||
|
||||
PRD_UTILS_ASSERT(prd_utils_clean_kv(max_length_key) == PRD_UTILS_RESULT_OK);
|
||||
PRD_UTILS_ASSERT(prd_utils_get_kv(max_length_key, &get_val) == PRD_UTILS_RESULT_KV_NOT_EXIST);
|
||||
|
||||
printf("Test: max key length(%u) pass\n\n", PRD_UTILS_KEY_MAX_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_prd_utils_max_kv_capacity()
|
||||
{
|
||||
char *get_val;
|
||||
char test_key[PRD_UTILS_KEY_MAX_LENGTH];
|
||||
char test_val[PRD_UTILS_VAL_MAX_LENGTH];
|
||||
|
||||
printf("Test: max kv capacity(key_len=%u, val_len=%u, count=%u) start\n",
|
||||
PRD_UTILS_KEY_MAX_LENGTH, PRD_UTILS_VAL_MAX_LENGTH, PRD_UTILS_KV_MAX_COUNT);
|
||||
|
||||
const int test_loop_count = PRD_UTILS_KV_MAX_COUNT;
|
||||
// set KVs
|
||||
printf(" step1. testing set max kv(loop=%d):\n ", test_loop_count);
|
||||
for (int i = 0; i < test_loop_count; i++)
|
||||
{
|
||||
//snprintf(test_key, PRD_UTILS_KEY_MAX_LENGTH, test_key_long_fmt, i);
|
||||
snprintf(test_key, PRD_UTILS_KEY_MAX_LENGTH,
|
||||
"12345678901234567890123456789012345678901234567890123456789_%03d", i);
|
||||
|
||||
PRD_UTILS_ASSERT(strlen(test_key) == PRD_UTILS_KEY_MAX_LENGTH - 1);
|
||||
|
||||
snprintf(test_val, PRD_UTILS_VAL_MAX_LENGTH,
|
||||
"12345678901234567890123456789012345678901234567890" \
|
||||
"12345678901234567890123456789012345678901234567890" \
|
||||
"12345678901234567890123456789012345678901234567890" \
|
||||
"12345678901234567890123456789012345678901234567890" \
|
||||
"12345678901234567890123456789012345678901234567890" \
|
||||
"1_%03d", i);
|
||||
PRD_UTILS_ASSERT(strlen(test_val) == PRD_UTILS_VAL_MAX_LENGTH - 1);
|
||||
|
||||
if (i == 0) GET_TIME_BEGIN();
|
||||
PRD_UTILS_ASSERT(prd_utils_set_kv(test_key, test_val) == PRD_UTILS_RESULT_OK);
|
||||
if (i == 0) GET_TIME_RECORD(perf_records.max_len_set);
|
||||
|
||||
printf("."); fflush(stdout); if (i % 64 == 63) printf("\n ");
|
||||
}
|
||||
|
||||
// get KVs and verify, clean
|
||||
printf("step2. testing get max kv(loop=%d):\n ", test_loop_count);
|
||||
for (int i = 0; i < test_loop_count; i++)
|
||||
{
|
||||
snprintf(test_key, PRD_UTILS_KEY_MAX_LENGTH,
|
||||
"12345678901234567890123456789012345678901234567890123456789_%03d", i);
|
||||
|
||||
snprintf(test_val, PRD_UTILS_VAL_MAX_LENGTH,
|
||||
"12345678901234567890123456789012345678901234567890" \
|
||||
"12345678901234567890123456789012345678901234567890" \
|
||||
"12345678901234567890123456789012345678901234567890" \
|
||||
"12345678901234567890123456789012345678901234567890" \
|
||||
"12345678901234567890123456789012345678901234567890" \
|
||||
"1_%03d", i);
|
||||
|
||||
if (i == 0) GET_TIME_BEGIN();
|
||||
PRD_UTILS_ASSERT(prd_utils_get_kv(test_key, &get_val) == PRD_UTILS_RESULT_OK);
|
||||
if (i == 0) GET_TIME_RECORD(perf_records.max_len_get);
|
||||
|
||||
PRD_UTILS_ASSERT(strncmp(test_val, get_val, PRD_UTILS_VAL_MAX_LENGTH) == 0);
|
||||
printf("."); fflush(stdout); if (i % 64 == 63) printf("\n ");
|
||||
}
|
||||
|
||||
// clean KVs
|
||||
printf("step3. testing clean max kv(loop=%d):\n ", test_loop_count);
|
||||
for (int i = 0; i < test_loop_count; i++)
|
||||
{
|
||||
snprintf(test_key, PRD_UTILS_KEY_MAX_LENGTH,
|
||||
"12345678901234567890123456789012345678901234567890123456789_%03d", i);
|
||||
|
||||
if (i == 0) GET_TIME_BEGIN();
|
||||
PRD_UTILS_ASSERT(prd_utils_clean_kv(test_key) == PRD_UTILS_RESULT_OK);
|
||||
if (i == 0) GET_TIME_RECORD(perf_records.max_len_clean);
|
||||
|
||||
PRD_UTILS_ASSERT(prd_utils_get_kv(test_key, &get_val) == PRD_UTILS_RESULT_KV_NOT_EXIST);
|
||||
printf("."); fflush(stdout); if (i % 64 == 63) printf("\n ");
|
||||
}
|
||||
|
||||
printf("Test: max kv capacity(key_len=%u, val_len=%u, count=%u) pass\n\n",
|
||||
PRD_UTILS_KEY_MAX_LENGTH, PRD_UTILS_VAL_MAX_LENGTH, PRD_UTILS_KV_MAX_COUNT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// test normal usage
|
||||
PRD_UTILS_ASSERT(test_prd_utils_set_kv() == 0);
|
||||
PRD_UTILS_ASSERT(test_prd_utils_get_kv() == 0);
|
||||
PRD_UTILS_ASSERT(test_prd_utils_clean_kv() == 0);
|
||||
|
||||
// test max length
|
||||
PRD_UTILS_ASSERT(test_prd_utils_max_kv_value_length() == 0);
|
||||
PRD_UTILS_ASSERT(test_prd_utils_max_kv_key_length() == 0);
|
||||
|
||||
// test max capacity
|
||||
PRD_UTILS_ASSERT(test_prd_utils_max_kv_capacity() == 0);
|
||||
|
||||
// print performance
|
||||
printf("==== prd_utils performance test results ====================\n");
|
||||
printf(" normal set_kv(key_len=%zu, val_len=%zu) cost %.3f ms\n",
|
||||
strlen(test_key), strlen(test_val), (1.0 * perf_records.normal_set) / 1000);
|
||||
printf(" normal get_kv(key_len=%zu, val_len=%zu) cost %.3f ms\n",
|
||||
strlen(test_key), strlen(test_val), (1.0 * perf_records.normal_get) / 1000);
|
||||
printf(" normal clean_kv(key_len=%zu, val_len=%zu) cost %.3f ms\n",
|
||||
strlen(test_key), strlen(test_val), (1.0 * perf_records.normal_clean) / 1000);
|
||||
|
||||
printf(" max_len set_kv(key_len=%u, val_len=%u) cost %.3f ms\n",
|
||||
PRD_UTILS_KEY_MAX_LENGTH, PRD_UTILS_VAL_MAX_LENGTH, (1.0 * perf_records.max_len_set) / 1000);
|
||||
printf(" max_len get_kv(key_len=%u, val_len=%u) cost %.3f ms\n",
|
||||
PRD_UTILS_KEY_MAX_LENGTH, PRD_UTILS_VAL_MAX_LENGTH, (1.0 * perf_records.max_len_get) / 1000);
|
||||
printf(" max_len clean_kv(key_len=%u, val_len=%u) cost %.3f ms\n",
|
||||
PRD_UTILS_KEY_MAX_LENGTH, PRD_UTILS_VAL_MAX_LENGTH, (1.0 * perf_records.max_len_clean) / 1000);
|
||||
printf("============================================================\n");
|
||||
|
||||
PRD_UTILS_ASSERT(perf_records.normal_set/1000 < KV_OP_MAX_DURATION &&
|
||||
perf_records.normal_get/1000 < KV_OP_MAX_DURATION &&
|
||||
perf_records.normal_clean/1000 < KV_OP_MAX_DURATION &&
|
||||
perf_records.max_len_set/1000 < KV_OP_MAX_DURATION &&
|
||||
perf_records.max_len_get/1000 < KV_OP_MAX_DURATION &&
|
||||
perf_records.max_len_clean/1000 < KV_OP_MAX_DURATION);
|
||||
|
||||
printf(LOG_COLOR_GREEN "All KV tests PASSED\n" LOG_COLOR_RESET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
12
utils/CMakeLists.txt
Normal file
12
utils/CMakeLists.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
#
|
||||
# Copyright (C) 2023 Alibaba Group Holding Limited
|
||||
#
|
||||
|
||||
include(${PROJECT_SOURCE_DIR}/cmake/custom_macros.cmake)
|
||||
|
||||
# Config all parameters for test cases below
|
||||
set(linkLibs prd_utils)
|
||||
|
||||
# test factory param
|
||||
BuildNormalProgram(prd_utils_kv)
|
||||
|
||||
128
utils/prd_utils_kv.c
Normal file
128
utils/prd_utils_kv.c
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <prd_utils_kv.h>
|
||||
|
||||
#define PROGRAM_NAME "prd_utils_kv"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int op_code; /* 0: set, 1:get; 2: clean */
|
||||
char key[PRD_UTILS_KEY_MAX_LENGTH];
|
||||
char val[PRD_UTILS_VAL_MAX_LENGTH];
|
||||
} cmd_params_s;
|
||||
|
||||
static const char *shortopts = "hs:g:c:";
|
||||
static const struct option long_options[] =
|
||||
{
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"SetParam", required_argument, 0, 's'},
|
||||
{"GetParam", required_argument, 0, 'g'},
|
||||
{"CleanParam", required_argument, 0, 'c'},
|
||||
{0, 0, 0, 0 } // Act as end of option
|
||||
};
|
||||
|
||||
static void usage(char *program_name)
|
||||
{
|
||||
printf("Usage: %s [OPTION]\n", program_name);
|
||||
printf(" -h, --help display this help and exit\n");
|
||||
printf(" -s, --SetParam set param, for example: %s -s sn=123456abcde\n", program_name);
|
||||
printf(" -g, --GetParam get param, for example: %s -g sn\n", program_name);
|
||||
printf(" -c, --CleanParam clean param, for example: %s -c sn\n", program_name);
|
||||
}
|
||||
|
||||
static int parse_params(int argc, char *argv[], cmd_params_s *params)
|
||||
{
|
||||
int c;
|
||||
int option_index = 0;
|
||||
int option_count = 0;
|
||||
|
||||
char *program_name = PROGRAM_NAME;
|
||||
|
||||
char *equal_sign;
|
||||
int pos;
|
||||
|
||||
while ((c = getopt_long(argc, argv, shortopts, long_options, &option_index)) != -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'h':
|
||||
usage(program_name);
|
||||
exit(0);
|
||||
case 's':
|
||||
params->op_code = 0;
|
||||
equal_sign = strchr(optarg, '=');
|
||||
if (equal_sign == NULL)
|
||||
{
|
||||
printf("command is invalid, please flow:\n");
|
||||
usage(program_name);
|
||||
exit(-1);
|
||||
}
|
||||
pos = equal_sign - optarg;
|
||||
strncpy(params->key, optarg, pos);
|
||||
strncpy(params->val, optarg + pos + 1, strlen(optarg) - pos);
|
||||
option_count++;
|
||||
break;
|
||||
case 'g':
|
||||
params->op_code = 1;
|
||||
sscanf(optarg, "%s", params->key);
|
||||
option_count++;
|
||||
break;
|
||||
case 'c':
|
||||
params->op_code = 2;
|
||||
sscanf(optarg, "%s", params->key);
|
||||
option_count++;
|
||||
break;
|
||||
default:
|
||||
printf("Not supported opt:'%c'\n", c);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return option_count;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ret;
|
||||
char *val;
|
||||
|
||||
cmd_params_s cmd_params;
|
||||
memset(&cmd_params, 0, sizeof(cmd_params));
|
||||
int option_count = parse_params(argc, argv, &cmd_params);
|
||||
if (option_count == 0)
|
||||
{
|
||||
usage(PROGRAM_NAME);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
switch (cmd_params.op_code)
|
||||
{
|
||||
case 0: // set
|
||||
ret = prd_utils_set_kv(cmd_params.key, cmd_params.val);
|
||||
printf("set '%s'='%s' %s\n", cmd_params.key, cmd_params.val, (ret == 0) ? "OK" : "failed");
|
||||
break;
|
||||
case 1: // get
|
||||
ret = prd_utils_get_kv(cmd_params.key, &val);
|
||||
if (ret != 0)
|
||||
{
|
||||
printf("get sys param '%s' failed\n", cmd_params.key);
|
||||
return ret;
|
||||
}
|
||||
printf("Got sys param '%s'='%s'\n", cmd_params.key, val);
|
||||
break;
|
||||
case 2: // clean;
|
||||
ret = prd_utils_clean_kv(cmd_params.key);
|
||||
printf("clean sys param '%s' %s\n", cmd_params.key, (ret == 0) ? "OK" : "failed");
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user