iSulad/0032-add-ut-for-devicemapper.patch

738 lines
31 KiB
Diff
Raw Normal View History

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