diff options
Diffstat (limited to '0032-add-ut-for-devicemapper.patch')
-rw-r--r-- | 0032-add-ut-for-devicemapper.patch | 737 |
1 files changed, 737 insertions, 0 deletions
diff --git a/0032-add-ut-for-devicemapper.patch b/0032-add-ut-for-devicemapper.patch new file mode 100644 index 0000000..e28c5fa --- /dev/null +++ b/0032-add-ut-for-devicemapper.patch @@ -0,0 +1,737 @@ +From ca297d26dc1e7b47d6987c6bbbd92dd2e3d78670 Mon Sep 17 00:00:00 2001 +From: jikai <jikai11@huawei.com> +Date: Wed, 22 Nov 2023 22:05:04 +0800 +Subject: [PATCH 32/64] add ut for devicemapper + +Signed-off-by: jikai <jikai11@huawei.com> +--- + test/image/oci/storage/layers/CMakeLists.txt | 2 + + .../storage/layers/devmapper/CMakeLists.txt | 71 +++++ + ...9702e4bd316dd50ae85467b0378a419b23b60ba73d | 6 + + ...a9fb83febf6dc0b1548dfe896161533668281c9f4f | 6 + + ...0a625721fdbea5c94ca6da897acdd814d710149770 | 6 + + .../devmapper/data/devicemapper/metadata/base | 7 + + .../devicemapper/metadata/deviceset-metadata | 5 + + .../metadata/transaction-metadata | 5 + + .../layers/devmapper/driver_devmapper_ut.cc | 283 ++++++++++++++++++ + test/mocks/libdevmapper_mock.cc | 191 ++++++++++++ + test/mocks/libdevmapper_mock.h | 52 ++++ + 11 files changed, 634 insertions(+) + create mode 100644 test/image/oci/storage/layers/devmapper/CMakeLists.txt + create mode 100644 test/image/oci/storage/layers/devmapper/data/devicemapper/metadata/068615102be4457b22d40c9702e4bd316dd50ae85467b0378a419b23b60ba73d + create mode 100644 test/image/oci/storage/layers/devmapper/data/devicemapper/metadata/3d24ee258efc3bfe4066a1a9fb83febf6dc0b1548dfe896161533668281c9f4f + create mode 100644 test/image/oci/storage/layers/devmapper/data/devicemapper/metadata/ba0dae6243cc9fa2890df40a625721fdbea5c94ca6da897acdd814d710149770 + create mode 100644 test/image/oci/storage/layers/devmapper/data/devicemapper/metadata/base + create mode 100644 test/image/oci/storage/layers/devmapper/data/devicemapper/metadata/deviceset-metadata + create mode 100644 test/image/oci/storage/layers/devmapper/data/devicemapper/metadata/transaction-metadata + create mode 100644 test/image/oci/storage/layers/devmapper/driver_devmapper_ut.cc + create mode 100644 test/mocks/libdevmapper_mock.cc + create mode 100644 test/mocks/libdevmapper_mock.h + +diff --git a/test/image/oci/storage/layers/CMakeLists.txt b/test/image/oci/storage/layers/CMakeLists.txt +index 413a8b38..e1c76453 100644 +--- a/test/image/oci/storage/layers/CMakeLists.txt ++++ b/test/image/oci/storage/layers/CMakeLists.txt +@@ -1,5 +1,7 @@ + project(iSulad_UT) + ++add_subdirectory(devmapper) ++ + # storage_driver_ut + SET(DRIVER_EXE storage_driver_ut) + +diff --git a/test/image/oci/storage/layers/devmapper/CMakeLists.txt b/test/image/oci/storage/layers/devmapper/CMakeLists.txt +new file mode 100644 +index 00000000..f98de1a8 +--- /dev/null ++++ b/test/image/oci/storage/layers/devmapper/CMakeLists.txt +@@ -0,0 +1,71 @@ ++project(iSulad_UT) ++ ++# driver_devmapper_ut ++SET(DRIVER_DEVMAPPER_EXE driver_devmapper_ut) ++ ++add_executable(${DRIVER_DEVMAPPER_EXE} ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/utils/cutils/utils.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/utils/cutils/utils_regex.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/utils/cutils/utils_verify.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/utils/cutils/utils_array.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/utils/cutils/utils_string.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/utils/cutils/utils_convert.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/utils/cutils/utils_file.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/utils/cutils/utils_fs.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/utils/cutils/util_atomic.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/utils/cutils/utils_base64.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/utils/cutils/utils_timestamp.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/utils/cutils/path.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/utils/cutils/map/map.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/utils/cutils/map/rb_tree.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/utils/buffer/buffer.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/utils/tar/util_archive.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/utils/tar/util_gzip.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/utils/sha256/sha256.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/daemon/config/daemon_arguments.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/daemon/config/isulad_config.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/daemon/common/err_msg.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/daemon/common/selinux_label.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper/deviceset.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper/driver_devmapper.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper/metadata_store.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper/wrapper_devmapper.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../mocks/libdevmapper_mock.cc ++ driver_devmapper_ut.cc) ++ ++target_include_directories(${DRIVER_DEVMAPPER_EXE} PUBLIC ++ ${GTEST_INCLUDE_DIR} ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../include ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/common ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/utils/tar ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/utils/cutils ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/utils/cutils/map ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/utils/sha256 ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/utils/console ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/utils/buffer ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/daemon/config ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/daemon/common ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/daemon/modules/api ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/daemon/modules/image ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/daemon/modules/image/oci/storage ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/daemon/modules/image/oci/storage/layer_store/graphdriver ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2 ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/daemon/modules/image/oci/storage/remote_layer_support ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../src/daemon/modules/image/oci/storage/layer_store/graphdriver/quota ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../mocks ++ ) ++ ++set_target_properties(${DRIVER_DEVMAPPER_EXE} PROPERTIES LINK_FLAGS "-Wl,--wrap,util_exec_cmd -Wl,--wrap,util_mount -Wl,--wrap,umount2") ++ ++target_link_libraries(${DRIVER_DEVMAPPER_EXE} ++ ${GTEST_BOTH_LIBRARIES} ++ ${GMOCK_LIBRARY} ++ ${GMOCK_MAIN_LIBRARY} ++ ${CMAKE_THREAD_LIBS_INIT} ++ ${ISULA_LIBUTILS_LIBRARY} ++ ${LIBTAR_LIBRARY} ++ -lcrypto -lyajl -larchive ${SELINUX_LIBRARY} -lz -lcap) ++ ++add_test(NAME ${DRIVER_DEVMAPPER_EXE} COMMAND ${DRIVER_DEVMAPPER_EXE} --gtest_output=xml:${DRIVER_DEVMAPPER_EXE}-Results.xml) ++set_tests_properties(${DRIVER_DEVMAPPER_EXE} PROPERTIES TIMEOUT 120) +diff --git a/test/image/oci/storage/layers/devmapper/data/devicemapper/metadata/068615102be4457b22d40c9702e4bd316dd50ae85467b0378a419b23b60ba73d b/test/image/oci/storage/layers/devmapper/data/devicemapper/metadata/068615102be4457b22d40c9702e4bd316dd50ae85467b0378a419b23b60ba73d +new file mode 100644 +index 00000000..f51ae926 +--- /dev/null ++++ b/test/image/oci/storage/layers/devmapper/data/devicemapper/metadata/068615102be4457b22d40c9702e4bd316dd50ae85467b0378a419b23b60ba73d +@@ -0,0 +1,6 @@ ++{ ++ "hash": "068615102be4457b22d40c9702e4bd316dd50ae85467b0378a419b23b60ba73d", ++ "device_id": 6, ++ "size": 10737418240, ++ "transaction_id": 8 ++} +diff --git a/test/image/oci/storage/layers/devmapper/data/devicemapper/metadata/3d24ee258efc3bfe4066a1a9fb83febf6dc0b1548dfe896161533668281c9f4f b/test/image/oci/storage/layers/devmapper/data/devicemapper/metadata/3d24ee258efc3bfe4066a1a9fb83febf6dc0b1548dfe896161533668281c9f4f +new file mode 100644 +index 00000000..de727a79 +--- /dev/null ++++ b/test/image/oci/storage/layers/devmapper/data/devicemapper/metadata/3d24ee258efc3bfe4066a1a9fb83febf6dc0b1548dfe896161533668281c9f4f +@@ -0,0 +1,6 @@ ++{ ++ "hash": "3d24ee258efc3bfe4066a1a9fb83febf6dc0b1548dfe896161533668281c9f4f", ++ "device_id": 4, ++ "size": 10737418240, ++ "transaction_id": 4 ++} +diff --git a/test/image/oci/storage/layers/devmapper/data/devicemapper/metadata/ba0dae6243cc9fa2890df40a625721fdbea5c94ca6da897acdd814d710149770 b/test/image/oci/storage/layers/devmapper/data/devicemapper/metadata/ba0dae6243cc9fa2890df40a625721fdbea5c94ca6da897acdd814d710149770 +new file mode 100644 +index 00000000..e1e8988e +--- /dev/null ++++ b/test/image/oci/storage/layers/devmapper/data/devicemapper/metadata/ba0dae6243cc9fa2890df40a625721fdbea5c94ca6da897acdd814d710149770 +@@ -0,0 +1,6 @@ ++{ ++ "hash": "ba0dae6243cc9fa2890df40a625721fdbea5c94ca6da897acdd814d710149770", ++ "device_id": 2, ++ "size": 10737418240, ++ "transaction_id": 2 ++} +diff --git a/test/image/oci/storage/layers/devmapper/data/devicemapper/metadata/base b/test/image/oci/storage/layers/devmapper/data/devicemapper/metadata/base +new file mode 100644 +index 00000000..2412113d +--- /dev/null ++++ b/test/image/oci/storage/layers/devmapper/data/devicemapper/metadata/base +@@ -0,0 +1,7 @@ ++{ ++ "hash": "base", ++ "device_id": 1, ++ "size": 10737418240, ++ "transaction_id": 1, ++ "initialized": true ++} +diff --git a/test/image/oci/storage/layers/devmapper/data/devicemapper/metadata/deviceset-metadata b/test/image/oci/storage/layers/devmapper/data/devicemapper/metadata/deviceset-metadata +new file mode 100644 +index 00000000..94f7a6a3 +--- /dev/null ++++ b/test/image/oci/storage/layers/devmapper/data/devicemapper/metadata/deviceset-metadata +@@ -0,0 +1,5 @@ ++{ ++ "next_device_id": 7, ++ "BaseDeviceFilesystem": "ext4", ++ "BaseDeviceUUID": "4fa22307-0c88-4fa4-8f16-a9459e9cbc4a" ++} +diff --git a/test/image/oci/storage/layers/devmapper/data/devicemapper/metadata/transaction-metadata b/test/image/oci/storage/layers/devmapper/data/devicemapper/metadata/transaction-metadata +new file mode 100644 +index 00000000..a011249a +--- /dev/null ++++ b/test/image/oci/storage/layers/devmapper/data/devicemapper/metadata/transaction-metadata +@@ -0,0 +1,5 @@ ++{ ++ "open_transaction_id": 8, ++ "device_hash": "068615102be4457b22d40c9702e4bd316dd50ae85467b0378a419b23b60ba73d", ++ "device_id": 6 ++} +diff --git a/test/image/oci/storage/layers/devmapper/driver_devmapper_ut.cc b/test/image/oci/storage/layers/devmapper/driver_devmapper_ut.cc +new file mode 100644 +index 00000000..59e53f97 +--- /dev/null ++++ b/test/image/oci/storage/layers/devmapper/driver_devmapper_ut.cc +@@ -0,0 +1,283 @@ ++/****************************************************************************** ++ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. ++ * iSulad licensed under the Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++ * PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ * Author: jikai ++ * Create: 2023-11-22 ++ * Description: provide oci storage driver unit test for devmapper ++ ******************************************************************************/ ++ ++#include <gtest/gtest.h> ++#include <gmock/gmock.h> ++ ++#include "driver_devmapper.h" ++#include "mock.h" ++#include "path.h" ++#include "utils.h" ++#include "libdevmapper_mock.h" ++ ++using ::testing::Invoke; ++using ::testing::NiceMock; ++using ::testing::Return; ++using ::testing::_; ++ ++extern "C" { ++ DECLARE_WRAPPER_V(util_exec_cmd, bool, (exec_func_t cb_func, void *args, const char *stdin_msg, char **stdout_msg, char **stderr_msg)); ++ DEFINE_WRAPPER_V(util_exec_cmd, bool, (exec_func_t cb_func, void *args, const char *stdin_msg, char **stdout_msg, char **stderr_msg), (cb_func, args, stdin_msg, stdout_msg, stderr_msg)); ++ ++ DECLARE_WRAPPER(util_mount, int, (const char *src, const char *dst, const char *mtype, const char *mntopts)); ++ DEFINE_WRAPPER(util_mount, int, (const char *src, const char *dst, const char *mtype, const char *mntopts), (src, dst, mtype, mntopts)); ++ ++ DECLARE_WRAPPER(umount2, int, (const char *__special_file, int __flags)); ++ DEFINE_WRAPPER(umount2, int, (const char *__special_file, int __flags), (__special_file, __flags)); ++} ++ ++static std::string GetDirectory() ++{ ++ char abs_path[PATH_MAX] { 0x00 }; ++ int ret = readlink("/proc/self/exe", abs_path, sizeof(abs_path)); ++ if (ret < 0 || static_cast<size_t>(ret) >= sizeof(abs_path)) { ++ return ""; ++ } ++ ++ for (int i { ret }; i >= 0; --i) { ++ if (abs_path[i] == '/') { ++ abs_path[i + 1] = '\0'; ++ break; ++ } ++ } ++ ++ return static_cast<std::string>(abs_path) + "../../../../../../../test/image/oci/storage/layers/devmapper"; ++} ++ ++static bool invokeUtilExecCmd(exec_func_t cb_func, void *args, const char *stdin_msg, char **stdout_msg, char **stderr_msg) ++{ ++ if (cb_func == nullptr || args == nullptr || stdout_msg == nullptr || stderr_msg == nullptr) { ++ return false; ++ } ++ ++ char **tmp_args = static_cast<char **>(args); ++ ++ if (util_array_len((const char **)tmp_args) < 1) { ++ return false; ++ } ++ ++ if (strcmp(tmp_args[0], "blkid") == 0) { ++ *stdout_msg = util_strdup_s("4fa22307-0c88-4fa4-8f16-a9459e9cbc4a"); ++ } ++ return true; ++} ++ ++static struct dm_task *invokeDMTaskCreate(int type) { ++ return static_cast<struct dm_task *>(util_common_calloc_s(sizeof(0))); ++} ++ ++static void invokeDMTaskDestroy(struct dm_task *task) { ++ free(task); ++ return; ++} ++ ++static int invokeDMTaskGetDriverVersion(struct dm_task *task, char *version, size_t size) { ++ if (task == nullptr || version == nullptr || strncpy(version, "4.27.0", size) == NULL) { ++ return 0; ++ } ++ ++ return 1; ++} ++ ++static int invokeDMTaskGetInfo(struct dm_task *task, struct dm_info *dmi) { ++ if (task == nullptr || dmi == nullptr) { ++ return 0; ++ } ++ ++ dmi->exists = 1; ++ return 1; ++} ++ ++static void *invokeDMGetNextTarget(struct dm_task *task, void *next, uint64_t *start, uint64_t *length, ++ char **target_type, char **params) { ++ static char type[] = "thin-pool"; ++ static char par[] = "0 0/1024 0/1024"; ++ if (target_type) { ++ *target_type = type; ++ } ++ if (params) { ++ *params = par; ++ } ++ return nullptr; ++} ++ ++class DriverDevmapperUnitTest : public testing::Test { ++protected: ++ void SetUp() override ++ { ++ MockLibdevmapper_SetMock(&m_libdevmapper_mock); ++ std::string isulad_dir { "/tmp/isulad/" }; ++ mkdir(isulad_dir.c_str(), 0755); ++ std::string root_dir = isulad_dir + "data"; ++ std::string run_dir = isulad_dir + "data/run"; ++ std::string data_dir = GetDirectory() + "/data"; ++ std::string driver_home = root_dir + "/devicemapper"; ++ ++ ASSERT_STRNE(util_clean_path(data_dir.c_str(), data_path, sizeof(data_path)), nullptr); ++ std::string cp_command = "cp -r " + std::string(data_path) + " " + isulad_dir; ++ ASSERT_EQ(system(cp_command.c_str()), 0); ++ ++ char **driver_opts = static_cast<char **>(util_common_calloc_s(3 * sizeof(char *))); ++ driver_opts[0] = strdup("dm.thinpooldev=/dev/mapper/isulad0-thinpool"); ++ driver_opts[1] = strdup("dm.fs=ext4"); ++ driver_opts[2] = strdup("dm.min_free_space=10%"); ++ int driver_opts_len = 3; ++ ++ ASSERT_EQ(devmapper_init(&driver, nullptr, (const char **)driver_opts, driver_opts_len), -1); ++ ++ EXPECT_CALL(m_libdevmapper_mock, DMTaskCreate(_)).WillRepeatedly(Invoke(invokeDMTaskCreate)); ++ EXPECT_CALL(m_libdevmapper_mock, DMTaskSetMessage(_, _)).WillRepeatedly(Return(1)); ++ EXPECT_CALL(m_libdevmapper_mock, DMTaskSetSector(_, _)).WillRepeatedly(Return(1)); ++ EXPECT_CALL(m_libdevmapper_mock, DMTaskSetAddNode(_, _)).WillRepeatedly(Return(1)); ++ EXPECT_CALL(m_libdevmapper_mock, DMTaskAddTarget(_, _, _, _, _)).WillRepeatedly(Return(1)); ++ EXPECT_CALL(m_libdevmapper_mock, DMTaskSetName(_, _)).WillRepeatedly(Return(1)); ++ EXPECT_CALL(m_libdevmapper_mock, DMTaskRun(_)).WillRepeatedly(Return(1)); ++ EXPECT_CALL(m_libdevmapper_mock, DMTaskDestroy(_)).WillRepeatedly(Invoke(invokeDMTaskDestroy)); ++ EXPECT_CALL(m_libdevmapper_mock, DMTaskGetInfo(_, _)).WillRepeatedly(Invoke(invokeDMTaskGetInfo)); ++ EXPECT_CALL(m_libdevmapper_mock, DMGetNextTarget(_, _, _, _, _, _)).WillRepeatedly(Invoke(invokeDMGetNextTarget)); ++ EXPECT_CALL(m_libdevmapper_mock, DMTaskSetCookie(_, _, _)).WillRepeatedly(Return(1)); ++ EXPECT_CALL(m_libdevmapper_mock, DMUdevWait(_)).WillRepeatedly(Return(1)); ++ EXPECT_CALL(m_libdevmapper_mock, DMUdevComplete(_)).WillRepeatedly(Return(1)); ++ EXPECT_CALL(m_libdevmapper_mock, DMTaskDeferredRemove(_)).WillRepeatedly(Return(1)); ++ ++ ++ char *names = static_cast<char *>(util_common_calloc_s(sizeof(struct dm_names) + strlen("isulad0-pool") + 1)); ++ struct dm_names *dname = (struct dm_names *)names; ++ dname->dev = 1; ++ dname->next = 0; ++ strcpy(names + sizeof(struct dm_names), "isulad0-pool"); ++ EXPECT_CALL(m_libdevmapper_mock, DMTaskGetNames(_)).WillOnce(Return(dname)); ++ EXPECT_CALL(m_libdevmapper_mock, DMSetDevDir(_)).WillOnce(Return(1)); ++ EXPECT_CALL(m_libdevmapper_mock, DMTaskGetDriverVersion(_, _, _)).WillOnce(Invoke(invokeDMTaskGetDriverVersion)); ++ EXPECT_CALL(m_libdevmapper_mock, DMUdevGetSyncSupport()).WillOnce(Return(1)); ++ ++ MOCK_SET_V(util_exec_cmd, invokeUtilExecCmd); ++ ++ ASSERT_EQ(devmapper_init(&driver, driver_home.c_str(), (const char **)driver_opts, driver_opts_len), 0); ++ MOCK_CLEAR(util_exec_cmd); ++ ++ util_free_array_by_len(driver_opts, driver_opts_len); ++ free(names); ++ } ++ ++ void TearDown() override ++ { ++ MockLibdevmapper_SetMock(nullptr); ++ std::string rm_command = "rm -rf /tmp/isulad/"; ++ ASSERT_EQ(system(rm_command.c_str()), 0); ++ } ++ ++ NiceMock<MockLibdevmapper> m_libdevmapper_mock; ++ char data_path[PATH_MAX] = { 0x00 }; ++ graphdriver driver = {.ops = nullptr, .name = "devicemapper", }; ++}; ++ ++TEST_F(DriverDevmapperUnitTest, test_devmapper_layer_exists) ++{ ++ std::string id { "3d24ee258efc3bfe4066a1a9fb83febf6dc0b1548dfe896161533668281c9f4f" }; ++ std::string incorrectId { "eb29745b8228e1e97c01b1d5c2554a319c00a94d8dd5746a3904222ad65a13f8" }; ++ ASSERT_TRUE(devmapper_layer_exist(id.c_str(), &driver)); ++ ASSERT_FALSE(devmapper_layer_exist(incorrectId.c_str(), &driver)); ++} ++ ++TEST_F(DriverDevmapperUnitTest, test_devmapper_create_rw) ++{ ++ std::string id { "eb29745b8228e1e97c01b1d5c2554a319c00a94d8dd5746a3904222ad65a13f8" }; ++ struct driver_create_opts *create_opts; ++ ++ create_opts = (struct driver_create_opts *)util_common_calloc_s(sizeof(struct driver_create_opts)); ++ ASSERT_NE(create_opts, nullptr); ++ ++ create_opts->storage_opt = static_cast<json_map_string_string *>(util_common_calloc_s(sizeof(json_map_string_string))); ++ ASSERT_NE(create_opts->storage_opt, nullptr); ++ create_opts->storage_opt->keys = static_cast<char **>(util_common_calloc_s(sizeof(char *))); ++ create_opts->storage_opt->values = static_cast<char **>(util_common_calloc_s(sizeof(char *))); ++ create_opts->storage_opt->keys[0] = strdup("size"); ++ create_opts->storage_opt->values[0] = strdup("10G"); ++ create_opts->storage_opt->len = 1; ++ ++ ASSERT_EQ(devmapper_create_rw(id.c_str(), nullptr, &driver, create_opts), 0); ++ ASSERT_TRUE(devmapper_layer_exist(id.c_str(), &driver)); ++} ++ ++TEST_F(DriverDevmapperUnitTest, test_devmapper_mount_layer) ++{ ++ std::string id { "3d24ee258efc3bfe4066a1a9fb83febf6dc0b1548dfe896161533668281c9f4f" }; ++ std::string merged_dir = "/tmp/isulad/data/devicemapper/mnt/" + id + "/rootfs"; ++ struct driver_mount_opts *mount_opts = nullptr; ++ char* mount_dir = nullptr; ++ ++ MOCK_SET(util_mount, 0); ++ mount_dir = devmapper_mount_layer(id.c_str(), &driver, mount_opts); ++ ASSERT_STREQ(mount_dir, merged_dir.c_str()); ++ MOCK_CLEAR(util_mount); ++ ++ MOCK_SET(umount2, 0); ++ ASSERT_EQ(devmapper_umount_layer(id.c_str(), &driver), 0); ++ MOCK_CLEAR(umount2); ++ free(mount_dir); ++ mount_dir = nullptr; ++ ++ mount_opts = static_cast<struct driver_mount_opts *>(util_common_calloc_s(sizeof(struct driver_mount_opts))); ++ ASSERT_NE(mount_opts, nullptr); ++ mount_opts->options = static_cast<char **>(util_common_calloc_s(1 * sizeof(char *))); ++ mount_opts->options[0] = strdup("ro"); ++ mount_opts->options_len = 1; ++ ++ MOCK_SET(util_mount, 0); ++ mount_dir = devmapper_mount_layer(id.c_str(), &driver, mount_opts); ++ ASSERT_STREQ(mount_dir, merged_dir.c_str()); ++ MOCK_CLEAR(util_mount); ++ ++ MOCK_SET(umount2, 0); ++ ASSERT_EQ(devmapper_umount_layer(id.c_str(), &driver), 0); ++ MOCK_CLEAR(umount2); ++ free(mount_opts->mount_label); ++ util_free_array_by_len(mount_opts->options, mount_opts->options_len); ++ free(mount_opts); ++ free(mount_dir); ++} ++ ++TEST_F(DriverDevmapperUnitTest, test_devmapper_get_layer_metadata) ++{ ++ std::string id { "3d24ee258efc3bfe4066a1a9fb83febf6dc0b1548dfe896161533668281c9f4f" }; ++ json_map_string_string *map_info = static_cast<json_map_string_string *>(util_common_calloc_s(sizeof(json_map_string_string))); ++ ++ ASSERT_EQ(devmapper_get_layer_metadata(id.c_str(), &driver, map_info), 0); ++ ASSERT_EQ(map_info->len, 4); ++ ASSERT_STREQ(map_info->keys[0], "DeviceId"); ++ ASSERT_STREQ(map_info->values[0], "4"); ++ ASSERT_STREQ(map_info->keys[1], "DeviceSize"); ++ ASSERT_STREQ(map_info->values[1], "10737418240"); ++ ASSERT_STREQ(map_info->keys[2], "DeviceName"); ++ ASSERT_STREQ(map_info->keys[3], "MergedDir"); ++ ASSERT_STREQ(map_info->values[3], "/tmp/isulad/data/devicemapper/mnt/3d24ee258efc3bfe4066a1a9fb83febf6dc0b1548dfe896161533668281c9f4f/rootfs"); ++ ++ free_json_map_string_string(map_info); ++} ++ ++TEST_F(DriverDevmapperUnitTest, test_devmapper_get_driver_status) ++{ ++ struct graphdriver_status *status = static_cast<struct graphdriver_status *>(util_common_calloc_s(sizeof(struct graphdriver_status))); ++ ++ EXPECT_CALL(m_libdevmapper_mock, DMUdevGetSyncSupport()).WillOnce(Return(1)); ++ ++ ASSERT_EQ(devmapper_get_driver_status(&driver, status), 0); ++ ASSERT_STREQ(status->driver_name, "devicemapper"); ++ free(status->driver_name); ++ free(status->backing_fs); ++ free(status->status); ++ free(status); ++} +diff --git a/test/mocks/libdevmapper_mock.cc b/test/mocks/libdevmapper_mock.cc +new file mode 100644 +index 00000000..7d6c8024 +--- /dev/null ++++ b/test/mocks/libdevmapper_mock.cc +@@ -0,0 +1,191 @@ ++/****************************************************************************** ++ * Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved. ++ * iSulad licensed under the Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++ * PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ * Author: jikai ++ * Create: 2023-11-22 ++ * Description: provide lib device mapper mock ++ ******************************************************************************/ ++ ++#include "libdevmapper_mock.h" ++ ++namespace { ++MockLibdevmapper *g_libdevmapper_mock = nullptr; ++} ++ ++void MockLibdevmapper_SetMock(MockLibdevmapper* mock) ++{ ++ g_libdevmapper_mock = mock; ++} ++ ++struct dm_task *dm_task_create(int type) ++{ ++ if (g_libdevmapper_mock != nullptr) { ++ return g_libdevmapper_mock->DMTaskCreate(type); ++ } ++ return nullptr; ++} ++ ++int dm_task_set_message(struct dm_task *dmt, const char *msg) ++{ ++ if (g_libdevmapper_mock != nullptr) { ++ return g_libdevmapper_mock->DMTaskSetMessage(dmt, msg); ++ } ++ return 0; ++} ++ ++int dm_task_set_sector(struct dm_task *dmt, uint64_t sector) ++{ ++ if (g_libdevmapper_mock != nullptr) { ++ return g_libdevmapper_mock->DMTaskSetSector(dmt, sector); ++ } ++ return 0; ++} ++ ++int dm_task_set_add_node(struct dm_task *dmt, dm_add_node_t add_node) ++{ ++ if (g_libdevmapper_mock != nullptr) { ++ return g_libdevmapper_mock->DMTaskSetAddNode(dmt, add_node); ++ } ++ return 0; ++} ++ ++int dm_task_add_target(struct dm_task *dmt, uint64_t start, uint64_t size, const char *ttype, const char *params) ++{ ++ if (g_libdevmapper_mock != nullptr) { ++ return g_libdevmapper_mock->DMTaskAddTarget(dmt, start, size, ttype, params); ++ } ++ return 0; ++} ++ ++int dm_set_dev_dir(const char *dir) ++{ ++ if (g_libdevmapper_mock != nullptr) { ++ return g_libdevmapper_mock->DMSetDevDir(dir); ++ } ++ return 0; ++} ++ ++int dm_task_set_name(struct dm_task *dmt, const char *name) ++{ ++ if (g_libdevmapper_mock != nullptr) { ++ return g_libdevmapper_mock->DMTaskSetName(dmt, name); ++ } ++ return 0; ++} ++ ++int dm_task_run(struct dm_task *dmt) ++{ ++ if (g_libdevmapper_mock != nullptr) { ++ return g_libdevmapper_mock->DMTaskRun(dmt); ++ } ++ return 0; ++} ++ ++int dm_task_get_driver_version(struct dm_task *dmt, char *version, size_t size) ++{ ++ if (g_libdevmapper_mock != nullptr) { ++ return g_libdevmapper_mock->DMTaskGetDriverVersion(dmt, version, size); ++ } ++ return 0; ++} ++ ++void dm_task_destroy(struct dm_task *dmt) ++{ ++ if (g_libdevmapper_mock != nullptr) { ++ g_libdevmapper_mock->DMTaskDestroy(dmt); ++ } ++} ++ ++int dm_get_library_version(char *version, size_t size) ++{ ++ if (g_libdevmapper_mock != nullptr) { ++ return g_libdevmapper_mock->DMGetLibraryVersion(version, size); ++ } ++ return 0; ++} ++ ++int dm_task_get_info(struct dm_task *dmt, struct dm_info *info) ++{ ++ if (g_libdevmapper_mock != nullptr) { ++ return g_libdevmapper_mock->DMTaskGetInfo(dmt, info); ++ } ++ return 0; ++} ++ ++void *dm_get_next_target(struct dm_task *dmt, void *next, uint64_t *start, uint64_t *length, ++ char **target_type, char **params) ++{ ++ if (g_libdevmapper_mock != nullptr) { ++ return g_libdevmapper_mock->DMGetNextTarget(dmt, next, start, length, target_type, params); ++ } ++ return nullptr; ++} ++ ++int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie, uint16_t flags) ++{ ++ if (g_libdevmapper_mock != nullptr) { ++ return g_libdevmapper_mock->DMTaskSetCookie(dmt, cookie, flags); ++ } ++ return 0; ++} ++ ++int dm_udev_wait(uint32_t cookie) ++{ ++ if (g_libdevmapper_mock != nullptr) { ++ return g_libdevmapper_mock->DMUdevWait(cookie); ++ } ++ return 0; ++} ++ ++int dm_udev_complete(uint32_t cookie) ++{ ++ if (g_libdevmapper_mock != nullptr) { ++ return g_libdevmapper_mock->DMUdevComplete(cookie); ++ } ++ return 0; ++} ++ ++int dm_task_deferred_remove(struct dm_task *dmt) ++{ ++ if (g_libdevmapper_mock != nullptr) { ++ return g_libdevmapper_mock->DMTaskDeferredRemove(dmt); ++ } ++ return 0; ++} ++ ++struct dm_names *dm_task_get_names(struct dm_task *dmt) ++{ ++ if (g_libdevmapper_mock != nullptr) { ++ return g_libdevmapper_mock->DMTaskGetNames(dmt); ++ } ++ return nullptr; ++} ++ ++int dm_udev_get_sync_support(void) ++{ ++ if (g_libdevmapper_mock != nullptr) { ++ return g_libdevmapper_mock->DMUdevGetSyncSupport(); ++ } ++ return 0; ++} ++ ++void dm_udev_set_sync_support(int sync_with_udev) ++{ ++ if (g_libdevmapper_mock != nullptr) { ++ g_libdevmapper_mock->DMUdevSetSyncSupport(sync_with_udev); ++ } ++} ++ ++void dm_log_with_errno_init(void log_cb(int level, const char *file, int line, int dm_errno_or_class, const char *f, ...)) ++{ ++ if (g_libdevmapper_mock != nullptr) { ++ g_libdevmapper_mock->DMLogWithErrnoInit(log_cb); ++ } ++} +diff --git a/test/mocks/libdevmapper_mock.h b/test/mocks/libdevmapper_mock.h +new file mode 100644 +index 00000000..53c5ad4b +--- /dev/null ++++ b/test/mocks/libdevmapper_mock.h +@@ -0,0 +1,52 @@ ++/****************************************************************************** ++ * Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved. ++ * iSulad licensed under the Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++ * PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ * Author: jikai ++ * Create: 2023-11-22 ++ * Description: provide lib device mapper mock ++ ******************************************************************************/ ++ ++#ifndef _ISULAD_TEST_MOCKS_DEVMAPPER_MOCK_H ++#define _ISULAD_TEST_MOCKS_DEVMAPPER_MOCK_H ++ ++#include <gmock/gmock.h> ++ ++#include <libdevmapper.h> ++ ++class MockLibdevmapper { ++public: ++ virtual ~MockLibdevmapper() = default; ++ MOCK_METHOD1(DMTaskCreate, struct dm_task*(int type)); ++ MOCK_METHOD2(DMTaskSetMessage, int(struct dm_task *dmt, const char *msg)); ++ MOCK_METHOD2(DMTaskSetSector, int(struct dm_task *dmt, uint64_t sector)); ++ MOCK_METHOD2(DMTaskSetAddNode, int(struct dm_task *dmt, dm_add_node_t add_node)); ++ MOCK_METHOD5(DMTaskAddTarget, int(struct dm_task *dmt, uint64_t start, uint64_t size, const char *ttype, const char *params)); ++ MOCK_METHOD1(DMSetDevDir, int(const char *dir)); ++ MOCK_METHOD2(DMTaskSetName, int(struct dm_task *dmt, const char *name)); ++ MOCK_METHOD1(DMTaskRun, int(struct dm_task *dmt)); ++ MOCK_METHOD3(DMTaskGetDriverVersion, int(struct dm_task *dmt, char *version, size_t size)); ++ MOCK_METHOD1(DMTaskDestroy, void(struct dm_task *dmt)); ++ MOCK_METHOD2(DMGetLibraryVersion, int(char *version, size_t size)); ++ MOCK_METHOD2(DMTaskGetInfo, int(struct dm_task *dmt, struct dm_info *info)); ++ MOCK_METHOD6(DMGetNextTarget, void*(struct dm_task *dmt, void *next, uint64_t *start, uint64_t *length, ++ char **target_type, char **params)); ++ MOCK_METHOD3(DMTaskSetCookie, int(struct dm_task *dmt, uint32_t *cookie, uint16_t flags)); ++ MOCK_METHOD1(DMUdevWait, int(uint32_t cookie)); ++ MOCK_METHOD1(DMUdevComplete, int(uint32_t cookie)); ++ MOCK_METHOD1(DMTaskDeferredRemove, int(struct dm_task *dmt)); ++ MOCK_METHOD1(DMTaskGetNames, struct dm_names *(struct dm_task *dmt)); ++ MOCK_METHOD0(DMUdevGetSyncSupport, int(void)); ++ MOCK_METHOD1(DMUdevSetSyncSupport, void(int sync_with_udev)); ++ MOCK_METHOD1(DMLogWithErrnoInit, void(void log_cb(int level, const char *file, int line, int dm_errno_or_class, const char *f, ...))); ++}; ++ ++void MockLibdevmapper_SetMock(MockLibdevmapper* mock); ++ ++#endif +-- +2.42.0 + |