From d6c5d0e1c20017f38e68748558842e4b076c90b8 Mon Sep 17 00:00:00 2001 From: Piotr Ganicz Date: Fri, 17 Feb 2017 14:11:30 +0100 Subject: [PATCH] Export Smoke Utils This change exports utility functions to smoke_utils.h Change-Id: I5035f0775af2749dbd07fe3d2970446f877d522d --- src/unit_tests/CMakeLists.txt | 2 + src/unit_tests/smoke_test.cc | 650 +----------------------------------------- src/unit_tests/smoke_utils.cc | 601 ++++++++++++++++++++++++++++++++++++++ src/unit_tests/smoke_utils.h | 212 ++++++++++++++ 4 files changed, 816 insertions(+), 649 deletions(-) create mode 100644 src/unit_tests/smoke_utils.cc create mode 100644 src/unit_tests/smoke_utils.h diff --git a/src/unit_tests/CMakeLists.txt b/src/unit_tests/CMakeLists.txt index dcb4d43..f0bc796 100644 --- a/src/unit_tests/CMakeLists.txt +++ b/src/unit_tests/CMakeLists.txt @@ -3,6 +3,8 @@ SET(DESTINATION_DIR tpk-backend-ut) # Executables ADD_EXECUTABLE(${TARGET_SMOKE_TEST} smoke_test.cc + smoke_utils.h + smoke_utils.cc ) ADD_EXECUTABLE(${TARGET_SMOKE_TEST_HELPER} diff --git a/src/unit_tests/smoke_test.cc b/src/unit_tests/smoke_test.cc index 71d9e5d..09bb300 100644 --- a/src/unit_tests/smoke_test.cc +++ b/src/unit_tests/smoke_test.cc @@ -2,661 +2,13 @@ // Use of this source code is governed by an apache-2.0 license that can be // found in the LICENSE file. -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include #include -#include #include #include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "tpk/tpk_app_query_interface.h" -#include "tpk/tpk_installer.h" - -#define SIZEOFARRAY(ARR) \ - sizeof(ARR) / sizeof(ARR[0]) \ - -namespace bf = boost::filesystem; -namespace bs = boost::system; -namespace ci = common_installer; - -namespace { - -const uid_t kGlobalUserUid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER); -const uid_t kGlobalUserGid = tzplatform_getgid(TZ_SYS_GLOBALAPP_USER); -const uid_t kDefaultUserUid = tzplatform_getuid(TZ_SYS_DEFAULT_USER); -// TODO(s89.jang): Test local case also -const uid_t kTestUserId = kGlobalUserUid; -const gid_t kTestGroupId = kGlobalUserGid; -const char kSystemShareGroupName[] = "system_share"; -const std::string& kTestUserIdStr = std::to_string(kTestUserId); -const std::string& kDefaultUserIdStr = std::to_string(kDefaultUserUid); -const char kLegacyExtImageDir[] = "legacy_extimage_dir"; -const char kMigrateTestDBName[] = "app2sd_migrate.db"; - -const bf::path kSmokePackagesDirectory = - "/usr/share/tpk-backend-ut/test_samples/smoke/"; - -// common entries -const std::vector kDBEntries = { - {".pkgmgr_parser.db"}, - {".pkgmgr_parser.db-journal"}, - {".pkgmgr_cert.db"}, - {".pkgmgr_cert.db-journal"}, - {".app2sd.db"}, - {".app2sd.db-journal"}, -}; -// globaluser entries -const char kGlobalManifestDir[] = "/opt/share/packages"; -const char kSkelDir[] = "/etc/skel/apps_rw"; -const char kPreloadApps[] = "/usr/apps"; -const char kPreloadManifestDir[] = "/usr/share/packages"; -const char kPreloadIcons[] = "/usr/share/icons"; - -enum class RequestResult { - NORMAL, - FAIL -}; - -class ScopedTzipInterface { - public: - explicit ScopedTzipInterface(const std::string& pkgid) - : pkg_path_(bf::path(ci::GetRootAppPath(false, - kTestUserId)) / pkgid), - interface_(ci::GetMountLocation(pkg_path_)), - mounted_(true) { - interface_.MountZip(ci::GetZipPackageLocation(pkg_path_, pkgid)); - } - - void Release() { - if (mounted_) { - interface_.UnmountZip(); - mounted_ = false; - } - } - - ~ScopedTzipInterface() { - Release(); - } - - private: - bf::path pkg_path_; - ci::TzipInterface interface_; - bool mounted_; -}; - -bool TouchFile(const bf::path& path) { - FILE* f = fopen(path.c_str(), "w+"); - if (!f) - return false; - fclose(f); - return true; -} - -class TestPkgmgrInstaller : public ci::PkgmgrInstallerInterface { - public: - bool CreatePkgMgrInstaller(pkgmgr_installer** installer, - ci::InstallationMode* mode) { - *installer = pkgmgr_installer_offline_new(); - if (!*installer) - return false; - *mode = ci::InstallationMode::ONLINE; - return true; - } - - bool ShouldCreateSignal() const { - return false; - } -}; - -void RemoveAllRecoveryFiles() { - bf::path root_path = ci::GetRootAppPath(false, - kTestUserId); - if (!bf::exists(root_path)) - return; - for (auto& dir_entry : boost::make_iterator_range( - bf::directory_iterator(root_path), bf::directory_iterator())) { - if (bf::is_regular_file(dir_entry)) { - if (dir_entry.path().string().find("/tpk-recovery") != - std::string::npos) { - bs::error_code error; - bf::remove(dir_entry.path(), error); - } - } - } -} - -bf::path FindRecoveryFile() { - bf::path root_path = ci::GetRootAppPath(false, - kTestUserId); - for (auto& dir_entry : boost::make_iterator_range( - bf::directory_iterator(root_path), bf::directory_iterator())) { - if (bf::is_regular_file(dir_entry)) { - if (dir_entry.path().string().find("/tpk-recovery") != std::string::npos) - return dir_entry.path(); - } - } - return {}; -} - -bool ValidateFileContentInPackage(const std::string& pkgid, - const std::string& relative, - const std::string& expected, - bool is_readonly = false) { - bf::path root_path = ci::GetRootAppPath(is_readonly, - kTestUserId); - bf::path file_path = root_path / pkgid / relative; - if (!bf::exists(file_path)) { - LOG(ERROR) << file_path << " doesn't exist"; - return false; - } - FILE* handle = fopen(file_path.c_str(), "r"); - if (!handle) { - LOG(ERROR) << file_path << " cannot be open"; - return false; - } - std::string content; - std::array buffer; - while (fgets(buffer.data(), buffer.size(), handle)) { - content += buffer.data(); - } - fclose(handle); - return content == expected; -} - -void ValidatePackageRWFS(const std::string& pkgid, uid_t uid) { - bf::path root_path = ci::GetRootAppPath(false, uid); - bf::path package_path = root_path / pkgid; - bf::path data_path = package_path / "data"; - bf::path cache_path = package_path / "cache"; - bf::path shared_data_path = package_path / "shared" / "data"; - - ASSERT_TRUE(bf::exists(data_path)); - ASSERT_TRUE(bf::exists(cache_path)); - - struct stat stats; - stat(data_path.c_str(), &stats); - // gid of RW dirs should be system_share - boost::optional system_share = - ci::GetGidByGroupName(kSystemShareGroupName); - ASSERT_EQ(uid, stats.st_uid) << "Invalid gid: " << data_path; - ASSERT_EQ(*system_share, stats.st_gid) << "Invalid gid: " << data_path; - if (bf::exists(shared_data_path)) { - stat(shared_data_path.c_str(), &stats); - ASSERT_EQ(uid, stats.st_uid) << "Invalid gid: " << shared_data_path; - ASSERT_EQ(*system_share, stats.st_gid) << "Invalid gid: " - << shared_data_path; - } - - stat(cache_path.c_str(), &stats); - ASSERT_EQ(uid, stats.st_uid) << "Invalid gid: " << cache_path; - ASSERT_EQ(*system_share, stats.st_gid) << "Invalid gid: " << cache_path; -} - -void ValidatePackageFS(const std::string& pkgid, const std::string& appid, - uid_t uid, gid_t gid, bool is_readonly = false) { - bf::path root_path = ci::GetRootAppPath(is_readonly, uid); - bf::path package_path = root_path / pkgid; - bf::path shared_path = package_path / "shared"; - ASSERT_TRUE(bf::exists(root_path)); - ASSERT_TRUE(bf::exists(package_path)); - ASSERT_TRUE(bf::exists(shared_path)); - - bf::path manifest_path = - bf::path(getUserManifestPath(uid, is_readonly)) / (pkgid + ".xml"); - ASSERT_TRUE(bf::exists(manifest_path)); - - // backups should not exist - bf::path package_backup = ci::GetBackupPathForPackagePath(package_path); - bf::path manifest_backup = ci::GetBackupPathForManifestFile(manifest_path); - ASSERT_FALSE(bf::exists(package_backup)); - ASSERT_FALSE(bf::exists(manifest_backup)); - - for (bf::recursive_directory_iterator iter(package_path); - iter != bf::recursive_directory_iterator(); ++iter) { - if (bf::is_symlink(symlink_status(iter->path()))) - continue; - if (iter->path().filename() == "data" || - iter->path().filename() == ".mmc") - continue; - struct stat stats; - stat(iter->path().c_str(), &stats); - ASSERT_EQ(uid, stats.st_uid) << "Invalid uid: " << iter->path(); - ASSERT_EQ(gid, stats.st_gid) << "Invalid gid: " << iter->path(); - } -} - -void PackageCheckCleanup(const std::string& pkgid, const std::string&, - bool is_readonly = false) { - bf::path root_path = ci::GetRootAppPath(is_readonly, - kTestUserId); - bf::path package_path = root_path / pkgid; - ASSERT_FALSE(bf::exists(package_path)); - - bf::path manifest_path = - bf::path(getUserManifestPath( - kTestUserId, is_readonly)) / (pkgid + ".xml"); - ASSERT_FALSE(bf::exists(manifest_path)); - - // backups should not exist - bf::path package_backup = ci::GetBackupPathForPackagePath(package_path); - bf::path manifest_backup = ci::GetBackupPathForManifestFile(manifest_path); - ASSERT_FALSE(bf::exists(package_backup)); - ASSERT_FALSE(bf::exists(manifest_backup)); -} - -void ValidatePackage(const std::string& pkgid, const std::string& appid, - bool is_readonly = false) { - ASSERT_TRUE(ci::QueryIsPackageInstalled( - pkgid, ci::GetRequestMode(kTestUserId), - kTestUserId)); - ValidatePackageFS(pkgid, appid, kTestUserId, kTestGroupId, is_readonly); - if (kTestUserId == kGlobalUserUid) { - ci::UserList list = ci::GetUserList(); - for (auto& l : list) - ValidatePackageRWFS(pkgid, std::get<0>(l)); - } else { - ValidatePackageRWFS(pkgid, kTestUserId); - } -} - -void ValidateExternalPackage_FS(const std::string& pkgid, - const std::string& appid, uid_t uid) { - ASSERT_EQ(app2ext_usr_enable_external_pkg(pkgid.c_str(), uid), 0); - bf::path root_path = ci::GetRootAppPath(false, uid); - ASSERT_TRUE(bf::exists(root_path / pkgid / ".mmc" / "bin")); - ASSERT_TRUE(bf::exists(root_path / pkgid / ".mmc" / "lib")); - ASSERT_TRUE(bf::exists(root_path / pkgid / ".mmc" / "res")); - ValidatePackage(pkgid, appid); - ASSERT_EQ(app2ext_usr_disable_external_pkg(pkgid.c_str(), uid), 0); -} - -void ValidateExternalPackage(const std::string& pkgid, - const std::string& appid) { - std::string storage = ci::QueryStorageForPkgId(pkgid, kTestUserId); - bf::path ext_mount_path = ci::GetExternalCardPath(); - if (bf::is_empty(ext_mount_path)) { - LOG(INFO) << "Sdcard not exists!"; - ASSERT_EQ(storage, "installed_internal"); - } else { - ASSERT_EQ(storage, "installed_external"); - } - ValidateExternalPackage_FS(pkgid, appid, kTestUserId); -} - -void CheckPackageNonExistance(const std::string& pkgid, - const std::string& appid, - bool is_readonly = false) { - ASSERT_FALSE(ci::QueryIsPackageInstalled( - pkgid, ci::GetRequestMode(kTestUserId), - kTestUserId)); - PackageCheckCleanup(pkgid, appid, is_readonly); - if (kTestUserId == kGlobalUserUid) { - bf::path skel_path(kSkelDir); - ASSERT_FALSE(bf::exists(skel_path / pkgid)); - ci::UserList list = ci::GetUserList(); - for (auto& l : list) { - bf::path root_path = ci::GetRootAppPath(false, std::get<0>(l)); - bf::path package_path = root_path / pkgid; - ASSERT_FALSE(bf::exists(package_path)); - } - } -} - -std::unique_ptr CreateQueryInterface() { - std::unique_ptr query_interface( - new tpk::TpkAppQueryInterface()); - return query_interface; -} - -std::unique_ptr CreateInstaller(ci::PkgMgrPtr pkgmgr) { - std::unique_ptr installer(new tpk::TpkInstaller(pkgmgr)); - return installer; -} - -ci::AppInstaller::Result RunInstallerWithPkgrmgr(ci::PkgMgrPtr pkgmgr, - RequestResult mode) { - std::unique_ptr installer = CreateInstaller(pkgmgr); - switch (mode) { - case RequestResult::FAIL: - installer->AddStep(); - break; - default: - break; - } - return installer->Run(); -} -ci::AppInstaller::Result CallBackend(int argc, - const char* argv[], - RequestResult mode) { - TestPkgmgrInstaller pkgmgr_installer; - std::unique_ptr query_interface = - CreateQueryInterface(); - auto pkgmgr = - ci::PkgMgrInterface::Create(argc, const_cast(argv), - &pkgmgr_installer, - query_interface.get()); - if (!pkgmgr) { - LOG(ERROR) << "Failed to initialize pkgmgr interface"; - return ci::AppInstaller::Result::UNKNOWN; - } - return RunInstallerWithPkgrmgr(pkgmgr, mode); -} - -ci::AppInstaller::Result Install(const bf::path& path, - RequestResult mode = RequestResult::NORMAL) { - const char* argv[] = {"", "-i", path.c_str(), "-u", kTestUserIdStr.c_str()}; - return CallBackend(SIZEOFARRAY(argv), argv, mode); -} - -ci::AppInstaller::Result InstallPreload(const bf::path& path, - RequestResult mode = RequestResult::NORMAL) { - const char* argv[] = {"", "-i", path.c_str(), "--preload"}; - return CallBackend(SIZEOFARRAY(argv), argv, mode); -} -bool CheckAvailableExternalPath() { - bf::path ext_mount_path = ci::GetExternalCardPath(); - LOG(DEBUG) << "ext_mount_path :" << ext_mount_path; - if (ext_mount_path.empty()) { - LOG(ERROR) << "Sdcard not exists!"; - return false; - } - return true; -} - -ci::AppInstaller::Result InstallExternal(const bf::path& path, - RequestResult mode = RequestResult::NORMAL) { - int default_storage = 0; - vconf_get_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT, - &default_storage); - vconf_set_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT, 1); - - const char* argv[] = {"", "-i", path.c_str(), "-u", kTestUserIdStr.c_str()}; - ci::AppInstaller::Result result = CallBackend(SIZEOFARRAY(argv), argv, mode); - - vconf_set_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT, - default_storage); - return result; -} - -ci::AppInstaller::Result MigrateLegacyExternalImage(const std::string& pkgid, - const bf::path& path, - const bf::path& legacy_path, - RequestResult mode = RequestResult::NORMAL) { - if (InstallExternal(path) != ci::AppInstaller::Result::OK) { - LOG(ERROR) << "Failed to install application. Cannot perform Migrate"; - return ci::AppInstaller::Result::ERROR; - } - - bf::path ext_mount_path = ci::GetExternalCardPath(); - if (bf::is_empty(ext_mount_path)) { - LOG(ERROR) << "Sdcard not exists!"; - return ci::AppInstaller::Result::ERROR; - } - bf::path app2sd_path = ext_mount_path / "app2sd"; - - char *image_name = app2ext_usr_getname_image(pkgid.c_str(), - kGlobalUserUid); - if (!image_name) { - LOG(ERROR) << "Failed to get external image name"; - return ci::AppInstaller::Result::ERROR; - } - bf::path org_image = app2sd_path / image_name; - free(image_name); - - bs::error_code error; - bf::remove(org_image, error); - if (error) { - LOG(ERROR) << "Failed to remove org image"; - return ci::AppInstaller::Result::ERROR; - } - - bf::path db_path = tzplatform_getenv(TZ_SYS_DB); - bf::path app2sd_db = db_path / ".app2sd.db"; - bf::path app2sd_db_journal = db_path / ".app2sd.db-journal"; - bf::remove(app2sd_db, error); - if (error) { - LOG(ERROR) << "Failed to remove app2sd db"; - return ci::AppInstaller::Result::ERROR; - } - bf::remove(app2sd_db_journal, error); - if (error) { - LOG(ERROR) << "Failed to remove app2sd journal db"; - return ci::AppInstaller::Result::ERROR; - } - - bf::path app2sd_migrate_db = legacy_path / kMigrateTestDBName; - if (!ci::CopyFile(app2sd_migrate_db, app2sd_db)) { - LOG(ERROR) << "Failed to copy test db"; - return ci::AppInstaller::Result::ERROR; - } - - bf::path legacy_src = legacy_path / pkgid; - bf::path legacy_dst = app2sd_path / pkgid; - if (!ci::CopyFile(legacy_src, legacy_dst)) { - LOG(ERROR) << "Failed to copy test image"; - return ci::AppInstaller::Result::ERROR; - } - const char* argv[] = {"", "--migrate-extimg", pkgid.c_str(), - "-u", kDefaultUserIdStr.c_str()}; - return CallBackend(SIZEOFARRAY(argv), argv, mode); -} - -ci::AppInstaller::Result InstallWithTEP( - const bf::path& path, - const bf::path& tep, - RequestResult mode = RequestResult::NORMAL) { - const char* argv[] = {"", "-i", path.c_str(), "-u", kTestUserIdStr.c_str(), - "-e", tep.c_str()}; - return CallBackend(SIZEOFARRAY(argv), argv, mode); -} - -ci::AppInstaller::Result Update(const bf::path& path_old, - const bf::path& path_new, - RequestResult mode = RequestResult::NORMAL) { - if (Install(path_old) != ci::AppInstaller::Result::OK) { - LOG(ERROR) << "Failed to install application. Cannot update"; - return ci::AppInstaller::Result::UNKNOWN; - } - return Install(path_new, mode); -} - -ci::AppInstaller::Result MountInstall(const bf::path& path, - RequestResult mode = RequestResult::NORMAL) { - const char* argv[] = {"", "-w", path.c_str(), "-u", kTestUserIdStr.c_str()}; - return CallBackend(SIZEOFARRAY(argv), argv, mode); -} - -ci::AppInstaller::Result MountInstallWithTEP( - const bf::path& path, - const bf::path& tep, - RequestResult mode = RequestResult::NORMAL) { - const char* argv[] = {"", "-w", path.c_str(), "-u", kTestUserIdStr.c_str(), - "-e", tep.c_str()}; - return CallBackend(SIZEOFARRAY(argv), argv, mode); -} - -ci::AppInstaller::Result MountUpdate(const bf::path& path_old, - const bf::path& path_new, - RequestResult mode = RequestResult::NORMAL) { - if (MountInstall(path_old) != ci::AppInstaller::Result::OK) { - LOG(ERROR) << "Failed to mount-install application. Cannot mount-update"; - return ci::AppInstaller::Result::UNKNOWN; - } - return MountInstall(path_new, mode); -} - -ci::AppInstaller::Result Uninstall(const std::string& pkgid, bool is_readonly, - RequestResult mode = RequestResult::NORMAL) { - if (is_readonly) { - const char* argv[] = {"", "-d", pkgid.c_str(), "--preload", - "--force-remove"}; - return CallBackend(SIZEOFARRAY(argv), argv, mode); - } else { - const char* argv[] = {"", "-d", pkgid.c_str(), "-u", - kTestUserIdStr.c_str()}; - return CallBackend(SIZEOFARRAY(argv), argv, mode); - } -} - -ci::AppInstaller::Result EnablePackage(const std::string& path, - RequestResult mode = RequestResult::NORMAL) { - const char* argv[] = {"", "-A", path.c_str(), "-u", kTestUserIdStr.c_str()}; - return CallBackend(SIZEOFARRAY(argv), argv, mode); -} - -ci::AppInstaller::Result DisablePackage(const std::string& path, - RequestResult mode = RequestResult::NORMAL) { - const char* argv[] = {"", "-D", path.c_str(), "-u", kTestUserIdStr.c_str()}; - return CallBackend(SIZEOFARRAY(argv), argv, mode); -} - -ci::AppInstaller::Result RDSUpdate(const bf::path& path, - const std::string& pkgid, - RequestResult mode = RequestResult::NORMAL) { - if (Install(path) != ci::AppInstaller::Result::OK) { - LOG(ERROR) << "Failed to install application. Cannot perform RDS"; - return ci::AppInstaller::Result::UNKNOWN; - } - const char* argv[] = {"", "-r", pkgid.c_str(), "-u", - kTestUserIdStr.c_str()}; - return CallBackend(SIZEOFARRAY(argv), argv, mode); -} - -ci::AppInstaller::Result DeltaInstall(const bf::path& path, - const bf::path& delta_package) { - if (Install(path) != ci::AppInstaller::Result::OK) { - LOG(ERROR) << "Failed to install application. Cannot perform RDS"; - return ci::AppInstaller::Result::UNKNOWN; - } - return Install(delta_package); -} - -ci::AppInstaller::Result Recover(const bf::path& recovery_file, - RequestResult mode = RequestResult::NORMAL) { - const char* argv[] = {"", "-b", recovery_file.c_str(), "-u", - kTestUserIdStr.c_str()}; - return CallBackend(SIZEOFARRAY(argv), argv, mode); -} - -void BackupPath(const bf::path& path) { - bf::path backup_path = path.string() + ".bck"; - std::cout << "Backup path: " << path << " to " << backup_path << std::endl; - bs::error_code error; - bf::remove_all(backup_path, error); - if (error) - LOG(ERROR) << "Remove failed: " << backup_path - << " (" << error.message() << ")"; - if (bf::exists(path)) { - bf::rename(path, backup_path, error); - if (error) - LOG(ERROR) << "Failed to setup test environment. Does some previous" - << " test crashed? Path: " - << backup_path << " should not exist."; - assert(!error); - } -} - -void RestorePath(const bf::path& path) { - bf::path backup_path = path.string() + ".bck"; - std::cout << "Restore path: " << path << " from " << backup_path << std::endl; - bs::error_code error; - bf::remove_all(path, error); - if (error) - LOG(ERROR) << "Remove failed: " << path - << " (" << error.message() << ")"; - if (bf::exists(backup_path)) { - bf::rename(backup_path, path, error); - if (error) - LOG(ERROR) << "Failed to restore backup path: " << backup_path - << " (" << error.message() << ")"; - } -} - -std::vector SetupBackupDirectories(uid_t uid) { - std::vector entries; - bf::path db_dir = bf::path(tzplatform_getenv(TZ_SYS_DB)); - if (uid != kGlobalUserUid) - db_dir = db_dir / "user" / std::to_string(uid); - for (auto e : kDBEntries) { - bf::path path = db_dir / e; - entries.emplace_back(path); - } - - if (getuid() == 0) { - entries.emplace_back(kPreloadApps); - entries.emplace_back(kPreloadManifestDir); - entries.emplace_back(kPreloadIcons); - } - - if (uid == kGlobalUserUid) { - entries.emplace_back(kSkelDir); - entries.emplace_back(kGlobalManifestDir); - ci::UserList list = ci::GetUserList(); - for (auto l : list) { - bf::path apps = std::get<2>(l) / "apps_rw"; - entries.emplace_back(apps); - } - } else { - tzplatform_set_user(uid); - bf::path approot = tzplatform_getenv(TZ_USER_APPROOT); - tzplatform_reset_user(); - entries.emplace_back(approot); - } - - bf::path apps_rw = ci::GetRootAppPath(false, uid); - entries.emplace_back(apps_rw); - - return entries; -} - -void UninstallAllAppsInDirectory(bf::path dir, bool is_readonly) { - if (bf::exists(dir)) { - for (auto& dir_entry : boost::make_iterator_range( - bf::directory_iterator(dir), bf::directory_iterator())) { - if (dir_entry.path().string().find("smoke") != std::string::npos && - bf::is_directory(dir_entry)) { - if (Uninstall(dir_entry.path().filename().string(), is_readonly, - RequestResult::NORMAL) != ci::AppInstaller::Result::OK) { - LOG(ERROR) << "Cannot uninstall smoke test app: " - << dir_entry.path().filename().string(); - } - } - } - } -} - -void UninstallAllSmokeApps(uid_t uid) { - if (getuid() == 0) { - bf::path root_path = kPreloadApps; - UninstallAllAppsInDirectory(root_path, true); - } - bf::path apps_rw = ci::GetRootAppPath(false, uid); - UninstallAllAppsInDirectory(apps_rw, false); -} +#include "unit_tests/smoke_utils.h" -} // namespace namespace common_installer { diff --git a/src/unit_tests/smoke_utils.cc b/src/unit_tests/smoke_utils.cc new file mode 100644 index 0000000..b2cacbb --- /dev/null +++ b/src/unit_tests/smoke_utils.cc @@ -0,0 +1,601 @@ +// Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved +// Use of this source code is governed by an apache-2.0 license that can be +// found in the LICENSE file. + +#include +#include +#include + + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "tpk/tpk_app_query_interface.h" + +#include "unit_tests/smoke_utils.h" + + +const uid_t kGlobalUserUid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER); +const uid_t kGlobalUserGid = tzplatform_getgid(TZ_SYS_GLOBALAPP_USER); +const uid_t kDefaultUserUid = tzplatform_getuid(TZ_SYS_DEFAULT_USER); +// TODO(s89.jang): Test local case also +const uid_t kTestUserId = kGlobalUserUid; +const gid_t kTestGroupId = kGlobalUserGid; +const char kSystemShareGroupName[] = "system_share"; +const std::string& kTestUserIdStr = std::to_string(kTestUserId); +const std::string& kDefaultUserIdStr = std::to_string(kDefaultUserUid); +const char kLegacyExtImageDir[] = "legacy_extimage_dir"; +const char kMigrateTestDBName[] = "app2sd_migrate.db"; + +const bf::path kSmokePackagesDirectory = + "/usr/share/tpk-backend-ut/test_samples/smoke/"; + +// common entries +const std::vector kDBEntries = { + {".pkgmgr_parser.db"}, + {".pkgmgr_parser.db-journal"}, + {".pkgmgr_cert.db"}, + {".pkgmgr_cert.db-journal"}, + {".app2sd.db"}, + {".app2sd.db-journal"}, +}; +// globaluser entries +const char kGlobalManifestDir[] = "/opt/share/packages"; +const char kSkelDir[] = "/etc/skel/apps_rw"; +const char kPreloadApps[] = "/usr/apps"; +const char kPreloadManifestDir[] = "/usr/share/packages"; +const char kPreloadIcons[] = "/usr/share/icons"; + + + +bool TouchFile(const bf::path& path) { + FILE* f = fopen(path.c_str(), "w+"); + if (!f) + return false; + fclose(f); + return true; +} + + +void RemoveAllRecoveryFiles() { + bf::path root_path = ci::GetRootAppPath(false, + kTestUserId); + if (!bf::exists(root_path)) + return; + for (auto& dir_entry : boost::make_iterator_range( + bf::directory_iterator(root_path), bf::directory_iterator())) { + if (bf::is_regular_file(dir_entry)) { + if (dir_entry.path().string().find("/tpk-recovery") + != std::string::npos) { + bs::error_code error; + bf::remove(dir_entry.path(), error); + } + } + } +} + +bf::path FindRecoveryFile() { + bf::path root_path = ci::GetRootAppPath(false, + kTestUserId); + for (auto& dir_entry : boost::make_iterator_range( + bf::directory_iterator(root_path), bf::directory_iterator())) { + if (bf::is_regular_file(dir_entry)) { + if (dir_entry.path().string().find("/tpk-recovery") + != std::string::npos) { + return dir_entry.path(); + } + } + } + return {}; +} + +bool ValidateFileContentInPackage(const std::string& pkgid, + const std::string& relative, + const std::string& expected, + bool is_readonly) { + bf::path root_path = ci::GetRootAppPath(is_readonly, kTestUserId); + bf::path file_path = root_path / pkgid / relative; + if (!bf::exists(file_path)) { + LOG(ERROR) << file_path << " doesn't exist"; + return false; + } + FILE* handle = fopen(file_path.c_str(), "r"); + if (!handle) { + LOG(ERROR) << file_path << " cannot be open"; + return false; + } + std::string content; + std::array buffer; + while (fgets(buffer.data(), buffer.size(), handle)) { + content += buffer.data(); + } + fclose(handle); + return content == expected; +} + +void ValidatePackageRWFS(const std::string& pkgid, uid_t uid) { + bf::path root_path = ci::GetRootAppPath(false, uid); + bf::path package_path = root_path / pkgid; + bf::path data_path = package_path / "data"; + bf::path cache_path = package_path / "cache"; + bf::path shared_data_path = package_path / "shared" / "data"; + + ASSERT_TRUE(bf::exists(data_path)); + ASSERT_TRUE(bf::exists(cache_path)); + + struct stat stats; + stat(data_path.c_str(), &stats); + // gid of RW dirs should be system_share + boost::optional system_share = + ci::GetGidByGroupName(kSystemShareGroupName); + ASSERT_EQ(uid, stats.st_uid); + ASSERT_EQ(*system_share, stats.st_gid); + if (bf::exists(shared_data_path)) { + stat(shared_data_path.c_str(), &stats); + ASSERT_EQ(uid, stats.st_uid); + ASSERT_EQ(*system_share, stats.st_gid); + } + + stat(cache_path.c_str(), &stats); + ASSERT_EQ(uid, stats.st_uid); + ASSERT_EQ(*system_share, stats.st_gid); +} + +void ValidatePackageFS(const std::string& pkgid, const std::string& appid, + uid_t uid, gid_t gid, bool is_readonly) { + bf::path root_path = ci::GetRootAppPath(is_readonly, uid); + bf::path package_path = root_path / pkgid; + bf::path shared_path = package_path / "shared"; + ASSERT_TRUE(bf::exists(root_path)); + ASSERT_TRUE(bf::exists(package_path)); + ASSERT_TRUE(bf::exists(shared_path)); + + bf::path manifest_path = + bf::path(getUserManifestPath(uid, is_readonly)) / (pkgid + ".xml"); + ASSERT_TRUE(bf::exists(manifest_path)); + + // backups should not exist + bf::path package_backup = ci::GetBackupPathForPackagePath(package_path); + bf::path manifest_backup = ci::GetBackupPathForManifestFile(manifest_path); + ASSERT_FALSE(bf::exists(package_backup)); + ASSERT_FALSE(bf::exists(manifest_backup)); + + for (bf::recursive_directory_iterator iter(package_path); + iter != bf::recursive_directory_iterator(); ++iter) { + if (bf::is_symlink(symlink_status(iter->path()))) + continue; + if (iter->path().filename() == "data" || + iter->path().filename() == ".mmc") + continue; + struct stat stats; + stat(iter->path().c_str(), &stats); + ASSERT_EQ(uid, stats.st_uid); + ASSERT_EQ(gid, stats.st_gid); + } +} + +void PackageCheckCleanup(const std::string& pkgid, const std::string&, + bool is_readonly) { + bf::path root_path = ci::GetRootAppPath(is_readonly, + kTestUserId); + bf::path package_path = root_path / pkgid; + ASSERT_FALSE(bf::exists(package_path)); + + bf::path manifest_path = bf::path(getUserManifestPath( + kTestUserId, is_readonly)) / (pkgid + ".xml"); + ASSERT_FALSE(bf::exists(manifest_path)); + + // backups should not exist + bf::path package_backup = ci::GetBackupPathForPackagePath(package_path); + bf::path manifest_backup = ci::GetBackupPathForManifestFile(manifest_path); + ASSERT_FALSE(bf::exists(package_backup)); + ASSERT_FALSE(bf::exists(manifest_backup)); +} + +void ValidatePackage(const std::string& pkgid, const std::string& appid, + bool is_readonly) { + ASSERT_TRUE(ci::QueryIsPackageInstalled( + pkgid, ci::GetRequestMode(kTestUserId), kTestUserId)); + ValidatePackageFS(pkgid, appid, kTestUserId, + kTestGroupId, is_readonly); + if (kTestUserId == kGlobalUserUid) { + ci::UserList list = ci::GetUserList(); + for (auto& l : list) + ValidatePackageRWFS(pkgid, std::get<0>(l)); + } else { + ValidatePackageRWFS(pkgid, kTestUserId); + } +} + +void ValidateExternalPackage_FS(const std::string& pkgid, + const std::string& appid, uid_t uid) { + ASSERT_EQ(app2ext_usr_enable_external_pkg(pkgid.c_str(), uid), 0); + bf::path root_path = ci::GetRootAppPath(false, uid); + ASSERT_TRUE(bf::exists(root_path / pkgid / ".mmc" / "bin")); + ASSERT_TRUE(bf::exists(root_path / pkgid / ".mmc" / "lib")); + ASSERT_TRUE(bf::exists(root_path / pkgid / ".mmc" / "res")); + ValidatePackage(pkgid, appid); + ASSERT_EQ(app2ext_usr_disable_external_pkg(pkgid.c_str(), uid), 0); +} + +void ValidateExternalPackage(const std::string& pkgid, + const std::string& appid) { + std::string storage = ci::QueryStorageForPkgId(pkgid, kTestUserId); + bf::path ext_mount_path = ci::GetExternalCardPath(); + if (bf::is_empty(ext_mount_path)) { + LOG(INFO) << "Sdcard not exists!"; + ASSERT_EQ(storage, "installed_internal"); + } else { + ASSERT_EQ(storage, "installed_external"); + } + ValidateExternalPackage_FS(pkgid, appid, kTestUserId); +} + +void CheckPackageNonExistance(const std::string& pkgid, + const std::string& appid, + bool is_readonly) { + ASSERT_FALSE(ci::QueryIsPackageInstalled( + pkgid, ci::GetRequestMode(kTestUserId), kTestUserId)); + PackageCheckCleanup(pkgid, appid, is_readonly); + if (kTestUserId == kGlobalUserUid) { + bf::path skel_path(kSkelDir); + ASSERT_FALSE(bf::exists(skel_path / pkgid)); + ci::UserList list = ci::GetUserList(); + for (auto& l : list) { + bf::path root_path = ci::GetRootAppPath(false, std::get<0>(l)); + bf::path package_path = root_path / pkgid; + ASSERT_FALSE(bf::exists(package_path)); + } + } +} + +std::unique_ptr CreateQueryInterface() { + std::unique_ptr query_interface( + new tpk::TpkAppQueryInterface()); + return query_interface; +} + +std::unique_ptr CreateInstaller(ci::PkgMgrPtr pkgmgr) { + std::unique_ptr installer(new tpk::TpkInstaller(pkgmgr)); + return installer; +} + +ci::AppInstaller::Result RunInstallerWithPkgrmgr(ci::PkgMgrPtr pkgmgr, + RequestResult mode) { + std::unique_ptr installer = CreateInstaller(pkgmgr); + switch (mode) { + case RequestResult::FAIL: + installer->AddStep(); + break; + default: + break; + } + return installer->Run(); +} +ci::AppInstaller::Result CallBackend(int argc, + const char* argv[], + RequestResult mode) { + TestPkgmgrInstaller pkgmgr_installer; + std::unique_ptr query_interface = + CreateQueryInterface(); + auto pkgmgr = + ci::PkgMgrInterface::Create(argc, const_cast(argv), + &pkgmgr_installer, + query_interface.get()); + if (!pkgmgr) { + LOG(ERROR) << "Failed to initialize pkgmgr interface"; + return ci::AppInstaller::Result::UNKNOWN; + } + return RunInstallerWithPkgrmgr(pkgmgr, mode); +} + +ci::AppInstaller::Result Install(const bf::path& path, + RequestResult mode) { + const char* argv[] = {"", "-i", path.c_str(), "-u", kTestUserIdStr.c_str()}; + return CallBackend(SIZEOFARRAY(argv), argv, mode); +} + +ci::AppInstaller::Result InstallPreload(const bf::path& path, + RequestResult mode) { + const char* argv[] = {"", "-i", path.c_str(), "--preload"}; + return CallBackend(SIZEOFARRAY(argv), argv, mode); +} + +bool CheckAvailableExternalPath() { + bf::path ext_mount_path = ci::GetExternalCardPath(); + LOG(DEBUG) << "ext_mount_path :" << ext_mount_path; + if (ext_mount_path.empty()) { + LOG(ERROR) << "Sdcard not exists!"; + return false; + } + return true; +} + +ci::AppInstaller::Result InstallExternal(const bf::path& path, + RequestResult mode) { + int default_storage = 0; + vconf_get_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT, + &default_storage); + vconf_set_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT, 1); + + const char* argv[] = {"", "-i", path.c_str(), "-u", kTestUserIdStr.c_str()}; + ci::AppInstaller::Result result = CallBackend(SIZEOFARRAY(argv), argv, mode); + + vconf_set_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT, + default_storage); + return result; +} + +ci::AppInstaller::Result MigrateLegacyExternalImage(const std::string& pkgid, + const bf::path& path, + const bf::path& legacy_path, + RequestResult mode) { + if (InstallExternal(path) != ci::AppInstaller::Result::OK) { + LOG(ERROR) << "Failed to install application. Cannot perform Migrate"; + return ci::AppInstaller::Result::ERROR; + } + + bf::path ext_mount_path = ci::GetExternalCardPath(); + if (bf::is_empty(ext_mount_path)) { + LOG(ERROR) << "Sdcard not exists!"; + return ci::AppInstaller::Result::ERROR; + } + bf::path app2sd_path = ext_mount_path / "app2sd"; + + char *image_name = app2ext_usr_getname_image(pkgid.c_str(), + kGlobalUserUid); + if (!image_name) { + LOG(ERROR) << "Failed to get external image name"; + return ci::AppInstaller::Result::ERROR; + } + bf::path org_image = app2sd_path / image_name; + free(image_name); + + bs::error_code error; + bf::remove(org_image, error); + if (error) { + LOG(ERROR) << "Failed to remove org image"; + return ci::AppInstaller::Result::ERROR; + } + + bf::path db_path = tzplatform_getenv(TZ_SYS_DB); + bf::path app2sd_db = db_path / ".app2sd.db"; + bf::path app2sd_db_journal = db_path / ".app2sd.db-journal"; + bf::remove(app2sd_db, error); + if (error) { + LOG(ERROR) << "Failed to remove app2sd db"; + return ci::AppInstaller::Result::ERROR; + } + bf::remove(app2sd_db_journal, error); + if (error) { + LOG(ERROR) << "Failed to remove app2sd journal db"; + return ci::AppInstaller::Result::ERROR; + } + + bf::path app2sd_migrate_db = legacy_path / kMigrateTestDBName; + if (!ci::CopyFile(app2sd_migrate_db, app2sd_db)) { + LOG(ERROR) << "Failed to copy test db"; + return ci::AppInstaller::Result::ERROR; + } + + bf::path legacy_src = legacy_path / pkgid; + bf::path legacy_dst = app2sd_path / pkgid; + if (!ci::CopyFile(legacy_src, legacy_dst)) { + LOG(ERROR) << "Failed to copy test image"; + return ci::AppInstaller::Result::ERROR; + } + const char* argv[] = {"", "--migrate-extimg", pkgid.c_str(), + "-u", kDefaultUserIdStr.c_str()}; + return CallBackend(SIZEOFARRAY(argv), argv, mode); +} + +ci::AppInstaller::Result InstallWithTEP( + const bf::path& path, + const bf::path& tep, + RequestResult mode) { + const char* argv[] = {"", "-i", path.c_str(), "-u", kTestUserIdStr.c_str(), + "-e", tep.c_str()}; + return CallBackend(SIZEOFARRAY(argv), argv, mode); +} + +ci::AppInstaller::Result Update(const bf::path& path_old, + const bf::path& path_new, + RequestResult mode) { + if (Install(path_old) != ci::AppInstaller::Result::OK) { + LOG(ERROR) << "Failed to install application. Cannot update"; + return ci::AppInstaller::Result::UNKNOWN; + } + return Install(path_new, mode); +} + +ci::AppInstaller::Result MountInstall(const bf::path& path, + RequestResult mode) { + const char* argv[] = {"", "-w", path.c_str(), "-u", kTestUserIdStr.c_str()}; + return CallBackend(SIZEOFARRAY(argv), argv, mode); +} + +ci::AppInstaller::Result MountInstallWithTEP( + const bf::path& path, + const bf::path& tep, + RequestResult mode) { + const char* argv[] = {"", "-w", path.c_str(), "-u", kTestUserIdStr.c_str(), + "-e", tep.c_str()}; + return CallBackend(SIZEOFARRAY(argv), argv, mode); +} + +ci::AppInstaller::Result MountUpdate(const bf::path& path_old, + const bf::path& path_new, + RequestResult mode) { + if (MountInstall(path_old) != ci::AppInstaller::Result::OK) { + LOG(ERROR) << "Failed to mount-install application. Cannot mount-update"; + return ci::AppInstaller::Result::UNKNOWN; + } + return MountInstall(path_new, mode); +} + +ci::AppInstaller::Result Uninstall(const std::string& pkgid, bool is_readonly, + RequestResult mode) { + if (is_readonly) { + const char* argv[] = {"", "-d", pkgid.c_str(), "--preload", + "--force-remove"}; + return CallBackend(SIZEOFARRAY(argv), argv, mode); + } else { + const char* argv[] = {"", "-d", pkgid.c_str(), "-u", + kTestUserIdStr.c_str()}; + return CallBackend(SIZEOFARRAY(argv), argv, mode); + } +} + +ci::AppInstaller::Result EnablePackage(const std::string& path, + RequestResult mode) { + const char* argv[] = {"", "-A", path.c_str(), "-u", kTestUserIdStr.c_str()}; + return CallBackend(SIZEOFARRAY(argv), argv, mode); +} + +ci::AppInstaller::Result DisablePackage(const std::string& path, + RequestResult mode) { + const char* argv[] = {"", "-D", path.c_str(), "-u", kTestUserIdStr.c_str()}; + return CallBackend(SIZEOFARRAY(argv), argv, mode); +} + +ci::AppInstaller::Result RDSUpdate(const bf::path& path, + const std::string& pkgid, + RequestResult mode) { + if (Install(path) != ci::AppInstaller::Result::OK) { + LOG(ERROR) << "Failed to install application. Cannot perform RDS"; + return ci::AppInstaller::Result::UNKNOWN; + } + const char* argv[] = {"", "-r", pkgid.c_str(), "-u", + kTestUserIdStr.c_str()}; + return CallBackend(SIZEOFARRAY(argv), argv, mode); +} + +ci::AppInstaller::Result DeltaInstall(const bf::path& path, + const bf::path& delta_package) { + if (Install(path) != ci::AppInstaller::Result::OK) { + LOG(ERROR) << "Failed to install application. Cannot perform RDS"; + return ci::AppInstaller::Result::UNKNOWN; + } + return Install(delta_package); +} + +ci::AppInstaller::Result Recover(const bf::path& recovery_file, + RequestResult mode) { + const char* argv[] = {"", "-b", recovery_file.c_str(), "-u", + kTestUserIdStr.c_str()}; + return CallBackend(SIZEOFARRAY(argv), argv, mode); +} + +void BackupPath(const bf::path& path) { + bf::path backup_path = path.string() + ".bck"; + std::cout << "Backup path: " << path << " to " << backup_path << std::endl; + bs::error_code error; + bf::remove_all(backup_path, error); + if (error) + LOG(ERROR) << "Remove failed: " << backup_path + << " (" << error.message() << ")"; + if (bf::exists(path)) { + bf::rename(path, backup_path, error); + if (error) + LOG(ERROR) << "Failed to setup test environment. Does some previous" + << " test crashed? Path: " + << backup_path << " should not exist."; + assert(!error); + } +} + +void RestorePath(const bf::path& path) { + bf::path backup_path = path.string() + ".bck"; + std::cout << "Restore path: " << path << " from " << backup_path << std::endl; + bs::error_code error; + bf::remove_all(path, error); + if (error) + LOG(ERROR) << "Remove failed: " << path + << " (" << error.message() << ")"; + if (bf::exists(backup_path)) { + bf::rename(backup_path, path, error); + if (error) + LOG(ERROR) << "Failed to restore backup path: " << backup_path + << " (" << error.message() << ")"; + } +} + +std::vector SetupBackupDirectories(uid_t uid) { + std::vector entries; + bf::path db_dir = bf::path(tzplatform_getenv(TZ_SYS_DB)); + if (uid != kGlobalUserUid) + db_dir = db_dir / "user" / std::to_string(uid); + for (auto e : kDBEntries) { + bf::path path = db_dir / e; + entries.emplace_back(path); + } + + if (getuid() == 0) { + entries.emplace_back(kPreloadApps); + entries.emplace_back(kPreloadManifestDir); + entries.emplace_back(kPreloadIcons); + } + + if (uid == kGlobalUserUid) { + entries.emplace_back(kSkelDir); + entries.emplace_back(kGlobalManifestDir); + ci::UserList list = ci::GetUserList(); + for (auto l : list) { + bf::path apps = std::get<2>(l) / "apps_rw"; + entries.emplace_back(apps); + } + } else { + tzplatform_set_user(uid); + bf::path approot = tzplatform_getenv(TZ_USER_APPROOT); + tzplatform_reset_user(); + entries.emplace_back(approot); + } + + bf::path apps_rw = ci::GetRootAppPath(false, uid); + entries.emplace_back(apps_rw); + + return entries; +} + +void UninstallAllAppsInDirectory(bf::path dir, bool is_readonly) { + if (bf::exists(dir)) { + for (auto& dir_entry : boost::make_iterator_range( + bf::directory_iterator(dir), bf::directory_iterator())) { + if (dir_entry.path().string().find("smoke") != std::string::npos && + bf::is_directory(dir_entry)) { + if (Uninstall(dir_entry.path().filename().string(), is_readonly, + RequestResult::NORMAL) != ci::AppInstaller::Result::OK) { + LOG(ERROR) << "Cannot uninstall smoke test app: " + << dir_entry.path().filename().string(); + } + } + } + } +} + +void UninstallAllSmokeApps(uid_t uid) { + if (getuid() == 0) { + bf::path root_path = kPreloadApps; + UninstallAllAppsInDirectory(root_path, true); + } + bf::path apps_rw = ci::GetRootAppPath(false, uid); + UninstallAllAppsInDirectory(apps_rw, false); +} + diff --git a/src/unit_tests/smoke_utils.h b/src/unit_tests/smoke_utils.h new file mode 100644 index 0000000..6a29aef --- /dev/null +++ b/src/unit_tests/smoke_utils.h @@ -0,0 +1,212 @@ +// Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved +// Use of this source code is governed by an apache-2.0 license that can be +// found in the LICENSE file. + +#ifndef UNIT_TESTS_SMOKE_UTILS_H_ +#define UNIT_TESTS_SMOKE_UTILS_H_ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "tpk/tpk_installer.h" + +#define SIZEOFARRAY(ARR) \ + sizeof(ARR) / sizeof(ARR[0]) \ + + +namespace bf = boost::filesystem; +namespace bs = boost::system; +namespace ci = common_installer; + +extern const uid_t kGlobalUserUid; +extern const uid_t kGlobalUserGid; +extern const uid_t kDefaultUserUid; +// TODO(s89.jang): Test local case also +extern const uid_t kTestUserId; +extern const gid_t kTestGroupId; +extern const char kSystemShareGroupName[]; +extern const std::string& kTestUserIdStr; +extern const std::string& kDefaultUserIdStr; +extern const char kLegacyExtImageDir[]; +extern const char kMigrateTestDBName[]; + +extern const bf::path kSmokePackagesDirectory; + +// common entries +extern const std::vector kDBEntries; + +// globaluser entries +extern const char kGlobalManifestDir[]; +extern const char kSkelDir[]; +extern const char kPreloadApps[]; +extern const char kPreloadManifestDir[]; +extern const char kPreloadIcons[]; + +enum class RequestResult { + NORMAL, + FAIL +}; + +class ScopedTzipInterface { + public: + explicit ScopedTzipInterface(const std::string& pkgid) + : pkg_path_(bf::path(ci::GetRootAppPath(false, + kTestUserId)) / pkgid), + interface_(ci::GetMountLocation(pkg_path_)), + mounted_(true) { + interface_.MountZip(ci::GetZipPackageLocation(pkg_path_, pkgid)); + } + + void Release() { + if (mounted_) { + interface_.UnmountZip(); + mounted_ = false; + } + } + + ~ScopedTzipInterface() { + Release(); + } + + private: + bf::path pkg_path_; + ci::TzipInterface interface_; + bool mounted_; +}; + + +class TestPkgmgrInstaller : public ci::PkgmgrInstallerInterface { + public: + bool CreatePkgMgrInstaller(pkgmgr_installer** installer, + ci::InstallationMode* mode) { + *installer = pkgmgr_installer_offline_new(); + if (!*installer) + return false; + *mode = ci::InstallationMode::ONLINE; + return true; + } + + bool ShouldCreateSignal() const { + return false; + } +}; + +bool TouchFile(const bf::path& path); + +void RemoveAllRecoveryFiles(); + +bf::path FindRecoveryFile(); + +bool ValidateFileContentInPackage(const std::string& pkgid, + const std::string& relative, + const std::string& expected, + bool is_readonly = false); + +void ValidatePackageRWFS(const std::string& pkgid, uid_t uid); + +void ValidatePackageFS(const std::string& pkgid, const std::string& appid, + uid_t uid, gid_t gid, bool is_readonly = false); + +void PackageCheckCleanup(const std::string& pkgid, const std::string&, + bool is_readonly = false); + +void ValidatePackage(const std::string& pkgid, const std::string& appid, + bool is_readonly = false); + +void ValidateExternalPackage_FS(const std::string& pkgid, + const std::string& appid, uid_t uid); + +void ValidateExternalPackage(const std::string& pkgid, + const std::string& appid); + +void CheckPackageNonExistance(const std::string& pkgid, + const std::string& appid, + bool is_readonly = false); + +bool CheckAvailableExternalPath(); + +std::unique_ptr CreateQueryInterface(); + +std::unique_ptr CreateInstaller(ci::PkgMgrPtr pkgmgr); + +ci::AppInstaller::Result RunInstallerWithPkgrmgr(ci::PkgMgrPtr pkgmgr, + RequestResult mode); +ci::AppInstaller::Result CallBackend(int argc, + const char* argv[], + RequestResult mode); + +ci::AppInstaller::Result Install(const bf::path& path, + RequestResult mode = RequestResult::NORMAL); + +ci::AppInstaller::Result InstallPreload(const bf::path& path, + RequestResult mode = RequestResult::NORMAL); + + +ci::AppInstaller::Result InstallExternal(const bf::path& path, + RequestResult mode = RequestResult::NORMAL); + +ci::AppInstaller::Result MigrateLegacyExternalImage(const std::string& pkgid, + const bf::path& path, + const bf::path& legacy_path, + RequestResult mode = RequestResult::NORMAL); + +ci::AppInstaller::Result InstallWithTEP( + const bf::path& path, + const bf::path& tep, + RequestResult mode = RequestResult::NORMAL); + +ci::AppInstaller::Result Update(const bf::path& path_old, + const bf::path& path_new, + RequestResult mode = RequestResult::NORMAL); + +ci::AppInstaller::Result MountInstall(const bf::path& path, + RequestResult mode = RequestResult::NORMAL); + +ci::AppInstaller::Result MountInstallWithTEP( + const bf::path& path, + const bf::path& tep, + RequestResult mode = RequestResult::NORMAL); + +ci::AppInstaller::Result MountUpdate(const bf::path& path_old, + const bf::path& path_new, + RequestResult mode = RequestResult::NORMAL); + +ci::AppInstaller::Result Uninstall(const std::string& pkgid, bool is_readonly, + RequestResult mode = RequestResult::NORMAL); + +ci::AppInstaller::Result EnablePackage(const std::string& path, + RequestResult mode = RequestResult::NORMAL); + +ci::AppInstaller::Result DisablePackage(const std::string& path, + RequestResult mode = RequestResult::NORMAL); + +ci::AppInstaller::Result RDSUpdate(const bf::path& path, + const std::string& pkgid, + RequestResult mode = RequestResult::NORMAL); + +ci::AppInstaller::Result DeltaInstall(const bf::path& path, + const bf::path& delta_package); + +ci::AppInstaller::Result Recover(const bf::path& recovery_file, + RequestResult mode = RequestResult::NORMAL); + +void BackupPath(const bf::path& path); + +void RestorePath(const bf::path& path); + +std::vector SetupBackupDirectories(uid_t uid); + +void UninstallAllAppsInDirectory(bf::path dir, bool is_readonly); + +void UninstallAllSmokeApps(uid_t uid); + +#endif // UNIT_TESTS_SMOKE_UTILS_H_ -- 2.7.4