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