lcr/0005-refactor-util-buffer-and-add-ut.patch
jake 26787717d8 !257 sync from upstream
* sync from upstream
2023-09-19 08:38:39 +00:00

1099 lines
32 KiB
Diff

From 9eff61689ae66c2531750d1bf1c8e551f6b576a9 Mon Sep 17 00:00:00 2001
From: haozi007 <liuhao27@huawei.com>
Date: Wed, 13 Sep 2023 11:05:19 +0800
Subject: [PATCH 5/8] refactor util buffer and add ut
Signed-off-by: haozi007 <liuhao27@huawei.com>
---
CMakeLists.txt | 3 +-
src/CMakeLists.txt | 25 ++-
src/buffer.h | 39 -----
src/constants.h | 8 +
src/runtime/conf.c | 32 ++--
src/runtime/conf.h | 8 +
src/runtime/lcr_list.h | 7 +
src/{buffer.c => utils/utils_buffer.c} | 189 ++++++++++++----------
src/utils/utils_buffer.h | 93 +++++++++++
tests/CMakeLists.txt | 35 +++-
tests/auto_cleanup_ut.cpp | 19 +++
tests/utils_buffer_ut.cpp | 213 +++++++++++++++++++++++++
12 files changed, 516 insertions(+), 155 deletions(-)
delete mode 100644 src/buffer.h
rename src/{buffer.c => utils/utils_buffer.c} (60%)
create mode 100644 src/utils/utils_buffer.h
create mode 100644 tests/utils_buffer_ut.cpp
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e00dc96..2bbb829 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -128,7 +128,8 @@ install(FILES src/json/parse_common.h DESTINATION include/isula_libutils)
install(DIRECTORY ${CMAKE_BINARY_DIR}/json/ DESTINATION include/isula_libutils
FILES_MATCHING PATTERN "*.h")
install(FILES src/auto_cleanup.h DESTINATION include/isula_libutils)
-# donot export utils now
+# export utils here
+install(FILES src/utils/utils_buffer.h DESTINATION include/isula_libutils)
# uninstall
if(NOT TARGET uninstall)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c423dd7..cb076e8 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -92,16 +92,29 @@ target_include_directories(isula_libutils
target_link_libraries(isula_libutils ${check_isula_utils_libs})
-add_library(isula_libutils_s
+add_library(isulad_shim_libutils
STATIC
- ${isula_libutils_srcs}
+ ${topsrcs}
+ ${THIRD_PARTY_SRCS}
+ ${commonjsonsrcs}
+ ${topjsonsrcs}
+ ${UTILS_SRCS}
+ ${CMAKE_BINARY_DIR}/json/logger_json_file.c
+ ${CMAKE_BINARY_DIR}/json/shim_client_process_state.c
+ ${CMAKE_BINARY_DIR}/json/shim_client_runtime_stats.c
+ ${CMAKE_BINARY_DIR}/json/shim_client_cgroup_resources.c
+ ${CMAKE_BINARY_DIR}/json/json_common.c
+ ${CMAKE_BINARY_DIR}/json/defs.c
+ ${CMAKE_BINARY_DIR}/json/oci_runtime_config_linux.c
+ ${CMAKE_BINARY_DIR}/json/oci_runtime_pspec.c
+ ${CMAKE_BINARY_DIR}/json/oci_runtime_spec.c
+ ${CMAKE_BINARY_DIR}/json/oci_runtime_state.c
)
-target_include_directories(isula_libutils_s
+target_include_directories(isulad_shim_libutils
PUBLIC ${isula_libutils_incs}
)
-target_link_libraries(isula_libutils_s ${check_isula_utils_libs})
-set_target_properties(isula_libutils_s PROPERTIES OUTPUT_NAME isula_libutils)
+target_link_libraries(isulad_shim_libutils ${LIBYAJL_LIBRARY})
if (ENABLE_LIBLCR)
# set liblcr library
@@ -149,5 +162,5 @@ endif()
install(TARGETS isula_libutils
LIBRARY DESTINATION ${LIB_INSTALL_DIR_DEFAULT} PERMISSIONS OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
-install(TARGETS isula_libutils_s
+install(TARGETS isulad_shim_libutils
ARCHIVE DESTINATION ${LIB_INSTALL_DIR_DEFAULT} PERMISSIONS OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
diff --git a/src/buffer.h b/src/buffer.h
deleted file mode 100644
index b7777ab..0000000
--- a/src/buffer.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/******************************************************************************
- * lcr: utils library for iSula
- *
- * Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved.
- *
- * Authors:
- * Haozi007 <liuhao27@huawei.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- ********************************************************************************/
-
-#ifndef _ISULA_UTILS_BUFFER_H
-#define _ISULA_UTILS_BUFFER_H
-
-#include <stdlib.h>
-
-typedef struct Buffer {
- char *contents;
- size_t bytes_used;
- size_t total_size;
-} Buffer;
-
-Buffer *buffer_alloc(size_t initial_size);
-void buffer_free(Buffer *buf);
-int buffer_nappendf(Buffer *buf, size_t length, const char *format, ...);
-char *buffer_to_s(const Buffer *buf);
-#endif
diff --git a/src/constants.h b/src/constants.h
index 85a3196..b62026d 100644
--- a/src/constants.h
+++ b/src/constants.h
@@ -24,6 +24,10 @@
#ifndef _ISULA_UTILS_CONSTANTS_H
#define _ISULA_UTILS_CONSTANTS_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* mode of file and directory */
#define DEFAULT_SECURE_FILE_MODE 0640
@@ -53,4 +57,8 @@
/* buffer constants defined here */
#define ISULA_PAGE_BUFSIZE 4096
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/src/runtime/conf.c b/src/runtime/conf.c
index 4554599..d505507 100644
--- a/src/runtime/conf.c
+++ b/src/runtime/conf.c
@@ -36,7 +36,7 @@
#include "utils.h"
#include "log.h"
-#include "buffer.h"
+#include "utils_buffer.h"
#include "lcr_list.h"
#include "constants.h"
@@ -2665,7 +2665,7 @@ static bool is_action_allow(const char *value)
#define DEFAULT_ACTION_OFFSET 12
/* seccomp append head info */
-static int seccomp_append_head_info(const char *action, Buffer *buffer)
+static int seccomp_append_head_info(const char *action, isula_buffer *buffer)
{
int ret = 0;
char *default_action = NULL;
@@ -2681,9 +2681,9 @@ static int seccomp_append_head_info(const char *action, Buffer *buffer)
}
if (is_action_allow(default_action)) {
- ret = buffer_nappendf(buffer, strlen(default_action) + DEFAULT_ACTION_OFFSET, "blacklist %s\n", default_action);
+ ret = buffer->nappend(buffer, strlen(default_action) + DEFAULT_ACTION_OFFSET, "blacklist %s\n", default_action);
} else {
- ret = buffer_nappendf(buffer, strlen(default_action) + DEFAULT_ACTION_OFFSET, "whitelist %s\n", default_action);
+ ret = buffer->nappend(buffer, strlen(default_action) + DEFAULT_ACTION_OFFSET, "whitelist %s\n", default_action);
}
if (ret != 0) {
ERROR("Failed to append seccomp config head info\n");
@@ -2773,7 +2773,7 @@ static char *seccomp_trans_arch(const char *arch)
}
/* seccomp append arch */
-static int seccomp_append_arch(char *arch, Buffer *buffer)
+static int seccomp_append_arch(char *arch, isula_buffer *buffer)
{
int ret = 0;
char *trans_arch = NULL;
@@ -2788,7 +2788,7 @@ static int seccomp_append_arch(char *arch, Buffer *buffer)
return -1;
}
- if (buffer_nappendf(buffer, strlen(trans_arch) + 2, "%s\n", trans_arch)) {
+ if (buffer->nappend(buffer, strlen(trans_arch) + 2, "%s\n", trans_arch)) {
ERROR("Failed to append seccomp config head info\n");
ret = -1;
}
@@ -2798,7 +2798,7 @@ static int seccomp_append_arch(char *arch, Buffer *buffer)
}
/* seccomp append rule */
-static int seccomp_append_rule(const defs_syscall *syscall, size_t i, Buffer *buffer, char *action)
+static int seccomp_append_rule(const defs_syscall *syscall, size_t i, isula_buffer *buffer, char *action)
{
int ret = 0;
size_t j = 0;
@@ -2808,7 +2808,7 @@ static int seccomp_append_rule(const defs_syscall *syscall, size_t i, Buffer *bu
ret = -1;
goto out;
}
- if (buffer_nappendf(buffer, strlen(syscall->names[i]) + strlen(action) + 2, "%s %s", syscall->names[i], action)) {
+ if (buffer->nappend(buffer, strlen(syscall->names[i]) + strlen(action) + 2, "%s %s", syscall->names[i], action)) {
ERROR("Failed to append syscall name and action\n");
ret = -1;
goto out;
@@ -2820,7 +2820,7 @@ static int seccomp_append_rule(const defs_syscall *syscall, size_t i, Buffer *bu
ret = -1;
goto out;
}
- if (buffer_nappendf(buffer, 20 * 3 + strlen(syscall->args[j]->op), " [%u,%llu,%s,%llu]",
+ if (buffer->nappend(buffer, 20 * 3 + strlen(syscall->args[j]->op), " [%u,%llu,%s,%llu]",
syscall->args[j]->index, syscall->args[j]->value, syscall->args[j]->op,
syscall->args[j]->value_two)) {
ERROR("Failed to append syscall rules\n");
@@ -2829,7 +2829,7 @@ static int seccomp_append_rule(const defs_syscall *syscall, size_t i, Buffer *bu
}
}
- if (buffer_nappendf(buffer, 2, "\n")) {
+ if (buffer->append(buffer, "\n")) {
ERROR("Failed to append newline\n");
ret = -1;
goto out;
@@ -2839,7 +2839,7 @@ out:
}
/* seccomp append rules */
-static int seccomp_append_rules(const defs_syscall *syscall, Buffer *buffer)
+static int seccomp_append_rules(const defs_syscall *syscall, isula_buffer *buffer)
{
int ret = 0;
size_t i = 0;
@@ -2905,7 +2905,7 @@ out_free:
return NULL;
}
-static int append_seccomp_with_archs(const oci_runtime_config_linux_seccomp *seccomp, Buffer *buffer)
+static int append_seccomp_with_archs(const oci_runtime_config_linux_seccomp *seccomp, isula_buffer *buffer)
{
int ret = 0;
size_t i = 0;
@@ -2963,14 +2963,14 @@ static int trans_oci_seccomp(const oci_runtime_config_linux_seccomp *seccomp, ch
size_t j = 0;
size_t init_size = 4 * SIZE_KB;
- Buffer *buffer = buffer_alloc(init_size);
+ isula_buffer *buffer = isula_buffer_alloc(init_size);
if (buffer == NULL) {
ERROR("Failed to malloc output_buffer\n");
return -1;
}
/* config version */
- if (buffer_nappendf(buffer, 3, "2\n")) {
+ if (buffer->append(buffer, "2\n")) {
ERROR("Failed to append seccomp config version\n");
ret = -1;
goto out_free;
@@ -2997,14 +2997,14 @@ static int trans_oci_seccomp(const oci_runtime_config_linux_seccomp *seccomp, ch
}
}
}
- *seccomp_conf = buffer_to_s(buffer);
+ *seccomp_conf = buffer->to_str(buffer);
if (*seccomp_conf == NULL) {
ret = -1;
goto out_free;
}
out_free:
- buffer_free(buffer);
+ isula_buffer_free(buffer);
return ret;
}
diff --git a/src/runtime/conf.h b/src/runtime/conf.h
index 6dfef79..38c1a3e 100644
--- a/src/runtime/conf.h
+++ b/src/runtime/conf.h
@@ -26,6 +26,10 @@
#include "oci_runtime_spec.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#define INVALID_INT 0
/*
@@ -118,4 +122,8 @@ struct lcr_list *get_needed_lxc_conf();
bool is_system_container(const oci_runtime_spec *container);
+#ifdef __cplusplus
+}
+#endif
+
#endif /*__LCR_CONF_H*/
diff --git a/src/runtime/lcr_list.h b/src/runtime/lcr_list.h
index bdf1f1b..86a13e0 100644
--- a/src/runtime/lcr_list.h
+++ b/src/runtime/lcr_list.h
@@ -24,6 +24,9 @@
#ifndef __LCR_LIST_H
#define __LCR_LIST_H
+#ifdef __cplusplus
+extern "C" {
+#endif
struct lcr_list {
void *elem;
@@ -144,4 +147,8 @@ static inline size_t lcr_list_len(struct lcr_list *list)
return i;
}
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/src/buffer.c b/src/utils/utils_buffer.c
similarity index 60%
rename from src/buffer.c
rename to src/utils/utils_buffer.c
index ca103ff..da34991 100644
--- a/src/buffer.c
+++ b/src/utils/utils_buffer.c
@@ -20,68 +20,28 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
********************************************************************************/
-
#define _GNU_SOURCE
-#include <stdio.h>
-#include <string.h>
+#include "utils_buffer.h"
-#include "buffer.h"
+#include "utils_memory.h"
#include "log.h"
-#include "utils.h"
#include "auto_cleanup.h"
-/* buffer allocate */
-Buffer *buffer_alloc(size_t initial_size)
-{
- Buffer *buf = NULL;
- char *tmp = NULL;
-
- if (initial_size == 0) {
- return NULL;
- }
-
- buf = lcr_util_common_calloc_s(sizeof(Buffer));
- if (buf == NULL) {
- return NULL;
- }
-
- tmp = calloc(1, initial_size);
- if (tmp == NULL) {
- free(buf);
- return NULL;
- }
-
- buf->contents = tmp;
- buf->bytes_used = 0;
- buf->total_size = initial_size;
-
- return buf;
-}
-
-/* buffer strlen */
-static size_t buffer_strlen(const Buffer *buf)
-{
- return buf == NULL ? 0 : buf->bytes_used;
-}
-
-/* buffer free */
-void buffer_free(Buffer *buf)
+void isula_buffer_clear(isula_buffer *buf)
{
if (buf == NULL) {
return;
}
- free(buf->contents);
- buf->contents = NULL;
- free(buf);
+ (void)memset(buf->contents, 0, buf->total_size);
+ buf->bytes_used = 0;
}
-/* buffer has space */
-static bool buffer_has_space(const Buffer *buf, size_t desired_length)
+static bool buffer_has_space(const isula_buffer *buf, size_t desired_length)
{
- size_t bytes_remaining = 0;
+ size_t bytes_remaining;
- if (buf == NULL) {
+ if (buf->total_size < buf->bytes_used) {
return false;
}
bytes_remaining = buf->total_size - buf->bytes_used;
@@ -89,36 +49,27 @@ static bool buffer_has_space(const Buffer *buf, size_t desired_length)
return desired_length <= bytes_remaining;
}
-/* buffer grow */
-static int buffer_grow(Buffer *buf, size_t minimum_size)
+static int buffer_grow(isula_buffer *buf, size_t minimum_size)
{
- size_t factor = 0;
- size_t new_size = 0;
+ size_t factor, new_size;
char *tmp = NULL;
- if (buf == NULL) {
- return -1;
- }
-
factor = buf->total_size;
if (factor < minimum_size) {
factor = minimum_size;
}
- if (factor > SIZE_MAX / 2) {
+ if (factor == 0) {
+ ERROR("Invalid grow size");
return -1;
}
- new_size = factor * 2;
- if (new_size == 0) {
- return -1;
- }
-
- tmp = lcr_util_common_calloc_s(new_size);
+ tmp = lcr_util_smart_calloc_s(factor, 2);
if (tmp == NULL) {
ERROR("Out of memory");
return -1;
}
+ new_size = factor * 2;
(void)memcpy(tmp, buf->contents, buf->total_size);
@@ -129,14 +80,9 @@ static int buffer_grow(Buffer *buf, size_t minimum_size)
return 0;
}
-/* buffer cat */
-static void buffer_cat(Buffer *buf, const char *append, size_t length)
+static void buffer_cat(isula_buffer *buf, const char *append, size_t length)
{
- size_t i = 0;
-
- if (buf == NULL) {
- return;
- }
+ size_t i;
for (i = 0; i < length; i++) {
if (append[i] == '\0') {
@@ -150,13 +96,12 @@ static void buffer_cat(Buffer *buf, const char *append, size_t length)
*(buf->contents + buf->bytes_used) = '\0';
}
-/* buffer append */
-static int buffer_append(Buffer *buf, const char *append, size_t length)
+static int buffer_append(isula_buffer *buf, const char *append, size_t length)
{
size_t desired_length = 0;
- if (buf == NULL) {
- return -1;
+ if (append == NULL) {
+ return 0;
}
desired_length = length + 1;
@@ -171,62 +116,132 @@ static int buffer_append(Buffer *buf, const char *append, size_t length)
return 0;
}
-/* buffer nappendf */
-int buffer_nappendf(Buffer *buf, size_t length, const char *format, ...)
+int isula_buffer_nappend(isula_buffer *buf, size_t length, const char *format, ...)
{
int status = 0;
- size_t printf_length = 0;
+ size_t printf_length;
__isula_auto_free char *tmp = NULL;
va_list argp;
if (buf == NULL) {
+ DEBUG("Empty buffer.");
return -1;
}
- if (length > SIZE_MAX / sizeof(char) - 1) {
+ if (format == NULL || length == 0) {
+ return 0;
+ }
+
+ if (length > SIZE_MAX - 1) {
+ ERROR("Too large append string");
return -1;
}
printf_length = length + 1;
- tmp = calloc(1, printf_length * sizeof(char));
+ tmp = lcr_util_smart_calloc_s(sizeof(char), printf_length);
if (tmp == NULL) {
+ ERROR("Out of memory");
return -1;
}
va_start(argp, format);
- status = vsnprintf(tmp, length, format, argp);
+ status = vsnprintf(tmp, printf_length, format, argp);
va_end(argp);
if (status < 0) {
+ SYSERROR("Sprintf error");
return -1;
}
- status = buffer_append(buf, tmp, length);
- if (status != 0) {
+ return buffer_append(buf, tmp, length);
+}
+
+int isula_buffer_append(isula_buffer *buf, const char *str)
+{
+ if (buf == NULL) {
+ DEBUG("Empty buffer.");
return -1;
}
- return 0;
+ if (str == NULL || strlen(str) == 0) {
+ return 0;
+ }
+
+ return buffer_append(buf, str, strlen(str));
}
-/* buffer to string */
-char *buffer_to_s(const Buffer *buf)
+char *isula_buffer_to_str(const isula_buffer *buf)
{
size_t len;
char *result = NULL;
if (buf == NULL) {
+ DEBUG("Empty argument.");
return NULL;
}
- len = buffer_strlen(buf);
+ len = buf->bytes_used;
if (len == SIZE_MAX) {
+ ERROR("Too large buffer data");
return NULL;
}
- result = calloc(1, len + 1);
+ result = lcr_util_smart_calloc_s(1, len + 1);
if (result == NULL) {
+ ERROR("Out of memory");
return NULL;
}
(void)strncpy(result, buf->contents, len);
return result;
}
+
+size_t isula_buffer_strlen(const isula_buffer *buf)
+{
+ return buf == NULL ? 0 : buf->bytes_used;
+}
+
+isula_buffer *isula_buffer_alloc(size_t initial_size)
+{
+ isula_buffer *buf = NULL;
+ char *tmp = NULL;
+
+ if (initial_size == 0) {
+ return NULL;
+ }
+
+ buf = lcr_util_common_calloc_s(sizeof(isula_buffer));
+ if (buf == NULL) {
+ ERROR("Out of memory");
+ return NULL;
+ }
+
+ tmp = lcr_util_smart_calloc_s(1, initial_size);
+ if (tmp == NULL) {
+ ERROR("Out of memory");
+ free(buf);
+ return NULL;
+ }
+
+ buf->contents = tmp;
+ buf->bytes_used = 0;
+ buf->total_size = initial_size;
+
+ buf->clear = isula_buffer_clear;
+ buf->nappend = isula_buffer_nappend;
+ buf->append = isula_buffer_append;
+ buf->to_str = isula_buffer_to_str;
+ buf->length = isula_buffer_strlen;
+
+ return buf;
+}
+
+void isula_buffer_free(isula_buffer *buf)
+{
+ if (buf == NULL) {
+ return;
+ }
+ free(buf->contents);
+ buf->contents = NULL;
+ buf->bytes_used = 0;
+ buf->total_size = 0;
+ free(buf);
+}
\ No newline at end of file
diff --git a/src/utils/utils_buffer.h b/src/utils/utils_buffer.h
new file mode 100644
index 0000000..22c975c
--- /dev/null
+++ b/src/utils/utils_buffer.h
@@ -0,0 +1,93 @@
+/******************************************************************************
+ * lcr: utils library for iSula
+ *
+ * Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved.
+ *
+ * Authors:
+ * Haozi007 <liuhao27@huawei.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ********************************************************************************/
+
+#ifndef _ISULA_UTILS_BUFFER_H
+#define _ISULA_UTILS_BUFFER_H
+
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct __isula_buffer;
+
+/*
+ * clear used data in buffer, and reset used_size to 0
+ */
+typedef void (*clear_op)(struct __isula_buffer *buf);
+
+/*
+* append string which length is length into buffer;
+* length should >= strlen(formatted string), else will truncate format string;
+* success, return 0;
+* fail, return -1;
+*/
+typedef int (*nappend_op)(struct __isula_buffer *buf, size_t length, const char *format, ...);
+
+/*
+* append string into buffer;
+* success, return 0;
+* fail, return -1;
+*/
+typedef int (*append_op)(struct __isula_buffer *buf, const char *str);
+
+/*
+* transform buffer to string, and return to caller
+*/
+typedef char *(*to_str_op)(const struct __isula_buffer *buf);
+
+/*
+* get length of data in buffer
+*/
+typedef size_t (*length_op)(const struct __isula_buffer *buf);
+
+struct __isula_buffer {
+ char *contents;
+ size_t bytes_used;
+ size_t total_size;
+ clear_op clear;
+ nappend_op nappend;
+ append_op append;
+ to_str_op to_str;
+ length_op length;
+};
+typedef struct __isula_buffer isula_buffer;
+
+/*
+* create isula buffer with initial size memory
+* if initial_size == 0, will return NULL;
+* if success, return a isula_buffer struct;
+*/
+isula_buffer *isula_buffer_alloc(size_t initial_size);
+
+/*
+* free isula_buffer struct and memory in it
+*/
+void isula_buffer_free(isula_buffer *buf);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 4c66a98..ff0ca47 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -26,29 +26,52 @@ find_package(GTest REQUIRED)
configure_file("data/ocihook.json" ${CMAKE_BINARY_DIR}/tests/ocihook.json COPYONLY)
configure_file("data/process.json" ${CMAKE_BINARY_DIR}/tests/process.json COPYONLY)
+file(GLOB_RECURSE test_util_srcs
+ "${CMAKE_SOURCE_DIR}/src/third_party/*.c"
+ "${CMAKE_SOURCE_DIR}/src/third_party/**/*.c"
+ "${CMAKE_SOURCE_DIR}/src/json/*.c"
+ "${CMAKE_SOURCE_DIR}/src/json/**/*.c"
+ "${CMAKE_SOURCE_DIR}/src/utils/*.c"
+ "${CMAKE_SOURCE_DIR}/src/utils/**/*.c"
+ "${CMAKE_BINARY_DIR}/json/*.c"
+)
+
+add_library(test_libisula_utils SHARED ${test_util_srcs})
+target_include_directories(test_libisula_utils
+ PUBLIC ${CMAKE_SOURCE_DIR}/src
+ PUBLIC ${CMAKE_SOURCE_DIR}/src/utils
+ PUBLIC ${CMAKE_SOURCE_DIR}/src/third_party
+ PUBLIC ${CMAKE_SOURCE_DIR}/src/third_party/libocispec
+ PUBLIC ${CMAKE_SOURCE_DIR}/src/json
+ PUBLIC ${CMAKE_SOURCE_DIR}/src/json/schema/src
+ PUBLIC ${CMAKE_BINARY_DIR}/json
+ PUBLIC ${CMAKE_BINARY_DIR}/conf
+ )
+target_link_libraries(test_libisula_utils ${LIBYAJL_LIBRARY})
+
macro(_DEFINE_NEW_TEST)
add_executable(${ARGV0}
- ${TESTS_UTILS_SRCS}
main.cpp
${ARGV0}.cpp
)
target_link_libraries(${ARGV0}
- isula_libutils
+ test_libisula_utils
${GTEST_LIBRARY}
- ${LIBYAJL_LIBRARY}
pthread
)
target_include_directories(${ARGV0} PUBLIC
${GTEST_INCLUDE_DIR}
- PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
PUBLIC ${CMAKE_SOURCE_DIR}/src
+ PUBLIC ${CMAKE_SOURCE_DIR}/src/utils
PUBLIC ${CMAKE_SOURCE_DIR}/src/third_party
+ PUBLIC ${CMAKE_SOURCE_DIR}/src/third_party/libocispec
PUBLIC ${CMAKE_SOURCE_DIR}/src/json
PUBLIC ${CMAKE_SOURCE_DIR}/src/json/schema/src
PUBLIC ${CMAKE_BINARY_DIR}/json
PUBLIC ${CMAKE_BINARY_DIR}/conf
+ PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
)
add_test(
@@ -72,7 +95,7 @@ _DEFINE_NEW_TEST(libocispec_ut libocispec_testcase)
_DEFINE_NEW_TEST(defs_process_ut defs_process_testcase)
_DEFINE_NEW_TEST(go_crc64_ut go_crc64_testcase)
_DEFINE_NEW_TEST(auto_cleanup_ut autocleanup_testcase)
-
+_DEFINE_NEW_TEST(utils_buffer_ut isula_buffer_testcase)
# mock test for run lcov to generate html
add_executable(mock_ut main.cpp)
@@ -84,7 +107,7 @@ target_link_libraries(mock_ut
${GTEST_LIBRARY}
pthread
)
-add_dependencies(mock_ut log_ut libocispec_ut defs_process_ut go_crc64_ut)
+add_dependencies(mock_ut log_ut libocispec_ut defs_process_ut go_crc64_ut auto_cleanup_ut utils_buffer_ut)
IF(ENABLE_GCOV)
add_custom_target(coverage
diff --git a/tests/auto_cleanup_ut.cpp b/tests/auto_cleanup_ut.cpp
index 1eff4b2..b167bcb 100644
--- a/tests/auto_cleanup_ut.cpp
+++ b/tests/auto_cleanup_ut.cpp
@@ -105,16 +105,34 @@ TEST(autocleanup_testcase, test__isula_auto_prw_unlock)
size_t do_auto_free()
{
__isula_auto_free void *test = nullptr;
+#if defined(__GLIBC__) && ((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 33))
+ struct mallinfo2 info = { 0 };
+
+ // use 1024 * 1024 to ensure memory allo from mmap
+ test = malloc(1024 * 1024);
+ info = mallinfo2();
+ return info.hblks;
+#else
struct mallinfo info = { 0 };
// use 1024 * 1024 to ensure memory allo from mmap
test = malloc(1024 * 1024);
info = mallinfo();
return info.hblks;
+#endif
}
TEST(autocleanup_testcase, test__isula_auto_free)
{
+#if defined(__GLIBC__) && ((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 33))
+ struct mallinfo2 before;
+ struct mallinfo2 after;
+ size_t used;
+
+ before = mallinfo2();
+ used = do_auto_free();
+ after = mallinfo2();
+#else
struct mallinfo before;
struct mallinfo after;
size_t used;
@@ -122,6 +140,7 @@ TEST(autocleanup_testcase, test__isula_auto_free)
before = mallinfo();
used = do_auto_free();
after = mallinfo();
+#endif
ASSERT_EQ(0, after.hblks);
ASSERT_NE(used, after.hblks);
ASSERT_NE(used, before.hblks);
diff --git a/tests/utils_buffer_ut.cpp b/tests/utils_buffer_ut.cpp
new file mode 100644
index 0000000..3cc95a6
--- /dev/null
+++ b/tests/utils_buffer_ut.cpp
@@ -0,0 +1,213 @@
+/******************************************************************************
+ * iSula-libutils: ut for utils_buffer.c
+ *
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
+ *
+ * Authors:
+ * Haozi007 <liuhao27@huawei.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ********************************************************************************/
+
+#include <gtest/gtest.h>
+
+#include <iostream>
+#include <string.h>
+
+#include "utils_buffer.h"
+
+TEST(isula_buffer_testcase, test__isula_buffer_alloc)
+{
+ isula_buffer *ib = nullptr;
+
+ ib = isula_buffer_alloc(0);
+ ASSERT_EQ(ib, nullptr);
+
+ ib = isula_buffer_alloc(SIZE_MAX);
+ ASSERT_EQ(ib, nullptr);
+
+ ib = isula_buffer_alloc(1);
+ ASSERT_NE(ib, nullptr);
+ ASSERT_NE(ib->contents, nullptr);
+ ASSERT_EQ(ib->bytes_used, 0);
+ ASSERT_EQ(ib->total_size, 1);
+
+ isula_buffer_free(ib);
+ ib = nullptr;
+
+ // check nullptr input, donot coredump
+ isula_buffer_free(ib);
+}
+
+TEST(isula_buffer_testcase, test__isula_buffer_nappend)
+{
+ isula_buffer *ib = nullptr;
+ int ret;
+ const size_t initSize = 8;
+
+ ib = isula_buffer_alloc(initSize);
+ ASSERT_NE(ib, nullptr);
+ ASSERT_NE(ib->contents, nullptr);
+ ASSERT_EQ(ib->bytes_used, 0);
+ ASSERT_EQ(ib->total_size, initSize);
+
+ ret = ib->nappend(nullptr, 1, "hello");
+ ASSERT_NE(ret, 0);
+ ret = ib->nappend(ib, SIZE_MAX, "hello");
+ ASSERT_NE(ret, 0);
+ ret = ib->nappend(ib, 0, "hello");
+ ASSERT_EQ(ret, 0);
+ ASSERT_EQ(ib->bytes_used, 0);
+ ret = ib->nappend(ib, 1, nullptr);
+ ASSERT_EQ(ret, 0);
+ ASSERT_EQ(ib->bytes_used, 0);
+ ret = ib->nappend(ib, 6, "hello");
+ ASSERT_EQ(ret, 0);
+ ASSERT_EQ(ib->bytes_used, 5);
+ ASSERT_EQ(ib->total_size, initSize);
+ ASSERT_STREQ(ib->contents, "hello");
+ ret = ib->nappend(ib, 7, " world");
+ ASSERT_EQ(ret, 0);
+ ASSERT_EQ(ib->bytes_used, 11);
+ ASSERT_EQ(ib->total_size, initSize * 2);
+ ASSERT_STREQ(ib->contents, "hello world");
+
+ ib->clear(ib);
+ ASSERT_EQ(ib->bytes_used, 0);
+
+ ret = ib->nappend(ib, 10, "hello %s", "world");
+ ASSERT_EQ(ret, 0);
+ ASSERT_EQ(ib->bytes_used, 10);
+ ASSERT_EQ(ib->total_size, initSize * 2);
+ ASSERT_STREQ(ib->contents, "hello worl");
+
+ isula_buffer_free(ib);
+ ib = nullptr;
+}
+
+
+TEST(isula_buffer_testcase, test__isula_buffer_append)
+{
+ isula_buffer *ib = nullptr;
+ int ret;
+ const size_t initSize = 8;
+
+ ib = isula_buffer_alloc(initSize);
+ ASSERT_NE(ib, nullptr);
+ ASSERT_NE(ib->contents, nullptr);
+ ASSERT_EQ(ib->bytes_used, 0);
+ ASSERT_EQ(ib->total_size, initSize);
+
+ ret = ib->append(nullptr, "hello");
+ ASSERT_NE(ret, 0);
+ ret = ib->append(ib, nullptr);
+ ASSERT_EQ(ret, 0);
+ ret = ib->append(ib, "");
+ ASSERT_EQ(ret, 0);
+ ASSERT_EQ(ib->bytes_used, 0);
+ ret = ib->append(ib, "hello");
+ ASSERT_EQ(ret, 0);
+ ASSERT_EQ(ib->bytes_used, 5);
+ ASSERT_EQ(ib->total_size, initSize);
+ ASSERT_STREQ(ib->contents, "hello");
+ ret = ib->append(ib, " world");
+ ASSERT_EQ(ret, 0);
+ ASSERT_EQ(ib->bytes_used, 11);
+ ASSERT_EQ(ib->total_size, initSize * 2);
+ ASSERT_STREQ(ib->contents, "hello world");
+
+ isula_buffer_free(ib);
+ ib = nullptr;
+}
+
+TEST(isula_buffer_testcase, test__isula_buffer_to_str)
+{
+ isula_buffer *ib = nullptr;
+ int ret;
+ const size_t initSize = 8;
+ char *tmpStr = nullptr;
+
+ ib = isula_buffer_alloc(initSize);
+ ASSERT_NE(ib, nullptr);
+ ASSERT_NE(ib->contents, nullptr);
+ ASSERT_EQ(ib->bytes_used, 0);
+ ASSERT_EQ(ib->total_size, initSize);
+
+ tmpStr = ib->to_str(nullptr);
+ ASSERT_EQ(tmpStr, nullptr);
+ tmpStr = ib->to_str(ib);
+ ASSERT_NE(tmpStr, nullptr);
+ ASSERT_STREQ(tmpStr, "");
+ free(tmpStr);
+
+ ret = ib->nappend(ib, 5, "hello");
+ ASSERT_EQ(ret, 0);
+ ASSERT_EQ(ib->bytes_used, 5);
+ ASSERT_EQ(ib->total_size, initSize);
+ ASSERT_STREQ(ib->contents, "hello");
+ tmpStr = ib->to_str(ib);
+ ASSERT_NE(tmpStr, nullptr);
+ ASSERT_STREQ(tmpStr, "hello");
+ free(tmpStr);
+
+ ret = ib->nappend(ib, 6, " world");
+ ASSERT_EQ(ret, 0);
+ ASSERT_EQ(ib->bytes_used, 11);
+ ASSERT_EQ(ib->total_size, initSize * 2);
+ ASSERT_STREQ(ib->contents, "hello world");
+ tmpStr = ib->to_str(ib);
+ ASSERT_NE(tmpStr, nullptr);
+ ASSERT_STREQ(tmpStr, "hello world");
+ free(tmpStr);
+
+ isula_buffer_free(ib);
+ ib = nullptr;
+}
+
+TEST(isula_buffer_testcase, test__isula_buffer_clear)
+{
+ isula_buffer *ib = nullptr;
+ int ret;
+ const size_t initSize = 8;
+ char *tmpStr = nullptr;
+
+ ib = isula_buffer_alloc(initSize);
+ ASSERT_NE(ib, nullptr);
+ ASSERT_NE(ib->contents, nullptr);
+ ASSERT_EQ(ib->bytes_used, 0);
+ ASSERT_EQ(ib->total_size, initSize);
+
+ ret = ib->nappend(ib, 5, "hello");
+ ASSERT_EQ(ret, 0);
+ ASSERT_EQ(ib->bytes_used, 5);
+ ASSERT_EQ(ib->length(ib), 5);
+ ASSERT_EQ(ib->total_size, initSize);
+ ASSERT_STREQ(ib->contents, "hello");
+ tmpStr = ib->to_str(ib);
+ ASSERT_NE(tmpStr, nullptr);
+ ASSERT_STREQ(tmpStr, "hello");
+ free(tmpStr);
+ ib->clear(ib);
+ ASSERT_NE(ib, nullptr);
+ ASSERT_NE(ib->contents, nullptr);
+ ASSERT_EQ(ib->length(ib), 0);
+ ASSERT_EQ(ib->total_size, initSize);
+
+ ib->clear(nullptr);
+ ASSERT_EQ(ib->length(nullptr), 0);
+
+ isula_buffer_free(ib);
+ ib = nullptr;
+}
\ No newline at end of file
--
2.34.1