From ba8eeb9ee04498832e53a0e6fac38ce786e07650 Mon Sep 17 00:00:00 2001 From: lanhaoyu Date: Tue, 10 Jun 2025 17:21:20 +0800 Subject: [PATCH 1/2] add all_dependent_configs Signed-off-by: lanhaoyu --- modules/native_adapter/BUILD.gn | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/native_adapter/BUILD.gn b/modules/native_adapter/BUILD.gn index 4a41ac59..e1819d51 100644 --- a/modules/native_adapter/BUILD.gn +++ b/modules/native_adapter/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2024 Huawei Device Co., Ltd. +# Copyright (c) 2024-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 @@ -40,6 +40,9 @@ ohos_shared_library("nativespawn") { "init:libbegetutil", "napi:ace_napi", ] + if (!defined(APPSPAWN_TEST)) { + external_deps += [ "common_event_service:cesfwk_innerkits" ] + } subsystem_name = "${subsystem_name}" part_name = "${part_name}" install_enable = true -- Gitee From 0682f31ce327a67c694bd9b907dce7fad60cba6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=B5=A9?= Date: Tue, 1 Jul 2025 21:23:21 +0800 Subject: [PATCH 2/2] remove soft link after uninstall MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 杨浩 --- service/hnp/base/hnp_base.h | 17 +++ service/hnp/installer/include/hnp_installer.h | 2 +- service/hnp/installer/src/hnp_installer.c | 50 +++++++ test/BUILD.gn | 1 + .../single_test/hnp_installer/BUILD.gn | 63 +++++++++ .../include/hnp_installer_test.h | 28 ++++ .../hnp_installer/src/hnp_installer_test.cpp | 125 ++++++++++++++++++ 7 files changed, 285 insertions(+), 1 deletion(-) create mode 100644 test/unittest/single_test/hnp_installer/BUILD.gn create mode 100644 test/unittest/single_test/hnp_installer/include/hnp_installer_test.h create mode 100644 test/unittest/single_test/hnp_installer/src/hnp_installer_test.cpp diff --git a/service/hnp/base/hnp_base.h b/service/hnp/base/hnp_base.h index 5129a0de..e327e1d5 100644 --- a/service/hnp/base/hnp_base.h +++ b/service/hnp/base/hnp_base.h @@ -63,8 +63,10 @@ extern "C" { #ifndef APPSPAWN_TEST #define APPSPAWN_STATIC static +#define HNP_TEST_PATH #else #define APPSPAWN_STATIC +#define HNP_TEST_PATH "/data/hnp_ut" #endif /* Native软件二进制软链接配置 */ @@ -327,6 +329,21 @@ char *HnpCurrentVersionGet(const char *name); HILOG_ERROR(LOG_CORE, "[%{public}s:%{public}d]" args, (__FILE_NAME__), (__LINE__), ##__VA_ARGS__); \ HnpLogPrintf(HNP_LOG_ERROR, "HNP", "[%{public}s:%{public}d]" args, (__FILE_NAME__), (__LINE__), ##__VA_ARGS__) #endif +#define HNP_ERROR_CHECK(ret, statement, format, ...) \ + do { \ + if (!(ret)) { \ + HNP_LOGE(format, ##__VA_ARGS__); \ + statement; \ + } \ + } while (0) + +#define HNP_INFO_CHECK(ret, statement, format, ...) \ + do { \ + if (!(ret)) { \ + HNP_LOGI(format, ##__VA_ARGS__); \ + statement; \ + } \ + } while (0) #ifdef __cplusplus } diff --git a/service/hnp/installer/include/hnp_installer.h b/service/hnp/installer/include/hnp_installer.h index 411e8727..82fbaa20 100644 --- a/service/hnp/installer/include/hnp_installer.h +++ b/service/hnp/installer/include/hnp_installer.h @@ -43,7 +43,7 @@ extern "C" { // 0x801307 restorecon 安装目录失败 #define HNP_ERRNO_INSTALLER_RESTORECON_HNP_PATH_FAIL HNP_ERRNO_COMMON(HNP_MID_INSTALLER, 0x7) -#define HNP_DEFAULT_INSTALL_ROOT_PATH "/data/app/el1/bundle" +#define HNP_DEFAULT_INSTALL_ROOT_PATH HNP_TEST_PATH"/data/app/el1/bundle" #define HNP_SANDBOX_BASE_PATH "/data/service/hnp" /* hap安装信息 */ diff --git a/service/hnp/installer/src/hnp_installer.c b/service/hnp/installer/src/hnp_installer.c index c8bee464..70fdc5c3 100644 --- a/service/hnp/installer/src/hnp_installer.c +++ b/service/hnp/installer/src/hnp_installer.c @@ -197,6 +197,55 @@ static int HnpInstall(const char *hnpFile, HnpInstallInfo *hnpInfo, HnpCfgInfo * return HnpGenerateSoftLink(hnpInfo->hnpVersionPath, hnpInfo->hnpBasePath, hnpCfg); } +/** + * 删除 ../hnppublic/bin目录下所有失效的hnp + */ +APPSPAWN_STATIC void ClearSoftLink(int uid) +{ + char path[MAX_FILE_PATH_LEN]; + ssize_t bytes = snprintf_s(path, MAX_FILE_PATH_LEN, MAX_FILE_PATH_LEN - 1, + HNP_DEFAULT_INSTALL_ROOT_PATH"/%d/hnppublic/bin", uid); + HNP_ERROR_CHECK(bytes > 0, return, + "Build bin path failed %{public}d %{public}zd", uid, bytes); + + DIR *dir = opendir(path); + HNP_ERROR_CHECK(dir != NULL, return, + "open bin path failed %{public}s %{public}d", path, errno); + + struct dirent *entry; + int count = 0; + while ((entry = readdir(dir)) != NULL) { + if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) { + continue; + } + count++; + HNP_INFO_CHECK(entry->d_type == DT_LNK, continue, + "not lnk file %s skip to next", entry->d_name); + + char sourcePath[MAX_FILE_PATH_LEN]; + bytes = snprintf_s(sourcePath, MAX_FILE_PATH_LEN, MAX_FILE_PATH_LEN - 1, + "%s/%s", path, entry->d_name); + HNP_ERROR_CHECK(bytes > 0, continue, + "build soft link path failed %{public}s", entry->d_name); + + char targetPath[MAX_FILE_PATH_LEN]; + bytes = readlink(sourcePath, targetPath, MAX_FILE_PATH_LEN); + HNP_ERROR_CHECK(bytes > 0, continue, "readlink failed %{public}s", sourcePath); + + char linkPath[MAX_FILE_PATH_LEN]; + bytes = snprintf_s(linkPath, MAX_FILE_PATH_LEN, MAX_FILE_PATH_LEN - 1, + "%s/%s", path, targetPath); + HNP_ERROR_CHECK(bytes > 0, continue, "build link file source path failed %{public}s", targetPath); + + if (access(linkPath, F_OK) != 0) { + int ret = unlink(sourcePath); + HNP_LOGI("unlink file %{public}s %{public}d", sourcePath, ret); + } + } + HNP_LOGI("file count is %d", count); + closedir(dir); +} + /** * 卸载公共hnp. * @@ -249,6 +298,7 @@ static int HnpUnInstallPublicHnp(const char* packageName, const char *name, cons } if (HnpPathFileCount(hnpNamePath) == 0) { + ClearSoftLink(uid); return HnpDeleteFolder(hnpNamePath); } diff --git a/test/BUILD.gn b/test/BUILD.gn index faf729d9..7679d784 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -31,6 +31,7 @@ group("unittest") { deps += [ "unittest/app_spawn_standard_test:AppSpawn_coldrun_ut" ] } deps += [ "unittest/hnp_test:HnpTest" ] + deps += [ "unittest/single_test/hnp_installer:hnp_installer_test" ] deps += [ "unittest/devicedebug_test:DevicedebugTest" ] } else { testonly = true diff --git a/test/unittest/single_test/hnp_installer/BUILD.gn b/test/unittest/single_test/hnp_installer/BUILD.gn new file mode 100644 index 00000000..066a4412 --- /dev/null +++ b/test/unittest/single_test/hnp_installer/BUILD.gn @@ -0,0 +1,63 @@ +# 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/appspawn/appspawn.gni") +import("//build/test.gni") + +if (!defined(ohos_lite)) { + ohos_unittest("hnp_installer_test") { + module_out_path = "appspawn/appspawn" + cflags = [ + "-Wno-implicit-fallthrough", + "-Wno-unused-function", + "-Dprivate=public", + "-Dprotected=public", + ] + + cflags_cc = [ + "-Wno-implicit-fallthrough", + "-fexceptions", + ] + + include_dirs = [ + "${appspawn_path}/service/hnp/base", + "${appspawn_path}/service/hnp/pack/include", + "${appspawn_path}/service/hnp/installer/include", + "${appspawn_path}/interfaces/innerkits/hnp/include", + "${appspawn_path}/util/include", + "include", + ] + + sources = [ + "${appspawn_path}/service/hnp/base/hnp_log.c", + "${appspawn_path}/service/hnp/installer/src/hnp_installer.c", + "src/hnp_installer_test.cpp", + ] + + defines = [ "APPSPAWN_TEST" ] + + deps = [ "${appspawn_path}/util:libappspawn_util" ] + + external_deps = [ + "bounds_checking_function:libsec_shared", + "cJSON:cjson", + "hilog:libhilog", + "init:libbegetutil", + "selinux_adapter:librestorecon", + "zlib:shared_libz", + ] + + if (appspawn_support_code_signature) { + external_deps += [ "code_signature:libcode_sign_utils" ] + } + } +} diff --git a/test/unittest/single_test/hnp_installer/include/hnp_installer_test.h b/test/unittest/single_test/hnp_installer/include/hnp_installer_test.h new file mode 100644 index 00000000..7100ccef --- /dev/null +++ b/test/unittest/single_test/hnp_installer/include/hnp_installer_test.h @@ -0,0 +1,28 @@ +/* + * 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 HNP_INSTALL_TEST_H +#define HNP_INSTALL_TEST_H + +#ifdef __cplusplus +extern "C" { +#endif + +void ClearSoftLink(int uid); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/test/unittest/single_test/hnp_installer/src/hnp_installer_test.cpp b/test/unittest/single_test/hnp_installer/src/hnp_installer_test.cpp new file mode 100644 index 00000000..b0dabc5e --- /dev/null +++ b/test/unittest/single_test/hnp_installer/src/hnp_installer_test.cpp @@ -0,0 +1,125 @@ +/* + * 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 "hnp_installer_test.h" +#include + +#include +#include +#include +#include +#include +#include "hnp_installer.h" + + +using namespace testing; +using namespace testing::ext; + + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef __cplusplus + } +#endif + +namespace OHOS { +class HnpInstallerTestNew : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void HnpInstallerTestNew::SetUpTestCase() +{ + GTEST_LOG_(INFO) << "Hnp_Installer_TEST SetUpTestCase"; +} + +void HnpInstallerTestNew::TearDownTestCase() +{ + GTEST_LOG_(INFO) << "Hnp_Installer_TEST TearDownTestCase"; +} + +void HnpInstallerTestNew::SetUp() +{ + GTEST_LOG_(INFO) << "Hnp_Installer_TEST SetUp"; +} + +void HnpInstallerTestNew::TearDown() +{ + GTEST_LOG_(INFO) << "Hnp_Installer_TEST TearDown"; +} + +static void MakeDirRecursive(const std::string &path, mode_t mode) +{ + size_t size = path.size(); + if (size == 0) { + return; + } + + size_t index = 0; + do { + size_t pathIndex = path.find_first_of('/', index); + index = pathIndex == std::string::npos ? size : pathIndex + 1; + std::string dir = path.substr(0, index); + if (access(dir.c_str(), F_OK) < 0) { + int ret = mkdir(dir.c_str(), mode); + if (ret != 0) { + return; + } + } + } while (index < size); +} + +static void CreateTestFile(const char *fileName, const char *data) +{ + FILE *tmpFile = fopen(fileName, "wr"); + if (tmpFile != nullptr) { + fprintf(tmpFile, "%s", data); + (void)fflush(tmpFile); + fclose(tmpFile); + } +} + +HWTEST_F(HnpInstallerTestNew, hnp_clearSoftLink_001, TestSize.Level0) +{ + GTEST_LOG_(INFO) << "hnp_clearSoftLink_001 start"; + + const std::string binDir = HNP_DEFAULT_INSTALL_ROOT_PATH"/100/hnppublic/bin"; + const std::string fileDir = HNP_DEFAULT_INSTALL_ROOT_PATH"/100/hnppublic/test.org/bin"; + + MakeDirRecursive(binDir, 0711); + MakeDirRecursive(fileDir, 0711); + + const std::string lnkFile = HNP_DEFAULT_INSTALL_ROOT_PATH"/100/hnppublic/bin/test"; + const std::string sourceFile = "../test.org/bin/test"; + + CreateTestFile(HNP_DEFAULT_INSTALL_ROOT_PATH"/100/hnppublic/test.org/bin/test", "test"); + symlink(sourceFile.c_str(), lnkFile.c_str()); + + ClearSoftLink(100); + int ret = access(lnkFile.c_str(), F_OK); + EXPECT_EQ(ret, 0); + + remove(HNP_DEFAULT_INSTALL_ROOT_PATH"/100/hnppublic/test.org/bin/test"); + ClearSoftLink(100); + + ret = access(lnkFile.c_str(), F_OK); + EXPECT_NE(ret, 0); +} + +} \ No newline at end of file -- Gitee