BUNDLE_DEPS
Boost
PKGMGR_INFO_DEPS
+ TZPLATFORM_DEPS
)
# Install
pkgid_(pkgid), path_list_(path_list) {};
virtual ErrorType Execute() = 0;
- virtual std::string GetRequestHandlerType() = 0;
+ virtual const std::string GetRequestHandlerType() const = 0;
protected:
std::string GetRootPath();
#include <list>
#include <string>
+#include "include/error_type.hh"
#include "include/rsc_path_info.hh"
+#include "include/request_type.hh"
namespace rsc_handler {
class ConditionValidator {
public:
- ConditionValidator(std::list<RscPathInfo> list);
- bool ValidateCondition();
+ ConditionValidator(std::string pkgid, uid_t uid);
+ ErrorType ValidateCondition(ReqType req_type,
+ std::list<RscPathInfo> path_list);
private:
- std::list<RscPathInfo> path_info_list_;
+ std::string pkgid_;
+ std::string root_path_;
+ uid_t uid_;
+
+ ErrorType CheckCopyRequest(std::list<RscPathInfo> path_list);
+ ErrorType CheckRemoveRequest(std::list<RscPathInfo> path_list);
};
-} // rsc_handler
+} // namespace rsc_handler
#endif // CONDITION_VALIDATOR_HH_
CopyRequestHandler(std::string pkgid, std::list<RscPathInfo> path_list);
ErrorType Execute() override;
- std::string GetRequestHandlerType() override;
+ const std::string GetRequestHandlerType() const override;
};
} // namespace rsc_handler
ERROR_PKG_NOT_FOUND,
ERROR_PERMISSION_DENIED,
ERROR_SYSTEM_ERROR,
+ ERROR_RES_NOT_FOUND,
ERROR_OUT_OF_SPACE,
ERROR_OUT_OF_MEMORY
};
RemoveRequestHandler(std::string pkgid, std::list<RscPathInfo> path_list);
ErrorType Execute() override;
- std::string GetRequestHandlerType() override;
+ const std::string GetRequestHandlerType() const override;
};
} // namespace rsc_handler
#ifndef REQUEST_HANDLER_INVOKER_HH_
#define REQUEST_HANDLER_INVOKER_HH_
-#include "include/param_checker.hh"
+#include <memory>
+#include <string>
+
+#include "include/abstract_request_handler.hh"
#include "include/event_signal_sender.hh"
+#include "include/param_checker.hh"
namespace rsc_handler {
class RequestHandlerInvoker {
public:
-
RequestHandlerInvoker(ParamChecker option, EventSignalSender signal);
bool Validate();
bool Execute();
+ const std::string GetHandlerType() const;
private:
+ std::unique_ptr<AbstractRequestHandler> handler_;
ParamChecker option_;
EventSignalSender signal_;
+
+ void SetReqHandler();
};
} // rsc_handler
UninstallRequestHandler(std::string pkgid, std::list<RscPathInfo> path_list);
ErrorType Execute() override;
- std::string GetRequestHandlerType() override;
+ const std::string GetRequestHandlerType() const override;
};
} // namespace rsc_handler
#include "include/condition_validator.hh"
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/path.hpp>
+#include <boost/system/error_code.hpp>
+#include <tzplatform_config.h>
+
#include <iostream>
+#include <list>
+#include <string>
+#include "include/logging.hh"
#include "include/request_type.hh"
#include "include/rsc_path_info.hh"
-namespace rsc_handler {
+#include <pkgmgr-info.h>
-ConditionValidator::ConditionValidator(std::list<RscPathInfo> list) :
- path_info_list_(list) {}
+namespace {
+
+std::string GetRootPath(uid_t uid) {
+ tzplatform_set_user(uid);
+ const char* rootpath = tzplatform_getenv(TZ_USER_HOME);
+ tzplatform_reset_user();
+ return rootpath;
+}
-bool ConditionValidator::ValidateCondition() {
- std::cout << "ConditionValidator::ValidateCondition" << std::endl;
+bool IsPackageExists(std::string pkgid, uid_t uid) {
+ pkgmgrinfo_pkginfo_h handle;
+ if (pkgmgrinfo_pkginfo_get_usr_pkginfo(
+ pkgid.c_str(), uid, &handle) != PMINFO_R_OK) {
+ LOG(ERROR) << "package not exists : " << pkgid;
+ return false;
+ }
+ pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
return true;
}
+bool CheckFreeSpaceAtPath(int64_t required_size,
+ const boost::filesystem::path& target_location) {
+ boost::system::error_code error;
+ boost::filesystem::path root = target_location;
+
+ while (!boost::filesystem::exists(root) && root != root.root_path())
+ root = root.parent_path();
+
+ if (!boost::filesystem::exists(root)) {
+ LOG(ERROR) << "No mount point for path: " << target_location;
+ return false;
+ }
+
+ boost::filesystem::space_info space_info =
+ boost::filesystem::space(root, error);
+ if (error) {
+ LOG(ERROR) << "Failed to get space_info: " << error.message();
+ return false;
+ }
+
+ return (space_info.free >= static_cast<uint64_t>(required_size));
+}
+
+} // namespace
+
+namespace rsc_handler {
+
+ConditionValidator::ConditionValidator(std::string pkgid, uid_t uid) :
+ pkgid_(pkgid), uid_(uid) {
+ root_path_ = GetRootPath(uid_);
+}
+
+ErrorType ConditionValidator::ValidateCondition(ReqType req_type,
+ std::list<RscPathInfo> path_list) {
+ if (!IsPackageExists(pkgid_, uid_))
+ return ErrorType::ERROR_PKG_NOT_FOUND;
+
+ if (req_type == ReqType::REQ_TYPE_NEW)
+ return CheckCopyRequest(path_list);
+ else if (req_type == ReqType::REQ_TYPE_REMOVE)
+ return CheckRemoveRequest(path_list);
+
+ return ErrorType::ERROR_NONE;
+}
+
+ErrorType ConditionValidator::CheckCopyRequest(
+ std::list<RscPathInfo> path_list) {
+ boost::filesystem::path src_root_path(root_path_);
+ uintmax_t rsc_size = 0;
+
+ src_root_path = src_root_path / "apps_rw" / pkgid_;
+ for (auto& path_info : path_list) {
+ boost::filesystem::path rsc_path(src_root_path);
+ rsc_path = rsc_path / path_info.GetSrcPath();
+ if (!boost::filesystem::exists(rsc_path)) {
+ LOG(ERROR) << "Resource not exists : " << rsc_path;
+ return ErrorType::ERROR_RES_NOT_FOUND;
+ }
+
+ rsc_size += boost::filesystem::file_size(rsc_path);
+ }
+ LOG(INFO) << "Required size for resource: " << rsc_size;
+
+ if (!CheckFreeSpaceAtPath(static_cast<int64_t>(rsc_size), root_path_)) {
+ LOG(ERROR) << "Not enough space for resource";
+ return ErrorType::ERROR_OUT_OF_SPACE;
+ }
+
+ return ErrorType::ERROR_NONE;
+}
+
+ErrorType ConditionValidator::CheckRemoveRequest(
+ std::list<RscPathInfo> path_list) {
+ for (auto& path_info : path_list) {
+ boost::filesystem::path dst_path(root_path_);
+ dst_path = dst_path / "shared_res"/ pkgid_ / path_info.GetDstPath();
+ if (!boost::filesystem::exists(dst_path)) {
+ LOG(ERROR) << "Resource not exists : " << dst_path;
+ return ErrorType::ERROR_RES_NOT_FOUND;
+ }
+ }
+
+ return ErrorType::ERROR_NONE;
+}
+
} // namespace rsc_handler
return ErrorType::ERROR_NONE;
}
-std::string CopyRequestHandler::GetRequestHandlerType() {
+const std::string CopyRequestHandler::GetRequestHandlerType() const {
return kCopyReqHandlerType;
}
return ErrorType::ERROR_NONE;
}
-std::string RemoveRequestHandler::GetRequestHandlerType() {
+const std::string RemoveRequestHandler::GetRequestHandlerType() const {
return kRemoveReqHandlerType;
}
#include <iostream>
+#include "include/abstract_request_handler.hh"
+#include "include/condition_validator.hh"
+#include "include/copy_request_handler.hh"
#include "include/event_signal_sender.hh"
+#include "include/logging.hh"
#include "include/param_checker.hh"
+#include "include/remove_request_handler.hh"
#include "include/request_type.hh"
+#include "include/uninstall_request_handler.hh"
namespace rsc_handler {
RequestHandlerInvoker::RequestHandlerInvoker(
ParamChecker option, EventSignalSender signal) :
- option_(option), signal_(signal) {}
+ option_(option), signal_(signal) {
+ SetReqHandler();
+}
bool RequestHandlerInvoker::Validate() {
- std::cout << "RequestHandlerInvoker::Validate" << std::endl;
+ if (!option_.Validate()) {
+ LOG(ERROR) << "Parameter validation failed";
+ return false;
+ }
+
+ if (handler_ == nullptr) {
+ LOG(ERROR) << "Failed to initialize handler";
+ return false;
+ }
+
+ ConditionValidator validator(option_.GetPkgID(), option_.GetUID());
+ if (validator.ValidateCondition(
+ option_.GetRequestType(), option_.GetPathList())
+ != ErrorType::ERROR_NONE) {
+ LOG(ERROR) << "Validation failed";
+ return false;
+ }
return true;
}
bool RequestHandlerInvoker::Execute() {
- std::cout << "RequestHandlerInvoker::Execute" << std::endl;
+ if (handler_ == nullptr)
+ return false;
- return true;
+ return handler_->Execute();
+}
+
+const std::string RequestHandlerInvoker::GetHandlerType() const {
+ if (handler_ == nullptr) {
+ LOG(ERROR) << "handler has not initialized";
+ return {};
+ }
+
+ return handler_->GetRequestHandlerType();
+}
+
+void RequestHandlerInvoker::SetReqHandler() {
+ switch (option_.GetRequestType()) {
+ case ReqType::REQ_TYPE_NEW:
+ handler_.reset(
+ new CopyRequestHandler(option_.GetPkgID(), option_.GetPathList()));
+ break;
+ case ReqType::REQ_TYPE_REMOVE:
+
+ handler_.reset(
+ new RemoveRequestHandler(option_.GetPkgID(), option_.GetPathList()));
+ break;
+ case ReqType::REQ_TYPE_UNINSTALL:
+ handler_.reset(
+ new UninstallRequestHandler(
+ option_.GetPkgID(), option_.GetPathList()));
+ break;
+ default:
+ LOG(ERROR) << "Invalid request type";
+ break;
+ }
}
} // namespace rsc_handler
return ErrorType::ERROR_NONE;
}
-std::string UninstallRequestHandler::GetRequestHandlerType() {
+const std::string UninstallRequestHandler::GetRequestHandlerType() const {
return kUninstallReqHandlerType;
}
--- /dev/null
+/*
+ * 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 <stdlib.h>
+#include <gtest/gtest.h>
+#include <stdio.h>
+
+#include <memory>
+
+#include "mock/os_mock.h"
+#include "mock/pkgmgr_info_mock.h"
+#include "mock/test_fixture.h"
+
+#include "include/condition_validator.hh"
+#include "include/param_checker.hh"
+
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::Invoke;
+using ::testing::Return;
+using ::testing::SetArgPointee;
+using ::testing::InvokeArgument;
+using ::testing::SaveArg;
+
+using rsc_handler::ConditionValidator;
+using rsc_handler::ParamChecker;
+
+class Mocks : public ::testing::NiceMock<PkgMgrInfoMock>,
+ public ::testing::NiceMock<OsMock> {};
+
+class ConditionValidatorTest : public TestFixture {
+ public:
+ ConditionValidatorTest() : TestFixture(std::make_unique<Mocks>()) {}
+ virtual ~ConditionValidatorTest() {}
+
+ virtual void SetUp() {
+ EXPECT_CALL(GetMock<PkgMgrInfoMock>(), pkgmgrinfo_pkginfo_get_usr_pkginfo(_, _, _))
+ .WillRepeatedly(Return(0));
+ EXPECT_CALL(GetMock<PkgMgrInfoMock>(), pkgmgrinfo_pkginfo_destroy_pkginfo(_))
+ .WillRepeatedly(Return(0)) ;
+ }
+ virtual void TearDown() {}
+};
+
+TEST_F(ConditionValidatorTest, PkgNotExist) {
+ EXPECT_CALL(GetMock<PkgMgrInfoMock>(), pkgmgrinfo_pkginfo_get_usr_pkginfo(_, _, _))
+ .WillRepeatedly(Return(-1));
+
+ const char *argv[] = { "/bin/rsc-copy", "--uid", "5001", "--copy",
+ "org.test.targetpkgid", "-p", "srcpath", "dstpath", nullptr};
+ ParamChecker checker(8, (char**)argv);
+ ConditionValidator validator(checker.GetPkgID(), checker.GetUID());
+ rsc_handler::ErrorType ret = validator.ValidateCondition(
+ checker.GetRequestType(), checker.GetPathList());
+
+ EXPECT_EQ(ret, rsc_handler::ErrorType::ERROR_PKG_NOT_FOUND);
+}
+
+TEST_F(ConditionValidatorTest, CopyPkgNotExist) {
+ EXPECT_CALL(GetMock<PkgMgrInfoMock>(), pkgmgrinfo_pkginfo_get_usr_pkginfo(_, _, _))
+ .WillRepeatedly(Return(-1));
+
+ const char *argv[] = { "/bin/rsc-copy", "--uid", "5001", "--copy",
+ "org.test.targetpkgid", "-p", "srcpath", "dstpath", nullptr};
+ ParamChecker checker(8, (char**)argv);
+ ConditionValidator validator(checker.GetPkgID(), checker.GetUID());
+ rsc_handler::ErrorType ret = validator.ValidateCondition(
+ checker.GetRequestType(), checker.GetPathList());
+
+ EXPECT_EQ(ret, rsc_handler::ErrorType::ERROR_PKG_NOT_FOUND);
+}
+
+TEST_F(ConditionValidatorTest, CopySrcNotExist) {
+ const char *argv[] = { "/bin/rsc-copy", "--uid", "5001", "--copy",
+ "org.test.targetpkgid", "-p", "srcpath", "dstpath", nullptr};
+ ParamChecker checker(8, (char**)argv);
+ ConditionValidator validator(checker.GetPkgID(), checker.GetUID());
+ rsc_handler::ErrorType ret = validator.ValidateCondition(
+ checker.GetRequestType(), checker.GetPathList());
+
+ EXPECT_EQ(ret, rsc_handler::ErrorType::ERROR_RES_NOT_FOUND);
+}
+
+TEST_F(ConditionValidatorTest, RemovePkgNotExist) {
+ EXPECT_CALL(GetMock<PkgMgrInfoMock>(), pkgmgrinfo_pkginfo_get_usr_pkginfo(_, _, _))
+ .WillRepeatedly(Return(-1));
+
+ const char *argv[] = { "/bin/rsc-copy", "--uid", "5001", "--remove",
+ "org.test.targetpkgid", "-p", "", "dstpath", nullptr};
+ ParamChecker checker(8, (char**)argv);
+ ConditionValidator validator(checker.GetPkgID(), checker.GetUID());
+ rsc_handler::ErrorType ret = validator.ValidateCondition(
+ checker.GetRequestType(), checker.GetPathList());
+
+ EXPECT_EQ(ret, rsc_handler::ErrorType::ERROR_PKG_NOT_FOUND);
+}
+
+TEST_F(ConditionValidatorTest, RemoveSrcNotExist) {
+ const char *argv[] = { "/bin/rsc-copy", "--uid", "5001", "--remove",
+ "org.test.targetpkgid", "-p", "", "dstpath", nullptr};
+ ParamChecker checker(8, (char**)argv);
+ ConditionValidator validator(checker.GetPkgID(), checker.GetUID());
+ rsc_handler::ErrorType ret = validator.ValidateCondition(
+ checker.GetRequestType(), checker.GetPathList());
+
+ EXPECT_EQ(ret, rsc_handler::ErrorType::ERROR_RES_NOT_FOUND);
+}
+
+TEST_F(ConditionValidatorTest, DeletePkgNotExist) {
+ EXPECT_CALL(GetMock<PkgMgrInfoMock>(), pkgmgrinfo_pkginfo_get_usr_pkginfo(_, _, _))
+ .WillRepeatedly(Return(-1));
+
+ const char *argv[] = { "/bin/rsc-copy", "--uid", "5001", "--delete",
+ "org.test.targetpkgid", nullptr};
+ ParamChecker checker(5, (char**)argv);
+ ConditionValidator validator(checker.GetPkgID(), checker.GetUID());
+ rsc_handler::ErrorType ret = validator.ValidateCondition(
+ checker.GetRequestType(), checker.GetPathList());
+
+ EXPECT_EQ(ret, rsc_handler::ErrorType::ERROR_PKG_NOT_FOUND);
+}
+
--- /dev/null
+/*
+ * 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 <stdlib.h>
+#include <gtest/gtest.h>
+#include <stdio.h>
+
+#include <memory>
+
+#include "mock/os_mock.h"
+#include "mock/pkgmgr_info_mock.h"
+#include "mock/test_fixture.h"
+#include "include/event_signal_sender.hh"
+#include "include/param_checker.hh"
+#include "include/request_handler_invoker.hh"
+#include "include/request_type.hh"
+
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::Invoke;
+using ::testing::Return;
+using ::testing::SetArgPointee;
+using ::testing::InvokeArgument;
+using ::testing::SaveArg;
+
+using rsc_handler::ParamChecker;
+using rsc_handler::RequestHandlerInvoker;
+
+class Mocks : public ::testing::NiceMock<PkgMgrInfoMock>,
+ public ::testing::NiceMock<OsMock> {};
+
+class RequestHandlerInvokerTest : public TestFixture {
+ public:
+ RequestHandlerInvokerTest() : TestFixture(std::make_unique<Mocks>()) {
+ signal_sender_.SetPkgID("org.tizen.targepkgid");
+ signal_sender_.SetReqType(rsc_handler::ReqType::REQ_TYPE_UNKNOWN);
+ }
+ virtual ~RequestHandlerInvokerTest() {}
+
+ virtual void SetUp() {}
+ virtual void TearDown() {}
+
+ rsc_handler::EventSignalSender signal_sender_;
+};
+
+TEST_F(RequestHandlerInvokerTest, CopyType) {
+ const char *argv[] = { "/bin/rsc-copy", "--uid", "5001", "--copy",
+ "org.test.targetpkgid", "-p", "srcpath", "dstpath", nullptr};
+ ParamChecker checker(8, (char**)argv);
+
+ RequestHandlerInvoker request_handler_invoker(checker, signal_sender_);
+ EXPECT_EQ(request_handler_invoker.GetHandlerType(), "copy");
+
+}
+
+TEST_F(RequestHandlerInvokerTest, RemoveType) {
+ const char *argv[] = { "/bin/rsc-copy", "--uid", "5001", "--remove",
+ "org.test.targetpkgid", "-p", "", "dstpath", nullptr};
+ ParamChecker checker(8, (char**)argv);
+
+ RequestHandlerInvoker request_handler_invoker(checker, signal_sender_);
+ EXPECT_EQ(request_handler_invoker.GetHandlerType(), "remove");
+}
+
+TEST_F(RequestHandlerInvokerTest, UninstallType) {
+ const char *argv[] = { "/bin/rsc-copy", "--uid", "5001", "--delete",
+ "org.test.targetpkgid", nullptr};
+ ParamChecker checker(5, (char**)argv);
+
+ RequestHandlerInvoker request_handler_invoker(checker, signal_sender_);
+ EXPECT_EQ(request_handler_invoker.GetHandlerType(), "delete");
+}
+
+TEST_F(RequestHandlerInvokerTest, InvalidType) {
+ const char *argv[] = { "/bin/rsc-copy", "--uid", "5001", nullptr};
+ ParamChecker checker(3, (char**)argv);
+
+ RequestHandlerInvoker request_handler_invoker(checker, signal_sender_);
+ EXPECT_EQ(request_handler_invoker.GetHandlerType(), "");
+ EXPECT_EQ(request_handler_invoker.Execute(), false);
+}