Reworked sharing of widget's shared/res directory.
[platform/core/appfw/wgt-backend.git] / src / unit_tests / smoke_test.cc
1 // Copyright (c) 2015 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.
4
5 #include <boost/filesystem/operations.hpp>
6 #include <boost/filesystem/path.hpp>
7 #include <boost/range/iterator_range.hpp>
8 #include <boost/system/error_code.hpp>
9 #include <boost/format.hpp>
10
11 #include <common/paths.h>
12 #include <common/pkgmgr_interface.h>
13 #include <common/pkgmgr_query.h>
14 #include <common/request.h>
15 #include <common/step/configuration/step_fail.h>
16 #include <common/tzip_interface.h>
17 #include <common/utils/file_util.h>
18 #include <common/utils/subprocess.h>
19 #include <common/utils/user_util.h>
20
21 #include <gtest/gtest.h>
22 #include <gtest/gtest-death-test.h>
23 #include <pkgmgr-info.h>
24 #include <signal.h>
25 #include <unistd.h>
26 #include <tzplatform_config.h>
27 #include <vconf.h>
28 #include <vconf-internal-keys.h>
29 #include <getopt.h>
30
31 #include <array>
32 #include <cstdio>
33 #include <cstdlib>
34 #include <vector>
35 #include <regex>
36
37 #include "hybrid/hybrid_installer.h"
38 #include "wgt/wgt_app_query_interface.h"
39 #include "wgt/wgt_installer.h"
40
41 #define SIZEOFARRAY(ARR)                                                       \
42   sizeof(ARR) / sizeof(ARR[0])                                                 \
43
44 namespace bf = boost::filesystem;
45 namespace bs = boost::system;
46 namespace ci = common_installer;
47
48 namespace {
49 ci::RequestMode kRequestMode = ci::RequestMode::GLOBAL;
50 const char *short_opts = "g:u";
51 const struct option long_opts[] = {
52     { "request_mode", 1, NULL, 'r' },
53     { 0, 0, 0, 0 }  /* sentinel */
54 };
55 const char *request_modes[] {
56      "global",
57      "user"
58 };
59 void ParseRequestMode(int argc,  char** argv) {
60   int c;
61   int opt_idx = 0;
62   do {
63     c = getopt_long(argc, argv, short_opts, long_opts, &opt_idx);
64     switch (c) {
65     case 'r':
66       if (strncmp(optarg, request_modes[0], strlen(request_modes[0])) == 0)
67         kRequestMode = ci::RequestMode::GLOBAL;
68       else if (strncmp(optarg, request_modes[1], strlen(request_modes[1])) == 0)
69         kRequestMode = ci::RequestMode::USER;
70       else
71         LOG(ERROR) << "Wrong request mode " << optarg
72                    << ". Available: \"global\" or \"user\"";
73       break;
74     case 'g':
75       kRequestMode = ci::RequestMode::GLOBAL;
76       break;
77     case 'u':
78       kRequestMode = ci::RequestMode::USER;
79       break;
80     default:
81       break;
82     }
83   } while (c != -1);
84 }
85
86 const uid_t kGlobalUserUid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
87 const uid_t kGlobalUserGid = tzplatform_getgid(TZ_SYS_GLOBALAPP_USER);
88 const uid_t kDefaultUserUid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
89 uid_t kTestUserId = kGlobalUserUid;
90 gid_t kTestGroupId = kGlobalUserGid;
91 std::string kTestUserIdStr = std::to_string(kTestUserId);
92 const char kNormalUserName[] = "smokeuser";
93 const char kSystemShareGroupName[] = "system_share";
94 const std::string& kDefaultUserIdStr = std::to_string(kDefaultUserUid);
95 const char kLegacyExtImageDir[] = "legacy_extimage_dir";
96 const char kMigrateTestDBName[] = "app2sd_migrate.db";
97
98 const bf::path kSmokePackagesDirectory =
99     "/usr/share/wgt-backend-ut/test_samples/smoke/";
100
101 enum RWDirectory {
102     DATA,
103     CACHE,
104     SHARED_CACHE,
105     SHARED_DATA,
106     SHARED_TRUSTED
107 };
108
109 const char* rwDirectories[] = {
110   "data",
111   "cache",
112   "shared/cache",
113   "shared/data",
114   "shared/trusted",
115 };
116
117 // common entries
118 const std::vector<std::string> kDBEntries = {
119   {".pkgmgr_parser.db"},
120   {".pkgmgr_parser.db-journal"},
121   {".pkgmgr_cert.db"},
122   {".pkgmgr_cert.db-journal"},
123   {".app2sd.db"},
124   {".app2sd.db-journal"},
125 };
126 // globaluser entries
127 const char kGlobalManifestDir[] = "/opt/share/packages";
128 const char kSkelDir[] = "/etc/skel/apps_rw";
129 const char kPreloadApps[] = "/usr/apps";
130 const char kPreloadManifestDir[] = "/usr/share/packages";
131 const char kPreloadIcons[] = "/usr/share/icons";
132
133 enum class RequestResult {
134   NORMAL,
135   FAIL
136 };
137
138 class ScopedTzipInterface {
139  public:
140   explicit ScopedTzipInterface(const std::string& pkgid)
141       : pkg_path_(bf::path(ci::GetRootAppPath(false,
142             kTestUserId)) / pkgid),
143         interface_(ci::GetMountLocation(pkg_path_)),
144         mounted_(true) {
145     interface_.MountZip(ci::GetZipPackageLocation(pkg_path_, pkgid));
146   }
147
148   void Release() {
149     if (mounted_) {
150       interface_.UnmountZip();
151       mounted_ = false;
152     }
153   }
154
155   ~ScopedTzipInterface() {
156     Release();
157   }
158
159  private:
160   bf::path pkg_path_;
161   ci::TzipInterface interface_;
162   bool mounted_;
163 };
164
165 class TestPkgmgrInstaller : public ci::PkgmgrInstallerInterface {
166  public:
167   bool CreatePkgMgrInstaller(pkgmgr_installer** installer,
168                              ci::InstallationMode* mode) {
169     *installer = pkgmgr_installer_offline_new();
170     if (!*installer)
171       return false;
172     *mode = ci::InstallationMode::ONLINE;
173     return true;
174   }
175
176   bool ShouldCreateSignal() const {
177     return false;
178   }
179 };
180
181 enum class PackageType {
182   WGT,
183   HYBRID
184 };
185
186 bool TouchFile(const bf::path& path) {
187   FILE* f = fopen(path.c_str(), "w+");
188   if (!f)
189     return false;
190   fclose(f);
191   return true;
192 }
193
194 bool AddTestUser(const char *user_name) {
195   std::cout << "Adding test user: " << user_name << std::endl;
196   gboolean ret = ci::AddUser(user_name);
197   if (boost::optional<uid_t> uid = ci::GetUidByUserName(user_name)) {
198     kTestUserId = *uid;
199     kTestUserIdStr = std::to_string(kTestUserId);
200     std::cout << "User created properly: uid=" << *uid;
201     if (boost::optional<gid_t> gid = ci::GetGidByUid(*uid)) {
202       kTestGroupId = *gid;
203       std::cout << " gid=" << *gid;
204     }
205     std::cout << std::endl;
206     return true;
207   }
208   LOG(ERROR) << "Adding test user failed";
209   return false;
210 }
211
212 bool DeleteTestUser(const char *user_name) {
213   std::cout << "Deleting test user: " << user_name << std::endl;
214   uid_t test_uid;
215   if (boost::optional<uid_t> uid = ci::GetUidByUserName(user_name))
216     test_uid = *uid;
217   gboolean ret = ci::DeleteUser(user_name, true);
218   if (boost::optional<uid_t> uid = ci::GetUidByUserName(user_name));
219   else {
220     std::cout << "User deleted properly: user_name=" << user_name
221               << " uid=" << test_uid << std::endl;
222     return true;
223   }
224   LOG(ERROR) << "Deleting test user failed";
225   return false;
226 }
227
228 void RemoveAllRecoveryFiles() {
229   bf::path root_path = ci::GetRootAppPath(false,
230       kTestUserId);
231   if (!bf::exists(root_path))
232     return;
233   for (auto& dir_entry : boost::make_iterator_range(
234          bf::directory_iterator(root_path), bf::directory_iterator())) {
235     if (bf::is_regular_file(dir_entry)) {
236       if (dir_entry.path().string().find("/recovery") != std::string::npos) {
237         bs::error_code error;
238         bf::remove(dir_entry.path(), error);
239       }
240     }
241   }
242 }
243
244 bf::path FindRecoveryFile() {
245   bf::path root_path = ci::GetRootAppPath(false,
246       kTestUserId);
247   for (auto& dir_entry : boost::make_iterator_range(
248          bf::directory_iterator(root_path), bf::directory_iterator())) {
249     if (bf::is_regular_file(dir_entry)) {
250       if (dir_entry.path().string().find("/recovery") != std::string::npos) {
251         return dir_entry.path();
252       }
253     }
254   }
255   return {};
256 }
257
258 bf::path GetPackageRoot(const std::string& pkgid, uid_t uid) {
259   bf::path root_path = ci::GetRootAppPath(false, uid);
260   return root_path / pkgid;
261 }
262
263 bool ValidateFileContentInPackage(const std::string& pkgid,
264                                   const std::string& relative,
265                                   const std::string& expected,
266                                   bool is_readonly = false) {
267   bf::path file_path = ci::GetRootAppPath(is_readonly, kTestUserId);
268   file_path = file_path / pkgid / relative;
269   if (!bf::exists(file_path)) {
270     LOG(ERROR) << file_path << " doesn't exist";
271     return false;
272   }
273   FILE* handle = fopen(file_path.c_str(), "r");
274   if (!handle) {
275     LOG(ERROR) << file_path << " cannot  be open";
276     return false;
277   }
278   std::string content;
279   std::array<char, 200> buffer;
280   while (fgets(buffer.data(), buffer.size(), handle)) {
281     content += buffer.data();
282   }
283   fclose(handle);
284   return content == expected;
285 }
286
287 void AddDataFiles(const std::string& pkgid, uid_t uid) {
288   if (uid == kGlobalUserUid) {
289     ci::UserList list = ci::GetUserList();
290     for (auto l : list) {
291       auto pkg_path = GetPackageRoot(pkgid, std::get<0>(l));
292       ASSERT_TRUE(TouchFile(pkg_path / "data" / "file1.txt"));
293       ASSERT_TRUE(TouchFile(pkg_path / "data" / "file2.txt"));
294     }
295   } else {
296     auto pkg_path = GetPackageRoot(pkgid, uid);
297     ASSERT_TRUE(TouchFile(pkg_path / "data" / "file1.txt"));
298     ASSERT_TRUE(TouchFile(pkg_path / "data" / "file2.txt"));
299   }
300 }
301
302 void ValidateDataFiles(const std::string& pkgid, uid_t uid) {
303   if (uid == kGlobalUserUid) {
304     ci::UserList list = ci::GetUserList();
305     for (auto l : list) {
306       auto pkg_path = GetPackageRoot(pkgid, std::get<0>(l));
307       ASSERT_TRUE(bf::exists(pkg_path / "data" / "file1.txt"));
308       ASSERT_TRUE(bf::exists(pkg_path / "data" / "file2.txt"));
309     }
310   } else {
311     auto pkg_path = GetPackageRoot(pkgid, uid);
312     ASSERT_TRUE(bf::exists(pkg_path / "data" / "file1.txt"));
313     ASSERT_TRUE(bf::exists(pkg_path / "data" / "file2.txt"));
314   }
315 }
316
317 void ValidatePackageRWFS(const std::string& pkgid, uid_t uid) {
318   bf::path root_path = ci::GetRootAppPath(false, uid);
319   bf::path package_path = root_path / pkgid;
320   bf::path data_path = package_path / rwDirectories[DATA];
321   bf::path cache_path = package_path / rwDirectories[CACHE];
322   bf::path shared_data_path = package_path / rwDirectories[SHARED_DATA];
323
324   ASSERT_TRUE(bf::exists(data_path));
325   ASSERT_TRUE(bf::exists(cache_path));
326
327   struct stat stats;
328   stat(data_path.c_str(), &stats);
329   // gid of RW dirs should be system_share
330   boost::optional<gid_t> system_share =
331     ci::GetGidByGroupName(kSystemShareGroupName);
332   ASSERT_EQ(uid, stats.st_uid) << "Invalid gid: " << data_path;
333   ASSERT_EQ(*system_share, stats.st_gid) << "Invalid gid: " << data_path;
334   if (bf::exists(shared_data_path)) {
335     stat(shared_data_path.c_str(), &stats);
336     ASSERT_EQ(uid, stats.st_uid) << "Invalid gid: " << shared_data_path;
337     ASSERT_EQ(*system_share, stats.st_gid) << "Invalid gid: "
338       << shared_data_path;
339   }
340
341   stat(cache_path.c_str(), &stats);
342   ASSERT_EQ(uid, stats.st_uid) << "Invalid gid: " << cache_path;
343   ASSERT_EQ(*system_share, stats.st_gid) << "Invalid gid: " << cache_path;
344 }
345
346 void ValidatePackageFS(const std::string& pkgid,
347                        const std::vector<std::string>& appids,
348                        uid_t uid, gid_t gid, bool is_readonly) {
349   bf::path root_path = ci::GetRootAppPath(is_readonly, uid);
350   bf::path package_path = root_path / pkgid;
351   bf::path shared_path = package_path / "shared";
352   ASSERT_TRUE(bf::exists(root_path));
353   ASSERT_TRUE(bf::exists(package_path));
354   ASSERT_TRUE(bf::exists(shared_path));
355
356   bf::path manifest_path =
357       bf::path(getUserManifestPath(uid, is_readonly)) / (pkgid + ".xml");
358   ASSERT_TRUE(bf::exists(manifest_path));
359
360   for (auto& appid : appids) {
361     bf::path binary_path = package_path / "bin" / appid;
362     ASSERT_TRUE(bf::exists(binary_path));
363   }
364
365   bf::path widget_root_path = package_path / "res" / "wgt";
366   bf::path config_path = widget_root_path / "config.xml";
367   ASSERT_TRUE(bf::exists(widget_root_path));
368   ASSERT_TRUE(bf::exists(config_path));
369
370   bf::path private_tmp_path = package_path / "tmp";
371   ASSERT_TRUE(bf::exists(private_tmp_path));
372
373   // backups should not exist
374   bf::path package_backup = ci::GetBackupPathForPackagePath(package_path);
375   bf::path manifest_backup = ci::GetBackupPathForManifestFile(manifest_path);
376   ASSERT_FALSE(bf::exists(package_backup));
377   ASSERT_FALSE(bf::exists(manifest_backup));
378
379   for (bf::recursive_directory_iterator iter(package_path);
380       iter != bf::recursive_directory_iterator(); ++iter) {
381     if (bf::is_symlink(symlink_status(iter->path())))
382       continue;
383     bool is_rw_dir = false;
384     for(const auto rw_dir : rwDirectories) {
385       bf::path rw_dir_path = rw_dir;
386       is_rw_dir |= ci::MakeRelativePath(iter->path(), package_path) == rw_dir_path;
387     }
388     if (is_rw_dir || iter->path().filename() == ".mmc") {
389       iter.no_push();
390       continue;
391     }
392     struct stat stats;
393     stat(iter->path().c_str(), &stats);
394     ASSERT_EQ(uid, stats.st_uid) << "Invalid uid: " << iter->path();
395     ASSERT_EQ(gid, stats.st_gid) << "Invalid gid: " << iter->path();
396   }
397 }
398
399 void PackageCheckCleanup(const std::string& pkgid,
400     const std::vector<std::string>&, bool is_readonly = false) {
401   bf::path root_path = ci::GetRootAppPath(is_readonly, kTestUserId);
402   bf::path package_path = root_path / pkgid;
403   ASSERT_FALSE(bf::exists(package_path));
404
405   bf::path manifest_path = bf::path(getUserManifestPath(kTestUserId,
406       is_readonly)) / (pkgid + ".xml");
407   ASSERT_FALSE(bf::exists(manifest_path));
408
409   // backups should not exist
410   bf::path package_backup = ci::GetBackupPathForPackagePath(package_path);
411   bf::path manifest_backup = ci::GetBackupPathForManifestFile(manifest_path);
412   ASSERT_FALSE(bf::exists(package_backup));
413   ASSERT_FALSE(bf::exists(manifest_backup));
414 }
415
416 void ValidatePackage(const std::string& pkgid,
417     const std::vector<std::string>& appids, bool is_readonly = false) {
418   ASSERT_TRUE(ci::QueryIsPackageInstalled(
419       pkgid, ci::GetRequestMode(kTestUserId), kTestUserId));
420   ValidatePackageFS(pkgid, appids, kTestUserId, kTestGroupId, is_readonly);
421   if (kTestUserId == kGlobalUserUid) {
422     ci::UserList list = ci::GetUserList();
423     for (auto& l : list)
424       ValidatePackageRWFS(pkgid, std::get<0>(l));
425   } else {
426     ValidatePackageRWFS(pkgid, kTestUserId);
427   }
428 }
429
430 void ValidateExternalPackageFS(const std::string& pkgid,
431                                const std::vector<std::string>& appids,
432                                uid_t uid, gid_t gid) {
433   ASSERT_EQ(app2ext_usr_enable_external_pkg(pkgid.c_str(), uid), 0);
434   bf::path root_path = ci::GetRootAppPath(false, uid);
435   ASSERT_TRUE(bf::exists(root_path / pkgid / ".mmc" / "res"));
436   ValidatePackageFS(pkgid, appids, uid, gid, false);
437   ASSERT_EQ(app2ext_usr_disable_external_pkg(pkgid.c_str(), uid), 0);
438 }
439
440 void ValidateExternalPackage(const std::string& pkgid,
441                              const std::vector<std::string>& appids) {
442   ASSERT_TRUE(ci::QueryIsPackageInstalled(
443       pkgid, ci::GetRequestMode(kTestUserId),
444       kTestUserId));
445   std::string storage = ci::QueryStorageForPkgId(pkgid, kTestUserId);
446   bf::path ext_mount_path = ci::GetExternalCardPath();
447   if (bf::is_empty(ext_mount_path)) {
448     LOG(INFO) << "Sdcard not exists!";
449     ASSERT_EQ(storage, "installed_internal");
450   } else {
451     ASSERT_EQ(storage, "installed_external");
452   }
453   ValidateExternalPackageFS(pkgid, appids, kTestUserId, kTestGroupId);
454   if (kTestUserId == kGlobalUserUid) {
455     ci::UserList list = ci::GetUserList();
456     for (auto& l : list)
457       ValidatePackageRWFS(pkgid, std::get<0>(l));
458   } else {
459     ValidatePackageRWFS(pkgid, kTestUserId);
460   }
461 }
462
463 void CheckPackageNonExistance(const std::string& pkgid,
464                               const std::vector<std::string>& appids) {
465   ASSERT_FALSE(ci::QueryIsPackageInstalled(
466       pkgid, ci::GetRequestMode(kTestUserId),
467       kTestUserId));
468   PackageCheckCleanup(pkgid, appids);
469   if (kTestUserId == kGlobalUserUid) {
470       ci::UserList list = ci::GetUserList();
471       bf::path skel_path(kSkelDir);
472       ASSERT_FALSE(bf::exists(skel_path / pkgid));
473       for (auto& l : list) {
474         bf::path root_path = ci::GetRootAppPath(false, std::get<0>(l));
475         bf::path package_path = root_path / pkgid;
476         ASSERT_FALSE(bf::exists(package_path));
477       }
478   }
479 }
480
481 void CheckPackageReadonlyNonExistance(const std::string& pkgid,
482                                       const std::vector<std::string>& appids) {
483   ASSERT_FALSE(ci::QueryIsPackageInstalled(
484       pkgid, ci::GetRequestMode(kTestUserId), kTestUserId));
485   PackageCheckCleanup(pkgid, appids, true);
486 }
487
488 std::unique_ptr<ci::AppQueryInterface> CreateQueryInterface() {
489   std::unique_ptr<ci::AppQueryInterface> query_interface(
490       new wgt::WgtAppQueryInterface());
491   return query_interface;
492 }
493
494 std::unique_ptr<ci::AppInstaller> CreateInstaller(ci::PkgMgrPtr pkgmgr,
495                                                   PackageType type) {
496   switch (type) {
497     case PackageType::WGT:
498       return std::unique_ptr<ci::AppInstaller>(new wgt::WgtInstaller(pkgmgr));
499     case PackageType::HYBRID:
500       return std::unique_ptr<ci::AppInstaller>(
501           new hybrid::HybridInstaller(pkgmgr));
502     default:
503       LOG(ERROR) << "Unknown installer type";
504       return nullptr;
505   }
506 }
507
508 ci::AppInstaller::Result RunInstallerWithPkgrmgr(ci::PkgMgrPtr pkgmgr,
509                                                  PackageType type,
510                                                  RequestResult mode) {
511   std::unique_ptr<ci::AppInstaller> installer = CreateInstaller(pkgmgr, type);
512   switch (mode) {
513   case RequestResult::FAIL:
514     installer->AddStep<ci::configuration::StepFail>();
515     break;
516   default:
517     break;
518   }
519   return installer->Run();
520 }
521 ci::AppInstaller::Result CallBackend(int argc,
522                                      const char* argv[],
523                                      PackageType type,
524                                      RequestResult mode = RequestResult::NORMAL
525                                      ) {
526   TestPkgmgrInstaller pkgmgr_installer;
527   std::unique_ptr<ci::AppQueryInterface> query_interface =
528       CreateQueryInterface();
529   auto pkgmgr =
530       ci::PkgMgrInterface::Create(argc, const_cast<char**>(argv),
531                                   &pkgmgr_installer, query_interface.get());
532   if (!pkgmgr) {
533     LOG(ERROR) << "Failed to initialize pkgmgr interface";
534     return ci::AppInstaller::Result::UNKNOWN;
535   }
536   return RunInstallerWithPkgrmgr(pkgmgr, type, mode);
537 }
538
539 ci::AppInstaller::Result Install(const bf::path& path,
540                                  PackageType type,
541                                  RequestResult mode = RequestResult::NORMAL) {
542   const char* argv[] = {"", "-i", path.c_str(), "-u", kTestUserIdStr.c_str()};
543   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
544 }
545
546 ci::AppInstaller::Result InstallPreload(const bf::path& path, PackageType type,
547     RequestResult mode = RequestResult::NORMAL) {
548   const char* argv[] = {"", "-i", path.c_str(), "--preload"};
549   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
550 }
551
552 bool CheckAvailableExternalPath() {
553   bf::path ext_mount_path = ci::GetExternalCardPath();
554   LOG(DEBUG) << "ext_mount_path :" << ext_mount_path;
555   if (ext_mount_path.empty()) {
556     LOG(ERROR) << "Sdcard not exists!";
557     return false;
558   }
559   return true;
560 }
561
562 ci::AppInstaller::Result InstallExternal(const bf::path& path,
563                                  PackageType type,
564                                  RequestResult mode = RequestResult::NORMAL) {
565   int default_storage = 0;
566   vconf_get_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT,
567                 &default_storage);
568   vconf_set_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT, 1);
569
570   const char* argv[] = {"", "-i", path.c_str(), "-u", kTestUserIdStr.c_str()};
571   ci::AppInstaller::Result result =
572                           CallBackend(SIZEOFARRAY(argv), argv, type, mode);
573
574   vconf_set_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT,
575                 default_storage);
576   return result;
577 }
578
579 ci::AppInstaller::Result MigrateLegacyExternalImage(const std::string& pkgid,
580                                  const bf::path& path,
581                                  const bf::path& legacy_path,
582                                  PackageType type,
583                                  RequestResult mode = RequestResult::NORMAL) {
584   if (InstallExternal(path, type) != ci::AppInstaller::Result::OK) {
585     LOG(ERROR) << "Failed to install application. Cannot perform Migrate";
586     return ci::AppInstaller::Result::ERROR;
587   }
588
589   bf::path ext_mount_path = ci::GetExternalCardPath();
590   if (bf::is_empty(ext_mount_path)) {
591     LOG(ERROR) << "Sdcard not exists!";
592     return ci::AppInstaller::Result::ERROR;
593   }
594   bf::path app2sd_path = ext_mount_path / "app2sd";
595
596   char* image_name = app2ext_usr_getname_image(pkgid.c_str(),
597                      kGlobalUserUid);
598   if (!image_name) {
599     LOG(ERROR) << "Failed to get external image name";
600     return ci::AppInstaller::Result::ERROR;
601   }
602   bf::path org_image = app2sd_path / image_name;
603   free(image_name);
604
605   bs::error_code error;
606   bf::remove(org_image, error);
607   if (error) {
608     LOG(ERROR) << "Failed to remove org image";
609     return ci::AppInstaller::Result::ERROR;
610   }
611
612   bf::path db_path = tzplatform_getenv(TZ_SYS_DB);
613   bf::path app2sd_db = db_path / ".app2sd.db";
614   bf::path app2sd_db_journal = db_path / ".app2sd.db-journal";
615   bf::remove(app2sd_db, error);
616   if (error) {
617     LOG(ERROR) << "Failed to remove app2sd db";
618     return ci::AppInstaller::Result::ERROR;
619   }
620   bf::remove(app2sd_db_journal, error);
621   if (error) {
622     LOG(ERROR) << "Failed to remove app2sd journal db";
623     return ci::AppInstaller::Result::ERROR;
624   }
625
626   bf::path app2sd_migrate_db = legacy_path / kMigrateTestDBName;
627   if (!ci::CopyFile(app2sd_migrate_db, app2sd_db)) {
628     LOG(ERROR) << "Failed to copy test db";
629     return ci::AppInstaller::Result::ERROR;
630   }
631
632   bf::path legacy_src = legacy_path / pkgid;
633   bf::path legacy_dst = app2sd_path / pkgid;
634   if (!ci::CopyFile(legacy_src, legacy_dst)) {
635     LOG(ERROR) << "Failed to copy test image";
636     return ci::AppInstaller::Result::ERROR;
637   }
638   const char* argv[] = {"", "--migrate-extimg", pkgid.c_str(),
639                        "-u", kDefaultUserIdStr.c_str()};
640   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
641 }
642
643 ci::AppInstaller::Result MountInstall(const bf::path& path,
644     PackageType type, RequestResult mode = RequestResult::NORMAL) {
645   const char* argv[] = {"", "-w", path.c_str(), "-u", kTestUserIdStr.c_str()};
646   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
647 }
648
649 ci::AppInstaller::Result Uninstall(const std::string& pkgid,
650                                    PackageType type,
651                                    bool is_preload,
652                                    RequestResult mode = RequestResult::NORMAL) {
653   if (is_preload) {
654     const char* argv[] = {"", "-d", pkgid.c_str(), "--preload",
655         "--force-remove"};
656     return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
657   } else {
658     const char* argv[] = {"", "-d", pkgid.c_str(), "-u",
659         kTestUserIdStr.c_str()};
660     return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
661   }
662 }
663
664 ci::AppInstaller::Result RDSUpdate(const bf::path& path,
665                                    const std::string& pkgid,
666                                    PackageType type,
667                                    RequestResult mode = RequestResult::NORMAL) {
668   if (Install(path, type) != ci::AppInstaller::Result::OK) {
669     LOG(ERROR) << "Failed to install application. Cannot perform RDS";
670     return ci::AppInstaller::Result::UNKNOWN;
671   }
672   const char* argv[] = {"", "-r", pkgid.c_str(), "-u",
673                         kTestUserIdStr.c_str()};
674   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
675 }
676
677 ci::AppInstaller::Result DeltaInstall(const bf::path& path,
678     const bf::path& delta_package, PackageType type) {
679   if (Install(path, type) != ci::AppInstaller::Result::OK) {
680     LOG(ERROR) << "Failed to install application. Cannot perform delta update";
681     return ci::AppInstaller::Result::UNKNOWN;
682   }
683   return Install(delta_package, type);
684 }
685
686 ci::AppInstaller::Result EnablePackage(const std::string& pkgid,
687                                   PackageType type,
688                                   RequestResult mode = RequestResult::NORMAL) {
689   const char* argv[] = {"", "-A", pkgid.c_str(), "-u", kTestUserIdStr.c_str()};
690   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
691 }
692
693 ci::AppInstaller::Result DisablePackage(const std::string& pkgid,
694                                   PackageType type,
695                                   RequestResult mode = RequestResult::NORMAL) {
696   const char* argv[] = {"", "-D", pkgid.c_str(), "-u", kTestUserIdStr.c_str()};
697   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
698 }
699
700 ci::AppInstaller::Result Recover(const bf::path& recovery_file,
701                                  PackageType type,
702                                  RequestResult mode = RequestResult::NORMAL) {
703   const char* argv[] = {"", "-b", recovery_file.c_str(), "-u",
704                         kTestUserIdStr.c_str()};
705   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
706 }
707
708 void BackupPath(const bf::path& path) {
709   bf::path backup_path = path.string() + ".bck";
710   std::cout << "Backup path: " << path << " to " << backup_path << std::endl;
711   bs::error_code error;
712   bf::remove_all(backup_path, error);
713   if (error)
714     LOG(ERROR) << "Remove failed: " << backup_path
715                << " (" << error.message() << ")";
716   if (bf::exists(path)) {
717     bf::rename(path, backup_path, error);
718     if (error)
719       LOG(ERROR) << "Failed to setup test environment. Does some previous"
720                  << " test crashed? Path: "
721                  << backup_path << " should not exist.";
722     assert(!error);
723   }
724 }
725
726 void RestorePath(const bf::path& path) {
727   bf::path backup_path = path.string() + ".bck";
728   std::cout << "Restore path: " << path << " from " << backup_path << std::endl;
729   bs::error_code error;
730   bf::remove_all(path, error);
731   if (error)
732     LOG(ERROR) << "Remove failed: " << path
733                << " (" << error.message() << ")";
734   if (bf::exists(backup_path)) {
735     bf::rename(backup_path, path, error);
736     if (error)
737       LOG(ERROR) << "Failed to restore backup path: " << backup_path
738                  << " (" << error.message() << ")";
739   }
740 }
741
742 std::vector<bf::path> SetupBackupDirectories() {
743   std::vector<bf::path> entries;
744   bf::path db_dir = bf::path(tzplatform_getenv(TZ_SYS_DB));
745   if (kTestUserId != kGlobalUserUid)
746     db_dir = db_dir / "user" / std::to_string(kTestUserId);
747   for (auto e : kDBEntries) {
748     bf::path path = db_dir / e;
749     entries.emplace_back(path);
750   }
751
752   if (getuid() == 0) {
753     entries.emplace_back(kPreloadApps);
754     entries.emplace_back(kPreloadManifestDir);
755     entries.emplace_back(kPreloadIcons);
756   }
757
758   if (kTestUserId == kGlobalUserUid) {
759     entries.emplace_back(kSkelDir);
760     entries.emplace_back(kGlobalManifestDir);
761     ci::UserList list = ci::GetUserList();
762     for (auto l : list) {
763       bf::path apps = std::get<2>(l) / "apps_rw";
764       entries.emplace_back(apps);
765     }
766   } else {
767     tzplatform_set_user(kTestUserId);
768     bf::path approot = tzplatform_getenv(TZ_USER_APPROOT);
769     tzplatform_reset_user();
770     entries.emplace_back(approot);
771   }
772
773   bf::path apps_rw = ci::GetRootAppPath(false, kTestUserId);
774   entries.emplace_back(apps_rw);
775
776   return entries;
777 }
778
779 void UninstallAllAppsInDirectory(bf::path dir, bool is_preload) {
780   if(bf::exists(dir)) {
781     for (auto& dir_entry : boost::make_iterator_range(
782         bf::directory_iterator(dir), bf::directory_iterator())) {
783       if (dir_entry.path().string().find("smoke") != std::string::npos &&
784           bf::is_directory(dir_entry)) {
785         std::string package = dir_entry.path().filename().string();
786         std::regex pkg_regex("smoke[a-zA-Z]{3,}[1-9]{2,}");
787         if (std::regex_match(package, pkg_regex)) {
788           if(Uninstall(dir_entry.path().filename().string(), PackageType::WGT,
789               is_preload, RequestResult::NORMAL) !=
790               ci::AppInstaller::Result::OK) {
791             LOG(ERROR) << "Cannot uninstall smoke test app: "
792                 << dir_entry.path().filename().string();
793           }
794         }
795       }
796     }
797   }
798 }
799
800 void UninstallAllSmokeApps() {
801   if (getuid() == 0 && kRequestMode == ci::RequestMode::GLOBAL) {
802     bf::path root_path = kPreloadApps;
803     UninstallAllAppsInDirectory(root_path, true);
804   }
805   bf::path apps_rw = ci::GetRootAppPath(false, kTestUserId);
806   UninstallAllAppsInDirectory(apps_rw, false);
807 }
808
809 }  // namespace
810
811 namespace common_installer {
812
813 class SmokeEnvironment : public testing::Environment {
814  public:
815   explicit SmokeEnvironment() {
816   }
817   void SetUp() override {
818     if (kRequestMode == ci::RequestMode::USER)
819       ASSERT_TRUE(AddTestUser(kNormalUserName));
820     else {
821       kTestUserId = kGlobalUserUid;
822       kTestGroupId = kGlobalUserGid;
823       kTestUserIdStr = std::to_string(kTestUserId);
824     }
825     backups_ = SetupBackupDirectories();
826     for (auto& path : backups_)
827       BackupPath(path);
828   }
829   void TearDown() override {
830     ASSERT_TRUE(kRequestMode == ci::RequestMode::GLOBAL ||
831                 (kRequestMode == ci::RequestMode::USER &&
832                 kGlobalUserUid != kTestUserId));
833     UninstallAllSmokeApps();
834     for (auto& path : backups_)
835       RestorePath(path);
836     if (kRequestMode == ci::RequestMode::USER)
837       ASSERT_TRUE(DeleteTestUser(kNormalUserName));
838   }
839
840  private:
841   std::vector<bf::path> backups_;
842 };
843
844 class SmokeTest : public testing::Test {
845 };
846
847 class PreloadSmokeTest : public testing::Test {
848   void SetUp() override {
849     ASSERT_TRUE(kRequestMode == ci::RequestMode::GLOBAL);
850   }
851 };
852
853 TEST_F(SmokeTest, InstallationMode) {
854   bf::path path = kSmokePackagesDirectory / "InstallationMode.wgt";
855   std::string pkgid = "smokewgt03";
856   std::string appid = "smokewgt03.InstallationMode";
857   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
858   ValidatePackage(pkgid, {appid});
859 }
860
861 TEST_F(SmokeTest, UpdateMode) {
862   bf::path path_old = kSmokePackagesDirectory / "UpdateMode.wgt";
863   bf::path path_new = kSmokePackagesDirectory / "UpdateMode_2.wgt";
864   std::string pkgid = "smokewgt04";
865   std::string appid = "smokewgt04.UpdateMode";
866   ASSERT_EQ(Install(path_old, PackageType::WGT), ci::AppInstaller::Result::OK);
867   AddDataFiles(pkgid, kTestUserId);
868   ASSERT_EQ(Install(path_new, PackageType::WGT), ci::AppInstaller::Result::OK);
869   ValidatePackage(pkgid, {appid});
870
871   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n"));
872   ValidateDataFiles(pkgid, kTestUserId);
873 }
874
875 TEST_F(SmokeTest, DeinstallationMode) {
876   bf::path path = kSmokePackagesDirectory / "DeinstallationMode.wgt";
877   std::string pkgid = "smokewgt05";
878   std::string appid = "smokewgt05.DeinstallationMode";
879   ASSERT_EQ(Install(path, PackageType::WGT),
880             ci::AppInstaller::Result::OK);
881   ASSERT_EQ(Uninstall(pkgid, PackageType::WGT, false),
882             ci::AppInstaller::Result::OK);
883   CheckPackageNonExistance(pkgid, {appid});
884 }
885
886 TEST_F(SmokeTest, RDSMode) {
887   bf::path path = kSmokePackagesDirectory / "RDSMode.wgt";
888   std::string pkgid = "smokewgt11";
889   std::string appid = "smokewgt11.RDSMode";
890   bf::path delta_directory = kSmokePackagesDirectory / "delta_dir/";
891   bf::path sdk_expected_directory =
892       bf::path(ci::GetRootAppPath(false, kTestUserId)) / "tmp" / pkgid;
893   bs::error_code error;
894   bf::create_directories(sdk_expected_directory.parent_path(), error);
895   ASSERT_FALSE(error);
896   ASSERT_TRUE(CopyDir(delta_directory, sdk_expected_directory));
897   ASSERT_EQ(RDSUpdate(path, pkgid, PackageType::WGT),
898             ci::AppInstaller::Result::OK);
899   ValidatePackage(pkgid, {appid});
900
901   // Check delta modifications
902   ASSERT_FALSE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
903       "res" / "wgt" / "DELETED"));
904   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
905       "res" / "wgt" / "ADDED"));
906   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED", "2\n"));
907 }
908
909 TEST_F(SmokeTest, EnablePkg) {
910   bf::path path = kSmokePackagesDirectory / "EnablePkg.wgt";
911   std::string pkgid = "smokewgt22";
912   ASSERT_EQ(Install(path, PackageType::WGT),
913             ci::AppInstaller::Result::OK);
914   ASSERT_EQ(DisablePackage(pkgid, PackageType::WGT),
915             ci::AppInstaller::Result::OK);
916   ASSERT_EQ(EnablePackage(pkgid, PackageType::WGT),
917             ci::AppInstaller::Result::OK);
918
919   ASSERT_TRUE(ci::QueryIsPackageInstalled(pkgid,
920       ci::GetRequestMode(kTestUserId),
921       kTestUserId));
922 }
923
924 TEST_F(SmokeTest, DisablePkg) {
925   bf::path path = kSmokePackagesDirectory / "DisablePkg.wgt";
926   std::string pkgid = "smokewgt21";
927   std::string appid = "smokewgt21.DisablePkg";
928   ASSERT_EQ(Install(path, PackageType::WGT),
929             ci::AppInstaller::Result::OK);
930   ASSERT_EQ(DisablePackage(pkgid, PackageType::WGT),
931             ci::AppInstaller::Result::OK);
932   ASSERT_TRUE(ci::QueryIsDisabledPackage(pkgid, kTestUserId));
933   ValidatePackage(pkgid, {appid});
934 }
935
936 TEST_F(SmokeTest, DeltaMode) {
937   bf::path path = kSmokePackagesDirectory / "DeltaMode.wgt";
938   bf::path delta_package = kSmokePackagesDirectory / "DeltaMode.delta";
939   std::string pkgid = "smokewgt17";
940   std::string appid = "smokewgt17.DeltaMode";
941   ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::WGT),
942             ci::AppInstaller::Result::OK);
943   ValidatePackage(pkgid, {appid});
944
945   // Check delta modifications
946   ASSERT_FALSE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
947       "res" / "wgt" / "DELETED"));
948   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
949       "res" / "wgt" / "ADDED"));
950   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
951       "res" / "wgt" / "css" / "style.css"));
952   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
953       "res" / "wgt" / "images" / "tizen_32.png"));
954   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
955       "res" / "wgt" / "js" / "main.js"));
956   ASSERT_TRUE(ValidateFileContentInPackage(
957       pkgid, "res/wgt/MODIFIED", "version 2\n"));
958 }
959
960 TEST_F(SmokeTest, RecoveryMode_ForInstallation) {
961   bf::path path = kSmokePackagesDirectory / "RecoveryMode_ForInstallation.wgt";
962   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
963   backend_crash.Run("-i", path.string(), "-u", kTestUserIdStr.c_str());
964   ASSERT_NE(backend_crash.Wait(), 0);
965
966   std::string pkgid = "smokewgt09";
967   std::string appid = "smokewgt09.RecoveryModeForInstallation";
968   bf::path recovery_file = FindRecoveryFile();
969   ASSERT_FALSE(recovery_file.empty());
970   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
971       ci::AppInstaller::Result::OK);
972   CheckPackageNonExistance(pkgid, {appid});
973 }
974
975 TEST_F(SmokeTest, RecoveryMode_ForUpdate) {
976   bf::path path_old = kSmokePackagesDirectory / "RecoveryMode_ForUpdate.wgt";
977   bf::path path_new = kSmokePackagesDirectory / "RecoveryMode_ForUpdate_2.wgt";
978   RemoveAllRecoveryFiles();
979   ASSERT_EQ(Install(path_old, PackageType::WGT), ci::AppInstaller::Result::OK);
980   std::string pkgid = "smokewgt10";
981   std::string appid = "smokewgt10.RecoveryModeForUpdate";
982   AddDataFiles(pkgid, kTestUserId);
983   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
984   backend_crash.Run("-i", path_new.string(), "-u", kTestUserIdStr.c_str());
985   ASSERT_NE(backend_crash.Wait(), 0);
986
987   bf::path recovery_file = FindRecoveryFile();
988   ASSERT_FALSE(recovery_file.empty());
989   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
990             ci::AppInstaller::Result::OK);
991   ValidatePackage(pkgid, {appid});
992
993   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
994   ValidateDataFiles(pkgid, kTestUserId);
995 }
996
997 TEST_F(SmokeTest, RecoveryMode_ForDelta) {
998   bf::path path_old = kSmokePackagesDirectory / "RecoveryMode_ForDelta.wgt";
999   bf::path path_new = kSmokePackagesDirectory / "RecoveryMode_ForDelta.delta";
1000   RemoveAllRecoveryFiles();
1001   ASSERT_EQ(Install(path_old, PackageType::WGT), ci::AppInstaller::Result::OK);
1002   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
1003   backend_crash.Run("-i", path_new.string(), "-u", kTestUserIdStr.c_str());
1004   ASSERT_NE(backend_crash.Wait(), 0);
1005
1006   std::string pkgid = "smokewgt30";
1007   std::string appid = "smokewgt30.RecoveryModeForDelta";
1008   bf::path recovery_file = FindRecoveryFile();
1009   ASSERT_FALSE(recovery_file.empty());
1010   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
1011             ci::AppInstaller::Result::OK);
1012   ValidatePackage(pkgid, {appid});
1013
1014   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
1015 }
1016
1017 TEST_F(SmokeTest, RecoveryMode_ForMountInstall) {
1018   bf::path path = kSmokePackagesDirectory / "RecoveryMode_ForMountInstall.wgt";
1019   RemoveAllRecoveryFiles();
1020   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
1021   backend_crash.Run("-w", path.string(), "-u", kTestUserIdStr.c_str());
1022   ASSERT_NE(backend_crash.Wait(), 0);
1023
1024   std::string pkgid = "smokewgt31";
1025   std::string appid = "smokewgt31.RecoveryModeForMountInstall";
1026   bf::path recovery_file = FindRecoveryFile();
1027   ASSERT_FALSE(recovery_file.empty());
1028   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
1029             ci::AppInstaller::Result::OK);
1030   CheckPackageNonExistance(pkgid, {appid});
1031 }
1032
1033 TEST_F(SmokeTest, RecoveryMode_ForMountUpdate) {
1034   bf::path path_old =
1035       kSmokePackagesDirectory / "RecoveryMode_ForMountUpdate.wgt";
1036   bf::path path_new =
1037       kSmokePackagesDirectory / "RecoveryMode_ForMountUpdate_2.wgt";
1038   std::string pkgid = "smokewgt32";
1039   std::string appid = "smokewgt32.RecoveryModeForMountUpdate";
1040   RemoveAllRecoveryFiles();
1041   ASSERT_EQ(MountInstall(path_old, PackageType::WGT),
1042             ci::AppInstaller::Result::OK);
1043   AddDataFiles(pkgid, kTestUserId);
1044   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
1045   backend_crash.Run("-w", path_new.string(), "-u", kTestUserIdStr.c_str());
1046   ASSERT_NE(backend_crash.Wait(), 0);
1047
1048   // Filesystem may be mounted after crash
1049   ScopedTzipInterface poweroff_unmount_interface(pkgid);
1050   poweroff_unmount_interface.Release();
1051
1052   bf::path recovery_file = FindRecoveryFile();
1053   ASSERT_FALSE(recovery_file.empty());
1054   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
1055             ci::AppInstaller::Result::OK);
1056
1057   ScopedTzipInterface interface(pkgid);
1058   ValidatePackage(pkgid, {appid});
1059   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
1060   ValidateDataFiles(pkgid, kTestUserId);
1061 }
1062
1063 TEST_F(SmokeTest, InstallationMode_GoodSignature) {
1064   bf::path path = kSmokePackagesDirectory / "InstallationMode_GoodSignature.wgt";  // NOLINT
1065   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
1066 }
1067
1068 TEST_F(SmokeTest, InstallationMode_WrongSignature) {
1069   bf::path path = kSmokePackagesDirectory / "InstallationMode_WrongSignature.wgt";  // NOLINT
1070   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::ERROR);
1071 }
1072
1073 TEST_F(SmokeTest, InstallationMode_Rollback) {
1074   bf::path path = kSmokePackagesDirectory / "InstallationMode_Rollback.wgt";
1075   std::string pkgid = "smokewgt06";
1076   std::string appid = "smokewgt06.InstallationModeRollback";
1077   ASSERT_EQ(Install(path, PackageType::WGT, RequestResult::FAIL),
1078             ci::AppInstaller::Result::ERROR);
1079   CheckPackageNonExistance(pkgid, {appid});
1080 }
1081
1082 TEST_F(SmokeTest, UpdateMode_Rollback) {
1083   bf::path path_old = kSmokePackagesDirectory / "UpdateMode_Rollback.wgt";
1084   bf::path path_new = kSmokePackagesDirectory / "UpdateMode_Rollback_2.wgt";
1085   std::string pkgid = "smokewgt07";
1086   std::string appid = "smokewgt07.UpdateModeRollback";
1087   ASSERT_EQ(Install(path_old, PackageType::WGT), ci::AppInstaller::Result::OK);
1088   AddDataFiles(pkgid, kTestUserId);
1089   ASSERT_EQ(Install(path_new, PackageType::WGT, RequestResult::FAIL),
1090                     ci::AppInstaller::Result::ERROR);
1091   ValidatePackage(pkgid, {appid});
1092
1093   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
1094   ValidateDataFiles(pkgid, kTestUserId);
1095 }
1096
1097 TEST_F(SmokeTest, DeltaMode_Rollback) {
1098   bf::path path = kSmokePackagesDirectory / "DeltaMode_Rollback.wgt";
1099   bf::path delta_package = kSmokePackagesDirectory / "DeltaMode_Rollback.delta";
1100   std::string pkgid = "smokewgt01";
1101   std::string appid = "smokewgt01.DeltaMode";
1102   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
1103   AddDataFiles(pkgid, kTestUserId);
1104   ASSERT_EQ(Install(delta_package, PackageType::WGT, RequestResult::FAIL),
1105             ci::AppInstaller::Result::ERROR);
1106
1107   ValidatePackage(pkgid, {appid});
1108   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED",
1109                                            "version 1\n"));
1110   ValidateDataFiles(pkgid, kTestUserId);
1111   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
1112                          "res/wgt/DELETED"));
1113   ASSERT_FALSE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
1114                           "res/wgt/ADDED"));
1115 }
1116
1117 TEST_F(SmokeTest, InstallationMode_Hybrid) {
1118   bf::path path = kSmokePackagesDirectory / "InstallationMode_Hybrid.wgt";
1119   std::string pkgid = "smokehyb01";
1120   // Excutable for native app doesn't create symlink
1121   std::string appid1 = "smokehyb01.Web";
1122   ASSERT_EQ(Install(path, PackageType::HYBRID), ci::AppInstaller::Result::OK);
1123   ValidatePackage(pkgid, {appid1});
1124 }
1125
1126 TEST_F(SmokeTest, UpdateMode_Hybrid) {
1127   bf::path path_old = kSmokePackagesDirectory / "UpdateMode_Hybrid.wgt";
1128   bf::path path_new = kSmokePackagesDirectory / "UpdateMode_Hybrid_2.wgt";
1129   std::string pkgid = "smokehyb02";
1130   std::string appid1 = "smokehyb02.Web";
1131   ASSERT_EQ(Install(path_old, PackageType::HYBRID),
1132             ci::AppInstaller::Result::OK);
1133 //  AddDataFiles(pkgid, kTestUserId);
1134   ASSERT_EQ(Install(path_new, PackageType::HYBRID),
1135             ci::AppInstaller::Result::OK);
1136   ValidatePackage(pkgid, {appid1});
1137
1138   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n"));
1139   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "VERSION", "2\n"));
1140 //  ValidateDataFiles(pkgid, kTestUserId);
1141 }
1142
1143 TEST_F(SmokeTest, DeinstallationMode_Hybrid) {
1144   bf::path path = kSmokePackagesDirectory / "DeinstallationMode_Hybrid.wgt";
1145   std::string pkgid = "smokehyb03";
1146   std::string appid1 = "smokehyb03.Web";
1147   ASSERT_EQ(Install(path, PackageType::HYBRID),
1148             ci::AppInstaller::Result::OK);
1149   ASSERT_EQ(Uninstall(pkgid, PackageType::HYBRID, false),
1150             ci::AppInstaller::Result::OK);
1151   CheckPackageNonExistance(pkgid, {appid1});
1152 }
1153
1154 TEST_F(SmokeTest, DeltaMode_Hybrid) {
1155   bf::path path = kSmokePackagesDirectory / "DeltaMode_Hybrid.wgt";
1156   bf::path delta_package = kSmokePackagesDirectory / "DeltaMode_Hybrid.delta";
1157   std::string pkgid = "smokehyb04";
1158   std::string appid1 = "smokehyb04.Web";
1159   ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::HYBRID),
1160             ci::AppInstaller::Result::OK);
1161   ValidatePackage(pkgid, {appid1});
1162
1163   // Check delta modifications
1164   bf::path root_path = ci::GetRootAppPath(false,
1165       kTestUserId);
1166   ASSERT_FALSE(bf::exists(root_path / pkgid / "res" / "wgt" / "DELETED"));
1167   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "ADDED"));
1168   ASSERT_FALSE(bf::exists(root_path / pkgid / "lib" / "DELETED"));
1169   ASSERT_TRUE(bf::exists(root_path / pkgid / "lib" / "ADDED"));
1170   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "css" / "style.css"));  // NOLINT
1171   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "images" / "tizen_32.png"));  // NOLINT
1172   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "js" / "main.js"));
1173   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED", "version 2\n"));  // NOLINT
1174   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/MODIFIED", "version 2\n"));  // NOLINT
1175 }
1176
1177 TEST_F(SmokeTest, MountInstallationMode_Hybrid) {
1178   bf::path path = kSmokePackagesDirectory / "MountInstallationMode_Hybrid.wgt";
1179   std::string pkgid = "smokehyb05";
1180   std::string appid1 = "smokehyb05.web";
1181   ASSERT_EQ(MountInstall(path, PackageType::HYBRID),
1182             ci::AppInstaller::Result::OK);
1183   ScopedTzipInterface interface(pkgid);
1184   ValidatePackage(pkgid, {appid1});
1185 }
1186
1187 TEST_F(SmokeTest, MountUpdateMode_Hybrid) {
1188   bf::path path_old = kSmokePackagesDirectory / "MountUpdateMode_Hybrid.wgt";
1189   bf::path path_new = kSmokePackagesDirectory / "MountUpdateMode_Hybrid_2.wgt";
1190   std::string pkgid = "smokehyb06";
1191   std::string appid1 = "smokehyb06.web";
1192   ASSERT_EQ(MountInstall(path_old, PackageType::HYBRID),
1193             ci::AppInstaller::Result::OK);
1194   AddDataFiles(pkgid, kTestUserId);
1195   ASSERT_EQ(MountInstall(path_new, PackageType::HYBRID),
1196             ci::AppInstaller::Result::OK);
1197   ScopedTzipInterface interface(pkgid);
1198   ValidatePackage(pkgid, {appid1});
1199
1200   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n"));
1201   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/VERSION", "2\n"));
1202   ValidateDataFiles(pkgid, kTestUserId);
1203 }
1204
1205 TEST_F(SmokeTest, InstallationMode_Rollback_Hybrid) {
1206   bf::path path = kSmokePackagesDirectory /
1207       "InstallationMode_Rollback_Hybrid.wgt";
1208   std::string pkgid = "smokehyb07";
1209   std::string appid1 = "smokehyb07.web";
1210   ASSERT_EQ(Install(path, PackageType::HYBRID, RequestResult::FAIL),
1211             ci::AppInstaller::Result::ERROR);
1212   CheckPackageNonExistance(pkgid, {appid1});
1213 }
1214
1215 TEST_F(SmokeTest, UpdateMode_Rollback_Hybrid) {
1216   bf::path path_old = kSmokePackagesDirectory /
1217       "UpdateMode_Rollback_Hybrid.wgt";
1218   bf::path path_new = kSmokePackagesDirectory /
1219       "UpdateMode_Rollback_Hybrid_2.wgt";
1220   std::string pkgid = "smokehyb08";
1221   std::string appid1 = "smokehyb08.web";
1222   ASSERT_EQ(Install(path_old, PackageType::HYBRID),
1223             ci::AppInstaller::Result::OK);
1224   AddDataFiles(pkgid, kTestUserId);
1225   ASSERT_EQ(Install(path_new, PackageType::HYBRID,
1226       RequestResult::FAIL), ci::AppInstaller::Result::ERROR);
1227   ValidatePackage(pkgid, {appid1});
1228
1229   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
1230   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/VERSION", "1\n"));
1231   ValidateDataFiles(pkgid, kTestUserId);
1232 }
1233
1234 TEST_F(SmokeTest, DeltaMode_Rollback_Hybrid) {
1235   bf::path path = kSmokePackagesDirectory / "DeltaMode_Rollback_Hybrid.wgt";
1236   bf::path delta_package = kSmokePackagesDirectory /
1237       "DeltaMode_Rollback_Hybrid.delta";
1238   std::string pkgid = "smokehyb11";
1239   std::string appid1 = "smokehyb11.web";
1240   ASSERT_EQ(Install(path, PackageType::HYBRID), ci::AppInstaller::Result::OK);
1241   AddDataFiles(pkgid, kTestUserId);
1242   ASSERT_EQ(Install(delta_package, PackageType::HYBRID, RequestResult::FAIL),
1243             ci::AppInstaller::Result::ERROR);
1244
1245   ValidatePackage(pkgid, {appid1});
1246   // Check delta modifications
1247   bf::path root_path = GetPackageRoot(pkgid, kTestUserId);
1248   ASSERT_TRUE(bf::exists(root_path / "res" / "wgt" / "DELETED"));
1249   ASSERT_FALSE(bf::exists(root_path / "res" / "wgt" / "ADDED"));
1250   ASSERT_TRUE(bf::exists(root_path / "lib" / "DELETED"));
1251   ASSERT_FALSE(bf::exists(root_path / "lib" / "ADDED"));
1252   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED",
1253                                            "version 1\n"));
1254   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/MODIFIED",
1255                                            "version 1\n"));
1256   ValidateDataFiles(pkgid, kTestUserId);
1257 }
1258
1259 TEST_F(SmokeTest, MountInstallationMode_Rollback_Hybrid) {
1260   bf::path path = kSmokePackagesDirectory /
1261       "MountInstallationMode_Rollback_Hybrid.wgt";
1262   std::string pkgid = "smokehyb09";
1263   std::string appid1 = "smokehyb09.web";
1264   ASSERT_EQ(MountInstall(path, PackageType::HYBRID, RequestResult::FAIL),
1265       ci::AppInstaller::Result::ERROR);
1266   ScopedTzipInterface interface(pkgid);
1267   CheckPackageNonExistance(pkgid, {appid1});
1268 }
1269
1270 TEST_F(SmokeTest, MountUpdateMode_Rollback_Hybrid) {
1271   bf::path path_old = kSmokePackagesDirectory /
1272       "MountUpdateMode_Rollback_Hybrid.wgt";
1273   bf::path path_new = kSmokePackagesDirectory /
1274       "MountUpdateMode_Rollback_Hybrid_2.wgt";
1275   std::string pkgid = "smokehyb10";
1276   std::string appid1 = "smokehyb10.web";
1277   ASSERT_EQ(MountInstall(path_old, PackageType::HYBRID),
1278             ci::AppInstaller::Result::OK);
1279   AddDataFiles(pkgid, kTestUserId);
1280   ASSERT_EQ(MountInstall(path_new, PackageType::HYBRID,
1281       RequestResult::FAIL), ci::AppInstaller::Result::ERROR);
1282   ScopedTzipInterface interface(pkgid);
1283   ValidatePackage(pkgid, {appid1});
1284
1285   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
1286   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/VERSION", "1\n"));
1287   ValidateDataFiles(pkgid, kTestUserId);
1288 }
1289
1290 TEST_F(SmokeTest, MountInstallationMode) {
1291   bf::path path = kSmokePackagesDirectory / "MountInstallationMode.wgt";
1292   std::string pkgid = "smokewgt28";
1293   std::string appid = "smokewgt28.InstallationMode";
1294   ASSERT_EQ(MountInstall(path, PackageType::WGT), ci::AppInstaller::Result::OK);
1295   ScopedTzipInterface interface(pkgid);
1296   ValidatePackage(pkgid, {appid});
1297 }
1298
1299 TEST_F(SmokeTest, MountUpdateMode) {
1300   bf::path path_old = kSmokePackagesDirectory / "MountUpdateMode.wgt";
1301   bf::path path_new = kSmokePackagesDirectory / "MountUpdateMode_2.wgt";
1302   std::string pkgid = "smokewgt29";
1303   std::string appid = "smokewgt29.UpdateMode";
1304   ASSERT_EQ(MountInstall(path_old, PackageType::WGT),
1305             ci::AppInstaller::Result::OK);
1306   AddDataFiles(pkgid, kTestUserId);
1307   ASSERT_EQ(MountInstall(path_new, PackageType::WGT),
1308             ci::AppInstaller::Result::OK);
1309   ScopedTzipInterface interface(pkgid);
1310   ValidatePackage(pkgid, {appid});
1311
1312   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n"));
1313   ValidateDataFiles(pkgid, kTestUserId);
1314 }
1315
1316 TEST_F(SmokeTest, MountInstallationMode_Rollback) {
1317   bf::path path =
1318       kSmokePackagesDirectory / "MountInstallationMode_Rollback.wgt";
1319   std::string pkgid = "smokewgt33";
1320   std::string appid = "smokewgt33.web";
1321   ASSERT_EQ(MountInstall(path, PackageType::WGT, RequestResult::FAIL),
1322             ci::AppInstaller::Result::ERROR);
1323   ScopedTzipInterface interface(pkgid);
1324   CheckPackageNonExistance(pkgid, {appid});
1325 }
1326
1327 TEST_F(SmokeTest, MountUpdateMode_Rollback) {
1328   bf::path path_old = kSmokePackagesDirectory / "MountUpdateMode_Rollback.wgt";
1329   bf::path path_new =
1330       kSmokePackagesDirectory / "MountUpdateMode_Rollback_2.wgt";
1331   std::string pkgid = "smokewgt34";
1332   std::string appid = "smokewgt34.web";
1333   ASSERT_EQ(MountInstall(path_old, PackageType::WGT),
1334             ci::AppInstaller::Result::OK);
1335   AddDataFiles(pkgid, kTestUserId);
1336   ASSERT_EQ(MountInstall(path_new, PackageType::WGT,
1337       RequestResult::FAIL), ci::AppInstaller::Result::ERROR);
1338   ScopedTzipInterface interface(pkgid);
1339   ValidatePackage(pkgid, {appid});
1340
1341   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
1342   ValidateDataFiles(pkgid, kTestUserId);
1343 }
1344
1345 TEST_F(SmokeTest, UserDefinedPlugins) {
1346   bf::path path = kSmokePackagesDirectory / "SimpleEchoPrivilege.wgt";
1347   std::string pkgid = "smokewgt02";
1348   std::string appid = "smokewgt02.SimpleEcho";
1349   std::string call_privilege = "http://tizen.org/privilege/call";
1350   std::string location_privilege = "http://tizen.org/privilege/location";
1351   std::string power_privilege = "http://tizen.org/privilege/power";
1352
1353   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
1354   ValidatePackage(pkgid, {appid});
1355   std::vector<std::string> res;
1356   ASSERT_TRUE(ci::QueryPrivilegesForPkgId(pkgid, kTestUserId, &res));
1357   ASSERT_TRUE(std::find(res.begin(), res.end(), call_privilege) != res.end());
1358   ASSERT_TRUE(std::find(res.begin(), res.end(), location_privilege)
1359           != res.end());
1360   ASSERT_TRUE(std::find(res.begin(), res.end(), power_privilege) != res.end());
1361 }
1362
1363 TEST_F(SmokeTest, InstallExternalMode) {
1364   ASSERT_TRUE(CheckAvailableExternalPath());
1365   bf::path path = kSmokePackagesDirectory / "InstallExternalMode.wgt";
1366   std::string pkgid = "smokewgt35";
1367   std::string appid = "smokewgt35.web";
1368   ASSERT_EQ(InstallExternal(path, PackageType::WGT),
1369       ci::AppInstaller::Result::OK);
1370   ValidateExternalPackage(pkgid, {appid});
1371 }
1372
1373 TEST_F(SmokeTest, MigrateLegacyExternalImageMode) {
1374   ASSERT_TRUE(CheckAvailableExternalPath());
1375   bf::path path =
1376       kSmokePackagesDirectory / "MigrateLegacyExternalImageMode.wgt";
1377   std::string pkgid = "smokewgt36";
1378   std::string appid = "smokewgt36.web";
1379   bf::path legacy_path = kSmokePackagesDirectory / kLegacyExtImageDir;
1380   ASSERT_EQ(MigrateLegacyExternalImage(pkgid, path, legacy_path,
1381       PackageType::WGT), ci::AppInstaller::Result::OK);
1382   ValidateExternalPackage(pkgid, {appid});
1383 }
1384
1385 TEST_F(PreloadSmokeTest, InstallationMode_Preload) {
1386   ASSERT_EQ(getuid(), 0) << "Test cannot be run by normal user";
1387   bf::path path = kSmokePackagesDirectory / "InstallationMode_Preload.wgt";
1388   std::string pkgid = "smokewgt37";
1389   std::string appid = "smokewgt37.InstallationModePreload";
1390   ASSERT_EQ(InstallPreload(path, PackageType::WGT),
1391             ci::AppInstaller::Result::OK);
1392   ValidatePackage(pkgid, {appid}, true);
1393 }
1394
1395 TEST_F(PreloadSmokeTest, UpdateMode_Preload) {
1396   ASSERT_EQ(getuid(), 0) << "Test cannot be run by normal user";
1397   bf::path path_old = kSmokePackagesDirectory / "UpdateMode_Preload.wgt";
1398   bf::path path_new = kSmokePackagesDirectory / "UpdateMode_Preload2.wgt";
1399   std::string pkgid = "smokewgt38";
1400   std::string appid = "smokewgt38.UpdateModePreload";
1401   ASSERT_EQ(InstallPreload(path_old, PackageType::WGT),
1402             ci::AppInstaller::Result::OK);
1403   AddDataFiles(pkgid, kTestUserId);
1404   ASSERT_EQ(InstallPreload(path_new, PackageType::WGT),
1405             ci::AppInstaller::Result::OK);
1406   ValidatePackage(pkgid, {appid}, true);
1407
1408   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2",
1409                                            true));
1410   ValidateDataFiles(pkgid, kTestUserId);
1411 }
1412
1413 TEST_F(PreloadSmokeTest, DeinstallationMode_Preload) {
1414   ASSERT_EQ(getuid(), 0) << "Test cannot be run by normal user";
1415   bf::path path = kSmokePackagesDirectory / "DeinstallationMode_Preload.wgt";
1416   std::string pkgid = "smokewgt39";
1417   std::string appid = "smokewgt39.DeinstallationModePreload";
1418   ASSERT_EQ(InstallPreload(path, PackageType::WGT),
1419             ci::AppInstaller::Result::OK);
1420   ASSERT_EQ(Uninstall(pkgid, PackageType::WGT, true),
1421             ci::AppInstaller::Result::OK);
1422   CheckPackageReadonlyNonExistance(pkgid, {appid});
1423 }
1424
1425 TEST_F(SmokeTest, SharedRes24) {
1426   bf::path path = kSmokePackagesDirectory / "SharedRes24.wgt";
1427   std::string pkgid = "smokeSh2xx";
1428   std::string appid = "smokeSh2xx.SharedRes24";
1429   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
1430   ValidatePackage(pkgid, {appid});
1431   bf::path root_path = ci::GetRootAppPath(false, kTestUserId);
1432   ASSERT_TRUE(bf::is_regular_file(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "NOT-SHARED-WGT"));  // NOLINT
1433   ASSERT_FALSE(bf::exists(root_path / pkgid / "shared" / "res" / "NOT-SHARED-WGT"));  // NOLINT
1434 }
1435
1436 TEST_F(SmokeTest, SharedRes30) {
1437   bf::path path = kSmokePackagesDirectory / "SharedRes30.wgt";
1438   std::string pkgid = "smokeSh3xx";
1439   std::string appid = "smokeSh3xx.SharedRes30";
1440   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
1441   ValidatePackage(pkgid, {appid});
1442   bf::path root_path = ci::GetRootAppPath(false, kTestUserId);
1443   ASSERT_TRUE(bf::is_regular_file(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-WGT"));  // NOLINT
1444   ASSERT_TRUE(bf::is_symlink(root_path / pkgid / "shared" / "res" / "SHARED-WGT"));  // NOLINT
1445 }
1446
1447 TEST_F(SmokeTest, SharedRes30Delta) {
1448   bf::path path = kSmokePackagesDirectory / "SharedRes30Delta.wgt";
1449   bf::path delta_package = kSmokePackagesDirectory / "SharedRes30Delta.delta";
1450   std::string pkgid = "smokeSh3De";
1451   std::string appid = "smokeSh3De.SharedRes30Delta";
1452   ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::WGT),
1453             ci::AppInstaller::Result::OK);
1454   ValidatePackage(pkgid, {appid});
1455   // Check delta modifications
1456   bf::path root_path = ci::GetRootAppPath(false, kTestUserId);
1457   ASSERT_TRUE(bf::is_regular_file(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-WGT-2"));  // NOLINT
1458   ASSERT_TRUE(bf::is_symlink(root_path / pkgid / "shared" / "res" / "SHARED-WGT-2"));  // NOLINT
1459   ASSERT_FALSE(bf::exists(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-WGT-1"));  // NOLINT
1460   ASSERT_FALSE(bf::exists(root_path / pkgid / "shared" / "res" / "SHARED-WGT-1"));  // NOLINT
1461 }
1462
1463 TEST_F(SmokeTest, SharedRes30Hybrid) {
1464   bf::path path = kSmokePackagesDirectory / "SharedRes30Hybrid.wgt";
1465   std::string pkgid = "smokeSh3Hy";
1466   std::string appid1 = "smokeSh3Hy.SharedRes30Hybrid";
1467   std::string appid2 = "sharedres30hybridserivce";
1468   ASSERT_EQ(Install(path, PackageType::HYBRID), ci::AppInstaller::Result::OK);
1469   ValidatePackage(pkgid, {appid1, appid2});
1470   bf::path root_path = ci::GetRootAppPath(false, kTestUserId);
1471   ASSERT_TRUE(bf::is_regular_file(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-WGT"));  // NOLINT
1472   ASSERT_TRUE(bf::is_symlink(root_path / pkgid / "shared" / "res" / "SHARED-WGT"));  // NOLINT
1473   ASSERT_TRUE(bf::is_regular_file(root_path / pkgid / "shared" / "res" / "SHARED-TPK"));  // NOLINT
1474   ASSERT_TRUE(bf::is_symlink(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-TPK"));  // NOLINT
1475 }
1476
1477 TEST_F(SmokeTest, SharedRes30HybridDelta) {
1478   bf::path path = kSmokePackagesDirectory / "SharedRes30HybridDelta.wgt";
1479   bf::path delta_package = kSmokePackagesDirectory / "SharedRes30HybridDelta.delta";
1480   std::string pkgid = "smokeSh3HD";
1481   std::string appid1 = "smokeSh3HD.SharedRes30HybridDelta";
1482   std::string appid2 = "sharedres30hybriddeltaserivce";
1483   ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::HYBRID),
1484             ci::AppInstaller::Result::OK);
1485   ValidatePackage(pkgid, {appid1, appid2});
1486   // Check delta modifications
1487   bf::path root_path = ci::GetRootAppPath(false, kTestUserId);
1488   ASSERT_TRUE(bf::is_regular_file(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-WGT-2"));  // NOLINT
1489   ASSERT_TRUE(bf::is_symlink(root_path / pkgid / "shared" / "res" / "SHARED-WGT-2"));  // NOLINT
1490   ASSERT_TRUE(bf::is_regular_file(root_path / pkgid / "shared" / "res" / "SHARED-TPK-2"));  // NOLINT
1491   ASSERT_TRUE(bf::is_symlink(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-TPK-2"));  // NOLINT
1492   ASSERT_FALSE(bf::exists(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-WGT-1"));  // NOLINT
1493   ASSERT_FALSE(bf::exists(root_path / pkgid / "shared" / "res" / "SHARED-WGT-1"));  // NOLINT
1494 }
1495
1496 }  // namespace common_installer
1497
1498 int main(int argc,  char** argv) {
1499   testing::InitGoogleTest(&argc, argv);
1500   testing::Environment *env = testing::AddGlobalTestEnvironment(
1501       new common_installer::SmokeEnvironment());
1502   ParseRequestMode(argc, argv);
1503   return RUN_ALL_TESTS();
1504 }