From 6607ff7348fa01271f7ec127c81ce525e35121eb Mon Sep 17 00:00:00 2001 From: jongmyeong ko Date: Fri, 17 Mar 2017 03:30:30 -0700 Subject: [PATCH 01/16] Revert "[SmokeTest] Add request mode choice" This reverts commit e2687ca7eb39fc8aa1ba278199a2b641e376f4ab. Change-Id: I830fd406565a3d43adc0fba3f752ba6348671bcd --- src/unit_tests/smoke_test.cc | 134 +++++++------------------------------------ 1 file changed, 22 insertions(+), 112 deletions(-) diff --git a/src/unit_tests/smoke_test.cc b/src/unit_tests/smoke_test.cc index 0fb52ff..d52b00b 100644 --- a/src/unit_tests/smoke_test.cc +++ b/src/unit_tests/smoke_test.cc @@ -6,7 +6,6 @@ #include #include #include -#include #include #include @@ -26,7 +25,6 @@ #include #include #include -#include #include #include @@ -46,51 +44,15 @@ namespace bs = boost::system; namespace ci = common_installer; namespace { -ci::RequestMode kRequestMode = ci::RequestMode::GLOBAL; -const char *short_opts = "g:u"; -const struct option long_opts[] = { - { "request_mode", 1, NULL, 'r' }, - { 0, 0, 0, 0 } /* sentinel */ -}; -const char *request_modes[] { - "global", - "user" -}; -void ParseRequestMode(int argc, char** argv) { - int c; - int opt_idx = 0; - do { - c = getopt_long(argc, argv, short_opts, long_opts, &opt_idx); - switch (c) { - case 'r': - if (strncmp(optarg, request_modes[0], strlen(request_modes[0])) == 0) - kRequestMode = ci::RequestMode::GLOBAL; - else if (strncmp(optarg, request_modes[1], strlen(request_modes[1])) == 0) - kRequestMode = ci::RequestMode::USER; - else - LOG(ERROR) << "Wrong request mode " << optarg - << ". Available: \"global\" or \"user\""; - break; - case 'g': - kRequestMode = ci::RequestMode::GLOBAL; - break; - case 'u': - kRequestMode = ci::RequestMode::USER; - break; - default: - break; - } - } while (c != -1); -} 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); -uid_t kTestUserId = kGlobalUserUid; -gid_t kTestGroupId = kGlobalUserGid; -std::string kTestUserIdStr = std::to_string(kTestUserId); -const char kNormalUserName[] = "smokeuser"; +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"; @@ -191,40 +153,6 @@ bool TouchFile(const bf::path& path) { return true; } -bool AddTestUser(const char *user_name) { - std::cout << "Adding test user: " << user_name << std::endl; - gboolean ret = ci::AddUser(user_name); - if (boost::optional uid = ci::GetUidByUserName(user_name)) { - kTestUserId = *uid; - kTestUserIdStr = std::to_string(kTestUserId); - std::cout << "User created properly: uid=" << *uid; - if (boost::optional gid = ci::GetGidByUid(*uid)) { - kTestGroupId = *gid; - std::cout << " gid=" << *gid; - } - std::cout << std::endl; - return true; - } - LOG(ERROR) << "Adding test user failed"; - return false; -} - -bool DeleteTestUser(const char *user_name) { - std::cout << "Deleting test user: " << user_name << std::endl; - uid_t test_uid; - if (boost::optional uid = ci::GetUidByUserName(user_name)) - test_uid = *uid; - gboolean ret = ci::DeleteUser(user_name, true); - if (boost::optional uid = ci::GetUidByUserName(user_name)); - else { - std::cout << "User deleted properly: user_name=" << user_name - << " uid=" << test_uid << std::endl; - return true; - } - LOG(ERROR) << "Deleting test user failed"; - return false; -} - void RemoveAllRecoveryFiles() { bf::path root_path = ci::GetRootAppPath(false, kTestUserId); @@ -741,11 +669,11 @@ void RestorePath(const bf::path& path) { } } -std::vector SetupBackupDirectories() { +std::vector SetupBackupDirectories(uid_t uid) { std::vector entries; bf::path db_dir = bf::path(tzplatform_getenv(TZ_SYS_DB)); - if (kTestUserId != kGlobalUserUid) - db_dir = db_dir / "user" / std::to_string(kTestUserId); + 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); @@ -757,7 +685,7 @@ std::vector SetupBackupDirectories() { entries.emplace_back(kPreloadIcons); } - if (kTestUserId == kGlobalUserUid) { + if (uid == kGlobalUserUid) { entries.emplace_back(kSkelDir); entries.emplace_back(kGlobalManifestDir); ci::UserList list = ci::GetUserList(); @@ -766,13 +694,13 @@ std::vector SetupBackupDirectories() { entries.emplace_back(apps); } } else { - tzplatform_set_user(kTestUserId); + 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, kTestUserId); + bf::path apps_rw = ci::GetRootAppPath(false, uid); entries.emplace_back(apps_rw); return entries; @@ -799,12 +727,12 @@ void UninstallAllAppsInDirectory(bf::path dir, bool is_preload) { } } -void UninstallAllSmokeApps() { - if (getuid() == 0 && kRequestMode == ci::RequestMode::GLOBAL) { +void UninstallAllSmokeApps(uid_t uid) { + if (getuid() == 0) { bf::path root_path = kPreloadApps; UninstallAllAppsInDirectory(root_path, true); } - bf::path apps_rw = ci::GetRootAppPath(false, kTestUserId); + bf::path apps_rw = ci::GetRootAppPath(false, uid); UninstallAllAppsInDirectory(apps_rw, false); } @@ -814,44 +742,27 @@ namespace common_installer { class SmokeEnvironment : public testing::Environment { public: - explicit SmokeEnvironment() { + explicit SmokeEnvironment(uid_t uid) : uid_(uid) { } void SetUp() override { - if (kRequestMode == ci::RequestMode::USER) - ASSERT_TRUE(AddTestUser(kNormalUserName)); - else { - kTestUserId = kGlobalUserUid; - kTestGroupId = kGlobalUserGid; - kTestUserIdStr = std::to_string(kTestUserId); - } - backups_ = SetupBackupDirectories(); + backups_ = SetupBackupDirectories(uid_); for (auto& path : backups_) BackupPath(path); } void TearDown() override { - ASSERT_TRUE(kRequestMode == ci::RequestMode::GLOBAL || - (kRequestMode == ci::RequestMode::USER && - kGlobalUserUid != kTestUserId)); - UninstallAllSmokeApps(); + UninstallAllSmokeApps(uid_); for (auto& path : backups_) RestorePath(path); - if (kRequestMode == ci::RequestMode::USER) - ASSERT_TRUE(DeleteTestUser(kNormalUserName)); } private: + uid_t uid_; std::vector backups_; }; class SmokeTest : public testing::Test { }; -class PreloadSmokeTest : public testing::Test { - void SetUp() override { - ASSERT_TRUE(kRequestMode == ci::RequestMode::GLOBAL); - } -}; - TEST_F(SmokeTest, InstallationMode) { bf::path path = kSmokePackagesDirectory / "InstallationMode.wgt"; std::string pkgid = "smokewgt03"; @@ -1386,7 +1297,7 @@ TEST_F(SmokeTest, MigrateLegacyExternalImageMode) { ValidateExternalPackage(pkgid, {appid}); } -TEST_F(PreloadSmokeTest, InstallationMode_Preload) { +TEST_F(SmokeTest, InstallationMode_Preload) { ASSERT_EQ(getuid(), 0) << "Test cannot be run by normal user"; bf::path path = kSmokePackagesDirectory / "InstallationMode_Preload.wgt"; std::string pkgid = "smokewgt37"; @@ -1396,7 +1307,7 @@ TEST_F(PreloadSmokeTest, InstallationMode_Preload) { ValidatePackage(pkgid, {appid}, true); } -TEST_F(PreloadSmokeTest, UpdateMode_Preload) { +TEST_F(SmokeTest, UpdateMode_Preload) { ASSERT_EQ(getuid(), 0) << "Test cannot be run by normal user"; bf::path path_old = kSmokePackagesDirectory / "UpdateMode_Preload.wgt"; bf::path path_new = kSmokePackagesDirectory / "UpdateMode_Preload2.wgt"; @@ -1414,7 +1325,7 @@ TEST_F(PreloadSmokeTest, UpdateMode_Preload) { ValidateDataFiles(pkgid, kTestUserId); } -TEST_F(PreloadSmokeTest, DeinstallationMode_Preload) { +TEST_F(SmokeTest, DeinstallationMode_Preload) { ASSERT_EQ(getuid(), 0) << "Test cannot be run by normal user"; bf::path path = kSmokePackagesDirectory / "DeinstallationMode_Preload.wgt"; std::string pkgid = "smokewgt39"; @@ -1501,8 +1412,7 @@ TEST_F(SmokeTest, SharedRes30HybridDelta) { int main(int argc, char** argv) { testing::InitGoogleTest(&argc, argv); - testing::Environment *env = testing::AddGlobalTestEnvironment( - new common_installer::SmokeEnvironment()); - ParseRequestMode(argc, argv); + testing::AddGlobalTestEnvironment( + new common_installer::SmokeEnvironment(kGlobalUserUid)); return RUN_ALL_TESTS(); } -- 2.7.4 From 2ca25f4e7413353488c598789e6ddf9a48f3240b Mon Sep 17 00:00:00 2001 From: jongmyeongko Date: Fri, 17 Mar 2017 20:03:41 +0900 Subject: [PATCH 02/16] Release version 0.4.2 Fix build break in release version 0.4.1 All changes in the version 0.4.1 will be released as version 0.4.2 also. Change-Id: I8762c6a63d6c64d0202daea941480a9f05b10778 Signed-off-by: jongmyeongko --- packaging/wgt-backend.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/wgt-backend.spec b/packaging/wgt-backend.spec index a433c0a..f892f08 100644 --- a/packaging/wgt-backend.spec +++ b/packaging/wgt-backend.spec @@ -1,6 +1,6 @@ Name: wgt-backend Summary: Application installer backend for WGT -Version: 0.4.1 +Version: 0.4.2 Release: 1 Group: Application Framework/Package Management License: Apache-2.0 -- 2.7.4 From c93a5812df30950ebbaebca0cb7d7ad32995d5cd Mon Sep 17 00:00:00 2001 From: Bartlomiej Date: Wed, 15 Mar 2017 09:43:27 +0100 Subject: [PATCH 03/16] Change order of some steps There is a case in recovery, when security manager need information from pkgmgr database, so we need to ensure that information about package are stored in pkgmgr database before the security registration/update step. Change-Id: Ic8c937d7cde3b06d492b16f982e73ad7e241d7c5 --- src/hybrid/hybrid_installer.cc | 18 +++++++++--------- src/wgt/wgt_installer.cc | 18 +++++++++--------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/hybrid/hybrid_installer.cc b/src/hybrid/hybrid_installer.cc index a6a832f..9c83f0b 100644 --- a/src/hybrid/hybrid_installer.cc +++ b/src/hybrid/hybrid_installer.cc @@ -145,8 +145,8 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); - AddStep(); AddStep(); + AddStep(); AddStep( ci::Plugin::ActionType::Install); AddStep( @@ -191,7 +191,6 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); - AddStep(); AddStep(); AddStep(); AddStep(); @@ -199,6 +198,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); AddStep(); @@ -274,7 +274,6 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); - AddStep(); AddStep(); AddStep(); AddStep(); @@ -282,6 +281,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); AddStep(); @@ -344,8 +344,8 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); - AddStep(); AddStep(); + AddStep(); AddStep( ci::Plugin::ActionType::Install); AddStep( @@ -389,7 +389,6 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); - AddStep(); AddStep(); AddStep(); AddStep(); @@ -397,6 +396,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); AddStep(); @@ -425,8 +425,8 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); - AddStep(); AddStep(); + AddStep(); AddStep( ci::Plugin::ActionType::Install); AddStep( @@ -454,13 +454,13 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) ci::configuration::StepParseManifest::ManifestLocation::INSTALLED, ci::configuration::StepParseManifest::StoreLocation::BACKUP); AddStep(); - AddStep(); AddStep(); AddStep(); AddStep(); AddStep(); AddStep(); AddStep(); + AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); AddStep(); @@ -478,8 +478,8 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); - AddStep(); AddStep(); + AddStep(); AddStep( ci::Plugin::ActionType::Install); AddStep( @@ -502,9 +502,9 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) ci::configuration::StepParseManifest::ManifestLocation::INSTALLED, ci::configuration::StepParseManifest::StoreLocation::BACKUP); AddStep(); - AddStep(); AddStep(); AddStep(); + AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); AddStep(); diff --git a/src/wgt/wgt_installer.cc b/src/wgt/wgt_installer.cc index 31565f7..32ba8d6 100755 --- a/src/wgt/wgt_installer.cc +++ b/src/wgt/wgt_installer.cc @@ -226,8 +226,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); - AddStep(); AddStep(); + AddStep(); AddStep( ci::Plugin::ActionType::Install); AddStep( @@ -271,9 +271,9 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); - AddStep(); AddStep(); AddStep(); + AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); AddStep(); @@ -369,9 +369,9 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); - AddStep(); AddStep(); AddStep(); + AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); AddStep(); @@ -428,8 +428,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); - AddStep(); AddStep(); + AddStep(); AddStep( ci::Plugin::ActionType::Install); AddStep( @@ -470,9 +470,9 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); - AddStep(); AddStep(); AddStep(); + AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); AddStep(); @@ -497,8 +497,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); - AddStep(); AddStep(); + AddStep(); AddStep(ci::Plugin::ActionType::Install); AddStep( wgt::filesystem::WgtAdditionalSharedDirs); @@ -524,11 +524,11 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) ci::configuration::StepParseManifest::StoreLocation::BACKUP); AddStep(); AddStep(); - AddStep(); AddStep(); AddStep(); AddStep(); AddStep(); + AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); AddStep(); @@ -611,8 +611,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) ci::security::StepPrivilegeCompatibility::InternalPrivType::WGT); AddStep(); AddStep(); - AddStep(); AddStep(); + AddStep(); AddStep(ci::Plugin::ActionType::Install); AddStep( wgt::filesystem::WgtAdditionalSharedDirs); @@ -632,9 +632,9 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) ci::security::StepPrivilegeCompatibility::InternalPrivType::WGT); AddStep(); AddStep(); - AddStep(); AddStep(); AddStep(); + AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); AddStep(); -- 2.7.4 From 1fef99c12ffdc618611d2541cae2710d213cd6fa Mon Sep 17 00:00:00 2001 From: Damian Pietruchowski Date: Tue, 14 Mar 2017 15:52:23 +0100 Subject: [PATCH 04/16] Change order of StepRemoveTemporaryDirectory This step should be executed before parse manifest. Package id is written to recovery file in StepParse after StepUnzip. For example if installation is terminated after StepUnzip and package id is not written to recovery file then in StepParseManifest recovery is terminated with status RECOVERY_DONE. In this case unzipped directory is not removed without this commit. Commit, which adds recovery termination with status RECOVERY_DONE: - https://review.tizen.org/gerrit/#/c/118845/ Change-Id: Ieaf8bf3a9b7d1f1594afb876f14b479bf00e6b50 Signed-off-by: Damian Pietruchowski --- src/wgt/wgt_installer.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wgt/wgt_installer.cc b/src/wgt/wgt_installer.cc index 32ba8d6..ee1f9b3 100755 --- a/src/wgt/wgt_installer.cc +++ b/src/wgt/wgt_installer.cc @@ -381,10 +381,10 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) void WgtInstaller::RecoverySteps() { AddStep(pkgmgr_); AddStep(); + AddStep(); AddStep( ci::configuration::StepParseManifest::ManifestLocation::RECOVERY, ci::configuration::StepParseManifest::StoreLocation::NORMAL); - AddStep(); AddStep(); AddStep(); AddStep(); -- 2.7.4 From a3b7fb6f828acc51cdc89c296b32b4081fd0d2e4 Mon Sep 17 00:00:00 2001 From: Damian Pietruchowski Date: Wed, 22 Feb 2017 17:12:39 +0100 Subject: [PATCH 05/16] [SmokeTest] Add request mode choice Smoke tests can be run with normal or global user. Normal user is created in environment SetUp() and is deleted in TearDown() method. Normal user name is "smokeuser". You can run tests by normal user with flags: -u or --request_mode=user You can run tests by global user with flags: -g or --request_mode=global Without above flags tests are run with global user by default Change-Id: Ibf6e195dd21c78f1c7d19c45c4fa0753ec1baf7f --- CMakeLists.txt | 1 + packaging/wgt-backend.spec | 1 + src/unit_tests/CMakeLists.txt | 1 + src/unit_tests/smoke_test.cc | 161 ++++++++++++++++++++++++++++++++++++------ 4 files changed, 142 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index db797e2..465821f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,6 +49,7 @@ PKG_CHECK_MODULES(PKGMGR_TYPES_DEPS REQUIRED pkgmgr-types) PKG_CHECK_MODULES(ENCRYPTION_DEPS REQUIRED libwebappenc) PKG_CHECK_MODULES(TPK_INSTALLER_DEPS REQUIRED tpk-installer) PKG_CHECK_MODULES(VCONF_DEPS REQUIRED vconf) +PKG_CHECK_MODULES(GUM_DEPS REQUIRED libgum) FIND_PACKAGE(Boost REQUIRED COMPONENTS system filesystem regex program_options) FIND_PACKAGE(GTest REQUIRED) diff --git a/packaging/wgt-backend.spec b/packaging/wgt-backend.spec index f892f08..b80b728 100644 --- a/packaging/wgt-backend.spec +++ b/packaging/wgt-backend.spec @@ -20,6 +20,7 @@ BuildRequires: pkgconfig(pkgmgr-types) BuildRequires: pkgconfig(libwebappenc) BuildRequires: pkgconfig(tpk-installer) BuildRequires: pkgconfig(vconf) +BuildRequires: pkgconfig(libgum) %description This is a package that installs the WGT backend of pkgmgr. diff --git a/src/unit_tests/CMakeLists.txt b/src/unit_tests/CMakeLists.txt index 3947045..7b0f80d 100644 --- a/src/unit_tests/CMakeLists.txt +++ b/src/unit_tests/CMakeLists.txt @@ -20,6 +20,7 @@ INSTALL(DIRECTORY test_samples/ DESTINATION ${SHAREDIR}/${DESTINATION_DIR}/test_ APPLY_PKG_CONFIG(${TARGET_SMOKE_TEST} PUBLIC Boost GTEST + GUM_DEPS ) APPLY_PKG_CONFIG(${TARGET_MANIFEST_TEST} PUBLIC Boost diff --git a/src/unit_tests/smoke_test.cc b/src/unit_tests/smoke_test.cc index d52b00b..0cbbfb8 100644 --- a/src/unit_tests/smoke_test.cc +++ b/src/unit_tests/smoke_test.cc @@ -6,6 +6,8 @@ #include #include #include +#include +#include #include #include @@ -16,6 +18,9 @@ #include #include #include +#include +#include +#include #include #include @@ -25,6 +30,7 @@ #include #include #include +#include #include #include @@ -41,18 +47,54 @@ namespace bf = boost::filesystem; namespace bs = boost::system; +namespace bo = boost::program_options; namespace ci = common_installer; namespace { +ci::RequestMode ParseRequestMode(int argc, char** argv) { + bo::options_description desc("Available options"); + desc.add_options() + ("request-mode", bo::value(), "set request mode") + ("global-request,g", "set request mode to global") + ("user-request,u", "set request mode to user"); + + bo::variables_map vm; + bo::store(bo::parse_command_line(argc, argv, desc), vm); + bo::notify(vm); + + if (vm.count("global-request")) { + std::cout << "Request mode was set to global." << std::endl; + return ci::RequestMode::GLOBAL; + } + if (vm.count("user-request")) { + std::cout << "Request mode was set to user." << std::endl; + return ci::RequestMode::USER; + } + if (vm.count("request-mode")) { + if (vm["request-mode"].as() == "global") { + std::cout << "Request mode was set to global." << std::endl; + return ci::RequestMode::GLOBAL; + } + if (vm["request-mode"].as() == "user") { + std::cout << "Request mode was set to user." << std::endl; + return ci::RequestMode::USER; + } + std::cout << "Cannot set request mode to " + << vm["request-mode"].as() << std::endl; + std::cout << "Request mode was set to global." << std::endl; + return ci::RequestMode::GLOBAL; + + } +} 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); -const uid_t kTestUserId = kGlobalUserUid; -const gid_t kTestGroupId = kGlobalUserGid; +uid_t kTestUserId = kGlobalUserUid; +gid_t kTestGroupId = kGlobalUserGid; +std::string kTestUserIdStr = std::to_string(kTestUserId); +const char kNormalUserName[] = "smokeuser"; 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"; @@ -153,6 +195,62 @@ bool TouchFile(const bf::path& path) { return true; } +bool AddUser(const char *user_name) { + GumUser* user = nullptr; + user = gum_user_create_sync(FALSE); + if (user == nullptr) + LOG(WARNING) << "Failed to create gum user! (user name: " + << user_name << ")"; + g_object_set(G_OBJECT(user), "username", user_name, "usertype", + GUM_USERTYPE_NORMAL, NULL); + gboolean rval = FALSE; + rval = gum_user_add_sync(user); + g_object_unref(user); + return rval; +} + +bool DeleteUser(const char *user_name, bool rem_home_dir) { + bool rval = FALSE; + GumUser* guser = gum_user_get_by_name_sync(user_name, FALSE); + if(guser) + rval = gum_user_delete_sync(guser, rem_home_dir); + return rval; +} + +bool AddTestUser(const char *user_name) { + std::cout << "Adding test user: " << user_name << std::endl; + bool ret = AddUser(user_name); + if (boost::optional uid = ci::GetUidByUserName(user_name)) { + kTestUserId = *uid; + kTestUserIdStr = std::to_string(kTestUserId); + std::cout << "User created properly: uid=" << *uid; + if (boost::optional gid = ci::GetGidByUid(*uid)) { + kTestGroupId = *gid; + std::cout << " gid=" << *gid; + } + std::cout << std::endl; + return true; + } + LOG(ERROR) << "Adding test user failed"; + return false; +} + +bool DeleteTestUser(const char *user_name) { + std::cout << "Deleting test user: " << user_name << std::endl; + uid_t test_uid; + if (boost::optional uid = ci::GetUidByUserName(user_name)) + test_uid = *uid; + bool ret = DeleteUser(user_name, true); + if (boost::optional uid = ci::GetUidByUserName(user_name)); + else { + std::cout << "User deleted properly: user_name=" << user_name + << " uid=" << test_uid << std::endl; + return true; + } + LOG(ERROR) << "Deleting test user failed"; + return false; +} + void RemoveAllRecoveryFiles() { bf::path root_path = ci::GetRootAppPath(false, kTestUserId); @@ -669,11 +767,11 @@ void RestorePath(const bf::path& path) { } } -std::vector SetupBackupDirectories(uid_t uid) { +std::vector SetupBackupDirectories() { 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); + if (kTestUserId != kGlobalUserUid) + db_dir = db_dir / "user" / std::to_string(kTestUserId); for (auto e : kDBEntries) { bf::path path = db_dir / e; entries.emplace_back(path); @@ -685,7 +783,7 @@ std::vector SetupBackupDirectories(uid_t uid) { entries.emplace_back(kPreloadIcons); } - if (uid == kGlobalUserUid) { + if (kTestUserId == kGlobalUserUid) { entries.emplace_back(kSkelDir); entries.emplace_back(kGlobalManifestDir); ci::UserList list = ci::GetUserList(); @@ -694,13 +792,13 @@ std::vector SetupBackupDirectories(uid_t uid) { entries.emplace_back(apps); } } else { - tzplatform_set_user(uid); + tzplatform_set_user(kTestUserId); bf::path approot = tzplatform_getenv(TZ_USER_APPROOT); tzplatform_reset_user(); entries.emplace_back(approot); } - bf::path apps_rw = ci::GetRootAppPath(false, uid); + bf::path apps_rw = ci::GetRootAppPath(false, kTestUserId); entries.emplace_back(apps_rw); return entries; @@ -727,12 +825,12 @@ void UninstallAllAppsInDirectory(bf::path dir, bool is_preload) { } } -void UninstallAllSmokeApps(uid_t uid) { - if (getuid() == 0) { +void UninstallAllSmokeApps(ci::RequestMode request_mode) { + if (getuid() == 0 && request_mode == ci::RequestMode::GLOBAL) { bf::path root_path = kPreloadApps; UninstallAllAppsInDirectory(root_path, true); } - bf::path apps_rw = ci::GetRootAppPath(false, uid); + bf::path apps_rw = ci::GetRootAppPath(false, kTestUserId); UninstallAllAppsInDirectory(apps_rw, false); } @@ -742,27 +840,46 @@ namespace common_installer { class SmokeEnvironment : public testing::Environment { public: - explicit SmokeEnvironment(uid_t uid) : uid_(uid) { + explicit SmokeEnvironment(ci::RequestMode mode) {\ + request_mode_ = mode; } void SetUp() override { - backups_ = SetupBackupDirectories(uid_); + if (request_mode_ == ci::RequestMode::USER) + ASSERT_TRUE(AddTestUser(kNormalUserName)); + else { + kTestUserId = kGlobalUserUid; + kTestGroupId = kGlobalUserGid; + kTestUserIdStr = std::to_string(kTestUserId); + } + backups_ = SetupBackupDirectories(); for (auto& path : backups_) BackupPath(path); } void TearDown() override { - UninstallAllSmokeApps(uid_); + ASSERT_TRUE(request_mode_ == ci::RequestMode::GLOBAL || + (request_mode_ == ci::RequestMode::USER && + kGlobalUserUid != kTestUserId)); + UninstallAllSmokeApps(request_mode_); for (auto& path : backups_) RestorePath(path); + if (request_mode_ == ci::RequestMode::USER) + ASSERT_TRUE(DeleteTestUser(kNormalUserName)); } private: - uid_t uid_; + ci::RequestMode request_mode_; std::vector backups_; }; class SmokeTest : public testing::Test { }; +class PreloadSmokeTest : public testing::Test { + void SetUp() override { + ASSERT_EQ(kGlobalUserUid, kTestUserId); + } +}; + TEST_F(SmokeTest, InstallationMode) { bf::path path = kSmokePackagesDirectory / "InstallationMode.wgt"; std::string pkgid = "smokewgt03"; @@ -1297,7 +1414,7 @@ TEST_F(SmokeTest, MigrateLegacyExternalImageMode) { ValidateExternalPackage(pkgid, {appid}); } -TEST_F(SmokeTest, InstallationMode_Preload) { +TEST_F(PreloadSmokeTest, InstallationMode_Preload) { ASSERT_EQ(getuid(), 0) << "Test cannot be run by normal user"; bf::path path = kSmokePackagesDirectory / "InstallationMode_Preload.wgt"; std::string pkgid = "smokewgt37"; @@ -1307,7 +1424,7 @@ TEST_F(SmokeTest, InstallationMode_Preload) { ValidatePackage(pkgid, {appid}, true); } -TEST_F(SmokeTest, UpdateMode_Preload) { +TEST_F(PreloadSmokeTest, UpdateMode_Preload) { ASSERT_EQ(getuid(), 0) << "Test cannot be run by normal user"; bf::path path_old = kSmokePackagesDirectory / "UpdateMode_Preload.wgt"; bf::path path_new = kSmokePackagesDirectory / "UpdateMode_Preload2.wgt"; @@ -1325,7 +1442,7 @@ TEST_F(SmokeTest, UpdateMode_Preload) { ValidateDataFiles(pkgid, kTestUserId); } -TEST_F(SmokeTest, DeinstallationMode_Preload) { +TEST_F(PreloadSmokeTest, DeinstallationMode_Preload) { ASSERT_EQ(getuid(), 0) << "Test cannot be run by normal user"; bf::path path = kSmokePackagesDirectory / "DeinstallationMode_Preload.wgt"; std::string pkgid = "smokewgt39"; @@ -1412,7 +1529,7 @@ TEST_F(SmokeTest, SharedRes30HybridDelta) { int main(int argc, char** argv) { testing::InitGoogleTest(&argc, argv); - testing::AddGlobalTestEnvironment( - new common_installer::SmokeEnvironment(kGlobalUserUid)); + testing::Environment *env = testing::AddGlobalTestEnvironment( + new common_installer::SmokeEnvironment(ParseRequestMode(argc, argv))); return RUN_ALL_TESTS(); } -- 2.7.4 From 9b081e6b7c72ad675ab372534cfee43589707889 Mon Sep 17 00:00:00 2001 From: Damian Pietruchowski Date: Fri, 3 Mar 2017 14:40:57 +0100 Subject: [PATCH 06/16] [SmokeTest] Skip tests for preload request Tests for preload request should be skipped when request mode is not global and when tests are called by user different than root. Change-Id: I9acd0ed5730162c30ab9a98fe02c8cdd92b8e507 --- src/unit_tests/smoke_test.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/unit_tests/smoke_test.cc b/src/unit_tests/smoke_test.cc index 0cbbfb8..37790e0 100644 --- a/src/unit_tests/smoke_test.cc +++ b/src/unit_tests/smoke_test.cc @@ -1528,8 +1528,13 @@ TEST_F(SmokeTest, SharedRes30HybridDelta) { } // namespace common_installer int main(int argc, char** argv) { + ci::RequestMode request_mode = ParseRequestMode(argc, argv); + if (getuid() != 0 || request_mode != ci::RequestMode::GLOBAL) { + std::cout << "Skip tests for preload request" << std::endl; + ::testing::GTEST_FLAG(filter) = "SmokeTest.*"; + } testing::InitGoogleTest(&argc, argv); testing::Environment *env = testing::AddGlobalTestEnvironment( - new common_installer::SmokeEnvironment(ParseRequestMode(argc, argv))); + new common_installer::SmokeEnvironment(request_mode)); return RUN_ALL_TESTS(); } -- 2.7.4 From ad0b24c375c41a68cd2f279a0358cc54fb525259 Mon Sep 17 00:00:00 2001 From: Piotr Ganicz Date: Mon, 20 Mar 2017 13:28:21 +0100 Subject: [PATCH 07/16] Export Smoke Utils This change exports utility functions to smoke_utils.h Change-Id: I080275d4add34c417710f6c792fe0108780d284f --- src/unit_tests/CMakeLists.txt | 2 + src/unit_tests/smoke_test.cc | 837 +----------------------------------------- src/unit_tests/smoke_utils.cc | 757 ++++++++++++++++++++++++++++++++++++++ src/unit_tests/smoke_utils.h | 242 ++++++++++++ 4 files changed, 1008 insertions(+), 830 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 7b0f80d..5aa1409 100644 --- a/src/unit_tests/CMakeLists.txt +++ b/src/unit_tests/CMakeLists.txt @@ -3,6 +3,8 @@ SET(DESTINATION_DIR wgt-backend-ut) # Executables ADD_EXECUTABLE(${TARGET_SMOKE_TEST} smoke_test.cc + smoke_utils.h + smoke_utils.cc ) ADD_EXECUTABLE(${TARGET_SMOKE_TEST_HELPER} smoke_test_helper.cc diff --git a/src/unit_tests/smoke_test.cc b/src/unit_tests/smoke_test.cc index 37790e0..f446f8a 100644 --- a/src/unit_tests/smoke_test.cc +++ b/src/unit_tests/smoke_test.cc @@ -2,839 +2,15 @@ // 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 -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "hybrid/hybrid_installer.h" -#include "wgt/wgt_app_query_interface.h" -#include "wgt/wgt_installer.h" - -#define SIZEOFARRAY(ARR) \ - sizeof(ARR) / sizeof(ARR[0]) \ - -namespace bf = boost::filesystem; -namespace bs = boost::system; -namespace bo = boost::program_options; -namespace ci = common_installer; - -namespace { -ci::RequestMode ParseRequestMode(int argc, char** argv) { - bo::options_description desc("Available options"); - desc.add_options() - ("request-mode", bo::value(), "set request mode") - ("global-request,g", "set request mode to global") - ("user-request,u", "set request mode to user"); - - bo::variables_map vm; - bo::store(bo::parse_command_line(argc, argv, desc), vm); - bo::notify(vm); - - if (vm.count("global-request")) { - std::cout << "Request mode was set to global." << std::endl; - return ci::RequestMode::GLOBAL; - } - if (vm.count("user-request")) { - std::cout << "Request mode was set to user." << std::endl; - return ci::RequestMode::USER; - } - if (vm.count("request-mode")) { - if (vm["request-mode"].as() == "global") { - std::cout << "Request mode was set to global." << std::endl; - return ci::RequestMode::GLOBAL; - } - if (vm["request-mode"].as() == "user") { - std::cout << "Request mode was set to user." << std::endl; - return ci::RequestMode::USER; - } - std::cout << "Cannot set request mode to " - << vm["request-mode"].as() << std::endl; - std::cout << "Request mode was set to global." << std::endl; - return ci::RequestMode::GLOBAL; - - } -} - -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); -uid_t kTestUserId = kGlobalUserUid; -gid_t kTestGroupId = kGlobalUserGid; -std::string kTestUserIdStr = std::to_string(kTestUserId); -const char kNormalUserName[] = "smokeuser"; -const char kSystemShareGroupName[] = "system_share"; -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/wgt-backend-ut/test_samples/smoke/"; - -enum RWDirectory { - DATA, - CACHE, - SHARED_CACHE, - SHARED_DATA, - SHARED_TRUSTED -}; - -const char* rwDirectories[] = { - "data", - "cache", - "shared/cache", - "shared/data", - "shared/trusted", -}; - -// 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_; -}; - -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; - } -}; - -enum class PackageType { - WGT, - HYBRID -}; - -bool TouchFile(const bf::path& path) { - FILE* f = fopen(path.c_str(), "w+"); - if (!f) - return false; - fclose(f); - return true; -} - -bool AddUser(const char *user_name) { - GumUser* user = nullptr; - user = gum_user_create_sync(FALSE); - if (user == nullptr) - LOG(WARNING) << "Failed to create gum user! (user name: " - << user_name << ")"; - g_object_set(G_OBJECT(user), "username", user_name, "usertype", - GUM_USERTYPE_NORMAL, NULL); - gboolean rval = FALSE; - rval = gum_user_add_sync(user); - g_object_unref(user); - return rval; -} - -bool DeleteUser(const char *user_name, bool rem_home_dir) { - bool rval = FALSE; - GumUser* guser = gum_user_get_by_name_sync(user_name, FALSE); - if(guser) - rval = gum_user_delete_sync(guser, rem_home_dir); - return rval; -} - -bool AddTestUser(const char *user_name) { - std::cout << "Adding test user: " << user_name << std::endl; - bool ret = AddUser(user_name); - if (boost::optional uid = ci::GetUidByUserName(user_name)) { - kTestUserId = *uid; - kTestUserIdStr = std::to_string(kTestUserId); - std::cout << "User created properly: uid=" << *uid; - if (boost::optional gid = ci::GetGidByUid(*uid)) { - kTestGroupId = *gid; - std::cout << " gid=" << *gid; - } - std::cout << std::endl; - return true; - } - LOG(ERROR) << "Adding test user failed"; - return false; -} - -bool DeleteTestUser(const char *user_name) { - std::cout << "Deleting test user: " << user_name << std::endl; - uid_t test_uid; - if (boost::optional uid = ci::GetUidByUserName(user_name)) - test_uid = *uid; - bool ret = DeleteUser(user_name, true); - if (boost::optional uid = ci::GetUidByUserName(user_name)); - else { - std::cout << "User deleted properly: user_name=" << user_name - << " uid=" << test_uid << std::endl; - return true; - } - LOG(ERROR) << "Deleting test user failed"; - 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("/wgt-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("/wgt-recovery") - != std::string::npos) { - return dir_entry.path(); - } - } - } - return {}; -} - -bf::path GetPackageRoot(const std::string& pkgid, uid_t uid) { - bf::path root_path = ci::GetRootAppPath(false, uid); - return root_path / pkgid; -} - -bool ValidateFileContentInPackage(const std::string& pkgid, - const std::string& relative, - const std::string& expected, - bool is_readonly = false) { - bf::path file_path = ci::GetRootAppPath(is_readonly, kTestUserId); - file_path = file_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 AddDataFiles(const std::string& pkgid, uid_t uid) { - if (uid == kGlobalUserUid) { - ci::UserList list = ci::GetUserList(); - for (auto l : list) { - auto pkg_path = GetPackageRoot(pkgid, std::get<0>(l)); - ASSERT_TRUE(TouchFile(pkg_path / "data" / "file1.txt")); - ASSERT_TRUE(TouchFile(pkg_path / "data" / "file2.txt")); - } - } else { - auto pkg_path = GetPackageRoot(pkgid, uid); - ASSERT_TRUE(TouchFile(pkg_path / "data" / "file1.txt")); - ASSERT_TRUE(TouchFile(pkg_path / "data" / "file2.txt")); - } -} - -void ValidateDataFiles(const std::string& pkgid, uid_t uid) { - if (uid == kGlobalUserUid) { - ci::UserList list = ci::GetUserList(); - for (auto l : list) { - auto pkg_path = GetPackageRoot(pkgid, std::get<0>(l)); - ASSERT_TRUE(bf::exists(pkg_path / "data" / "file1.txt")); - ASSERT_TRUE(bf::exists(pkg_path / "data" / "file2.txt")); - } - } else { - auto pkg_path = GetPackageRoot(pkgid, uid); - ASSERT_TRUE(bf::exists(pkg_path / "data" / "file1.txt")); - ASSERT_TRUE(bf::exists(pkg_path / "data" / "file2.txt")); - } -} - -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 / rwDirectories[DATA]; - bf::path cache_path = package_path / rwDirectories[CACHE]; - bf::path shared_data_path = package_path / rwDirectories[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::vector& appids, - 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)); - - for (auto& appid : appids) { - bf::path binary_path = package_path / "bin" / appid; - ASSERT_TRUE(bf::exists(binary_path)); - } - - bf::path widget_root_path = package_path / "res" / "wgt"; - bf::path config_path = widget_root_path / "config.xml"; - ASSERT_TRUE(bf::exists(widget_root_path)); - ASSERT_TRUE(bf::exists(config_path)); - - bf::path private_tmp_path = package_path / "tmp"; - ASSERT_TRUE(bf::exists(private_tmp_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; - bool is_rw_dir = false; - for(const auto rw_dir : rwDirectories) { - bf::path rw_dir_path = rw_dir; - is_rw_dir |= ci::MakeRelativePath(iter->path(), package_path) == rw_dir_path; - } - if (is_rw_dir || iter->path().filename() == ".mmc") { - iter.no_push(); - 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::vector&, 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::vector& appids, bool is_readonly = false) { - ASSERT_TRUE(ci::QueryIsPackageInstalled( - pkgid, ci::GetRequestMode(kTestUserId), kTestUserId)); - ValidatePackageFS(pkgid, appids, 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 ValidateExternalPackageFS(const std::string& pkgid, - const std::vector& appids, - uid_t uid, gid_t gid) { - 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" / "res")); - ValidatePackageFS(pkgid, appids, uid, gid, false); - ASSERT_EQ(app2ext_usr_disable_external_pkg(pkgid.c_str(), uid), 0); -} - -void ValidateExternalPackage(const std::string& pkgid, - const std::vector& appids) { - ASSERT_TRUE(ci::QueryIsPackageInstalled( - pkgid, ci::GetRequestMode(kTestUserId), - kTestUserId)); - 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"); - } - ValidateExternalPackageFS(pkgid, appids, kTestUserId, kTestGroupId); - if (kTestUserId == kGlobalUserUid) { - ci::UserList list = ci::GetUserList(); - for (auto& l : list) - ValidatePackageRWFS(pkgid, std::get<0>(l)); - } else { - ValidatePackageRWFS(pkgid, kTestUserId); - } -} - -void CheckPackageNonExistance(const std::string& pkgid, - const std::vector& appids) { - ASSERT_FALSE(ci::QueryIsPackageInstalled( - pkgid, ci::GetRequestMode(kTestUserId), - kTestUserId)); - PackageCheckCleanup(pkgid, appids); - if (kTestUserId == kGlobalUserUid) { - ci::UserList list = ci::GetUserList(); - bf::path skel_path(kSkelDir); - ASSERT_FALSE(bf::exists(skel_path / pkgid)); - 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)); - } - } -} - -void CheckPackageReadonlyNonExistance(const std::string& pkgid, - const std::vector& appids) { - ASSERT_FALSE(ci::QueryIsPackageInstalled( - pkgid, ci::GetRequestMode(kTestUserId), kTestUserId)); - PackageCheckCleanup(pkgid, appids, true); -} - -std::unique_ptr CreateQueryInterface() { - std::unique_ptr query_interface( - new wgt::WgtAppQueryInterface()); - return query_interface; -} - -std::unique_ptr CreateInstaller(ci::PkgMgrPtr pkgmgr, - PackageType type) { - switch (type) { - case PackageType::WGT: - return std::unique_ptr(new wgt::WgtInstaller(pkgmgr)); - case PackageType::HYBRID: - return std::unique_ptr( - new hybrid::HybridInstaller(pkgmgr)); - default: - LOG(ERROR) << "Unknown installer type"; - return nullptr; - } -} - -ci::AppInstaller::Result RunInstallerWithPkgrmgr(ci::PkgMgrPtr pkgmgr, - PackageType type, - RequestResult mode) { - std::unique_ptr installer = CreateInstaller(pkgmgr, type); - switch (mode) { - case RequestResult::FAIL: - installer->AddStep(); - break; - default: - break; - } - return installer->Run(); -} -ci::AppInstaller::Result CallBackend(int argc, - const char* argv[], - PackageType type, - RequestResult mode = RequestResult::NORMAL - ) { - 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, type, mode); -} - -ci::AppInstaller::Result Install(const bf::path& path, - PackageType type, - RequestResult mode = RequestResult::NORMAL) { - const char* argv[] = {"", "-i", path.c_str(), "-u", kTestUserIdStr.c_str()}; - return CallBackend(SIZEOFARRAY(argv), argv, type, mode); -} - -ci::AppInstaller::Result InstallPreload(const bf::path& path, PackageType type, - RequestResult mode = RequestResult::NORMAL) { - const char* argv[] = {"", "-i", path.c_str(), "--preload"}; - return CallBackend(SIZEOFARRAY(argv), argv, type, 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, - PackageType type, - 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, type, 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, - PackageType type, - RequestResult mode = RequestResult::NORMAL) { - if (InstallExternal(path, type) != 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, type, mode); -} - -ci::AppInstaller::Result MountInstall(const bf::path& path, - PackageType type, RequestResult mode = RequestResult::NORMAL) { - const char* argv[] = {"", "-w", path.c_str(), "-u", kTestUserIdStr.c_str()}; - return CallBackend(SIZEOFARRAY(argv), argv, type, mode); -} - -ci::AppInstaller::Result Uninstall(const std::string& pkgid, - PackageType type, - bool is_preload, - RequestResult mode = RequestResult::NORMAL) { - if (is_preload) { - const char* argv[] = {"", "-d", pkgid.c_str(), "--preload", - "--force-remove"}; - return CallBackend(SIZEOFARRAY(argv), argv, type, mode); - } else { - const char* argv[] = {"", "-d", pkgid.c_str(), "-u", - kTestUserIdStr.c_str()}; - return CallBackend(SIZEOFARRAY(argv), argv, type, mode); - } -} - -ci::AppInstaller::Result RDSUpdate(const bf::path& path, - const std::string& pkgid, - PackageType type, - RequestResult mode = RequestResult::NORMAL) { - if (Install(path, type) != 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, type, mode); -} - -ci::AppInstaller::Result DeltaInstall(const bf::path& path, - const bf::path& delta_package, PackageType type) { - if (Install(path, type) != ci::AppInstaller::Result::OK) { - LOG(ERROR) << "Failed to install application. Cannot perform delta update"; - return ci::AppInstaller::Result::UNKNOWN; - } - return Install(delta_package, type); -} - -ci::AppInstaller::Result EnablePackage(const std::string& pkgid, - PackageType type, - RequestResult mode = RequestResult::NORMAL) { - const char* argv[] = {"", "-A", pkgid.c_str(), "-u", kTestUserIdStr.c_str()}; - return CallBackend(SIZEOFARRAY(argv), argv, type, mode); -} - -ci::AppInstaller::Result DisablePackage(const std::string& pkgid, - PackageType type, - RequestResult mode = RequestResult::NORMAL) { - const char* argv[] = {"", "-D", pkgid.c_str(), "-u", kTestUserIdStr.c_str()}; - return CallBackend(SIZEOFARRAY(argv), argv, type, mode); -} - -ci::AppInstaller::Result Recover(const bf::path& recovery_file, - PackageType type, - RequestResult mode = RequestResult::NORMAL) { - const char* argv[] = {"", "-b", recovery_file.c_str(), "-u", - kTestUserIdStr.c_str()}; - return CallBackend(SIZEOFARRAY(argv), argv, type, 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); - } -} +#include "unit_tests/smoke_utils.h" -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() { - std::vector entries; - bf::path db_dir = bf::path(tzplatform_getenv(TZ_SYS_DB)); - if (kTestUserId != kGlobalUserUid) - db_dir = db_dir / "user" / std::to_string(kTestUserId); - 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 (kTestUserId == 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(kTestUserId); - bf::path approot = tzplatform_getenv(TZ_USER_APPROOT); - tzplatform_reset_user(); - entries.emplace_back(approot); - } - - bf::path apps_rw = ci::GetRootAppPath(false, kTestUserId); - entries.emplace_back(apps_rw); - - return entries; -} - -void UninstallAllAppsInDirectory(bf::path dir, bool is_preload) { - 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)) { - std::string package = dir_entry.path().filename().string(); - std::regex pkg_regex("smoke[a-zA-Z]{3,}[1-9]{2,}"); - if (std::regex_match(package, pkg_regex)) { - if(Uninstall(dir_entry.path().filename().string(), PackageType::WGT, - is_preload, RequestResult::NORMAL) != - ci::AppInstaller::Result::OK) { - LOG(ERROR) << "Cannot uninstall smoke test app: " - << dir_entry.path().filename().string(); - } - } - } - } - } -} - -void UninstallAllSmokeApps(ci::RequestMode request_mode) { - if (getuid() == 0 && request_mode == ci::RequestMode::GLOBAL) { - bf::path root_path = kPreloadApps; - UninstallAllAppsInDirectory(root_path, true); - } - bf::path apps_rw = ci::GetRootAppPath(false, kTestUserId); - UninstallAllAppsInDirectory(apps_rw, false); -} - -} // namespace namespace common_installer { @@ -844,9 +20,9 @@ class SmokeEnvironment : public testing::Environment { request_mode_ = mode; } void SetUp() override { - if (request_mode_ == ci::RequestMode::USER) + if (request_mode_ == ci::RequestMode::USER) { ASSERT_TRUE(AddTestUser(kNormalUserName)); - else { + } else { kTestUserId = kGlobalUserUid; kTestGroupId = kGlobalUserGid; kTestUserIdStr = std::to_string(kTestUserId); @@ -1508,7 +684,8 @@ TEST_F(SmokeTest, SharedRes30Hybrid) { TEST_F(SmokeTest, SharedRes30HybridDelta) { bf::path path = kSmokePackagesDirectory / "SharedRes30HybridDelta.wgt"; - bf::path delta_package = kSmokePackagesDirectory / "SharedRes30HybridDelta.delta"; + bf::path delta_package = kSmokePackagesDirectory / + "SharedRes30HybridDelta.delta"; std::string pkgid = "smokeSh3HD"; std::string appid1 = "smokeSh3HD.SharedRes30HybridDelta"; std::string appid2 = "sharedres30hybriddeltaserivce"; diff --git a/src/unit_tests/smoke_utils.cc b/src/unit_tests/smoke_utils.cc new file mode 100644 index 0000000..c1750f1 --- /dev/null +++ b/src/unit_tests/smoke_utils.cc @@ -0,0 +1,757 @@ +// 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 +#include + +#include "wgt/wgt_installer.h" + +#include "unit_tests/smoke_utils.h" + +namespace bo = boost::program_options; + +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); +uid_t kTestUserId = kGlobalUserUid; +gid_t kTestGroupId = kGlobalUserGid; +const char kNormalUserName[] = "smokeuser"; +const char kSystemShareGroupName[] = "system_share"; +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/wgt-backend-ut/test_samples/smoke/"; + + +const char* rwDirectories[] = { + "data", + "cache", + "shared/cache", + "shared/data", + "shared/trusted", +}; + +// 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"; + + +ci::RequestMode ParseRequestMode(int argc, char** argv) { + bo::options_description desc("Available options"); + desc.add_options() + ("request-mode", bo::value(), "set request mode") + ("global-request,g", "set request mode to global") + ("user-request,u", "set request mode to user"); + + bo::variables_map vm; + bo::store(bo::parse_command_line(argc, argv, desc), vm); + bo::notify(vm); + + if (vm.count("global-request")) { + std::cout << "Request mode was set to global." << std::endl; + return ci::RequestMode::GLOBAL; + } + if (vm.count("user-request")) { + std::cout << "Request mode was set to user." << std::endl; + return ci::RequestMode::USER; + } + if (vm.count("request-mode")) { + if (vm["request-mode"].as() == "global") { + std::cout << "Request mode was set to global." << std::endl; + return ci::RequestMode::GLOBAL; + } + if (vm["request-mode"].as() == "user") { + std::cout << "Request mode was set to user." << std::endl; + return ci::RequestMode::USER; + } + std::cout << "Cannot set request mode to " + << vm["request-mode"].as() << std::endl; + std::cout << "Request mode was set to global." << std::endl; + return ci::RequestMode::GLOBAL; + } +} + +bool TouchFile(const bf::path& path) { + FILE* f = fopen(path.c_str(), "w+"); + if (!f) + return false; + fclose(f); + return true; +} + +bool AddUser(const char *user_name) { + GumUser* user = nullptr; + user = gum_user_create_sync(FALSE); + if (user == nullptr) + LOG(WARNING) << "Failed to create gum user! (user name: " + << user_name << ")"; + g_object_set(G_OBJECT(user), "username", user_name, "usertype", + GUM_USERTYPE_NORMAL, NULL); + gboolean rval = FALSE; + rval = gum_user_add_sync(user); + g_object_unref(user); + return rval; +} + +bool DeleteUser(const char *user_name, bool rem_home_dir) { + bool rval = FALSE; + GumUser* guser = gum_user_get_by_name_sync(user_name, FALSE); + if (guser) + rval = gum_user_delete_sync(guser, rem_home_dir); + return rval; +} + +bool AddTestUser(const char *user_name) { + std::cout << "Adding test user: " << user_name << std::endl; + bool ret = AddUser(user_name); + if (boost::optional uid = ci::GetUidByUserName(user_name)) { + kTestUserId = *uid; + kTestUserIdStr = std::to_string(kTestUserId); + std::cout << "User created properly: uid=" << *uid; + if (boost::optional gid = ci::GetGidByUid(*uid)) { + kTestGroupId = *gid; + std::cout << " gid=" << *gid; + } + std::cout << std::endl; + return true; + } + LOG(ERROR) << "Adding test user failed"; + return false; +} + +bool DeleteTestUser(const char *user_name) { + std::cout << "Deleting test user: " << user_name << std::endl; + uid_t test_uid; + if (boost::optional uid = ci::GetUidByUserName(user_name)) + test_uid = *uid; + bool ret = DeleteUser(user_name, true); + if (!ci::GetUidByUserName(user_name)) { + std::cout << "User deleted properly: user_name=" << user_name + << " uid=" << test_uid << std::endl; + return true; + } + LOG(ERROR) << "Deleting test user failed"; + 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("/wgt-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("/wgt-recovery") + != std::string::npos) { + return dir_entry.path(); + } + } + } + return {}; +} + +bf::path GetPackageRoot(const std::string& pkgid, uid_t uid) { + bf::path root_path = ci::GetRootAppPath(false, uid); + return root_path / pkgid; +} + +bool ValidateFileContentInPackage(const std::string& pkgid, + const std::string& relative, + const std::string& expected, + bool is_readonly) { + bf::path file_path = ci::GetRootAppPath(is_readonly, kTestUserId); + file_path = file_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 AddDataFiles(const std::string& pkgid, uid_t uid) { + if (uid == kGlobalUserUid) { + ci::UserList list = ci::GetUserList(); + for (auto l : list) { + auto pkg_path = GetPackageRoot(pkgid, std::get<0>(l)); + ASSERT_TRUE(TouchFile(pkg_path / "data" / "file1.txt")); + ASSERT_TRUE(TouchFile(pkg_path / "data" / "file2.txt")); + } + } else { + auto pkg_path = GetPackageRoot(pkgid, uid); + ASSERT_TRUE(TouchFile(pkg_path / "data" / "file1.txt")); + ASSERT_TRUE(TouchFile(pkg_path / "data" / "file2.txt")); + } +} + +void ValidateDataFiles(const std::string& pkgid, uid_t uid) { + if (uid == kGlobalUserUid) { + ci::UserList list = ci::GetUserList(); + for (auto l : list) { + auto pkg_path = GetPackageRoot(pkgid, std::get<0>(l)); + ASSERT_TRUE(bf::exists(pkg_path / "data" / "file1.txt")); + ASSERT_TRUE(bf::exists(pkg_path / "data" / "file2.txt")); + } + } else { + auto pkg_path = GetPackageRoot(pkgid, uid); + ASSERT_TRUE(bf::exists(pkg_path / "data" / "file1.txt")); + ASSERT_TRUE(bf::exists(pkg_path / "data" / "file2.txt")); + } +} + +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 / rwDirectories[DATA]; + bf::path cache_path = package_path / rwDirectories[CACHE]; + bf::path shared_data_path = package_path / rwDirectories[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::vector& appids, + 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)); + + for (auto& appid : appids) { + bf::path binary_path = package_path / "bin" / appid; + ASSERT_TRUE(bf::exists(binary_path)); + } + + bf::path widget_root_path = package_path / "res" / "wgt"; + bf::path config_path = widget_root_path / "config.xml"; + ASSERT_TRUE(bf::exists(widget_root_path)); + ASSERT_TRUE(bf::exists(config_path)); + + bf::path private_tmp_path = package_path / "tmp"; + ASSERT_TRUE(bf::exists(private_tmp_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; + bool is_rw_dir = false; + for (const auto rw_dir : rwDirectories) { + bf::path rw_dir_path = rw_dir; + is_rw_dir |= ci::MakeRelativePath(iter->path(), package_path) + == rw_dir_path; + } + if (is_rw_dir || iter->path().filename() == ".mmc") { + iter.no_push(); + 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::vector&, 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::vector& appids, bool is_readonly) { + ASSERT_TRUE(ci::QueryIsPackageInstalled( + pkgid, ci::GetRequestMode(kTestUserId), kTestUserId)); + ValidatePackageFS(pkgid, appids, 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 ValidateExternalPackageFS(const std::string& pkgid, + const std::vector& appids, + uid_t uid, gid_t gid) { + 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" / "res")); + ValidatePackageFS(pkgid, appids, uid, gid, false); + ASSERT_EQ(app2ext_usr_disable_external_pkg(pkgid.c_str(), uid), 0); +} + +void ValidateExternalPackage(const std::string& pkgid, + const std::vector& appids) { + ASSERT_TRUE(ci::QueryIsPackageInstalled( + pkgid, ci::GetRequestMode(kTestUserId), + kTestUserId)); + 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"); + } + ValidateExternalPackageFS(pkgid, appids, kTestUserId, kTestGroupId); + if (kTestUserId == kGlobalUserUid) { + ci::UserList list = ci::GetUserList(); + for (auto& l : list) + ValidatePackageRWFS(pkgid, std::get<0>(l)); + } else { + ValidatePackageRWFS(pkgid, kTestUserId); + } +} + +void CheckPackageNonExistance(const std::string& pkgid, + const std::vector& appids) { + ASSERT_FALSE(ci::QueryIsPackageInstalled( + pkgid, ci::GetRequestMode(kTestUserId), + kTestUserId)); + PackageCheckCleanup(pkgid, appids); + if (kTestUserId == kGlobalUserUid) { + ci::UserList list = ci::GetUserList(); + bf::path skel_path(kSkelDir); + ASSERT_FALSE(bf::exists(skel_path / pkgid)); + 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)); + } + } +} + +void CheckPackageReadonlyNonExistance(const std::string& pkgid, + const std::vector& appids) { + ASSERT_FALSE(ci::QueryIsPackageInstalled( + pkgid, ci::GetRequestMode(kTestUserId), kTestUserId)); + PackageCheckCleanup(pkgid, appids, true); +} + +std::unique_ptr CreateQueryInterface() { + std::unique_ptr query_interface( + new wgt::WgtAppQueryInterface()); + return query_interface; +} + +std::unique_ptr CreateInstaller(ci::PkgMgrPtr pkgmgr, + PackageType type) { + switch (type) { + case PackageType::WGT: + return std::unique_ptr(new wgt::WgtInstaller(pkgmgr)); + case PackageType::HYBRID: + return std::unique_ptr( + new hybrid::HybridInstaller(pkgmgr)); + default: + LOG(ERROR) << "Unknown installer type"; + return nullptr; + } +} + +ci::AppInstaller::Result RunInstallerWithPkgrmgr(ci::PkgMgrPtr pkgmgr, + PackageType type, + RequestResult mode) { + std::unique_ptr installer = CreateInstaller(pkgmgr, type); + switch (mode) { + case RequestResult::FAIL: + installer->AddStep(); + break; + default: + break; + } + return installer->Run(); +} +ci::AppInstaller::Result CallBackend(int argc, + const char* argv[], + PackageType type, + 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, type, mode); +} + +ci::AppInstaller::Result Install(const bf::path& path, + PackageType type, + RequestResult mode) { + const char* argv[] = {"", "-i", path.c_str(), "-u", kTestUserIdStr.c_str()}; + return CallBackend(SIZEOFARRAY(argv), argv, type, mode); +} + +ci::AppInstaller::Result InstallPreload(const bf::path& path, PackageType type, + RequestResult mode) { + const char* argv[] = {"", "-i", path.c_str(), "--preload"}; + return CallBackend(SIZEOFARRAY(argv), argv, type, 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, + PackageType type, + 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, type, 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, + PackageType type, + RequestResult mode) { + if (InstallExternal(path, type) != 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, type, mode); +} + +ci::AppInstaller::Result MountInstall(const bf::path& path, + PackageType type, RequestResult mode) { + const char* argv[] = {"", "-w", path.c_str(), "-u", kTestUserIdStr.c_str()}; + return CallBackend(SIZEOFARRAY(argv), argv, type, mode); +} + +ci::AppInstaller::Result Uninstall(const std::string& pkgid, + PackageType type, + bool is_preload, + RequestResult mode) { + if (is_preload) { + const char* argv[] = {"", "-d", pkgid.c_str(), "--preload", + "--force-remove"}; + return CallBackend(SIZEOFARRAY(argv), argv, type, mode); + } else { + const char* argv[] = {"", "-d", pkgid.c_str(), "-u", + kTestUserIdStr.c_str()}; + return CallBackend(SIZEOFARRAY(argv), argv, type, mode); + } +} + +ci::AppInstaller::Result RDSUpdate(const bf::path& path, + const std::string& pkgid, + PackageType type, + RequestResult mode) { + if (Install(path, type) != 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, type, mode); +} + +ci::AppInstaller::Result DeltaInstall(const bf::path& path, + const bf::path& delta_package, PackageType type) { + if (Install(path, type) != ci::AppInstaller::Result::OK) { + LOG(ERROR) << "Failed to install application. Cannot perform delta update"; + return ci::AppInstaller::Result::UNKNOWN; + } + return Install(delta_package, type); +} + +ci::AppInstaller::Result EnablePackage(const std::string& pkgid, + PackageType type, + RequestResult mode) { + const char* argv[] = {"", "-A", pkgid.c_str(), "-u", kTestUserIdStr.c_str()}; + return CallBackend(SIZEOFARRAY(argv), argv, type, mode); +} + +ci::AppInstaller::Result DisablePackage(const std::string& pkgid, + PackageType type, + RequestResult mode) { + const char* argv[] = {"", "-D", pkgid.c_str(), "-u", kTestUserIdStr.c_str()}; + return CallBackend(SIZEOFARRAY(argv), argv, type, mode); +} + +ci::AppInstaller::Result Recover(const bf::path& recovery_file, + PackageType type, + RequestResult mode) { + const char* argv[] = {"", "-b", recovery_file.c_str(), "-u", + kTestUserIdStr.c_str()}; + return CallBackend(SIZEOFARRAY(argv), argv, type, 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() { + std::vector entries; + bf::path db_dir = bf::path(tzplatform_getenv(TZ_SYS_DB)); + if (kTestUserId != kGlobalUserUid) + db_dir = db_dir / "user" / std::to_string(kTestUserId); + 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 (kTestUserId == 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(kTestUserId); + bf::path approot = tzplatform_getenv(TZ_USER_APPROOT); + tzplatform_reset_user(); + entries.emplace_back(approot); + } + + bf::path apps_rw = ci::GetRootAppPath(false, kTestUserId); + entries.emplace_back(apps_rw); + + return entries; +} + +void UninstallAllAppsInDirectory(bf::path dir, bool is_preload) { + 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)) { + std::string package = dir_entry.path().filename().string(); + std::regex pkg_regex("smoke[a-zA-Z]{3,}[1-9]{2,}"); + if (std::regex_match(package, pkg_regex)) { + if (Uninstall(dir_entry.path().filename().string(), PackageType::WGT, + is_preload, RequestResult::NORMAL) != + ci::AppInstaller::Result::OK) { + LOG(ERROR) << "Cannot uninstall smoke test app: " + << dir_entry.path().filename().string(); + } + } + } + } + } +} + +void UninstallAllSmokeApps(ci::RequestMode request_mode) { + if (getuid() == 0 && request_mode == ci::RequestMode::GLOBAL) { + bf::path root_path = kPreloadApps; + UninstallAllAppsInDirectory(root_path, true); + } + bf::path apps_rw = ci::GetRootAppPath(false, kTestUserId); + 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..efc2551 --- /dev/null +++ b/src/unit_tests/smoke_utils.h @@ -0,0 +1,242 @@ +// 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 +#include + +#include "hybrid/hybrid_installer.h" +#include "wgt/wgt_app_query_interface.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; +extern uid_t kTestUserId; +extern gid_t kTestGroupId; +extern std::string kTestUserIdStr; +extern const char kNormalUserName[]; +extern const char kSystemShareGroupName[]; +extern const std::string& kDefaultUserIdStr; +extern const char kLegacyExtImageDir[]; +extern const char kMigrateTestDBName[]; + +extern const bf::path kSmokePackagesDirectory; + +enum RWDirectory { + DATA, + CACHE, + SHARED_CACHE, + SHARED_DATA, + SHARED_TRUSTED +}; + +extern const char* rwDirectories[]; + +// 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; + } +}; + +enum class PackageType { + WGT, + HYBRID +}; + +ci::RequestMode ParseRequestMode(int argc, char** argv); + +bool TouchFile(const bf::path& path); + +bool AddUser(const char *user_name); + +bool DeleteUser(const char *user_name, bool rem_home_dir); + +bool AddTestUser(const char *user_name); + +bool DeleteTestUser(const char *user_name); + +void RemoveAllRecoveryFiles(); + +bf::path FindRecoveryFile(); + +bf::path GetPackageRoot(const std::string& pkgid, uid_t uid); + +bool ValidateFileContentInPackage(const std::string& pkgid, + const std::string& relative, + const std::string& expected, + bool is_readonly = false); + +void AddDataFiles(const std::string& pkgid, uid_t uid); + +void ValidateDataFiles(const std::string& pkgid, uid_t uid); + +void ValidatePackageRWFS(const std::string& pkgid, uid_t uid); + +void ValidatePackageFS(const std::string& pkgid, + const std::vector& appids, + uid_t uid, gid_t gid, bool is_readonly); + +void PackageCheckCleanup(const std::string& pkgid, + const std::vector&, bool is_readonly = false); + +void ValidatePackage(const std::string& pkgid, + const std::vector& appids, bool is_readonly = false); + +void ValidateExternalPackageFS(const std::string& pkgid, + const std::vector& appids, + uid_t uid, gid_t gid); + +void ValidateExternalPackage(const std::string& pkgid, + const std::vector& appids); + +void CheckPackageNonExistance(const std::string& pkgid, + const std::vector& appids); + +void CheckPackageReadonlyNonExistance(const std::string& pkgid, + const std::vector& appids); + +std::unique_ptr CreateQueryInterface(); + +std::unique_ptr CreateInstaller(ci::PkgMgrPtr pkgmgr, + PackageType type); + +ci::AppInstaller::Result RunInstallerWithPkgrmgr(ci::PkgMgrPtr pkgmgr, + PackageType type, + RequestResult mode); +ci::AppInstaller::Result CallBackend(int argc, + const char* argv[], + PackageType type, + RequestResult mode + = RequestResult::NORMAL); + +ci::AppInstaller::Result Install(const bf::path& path, + PackageType type, + RequestResult mode = RequestResult::NORMAL); + +ci::AppInstaller::Result InstallPreload(const bf::path& path, PackageType type, + RequestResult mode = RequestResult::NORMAL); + +bool CheckAvailableExternalPath(); + +ci::AppInstaller::Result InstallExternal(const bf::path& path, + PackageType type, + RequestResult mode = RequestResult::NORMAL); + +ci::AppInstaller::Result MigrateLegacyExternalImage(const std::string& pkgid, + const bf::path& path, + const bf::path& legacy_path, + PackageType type, + RequestResult mode = RequestResult::NORMAL); + +ci::AppInstaller::Result MountInstall(const bf::path& path, + PackageType type, RequestResult mode = RequestResult::NORMAL); + +ci::AppInstaller::Result Uninstall(const std::string& pkgid, + PackageType type, + bool is_preload, + RequestResult mode = RequestResult::NORMAL); + +ci::AppInstaller::Result RDSUpdate(const bf::path& path, + const std::string& pkgid, + PackageType type, + RequestResult mode = RequestResult::NORMAL); + +ci::AppInstaller::Result DeltaInstall(const bf::path& path, + const bf::path& delta_package, PackageType type); + +ci::AppInstaller::Result EnablePackage(const std::string& pkgid, + PackageType type, + RequestResult mode = RequestResult::NORMAL); + +ci::AppInstaller::Result DisablePackage(const std::string& pkgid, + PackageType type, + RequestResult mode = RequestResult::NORMAL); + +ci::AppInstaller::Result Recover(const bf::path& recovery_file, + PackageType type, + RequestResult mode = RequestResult::NORMAL); + +void BackupPath(const bf::path& path); + +void RestorePath(const bf::path& path); + +std::vector SetupBackupDirectories(); + +void UninstallAllAppsInDirectory(bf::path dir, bool is_preload); + +void UninstallAllSmokeApps(ci::RequestMode request_mode); + + +#endif // UNIT_TESTS_SMOKE_UTILS_H_ -- 2.7.4 From bbce0a0830cbaffba1f8b0a78109f20e142b1049 Mon Sep 17 00:00:00 2001 From: Piotr Ganicz Date: Mon, 20 Mar 2017 15:41:46 +0100 Subject: [PATCH 08/16] Extensive tests for Recovery and Rollback This commit creates new executable (extensive-smoke-test) for new type of tests which will be testing recovery and rollback modes after each step in each installation mode. Requires: - https://review.tizen.org/gerrit/#/c/116059/ - https://review.tizen.org/gerrit/#/c/119925/ Change-Id: Ib39dfd3df2f42ff33644904f682775a6a9b113f7 --- CMakeLists.txt | 1 + src/unit_tests/CMakeLists.txt | 13 ++ src/unit_tests/extensive_smoke_test.cc | 388 +++++++++++++++++++++++++++++++++ src/unit_tests/smoke_test.cc | 96 ++++---- src/unit_tests/smoke_test_helper.cc | 14 +- src/unit_tests/smoke_utils.cc | 142 ++++++++---- src/unit_tests/smoke_utils.h | 40 +++- 7 files changed, 603 insertions(+), 91 deletions(-) create mode 100644 src/unit_tests/extensive_smoke_test.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 465821f..86b3f98 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,7 @@ SET(TARGET_WGT_BACKEND "wgt-backend") SET(TARGET_LIBNAME_HYBRID "hybrid-installer") SET(TARGET_SMOKE_TEST "smoke-test") +SET(TARGET_SMOKE_TEST_EXTENSIVE "extensive-smoke-test") SET(TARGET_SMOKE_TEST_HELPER "smoke-test-helper") SET(TARGET_MANIFEST_TEST "manifest-test") diff --git a/src/unit_tests/CMakeLists.txt b/src/unit_tests/CMakeLists.txt index 5aa1409..6b0aac1 100644 --- a/src/unit_tests/CMakeLists.txt +++ b/src/unit_tests/CMakeLists.txt @@ -6,6 +6,11 @@ ADD_EXECUTABLE(${TARGET_SMOKE_TEST} smoke_utils.h smoke_utils.cc ) +ADD_EXECUTABLE(${TARGET_SMOKE_TEST_EXTENSIVE} + extensive_smoke_test.cc + smoke_utils.h + smoke_utils.cc +) ADD_EXECUTABLE(${TARGET_SMOKE_TEST_HELPER} smoke_test_helper.cc ) @@ -14,6 +19,7 @@ ADD_EXECUTABLE(${TARGET_MANIFEST_TEST} ) TARGET_INCLUDE_DIRECTORIES(${TARGET_SMOKE_TEST} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../) +TARGET_INCLUDE_DIRECTORIES(${TARGET_SMOKE_TEST_EXTENSIVE} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../) TARGET_INCLUDE_DIRECTORIES(${TARGET_SMOKE_TEST_HELPER} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../) TARGET_INCLUDE_DIRECTORIES(${TARGET_MANIFEST_TEST} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../) @@ -24,6 +30,11 @@ APPLY_PKG_CONFIG(${TARGET_SMOKE_TEST} PUBLIC GTEST GUM_DEPS ) +APPLY_PKG_CONFIG(${TARGET_SMOKE_TEST_EXTENSIVE} PUBLIC + Boost + GTEST + GUM_DEPS +) APPLY_PKG_CONFIG(${TARGET_MANIFEST_TEST} PUBLIC Boost GTEST @@ -33,9 +44,11 @@ APPLY_PKG_CONFIG(${TARGET_MANIFEST_TEST} PUBLIC # GTest main libraries is still missing, so additional linking of # GTEST_MAIN_LIBRARIES is needed. TARGET_LINK_LIBRARIES(${TARGET_SMOKE_TEST} PRIVATE ${TARGET_LIBNAME_WGT} ${TARGET_LIBNAME_HYBRID} ${GTEST_MAIN_LIBRARIES}) +TARGET_LINK_LIBRARIES(${TARGET_SMOKE_TEST_EXTENSIVE} PRIVATE ${TARGET_LIBNAME_WGT} ${TARGET_LIBNAME_HYBRID} ${GTEST_MAIN_LIBRARIES}) TARGET_LINK_LIBRARIES(${TARGET_SMOKE_TEST_HELPER} PRIVATE ${TARGET_LIBNAME_WGT}) TARGET_LINK_LIBRARIES(${TARGET_MANIFEST_TEST} PRIVATE ${TARGET_LIBNAME_WGT} ${GTEST_MAIN_LIBRARIES}) INSTALL(TARGETS ${TARGET_SMOKE_TEST} DESTINATION ${BINDIR}/${DESTINATION_DIR}) +INSTALL(TARGETS ${TARGET_SMOKE_TEST_EXTENSIVE} DESTINATION ${BINDIR}/${DESTINATION_DIR}) INSTALL(TARGETS ${TARGET_SMOKE_TEST_HELPER} DESTINATION ${BINDIR}/${DESTINATION_DIR}) INSTALL(TARGETS ${TARGET_MANIFEST_TEST} DESTINATION ${BINDIR}/${DESTINATION_DIR}) diff --git a/src/unit_tests/extensive_smoke_test.cc b/src/unit_tests/extensive_smoke_test.cc new file mode 100644 index 0000000..58f11f6 --- /dev/null +++ b/src/unit_tests/extensive_smoke_test.cc @@ -0,0 +1,388 @@ +// 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 "unit_tests/smoke_utils.h" + + +namespace common_installer { + +class SmokeEnvironment : public testing::Environment { + public: + explicit SmokeEnvironment(ci::RequestMode mode) {\ + request_mode_ = mode; + } + void SetUp() override { + if (request_mode_ == ci::RequestMode::USER) { + ASSERT_TRUE(AddTestUser(kNormalUserName)); + } else { + kTestUserId = kGlobalUserUid; + kTestGroupId = kGlobalUserGid; + kTestUserIdStr = std::to_string(kTestUserId); + } + backups_ = SetupBackupDirectories(); + for (auto& path : backups_) + BackupPath(path); + } + void TearDown() override { + ASSERT_TRUE(request_mode_ == ci::RequestMode::GLOBAL || + (request_mode_ == ci::RequestMode::USER && + kGlobalUserUid != kTestUserId)); + UninstallAllSmokeApps(request_mode_); + for (auto& path : backups_) + RestorePath(path); + if (request_mode_ == ci::RequestMode::USER) + ASSERT_TRUE(DeleteTestUser(kNormalUserName)); + } + + private: + ci::RequestMode request_mode_; + std::vector backups_; +}; + +class SmokeTest : public testing::Test { +}; + +class PreloadSmokeTest : public testing::Test { + void SetUp() override { + ASSERT_EQ(kGlobalUserUid, kTestUserId); + } +}; + +TEST_F(SmokeTest, RecoveryMode_ForInstallation) { + bf::path path = kSmokePackagesDirectory / "RecoveryMode_ForInstallation.wgt"; + std::string pkgid = "smokewgt09"; + std::string appid = "smokewgt09.RecoveryModeForInstallation"; + + std::vector args = + {"", "-i", path.string(), "-u", kTestUserIdStr.c_str()}; + CrashAfterEachStep(args, [=](int step) -> bool { + if (step >= 1) { + bf::path recovery_file = FindRecoveryFile(); + EXTENDED_ASSERT_FALSE(recovery_file.empty()); + EXTENDED_ASSERT_EQ(Recover(recovery_file, PackageType::WGT), + ci::AppInstaller::Result::OK); + EXTENDED_ASSERT_TRUE(CheckPackageNonExistance(pkgid, {appid})); + } + return true; + }); +} + +TEST_F(SmokeTest, RecoveryMode_ForUpdate) { + bf::path path_old = kSmokePackagesDirectory / "RecoveryMode_ForUpdate.wgt"; + bf::path path_new = kSmokePackagesDirectory / "RecoveryMode_ForUpdate_2.wgt"; + RemoveAllRecoveryFiles(); + ASSERT_EQ(Install(path_old, PackageType::WGT), ci::AppInstaller::Result::OK); + std::string pkgid = "smokewgt10"; + std::string appid = "smokewgt10.RecoveryModeForUpdate"; + AddDataFiles(pkgid, kTestUserId); + + std::vector args = + {"", "-i", path_new.string(), "-u", kTestUserIdStr.c_str()}; + CrashAfterEachStep(args, [=](int step) -> bool { + if (step >= 1) { + bf::path recovery_file = FindRecoveryFile(); + EXTENDED_ASSERT_FALSE(recovery_file.empty()); + EXTENDED_ASSERT_EQ(Recover(recovery_file, PackageType::WGT), + ci::AppInstaller::Result::OK); + EXTENDED_ASSERT_TRUE(ValidatePackage(pkgid, {appid})); + + EXTENDED_ASSERT_TRUE(ValidateFileContentInPackage(pkgid, + "res/wgt/VERSION", "1\n")); + EXTENDED_ASSERT_TRUE(ValidateDataFiles(pkgid, kTestUserId)); + } + return true; + }); +} + +TEST_F(SmokeTest, RecoveryMode_ForDelta) { + bf::path path_old = kSmokePackagesDirectory / "RecoveryMode_ForDelta.wgt"; + bf::path path_new = kSmokePackagesDirectory / "RecoveryMode_ForDelta.delta"; + std::string pkgid = "smokewgt30"; + std::string appid = "smokewgt30.RecoveryModeForDelta"; + bf::path recovery_file = FindRecoveryFile(); + RemoveAllRecoveryFiles(); + std::vector args = + {"", "-i", path_new.string(), "-u", kTestUserIdStr.c_str()}; + CrashAfterEachStep(args, [=](int step) -> bool { + if (step >= 1) { + EXTENDED_ASSERT_FALSE(recovery_file.empty()); + EXTENDED_ASSERT_EQ(Recover(recovery_file, PackageType::WGT), + ci::AppInstaller::Result::OK); + EXTENDED_ASSERT_TRUE(ValidatePackage(pkgid, {appid})); + + EXTENDED_ASSERT_TRUE(ValidateFileContentInPackage(pkgid, + "res/wgt/VERSION", "1\n")); + } + return true; + }); +} + +TEST_F(SmokeTest, RecoveryMode_ForMountInstall) { + bf::path path = kSmokePackagesDirectory / "RecoveryMode_ForMountInstall.wgt"; + std::string pkgid = "smokewgt31"; + std::string appid = "smokewgt31.RecoveryModeForMountInstall"; + RemoveAllRecoveryFiles(); + std::vector args = + {"", "-w", path.string(), "-u", kTestUserIdStr.c_str()}; + CrashAfterEachStep(args, [=](int step) -> bool { + if (step >= 1) { + bf::path recovery_file = FindRecoveryFile(); + EXTENDED_ASSERT_FALSE(recovery_file.empty()); + EXTENDED_ASSERT_EQ(Recover(recovery_file, PackageType::WGT), + ci::AppInstaller::Result::OK); + EXTENDED_ASSERT_TRUE(CheckPackageNonExistance(pkgid, {appid})); + } + return true; + }); +} + +TEST_F(SmokeTest, RecoveryMode_ForMountUpdate) { + bf::path path_old = + kSmokePackagesDirectory / "RecoveryMode_ForMountUpdate.wgt"; + bf::path path_new = + kSmokePackagesDirectory / "RecoveryMode_ForMountUpdate_2.wgt"; + std::string pkgid = "smokewgt32"; + std::string appid = "smokewgt32.RecoveryModeForMountUpdate"; + RemoveAllRecoveryFiles(); + ASSERT_EQ(MountInstall(path_old, PackageType::WGT), + ci::AppInstaller::Result::OK); + AddDataFiles(pkgid, kTestUserId); + std::vector args = + {"", "-w", path_new.string(), "-u", kTestUserIdStr.c_str()}; + CrashAfterEachStep(args, [=](int step) -> bool { + if (step >= 1) { + // Filesystem may be mounted after crash + ScopedTzipInterface poweroff_unmount_interface(pkgid); + poweroff_unmount_interface.Release(); + + bf::path recovery_file = FindRecoveryFile(); + EXTENDED_ASSERT_FALSE(recovery_file.empty()); + EXTENDED_ASSERT_EQ(Recover(recovery_file, PackageType::WGT), + ci::AppInstaller::Result::OK); + + ScopedTzipInterface interface(pkgid); + EXTENDED_ASSERT_TRUE(ValidatePackage(pkgid, {appid})); + EXTENDED_ASSERT_TRUE(ValidateFileContentInPackage( + pkgid, "res/wgt/VERSION", "1\n")); + EXTENDED_ASSERT_TRUE(ValidateDataFiles(pkgid, kTestUserId)); + } + return true; + }); +} + + +TEST_F(SmokeTest, InstallationMode_Rollback) { + bf::path path = kSmokePackagesDirectory / "InstallationMode_Rollback.wgt"; + std::string pkgid = "smokewgt06"; + std::string appid = "smokewgt06.InstallationModeRollback"; + + const char* argv[] = {"", "-i", path.c_str(), "-u", kTestUserIdStr.c_str()}; + TestRollbackAfterEachStep(SIZEOFARRAY(argv), argv, [=]() -> bool { + EXTENDED_ASSERT_EQ(Install(path, PackageType::WGT, RequestResult::FAIL), + ci::AppInstaller::Result::ERROR); + EXTENDED_ASSERT_TRUE(CheckPackageNonExistance(pkgid, {appid})); + return true; + }); +} + +TEST_F(SmokeTest, UpdateMode_Rollback) { + bf::path path_old = kSmokePackagesDirectory / "UpdateMode_Rollback.wgt"; + bf::path path_new = kSmokePackagesDirectory / "UpdateMode_Rollback_2.wgt"; + std::string pkgid = "smokewgt07"; + std::string appid = "smokewgt07.UpdateModeRollback"; + ASSERT_EQ(Install(path_old, PackageType::WGT), ci::AppInstaller::Result::OK); + AddDataFiles(pkgid, kTestUserId); + const char* argv[] = + {"", "-i", path_new.c_str(), "-u", kTestUserIdStr.c_str()}; + TestRollbackAfterEachStep(SIZEOFARRAY(argv), argv, [=]() -> bool { + EXTENDED_ASSERT_EQ(Install(path_new, PackageType::WGT, RequestResult::FAIL), + ci::AppInstaller::Result::ERROR); + EXTENDED_ASSERT_TRUE(ValidatePackage(pkgid, {appid})); + + EXTENDED_ASSERT_TRUE(ValidateFileContentInPackage(pkgid, + "res/wgt/VERSION", "1\n")); + EXTENDED_ASSERT_TRUE(ValidateDataFiles(pkgid, kTestUserId)); + return true; + }); +} + +TEST_F(SmokeTest, DeltaMode_Rollback) { + bf::path path = kSmokePackagesDirectory / "DeltaMode_Rollback.wgt"; + bf::path delta_package = kSmokePackagesDirectory / "DeltaMode_Rollback.delta"; + std::string pkgid = "smokewgt01"; + std::string appid = "smokewgt01.DeltaMode"; + ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK); + AddDataFiles(pkgid, kTestUserId); + const char* argv[] = + {"", "-i", delta_package.c_str(), "-u", kTestUserIdStr.c_str()}; + TestRollbackAfterEachStep(SIZEOFARRAY(argv), argv, [=]() -> bool { + EXTENDED_ASSERT_TRUE(ValidatePackage(pkgid, {appid})); + EXTENDED_ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED", + "version 1\n")); + EXTENDED_ASSERT_TRUE(ValidateDataFiles(pkgid, kTestUserId)); + EXTENDED_ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) / + "res/wgt/DELETED")); + EXTENDED_ASSERT_FALSE(bf::exists(GetPackageRoot(pkgid, kTestUserId) / + "res/wgt/ADDED")); + return true; + }); +} + +TEST_F(SmokeTest, InstallationMode_Rollback_Hybrid) { + bf::path path = kSmokePackagesDirectory / + "InstallationMode_Rollback_Hybrid.wgt"; + std::string pkgid = "smokehyb07"; + std::string appid1 = "smokehyb07.web"; + const char* argv[] = {"", "-i", path.c_str(), "-u", kTestUserIdStr.c_str()}; + TestRollbackAfterEachStep(SIZEOFARRAY(argv), argv, [=]() -> bool { + EXTENDED_ASSERT_TRUE(CheckPackageNonExistance(pkgid, {appid1})); + return true; + }, PackageType::HYBRID); +} + +TEST_F(SmokeTest, UpdateMode_Rollback_Hybrid) { + bf::path path_old = kSmokePackagesDirectory / + "UpdateMode_Rollback_Hybrid.wgt"; + bf::path path_new = kSmokePackagesDirectory / + "UpdateMode_Rollback_Hybrid_2.wgt"; + std::string pkgid = "smokehyb08"; + std::string appid1 = "smokehyb08.web"; + ASSERT_EQ(Install(path_old, PackageType::HYBRID), + ci::AppInstaller::Result::OK); + AddDataFiles(pkgid, kTestUserId); + const char* argv[] = + {"", "-i", path_new.c_str(), "-u", kTestUserIdStr.c_str()}; + TestRollbackAfterEachStep(SIZEOFARRAY(argv), argv, [=]() -> bool { + EXTENDED_ASSERT_TRUE(ValidatePackage(pkgid, {appid1})); + + EXTENDED_ASSERT_TRUE(ValidateFileContentInPackage(pkgid, + "res/wgt/VERSION", "1\n")); + EXTENDED_ASSERT_TRUE(ValidateFileContentInPackage(pkgid, + "lib/VERSION", "1\n")); + EXTENDED_ASSERT_TRUE(ValidateDataFiles(pkgid, kTestUserId)); + return true; + }, PackageType::HYBRID); +} + +TEST_F(SmokeTest, DeltaMode_Rollback_Hybrid) { + bf::path path = kSmokePackagesDirectory / "DeltaMode_Rollback_Hybrid.wgt"; + bf::path delta_package = kSmokePackagesDirectory / + "DeltaMode_Rollback_Hybrid.delta"; + std::string pkgid = "smokehyb11"; + std::string appid1 = "smokehyb11.web"; + ASSERT_EQ(Install(path, PackageType::HYBRID), ci::AppInstaller::Result::OK); + AddDataFiles(pkgid, kTestUserId); + const char* argv[] = {"", "-i", path.c_str(), "-u", kTestUserIdStr.c_str()}; + TestRollbackAfterEachStep(SIZEOFARRAY(argv), argv, [=]() -> bool { + EXTENDED_ASSERT_TRUE(ValidatePackage(pkgid, {appid1})); + // Check delta modifications + bf::path root_path = GetPackageRoot(pkgid, kTestUserId); + EXTENDED_ASSERT_TRUE(bf::exists(root_path / "res" / "wgt" / "DELETED")); + EXTENDED_ASSERT_FALSE(bf::exists(root_path / "res" / "wgt" / "ADDED")); + EXTENDED_ASSERT_TRUE(bf::exists(root_path / "lib" / "DELETED")); + EXTENDED_ASSERT_FALSE(bf::exists(root_path / "lib" / "ADDED")); + EXTENDED_ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED", + "version 1\n")); + EXTENDED_ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/MODIFIED", + "version 1\n")); + EXTENDED_ASSERT_TRUE(ValidateDataFiles(pkgid, kTestUserId)); + return true; + }); +} + +TEST_F(SmokeTest, MountInstallationMode_Rollback_Hybrid) { + bf::path path = kSmokePackagesDirectory / + "MountInstallationMode_Rollback_Hybrid.wgt"; + std::string pkgid = "smokehyb09"; + std::string appid1 = "smokehyb09.web"; + const char* argv[] = {"", "-w", path.c_str(), "-u", kTestUserIdStr.c_str()}; + TestRollbackAfterEachStep(SIZEOFARRAY(argv), argv, [=]() -> bool { + ScopedTzipInterface interface(pkgid); + EXTENDED_ASSERT_TRUE(CheckPackageNonExistance(pkgid, {appid1})); + return true; + }, PackageType::HYBRID); +} + +TEST_F(SmokeTest, MountUpdateMode_Rollback_Hybrid) { + bf::path path_old = kSmokePackagesDirectory / + "MountUpdateMode_Rollback_Hybrid.wgt"; + bf::path path_new = kSmokePackagesDirectory / + "MountUpdateMode_Rollback_Hybrid_2.wgt"; + std::string pkgid = "smokehyb10"; + std::string appid1 = "smokehyb10.web"; + ASSERT_EQ(MountInstall(path_old, PackageType::HYBRID), + ci::AppInstaller::Result::OK); + AddDataFiles(pkgid, kTestUserId); + const char* argv[] = + {"", "-w", path_new.c_str(), "-u", kTestUserIdStr.c_str()}; + TestRollbackAfterEachStep(SIZEOFARRAY(argv), argv, [=]() -> bool { + ScopedTzipInterface interface(pkgid); + EXTENDED_ASSERT_TRUE(ValidatePackage(pkgid, {appid1})); + + EXTENDED_ASSERT_TRUE(ValidateFileContentInPackage(pkgid, + "res/wgt/VERSION", "1\n")); + EXTENDED_ASSERT_TRUE(ValidateFileContentInPackage(pkgid, + "lib/VERSION", "1\n")); + EXTENDED_ASSERT_TRUE(ValidateDataFiles(pkgid, kTestUserId)); + return true; + }); +} + +TEST_F(SmokeTest, MountInstallationMode_Rollback) { + bf::path path = + kSmokePackagesDirectory / "MountInstallationMode_Rollback.wgt"; + std::string pkgid = "smokewgt33"; + std::string appid = "smokewgt33.web"; + const char* argv[] = {"", "-w", path.c_str(), "-u", kTestUserIdStr.c_str()}; + TestRollbackAfterEachStep(SIZEOFARRAY(argv), argv, [=]() -> bool { + ScopedTzipInterface interface(pkgid); + EXTENDED_ASSERT_TRUE(CheckPackageNonExistance(pkgid, {appid})); + return true; + }); +} + +TEST_F(SmokeTest, MountUpdateMode_Rollback) { + bf::path path_old = kSmokePackagesDirectory / "MountUpdateMode_Rollback.wgt"; + bf::path path_new = + kSmokePackagesDirectory / "MountUpdateMode_Rollback_2.wgt"; + std::string pkgid = "smokewgt34"; + std::string appid = "smokewgt34.web"; + ASSERT_EQ(MountInstall(path_old, PackageType::WGT), + ci::AppInstaller::Result::OK); + AddDataFiles(pkgid, kTestUserId); + const char* argv[] = + {"", "-w", path_new.c_str(), "-u", kTestUserIdStr.c_str()}; + TestRollbackAfterEachStep(SIZEOFARRAY(argv), argv, [=]() -> bool { + EXTENDED_ASSERT_EQ(MountInstall(path_new, PackageType::WGT, + RequestResult::FAIL), ci::AppInstaller::Result::ERROR); + ScopedTzipInterface interface(pkgid); + EXTENDED_ASSERT_TRUE(ValidatePackage(pkgid, {appid})); + + EXTENDED_ASSERT_TRUE(ValidateFileContentInPackage(pkgid, + "res/wgt/VERSION", "1\n")); + EXTENDED_ASSERT_TRUE(ValidateDataFiles(pkgid, kTestUserId)); + return true; + }); +} + +} // namespace common_installer + +int main(int argc, char** argv) { + ci::RequestMode request_mode = ParseRequestMode(argc, argv); + if (getuid() != 0 || request_mode != ci::RequestMode::GLOBAL) { + std::cout << "Skip tests for preload request" << std::endl; + ::testing::GTEST_FLAG(filter) = "SmokeTest.*"; + } + testing::InitGoogleTest(&argc, argv); + testing::Environment *env = testing::AddGlobalTestEnvironment( + new common_installer::SmokeEnvironment(request_mode)); + return RUN_ALL_TESTS(); +} diff --git a/src/unit_tests/smoke_test.cc b/src/unit_tests/smoke_test.cc index f446f8a..38c2b01 100644 --- a/src/unit_tests/smoke_test.cc +++ b/src/unit_tests/smoke_test.cc @@ -61,7 +61,7 @@ TEST_F(SmokeTest, InstallationMode) { std::string pkgid = "smokewgt03"; std::string appid = "smokewgt03.InstallationMode"; ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK); - ValidatePackage(pkgid, {appid}); + ASSERT_TRUE(ValidatePackage(pkgid, {appid})); } TEST_F(SmokeTest, UpdateMode) { @@ -72,10 +72,10 @@ TEST_F(SmokeTest, UpdateMode) { ASSERT_EQ(Install(path_old, PackageType::WGT), ci::AppInstaller::Result::OK); AddDataFiles(pkgid, kTestUserId); ASSERT_EQ(Install(path_new, PackageType::WGT), ci::AppInstaller::Result::OK); - ValidatePackage(pkgid, {appid}); + ASSERT_TRUE(ValidatePackage(pkgid, {appid})); ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n")); - ValidateDataFiles(pkgid, kTestUserId); + ASSERT_TRUE(ValidateDataFiles(pkgid, kTestUserId)); } TEST_F(SmokeTest, DeinstallationMode) { @@ -86,7 +86,7 @@ TEST_F(SmokeTest, DeinstallationMode) { ci::AppInstaller::Result::OK); ASSERT_EQ(Uninstall(pkgid, PackageType::WGT, false), ci::AppInstaller::Result::OK); - CheckPackageNonExistance(pkgid, {appid}); + ASSERT_TRUE(CheckPackageNonExistance(pkgid, {appid})); } TEST_F(SmokeTest, RDSMode) { @@ -102,7 +102,7 @@ TEST_F(SmokeTest, RDSMode) { ASSERT_TRUE(CopyDir(delta_directory, sdk_expected_directory)); ASSERT_EQ(RDSUpdate(path, pkgid, PackageType::WGT), ci::AppInstaller::Result::OK); - ValidatePackage(pkgid, {appid}); + ASSERT_TRUE(ValidatePackage(pkgid, {appid})); // Check delta modifications ASSERT_FALSE(bf::exists(GetPackageRoot(pkgid, kTestUserId) / @@ -136,7 +136,7 @@ TEST_F(SmokeTest, DisablePkg) { ASSERT_EQ(DisablePackage(pkgid, PackageType::WGT), ci::AppInstaller::Result::OK); ASSERT_TRUE(ci::QueryIsDisabledPackage(pkgid, kTestUserId)); - ValidatePackage(pkgid, {appid}); + ASSERT_TRUE(ValidatePackage(pkgid, {appid})); } TEST_F(SmokeTest, DeltaMode) { @@ -146,7 +146,7 @@ TEST_F(SmokeTest, DeltaMode) { std::string appid = "smokewgt17.DeltaMode"; ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::WGT), ci::AppInstaller::Result::OK); - ValidatePackage(pkgid, {appid}); + ASSERT_TRUE(ValidatePackage(pkgid, {appid})); // Check delta modifications ASSERT_FALSE(bf::exists(GetPackageRoot(pkgid, kTestUserId) / @@ -175,7 +175,7 @@ TEST_F(SmokeTest, RecoveryMode_ForInstallation) { ASSERT_FALSE(recovery_file.empty()); ASSERT_EQ(Recover(recovery_file, PackageType::WGT), ci::AppInstaller::Result::OK); - CheckPackageNonExistance(pkgid, {appid}); + ASSERT_TRUE(CheckPackageNonExistance(pkgid, {appid})); } TEST_F(SmokeTest, RecoveryMode_ForUpdate) { @@ -194,10 +194,10 @@ TEST_F(SmokeTest, RecoveryMode_ForUpdate) { ASSERT_FALSE(recovery_file.empty()); ASSERT_EQ(Recover(recovery_file, PackageType::WGT), ci::AppInstaller::Result::OK); - ValidatePackage(pkgid, {appid}); + ASSERT_TRUE(ValidatePackage(pkgid, {appid})); ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n")); - ValidateDataFiles(pkgid, kTestUserId); + ASSERT_TRUE(ValidateDataFiles(pkgid, kTestUserId)); } TEST_F(SmokeTest, RecoveryMode_ForDelta) { @@ -215,7 +215,7 @@ TEST_F(SmokeTest, RecoveryMode_ForDelta) { ASSERT_FALSE(recovery_file.empty()); ASSERT_EQ(Recover(recovery_file, PackageType::WGT), ci::AppInstaller::Result::OK); - ValidatePackage(pkgid, {appid}); + ASSERT_TRUE(ValidatePackage(pkgid, {appid})); ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n")); } @@ -233,7 +233,7 @@ TEST_F(SmokeTest, RecoveryMode_ForMountInstall) { ASSERT_FALSE(recovery_file.empty()); ASSERT_EQ(Recover(recovery_file, PackageType::WGT), ci::AppInstaller::Result::OK); - CheckPackageNonExistance(pkgid, {appid}); + ASSERT_TRUE(CheckPackageNonExistance(pkgid, {appid})); } TEST_F(SmokeTest, RecoveryMode_ForMountUpdate) { @@ -261,9 +261,9 @@ TEST_F(SmokeTest, RecoveryMode_ForMountUpdate) { ci::AppInstaller::Result::OK); ScopedTzipInterface interface(pkgid); - ValidatePackage(pkgid, {appid}); + ASSERT_TRUE(ValidatePackage(pkgid, {appid})); ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n")); - ValidateDataFiles(pkgid, kTestUserId); + ASSERT_TRUE(ValidateDataFiles(pkgid, kTestUserId)); } TEST_F(SmokeTest, InstallationMode_GoodSignature) { @@ -284,7 +284,7 @@ TEST_F(SmokeTest, InstallationMode_Rollback) { std::string appid = "smokewgt06.InstallationModeRollback"; ASSERT_EQ(Install(path, PackageType::WGT, RequestResult::FAIL), ci::AppInstaller::Result::ERROR); - CheckPackageNonExistance(pkgid, {appid}); + ASSERT_TRUE(CheckPackageNonExistance(pkgid, {appid})); } TEST_F(SmokeTest, UpdateMode_Rollback) { @@ -296,10 +296,10 @@ TEST_F(SmokeTest, UpdateMode_Rollback) { AddDataFiles(pkgid, kTestUserId); ASSERT_EQ(Install(path_new, PackageType::WGT, RequestResult::FAIL), ci::AppInstaller::Result::ERROR); - ValidatePackage(pkgid, {appid}); + ASSERT_TRUE(ValidatePackage(pkgid, {appid})); ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n")); - ValidateDataFiles(pkgid, kTestUserId); + ASSERT_TRUE(ValidateDataFiles(pkgid, kTestUserId)); } TEST_F(SmokeTest, DeltaMode_Rollback) { @@ -312,10 +312,10 @@ TEST_F(SmokeTest, DeltaMode_Rollback) { ASSERT_EQ(Install(delta_package, PackageType::WGT, RequestResult::FAIL), ci::AppInstaller::Result::ERROR); - ValidatePackage(pkgid, {appid}); + ASSERT_TRUE(ValidatePackage(pkgid, {appid})); ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED", "version 1\n")); - ValidateDataFiles(pkgid, kTestUserId); + ASSERT_TRUE(ValidateDataFiles(pkgid, kTestUserId)); ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) / "res/wgt/DELETED")); ASSERT_FALSE(bf::exists(GetPackageRoot(pkgid, kTestUserId) / @@ -328,7 +328,7 @@ TEST_F(SmokeTest, InstallationMode_Hybrid) { // Excutable for native app doesn't create symlink std::string appid1 = "smokehyb01.Web"; ASSERT_EQ(Install(path, PackageType::HYBRID), ci::AppInstaller::Result::OK); - ValidatePackage(pkgid, {appid1}); + ASSERT_TRUE(ValidatePackage(pkgid, {appid1})); } TEST_F(SmokeTest, UpdateMode_Hybrid) { @@ -341,7 +341,7 @@ TEST_F(SmokeTest, UpdateMode_Hybrid) { // AddDataFiles(pkgid, kTestUserId); ASSERT_EQ(Install(path_new, PackageType::HYBRID), ci::AppInstaller::Result::OK); - ValidatePackage(pkgid, {appid1}); + ASSERT_TRUE(ValidatePackage(pkgid, {appid1})); ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n")); ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "VERSION", "2\n")); @@ -356,7 +356,7 @@ TEST_F(SmokeTest, DeinstallationMode_Hybrid) { ci::AppInstaller::Result::OK); ASSERT_EQ(Uninstall(pkgid, PackageType::HYBRID, false), ci::AppInstaller::Result::OK); - CheckPackageNonExistance(pkgid, {appid1}); + ASSERT_TRUE(CheckPackageNonExistance(pkgid, {appid1})); } TEST_F(SmokeTest, DeltaMode_Hybrid) { @@ -366,7 +366,7 @@ TEST_F(SmokeTest, DeltaMode_Hybrid) { std::string appid1 = "smokehyb04.Web"; ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::HYBRID), ci::AppInstaller::Result::OK); - ValidatePackage(pkgid, {appid1}); + ASSERT_TRUE(ValidatePackage(pkgid, {appid1})); // Check delta modifications bf::path root_path = ci::GetRootAppPath(false, @@ -389,7 +389,7 @@ TEST_F(SmokeTest, MountInstallationMode_Hybrid) { ASSERT_EQ(MountInstall(path, PackageType::HYBRID), ci::AppInstaller::Result::OK); ScopedTzipInterface interface(pkgid); - ValidatePackage(pkgid, {appid1}); + ASSERT_TRUE(ValidatePackage(pkgid, {appid1})); } TEST_F(SmokeTest, MountUpdateMode_Hybrid) { @@ -403,11 +403,11 @@ TEST_F(SmokeTest, MountUpdateMode_Hybrid) { ASSERT_EQ(MountInstall(path_new, PackageType::HYBRID), ci::AppInstaller::Result::OK); ScopedTzipInterface interface(pkgid); - ValidatePackage(pkgid, {appid1}); + ASSERT_TRUE(ValidatePackage(pkgid, {appid1})); ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n")); ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/VERSION", "2\n")); - ValidateDataFiles(pkgid, kTestUserId); + ASSERT_TRUE(ValidateDataFiles(pkgid, kTestUserId)); } TEST_F(SmokeTest, InstallationMode_Rollback_Hybrid) { @@ -417,7 +417,7 @@ TEST_F(SmokeTest, InstallationMode_Rollback_Hybrid) { std::string appid1 = "smokehyb07.web"; ASSERT_EQ(Install(path, PackageType::HYBRID, RequestResult::FAIL), ci::AppInstaller::Result::ERROR); - CheckPackageNonExistance(pkgid, {appid1}); + ASSERT_TRUE(CheckPackageNonExistance(pkgid, {appid1})); } TEST_F(SmokeTest, UpdateMode_Rollback_Hybrid) { @@ -432,11 +432,11 @@ TEST_F(SmokeTest, UpdateMode_Rollback_Hybrid) { AddDataFiles(pkgid, kTestUserId); ASSERT_EQ(Install(path_new, PackageType::HYBRID, RequestResult::FAIL), ci::AppInstaller::Result::ERROR); - ValidatePackage(pkgid, {appid1}); + ASSERT_TRUE(ValidatePackage(pkgid, {appid1})); ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n")); ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/VERSION", "1\n")); - ValidateDataFiles(pkgid, kTestUserId); + ASSERT_TRUE(ValidateDataFiles(pkgid, kTestUserId)); } TEST_F(SmokeTest, DeltaMode_Rollback_Hybrid) { @@ -450,7 +450,7 @@ TEST_F(SmokeTest, DeltaMode_Rollback_Hybrid) { ASSERT_EQ(Install(delta_package, PackageType::HYBRID, RequestResult::FAIL), ci::AppInstaller::Result::ERROR); - ValidatePackage(pkgid, {appid1}); + ASSERT_TRUE(ValidatePackage(pkgid, {appid1})); // Check delta modifications bf::path root_path = GetPackageRoot(pkgid, kTestUserId); ASSERT_TRUE(bf::exists(root_path / "res" / "wgt" / "DELETED")); @@ -461,7 +461,7 @@ TEST_F(SmokeTest, DeltaMode_Rollback_Hybrid) { "version 1\n")); ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/MODIFIED", "version 1\n")); - ValidateDataFiles(pkgid, kTestUserId); + ASSERT_TRUE(ValidateDataFiles(pkgid, kTestUserId)); } TEST_F(SmokeTest, MountInstallationMode_Rollback_Hybrid) { @@ -472,7 +472,7 @@ TEST_F(SmokeTest, MountInstallationMode_Rollback_Hybrid) { ASSERT_EQ(MountInstall(path, PackageType::HYBRID, RequestResult::FAIL), ci::AppInstaller::Result::ERROR); ScopedTzipInterface interface(pkgid); - CheckPackageNonExistance(pkgid, {appid1}); + ASSERT_TRUE(CheckPackageNonExistance(pkgid, {appid1})); } TEST_F(SmokeTest, MountUpdateMode_Rollback_Hybrid) { @@ -488,11 +488,11 @@ TEST_F(SmokeTest, MountUpdateMode_Rollback_Hybrid) { ASSERT_EQ(MountInstall(path_new, PackageType::HYBRID, RequestResult::FAIL), ci::AppInstaller::Result::ERROR); ScopedTzipInterface interface(pkgid); - ValidatePackage(pkgid, {appid1}); + ASSERT_TRUE(ValidatePackage(pkgid, {appid1})); ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n")); ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/VERSION", "1\n")); - ValidateDataFiles(pkgid, kTestUserId); + ASSERT_TRUE(ValidateDataFiles(pkgid, kTestUserId)); } TEST_F(SmokeTest, MountInstallationMode) { @@ -501,7 +501,7 @@ TEST_F(SmokeTest, MountInstallationMode) { std::string appid = "smokewgt28.InstallationMode"; ASSERT_EQ(MountInstall(path, PackageType::WGT), ci::AppInstaller::Result::OK); ScopedTzipInterface interface(pkgid); - ValidatePackage(pkgid, {appid}); + ASSERT_TRUE(ValidatePackage(pkgid, {appid})); } TEST_F(SmokeTest, MountUpdateMode) { @@ -515,10 +515,10 @@ TEST_F(SmokeTest, MountUpdateMode) { ASSERT_EQ(MountInstall(path_new, PackageType::WGT), ci::AppInstaller::Result::OK); ScopedTzipInterface interface(pkgid); - ValidatePackage(pkgid, {appid}); + ASSERT_TRUE(ValidatePackage(pkgid, {appid})); ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n")); - ValidateDataFiles(pkgid, kTestUserId); + ASSERT_TRUE(ValidateDataFiles(pkgid, kTestUserId)); } TEST_F(SmokeTest, MountInstallationMode_Rollback) { @@ -529,7 +529,7 @@ TEST_F(SmokeTest, MountInstallationMode_Rollback) { ASSERT_EQ(MountInstall(path, PackageType::WGT, RequestResult::FAIL), ci::AppInstaller::Result::ERROR); ScopedTzipInterface interface(pkgid); - CheckPackageNonExistance(pkgid, {appid}); + ASSERT_TRUE(CheckPackageNonExistance(pkgid, {appid})); } TEST_F(SmokeTest, MountUpdateMode_Rollback) { @@ -544,10 +544,10 @@ TEST_F(SmokeTest, MountUpdateMode_Rollback) { ASSERT_EQ(MountInstall(path_new, PackageType::WGT, RequestResult::FAIL), ci::AppInstaller::Result::ERROR); ScopedTzipInterface interface(pkgid); - ValidatePackage(pkgid, {appid}); + ASSERT_TRUE(ValidatePackage(pkgid, {appid})); ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n")); - ValidateDataFiles(pkgid, kTestUserId); + ASSERT_TRUE(ValidateDataFiles(pkgid, kTestUserId)); } TEST_F(SmokeTest, UserDefinedPlugins) { @@ -559,7 +559,7 @@ TEST_F(SmokeTest, UserDefinedPlugins) { std::string power_privilege = "http://tizen.org/privilege/power"; ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK); - ValidatePackage(pkgid, {appid}); + ASSERT_TRUE(ValidatePackage(pkgid, {appid})); std::vector res; ASSERT_TRUE(ci::QueryPrivilegesForPkgId(pkgid, kTestUserId, &res)); ASSERT_TRUE(std::find(res.begin(), res.end(), call_privilege) != res.end()); @@ -597,7 +597,7 @@ TEST_F(PreloadSmokeTest, InstallationMode_Preload) { std::string appid = "smokewgt37.InstallationModePreload"; ASSERT_EQ(InstallPreload(path, PackageType::WGT), ci::AppInstaller::Result::OK); - ValidatePackage(pkgid, {appid}, true); + ASSERT_TRUE(ValidatePackage(pkgid, {appid}, true)); } TEST_F(PreloadSmokeTest, UpdateMode_Preload) { @@ -611,11 +611,11 @@ TEST_F(PreloadSmokeTest, UpdateMode_Preload) { AddDataFiles(pkgid, kTestUserId); ASSERT_EQ(InstallPreload(path_new, PackageType::WGT), ci::AppInstaller::Result::OK); - ValidatePackage(pkgid, {appid}, true); + ASSERT_TRUE(ValidatePackage(pkgid, {appid}, true)); ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2", true)); - ValidateDataFiles(pkgid, kTestUserId); + ASSERT_TRUE(ValidateDataFiles(pkgid, kTestUserId)); } TEST_F(PreloadSmokeTest, DeinstallationMode_Preload) { @@ -646,7 +646,7 @@ TEST_F(SmokeTest, SharedRes30) { std::string pkgid = "smokeSh3xx"; std::string appid = "smokeSh3xx.SharedRes30"; ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK); - ValidatePackage(pkgid, {appid}); + ASSERT_TRUE(ValidatePackage(pkgid, {appid})); bf::path root_path = ci::GetRootAppPath(false, kTestUserId); ASSERT_TRUE(bf::is_regular_file(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-WGT")); // NOLINT ASSERT_TRUE(bf::is_symlink(root_path / pkgid / "shared" / "res" / "SHARED-WGT")); // NOLINT @@ -659,7 +659,7 @@ TEST_F(SmokeTest, SharedRes30Delta) { std::string appid = "smokeSh3De.SharedRes30Delta"; ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::WGT), ci::AppInstaller::Result::OK); - ValidatePackage(pkgid, {appid}); + ASSERT_TRUE(ValidatePackage(pkgid, {appid})); // Check delta modifications bf::path root_path = ci::GetRootAppPath(false, kTestUserId); ASSERT_TRUE(bf::is_regular_file(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-WGT-2")); // NOLINT @@ -674,7 +674,7 @@ TEST_F(SmokeTest, SharedRes30Hybrid) { std::string appid1 = "smokeSh3Hy.SharedRes30Hybrid"; std::string appid2 = "sharedres30hybridserivce"; ASSERT_EQ(Install(path, PackageType::HYBRID), ci::AppInstaller::Result::OK); - ValidatePackage(pkgid, {appid1, appid2}); + ASSERT_TRUE(ValidatePackage(pkgid, {appid1, appid2})); bf::path root_path = ci::GetRootAppPath(false, kTestUserId); ASSERT_TRUE(bf::is_regular_file(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-WGT")); // NOLINT ASSERT_TRUE(bf::is_symlink(root_path / pkgid / "shared" / "res" / "SHARED-WGT")); // NOLINT @@ -691,7 +691,7 @@ TEST_F(SmokeTest, SharedRes30HybridDelta) { std::string appid2 = "sharedres30hybriddeltaserivce"; ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::HYBRID), ci::AppInstaller::Result::OK); - ValidatePackage(pkgid, {appid1, appid2}); + ASSERT_TRUE(ValidatePackage(pkgid, {appid1, appid2})); // Check delta modifications bf::path root_path = ci::GetRootAppPath(false, kTestUserId); ASSERT_TRUE(bf::is_regular_file(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-WGT-2")); // NOLINT diff --git a/src/unit_tests/smoke_test_helper.cc b/src/unit_tests/smoke_test_helper.cc index 0d37d1c..4501e89 100644 --- a/src/unit_tests/smoke_test_helper.cc +++ b/src/unit_tests/smoke_test_helper.cc @@ -31,6 +31,14 @@ class StepCrash : public ci::Step { // this main of test binay in done purely for recovery smoke test. int main(int argc, char** argv) { + int index = -1; + int backend_argc = argc; + if (!strcmp(argv[argc-2], "-idx")) { + index = atoi(argv[argc-1]); + backend_argc = argc - 2; + LOG(DEBUG) << "Step crash after " << index << " step."; + } + ci::PkgmgrInstaller pkgmgr_installer; wgt::WgtAppQueryInterface query_interface; auto pkgmgr = ci::PkgMgrInterface::Create(argc, argv, &pkgmgr_installer, @@ -41,7 +49,11 @@ int main(int argc, char** argv) { } wgt::WgtInstaller installer(pkgmgr); - installer.AddStep(); + if (index != -1) { + installer.AddStepAtIndex(index); + } else { + installer.AddStep(); + } return (installer.Run() == ci::AppInstaller::Result::OK) ? 0 : 1; } diff --git a/src/unit_tests/smoke_utils.cc b/src/unit_tests/smoke_utils.cc index c1750f1..fff20f4 100644 --- a/src/unit_tests/smoke_utils.cc +++ b/src/unit_tests/smoke_utils.cc @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -249,82 +250,83 @@ void AddDataFiles(const std::string& pkgid, uid_t uid) { } } -void ValidateDataFiles(const std::string& pkgid, uid_t uid) { +bool ValidateDataFiles(const std::string& pkgid, uid_t uid) { if (uid == kGlobalUserUid) { ci::UserList list = ci::GetUserList(); for (auto l : list) { auto pkg_path = GetPackageRoot(pkgid, std::get<0>(l)); - ASSERT_TRUE(bf::exists(pkg_path / "data" / "file1.txt")); - ASSERT_TRUE(bf::exists(pkg_path / "data" / "file2.txt")); + EXTENDED_ASSERT_TRUE(bf::exists(pkg_path / "data" / "file1.txt")); + EXTENDED_ASSERT_TRUE(bf::exists(pkg_path / "data" / "file2.txt")); } } else { auto pkg_path = GetPackageRoot(pkgid, uid); - ASSERT_TRUE(bf::exists(pkg_path / "data" / "file1.txt")); - ASSERT_TRUE(bf::exists(pkg_path / "data" / "file2.txt")); + EXTENDED_ASSERT_TRUE(bf::exists(pkg_path / "data" / "file1.txt")); + EXTENDED_ASSERT_TRUE(bf::exists(pkg_path / "data" / "file2.txt")); } + return true; } -void ValidatePackageRWFS(const std::string& pkgid, uid_t uid) { +bool 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 / rwDirectories[DATA]; bf::path cache_path = package_path / rwDirectories[CACHE]; bf::path shared_data_path = package_path / rwDirectories[SHARED_DATA]; - ASSERT_TRUE(bf::exists(data_path)); - ASSERT_TRUE(bf::exists(cache_path)); + EXTENDED_ASSERT_TRUE(bf::exists(data_path)); + EXTENDED_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; + EXTENDED_ASSERT_EQ(uid, stats.st_uid); + EXTENDED_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) << "Invalid gid: " << shared_data_path; - ASSERT_EQ(*system_share, stats.st_gid) << "Invalid gid: " - << shared_data_path; + EXTENDED_ASSERT_EQ(uid, stats.st_uid); + EXTENDED_ASSERT_EQ(*system_share, stats.st_gid); } 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; + EXTENDED_ASSERT_EQ(uid, stats.st_uid); + EXTENDED_ASSERT_EQ(*system_share, stats.st_gid); + return true; } -void ValidatePackageFS(const std::string& pkgid, +bool ValidatePackageFS(const std::string& pkgid, const std::vector& appids, 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)); + EXTENDED_ASSERT_TRUE(bf::exists(root_path)); + EXTENDED_ASSERT_TRUE(bf::exists(package_path)); + EXTENDED_ASSERT_TRUE(bf::exists(shared_path)); bf::path manifest_path = bf::path(getUserManifestPath(uid, is_readonly)) / (pkgid + ".xml"); - ASSERT_TRUE(bf::exists(manifest_path)); + EXTENDED_ASSERT_TRUE(bf::exists(manifest_path)); for (auto& appid : appids) { bf::path binary_path = package_path / "bin" / appid; - ASSERT_TRUE(bf::exists(binary_path)); + EXTENDED_ASSERT_TRUE(bf::exists(binary_path)); } bf::path widget_root_path = package_path / "res" / "wgt"; bf::path config_path = widget_root_path / "config.xml"; - ASSERT_TRUE(bf::exists(widget_root_path)); - ASSERT_TRUE(bf::exists(config_path)); + EXTENDED_ASSERT_TRUE(bf::exists(widget_root_path)); + EXTENDED_ASSERT_TRUE(bf::exists(config_path)); bf::path private_tmp_path = package_path / "tmp"; - ASSERT_TRUE(bf::exists(private_tmp_path)); + EXTENDED_ASSERT_TRUE(bf::exists(private_tmp_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)); + EXTENDED_ASSERT_FALSE(bf::exists(package_backup)); + EXTENDED_ASSERT_FALSE(bf::exists(manifest_backup)); for (bf::recursive_directory_iterator iter(package_path); iter != bf::recursive_directory_iterator(); ++iter) { @@ -342,9 +344,10 @@ void ValidatePackageFS(const std::string& pkgid, } 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(); + EXTENDED_ASSERT_EQ(uid, stats.st_uid); + EXTENDED_ASSERT_EQ(gid, stats.st_gid); } + return true; } void PackageCheckCleanup(const std::string& pkgid, @@ -364,18 +367,20 @@ void PackageCheckCleanup(const std::string& pkgid, ASSERT_FALSE(bf::exists(manifest_backup)); } -void ValidatePackage(const std::string& pkgid, +bool ValidatePackage(const std::string& pkgid, const std::vector& appids, bool is_readonly) { - ASSERT_TRUE(ci::QueryIsPackageInstalled( + EXTENDED_ASSERT_TRUE(ci::QueryIsPackageInstalled( pkgid, ci::GetRequestMode(kTestUserId), kTestUserId)); - ValidatePackageFS(pkgid, appids, kTestUserId, kTestGroupId, is_readonly); + EXTENDED_ASSERT_TRUE(ValidatePackageFS( + pkgid, appids, kTestUserId, kTestGroupId, is_readonly)); if (kTestUserId == kGlobalUserUid) { ci::UserList list = ci::GetUserList(); for (auto& l : list) - ValidatePackageRWFS(pkgid, std::get<0>(l)); + EXTENDED_ASSERT_TRUE(ValidatePackageRWFS(pkgid, std::get<0>(l))); } else { - ValidatePackageRWFS(pkgid, kTestUserId); + EXTENDED_ASSERT_TRUE(ValidatePackageRWFS(pkgid, kTestUserId)); } + return true; } void ValidateExternalPackageFS(const std::string& pkgid, @@ -411,22 +416,23 @@ void ValidateExternalPackage(const std::string& pkgid, } } -void CheckPackageNonExistance(const std::string& pkgid, +bool CheckPackageNonExistance(const std::string& pkgid, const std::vector& appids) { - ASSERT_FALSE(ci::QueryIsPackageInstalled( + EXTENDED_ASSERT_FALSE(ci::QueryIsPackageInstalled( pkgid, ci::GetRequestMode(kTestUserId), kTestUserId)); PackageCheckCleanup(pkgid, appids); if (kTestUserId == kGlobalUserUid) { ci::UserList list = ci::GetUserList(); bf::path skel_path(kSkelDir); - ASSERT_FALSE(bf::exists(skel_path / pkgid)); + EXTENDED_ASSERT_FALSE(bf::exists(skel_path / pkgid)); 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)); + EXTENDED_ASSERT_FALSE(bf::exists(package_path)); } } + return true; } void CheckPackageReadonlyNonExistance(const std::string& pkgid, @@ -456,6 +462,68 @@ std::unique_ptr CreateInstaller(ci::PkgMgrPtr pkgmgr, } } +void TestRollbackAfterEachStep(int argc, const char*argv[], + std::function validator, + PackageType type) { + 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; + } + std::unique_ptr backend = CreateInstaller(pkgmgr, type); + int i; + for (i = backend->StepCount()-1; i >= 0; i--) { + backend->AddStepAtIndex(i); + LOG(DEBUG) << "StepFail is inserted at: " << i; + ASSERT_EQ(ci::AppInstaller::Result::ERROR, + backend->Run()); + if (!validator()) + break; + } + ASSERT_EQ(-1, i); +} + +void CrashAfterEachStep(std::vector args, + std::function validator, + PackageType type) { + std::unique_ptr argv(new const char*[args.size()]); + for (size_t i = 0; i < args.size(); ++i) { + argv[i] = args[i].c_str(); + } + TestPkgmgrInstaller pkgmgr_installer; + std::unique_ptr query_interface = + CreateQueryInterface(); + auto pkgmgr = + ci::PkgMgrInterface::Create(args.size(), const_cast(argv.get()), + &pkgmgr_installer, + query_interface.get()); + if (!pkgmgr) { + LOG(ERROR) << "Failed to initialize pkgmgr interface"; + return; + } + std::unique_ptr backend = CreateInstaller(pkgmgr, type); + int stepCount = backend->StepCount(); + + args.push_back("-idx"); + args.push_back(std::to_string(stepCount)); + int i; + for (i = 0; i < stepCount; i++) { + ci::Subprocess backend_crash("/usr/bin/tpk-backend-ut/smoke-test-helper"); + args.back() = std::to_string(i); + backend_crash.Run(args); + ASSERT_NE(backend_crash.Wait(), 0); + if (!validator(i)) + break; + } + ASSERT_EQ(stepCount, i); +} + ci::AppInstaller::Result RunInstallerWithPkgrmgr(ci::PkgMgrPtr pkgmgr, PackageType type, RequestResult mode) { diff --git a/src/unit_tests/smoke_utils.h b/src/unit_tests/smoke_utils.h index efc2551..d0a4b47 100644 --- a/src/unit_tests/smoke_utils.h +++ b/src/unit_tests/smoke_utils.h @@ -5,6 +5,7 @@ #ifndef UNIT_TESTS_SMOKE_UTILS_H_ #define UNIT_TESTS_SMOKE_UTILS_H_ + #include #include @@ -25,6 +26,27 @@ #define SIZEOFARRAY(ARR) \ sizeof(ARR) / sizeof(ARR[0]) \ +#define EXTENDED_ASSERT_TRUE(expression) do { \ + bool tmp = expression; \ + EXPECT_TRUE(tmp) << #expression << " is not true"; \ + if (!tmp) \ + return false; \ +} while (0); + +#define EXTENDED_ASSERT_FALSE(expression) do { \ + bool tmp = expression; \ + EXPECT_FALSE(tmp) << #expression << " is not false"; \ + if (tmp) \ + return false; \ +} while (0); + +#define EXTENDED_ASSERT_EQ(expression, value) do { \ + auto ret = expression; \ + EXPECT_EQ(ret, value) << #expression << " is not equal to " << #value; \ + if (ret != value) \ + return false; \ +} while (0); + namespace bf = boost::filesystem; namespace bs = boost::system; namespace ci = common_installer; @@ -140,18 +162,18 @@ bool ValidateFileContentInPackage(const std::string& pkgid, void AddDataFiles(const std::string& pkgid, uid_t uid); -void ValidateDataFiles(const std::string& pkgid, uid_t uid); +bool ValidateDataFiles(const std::string& pkgid, uid_t uid); -void ValidatePackageRWFS(const std::string& pkgid, uid_t uid); +bool ValidatePackageRWFS(const std::string& pkgid, uid_t uid); -void ValidatePackageFS(const std::string& pkgid, +bool ValidatePackageFS(const std::string& pkgid, const std::vector& appids, uid_t uid, gid_t gid, bool is_readonly); void PackageCheckCleanup(const std::string& pkgid, const std::vector&, bool is_readonly = false); -void ValidatePackage(const std::string& pkgid, +bool ValidatePackage(const std::string& pkgid, const std::vector& appids, bool is_readonly = false); void ValidateExternalPackageFS(const std::string& pkgid, @@ -161,7 +183,7 @@ void ValidateExternalPackageFS(const std::string& pkgid, void ValidateExternalPackage(const std::string& pkgid, const std::vector& appids); -void CheckPackageNonExistance(const std::string& pkgid, +bool CheckPackageNonExistance(const std::string& pkgid, const std::vector& appids); void CheckPackageReadonlyNonExistance(const std::string& pkgid, @@ -172,6 +194,14 @@ std::unique_ptr CreateQueryInterface(); std::unique_ptr CreateInstaller(ci::PkgMgrPtr pkgmgr, PackageType type); +void TestRollbackAfterEachStep(int argc, const char*argv[], + std::function validator, + PackageType type = PackageType::WGT); + +void CrashAfterEachStep(std::vector args, + std::function validator, + PackageType type = PackageType::WGT); + ci::AppInstaller::Result RunInstallerWithPkgrmgr(ci::PkgMgrPtr pkgmgr, PackageType type, RequestResult mode); -- 2.7.4 From 390d91ff1033a94414b93d054cff94393962c30b Mon Sep 17 00:00:00 2001 From: Damian Pietruchowski Date: Thu, 23 Mar 2017 15:11:17 +0100 Subject: [PATCH 09/16] [SmokeTest] Fixes for ParseRequestMode() function - Allow to parse unknown options. - Return global request mode for unknown options. Change-Id: I2f2c71820a6f5e8552842f4c3ee0378617176aa8 Signed-off-by: Damian Pietruchowski --- src/unit_tests/smoke_utils.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/unit_tests/smoke_utils.cc b/src/unit_tests/smoke_utils.cc index fff20f4..c88f3fa 100644 --- a/src/unit_tests/smoke_utils.cc +++ b/src/unit_tests/smoke_utils.cc @@ -84,7 +84,8 @@ ci::RequestMode ParseRequestMode(int argc, char** argv) { ("user-request,u", "set request mode to user"); bo::variables_map vm; - bo::store(bo::parse_command_line(argc, argv, desc), vm); + bo::store(bo::command_line_parser(argc, argv). + options(desc).allow_unregistered().run(), vm); bo::notify(vm); if (vm.count("global-request")) { @@ -106,9 +107,9 @@ ci::RequestMode ParseRequestMode(int argc, char** argv) { } std::cout << "Cannot set request mode to " << vm["request-mode"].as() << std::endl; - std::cout << "Request mode was set to global." << std::endl; - return ci::RequestMode::GLOBAL; } + std::cout << "Request mode was set to global." << std::endl; + return ci::RequestMode::GLOBAL; } bool TouchFile(const bf::path& path) { -- 2.7.4 From 8e4ad744154151aee46f6fdbc39077bf6a483c3a Mon Sep 17 00:00:00 2001 From: Damian Pietruchowski Date: Mon, 27 Mar 2017 14:21:35 +0200 Subject: [PATCH 10/16] [SmokeTest] Fix for recovery smoke tests Change-Id: I464fd123c34ddd4dac14a319e586a6e1c45c4dea Signed-off-by: Damian Pietruchowski --- src/unit_tests/smoke_test_helper.cc | 2 +- src/unit_tests/smoke_utils.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/unit_tests/smoke_test_helper.cc b/src/unit_tests/smoke_test_helper.cc index 4501e89..156b64b 100644 --- a/src/unit_tests/smoke_test_helper.cc +++ b/src/unit_tests/smoke_test_helper.cc @@ -41,7 +41,7 @@ int main(int argc, char** argv) { ci::PkgmgrInstaller pkgmgr_installer; wgt::WgtAppQueryInterface query_interface; - auto pkgmgr = ci::PkgMgrInterface::Create(argc, argv, &pkgmgr_installer, + auto pkgmgr = ci::PkgMgrInterface::Create(backend_argc, argv, &pkgmgr_installer, &query_interface); if (!pkgmgr) { LOG(ERROR) << "Options of pkgmgr installer cannot be parsed"; diff --git a/src/unit_tests/smoke_utils.cc b/src/unit_tests/smoke_utils.cc index c88f3fa..24f92b3 100644 --- a/src/unit_tests/smoke_utils.cc +++ b/src/unit_tests/smoke_utils.cc @@ -515,7 +515,7 @@ void CrashAfterEachStep(std::vector args, args.push_back(std::to_string(stepCount)); int i; for (i = 0; i < stepCount; i++) { - ci::Subprocess backend_crash("/usr/bin/tpk-backend-ut/smoke-test-helper"); + ci::Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper"); args.back() = std::to_string(i); backend_crash.Run(args); ASSERT_NE(backend_crash.Wait(), 0); -- 2.7.4 From 36493ef3231a513608a91d768345f40618301d47 Mon Sep 17 00:00:00 2001 From: Damian Pietruchowski Date: Thu, 6 Apr 2017 16:13:09 +0200 Subject: [PATCH 11/16] [SmokeTest] Add SIGINT and SIGSEGV handling Change-Id: I497435a6d89a7df26bbfe19e4fd308be2dd9b55d Signed-off-by: Damian Pietruchowski --- src/unit_tests/extensive_smoke_test.cc | 4 +++- src/unit_tests/smoke_test.cc | 6 +++--- src/unit_tests/smoke_utils.cc | 6 ++++++ src/unit_tests/smoke_utils.h | 5 +++++ 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/unit_tests/extensive_smoke_test.cc b/src/unit_tests/extensive_smoke_test.cc index 58f11f6..043c293 100644 --- a/src/unit_tests/extensive_smoke_test.cc +++ b/src/unit_tests/extensive_smoke_test.cc @@ -382,7 +382,9 @@ int main(int argc, char** argv) { ::testing::GTEST_FLAG(filter) = "SmokeTest.*"; } testing::InitGoogleTest(&argc, argv); - testing::Environment *env = testing::AddGlobalTestEnvironment( + env = testing::AddGlobalTestEnvironment( new common_installer::SmokeEnvironment(request_mode)); + signal(SIGINT, signalHandler); + signal(SIGSEGV, signalHandler); return RUN_ALL_TESTS(); } diff --git a/src/unit_tests/smoke_test.cc b/src/unit_tests/smoke_test.cc index 38c2b01..9b90c2a 100644 --- a/src/unit_tests/smoke_test.cc +++ b/src/unit_tests/smoke_test.cc @@ -3,10 +3,8 @@ // found in the LICENSE file. #include - #include -#include #include #include "unit_tests/smoke_utils.h" @@ -711,7 +709,9 @@ int main(int argc, char** argv) { ::testing::GTEST_FLAG(filter) = "SmokeTest.*"; } testing::InitGoogleTest(&argc, argv); - testing::Environment *env = testing::AddGlobalTestEnvironment( + env = testing::AddGlobalTestEnvironment( new common_installer::SmokeEnvironment(request_mode)); + signal(SIGINT, signalHandler); + signal(SIGSEGV, signalHandler); return RUN_ALL_TESTS(); } diff --git a/src/unit_tests/smoke_utils.cc b/src/unit_tests/smoke_utils.cc index 24f92b3..2ef8402 100644 --- a/src/unit_tests/smoke_utils.cc +++ b/src/unit_tests/smoke_utils.cc @@ -75,6 +75,11 @@ const char kPreloadApps[] = "/usr/apps"; const char kPreloadManifestDir[] = "/usr/share/packages"; const char kPreloadIcons[] = "/usr/share/icons"; +testing::Environment *env = nullptr; +void signalHandler(int signum) { + env->TearDown(); + exit(signum); +} ci::RequestMode ParseRequestMode(int argc, char** argv) { bo::options_description desc("Available options"); @@ -817,6 +822,7 @@ void UninstallAllAppsInDirectory(bf::path dir, bool is_preload) { } void UninstallAllSmokeApps(ci::RequestMode request_mode) { + std::cout << "Uninstalling all smoke apps" << std::endl; if (getuid() == 0 && request_mode == ci::RequestMode::GLOBAL) { bf::path root_path = kPreloadApps; UninstallAllAppsInDirectory(root_path, true); diff --git a/src/unit_tests/smoke_utils.h b/src/unit_tests/smoke_utils.h index d0a4b47..448b71f 100644 --- a/src/unit_tests/smoke_utils.h +++ b/src/unit_tests/smoke_utils.h @@ -16,6 +16,8 @@ #include #include +#include + #include #include #include @@ -84,6 +86,9 @@ extern const char kPreloadApps[]; extern const char kPreloadManifestDir[]; extern const char kPreloadIcons[]; +extern testing::Environment *env; +void signalHandler(int signum); + enum class RequestResult { NORMAL, FAIL -- 2.7.4 From 1ce595996ed65c28b72fd41d1ed220fd92bd7ad9 Mon Sep 17 00:00:00 2001 From: jongmyeongko Date: Sat, 8 Apr 2017 15:51:26 +0900 Subject: [PATCH 12/16] Fix Mount Installation Failure Requires : https://review.tizen.org/gerrit/#/c/123947/ Change-Id: Icd0342eab4266467288d06cbe88f573e1a16ee63 Signed-off-by: jongmyeongko (cherry picked from commit 77476e84f50dd9b72a7e1cf2341c50dedd4d10cc) --- src/hybrid/hybrid_installer.cc | 4 ++-- src/wgt/wgt_installer.cc | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hybrid/hybrid_installer.cc b/src/hybrid/hybrid_installer.cc index 9c83f0b..ba50202 100644 --- a/src/hybrid/hybrid_installer.cc +++ b/src/hybrid/hybrid_installer.cc @@ -350,7 +350,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) ci::Plugin::ActionType::Install); AddStep( wgt::filesystem::HybridAdditionalSharedDirs); - AddStep(); + AddStep(true); AddStep(); break; case ci::RequestType::MountUpdate: @@ -399,7 +399,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); - AddStep(); + AddStep(true); AddStep(); break; case ci::RequestType::ManifestDirectInstall: diff --git a/src/wgt/wgt_installer.cc b/src/wgt/wgt_installer.cc index ee1f9b3..475c05e 100755 --- a/src/wgt/wgt_installer.cc +++ b/src/wgt/wgt_installer.cc @@ -434,7 +434,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) ci::Plugin::ActionType::Install); AddStep( wgt::filesystem::WgtAdditionalSharedDirs); - AddStep(); + AddStep(true); AddStep(); } @@ -475,7 +475,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); - AddStep(); + AddStep(true); AddStep(); } -- 2.7.4 From 330a232445b9db00f63f3975a1338e7116bd570c Mon Sep 17 00:00:00 2001 From: Damian Pietruchowski Date: Fri, 7 Apr 2017 13:02:40 +0200 Subject: [PATCH 13/16] [SmokeTest] Fix restore backup When something goes wrong (for example unmount failed) then backup is not restored. After that fix, directory, which could not be removed, will be renamed to path with "trash" extension. User have to remove this directory manually.. Change-Id: Ie616f27f1bccbe2d5efbc31316f7b99cf6fec87b Signed-off-by: Damian Pietruchowski --- src/unit_tests/smoke_test.cc | 4 ++-- src/unit_tests/smoke_utils.cc | 42 +++++++++++++++++++++++++++++++++++------- src/unit_tests/smoke_utils.h | 4 ++-- 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/src/unit_tests/smoke_test.cc b/src/unit_tests/smoke_test.cc index 9b90c2a..35bdfbc 100644 --- a/src/unit_tests/smoke_test.cc +++ b/src/unit_tests/smoke_test.cc @@ -27,7 +27,7 @@ class SmokeEnvironment : public testing::Environment { } backups_ = SetupBackupDirectories(); for (auto& path : backups_) - BackupPath(path); + ASSERT_TRUE(BackupPath(path)); } void TearDown() override { ASSERT_TRUE(request_mode_ == ci::RequestMode::GLOBAL || @@ -35,7 +35,7 @@ class SmokeEnvironment : public testing::Environment { kGlobalUserUid != kTestUserId)); UninstallAllSmokeApps(request_mode_); for (auto& path : backups_) - RestorePath(path); + ASSERT_TRUE(RestorePath(path)); if (request_mode_ == ci::RequestMode::USER) ASSERT_TRUE(DeleteTestUser(kNormalUserName)); } diff --git a/src/unit_tests/smoke_utils.cc b/src/unit_tests/smoke_utils.cc index 2ef8402..ec50e82 100644 --- a/src/unit_tests/smoke_utils.cc +++ b/src/unit_tests/smoke_utils.cc @@ -729,7 +729,21 @@ ci::AppInstaller::Result Recover(const bf::path& recovery_file, return CallBackend(SIZEOFARRAY(argv), argv, type, mode); } -void BackupPath(const bf::path& path) { +namespace { + +boost::filesystem::path GetTrashPath(const boost::filesystem::path& path) { + return path.string() + ".trash"; +} + +} + +bool BackupPath(const bf::path& path) { + bf::path trash_path = GetTrashPath(path); + if (bf::exists(trash_path)) { + LOG(ERROR) << trash_path << " exists. Please remove " + << trash_path << " manually!"; + return false; + } bf::path backup_path = path.string() + ".bck"; std::cout << "Backup path: " << path << " to " << backup_path << std::endl; bs::error_code error; @@ -739,28 +753,42 @@ void BackupPath(const bf::path& path) { << " (" << error.message() << ")"; if (bf::exists(path)) { bf::rename(path, backup_path, error); - if (error) + if (error) { LOG(ERROR) << "Failed to setup test environment. Does some previous" << " test crashed? Path: " << backup_path << " should not exist."; + return false; + } assert(!error); } + return true; } -void RestorePath(const bf::path& path) { +bool 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 (error) { + bf::path trash_path = GetTrashPath(path); + LOG(ERROR) << "Remove failed: " << path << " (" << error.message() << ")"; + std::cout << "Moving " << path << " to " << trash_path << std::endl; + bf::rename(path, trash_path, error); + if (error) + LOG(ERROR) << "Failed to move " << path << " to " << trash_path + << " (" << error.message() << ")"; + else + LOG(ERROR) << trash_path << " should be removed manually!"; + } if (bf::exists(backup_path)) { bf::rename(backup_path, path, error); - if (error) + if (error) { LOG(ERROR) << "Failed to restore backup path: " << backup_path << " (" << error.message() << ")"; + return false; + } } + return true; } std::vector SetupBackupDirectories() { diff --git a/src/unit_tests/smoke_utils.h b/src/unit_tests/smoke_utils.h index 448b71f..808e19b 100644 --- a/src/unit_tests/smoke_utils.h +++ b/src/unit_tests/smoke_utils.h @@ -263,9 +263,9 @@ ci::AppInstaller::Result Recover(const bf::path& recovery_file, PackageType type, RequestResult mode = RequestResult::NORMAL); -void BackupPath(const bf::path& path); +bool BackupPath(const bf::path& path); -void RestorePath(const bf::path& path); +bool RestorePath(const bf::path& path); std::vector SetupBackupDirectories(); -- 2.7.4 From 88fc2091153fda400934a7056617b8bc16e12383 Mon Sep 17 00:00:00 2001 From: jongmyeongko Date: Wed, 19 Apr 2017 18:15:56 +0900 Subject: [PATCH 14/16] Fix crash issue when getting the locale was failed Change-Id: Id4c860204b942a636bbd6f01b00ae99551cbddc7 Signed-off-by: jongmyeongko --- src/lib/wgt_archive_info.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lib/wgt_archive_info.cc b/src/lib/wgt_archive_info.cc index 5e95b1f..eb508e1 100644 --- a/src/lib/wgt_archive_info.cc +++ b/src/lib/wgt_archive_info.cc @@ -28,7 +28,7 @@ namespace ci = common_installer; namespace { -const char kVconfLanguageKey[] = "db/menu_widget/language"; +const char kVconfLanguageKey[] = VCONFKEY_LANGSET; const char kConfigFileName[] = "config.xml"; const char kHybridConfigFileName[] = "res/wgt/config.xml"; @@ -226,6 +226,8 @@ bool WgtArchiveInfo::GetArchiveInfo(const char* file_path, } char* locale = vconf_get_str(kVconfLanguageKey); + if (!locale) + locale = strdup(""); if (!GetLabelInfo(parser, locale, info)) LOG(WARNING) << "Failed to get label info"; if (!GetDescriptionInfo(parser, locale, info)) -- 2.7.4 From c2fd87783a4f43f8e11f0bfb5f5144b737cb0e55 Mon Sep 17 00:00:00 2001 From: Sangyoon Jang Date: Wed, 24 May 2017 14:38:17 +0900 Subject: [PATCH 15/16] Fix crash when parsing icon info from wgt archive Change-Id: Ifa4866a495af0764be72eb4e5d68d016642b931f Signed-off-by: Sangyoon Jang --- src/lib/wgt_archive_info.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/wgt_archive_info.cc b/src/lib/wgt_archive_info.cc index eb508e1..205ba5f 100644 --- a/src/lib/wgt_archive_info.cc +++ b/src/lib/wgt_archive_info.cc @@ -164,7 +164,7 @@ std::string GetIconInfo(const wgt::parse::WidgetConfigParser& parser) { auto icons_info = std::static_pointer_cast( parser.GetManifestData(wgt::parse::ApplicationIconsInfo::Key())); - if (!icons_info) + if (!icons_info || icons_info->icons().empty()) return {}; return std::string(icons_info->icons().front().path()); -- 2.7.4 From fef5e9e1ee8396fb3413d4cc2523c202dfe61f43 Mon Sep 17 00:00:00 2001 From: Junghyun Yeon Date: Mon, 22 May 2017 10:43:28 +0900 Subject: [PATCH 16/16] Add update step of directories - shared/data directory of package should be created/removed when updating hybrid pkg Change-Id: Ib3f7bd0091f79d42472cc505c5bcf7ad96f69875 Signed-off-by: Junghyun Yeon --- src/hybrid/hybrid_installer.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/hybrid/hybrid_installer.cc b/src/hybrid/hybrid_installer.cc index ba50202..28ef97c 100644 --- a/src/hybrid/hybrid_installer.cc +++ b/src/hybrid/hybrid_installer.cc @@ -42,6 +42,8 @@ #include #include #include +#include +#include #include #include #include @@ -185,6 +187,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(true); AddStep(); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -201,6 +204,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); + AddStep(); AddStep(); AddStep(); break; @@ -268,6 +272,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(true); AddStep(); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -284,6 +289,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); + AddStep(); AddStep(); AddStep(); break; @@ -384,6 +390,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -399,6 +406,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); + AddStep(); AddStep(true); AddStep(); break; @@ -463,6 +471,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); + AddStep(); AddStep(); AddStep(); break; @@ -507,6 +516,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); + AddStep(); AddStep(); break; } -- 2.7.4