#include <boost/filesystem/path.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/system/error_code.hpp>
+#include <boost/format.hpp>
+#include <boost/program_options.hpp>
#include <common/paths.h>
#include <common/pkgmgr_interface.h>
#include <common/utils/file_util.h>
#include <common/utils/subprocess.h>
#include <common/utils/user_util.h>
+#include <gum/gum-user.h>
+#include <gum/gum-user-service.h>
+#include <gum/common/gum-user-types.h>
#include <gtest/gtest.h>
#include <gtest/gtest-death-test.h>
#include <tzplatform_config.h>
#include <vconf.h>
#include <vconf-internal-keys.h>
+#include <getopt.h>
#include <array>
#include <cstdio>
#include <cstdlib>
#include <vector>
+#include <regex>
#include "hybrid/hybrid_installer.h"
#include "wgt/wgt_app_query_interface.h"
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<std::string>(), "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<std::string>() == "global") {
+ std::cout << "Request mode was set to global." << std::endl;
+ return ci::RequestMode::GLOBAL;
+ }
+ if (vm["request-mode"].as<std::string>() == "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::string>() << 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";
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<std::string> kDBEntries = {
{".pkgmgr_parser.db"},
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_t> uid = ci::GetUidByUserName(user_name)) {
+ kTestUserId = *uid;
+ kTestUserIdStr = std::to_string(kTestUserId);
+ std::cout << "User created properly: uid=" << *uid;
+ if (boost::optional<gid_t> 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_t> uid = ci::GetUidByUserName(user_name))
+ test_uid = *uid;
+ bool ret = DeleteUser(user_name, true);
+ if (boost::optional<uid_t> 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);
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);
}
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();
}
}
void ValidatePackageRWFS(const std::string& pkgid, uid_t uid) {
bf::path root_path = ci::GetRootAppPath(false, uid);
bf::path package_path = root_path / pkgid;
- bf::path data_path = package_path / "data";
- bf::path cache_path = package_path / "cache";
- bf::path shared_data_path = package_path / "shared" / "data";
+ 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));
iter != bf::recursive_directory_iterator(); ++iter) {
if (bf::is_symlink(symlink_status(iter->path())))
continue;
- if (iter->path().filename() == "data" ||
- iter->path().filename() == ".mmc")
+ 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();
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;
}
}
-std::vector<bf::path> SetupBackupDirectories(uid_t uid) {
+std::vector<bf::path> SetupBackupDirectories() {
std::vector<bf::path> 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);
entries.emplace_back(kPreloadIcons);
}
- if (uid == kGlobalUserUid) {
+ if (kTestUserId == kGlobalUserUid) {
entries.emplace_back(kSkelDir);
entries.emplace_back(kGlobalManifestDir);
ci::UserList list = ci::GetUserList();
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;
bf::directory_iterator(dir), bf::directory_iterator())) {
if (dir_entry.path().string().find("smoke") != std::string::npos &&
bf::is_directory(dir_entry)) {
- if(Uninstall(dir_entry.path().filename().string(), PackageType::WGT,
- is_preload, RequestResult::NORMAL) !=
- ci::AppInstaller::Result::OK) {
- LOG(ERROR) << "Cannot uninstall smoke test app: "
- << dir_entry.path().filename().string();
+ 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(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);
}
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<bf::path> 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";
}
TEST_F(SmokeTest, InstallationMode_GoodSignature) {
+ // pkgid: smokewgt08
bf::path path = kSmokePackagesDirectory / "InstallationMode_GoodSignature.wgt"; // NOLINT
ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
}
TEST_F(SmokeTest, InstallationMode_WrongSignature) {
+ // pkgid: smokewgt12
bf::path path = kSmokePackagesDirectory / "InstallationMode_WrongSignature.wgt"; // NOLINT
ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::ERROR);
}
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";
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";
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";
CheckPackageReadonlyNonExistance(pkgid, {appid});
}
+TEST_F(SmokeTest, SharedRes24) {
+ bf::path path = kSmokePackagesDirectory / "SharedRes24.wgt";
+ std::string pkgid = "smokeSh2xx";
+ std::string appid = "smokeSh2xx.SharedRes24";
+ ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
+ ValidatePackage(pkgid, {appid});
+ bf::path root_path = ci::GetRootAppPath(false, kTestUserId);
+ ASSERT_TRUE(bf::is_regular_file(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "NOT-SHARED-WGT")); // NOLINT
+ ASSERT_FALSE(bf::exists(root_path / pkgid / "shared" / "res" / "NOT-SHARED-WGT")); // NOLINT
+}
+
+TEST_F(SmokeTest, SharedRes30) {
+ bf::path path = kSmokePackagesDirectory / "SharedRes30.wgt";
+ std::string pkgid = "smokeSh3xx";
+ std::string appid = "smokeSh3xx.SharedRes30";
+ ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
+ 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
+}
+
+TEST_F(SmokeTest, SharedRes30Delta) {
+ bf::path path = kSmokePackagesDirectory / "SharedRes30Delta.wgt";
+ bf::path delta_package = kSmokePackagesDirectory / "SharedRes30Delta.delta";
+ std::string pkgid = "smokeSh3De";
+ std::string appid = "smokeSh3De.SharedRes30Delta";
+ ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::WGT),
+ ci::AppInstaller::Result::OK);
+ 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
+ ASSERT_TRUE(bf::is_symlink(root_path / pkgid / "shared" / "res" / "SHARED-WGT-2")); // NOLINT
+ ASSERT_FALSE(bf::exists(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-WGT-1")); // NOLINT
+ ASSERT_FALSE(bf::exists(root_path / pkgid / "shared" / "res" / "SHARED-WGT-1")); // NOLINT
+}
+
+TEST_F(SmokeTest, SharedRes30Hybrid) {
+ bf::path path = kSmokePackagesDirectory / "SharedRes30Hybrid.wgt";
+ std::string pkgid = "smokeSh3Hy";
+ std::string appid1 = "smokeSh3Hy.SharedRes30Hybrid";
+ std::string appid2 = "sharedres30hybridserivce";
+ ASSERT_EQ(Install(path, PackageType::HYBRID), ci::AppInstaller::Result::OK);
+ 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
+ ASSERT_TRUE(bf::is_regular_file(root_path / pkgid / "shared" / "res" / "SHARED-TPK")); // NOLINT
+ ASSERT_TRUE(bf::is_symlink(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-TPK")); // NOLINT
+}
+
+TEST_F(SmokeTest, SharedRes30HybridDelta) {
+ bf::path path = kSmokePackagesDirectory / "SharedRes30HybridDelta.wgt";
+ bf::path delta_package = kSmokePackagesDirectory / "SharedRes30HybridDelta.delta";
+ std::string pkgid = "smokeSh3HD";
+ std::string appid1 = "smokeSh3HD.SharedRes30HybridDelta";
+ std::string appid2 = "sharedres30hybriddeltaserivce";
+ ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::HYBRID),
+ ci::AppInstaller::Result::OK);
+ 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
+ ASSERT_TRUE(bf::is_symlink(root_path / pkgid / "shared" / "res" / "SHARED-WGT-2")); // NOLINT
+ ASSERT_TRUE(bf::is_regular_file(root_path / pkgid / "shared" / "res" / "SHARED-TPK-2")); // NOLINT
+ ASSERT_TRUE(bf::is_symlink(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-TPK-2")); // NOLINT
+ ASSERT_FALSE(bf::exists(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-WGT-1")); // NOLINT
+ ASSERT_FALSE(bf::exists(root_path / pkgid / "shared" / "res" / "SHARED-WGT-1")); // NOLINT
+}
+
} // namespace common_installer
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();
}