diff --git a/interfaces/innerkits/fs_manager/fstab_mount.c b/interfaces/innerkits/fs_manager/fstab_mount.c index 78020c87cb539b5fe637e11cebf716ebc51ef66e..3dd1a7e9e94c2f91d5d515be8db037b2b80bfbfe 100755 --- a/interfaces/innerkits/fs_manager/fstab_mount.c +++ b/interfaces/innerkits/fs_manager/fstab_mount.c @@ -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; @@ -528,7 +527,7 @@ static int GetDataWithoutCheckpoint(char *fsSpecificData, size_t fsSpecificDataS char *checkpointData, size_t checkpointDataSize) { if (fsSpecificData == NULL || strstr(fsSpecificData, "checkpoint=disable") == NULL) { - BEGET_LOGI("Not checkpoint Mount info"); + BEGET_LOGE("Not checkpoint Mount info"); return -1; } if (checkpointData == NULL) { @@ -539,7 +538,7 @@ static int GetDataWithoutCheckpoint(char *fsSpecificData, size_t fsSpecificDataS const int maxCount = 15; char *splitStr = strdup(fsSpecificData); if (splitStr == NULL) { - BEGET_LOGI("dump fsData failed"); + BEGET_LOGE("dump fsData failed"); return -1; } char **flagsVector = SplitStringExt(splitStr, ",", &flagCount, maxCount); diff --git a/remount/include/ErofsMountOverlayMock.cpp b/remount/include/ErofsMountOverlayMock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3ab5042463dcb2a74685ede72a52f435ed8474fd --- /dev/null +++ b/remount/include/ErofsMountOverlayMock.cpp @@ -0,0 +1,18 @@ +#include "ErofsMountOverlayMock.h" + +#include "fs_manager/fs_manager.h" +#include "erofs_overlay_common.h" +int DoMountOverlayDevice(FstabItem *item) { + if (instance == nullptr) { + return reinterpret_cast(0); + } + return ErofsMountOverlay::instance->DoMountOverlayDevice(item); +} + +int MountExt4Device(const char *dev, const char *mnt, bool isFirstMount) { + if (instance == nullptr) { + return reinterpret_cast(0); + } + return ErofsMountOverlay::instance->MountExt4Device(dev, mnt, isFirstMount); +} + diff --git a/remount/include/ErofsMountOverlayMock.h b/remount/include/ErofsMountOverlayMock.h new file mode 100644 index 0000000000000000000000000000000000000000..0f2153f879499123cbd2a00242c4bbd0023648d9 --- /dev/null +++ b/remount/include/ErofsMountOverlayMock.h @@ -0,0 +1,23 @@ +#ifndef EROFSMOUNTOVERLAY_MOCK_H +#define EROFSMOUNTOVERLAY_MOCK_H + +#include "fs_manager/fs_manager.h" +#include "erofs_overlay_common.h" +#include + +class ErofsMountOverlay { +public: + virtual ~ErofsMountOverlay() = default; // Default destructor + virtual int DoMountOverlayDevice(FstabItem *item) = 0; + virtual int MountExt4Device(const char *dev, const char *mnt, bool isFirstMount) = 0; +public: + static inline std::shared_ptr instance = nullptr; +}; + +// Mock class: ErofsMountOverlayMock +class ErofsMountOverlayMock : public ErofsMountOverlay { +public: + MOCK_METHOD1(DoMountOverlayDevice, int(FstabItem *item)); + MOCK_METHOD3(MountExt4Device, int(const char *dev, const char *mnt, bool isFirstMount)); + +#endif // EROFSMOUNTOVERLAY_MOCK_H diff --git a/remount/include/ErofsOverlayCommonMock.cpp b/remount/include/ErofsOverlayCommonMock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..94721693accec63753314a30ef62e1a2933daa46 --- /dev/null +++ b/remount/include/ErofsOverlayCommonMock.cpp @@ -0,0 +1,27 @@ +#include "ErofsOverlayCommonMock.h" + +#include "stdbool.h" +#include "stdint.h" +#include "fs_manager/ext4_super_block.h" +#include "fs_manager/erofs_super_block.h" +bool IsOverlayEnable(void) { + if (instance == nullptr) { + return reinterpret_cast(0); + } + return ErofsOverlayCommon::instance->IsOverlayEnable(); +} + +bool CheckIsExt4(const char *dev, uint64_t offset) { + if (instance == nullptr) { + return reinterpret_cast(0); + } + return ErofsOverlayCommon::instance->CheckIsExt4(dev, offset); +} + +bool CheckIsErofs(const char *dev) { + if (instance == nullptr) { + return reinterpret_cast(0); + } + return ErofsOverlayCommon::instance->CheckIsErofs(dev); +} + diff --git a/remount/include/ErofsOverlayCommonMock.h b/remount/include/ErofsOverlayCommonMock.h new file mode 100644 index 0000000000000000000000000000000000000000..3d4a9f9521272baa011da2064597e95688f55c08 --- /dev/null +++ b/remount/include/ErofsOverlayCommonMock.h @@ -0,0 +1,27 @@ +#ifndef EROFSOVERLAYCOMMON_MOCK_H +#define EROFSOVERLAYCOMMON_MOCK_H + +#include "stdbool.h" +#include "stdint.h" +#include "fs_manager/ext4_super_block.h" +#include "fs_manager/erofs_super_block.h" +#include + +class ErofsOverlayCommon { +public: + virtual ~ErofsOverlayCommon() = default; // Default destructor + virtual bool IsOverlayEnable(void) = 0; + virtual bool CheckIsExt4(const char *dev, uint64_t offset) = 0; + virtual bool CheckIsErofs(const char *dev) = 0; +public: + static inline std::shared_ptr instance = nullptr; +}; + +// Mock class: ErofsOverlayCommonMock +class ErofsOverlayCommonMock : public ErofsOverlayCommon { +public: + MOCK_METHOD0(IsOverlayEnable, bool(void)); + MOCK_METHOD2(CheckIsExt4, bool(const char *dev, uint64_t offset)); + MOCK_METHOD1(CheckIsErofs, bool(const char *dev)); + +#endif // EROFSOVERLAYCOMMON_MOCK_H diff --git a/remount/include/ErofsRemountOverlayMock.cpp b/remount/include/ErofsRemountOverlayMock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a4022a0c0603890f1baf5a8d0ffdd954027f8ea5 --- /dev/null +++ b/remount/include/ErofsRemountOverlayMock.cpp @@ -0,0 +1,45 @@ +#include "ErofsRemountOverlayMock.h" + +#include "erofs_overlay_common.h" +int GetRemountResult(void) { + if (instance == nullptr) { + return reinterpret_cast(0); + } + return ErofsRemountOverlay::instance->GetRemountResult(); +} + +void SetRemountResultFlag() { + if (instance == nullptr) { + return; + } + ErofsRemountOverlay::instance->SetRemountResultFlag(); +} + +int RemountOverlay(void) { + if (instance == nullptr) { + return reinterpret_cast(0); + } + return ErofsRemountOverlay::instance->RemountOverlay(); +} + +int MountOverlayOne(const char *mnt) { + if (instance == nullptr) { + return reinterpret_cast(0); + } + return ErofsRemountOverlay::instance->MountOverlayOne(mnt); +} + +void OverlayRemountVendorPre(void) { + if (instance == nullptr) { + return; + } + ErofsRemountOverlay::instance->OverlayRemountVendorPre(); +} + +void OverlayRemountVendorPost(void) { + if (instance == nullptr) { + return; + } + ErofsRemountOverlay::instance->OverlayRemountVendorPost(); +} + diff --git a/remount/include/ErofsRemountOverlayMock.h b/remount/include/ErofsRemountOverlayMock.h new file mode 100644 index 0000000000000000000000000000000000000000..06e6a6d14fb12635f4c9db4d395b494aacc1cc7e --- /dev/null +++ b/remount/include/ErofsRemountOverlayMock.h @@ -0,0 +1,30 @@ +#ifndef EROFSREMOUNTOVERLAY_MOCK_H +#define EROFSREMOUNTOVERLAY_MOCK_H + +#include "erofs_overlay_common.h" +#include + +class ErofsRemountOverlay { +public: + virtual ~ErofsRemountOverlay() = default; // Default destructor + virtual int GetRemountResult(void) = 0; + virtual void SetRemountResultFlag() = 0; + virtual int RemountOverlay(void) = 0; + virtual int MountOverlayOne(const char *mnt) = 0; + virtual void OverlayRemountVendorPre(void) = 0; + virtual void OverlayRemountVendorPost(void) = 0; +public: + static inline std::shared_ptr instance = nullptr; +}; + +// Mock class: ErofsRemountOverlayMock +class ErofsRemountOverlayMock : public ErofsRemountOverlay { +public: + MOCK_METHOD0(GetRemountResult, int(void)); + MOCK_METHOD0(SetRemountResultFlag, void()); + MOCK_METHOD0(RemountOverlay, int(void)); + MOCK_METHOD1(MountOverlayOne, int(const char *mnt)); + MOCK_METHOD0(OverlayRemountVendorPre, void(void)); + MOCK_METHOD0(OverlayRemountVendorPost, void(void)); + +#endif // EROFSREMOUNTOVERLAY_MOCK_H diff --git a/remount/include/RemountOverlayMock.cpp b/remount/include/RemountOverlayMock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..68e90c5928546091fd4b86f1d8c403ad76a7b083 --- /dev/null +++ b/remount/include/RemountOverlayMock.cpp @@ -0,0 +1,10 @@ +#include "RemountOverlayMock.h" + +#include "fs_manager.h" +int RemountRofsOverlay() { + if (instance == nullptr) { + return reinterpret_cast(0); + } + return RemountOverlay::instance->RemountRofsOverlay(); +} + diff --git a/remount/include/RemountOverlayMock.h b/remount/include/RemountOverlayMock.h new file mode 100644 index 0000000000000000000000000000000000000000..31495d1c3726b2eec5518ed55de9e4f572629dab --- /dev/null +++ b/remount/include/RemountOverlayMock.h @@ -0,0 +1,20 @@ +#ifndef REMOUNTOVERLAY_MOCK_H +#define REMOUNTOVERLAY_MOCK_H + +#include "fs_manager.h" +#include + +class RemountOverlay { +public: + virtual ~RemountOverlay() = default; // Default destructor + virtual int RemountRofsOverlay() = 0; +public: + static inline std::shared_ptr instance = nullptr; +}; + +// Mock class: RemountOverlayMock +class RemountOverlayMock : public RemountOverlay { +public: + MOCK_METHOD0(RemountRofsOverlay, int()); + +#endif // REMOUNTOVERLAY_MOCK_H diff --git a/remount/include/erofs_mount_overlay.h b/remount/include/erofs_mount_overlay.h new file mode 100644 index 0000000000000000000000000000000000000000..5b183b7775dfecf9af193f0b1fc234ecdae9dc85 --- /dev/null +++ b/remount/include/erofs_mount_overlay.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024-2024 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 EROFS_MOUNT_OVERLAY_H +#define EROFS_MOUNT_OVERLAY_H + +#include "fs_manager/fs_manager.h" +#include "erofs_overlay_common.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +int DoMountOverlayDevice(FstabItem *item); + +int MountExt4Device(const char *dev, const char *mnt, bool isFirstMount); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif // EROFS_MOUNT_OVERLAY_H diff --git a/remount/include/erofs_overlay_common.h b/remount/include/erofs_overlay_common.h new file mode 100644 index 0000000000000000000000000000000000000000..cdb643273c60ace4898ac9737fc1550a4bf439e4 --- /dev/null +++ b/remount/include/erofs_overlay_common.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2024-2024 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 EROFS_OVERLAY_COMMON_H +#define EROFS_OVERLAY_COMMON_H + +#include +#include +#include "fs_manager/ext4_super_block.h" +#include "fs_manager/erofs_super_block.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#define MODE_MKDIR 0755 +#define EXT4_SUPER_MAGIC 0xEF53 +#define EXT4_SUPER_OFFSET 0x400 +#define SECTOR_SIZE 512 +#define PREFIX_LOWER "/mnt/lower" +#define PREFIX_OVERLAY "/mnt/overlay" +#define PREFIX_UPPER "/upper" +#define PREFIX_WORK "/work" + +bool IsOverlayEnable(void); + +bool CheckIsExt4(const char *dev, uint64_t offset); + +bool CheckIsErofs(const char *dev); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif \ No newline at end of file diff --git a/remount/include/erofs_remount_overlay.h b/remount/include/erofs_remount_overlay.h new file mode 100644 index 0000000000000000000000000000000000000000..aafc2dec5dcd46345fb80f5e525feda1c143cadf --- /dev/null +++ b/remount/include/erofs_remount_overlay.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2024-2024 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 EROFS_REMOUNT_OVERLAY_H +#define EROFS_REMOUNT_OVERLAY_H + +#include "erofs_overlay_common.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#define MODEM_DRIVER_MNT_PATH STARTUP_INIT_UT_PATH"/vendor/modem/modem_driver" +#define MODEM_VENDOR_MNT_PATH STARTUP_INIT_UT_PATH"/vendor/modem/modem_vendor" +#define MODEM_FW_MNT_PATH STARTUP_INIT_UT_PATH"/vendor/modem/modem_fw" +#define MODEM_DRIVER_EXCHANGE_PATH STARTUP_INIT_UT_PATH"/mnt/driver_exchange" +#define MODEM_VENDOR_EXCHANGE_PATH STARTUP_INIT_UT_PATH"/mnt/vendor_exchange" +#define MODEM_FW_EXCHANGE_PATH STARTUP_INIT_UT_PATH"/mnt/fw_exchange" +#define REMOUNT_RESULT_PATH STARTUP_INIT_UT_PATH"/data/service/el1/startup/remount/" +#define REMOUNT_RESULT_FLAG STARTUP_INIT_UT_PATH"/data/service/el1/startup/remount/remount.result.done" + +#define REMOUNT_SUCC 0 +#define REMOUNT_FAIL 1 + +int GetRemountResult(void); + +void SetRemountResultFlag(); + +int RemountOverlay(void); + +int MountOverlayOne(const char *mnt); + +void OverlayRemountVendorPre(void); + +void OverlayRemountVendorPost(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif // EROFS_REMOUNT_OVERLAY_H diff --git a/remount/include/test.py b/remount/include/test.py new file mode 100644 index 0000000000000000000000000000000000000000..9765584cd7df65493783467db2820ffc3d1847ee --- /dev/null +++ b/remount/include/test.py @@ -0,0 +1,185 @@ +import os +import re + +def to_camel_case(s): + """Convert a string to CamelCase.""" + return ''.join(word.capitalize() for word in s.split('_')) + +def extract_dependencies(header_lines): + """Extract #include directives from the header file.""" + dependencies = [] + include_pattern = re.compile(r'#include\s+["<](.*)[">]') + + for line in header_lines: + line = line.strip() + match = include_pattern.match(line) + if match: + dependencies.append(match.group(1).strip()) + + return dependencies + +import re + +def extract_functions_from_header(header_lines): + """Extract function declarations from the header file.""" + functions = [] + # 适配跨行的函数定义 + func_pattern = re.compile(r'(\w[\w\s\*]+)\s+(\w+)\s*\(([^)]*)\)\s*;') + + # 合并多行 + full_code = ''.join(header_lines) + + # 在合并后的字符串中查找所有的函数定义 + for match in func_pattern.finditer(full_code): + return_type = match.group(1).strip() + func_name = match.group(2).strip() + args = match.group(3).strip() + functions.append((return_type, func_name, args)) + + return functions + + +def extract_non_functional_content(header_lines): + """Extract non-function content (macros, constants, typedefs, etc.) from the header file.""" + non_functions = [] + non_function_pattern = re.compile(r'#.*|typedef\s+\S+|\s*namespace\s+\S+|const\s+\S+') + + for line in header_lines: + line = line.strip() + if non_function_pattern.match(line): + non_functions.append(line) + + return non_functions + +# 去除修饰符并返回变量名 +def remove_modifiers(param): + # 按空格切割,取最后一部分(变量名) + parts = param.strip().split() + + # 如果 parts 为空(例如,参数是 "const char*"),返回空字符串 + if not parts: + return '' + + variable = parts[-1] + + # 移除变量名中的 * 和 [] 等修饰符 + variable = re.sub(r'[\*\[\]]', '', variable) + + return variable.strip() + +def generate_mock_files(header_file_path): + # Get the base name and convert it to CamelCase + base_name = os.path.splitext(os.path.basename(header_file_path))[0] + class_name = to_camel_case(base_name) + mock_header_file_name = class_name + 'Mock.h' + mock_cpp_file_name = class_name + 'Mock.cpp' + + # Read the original C header file + with open(header_file_path, 'r') as file: + lines = file.readlines() + + # Extract dependencies + dependencies = extract_dependencies(lines) + # Extract non-function content + non_function_content = extract_non_functional_content(lines) + + # Extract functions + functions = extract_functions_from_header(lines) + + # Start generating the mock header file (mock.h) + cpp_header_content = '#ifndef ' + class_name.upper() + '_MOCK_H\n' + cpp_header_content += '#define ' + class_name.upper() + '_MOCK_H\n\n' + + # Add dependencies + for dep in dependencies: + cpp_header_content += f'#include "{dep}"\n' + cpp_header_content += '#include \n\n' + + # Add non-function content (macros, constants, typedefs, etc.) + # for line in non_function_content: + # cpp_header_content += line + '\n' + + # Add base class definition in the header file + cpp_header_content += 'class ' + class_name + ' {\npublic:\n' + cpp_header_content += ' virtual ~' + class_name + '() = default; // Default destructor\n' + for return_type, func_name, args in functions: + cpp_header_content += f' virtual {return_type} {func_name}({args}) = 0;\n' + + # Add static member variable: std::shared_ptr instance = nullptr + cpp_header_content += f'public: \n' + cpp_header_content += f' static inline std::shared_ptr<{class_name}> instance = nullptr;\n' + cpp_header_content += '};\n\n' + + # Add Mock class + cpp_header_content += f'// Mock class: {class_name}Mock\n' + cpp_header_content += f'class {class_name}Mock : public {class_name} {{\npublic:\n' + + # Add MOCK_METHOD for each function in mock class + for return_type, func_name, args in functions: + # If args is 'void', treat as 0 arguments + if args.strip() == "void": + num_args = 0 + else: + num_args = len([arg.strip() for arg in args.split(',') if arg.strip()]) + cpp_header_content += f' MOCK_METHOD{num_args}({func_name}, {return_type}({args}));\n' + + cpp_header_content += '\n#endif // ' + class_name.upper() + '_MOCK_H\n' + + # Save the generated mock header content + with open(mock_header_file_name, 'w') as mock_file: + mock_file.write(cpp_header_content) + print(f"C++ mock header file '{mock_header_file_name}' has been generated.") + + # Start generating the cpp source file (mock.cpp) + cpp_source_content = '#include "' + class_name + 'Mock.h"\n\n' + # Add dependencies + for dep in dependencies: + cpp_source_content += f'#include "{dep}"\n' + # Add the mock method implementations in mock.cpp + for return_type, func_name, args in functions: + # 如果返回类型是 void + if return_type == "void": + cpp_source_content += f'{return_type} {func_name}({args}) {{\n' + cpp_source_content += f' if (instance == nullptr) {{\n' + cpp_source_content += f' return;\n' # void 类型的返回值无需返回任何内容 + cpp_source_content += f' }}\n' + + # 检查参数是否为 void 类型 + if args.strip() == "void": + cpp_source_content += f' {class_name}::instance->{func_name}();\n' # void 参数,调用时不传递参数 + else: + # 去除参数修饰符后再传递 + cleaned_args = ", ".join([remove_modifiers(arg.strip()) for arg in args.split(",")]) + cpp_source_content += f' {class_name}::instance->{func_name}({cleaned_args});\n' + else: + cpp_source_content += f'{return_type} {func_name}({args}) {{\n' + cpp_source_content += f' if (instance == nullptr) {{\n' + + # 如果 instance 是 nullptr,返回默认值 + if return_type == "void": + cpp_source_content += f' return;\n' + else: + cpp_source_content += f' return reinterpret_cast<{return_type}>(0);\n' + + cpp_source_content += f' }}\n' + + # 检查参数是否为 void 类型 + if args.strip() == "void": + cpp_source_content += f' return {class_name}::instance->{func_name}();\n' # void 参数,调用时不传递参数 + else: + # 去除参数修饰符后再传递 + cleaned_args = ", ".join([remove_modifiers(arg.strip()) for arg in args.split(",")]) + cpp_source_content += f' return {class_name}::instance->{func_name}({cleaned_args});\n' + + cpp_source_content += f'}}\n\n' + # Save the generated mock source content + with open(mock_cpp_file_name, 'w') as cpp_file: + cpp_file.write(cpp_source_content) + print(f"C++ mock source file '{mock_cpp_file_name}' has been generated.") + +def generate_mock_headers_in_directory(): + # Process all .h files in the current directory + for file_name in os.listdir('.'): + if file_name.endswith('.h'): + generate_mock_files(file_name) +generate_mock_headers_in_directory() 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..985ed1eb204f1837887487f761f643e52143f6a6 --- /dev/null +++ b/test/unittest/single_test/fstab_mount/BUILD.gn @@ -0,0 +1,60 @@ +# 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("init_firststage_unittest") { + module_out_path = "init/init" + include_dirs = [ + "//base/startup/init/test/unittest/single_test/init_firststage/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", + ] + + sources = [ + "//base/startup/init/services/init/standard/init_firststage.c", + "//base/startup/init/test/unittest/single_test/init_firststage/src/init_firststage_test.cpp", + ] + + cflags_cc = [ "-fexceptions" ] + cflags = [ + "-Dexecv=ExecvStub", + "-DCloseStdio=CloseStdioStub", + "-Daccess=AccessStub", + ] + + 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 = [ + "cJSON:cjson", + "c_utils:utils", + "googletest:gtest", + "hilog:libhilog", + ] +} diff --git a/test/unittest/single_test/fstab_mount/include/fatab_mount_test.h b/test/unittest/single_test/fstab_mount/include/fatab_mount_test.h new file mode 100644 index 0000000000000000000000000000000000000000..cb3c12601fc091f7f7d4203ce97fac61d5457faa --- /dev/null +++ b/test/unittest/single_test/fstab_mount/include/fatab_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/src/fatab_mount_test.cpp b/test/unittest/single_test/fstab_mount/src/fatab_mount_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dd1c3197a969745258113abd5175112cf3f55b31 --- /dev/null +++ b/test/unittest/single_test/fstab_mount/src/fatab_mount_test.cpp @@ -0,0 +1,117 @@ +/* + * 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 +#include +#include "init_utils.h" +#include "securec.h" +using namespace testing; +using namespace testing::ext; +#define STRSIZE 16 +static int g_access = 0; + +#ifdef __cplusplus + extern "C" { +#endif + +int MkdirStub(const char*path, int mode) +{ + return 0; +} + +int MountStub(const char *source, const char *target, const char *fsType, + unsigned long flags, const void *data) +{ + return -1; +} + +#ifdef __cplusplus + } +#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, + .fsMaanagerFlags = fsManagerFlags, + .next = NULL, + }; + + int rc = DoMountOneItem(&item); + EXPECT_TRUE(rc, 0); +} + +HWTEST_F(FstabMountTest, DoOneMountItem_002, 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, + .fsMaanagerFlags = fsManagerFlags, + .next = NULL, + }; + + int rc = DoMountOneItem(&item); + EXPECT_TRUE(rc, 0); +} + +} \ No newline at end of file