1 // Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by an apache-2.0 license that can be
3 // found in the LICENSE file.
5 #include <boost/filesystem/operations.hpp>
6 #include <boost/range/iterator_range.hpp>
7 #include <boost/format.hpp>
8 #include <boost/program_options.hpp>
9 #include <boost/system/error_code.hpp>
11 #include <common/step/configuration/step_fail.h>
12 #include <common/utils/user_util.h>
13 #include <common/utils/file_util.h>
14 #include <common/request.h>
16 #include <gtest/gtest.h>
17 #include <gtest/gtest-death-test.h>
19 #include <pkgmgr-info.h>
22 #include <tzplatform_config.h>
24 #include <vconf-internal-keys.h>
31 #include "wgt/wgt_installer.h"
33 #include "unit_tests/smoke_utils.h"
35 namespace bo = boost::program_options;
37 const uid_t kGlobalUserUid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
38 const uid_t kGlobalUserGid = tzplatform_getgid(TZ_SYS_GLOBALAPP_USER);
39 const uid_t kDefaultUserUid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
40 uid_t kTestUserId = kGlobalUserUid;
41 gid_t kTestGroupId = kGlobalUserGid;
42 const char kNormalUserName[] = "smokeuser";
43 const char kSystemShareGroupName[] = "system_share";
44 std::string kTestUserIdStr = std::to_string(kTestUserId);
45 const std::string& kDefaultUserIdStr = std::to_string(kDefaultUserUid);
46 const char kLegacyExtImageDir[] = "legacy_extimage_dir";
47 const char kMigrateTestDBName[] = "app2sd_migrate.db";
49 const bf::path kSmokePackagesDirectory =
50 "/usr/share/wgt-backend-ut/test_samples/smoke/";
53 const char* rwDirectories[] = {
62 const std::vector<std::string> kDBEntries = {
63 {".pkgmgr_parser.db"},
64 {".pkgmgr_parser.db-journal"},
66 {".pkgmgr_cert.db-journal"},
68 {".app2sd.db-journal"},
71 const char kGlobalManifestDir[] = "/opt/share/packages";
72 const char kSkelDir[] = "/etc/skel/apps_rw";
73 const char kPreloadApps[] = "/usr/apps";
74 const char kPreloadManifestDir[] = "/usr/share/packages";
75 const char kPreloadIcons[] = "/usr/share/icons";
78 ci::RequestMode ParseRequestMode(int argc, char** argv) {
79 bo::options_description desc("Available options");
81 ("request-mode", bo::value<std::string>(), "set request mode")
82 ("global-request,g", "set request mode to global")
83 ("user-request,u", "set request mode to user");
86 bo::store(bo::parse_command_line(argc, argv, desc), vm);
89 if (vm.count("global-request")) {
90 std::cout << "Request mode was set to global." << std::endl;
91 return ci::RequestMode::GLOBAL;
93 if (vm.count("user-request")) {
94 std::cout << "Request mode was set to user." << std::endl;
95 return ci::RequestMode::USER;
97 if (vm.count("request-mode")) {
98 if (vm["request-mode"].as<std::string>() == "global") {
99 std::cout << "Request mode was set to global." << std::endl;
100 return ci::RequestMode::GLOBAL;
102 if (vm["request-mode"].as<std::string>() == "user") {
103 std::cout << "Request mode was set to user." << std::endl;
104 return ci::RequestMode::USER;
106 std::cout << "Cannot set request mode to "
107 << vm["request-mode"].as<std::string>() << std::endl;
108 std::cout << "Request mode was set to global." << std::endl;
109 return ci::RequestMode::GLOBAL;
113 bool TouchFile(const bf::path& path) {
114 FILE* f = fopen(path.c_str(), "w+");
121 bool AddUser(const char *user_name) {
122 GumUser* user = nullptr;
123 user = gum_user_create_sync(FALSE);
125 LOG(WARNING) << "Failed to create gum user! (user name: "
127 g_object_set(G_OBJECT(user), "username", user_name, "usertype",
128 GUM_USERTYPE_NORMAL, NULL);
129 gboolean rval = FALSE;
130 rval = gum_user_add_sync(user);
131 g_object_unref(user);
135 bool DeleteUser(const char *user_name, bool rem_home_dir) {
137 GumUser* guser = gum_user_get_by_name_sync(user_name, FALSE);
139 rval = gum_user_delete_sync(guser, rem_home_dir);
143 bool AddTestUser(const char *user_name) {
144 std::cout << "Adding test user: " << user_name << std::endl;
145 bool ret = AddUser(user_name);
146 if (boost::optional<uid_t> uid = ci::GetUidByUserName(user_name)) {
148 kTestUserIdStr = std::to_string(kTestUserId);
149 std::cout << "User created properly: uid=" << *uid;
150 if (boost::optional<gid_t> gid = ci::GetGidByUid(*uid)) {
152 std::cout << " gid=" << *gid;
154 std::cout << std::endl;
157 LOG(ERROR) << "Adding test user failed";
161 bool DeleteTestUser(const char *user_name) {
162 std::cout << "Deleting test user: " << user_name << std::endl;
164 if (boost::optional<uid_t> uid = ci::GetUidByUserName(user_name))
166 bool ret = DeleteUser(user_name, true);
167 if (!ci::GetUidByUserName(user_name)) {
168 std::cout << "User deleted properly: user_name=" << user_name
169 << " uid=" << test_uid << std::endl;
172 LOG(ERROR) << "Deleting test user failed";
176 void RemoveAllRecoveryFiles() {
177 bf::path root_path = ci::GetRootAppPath(false,
179 if (!bf::exists(root_path))
181 for (auto& dir_entry : boost::make_iterator_range(
182 bf::directory_iterator(root_path), bf::directory_iterator())) {
183 if (bf::is_regular_file(dir_entry)) {
184 if (dir_entry.path().string().find("/wgt-recovery")
185 != std::string::npos) {
186 bs::error_code error;
187 bf::remove(dir_entry.path(), error);
193 bf::path FindRecoveryFile() {
194 bf::path root_path = ci::GetRootAppPath(false,
196 for (auto& dir_entry : boost::make_iterator_range(
197 bf::directory_iterator(root_path), bf::directory_iterator())) {
198 if (bf::is_regular_file(dir_entry)) {
199 if (dir_entry.path().string().find("/wgt-recovery")
200 != std::string::npos) {
201 return dir_entry.path();
208 bf::path GetPackageRoot(const std::string& pkgid, uid_t uid) {
209 bf::path root_path = ci::GetRootAppPath(false, uid);
210 return root_path / pkgid;
213 bool ValidateFileContentInPackage(const std::string& pkgid,
214 const std::string& relative,
215 const std::string& expected,
217 bf::path file_path = ci::GetRootAppPath(is_readonly, kTestUserId);
218 file_path = file_path / pkgid / relative;
219 if (!bf::exists(file_path)) {
220 LOG(ERROR) << file_path << " doesn't exist";
223 FILE* handle = fopen(file_path.c_str(), "r");
225 LOG(ERROR) << file_path << " cannot be open";
229 std::array<char, 200> buffer;
230 while (fgets(buffer.data(), buffer.size(), handle)) {
231 content += buffer.data();
234 return content == expected;
237 void AddDataFiles(const std::string& pkgid, uid_t uid) {
238 if (uid == kGlobalUserUid) {
239 ci::UserList list = ci::GetUserList();
240 for (auto l : list) {
241 auto pkg_path = GetPackageRoot(pkgid, std::get<0>(l));
242 ASSERT_TRUE(TouchFile(pkg_path / "data" / "file1.txt"));
243 ASSERT_TRUE(TouchFile(pkg_path / "data" / "file2.txt"));
246 auto pkg_path = GetPackageRoot(pkgid, uid);
247 ASSERT_TRUE(TouchFile(pkg_path / "data" / "file1.txt"));
248 ASSERT_TRUE(TouchFile(pkg_path / "data" / "file2.txt"));
252 void ValidateDataFiles(const std::string& pkgid, uid_t uid) {
253 if (uid == kGlobalUserUid) {
254 ci::UserList list = ci::GetUserList();
255 for (auto l : list) {
256 auto pkg_path = GetPackageRoot(pkgid, std::get<0>(l));
257 ASSERT_TRUE(bf::exists(pkg_path / "data" / "file1.txt"));
258 ASSERT_TRUE(bf::exists(pkg_path / "data" / "file2.txt"));
261 auto pkg_path = GetPackageRoot(pkgid, uid);
262 ASSERT_TRUE(bf::exists(pkg_path / "data" / "file1.txt"));
263 ASSERT_TRUE(bf::exists(pkg_path / "data" / "file2.txt"));
267 void ValidatePackageRWFS(const std::string& pkgid, uid_t uid) {
268 bf::path root_path = ci::GetRootAppPath(false, uid);
269 bf::path package_path = root_path / pkgid;
270 bf::path data_path = package_path / rwDirectories[DATA];
271 bf::path cache_path = package_path / rwDirectories[CACHE];
272 bf::path shared_data_path = package_path / rwDirectories[SHARED_DATA];
274 ASSERT_TRUE(bf::exists(data_path));
275 ASSERT_TRUE(bf::exists(cache_path));
278 stat(data_path.c_str(), &stats);
279 // gid of RW dirs should be system_share
280 boost::optional<gid_t> system_share =
281 ci::GetGidByGroupName(kSystemShareGroupName);
282 ASSERT_EQ(uid, stats.st_uid) << "Invalid gid: " << data_path;
283 ASSERT_EQ(*system_share, stats.st_gid) << "Invalid gid: " << data_path;
284 if (bf::exists(shared_data_path)) {
285 stat(shared_data_path.c_str(), &stats);
286 ASSERT_EQ(uid, stats.st_uid) << "Invalid gid: " << shared_data_path;
287 ASSERT_EQ(*system_share, stats.st_gid) << "Invalid gid: "
291 stat(cache_path.c_str(), &stats);
292 ASSERT_EQ(uid, stats.st_uid) << "Invalid gid: " << cache_path;
293 ASSERT_EQ(*system_share, stats.st_gid) << "Invalid gid: " << cache_path;
296 void ValidatePackageFS(const std::string& pkgid,
297 const std::vector<std::string>& appids,
298 uid_t uid, gid_t gid, bool is_readonly) {
299 bf::path root_path = ci::GetRootAppPath(is_readonly, uid);
300 bf::path package_path = root_path / pkgid;
301 bf::path shared_path = package_path / "shared";
302 ASSERT_TRUE(bf::exists(root_path));
303 ASSERT_TRUE(bf::exists(package_path));
304 ASSERT_TRUE(bf::exists(shared_path));
306 bf::path manifest_path =
307 bf::path(getUserManifestPath(uid, is_readonly)) / (pkgid + ".xml");
308 ASSERT_TRUE(bf::exists(manifest_path));
310 for (auto& appid : appids) {
311 bf::path binary_path = package_path / "bin" / appid;
312 ASSERT_TRUE(bf::exists(binary_path));
315 bf::path widget_root_path = package_path / "res" / "wgt";
316 bf::path config_path = widget_root_path / "config.xml";
317 ASSERT_TRUE(bf::exists(widget_root_path));
318 ASSERT_TRUE(bf::exists(config_path));
320 bf::path private_tmp_path = package_path / "tmp";
321 ASSERT_TRUE(bf::exists(private_tmp_path));
323 // backups should not exist
324 bf::path package_backup = ci::GetBackupPathForPackagePath(package_path);
325 bf::path manifest_backup = ci::GetBackupPathForManifestFile(manifest_path);
326 ASSERT_FALSE(bf::exists(package_backup));
327 ASSERT_FALSE(bf::exists(manifest_backup));
329 for (bf::recursive_directory_iterator iter(package_path);
330 iter != bf::recursive_directory_iterator(); ++iter) {
331 if (bf::is_symlink(symlink_status(iter->path())))
333 bool is_rw_dir = false;
334 for (const auto rw_dir : rwDirectories) {
335 bf::path rw_dir_path = rw_dir;
336 is_rw_dir |= ci::MakeRelativePath(iter->path(), package_path)
339 if (is_rw_dir || iter->path().filename() == ".mmc") {
344 stat(iter->path().c_str(), &stats);
345 ASSERT_EQ(uid, stats.st_uid) << "Invalid uid: " << iter->path();
346 ASSERT_EQ(gid, stats.st_gid) << "Invalid gid: " << iter->path();
350 void PackageCheckCleanup(const std::string& pkgid,
351 const std::vector<std::string>&, bool is_readonly) {
352 bf::path root_path = ci::GetRootAppPath(is_readonly, kTestUserId);
353 bf::path package_path = root_path / pkgid;
354 ASSERT_FALSE(bf::exists(package_path));
356 bf::path manifest_path = bf::path(getUserManifestPath(kTestUserId,
357 is_readonly)) / (pkgid + ".xml");
358 ASSERT_FALSE(bf::exists(manifest_path));
360 // backups should not exist
361 bf::path package_backup = ci::GetBackupPathForPackagePath(package_path);
362 bf::path manifest_backup = ci::GetBackupPathForManifestFile(manifest_path);
363 ASSERT_FALSE(bf::exists(package_backup));
364 ASSERT_FALSE(bf::exists(manifest_backup));
367 void ValidatePackage(const std::string& pkgid,
368 const std::vector<std::string>& appids, bool is_readonly) {
369 ASSERT_TRUE(ci::QueryIsPackageInstalled(
370 pkgid, ci::GetRequestMode(kTestUserId), kTestUserId));
371 ValidatePackageFS(pkgid, appids, kTestUserId, kTestGroupId, is_readonly);
372 if (kTestUserId == kGlobalUserUid) {
373 ci::UserList list = ci::GetUserList();
375 ValidatePackageRWFS(pkgid, std::get<0>(l));
377 ValidatePackageRWFS(pkgid, kTestUserId);
381 void ValidateExternalPackageFS(const std::string& pkgid,
382 const std::vector<std::string>& appids,
383 uid_t uid, gid_t gid) {
384 ASSERT_EQ(app2ext_usr_enable_external_pkg(pkgid.c_str(), uid), 0);
385 bf::path root_path = ci::GetRootAppPath(false, uid);
386 ASSERT_TRUE(bf::exists(root_path / pkgid / ".mmc" / "res"));
387 ValidatePackageFS(pkgid, appids, uid, gid, false);
388 ASSERT_EQ(app2ext_usr_disable_external_pkg(pkgid.c_str(), uid), 0);
391 void ValidateExternalPackage(const std::string& pkgid,
392 const std::vector<std::string>& appids) {
393 ASSERT_TRUE(ci::QueryIsPackageInstalled(
394 pkgid, ci::GetRequestMode(kTestUserId),
396 std::string storage = ci::QueryStorageForPkgId(pkgid, kTestUserId);
397 bf::path ext_mount_path = ci::GetExternalCardPath();
398 if (bf::is_empty(ext_mount_path)) {
399 LOG(INFO) << "Sdcard not exists!";
400 ASSERT_EQ(storage, "installed_internal");
402 ASSERT_EQ(storage, "installed_external");
404 ValidateExternalPackageFS(pkgid, appids, kTestUserId, kTestGroupId);
405 if (kTestUserId == kGlobalUserUid) {
406 ci::UserList list = ci::GetUserList();
408 ValidatePackageRWFS(pkgid, std::get<0>(l));
410 ValidatePackageRWFS(pkgid, kTestUserId);
414 void CheckPackageNonExistance(const std::string& pkgid,
415 const std::vector<std::string>& appids) {
416 ASSERT_FALSE(ci::QueryIsPackageInstalled(
417 pkgid, ci::GetRequestMode(kTestUserId),
419 PackageCheckCleanup(pkgid, appids);
420 if (kTestUserId == kGlobalUserUid) {
421 ci::UserList list = ci::GetUserList();
422 bf::path skel_path(kSkelDir);
423 ASSERT_FALSE(bf::exists(skel_path / pkgid));
424 for (auto& l : list) {
425 bf::path root_path = ci::GetRootAppPath(false, std::get<0>(l));
426 bf::path package_path = root_path / pkgid;
427 ASSERT_FALSE(bf::exists(package_path));
432 void CheckPackageReadonlyNonExistance(const std::string& pkgid,
433 const std::vector<std::string>& appids) {
434 ASSERT_FALSE(ci::QueryIsPackageInstalled(
435 pkgid, ci::GetRequestMode(kTestUserId), kTestUserId));
436 PackageCheckCleanup(pkgid, appids, true);
439 std::unique_ptr<ci::AppQueryInterface> CreateQueryInterface() {
440 std::unique_ptr<ci::AppQueryInterface> query_interface(
441 new wgt::WgtAppQueryInterface());
442 return query_interface;
445 std::unique_ptr<ci::AppInstaller> CreateInstaller(ci::PkgMgrPtr pkgmgr,
448 case PackageType::WGT:
449 return std::unique_ptr<ci::AppInstaller>(new wgt::WgtInstaller(pkgmgr));
450 case PackageType::HYBRID:
451 return std::unique_ptr<ci::AppInstaller>(
452 new hybrid::HybridInstaller(pkgmgr));
454 LOG(ERROR) << "Unknown installer type";
459 ci::AppInstaller::Result RunInstallerWithPkgrmgr(ci::PkgMgrPtr pkgmgr,
461 RequestResult mode) {
462 std::unique_ptr<ci::AppInstaller> installer = CreateInstaller(pkgmgr, type);
464 case RequestResult::FAIL:
465 installer->AddStep<ci::configuration::StepFail>();
470 return installer->Run();
472 ci::AppInstaller::Result CallBackend(int argc,
475 RequestResult mode) {
476 TestPkgmgrInstaller pkgmgr_installer;
477 std::unique_ptr<ci::AppQueryInterface> query_interface =
478 CreateQueryInterface();
480 ci::PkgMgrInterface::Create(argc, const_cast<char**>(argv),
481 &pkgmgr_installer, query_interface.get());
483 LOG(ERROR) << "Failed to initialize pkgmgr interface";
484 return ci::AppInstaller::Result::UNKNOWN;
486 return RunInstallerWithPkgrmgr(pkgmgr, type, mode);
489 ci::AppInstaller::Result Install(const bf::path& path,
491 RequestResult mode) {
492 const char* argv[] = {"", "-i", path.c_str(), "-u", kTestUserIdStr.c_str()};
493 return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
496 ci::AppInstaller::Result InstallPreload(const bf::path& path, PackageType type,
497 RequestResult mode) {
498 const char* argv[] = {"", "-i", path.c_str(), "--preload"};
499 return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
502 bool CheckAvailableExternalPath() {
503 bf::path ext_mount_path = ci::GetExternalCardPath();
504 LOG(DEBUG) << "ext_mount_path :" << ext_mount_path;
505 if (ext_mount_path.empty()) {
506 LOG(ERROR) << "Sdcard not exists!";
512 ci::AppInstaller::Result InstallExternal(const bf::path& path,
514 RequestResult mode) {
515 int default_storage = 0;
516 vconf_get_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT,
518 vconf_set_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT, 1);
520 const char* argv[] = {"", "-i", path.c_str(), "-u", kTestUserIdStr.c_str()};
521 ci::AppInstaller::Result result =
522 CallBackend(SIZEOFARRAY(argv), argv, type, mode);
524 vconf_set_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT,
529 ci::AppInstaller::Result MigrateLegacyExternalImage(const std::string& pkgid,
530 const bf::path& path,
531 const bf::path& legacy_path,
533 RequestResult mode) {
534 if (InstallExternal(path, type) != ci::AppInstaller::Result::OK) {
535 LOG(ERROR) << "Failed to install application. Cannot perform Migrate";
536 return ci::AppInstaller::Result::ERROR;
539 bf::path ext_mount_path = ci::GetExternalCardPath();
540 if (bf::is_empty(ext_mount_path)) {
541 LOG(ERROR) << "Sdcard not exists!";
542 return ci::AppInstaller::Result::ERROR;
544 bf::path app2sd_path = ext_mount_path / "app2sd";
546 char* image_name = app2ext_usr_getname_image(pkgid.c_str(),
549 LOG(ERROR) << "Failed to get external image name";
550 return ci::AppInstaller::Result::ERROR;
552 bf::path org_image = app2sd_path / image_name;
555 bs::error_code error;
556 bf::remove(org_image, error);
558 LOG(ERROR) << "Failed to remove org image";
559 return ci::AppInstaller::Result::ERROR;
562 bf::path db_path = tzplatform_getenv(TZ_SYS_DB);
563 bf::path app2sd_db = db_path / ".app2sd.db";
564 bf::path app2sd_db_journal = db_path / ".app2sd.db-journal";
565 bf::remove(app2sd_db, error);
567 LOG(ERROR) << "Failed to remove app2sd db";
568 return ci::AppInstaller::Result::ERROR;
570 bf::remove(app2sd_db_journal, error);
572 LOG(ERROR) << "Failed to remove app2sd journal db";
573 return ci::AppInstaller::Result::ERROR;
576 bf::path app2sd_migrate_db = legacy_path / kMigrateTestDBName;
577 if (!ci::CopyFile(app2sd_migrate_db, app2sd_db)) {
578 LOG(ERROR) << "Failed to copy test db";
579 return ci::AppInstaller::Result::ERROR;
582 bf::path legacy_src = legacy_path / pkgid;
583 bf::path legacy_dst = app2sd_path / pkgid;
584 if (!ci::CopyFile(legacy_src, legacy_dst)) {
585 LOG(ERROR) << "Failed to copy test image";
586 return ci::AppInstaller::Result::ERROR;
588 const char* argv[] = {"", "--migrate-extimg", pkgid.c_str(),
589 "-u", kDefaultUserIdStr.c_str()};
590 return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
593 ci::AppInstaller::Result MountInstall(const bf::path& path,
594 PackageType type, RequestResult mode) {
595 const char* argv[] = {"", "-w", path.c_str(), "-u", kTestUserIdStr.c_str()};
596 return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
599 ci::AppInstaller::Result Uninstall(const std::string& pkgid,
602 RequestResult mode) {
604 const char* argv[] = {"", "-d", pkgid.c_str(), "--preload",
606 return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
608 const char* argv[] = {"", "-d", pkgid.c_str(), "-u",
609 kTestUserIdStr.c_str()};
610 return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
614 ci::AppInstaller::Result RDSUpdate(const bf::path& path,
615 const std::string& pkgid,
617 RequestResult mode) {
618 if (Install(path, type) != ci::AppInstaller::Result::OK) {
619 LOG(ERROR) << "Failed to install application. Cannot perform RDS";
620 return ci::AppInstaller::Result::UNKNOWN;
622 const char* argv[] = {"", "-r", pkgid.c_str(), "-u",
623 kTestUserIdStr.c_str()};
624 return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
627 ci::AppInstaller::Result DeltaInstall(const bf::path& path,
628 const bf::path& delta_package, PackageType type) {
629 if (Install(path, type) != ci::AppInstaller::Result::OK) {
630 LOG(ERROR) << "Failed to install application. Cannot perform delta update";
631 return ci::AppInstaller::Result::UNKNOWN;
633 return Install(delta_package, type);
636 ci::AppInstaller::Result EnablePackage(const std::string& pkgid,
638 RequestResult mode) {
639 const char* argv[] = {"", "-A", pkgid.c_str(), "-u", kTestUserIdStr.c_str()};
640 return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
643 ci::AppInstaller::Result DisablePackage(const std::string& pkgid,
645 RequestResult mode) {
646 const char* argv[] = {"", "-D", pkgid.c_str(), "-u", kTestUserIdStr.c_str()};
647 return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
650 ci::AppInstaller::Result Recover(const bf::path& recovery_file,
652 RequestResult mode) {
653 const char* argv[] = {"", "-b", recovery_file.c_str(), "-u",
654 kTestUserIdStr.c_str()};
655 return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
658 void BackupPath(const bf::path& path) {
659 bf::path backup_path = path.string() + ".bck";
660 std::cout << "Backup path: " << path << " to " << backup_path << std::endl;
661 bs::error_code error;
662 bf::remove_all(backup_path, error);
664 LOG(ERROR) << "Remove failed: " << backup_path
665 << " (" << error.message() << ")";
666 if (bf::exists(path)) {
667 bf::rename(path, backup_path, error);
669 LOG(ERROR) << "Failed to setup test environment. Does some previous"
670 << " test crashed? Path: "
671 << backup_path << " should not exist.";
676 void RestorePath(const bf::path& path) {
677 bf::path backup_path = path.string() + ".bck";
678 std::cout << "Restore path: " << path << " from " << backup_path << std::endl;
679 bs::error_code error;
680 bf::remove_all(path, error);
682 LOG(ERROR) << "Remove failed: " << path
683 << " (" << error.message() << ")";
684 if (bf::exists(backup_path)) {
685 bf::rename(backup_path, path, error);
687 LOG(ERROR) << "Failed to restore backup path: " << backup_path
688 << " (" << error.message() << ")";
692 std::vector<bf::path> SetupBackupDirectories() {
693 std::vector<bf::path> entries;
694 bf::path db_dir = bf::path(tzplatform_getenv(TZ_SYS_DB));
695 if (kTestUserId != kGlobalUserUid)
696 db_dir = db_dir / "user" / std::to_string(kTestUserId);
697 for (auto e : kDBEntries) {
698 bf::path path = db_dir / e;
699 entries.emplace_back(path);
703 entries.emplace_back(kPreloadApps);
704 entries.emplace_back(kPreloadManifestDir);
705 entries.emplace_back(kPreloadIcons);
708 if (kTestUserId == kGlobalUserUid) {
709 entries.emplace_back(kSkelDir);
710 entries.emplace_back(kGlobalManifestDir);
711 ci::UserList list = ci::GetUserList();
712 for (auto l : list) {
713 bf::path apps = std::get<2>(l) / "apps_rw";
714 entries.emplace_back(apps);
717 tzplatform_set_user(kTestUserId);
718 bf::path approot = tzplatform_getenv(TZ_USER_APPROOT);
719 tzplatform_reset_user();
720 entries.emplace_back(approot);
723 bf::path apps_rw = ci::GetRootAppPath(false, kTestUserId);
724 entries.emplace_back(apps_rw);
729 void UninstallAllAppsInDirectory(bf::path dir, bool is_preload) {
730 if (bf::exists(dir)) {
731 for (auto& dir_entry : boost::make_iterator_range(
732 bf::directory_iterator(dir), bf::directory_iterator())) {
733 if (dir_entry.path().string().find("smoke") != std::string::npos &&
734 bf::is_directory(dir_entry)) {
735 std::string package = dir_entry.path().filename().string();
736 std::regex pkg_regex("smoke[a-zA-Z]{3,}[1-9]{2,}");
737 if (std::regex_match(package, pkg_regex)) {
738 if (Uninstall(dir_entry.path().filename().string(), PackageType::WGT,
739 is_preload, RequestResult::NORMAL) !=
740 ci::AppInstaller::Result::OK) {
741 LOG(ERROR) << "Cannot uninstall smoke test app: "
742 << dir_entry.path().filename().string();
750 void UninstallAllSmokeApps(ci::RequestMode request_mode) {
751 if (getuid() == 0 && request_mode == ci::RequestMode::GLOBAL) {
752 bf::path root_path = kPreloadApps;
753 UninstallAllAppsInDirectory(root_path, true);
755 bf::path apps_rw = ci::GetRootAppPath(false, kTestUserId);
756 UninstallAllAppsInDirectory(apps_rw, false);