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