diff --git a/interfaces/innerkits/fs_manager/fstab_mount.c b/interfaces/innerkits/fs_manager/fstab_mount.c index 78020c87cb539b5fe637e11cebf716ebc51ef66e..217d3752b0aed6aaf3dabe278ee534b0407f5243 100755 --- a/interfaces/innerkits/fs_manager/fstab_mount.c +++ b/interfaces/innerkits/fs_manager/fstab_mount.c @@ -289,7 +289,7 @@ MountStatus GetMountStatusForMountPoint(const char *mp) return status; } -static int DoMountOneItem(FstabItem *item); +INIT_STATIC int DoMountOneItem(FstabItem *item); #define MAX_RESIZE_PARAM_NUM 20 static int DoResizeF2fs(FstabItem *item, const unsigned long long size) { @@ -434,7 +434,7 @@ static int Mount(const char *source, const char *target, const char *fsType, return rc; } -static int MountWithCheckpoint(const char *source, const char *target, const char *fsType, +INIT_STATIC int MountWithCheckpoint(const char *source, const char *target, const char *fsType, unsigned long flags, const char *data) { struct stat st = {}; @@ -457,7 +457,6 @@ static int MountWithCheckpoint(const char *source, const char *target, const cha char realData[FS_MANAGER_BUFFER_SIZE] = {0}; size_t bytes = snprintf_s(realData, FS_MANAGER_BUFFER_SIZE, FS_MANAGER_BUFFER_SIZE - 1, "%s,%s:%d%%", data, "checkpoint=disable", gcAllowance); - BEGET_ERROR_CHECK(bytes > 0, break, "build realData failed"); if (bytes <= 0) { BEGET_LOGE("build realData failed"); break; @@ -524,7 +523,7 @@ int GetCurrentSlot(void) return GetSlotInfoFromBootctrl(PARTITION_ACTIVE_SLOT_OFFSET, PARTITION_ACTIVE_SLOT_SIZE); } -static int GetDataWithoutCheckpoint(char *fsSpecificData, size_t fsSpecificDataSize, +INIT_STATIC int GetDataWithoutCheckpoint(char *fsSpecificData, size_t fsSpecificDataSize, char *checkpointData, size_t checkpointDataSize) { if (fsSpecificData == NULL || strstr(fsSpecificData, "checkpoint=disable") == NULL) { @@ -574,7 +573,7 @@ static int GetDataWithoutCheckpoint(char *fsSpecificData, size_t fsSpecificDataS return rc; } -static int DoMountOneItem(FstabItem *item) +INIT_STATIC int DoMountOneItem(FstabItem *item) { BEGET_LOGI("Mount device %s to %s", item->deviceName, item->mountPoint); unsigned long mountFlags; diff --git a/test/BUILD.gn b/test/BUILD.gn index 5b0fe408e4513712ed9f96fa43d34844297eaadf..b18aa1153269895e1a9e57b3e0a6662b649f30c5 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -25,6 +25,7 @@ group("testgroup") { "unittest:init_fshvb_unittest", "unittest:init_unittest", "unittest/single_test/init_firststage:init_firststage_unittest", + "unittest/single_test/fstab_mount:fstab_mount_unittest", ] } else { if (ohos_kernel_type == "liteos_a" || ohos_kernel_type == "linux") { diff --git a/test/unittest/single_test/fstab_mount/BUILD.gn b/test/unittest/single_test/fstab_mount/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..8edf40317a163eb640db77fb1edb59fc42c135d1 --- /dev/null +++ b/test/unittest/single_test/fstab_mount/BUILD.gn @@ -0,0 +1,66 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import("//base/startup/init/begetd.gni") +import("//build/test.gni") + +ohos_unittest("fstab_mount_unittest") { + module_out_path = "init/init" + include_dirs = [ + "//base/startup/init/test/unittest/single_test/fstab_mount/include", + "//base/startup/init/services/init/include", + "//base/startup/init/services/log", + "//base/startup/init/services/init/standard", + "//base/startup/init/interfaces/innerkits/include", + "//base/startup/init/ueventd/include", + "//base/startup/init/interfaces/innerkits/fs_manager/switch_root/include", + "//base/startup/init/interfaces/innerkits/init_module_engine/include", + "//base/startup/init/test/mock/libc/include" + ] + + sources = [ + "//base/startup/init/interfaces/innerkits/fs_manager/fstab_mount.c", + "//base/startup/init/test/unittest/single_test/fstab_mount/src/fstab_mount_test.cpp", + "//base/startup/init/test/unittest/single_test/fstab_mount/src/func_wrapper.cpp", + ] + + cflags_cc = [ "-fexceptions" ] + ldflags = [ + "-Wl,--wrap=strdup", + "-Wl,--wrap=stat", + "-Wl,--wrap=mount", + "-Wl,--wrap=mkdir", + "-Wl,--wrap=malloc", + "-Wl,--wrap=strncat_s", + "-Wl,--wrap=snprintf_s", + ] + deps = [ + "//base/startup/init/interfaces/innerkits:libbegetutil", + "//base/startup/init/interfaces/innerkits/fs_manager:libfsmanager_static", + ] + + defines = [ + "STARTUP_INIT_UT_PATH =\"/data/init_ut\"", + "ASAN_DETECTOR", + "STARTUP_INIT_TEST", + ] + + configs = [] + + external_deps = [ + "bounds_checking_function:libsec_static", + "cJSON:cjson", + "c_utils:utils", + "googletest:gtest", + "hilog:libhilog", + ] +} diff --git a/test/unittest/single_test/fstab_mount/include/fstab_mount_test.h b/test/unittest/single_test/fstab_mount/include/fstab_mount_test.h new file mode 100644 index 0000000000000000000000000000000000000000..72b16634a11d130afc2d9d7109504316f1789d80 --- /dev/null +++ b/test/unittest/single_test/fstab_mount/include/fstab_mount_test.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INIT_FSTAB_MOUNT_TEST_H +#define INIT_FSTAB_MOUNT_TEST_H +#include "fs_manager/fs_manager.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int MountWithCheckpoint(const char *source, const char *target, + const char *fsType, unsigned long flags, const char *data); + +int GetDataWithoutCheckpoint(char *fsSpecificData, size_t fsSpecificDataSize, + char *checkpointData, size_t checkpointDataSize); + +int DoMountOneItem(FstabItem *item); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/test/unittest/single_test/fstab_mount/include/func_wrapper.h b/test/unittest/single_test/fstab_mount/include/func_wrapper.h new file mode 100644 index 0000000000000000000000000000000000000000..477c53eb5a5072d2d4ac113d3b50d93bb5fbe229 --- /dev/null +++ b/test/unittest/single_test/fstab_mount/include/func_wrapper.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef TEST_WRAPPER_H +#define TEST_WRAPPER_H +#include +#include +#include +#include +#include +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +// for wrapper strdup; +char* __real_strdup(const char* string); +typedef char* (*StrdupFunc)(const char* string); +void UpdateStrdupFunc(StrdupFunc func); + +// for wrapper malloc; +void* __real_malloc(size_t size); +typedef void* (*MallocFunc)(size_t size); +void UpdateMallocFunc(MallocFunc func); + +// for wrapper strncat_s; +int __real_strncat_s(char *strDest, size_t destMax, const char *strSrc, size_t count); +typedef int (*StrncatSFunc)(char *strDest, size_t destMax, const char *strSrc, size_t count); +void UpdateStrncatSFunc(StrncatSFunc func); + +// for wrapper mkdir; +int __real_mkdir(const char *path, mode_t mode); +typedef int (*MkdirFunc)(const char *path, mode_t mode); +void UpdateMkdirFunc(MkdirFunc func); + +// for wrapper mount; +int __real_mount(const char *source, const char *target, const char *fsType, unsigned long flags, const void *data); +typedef int (*MountFunc)(const char *source, const char *target, + const char *fsType, unsigned long flags, const void *data); +void UpdateMountFunc(MountFunc func); + +// for wrapper stat; +int __real_stat(const char *pathname, struct stat *buf); +typedef int (*StatFunc)(const char *pathname, struct stat *buf); +void UpdateStatFunc(StatFunc func); + +// for wrapper snprintf_s; +size_t __real_snprintf_s(char *strDest, size_t destMax, size_t count, const char *format, ...); +typedef size_t (*SnprintfSFunc)(char *strDest, size_t destMax, size_t count, const char *format, ...); +void UpdateSnprintfSFunc(SnprintfSFunc func); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif +#endif // TEST_WRAPPER_H \ No newline at end of file diff --git a/test/unittest/single_test/fstab_mount/src/fstab_mount_test.cpp b/test/unittest/single_test/fstab_mount/src/fstab_mount_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dc1975374e3895ec6edfda6c5a8dc0231db23f5d --- /dev/null +++ b/test/unittest/single_test/fstab_mount/src/fstab_mount_test.cpp @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "fstab_mount_test.h" +#include +#include "func_wrapper.h" +#include +#include +#include "init_utils.h" +#include "securec.h" +using namespace testing; +using namespace testing::ext; +#define STRSIZE 64 + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +size_t SnprintfSReturnZero(char *strDest, size_t destMax, size_t count, const char *format, ...) +{ + return 0; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + + +namespace OHOS { +class FstabMountTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void FstabMountTest::SetUpTestCase() +{ + GTEST_LOG_(INFO) << "FstabMountTest SetUpTestCase"; +} + +void FstabMountTest::TearDownTestCase() +{ + GTEST_LOG_(INFO) << "FstabMountTest TearDownTestCase"; +} + +void FstabMountTest::SetUp() +{ + GTEST_LOG_(INFO) << "FstabMountTest SetUp"; +} + +void FstabMountTest::TearDown() +{ + GTEST_LOG_(INFO) << "FstabMountTest TearDown"; +} + +HWTEST_F(FstabMountTest, DoOneMountItem_001, TestSize.Level0) +{ + char deviceName[STRSIZE] = "deviceName"; + char mountPoint[STRSIZE] = "mountPoint"; + char fsType[STRSIZE] = "fstype"; + char mountOptions[STRSIZE] = "op1,op2,op3,op4,op5"; + unsigned int fsManagerFlags = 0; + + FstabItem item = { + .deviceName = deviceName, + .mountPoint = mountPoint, + .fsType = fsType, + .mountOptions = mountOptions, + .fsManagerFlags = fsManagerFlags, + .next = NULL, + }; + + int rc = DoMountOneItem(&item); + EXPECT_EQ(rc, -1); +} + +HWTEST_F(FstabMountTest, DoOneMountItem_002, TestSize.Level0) +{ + char deviceName[STRSIZE] = "deviceName"; + char mountPoint[STRSIZE] = "mountPoint"; + char fsType[STRSIZE] = "hmfs"; + char mountOptions[STRSIZE] = "op1,op2,op3,op4,op5,checkpoint=disable"; + unsigned int fsManagerFlags = 0; + + FstabItem item = { + .deviceName = deviceName, + .mountPoint = mountPoint, + .fsType = fsType, + .mountOptions = mountOptions, + .fsManagerFlags = fsManagerFlags, + .next = NULL, + }; + + int rc = DoMountOneItem(&item); + EXPECT_EQ(rc, -1); +} + +HWTEST_F(FstabMountTest, GetDataWithoutCheckpoint_001, TestSize.Level0) +{ + int rc = GetDataWithoutCheckpoint(nullptr, 0, nullptr, 0); + EXPECT_EQ(rc, -1); +} + +HWTEST_F(FstabMountTest, GetDataWithoutCheckpoint_002, TestSize.Level0) +{ + char fsData[STRSIZE] = "checkpoint=disable,op1,op2,op3"; + int rc = GetDataWithoutCheckpoint(fsData, STRSIZE, nullptr, 0); + EXPECT_EQ(rc, -1); + + char result[STRSIZE] = {0}; + rc = GetDataWithoutCheckpoint(fsData, STRSIZE, result, STRSIZE); + EXPECT_EQ(rc, 0); +} + +HWTEST_F(FstabMountTest, GetDataWithoutCheckpoint_003, TestSize.Level0) +{ + char fsData[STRSIZE] = "checkpoint=disable,op1,op2,op3,op4,op5"; + char result[STRSIZE] = {0}; + StrdupFunc func = [](const char *path) -> char * + { + return nullptr; + }; + UpdateStrdupFunc(func); + int rc = GetDataWithoutCheckpoint(fsData, STRSIZE, result, STRSIZE); + UpdateStrdupFunc(nullptr); + EXPECT_EQ(rc, -1); +} + +HWTEST_F(FstabMountTest, GetDataWithoutCheckpoint_004, TestSize.Level0) +{ + char fsData[STRSIZE] = "checkpoint=disable,op1,op2,op3,op4,op5"; + char result[STRSIZE] = {0}; + MallocFunc func = [](size_t size) -> void* { + return nullptr; + }; + UpdateMallocFunc(func); + int rc = GetDataWithoutCheckpoint(fsData, STRSIZE, result, STRSIZE); + UpdateMallocFunc(nullptr); + EXPECT_EQ(rc, -1); +} + + +HWTEST_F(FstabMountTest, GetDataWithoutCheckpoint_005, TestSize.Level0) +{ + char fsData[STRSIZE] = "checkpoint=disable,op1,op2,op3,op4,op5"; + char result[STRSIZE] = {0}; + StrncatSFunc func = [](char * strDest, size_t destMax, const char * strSrc, size_t count) -> int { + if (strcmp(strSrc, ",") == 0) { + return -1; + } + return __real_strncat_s(strDest, destMax, strSrc, count); + }; + UpdateStrncatSFunc(func); + int rc = GetDataWithoutCheckpoint(fsData, STRSIZE, result, STRSIZE); + UpdateStrncatSFunc(nullptr); + EXPECT_EQ(rc, -1); +} + +HWTEST_F(FstabMountTest, GetDataWithoutCheckpoint_006, TestSize.Level0) +{ + char fsData[STRSIZE] = "checkpoint=disable,op1,op2,op3,op4,op5"; + char result[STRSIZE] = {0}; + StrncatSFunc func = [](char *, size_t, const char *, size_t) -> int { + return -1; + }; + UpdateStrncatSFunc(func); + int rc = GetDataWithoutCheckpoint(fsData, STRSIZE, result, STRSIZE); + UpdateStrncatSFunc(nullptr); + EXPECT_EQ(rc, -1); +} + +HWTEST_F(FstabMountTest, MountWithCheckpoint_001, TestSize.Level0) +{ + StatFunc func = [](const char* path, struct stat *) -> int { + return 0; + }; + UpdateStatFunc(func); + int rc = MountWithCheckpoint("/source", "/target", "fsType", 0, "op1,op2,op3,op4,op5"); + UpdateStatFunc(nullptr); + EXPECT_EQ(rc, -1); +} + +HWTEST_F(FstabMountTest, MountWithCheckpoint_002, TestSize.Level0) +{ + StatFunc func = [](const char* path, struct stat *) -> int { + return 0; + }; + UpdateStatFunc(func); + + MkdirFunc mkdirFunc = [](const char*, mode_t) -> int { + return 0; + }; + UpdateMkdirFunc(mkdirFunc); + UpdateSnprintfSFunc(SnprintfSReturnZero); + + int rc = MountWithCheckpoint("/source", "/target", "fsType", 0, "op1,op2,op3,op4,op5"); + UpdateStatFunc(nullptr); + UpdateMkdirFunc(nullptr); + UpdateSnprintfSFunc(nullptr); + + EXPECT_EQ(rc, -1); +} + +HWTEST_F(FstabMountTest, MountWithCheckpoint_003, TestSize.Level0) +{ + StatFunc func = [](const char* path, struct stat *) -> int { + return 0; + }; + UpdateStatFunc(func); + + MkdirFunc mkdirFunc = [](const char*, mode_t) -> int { + return 0; + }; + UpdateMkdirFunc(mkdirFunc); + + MountFunc mountFunc = [](const char *, const char *, const char *, unsigned long, const void *) -> int { + errno = EBUSY; + return -1; + }; + UpdateMountFunc(mountFunc); + + int rc = MountWithCheckpoint("/source", "/target", "fsType", 0, "op1,op2,op3,op4,op5"); + UpdateStatFunc(nullptr); + UpdateMkdirFunc(nullptr); + UpdateMountFunc(nullptr); + + EXPECT_EQ(rc, 0); +} + +} \ No newline at end of file diff --git a/test/unittest/single_test/fstab_mount/src/func_wrapper.cpp b/test/unittest/single_test/fstab_mount/src/func_wrapper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..91180944195fc4ccb30f62b821c05fdda759183f --- /dev/null +++ b/test/unittest/single_test/fstab_mount/src/func_wrapper.cpp @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "func_wrapper.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +// start wrap strdup +static StrdupFunc g_strdup = NULL; +void UpdateStrdupFunc(StrdupFunc func) +{ + g_strdup = func; +} +char* __wrap_strdup(const char* string) +{ + if (g_strdup) { + return g_strdup(string); + } else { + return __real_strdup(string); + } +} + +// start wrap malloc +static MallocFunc g_malloc = NULL; +void UpdateMallocFunc(MallocFunc func) +{ + g_malloc = func; +} +void* __wrap_malloc(size_t size) +{ + if (g_malloc) { + return g_malloc(size); + } else { + return __real_malloc(size); + } +} + +// start wrap strncat_s +static StrncatSFunc g_strncat_s = NULL; +void UpdateStrncatSFunc(StrncatSFunc func) +{ + g_strncat_s = func; +} +int __wrap_strncat_s(char *strDest, size_t destMax, const char *strSrc, size_t count) +{ + if (g_strncat_s) { + return g_strncat_s(strDest, destMax, strSrc, count); + } else { + return __real_strncat_s(strDest, destMax, strSrc, count); + } +} + +// start wrap mkdir +static MkdirFunc g_mkdir = NULL; +void UpdateMkdirFunc(MkdirFunc func) +{ + g_mkdir = func; +} +int __wrap_mkdir(const char *path, mode_t mode) +{ + if (g_mkdir) { + return g_mkdir(path, mode); + } else { + return __real_mkdir(path, mode); + } +} + +// start wrap mount +static MountFunc g_mount = NULL; +void UpdateMountFunc(MountFunc func) +{ + g_mount = func; +} +int __wrap_mount(const char *source, const char *target, + const char *fsType, unsigned long flags, const void *data) +{ + if (g_mount) { + return g_mount(source, target, fsType, flags, data); + } else { + return __real_mount(source, target, fsType, flags, data); + } +} + +// start wrap stat +static StatFunc g_stat = NULL; +void UpdateStatFunc(StatFunc func) +{ + g_stat = func; +} +int __wrap_stat(const char *pathname, struct stat *buf) +{ + if (g_stat) { + return g_stat(pathname, buf); + } else { + return __real_stat(pathname, buf); + } +} + +// start wrap snprintf_s +static SnprintfSFunc g_snprintf_s = NULL; +void UpdateSnprintfSFunc(SnprintfSFunc func) +{ + g_snprintf_s = func; +} +size_t __wrap_snprintf_s(char *strDest, size_t destMax, size_t count, const char *format, ...) +{ + va_list args; + va_start(args, format); + size_t rc; + if (g_snprintf_s) { + rc = g_snprintf_s(strDest, destMax, count, format, args); + } else { + rc = __real_snprintf_s(strDest, destMax, count, format, args); + } + va_end(args); + return rc; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif