From e73367757f24a76db49fe24ee19552a5942e81c5 Mon Sep 17 00:00:00 2001 From: Bartlomiej Date: Mon, 13 Mar 2017 10:47:07 +0100 Subject: [PATCH 01/16] Change order of StepRecoverApplication At this moment, in some situation StepRecoverSecurity needs data from pkgmgr database, so unregister application step should be done after StepRecoverSecurity. Change-Id: I06558231cd65cdd214eb930937f344c0b2827e4c --- src/hybrid/hybrid_installer.cc | 2 +- src/wgt/wgt_installer.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hybrid/hybrid_installer.cc b/src/hybrid/hybrid_installer.cc index f1dd5c4..a6a832f 100644 --- a/src/hybrid/hybrid_installer.cc +++ b/src/hybrid/hybrid_installer.cc @@ -301,9 +301,9 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); - AddStep(); AddStep(); AddStep(); + AddStep(); break; case ci::RequestType::MountInstall: AddStep(pkgmgr_); diff --git a/src/wgt/wgt_installer.cc b/src/wgt/wgt_installer.cc index 1eacc18..31565f7 100755 --- a/src/wgt/wgt_installer.cc +++ b/src/wgt/wgt_installer.cc @@ -393,9 +393,9 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); - AddStep(); AddStep(); AddStep(); + AddStep(); } void WgtInstaller::MountInstallSteps() { -- 2.7.4 From 7dc1a62311fd8cbebcd4abdb1c4b08298eabe71d Mon Sep 17 00:00:00 2001 From: Bartlomiej Kunikowski Date: Mon, 6 Mar 2017 11:01:33 +0100 Subject: [PATCH 02/16] [SmokeTest] Fix smoke test Fix related to changes in recovery file name convention. It repairs: SmokeTest.RecoveryMode_ForInstallation SmokeTest.RecoveryMode_ForMountInstall And partially repairs: SmokeTest.RecoveryMode_ForUpdate; SmokeTest.RecoveryMode_ForDelta SmokeTest.RecoveryMode_ForMountUpdate Change-Id: I836618dcca2a12f83a3b8d41ee3ce61998312880 --- src/unit_tests/smoke_test.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/unit_tests/smoke_test.cc b/src/unit_tests/smoke_test.cc index 369b3f5..99ba20b 100644 --- a/src/unit_tests/smoke_test.cc +++ b/src/unit_tests/smoke_test.cc @@ -233,7 +233,8 @@ void RemoveAllRecoveryFiles() { 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("/recovery") != std::string::npos) { + if (dir_entry.path().string().find("/wgt-recovery") + != std::string::npos) { bs::error_code error; bf::remove(dir_entry.path(), error); } @@ -247,7 +248,8 @@ bf::path FindRecoveryFile() { 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("/recovery") != std::string::npos) { + if (dir_entry.path().string().find("/wgt-recovery") + != std::string::npos) { return dir_entry.path(); } } -- 2.7.4 From ca83749c7b1f7e26f90e86f2145155a75033913a Mon Sep 17 00:00:00 2001 From: Damian Pietruchowski Date: Fri, 3 Mar 2017 14:40:57 +0100 Subject: [PATCH 03/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: I249c07794e713023fad6f21d1f621bcac3080621 Signed-off-by: Damian Pietruchowski --- src/unit_tests/smoke_test.cc | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/unit_tests/smoke_test.cc b/src/unit_tests/smoke_test.cc index 0fb52ff..25d87d8 100644 --- a/src/unit_tests/smoke_test.cc +++ b/src/unit_tests/smoke_test.cc @@ -848,7 +848,8 @@ class SmokeTest : public testing::Test { class PreloadSmokeTest : public testing::Test { void SetUp() override { - ASSERT_TRUE(kRequestMode == ci::RequestMode::GLOBAL); + ASSERT_EQ(ci::RequestMode::GLOBAL, kRequestMode); + ASSERT_EQ(0, getuid()) << "Test cannot be run by normal user"; } }; @@ -1386,8 +1387,7 @@ TEST_F(SmokeTest, MigrateLegacyExternalImageMode) { ValidateExternalPackage(pkgid, {appid}); } -TEST_F(PreloadSmokeTest, InstallationMode_Preload) { - ASSERT_EQ(getuid(), 0) << "Test cannot be run by normal user"; +TEST_F(PreloadSmokeTest, InstallationMode_Preload) {; bf::path path = kSmokePackagesDirectory / "InstallationMode_Preload.wgt"; std::string pkgid = "smokewgt37"; std::string appid = "smokewgt37.InstallationModePreload"; @@ -1397,7 +1397,6 @@ TEST_F(PreloadSmokeTest, InstallationMode_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"; std::string pkgid = "smokewgt38"; @@ -1415,7 +1414,6 @@ TEST_F(PreloadSmokeTest, UpdateMode_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"; std::string appid = "smokewgt39.DeinstallationModePreload"; @@ -1500,9 +1498,13 @@ TEST_F(SmokeTest, SharedRes30HybridDelta) { } // namespace common_installer int main(int argc, char** argv) { + ParseRequestMode(argc, argv); + if (getuid() != 0 || kRequestMode != 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); return RUN_ALL_TESTS(); } -- 2.7.4 From 1c037713e31b1d776ce0b61ebd0018513b659050 Mon Sep 17 00:00:00 2001 From: Bartlomiej Date: Tue, 14 Mar 2017 09:34:06 +0100 Subject: [PATCH 04/16] [Smoke Test] Fix smoke test packages and other files This is fix for MigrateLegacyExternalImageMode and MountUpdateMode_Rollback smoke tests. Change-Id: I0eca0a6ae167edd63f16dfef3eb4b0a7e6bc40bc --- .../smoke/MountUpdateMode_Rollback_2.wgt | Bin 38133 -> 38129 bytes .../smoke/legacy_extimage_dir/app2sd_migrate.db | Bin 16384 -> 16384 bytes .../legacy_extimage_dir/{smokeapp36 => smokewgt36} | Bin 3 files changed, 0 insertions(+), 0 deletions(-) rename src/unit_tests/test_samples/smoke/legacy_extimage_dir/{smokeapp36 => smokewgt36} (100%) diff --git a/src/unit_tests/test_samples/smoke/MountUpdateMode_Rollback_2.wgt b/src/unit_tests/test_samples/smoke/MountUpdateMode_Rollback_2.wgt index 299f4c54d72e095db31cf98e40bfb202acdd33f0..b1273e5ca07288c0a18c5e2185be13b92e309b20 100644 GIT binary patch delta 5292 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 UL__~43-|Z_{ChIOkbk`Y0TAxgoB#j- delta 5435 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 Ee+GgJssI20 diff --git a/src/unit_tests/test_samples/smoke/legacy_extimage_dir/app2sd_migrate.db b/src/unit_tests/test_samples/smoke/legacy_extimage_dir/app2sd_migrate.db index a1193690f4c9fe06761ced00e715628e272adf77..a1431ad3a67146ac0caaff6b8ced6d03cda5eda0 100644 GIT binary patch delta 59 zcmZo@U~Fh$oFL7}H&Mn}kdHz4;|^Z_KMYL#(hU64{6{wn3asYaEX{vafw?@rWb Date: Tue, 14 Mar 2017 09:22:34 +0100 Subject: [PATCH 05/16] Fix query IsHybridApplication() Recovery file naming rule is changed to: wgt-recovery-, so argument of find() function should be changed to "wgt-recovery-" for query is recovery request type. If #is_recovery is true it should not trying to unpack recovery file Change-Id: I37f9f31df602bab1a39702e6306082d8b10e2a03 Signed-off-by: Damian Pietruchowski --- src/wgt/wgt_app_query_interface.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/wgt/wgt_app_query_interface.cc b/src/wgt/wgt_app_query_interface.cc index 464165d..7b2eee4 100644 --- a/src/wgt/wgt_app_query_interface.cc +++ b/src/wgt/wgt_app_query_interface.cc @@ -102,7 +102,8 @@ bool WgtAppQueryInterface::IsPkgInstalled(const std::string& arg, uid_t uid) { bool WgtAppQueryInterface::IsHybridApplication(const std::string& arg, uid_t uid) { std::string info; - if (arg.find("apps_rw/recovery-") != std::string::npos) + bool is_recovery = arg.find("wgt-recovery-") != std::string::npos; + if (is_recovery) info = ReadPkgidFromRecovery(arg); else info = arg; @@ -112,7 +113,7 @@ bool WgtAppQueryInterface::IsHybridApplication(const std::string& arg, if (bf::exists(package_directory / info / kTizenManifestLocation) && bf::exists(package_directory / info / kHybridConfigLocation)) return true; - } else { + } else if (!is_recovery) { bool tizen_manifest_found = false; bool config_xml_found = false; if (!ci::CheckPathInZipArchive(info.c_str(), kTizenManifestLocation, -- 2.7.4 From e1dc5001917bc6d92251dbf7d1dd4bca88631b13 Mon Sep 17 00:00:00 2001 From: Junghyun Yeon Date: Fri, 17 Mar 2017 15:49:40 +0900 Subject: [PATCH 06/16] Release version 0.4.1 - Fix smoke tests - Rework widget's shared directory - Change step order of StepRecoverApplication Change-Id: If0c4113f6f43344833a34be9711f3b9506f17a69 Signed-off-by: Junghyun Yeon --- 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 4dd083f..a433c0a 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.0 +Version: 0.4.1 Release: 1 Group: Application Framework/Package Management License: Apache-2.0 -- 2.7.4 From 374fdf81f016d0c6ea717c87aceffc57c12955d3 Mon Sep 17 00:00:00 2001 From: jongmyeong ko Date: Fri, 17 Mar 2017 03:36:49 -0700 Subject: [PATCH 07/16] Revert "[SmokeTest] Skip tests for preload request" This reverts commit ca83749c7b1f7e26f90e86f2145155a75033913a. Change-Id: I7de10af58e13c46a7dc48916b3ade5dac316b029 --- src/unit_tests/smoke_test.cc | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/unit_tests/smoke_test.cc b/src/unit_tests/smoke_test.cc index 25d87d8..0fb52ff 100644 --- a/src/unit_tests/smoke_test.cc +++ b/src/unit_tests/smoke_test.cc @@ -848,8 +848,7 @@ class SmokeTest : public testing::Test { class PreloadSmokeTest : public testing::Test { void SetUp() override { - ASSERT_EQ(ci::RequestMode::GLOBAL, kRequestMode); - ASSERT_EQ(0, getuid()) << "Test cannot be run by normal user"; + ASSERT_TRUE(kRequestMode == ci::RequestMode::GLOBAL); } }; @@ -1387,7 +1386,8 @@ TEST_F(SmokeTest, MigrateLegacyExternalImageMode) { ValidateExternalPackage(pkgid, {appid}); } -TEST_F(PreloadSmokeTest, 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"; std::string appid = "smokewgt37.InstallationModePreload"; @@ -1397,6 +1397,7 @@ TEST_F(PreloadSmokeTest, InstallationMode_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"; std::string pkgid = "smokewgt38"; @@ -1414,6 +1415,7 @@ TEST_F(PreloadSmokeTest, UpdateMode_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"; std::string appid = "smokewgt39.DeinstallationModePreload"; @@ -1498,13 +1500,9 @@ TEST_F(SmokeTest, SharedRes30HybridDelta) { } // namespace common_installer int main(int argc, char** argv) { - ParseRequestMode(argc, argv); - if (getuid() != 0 || kRequestMode != 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); return RUN_ALL_TESTS(); } -- 2.7.4 From 6607ff7348fa01271f7ec127c81ce525e35121eb Mon Sep 17 00:00:00 2001 From: jongmyeong ko Date: Fri, 17 Mar 2017 03:30:30 -0700 Subject: [PATCH 08/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 09/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 10/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 11/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 12/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 13/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 14/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 15/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 16/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