From: Junghyun Yeon Date: Fri, 20 Aug 2021 03:33:08 +0000 (+0900) Subject: Implement CreateDir request handler X-Git-Tag: submit/tizen/20210826.063234~5 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=52b2caad1eed674029521fa728ecca30d2a8bee7;p=platform%2Fcore%2Fappfw%2Fpkgmgr-tool.git Implement CreateDir request handler Implement CreateDir request handler which responsible for creating new directories. Change-Id: Ib5dba75b3f2d8975917eeb248fcd7cdf15afad95 Signed-off-by: Junghyun Yeon --- diff --git a/src/res-copy/include/abstract_request_handler.hh b/src/res-copy/include/abstract_request_handler.hh index 09c79ce..c0dcb7b 100644 --- a/src/res-copy/include/abstract_request_handler.hh +++ b/src/res-copy/include/abstract_request_handler.hh @@ -28,8 +28,10 @@ namespace res_handler { class AbstractRequestHandler { public: AbstractRequestHandler( - std::string pkgid, std::string root_path, std::list path_list) : - pkgid_(pkgid), root_path_(root_path), path_list_(path_list) {}; + std::string pkgid, uid_t uid, + std::string root_path, std::list path_list) + : pkgid_(pkgid), uid_(uid), root_path_(root_path), + path_list_(path_list) {}; virtual ErrorType Execute() = 0; virtual const std::string GetRequestHandlerType() const = 0; @@ -38,9 +40,11 @@ class AbstractRequestHandler { std::string GetRootPath(); const std::string GetPkgID() const; const std::list GetPathList() const; + uid_t GetUID() const; private: std::string pkgid_; + uid_t uid_; std::string root_path_; std::list path_list_; }; diff --git a/src/res-copy/include/copy_request_handler.hh b/src/res-copy/include/copy_request_handler.hh index 66bb747..9709fa5 100644 --- a/src/res-copy/include/copy_request_handler.hh +++ b/src/res-copy/include/copy_request_handler.hh @@ -28,7 +28,7 @@ namespace res_handler { class CopyRequestHandler : public AbstractRequestHandler { public: - CopyRequestHandler(std::string pkgid, std::string root_path, + CopyRequestHandler(std::string pkgid, uid_t uid, std::string root_path, std::list path_list); ErrorType Execute() override; diff --git a/src/res-copy/include/createdir_request_handler.hh b/src/res-copy/include/createdir_request_handler.hh new file mode 100644 index 0000000..63eccdf --- /dev/null +++ b/src/res-copy/include/createdir_request_handler.hh @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 Samsung Electronics 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 CREATEDIR_REQUEST_HANDLER_HH_ +#define CREATEDIR_REQUEST_HANDLER_HH_ + +#include +#include + +#include "include/abstract_request_handler.hh" +#include "include/error_type.hh" +#include "include/res_path_info.hh" + +namespace res_handler { + +class CreateDirRequestHandler : public AbstractRequestHandler { + public: + CreateDirRequestHandler(std::string pkgid, uid_t uid, std::string root_path, + std::list path_list); + + ErrorType Execute() override; + const std::string GetRequestHandlerType() const override; +}; + +} // namespace res_handler + +#endif // CREATEDIR_REQUEST_HANDLER_HH_ diff --git a/src/res-copy/include/file_util.hh b/src/res-copy/include/file_util.hh index bcb786e..ccec6d1 100644 --- a/src/res-copy/include/file_util.hh +++ b/src/res-copy/include/file_util.hh @@ -20,6 +20,9 @@ #include #include +#include + +namespace bf = boost::filesystem; namespace res_handler { @@ -34,17 +37,29 @@ enum FSFlag : int { FSFlag operator|(FSFlag a, FSFlag b); -bool CreateDir(const boost::filesystem::path& path); +bool CreateDir(const boost::filesystem::path& path, uid_t uid = 0); +bool CreateDirs(const std::string& pkgid, const boost::filesystem::path& path, uid_t uid = 0); bool CopyDir(const boost::filesystem::path& src, const boost::filesystem::path& dst, - FSFlag flags = FS_NONE, bool skip_symlink = false); + uid_t uid, FSFlag flags = FS_NONE, bool skip_symlink = false); bool CopyFile(const boost::filesystem::path& src, const boost::filesystem::path& dst); bool RemoveAll(const boost::filesystem::path& path); +boost::optional GetGidByUid(uid_t uid); + +bool SetDirOwnershipAndPermissions(const boost::filesystem::path& path, + boost::filesystem::perms permissions, uid_t uid, + gid_t gid); + +bool SetDirPermissions(const boost::filesystem::path& path, + boost::filesystem::perms permissions); + +bool SetOwnership(const bf::path& path, uid_t uid, gid_t gid); + } // namespace res_handler #endif // FILE_UTIL_HH_ diff --git a/src/res-copy/include/remove_request_handler.hh b/src/res-copy/include/remove_request_handler.hh index a378a79..0c3d3eb 100644 --- a/src/res-copy/include/remove_request_handler.hh +++ b/src/res-copy/include/remove_request_handler.hh @@ -29,7 +29,7 @@ namespace res_handler { class RemoveRequestHandler : public AbstractRequestHandler { public: RemoveRequestHandler( - std::string pkgid, std::string root_path, + std::string pkgid, uid_t uid, std::string root_path, std::list path_list); ErrorType Execute() override; diff --git a/src/res-copy/include/request_type.hh b/src/res-copy/include/request_type.hh index 7cf97b7..71be941 100644 --- a/src/res-copy/include/request_type.hh +++ b/src/res-copy/include/request_type.hh @@ -23,6 +23,7 @@ enum ReqType { REQ_TYPE_NEW = 0, REQ_TYPE_REMOVE = 1, REQ_TYPE_UNINSTALL, + REQ_TYPE_CREATEDIR, REQ_TYPE_UNKNOWN }; diff --git a/src/res-copy/include/uninstall_request_handler.hh b/src/res-copy/include/uninstall_request_handler.hh index 55997bf..8844c94 100644 --- a/src/res-copy/include/uninstall_request_handler.hh +++ b/src/res-copy/include/uninstall_request_handler.hh @@ -29,7 +29,8 @@ namespace res_handler { class UninstallRequestHandler : public AbstractRequestHandler { public: UninstallRequestHandler( - std::string pkgid, std::string root_path, std::list path_list); + std::string pkgid, uid_t uid, + std::string root_path, std::list path_list); ErrorType Execute() override; const std::string GetRequestHandlerType() const override; diff --git a/src/res-copy/src/abstract_request_handler.cc b/src/res-copy/src/abstract_request_handler.cc index 24f34f7..0f95365 100644 --- a/src/res-copy/src/abstract_request_handler.cc +++ b/src/res-copy/src/abstract_request_handler.cc @@ -36,4 +36,8 @@ const std::list AbstractRequestHandler::GetPathList() const { return path_list_; } +uid_t AbstractRequestHandler::GetUID() const { + return uid_; +} + } // namespace res_handler diff --git a/src/res-copy/src/copy_request_handler.cc b/src/res-copy/src/copy_request_handler.cc index ff76159..0544fa2 100644 --- a/src/res-copy/src/copy_request_handler.cc +++ b/src/res-copy/src/copy_request_handler.cc @@ -40,16 +40,16 @@ constexpr char kCopyReqHandlerType[] = "copy"; namespace res_handler { CopyRequestHandler::CopyRequestHandler( - std::string pkgid, std::string root_path, + std::string pkgid, uid_t uid, std::string root_path, std::list path_list) : - AbstractRequestHandler(pkgid, root_path, path_list) {} + AbstractRequestHandler(pkgid, uid, root_path, path_list) {} ErrorType CopyRequestHandler::Execute() { bf::path root_path(GetRootPath()); bf::path src_root_path = root_path / "apps_rw" / GetPkgID(); bf::path dst_root_path = root_path / "shared_res" / GetPkgID(); - if (!CreateDir(dst_root_path)) + if (!CreateDir(dst_root_path, GetUID())) return ErrorType::ERROR_SYSTEM_ERROR; for (auto& path_info : GetPathList()) { @@ -62,7 +62,7 @@ ErrorType CopyRequestHandler::Execute() { bf::path dst_path = dst_root_path / path_info.GetDstPath(); if (bf::is_directory(src_path)) { - if (!CopyDir(src_path, dst_path, + if (!CopyDir(src_path, dst_path, GetUID(), FS_MERGE_OVERWRITE | FS_PRESERVE_OWNERSHIP_AND_PERMISSIONS, true)) { LOG(ERROR) << "Failed to copy directory " << src_path; return ErrorType::ERROR_SYSTEM_ERROR; diff --git a/src/res-copy/src/createdir_request_handler.cc b/src/res-copy/src/createdir_request_handler.cc new file mode 100644 index 0000000..d03f1f5 --- /dev/null +++ b/src/res-copy/src/createdir_request_handler.cc @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2021 Samsung Electronics 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 "include/createdir_request_handler.hh" + +#include +#include + +#include +#include + +#include "include/abstract_request_handler.hh" +#include "include/error_type.hh" +#include "include/file_util.hh" +#include "include/logging.hh" +#include "include/res_path_info.hh" + +namespace bf = boost::filesystem; + +namespace { + +constexpr char kCreateDirReqHandlerType[] = "createdir"; + +} // namespace + +namespace res_handler { + +CreateDirRequestHandler::CreateDirRequestHandler( + std::string pkgid, uid_t uid, std::string root_path, + std::list path_list) : + AbstractRequestHandler(pkgid, uid, root_path, path_list) {} + +ErrorType CreateDirRequestHandler::Execute() { + bf::path root_path(GetRootPath()); + bf::path dst_root_path = root_path / "shared_res" / GetPkgID(); + + if (!CreateDir(dst_root_path, GetUID())) + return ErrorType::ERROR_SYSTEM_ERROR; + + for (auto& path_info : GetPathList()) { + bf::path dst_path = dst_root_path / path_info.GetSrcPath(); + if (!CreateDirs(GetPkgID(), dst_path, GetUID())) + return ErrorType::ERROR_SYSTEM_ERROR; + } + + return ErrorType::ERROR_NONE; +} + +const std::string CreateDirRequestHandler::GetRequestHandlerType() const { + return kCreateDirReqHandlerType; +} + +} // namespace res_handler diff --git a/src/res-copy/src/file_util.cc b/src/res-copy/src/file_util.cc index 87cf65d..b7f1271 100644 --- a/src/res-copy/src/file_util.cc +++ b/src/res-copy/src/file_util.cc @@ -18,10 +18,14 @@ #include "include/file_util.hh" #include +#include #include +#include +#include #include #include +#include #include #include "include/logging.hh" @@ -29,6 +33,13 @@ namespace bs = boost::system; namespace bf = boost::filesystem; +namespace { + +const int32_t kPWBufSize = sysconf(_SC_GETPW_R_SIZE_MAX); +const int32_t kGRBufSize = sysconf(_SC_GETGR_R_SIZE_MAX); + +} // namespace + namespace res_handler { FSFlag operator|(FSFlag a, FSFlag b) { @@ -48,32 +59,6 @@ bool SetDirPermissions(const boost::filesystem::path& path, return true; } -bool SetOwnership(const bf::path& path, uid_t uid, gid_t gid) { - int ret = lchown(path.c_str(), uid, gid); - if (ret != 0) { - LOG(ERROR) << "Failed to change owner of: " << path; - return false; - } - return true; -} - -bool SetDirOwnershipAndPermissions(const boost::filesystem::path& path, - boost::filesystem::perms permissions, uid_t uid, - gid_t gid) { - if (!SetOwnership(path, uid, gid)) { - LOG(ERROR) << "Failed to change owner: " << path - << "(" << uid << ", " << gid << ")"; - return false; - } - if (!SetDirPermissions(path, permissions)) { - LOG(ERROR) << "Failed to change permission: " << path - << std::oct << permissions; - return false; - } - - return true; -} - bool CopyOwnershipAndPermissions(const boost::filesystem::path& src, const boost::filesystem::path& dst) { if (!bf::exists(src)) { @@ -85,6 +70,7 @@ bool CopyOwnershipAndPermissions(const boost::filesystem::path& src, struct stat stats; if (stat(src.c_str(), &stats) != 0) return false; + if (!SetDirOwnershipAndPermissions(dst, permissions, stats.st_uid, stats.st_gid)) { LOG(ERROR) << "Failed to copy ownership and permissions" @@ -111,7 +97,7 @@ bool RemoveAll(const bf::path& path) { bool CopyDir(const boost::filesystem::path& src, const boost::filesystem::path& dst, - FSFlag flags, bool skip_symlink) { + uid_t uid, FSFlag flags, bool skip_symlink) { try { // Check whether the function call is valid if (!bf::exists(src) || !bf::is_directory(src)) { @@ -121,7 +107,7 @@ bool CopyDir(const boost::filesystem::path& src, } if (!bf::exists(dst)) { // Create the destination directory - if (!CreateDir(dst)) { + if (!CreateDir(dst, uid)) { LOG(ERROR) << "Unable to create destination directory" << dst; return false; } @@ -164,7 +150,7 @@ bool CopyDir(const boost::filesystem::path& src, } } else if (bf::is_directory(current)) { // Found directory: Recursion - if (!CopyDir(current, target, flags, skip_symlink)) { + if (!CopyDir(current, target, uid, flags, skip_symlink)) { return false; } } else { @@ -199,18 +185,27 @@ bool CopyDir(const boost::filesystem::path& src, return true; } -bool CreateDir(const bf::path& path) { +bool CreateDir(const bf::path& path, uid_t uid) { if (bf::exists(path)) return true; boost::system::error_code error; - bf::create_directories(path, error); + bf::create_directory(path, error); if (error) { LOG(ERROR) << "Failed to create directory: " << boost::system::system_error(error).what(); return false; } + + boost::optional gid = GetGidByUid(uid); + if (!gid) + return false; + + bf::perms perms755 = bf::all_all ^ bf::group_write ^ bf::others_write; + if (!SetDirOwnershipAndPermissions(path, perms755, uid, *gid)) + return false; + return true; } @@ -223,6 +218,78 @@ bool CopyFile(const bf::path& src, const bf::path& dst) { << error.message() << "]"; return false; } + + if (!CopyOwnershipAndPermissions(src, dst)) { + LOG(ERROR) << "Failed set permission for file " << dst; + return false; + } + + return true; +} + +boost::optional GetGidByUid(uid_t uid) { + struct passwd pwd; + struct passwd* pwd_result; + char buf[kPWBufSize]; + int ret = getpwuid_r(uid, &pwd, buf, sizeof(buf), &pwd_result); + if (ret != 0 || pwd_result == nullptr) + return {}; + return pwd.pw_gid; +} + +bool SetOwnership(const bf::path& path, uid_t uid, gid_t gid) { + int ret = lchown(path.c_str(), uid, gid); + if (ret != 0) { + LOG(ERROR) << "Failed to change owner of: " << path; + return false; + } + return true; +} + +bool SetDirOwnershipAndPermissions(const boost::filesystem::path& path, + boost::filesystem::perms permissions, uid_t uid, + gid_t gid) { + if (!SetOwnership(path, uid, gid)) { + LOG(ERROR) << "Failed to change owner: " << path + << "(" << uid << ", " << gid << ")"; + return false; + } + if (!SetDirPermissions(path, permissions)) { + LOG(ERROR) << "Failed to change permission: " << path + << std::oct << permissions; + return false; + } + + return true; +} + +bool CreateDirs(const std::string& pkgid, const boost::filesystem::path& path, uid_t uid) { + boost::system::error_code error; + bf::create_directories(path, error); + + if (error) { + LOG(ERROR) << "Failed to create directory: " + << boost::system::system_error(error).what(); + return false; + } + + boost::optional gid = GetGidByUid(uid); + bf::perms perms755 = bf::all_all ^ bf::group_write ^ bf::others_write; + if (!gid) + return false; + + bf::path target_path = path; + while(target_path.filename() != pkgid) { + + if (!SetDirOwnershipAndPermissions(target_path, perms755, uid, *gid)) + return false; + + target_path = target_path.parent_path(); + } + + if (!SetDirOwnershipAndPermissions(target_path, perms755, uid, *gid)) + return false; + return true; } diff --git a/src/res-copy/src/param_checker.cc b/src/res-copy/src/param_checker.cc index 259974a..d44ca85 100644 --- a/src/res-copy/src/param_checker.cc +++ b/src/res-copy/src/param_checker.cc @@ -49,6 +49,7 @@ ParamChecker::ParamChecker(int argc, char* argv[]) { ("delete,d", bpo::value(), "delete shared resource for package") ("copy,c", bpo::value(), "copy resource") + ("createdir,D", bpo::value(), "create directories") ("help,h", "Show this message"); bpo::parsed_options parsed_options = bpo::command_line_parser(argc, argv) @@ -67,7 +68,8 @@ ParamChecker::ParamChecker(int argc, char* argv[]) { path_info_list_.emplace_back(o.value.front(), o.value.back()); } else if (o.string_key == "copy" || o.string_key == "delete" || - o.string_key == "remove") { + o.string_key == "remove" || + o.string_key == "createdir") { pkgid_ = o.value.front(); SetRequestType(o.string_key); } else if (o.string_key == "help") { @@ -125,6 +127,8 @@ void ParamChecker::SetRequestType(std::string key) { req_type_ = ReqType::REQ_TYPE_REMOVE; else if (key == "delete") req_type_ = ReqType::REQ_TYPE_UNINSTALL; + else if (key == "createdir") + req_type_ = ReqType::REQ_TYPE_CREATEDIR; } bool ParamChecker::ValidatePkgID() { diff --git a/src/res-copy/src/remove_request_handler.cc b/src/res-copy/src/remove_request_handler.cc index b6fdb74..cc3ed1c 100644 --- a/src/res-copy/src/remove_request_handler.cc +++ b/src/res-copy/src/remove_request_handler.cc @@ -40,9 +40,9 @@ constexpr char kRemoveReqHandlerType[] = "remove"; namespace res_handler { RemoveRequestHandler::RemoveRequestHandler( - std::string pkgid, std::string root_path, + std::string pkgid, uid_t uid, std::string root_path, std::list path_list) : - AbstractRequestHandler(pkgid, root_path, path_list) {} + AbstractRequestHandler(pkgid, uid, root_path, path_list) {} ErrorType RemoveRequestHandler::Execute() { bf::path root_path(GetRootPath()); diff --git a/src/res-copy/src/request_handler_invoker.cc b/src/res-copy/src/request_handler_invoker.cc index c8415a9..588182c 100644 --- a/src/res-copy/src/request_handler_invoker.cc +++ b/src/res-copy/src/request_handler_invoker.cc @@ -24,6 +24,7 @@ #include "include/abstract_request_handler.hh" #include "include/condition_validator.hh" #include "include/copy_request_handler.hh" +#include "include/createdir_request_handler.hh" #include "include/event_signal_sender.hh" #include "include/logging.hh" #include "include/param_checker.hh" @@ -92,6 +93,7 @@ void RequestHandlerInvoker::SetReqHandler() { handler_.reset( new CopyRequestHandler( option_.GetPkgID(), + option_.GetUID(), GetRootPathForUid(option_.GetUID()), option_.GetPathList())); break; @@ -100,6 +102,7 @@ void RequestHandlerInvoker::SetReqHandler() { handler_.reset( new RemoveRequestHandler( option_.GetPkgID(), + option_.GetUID(), GetRootPathForUid(option_.GetUID()), option_.GetPathList())); break; @@ -107,6 +110,15 @@ void RequestHandlerInvoker::SetReqHandler() { handler_.reset( new UninstallRequestHandler( option_.GetPkgID(), + option_.GetUID(), + GetRootPathForUid(option_.GetUID()), + option_.GetPathList())); + break; + case ReqType::REQ_TYPE_CREATEDIR: + handler_.reset( + new CreateDirRequestHandler( + option_.GetPkgID(), + option_.GetUID(), GetRootPathForUid(option_.GetUID()), option_.GetPathList())); break; diff --git a/src/res-copy/src/uninstall_request_handler.cc b/src/res-copy/src/uninstall_request_handler.cc index 6655f1a..da0b841 100644 --- a/src/res-copy/src/uninstall_request_handler.cc +++ b/src/res-copy/src/uninstall_request_handler.cc @@ -37,9 +37,9 @@ constexpr char kUninstallReqHandlerType[] = "delete"; namespace res_handler { UninstallRequestHandler::UninstallRequestHandler( - std::string pkgid, std::string root_path, + std::string pkgid, uid_t uid, std::string root_path, std::list path_list) : - AbstractRequestHandler(pkgid, root_path, path_list) {} + AbstractRequestHandler(pkgid, uid, root_path, path_list) {} ErrorType UninstallRequestHandler::Execute() { if (GetPkgID().length() == 0) { diff --git a/tests/unit_tests/res-copy/data/apps_rw/test_pkg/data/resource_dir1/resource_dir2/resource_file2.txt b/tests/unit_tests/res-copy/data/apps_rw/test_pkg/data/resource_dir1/resource_dir2/resource_file2.txt index 409d6cf..9de57b8 100644 --- a/tests/unit_tests/res-copy/data/apps_rw/test_pkg/data/resource_dir1/resource_dir2/resource_file2.txt +++ b/tests/unit_tests/res-copy/data/apps_rw/test_pkg/data/resource_dir1/resource_dir2/resource_file2.txt @@ -1 +1 @@ -this is second resource file +this is second resource file \ No newline at end of file diff --git a/tests/unit_tests/res-copy/data/apps_rw/test_pkg/data/resource_dir1/resource_file3.txt b/tests/unit_tests/res-copy/data/apps_rw/test_pkg/data/resource_dir1/resource_file3.txt index 241ce06..00a06c3 100644 --- a/tests/unit_tests/res-copy/data/apps_rw/test_pkg/data/resource_dir1/resource_file3.txt +++ b/tests/unit_tests/res-copy/data/apps_rw/test_pkg/data/resource_dir1/resource_file3.txt @@ -1 +1 @@ -this is 3rd resource file +this is 3rd resource file \ No newline at end of file diff --git a/tests/unit_tests/res-copy/data/apps_rw/test_pkg/data/resource_file.txt b/tests/unit_tests/res-copy/data/apps_rw/test_pkg/data/resource_file.txt index 93ec8fc..aa260be 100644 --- a/tests/unit_tests/res-copy/data/apps_rw/test_pkg/data/resource_file.txt +++ b/tests/unit_tests/res-copy/data/apps_rw/test_pkg/data/resource_file.txt @@ -1 +1 @@ -this is resource file to being copied +this is resource file to being copied \ No newline at end of file diff --git a/tests/unit_tests/res-copy/src/test_request_handler.cc b/tests/unit_tests/res-copy/src/test_request_handler.cc index 3586c1b..fbfce84 100644 --- a/tests/unit_tests/res-copy/src/test_request_handler.cc +++ b/tests/unit_tests/res-copy/src/test_request_handler.cc @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -32,6 +33,7 @@ #include "include/abstract_request_handler.hh" #include "include/copy_request_handler.hh" +#include "include/createdir_request_handler.hh" #include "include/error_type.hh" #include "include/param_checker.hh" #include "include/remove_request_handler.hh" @@ -47,6 +49,7 @@ using ::testing::InvokeArgument; using ::testing::SaveArg; using res_handler::CopyRequestHandler; +using res_handler::CreateDirRequestHandler; using res_handler::RemoveRequestHandler; using res_handler::ResPathInfo; using res_handler::UninstallRequestHandler; @@ -64,6 +67,7 @@ class CopyRequestHandlerTest : public TestFixture { virtual void SetUp() { bf::path rootpath(root_path); + bf::create_directories( rootpath / "shared_res/test_pkg/dest_dir"); } @@ -81,6 +85,7 @@ class RemoveRequestHandlerTest : public TestFixture { virtual void SetUp() { bf::path rootpath(root_path); + bf::create_directories( rootpath / "shared_res/test_pkg/new_dir/new_dir2"); @@ -117,10 +122,27 @@ class UninstallRequestHandlerTest : public TestFixture { std::string root_path = "./tests/unit_tests/res-copy/data"; }; +class CreateDirRequestHandlerTest : public TestFixture { + public: + CreateDirRequestHandlerTest() : TestFixture(std::make_unique()) {} + virtual ~CreateDirRequestHandlerTest() {} + + virtual void SetUp() { + bf::path rootpath(root_path); + bf::create_directories( + rootpath / "shared_res/test_pkg/existed_dir"); + } + virtual void TearDown() { + bf::remove_all("./tests/unit_tests/res-copy/data/shared_res/test_pkg"); + } + + std::string root_path = "./tests/unit_tests/res-copy/data"; +}; + TEST_F(CopyRequestHandlerTest, CopyFileAtRootToRoot) { std::list path_list; path_list.emplace_back("data/resource_file.txt", ""); - CopyRequestHandler handler("test_pkg", root_path, path_list); + CopyRequestHandler handler("test_pkg", 0, root_path, path_list); EXPECT_EQ(handler.Execute(), res_handler::ErrorType::ERROR_NONE); @@ -134,7 +156,7 @@ TEST_F(CopyRequestHandlerTest, CopyFileAtRootToRoot) { TEST_F(CopyRequestHandlerTest, CopyFileAtRootToRoot_ChangeFileName) { std::list path_list; path_list.emplace_back("data/resource_file.txt", "another_name.txt"); - CopyRequestHandler handler("test_pkg", root_path, path_list); + CopyRequestHandler handler("test_pkg", 0, root_path, path_list); EXPECT_EQ(handler.Execute(), res_handler::ErrorType::ERROR_NONE); @@ -148,7 +170,7 @@ TEST_F(CopyRequestHandlerTest, CopyFileAtRootToRoot_ChangeFileName) { TEST_F(CopyRequestHandlerTest, CopyFileAtRootToDirectory) { std::list path_list; path_list.emplace_back("data/resource_file.txt", "dest_dir"); - CopyRequestHandler handler("test_pkg", root_path, path_list); + CopyRequestHandler handler("test_pkg", 0, root_path, path_list); EXPECT_EQ(handler.Execute(), res_handler::ErrorType::ERROR_NONE); @@ -165,7 +187,7 @@ TEST_F(CopyRequestHandlerTest, CopyFileAtRootToDirectory) { TEST_F(CopyRequestHandlerTest, CopyFileAtRootToDirectory_ChangeFileName) { std::list path_list; path_list.emplace_back("data/resource_file.txt", "dest_dir/newname.txt"); - CopyRequestHandler handler("test_pkg", root_path, path_list); + CopyRequestHandler handler("test_pkg", 0, root_path, path_list); EXPECT_EQ(handler.Execute(), res_handler::ErrorType::ERROR_NONE); @@ -182,7 +204,7 @@ TEST_F(CopyRequestHandlerTest, CopyFileAtRootToDirectory_ChangeFileName) { TEST_F(CopyRequestHandlerTest, CopyFileAtDirectoryToRoot) { std::list path_list; path_list.emplace_back("data/resource_dir1/resource_file3.txt", ""); - CopyRequestHandler handler("test_pkg", root_path, path_list); + CopyRequestHandler handler("test_pkg", 0, root_path, path_list); EXPECT_EQ(handler.Execute(), res_handler::ErrorType::ERROR_NONE); @@ -197,7 +219,7 @@ TEST_F(CopyRequestHandlerTest, CopyFileAtDirectoryToRoot_ChangeFileName) { std::list path_list; path_list.emplace_back( "data/resource_dir1/resource_file3.txt", "newname.txt"); - CopyRequestHandler handler("test_pkg", root_path, path_list); + CopyRequestHandler handler("test_pkg", 0, root_path, path_list); EXPECT_EQ(handler.Execute(), res_handler::ErrorType::ERROR_NONE); @@ -211,7 +233,7 @@ TEST_F(CopyRequestHandlerTest, CopyFileAtDirectoryToRoot_ChangeFileName) { TEST_F(CopyRequestHandlerTest, CopyFileAtDirectoryToDirectory) { std::list path_list; path_list.emplace_back("data/resource_dir1/resource_file3.txt", "dest_dir"); - CopyRequestHandler handler("test_pkg", root_path, path_list); + CopyRequestHandler handler("test_pkg", 0, root_path, path_list); EXPECT_EQ(handler.Execute(), res_handler::ErrorType::ERROR_NONE); @@ -229,7 +251,7 @@ TEST_F(CopyRequestHandlerTest, CopyDirectoryAtRootToRoot_ChangeFileName) { std::list path_list; path_list.emplace_back( "data/resource_dir1/resource_file3.txt", "dest_dir/newname.txt"); - CopyRequestHandler handler("test_pkg", root_path, path_list); + CopyRequestHandler handler("test_pkg", 0, root_path, path_list); EXPECT_EQ(handler.Execute(), res_handler::ErrorType::ERROR_NONE); @@ -246,7 +268,7 @@ TEST_F(CopyRequestHandlerTest, CopyDirectoryAtRootToRoot_ChangeFileName) { TEST_F(CopyRequestHandlerTest, CopyDirectoryAtRootToRoot) { std::list path_list; path_list.emplace_back("data/resource_dir1", ""); - CopyRequestHandler handler("test_pkg", root_path, path_list); + CopyRequestHandler handler("test_pkg", getuid(), root_path, path_list); EXPECT_EQ(handler.Execute(), res_handler::ErrorType::ERROR_NONE); @@ -267,7 +289,7 @@ TEST_F(CopyRequestHandlerTest, CopyDirectoryAtRootToRoot) { TEST_F(CopyRequestHandlerTest, CopyDirectoryAtRootToDirectory) { std::list path_list; path_list.emplace_back("data/resource_dir1", "dest_dir"); - CopyRequestHandler handler("test_pkg", root_path, path_list); + CopyRequestHandler handler("test_pkg", getuid(), root_path, path_list); EXPECT_EQ(handler.Execute(), res_handler::ErrorType::ERROR_NONE); @@ -291,7 +313,7 @@ TEST_F(CopyRequestHandlerTest, CopyDirectoryAtRootToDirectory) { TEST_F(CopyRequestHandlerTest, CopyDirectoryAtRootToDirectory2) { std::list path_list; path_list.emplace_back("data/resource_dir1", "resource_dir1"); - CopyRequestHandler handler("test_pkg", root_path, path_list); + CopyRequestHandler handler("test_pkg", getuid(), root_path, path_list); EXPECT_EQ(handler.Execute(), res_handler::ErrorType::ERROR_NONE); @@ -315,7 +337,7 @@ TEST_F(CopyRequestHandlerTest, CopyDirectoryAtRootToDirectory2) { TEST_F(CopyRequestHandlerTest, CopyDirectoryAtDirectoryToRoot) { std::list path_list; path_list.emplace_back("data/resource_dir1/resource_dir2", ""); - CopyRequestHandler handler("test_pkg", root_path, path_list); + CopyRequestHandler handler("test_pkg", 0, root_path, path_list); EXPECT_EQ(handler.Execute(), res_handler::ErrorType::ERROR_NONE); @@ -329,7 +351,7 @@ TEST_F(CopyRequestHandlerTest, CopyDirectoryAtDirectoryToRoot) { TEST_F(CopyRequestHandlerTest, CopyDirectoryAtDirectoryToDirectory) { std::list path_list; path_list.emplace_back("data/resource_dir1/resource_dir2", "dest_dir"); - CopyRequestHandler handler("test_pkg", root_path, path_list); + CopyRequestHandler handler("test_pkg", 0, root_path, path_list); EXPECT_EQ(handler.Execute(), res_handler::ErrorType::ERROR_NONE); @@ -346,7 +368,7 @@ TEST_F(CopyRequestHandlerTest, CopyDirectoryAtDirectoryToDirectory) { TEST_F(CopyRequestHandlerTest, ResNotexists) { std::list path_list; path_list.emplace_back("data/not_existed_res", "new_dir"); - CopyRequestHandler handler("test_pkg", root_path, path_list); + CopyRequestHandler handler("test_pkg", 0, root_path, path_list); EXPECT_EQ(handler.Execute(), res_handler::ErrorType::ERROR_RES_NOT_FOUND); } @@ -355,10 +377,10 @@ TEST_F(CopyRequestHandlerTest, ReplaceRes) { std::list path_list; path_list.emplace_back("data/resource_file.txt", "new_dir"); - CopyRequestHandler handler("test_pkg", root_path, path_list); + CopyRequestHandler handler("test_pkg", 0, root_path, path_list); EXPECT_EQ(handler.Execute(), res_handler::ErrorType::ERROR_NONE); - CopyRequestHandler replace_handler("test_pkg", root_path, path_list); + CopyRequestHandler replace_handler("test_pkg", 0, root_path, path_list); EXPECT_EQ(handler.Execute(), res_handler::ErrorType::ERROR_NONE); } @@ -366,7 +388,7 @@ TEST_F(RemoveRequestHandlerTest, RemoveFileAtRoot) { std::list path_list; path_list.emplace_back("resource_file.txt", ""); - RemoveRequestHandler handler("test_pkg", root_path, path_list); + RemoveRequestHandler handler("test_pkg", 0, root_path, path_list); EXPECT_EQ(handler.Execute(), res_handler::ErrorType::ERROR_NONE); bf::path check_path(root_path + "/shared_res/test_pkg/resource_file.txt"); @@ -377,7 +399,7 @@ TEST_F(RemoveRequestHandlerTest, RemoveFileAtDirectory) { std::list path_list; path_list.emplace_back("new_dir/resource_file.txt", ""); - RemoveRequestHandler handler("test_pkg", root_path, path_list); + RemoveRequestHandler handler("test_pkg", 0, root_path, path_list); EXPECT_EQ(handler.Execute(), res_handler::ErrorType::ERROR_NONE); bf::path check_path( @@ -389,7 +411,7 @@ TEST_F(RemoveRequestHandlerTest, RemoveDirectoryAtRoot) { std::list path_list; path_list.emplace_back("new_dir", ""); - RemoveRequestHandler handler("test_pkg", root_path, path_list); + RemoveRequestHandler handler("test_pkg", 0, root_path, path_list); EXPECT_EQ(handler.Execute(), res_handler::ErrorType::ERROR_NONE); bf::path check_path(root_path + "/shared_res/test_pkg/new_dir"); @@ -400,7 +422,7 @@ TEST_F(RemoveRequestHandlerTest, RemoveDirectoryAtDirectory) { std::list path_list; path_list.emplace_back("new_dir/new_dir2", ""); - RemoveRequestHandler handler("test_pkg", root_path, path_list); + RemoveRequestHandler handler("test_pkg", 0, root_path, path_list); EXPECT_EQ(handler.Execute(), res_handler::ErrorType::ERROR_NONE); bf::path check_path(root_path + "/shared_res/test_pkg/new_dir/new_dir2"); @@ -410,7 +432,7 @@ TEST_F(RemoveRequestHandlerTest, RemoveDirectoryAtDirectory) { TEST_F(UninstallRequestHandlerTest, RemoveRootPath) { std::list path_list; - UninstallRequestHandler handler("test_pkg", root_path, path_list); + UninstallRequestHandler handler("test_pkg", 0, root_path, path_list); EXPECT_EQ(handler.Execute(), res_handler::ErrorType::ERROR_NONE); bf::path check_path(root_path + "/shared_res/test_pkg/"); @@ -422,14 +444,69 @@ TEST_F(UninstallRequestHandlerTest, RootNotExists) { bf::path check_path(root_path + "/shared_res/test_pkg/"); bf::remove_all(check_path); - UninstallRequestHandler handler("test_pkg", root_path, path_list); + UninstallRequestHandler handler("test_pkg", 0, root_path, path_list); EXPECT_EQ(handler.Execute(), res_handler::ErrorType::ERROR_NONE); } TEST_F(UninstallRequestHandlerTest, EmptyPkgID) { std::list path_list; - UninstallRequestHandler handler("", root_path, path_list); + UninstallRequestHandler handler("", 0, root_path, path_list); EXPECT_EQ(handler.Execute(), res_handler::ErrorType::ERROR_INVALID_PARAMETER); } + +TEST_F(CreateDirRequestHandlerTest, CreateOneAtRoot) { + std::list path_list; + path_list.emplace_back("new_dir", ""); + + CreateDirRequestHandler handler("test_pkg", getuid(), root_path, path_list); + EXPECT_EQ(handler.Execute(), + res_handler::ErrorType::ERROR_NONE); + + bf::path check_path(root_path + "/shared_res/test_pkg/new_dir"); + EXPECT_TRUE(bf::exists(check_path)); +} + +TEST_F(CreateDirRequestHandlerTest, CreateOneAtExistedDirectory) { + std::list path_list; + path_list.emplace_back("existed_dir/new_dir", ""); + + CreateDirRequestHandler handler("test_pkg", getuid(), root_path, path_list); + EXPECT_EQ(handler.Execute(), + res_handler::ErrorType::ERROR_NONE); + + bf::path check_path(root_path + "/shared_res/test_pkg/existed_dir/new_dir"); + EXPECT_TRUE(bf::exists(check_path)); +} + +TEST_F(CreateDirRequestHandlerTest, CreateHierachyAtRoot) { + std::list path_list; + path_list.emplace_back("new_dir/another_new_dir", ""); + + CreateDirRequestHandler handler("test_pkg", getuid(), root_path, path_list); + EXPECT_EQ(handler.Execute(), + res_handler::ErrorType::ERROR_NONE); + + bf::path check_path(root_path + "/shared_res/test_pkg/new_dir"); + EXPECT_TRUE(bf::exists(check_path)); + + check_path /= "another_new_dir"; + EXPECT_TRUE(bf::exists(check_path)); +} + + +TEST_F(CreateDirRequestHandlerTest, CreateHierachyAtExistedDirectory) { + std::list path_list; + path_list.emplace_back("existed_dir/new_dir/another_new_dir", ""); + + CreateDirRequestHandler handler("test_pkg", getuid(), root_path, path_list); + EXPECT_EQ(handler.Execute(), + res_handler::ErrorType::ERROR_NONE); + + bf::path check_path(root_path + "/shared_res/test_pkg/existed_dir/new_dir"); + EXPECT_TRUE(bf::exists(check_path)); + + check_path /= "another_new_dir"; + EXPECT_TRUE(bf::exists(check_path)); +} diff --git a/tests/unit_tests/res-copy/src/test_request_handler_invoker.cc b/tests/unit_tests/res-copy/src/test_request_handler_invoker.cc index ff8bf6a..ac446a4 100644 --- a/tests/unit_tests/res-copy/src/test_request_handler_invoker.cc +++ b/tests/unit_tests/res-copy/src/test_request_handler_invoker.cc @@ -84,6 +84,15 @@ TEST_F(RequestHandlerInvokerTest, UninstallType) { EXPECT_EQ(request_handler_invoker.GetHandlerType(), "delete"); } +TEST_F(RequestHandlerInvokerTest, CreateDirType) { + const char *argv[] = { "/bin/res-copy", "--uid", "5001", "-D", + "org.test.targetpkgid", "-p", "newdir", nullptr}; + ParamChecker checker(7, (char**)argv); + + RequestHandlerInvoker request_handler_invoker(checker, signal_sender_); + EXPECT_EQ(request_handler_invoker.GetHandlerType(), "createdir"); +} + TEST_F(RequestHandlerInvokerTest, InvalidType) { const char *argv[] = { "/bin/res-copy", "--uid", "5001", nullptr}; ParamChecker checker(3, (char**)argv);